fixed longstanding buffer logic bug
This commit is contained in:
@@ -33,7 +33,7 @@
|
|||||||
#ifndef _SDK_DEBUG_H_
|
#ifndef _SDK_DEBUG_H_
|
||||||
#define _SDK_DEBUG_H_
|
#define _SDK_DEBUG_H_
|
||||||
|
|
||||||
#define DEBUG_LEVEL 1 // Set this to adjust what you'd like to see in the debug traces
|
#define DEBUG_LEVEL 0 // Set this to adjust what you'd like to see in the debug traces
|
||||||
|
|
||||||
#define MSG_ERROR 1 // Errors
|
#define MSG_ERROR 1 // Errors
|
||||||
#define MSG_TRANSFER 2 // RX/TX specific statements
|
#define MSG_TRANSFER 2 // RX/TX specific statements
|
||||||
|
|||||||
@@ -167,12 +167,14 @@ int rpc_send_command(char *path, int cmd, int forfd, void *data, int len)
|
|||||||
uint64_t canary_num;
|
uint64_t canary_num;
|
||||||
// ephemeral RPC socket used only for this command
|
// ephemeral RPC socket used only for this command
|
||||||
int rpc_sock = rpc_join(path);
|
int rpc_sock = rpc_join(path);
|
||||||
|
|
||||||
// Generate token
|
// Generate token
|
||||||
int fdrand = open("/dev/urandom", O_RDONLY);
|
int fdrand = open("/dev/urandom", O_RDONLY);
|
||||||
if(read(fdrand, &CANARY, CANARY_SZ) < 0) {
|
if(read(fdrand, &CANARY, CANARY_SZ) < 0) {
|
||||||
DEBUG_ERROR("unable to read from /dev/urandom for RPC canary data");
|
DEBUG_ERROR("unable to read from /dev/urandom for RPC canary data");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fdrand);
|
close(fdrand);
|
||||||
memcpy(&canary_num, CANARY, CANARY_SZ);
|
memcpy(&canary_num, CANARY, CANARY_SZ);
|
||||||
cmdbuf[CMD_ID_IDX] = cmd;
|
cmdbuf[CMD_ID_IDX] = cmd;
|
||||||
@@ -204,6 +206,7 @@ int rpc_send_command(char *path, int cmd, int forfd, void *data, int len)
|
|||||||
/* Combine command flag+payload with RPC metadata */
|
/* Combine command flag+payload with RPC metadata */
|
||||||
memcpy(metabuf, RPC_PHRASE, RPC_PHRASE_SZ); // Write signal phrase
|
memcpy(metabuf, RPC_PHRASE, RPC_PHRASE_SZ); // Write signal phrase
|
||||||
memcpy(&metabuf[IDX_PAYLOAD], cmdbuf, len + 1 + CANARY_SZ);
|
memcpy(&metabuf[IDX_PAYLOAD], cmdbuf, len + 1 + CANARY_SZ);
|
||||||
|
|
||||||
// Write RPC
|
// Write RPC
|
||||||
long n_write = write(rpc_sock, &metabuf, BUF_SZ);
|
long n_write = write(rpc_sock, &metabuf, BUF_SZ);
|
||||||
if(n_write < 0) {
|
if(n_write < 0) {
|
||||||
|
|||||||
@@ -55,9 +55,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// -------------- Socket API function signatures for convenience ----------------
|
// -------------- Socket API function signatures for convenience ----------------
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -320,7 +320,6 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
|
|
||||||
if(n>0) {
|
if(n>0) {
|
||||||
total_read += n;
|
total_read += n;
|
||||||
total_socket_rx += n;
|
|
||||||
}
|
}
|
||||||
else if (n < 0)
|
else if (n < 0)
|
||||||
return n;
|
return n;
|
||||||
@@ -555,7 +554,6 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
JNIEXPORT jint JNICALL Java_ZeroTier_ZTSDK_zt_1connect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
|
JNIEXPORT jint JNICALL Java_ZeroTier_ZTSDK_zt_1connect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
const char *str = (*env)->GetStringUTFChars(env, addrstr, 0);
|
const char *str = (*env)->GetStringUTFChars(env, addrstr, 0);
|
||||||
DEBUG_INFO("fd=%d, addr=%s, port=%d", fd, str, port);
|
|
||||||
addr.sin_addr.s_addr = inet_addr(str);
|
addr.sin_addr.s_addr = inet_addr(str);
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons( port );
|
addr.sin_port = htons( port );
|
||||||
@@ -571,7 +569,6 @@ int (*realclose)(CLOSE_SIG);
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
get_api_netpath();
|
get_api_netpath();
|
||||||
//DEBUG_INFO("fd=%d", fd);
|
|
||||||
struct connect_st rpc_st;
|
struct connect_st rpc_st;
|
||||||
rpc_st.fd = fd;
|
rpc_st.fd = fd;
|
||||||
memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));
|
memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ namespace ZeroTier {
|
|||||||
void pico_init_interface(NetconEthernetTap *tap, const InetAddress &ip)
|
void pico_init_interface(NetconEthernetTap *tap, const InetAddress &ip)
|
||||||
{
|
{
|
||||||
picoTCP_stack *stack = tap->picostack;
|
picoTCP_stack *stack = tap->picostack;
|
||||||
DEBUG_INFO();
|
|
||||||
if (std::find(picotap->_ips.begin(),picotap->_ips.end(),ip) == picotap->_ips.end()) {
|
if (std::find(picotap->_ips.begin(),picotap->_ips.end(),ip) == picotap->_ips.end()) {
|
||||||
picotap->_ips.push_back(ip);
|
picotap->_ips.push_back(ip);
|
||||||
std::sort(picotap->_ips.begin(),picotap->_ips.end());
|
std::sort(picotap->_ips.begin(),picotap->_ips.end());
|
||||||
@@ -128,7 +127,6 @@ namespace ZeroTier {
|
|||||||
// After this step, buffer will be emptied periodically by pico_handleRead()
|
// After this step, buffer will be emptied periodically by pico_handleRead()
|
||||||
void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
Connection *conn = tap->getConnection(s);
|
Connection *conn = tap->getConnection(s);
|
||||||
if(conn) {
|
if(conn) {
|
||||||
int r;
|
int r;
|
||||||
@@ -171,8 +169,6 @@ namespace ZeroTier {
|
|||||||
//
|
//
|
||||||
void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
|
|
||||||
Connection *conn = tap->getConnection(s);
|
Connection *conn = tap->getConnection(s);
|
||||||
if(conn) {
|
if(conn) {
|
||||||
|
|
||||||
@@ -190,16 +186,14 @@ namespace ZeroTier {
|
|||||||
|
|
||||||
// RX
|
// RX
|
||||||
int r = tap->picostack->__pico_socket_recvfrom(s, tmpbuf, SDK_MTU, (void *)&peer.ip4.addr, &port);
|
int r = tap->picostack->__pico_socket_recvfrom(s, tmpbuf, SDK_MTU, (void *)&peer.ip4.addr, &port);
|
||||||
DEBUG_FLOW(" [ RXBUF <- STACK] Receiving (%d) from stack, copying to receving buffer", r);
|
//DEBUG_FLOW(" [ RXBUF <- STACK] Receiving (%d) from stack, copying to receving buffer", r);
|
||||||
|
|
||||||
// Mutex::Lock _l2(tap->_rx_buf_m);
|
// Mutex::Lock _l2(tap->_rx_buf_m);
|
||||||
// struct sockaddr_in6 addr_in6;
|
// struct sockaddr_in6 addr_in6;
|
||||||
// addr_in6.sin6_addr.s6_addr;
|
// addr_in6.sin6_addr.s6_addr;
|
||||||
// addr_in6.sin6_port = Utils::ntoh(s->remote_port);
|
// addr_in6.sin6_port = Utils::ntoh(s->remote_port);
|
||||||
// DEBUG_ATTN("remote_port=%d, local_port=%d", s->remote_port, Utils::ntoh(s->local_port));
|
// DEBUG_ATTN("remote_port=%d, local_port=%d", s->remote_port, Utils::ntoh(s->local_port));
|
||||||
|
|
||||||
picotap->_rx_buf_m.lock();
|
picotap->_rx_buf_m.lock();
|
||||||
|
|
||||||
if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full
|
if(conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full
|
||||||
//DEBUG_FLOW(" [ RXBUF <- STACK] UDP RX buffer full. Discarding oldest payload segment");
|
//DEBUG_FLOW(" [ RXBUF <- STACK] UDP RX buffer full. Discarding oldest payload segment");
|
||||||
memmove(conn->rxbuf, conn->rxbuf + SDK_MTU, DEFAULT_UDP_RX_BUF_SZ - SDK_MTU);
|
memmove(conn->rxbuf, conn->rxbuf + SDK_MTU, DEFAULT_UDP_RX_BUF_SZ - SDK_MTU);
|
||||||
@@ -214,19 +208,22 @@ namespace ZeroTier {
|
|||||||
payload_pos = addr_pos + sizeof(struct sockaddr_storage) + sizeof(r);
|
payload_pos = addr_pos + sizeof(struct sockaddr_storage) + sizeof(r);
|
||||||
memcpy(addr_pos, &addr_in, sizeof(struct sockaddr_storage));
|
memcpy(addr_pos, &addr_in, sizeof(struct sockaddr_storage));
|
||||||
|
|
||||||
|
memcpy(payload_pos, tmpbuf, r); // write payload to app's socket
|
||||||
|
|
||||||
// Adjust buffer size
|
// Adjust buffer size
|
||||||
if(r) {
|
if(r) {
|
||||||
conn->rxsz += SDK_MTU;
|
conn->rxsz += SDK_MTU;
|
||||||
memcpy(sz_pos, &r, sizeof(r));
|
memcpy(sz_pos, &r, sizeof(r));
|
||||||
tap->phyOnUnixWritable(conn->sock, NULL, true);
|
|
||||||
//tap->_phy.setNotifyWritable(conn->sock, false);
|
|
||||||
}
|
}
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
DEBUG_ERROR("unable to read from picosock=%p", s);
|
DEBUG_ERROR("unable to read from picosock=%p", s);
|
||||||
}
|
}
|
||||||
memcpy(payload_pos, tmpbuf, r); // write payload to app's socket
|
picotap->_rx_buf_m.unlock();
|
||||||
|
|
||||||
|
// TODO: Revisit logic
|
||||||
|
if(r)
|
||||||
|
tap->phyOnUnixWritable(conn->sock, NULL, true);
|
||||||
//DEBUG_EXTRA(" Copied onto rxbuf (%d) from stack socket", r);
|
//DEBUG_EXTRA(" Copied onto rxbuf (%d) from stack socket", r);
|
||||||
picotap->_rx_buf_m.unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,8 +236,6 @@ namespace ZeroTier {
|
|||||||
DEBUG_ERROR("invalid connection");
|
DEBUG_ERROR("invalid connection");
|
||||||
if(!conn->txsz)
|
if(!conn->txsz)
|
||||||
return;
|
return;
|
||||||
DEBUG_INFO("txsz=%d bytes ready to be written", conn->txsz);
|
|
||||||
|
|
||||||
// Only called from a locked context, no need to lock anything
|
// Only called from a locked context, no need to lock anything
|
||||||
if(conn->txsz > 0) {
|
if(conn->txsz > 0) {
|
||||||
int r, max_write_len = conn->txsz < SDK_MTU ? conn->txsz : SDK_MTU;
|
int r, max_write_len = conn->txsz < SDK_MTU ? conn->txsz : SDK_MTU;
|
||||||
@@ -262,7 +257,6 @@ namespace ZeroTier {
|
|||||||
// Main callback for TCP connections
|
// Main callback for TCP connections
|
||||||
void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
|
void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
int err;
|
int err;
|
||||||
Mutex::Lock _l(picotap->_tcpconns_m);
|
Mutex::Lock _l(picotap->_tcpconns_m);
|
||||||
Connection *conn = picotap->getConnection(s);
|
Connection *conn = picotap->getConnection(s);
|
||||||
@@ -313,7 +307,6 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read from picoTCP socket
|
// Read from picoTCP socket
|
||||||
if (ev & PICO_SOCK_EV_RD) {
|
if (ev & PICO_SOCK_EV_RD) {
|
||||||
if(conn->type==SOCK_STREAM)
|
if(conn->type==SOCK_STREAM)
|
||||||
@@ -352,7 +345,6 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
int pico_eth_send(struct pico_device *dev, void *buf, int len)
|
int pico_eth_send(struct pico_device *dev, void *buf, int len)
|
||||||
{
|
{
|
||||||
//DEBUG_INFO("len=%d", len);
|
|
||||||
struct pico_eth_hdr *ethhdr;
|
struct pico_eth_hdr *ethhdr;
|
||||||
ethhdr = (struct pico_eth_hdr *)buf;
|
ethhdr = (struct pico_eth_hdr *)buf;
|
||||||
|
|
||||||
@@ -376,7 +368,6 @@ namespace ZeroTier {
|
|||||||
// It will then periodically be transfered into the network stack via pico_eth_poll()
|
// It will then periodically be transfered into the network stack via pico_eth_poll()
|
||||||
void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
|
void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
// Since picoTCP only allows the reception of frames from within the polling function, we
|
// Since picoTCP only allows the reception of frames from within the polling function, we
|
||||||
// must enqueue each frame into a memory structure shared by both threads. This structure will
|
// must enqueue each frame into a memory structure shared by both threads. This structure will
|
||||||
Mutex::Lock _l(tap->_pico_frame_rxbuf_m);
|
Mutex::Lock _l(tap->_pico_frame_rxbuf_m);
|
||||||
@@ -392,7 +383,7 @@ namespace ZeroTier {
|
|||||||
while(newlen > (MAX_PICO_FRAME_RX_BUF_SZ-tap->pico_frame_rxbuf_tot) && ethhdr.proto == 56710)
|
while(newlen > (MAX_PICO_FRAME_RX_BUF_SZ-tap->pico_frame_rxbuf_tot) && ethhdr.proto == 56710)
|
||||||
{
|
{
|
||||||
mylen = 0;
|
mylen = 0;
|
||||||
DEBUG_ERROR(" [ ZTWIRE -> FBUF ] not enough space left on RX frame buffer, dropping oldest packet in buffer");
|
//DEBUG_FLOW(" [ ZTWIRE -> FBUF ] not enough space left on RX frame buffer, dropping oldest packet in buffer");
|
||||||
/*
|
/*
|
||||||
memcpy(&mylen, picotap->pico_frame_rxbuf, sizeof(len));
|
memcpy(&mylen, picotap->pico_frame_rxbuf, sizeof(len));
|
||||||
memmove(tap->pico_frame_rxbuf, tap->pico_frame_rxbuf + mylen, MAX_PICO_FRAME_RX_BUF_SZ-mylen); // shift buffer
|
memmove(tap->pico_frame_rxbuf, tap->pico_frame_rxbuf + mylen, MAX_PICO_FRAME_RX_BUF_SZ-mylen); // shift buffer
|
||||||
@@ -406,28 +397,6 @@ namespace ZeroTier {
|
|||||||
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
|
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
|
||||||
tap->pico_frame_rxbuf_tot += newlen;
|
tap->pico_frame_rxbuf_tot += newlen;
|
||||||
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Move FRAME(sz=%d) into FBUF(sz=%d), data_len=%d", newlen, picotap->pico_frame_rxbuf_tot, len);
|
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Move FRAME(sz=%d) into FBUF(sz=%d), data_len=%d", newlen, picotap->pico_frame_rxbuf_tot, len);
|
||||||
|
|
||||||
/*
|
|
||||||
char graph[GRAPH_BUF_SZ];
|
|
||||||
gengraph(&graph, GRAPH_BUF_SZ, '|', 0.6);
|
|
||||||
DEBUG_FLOW(graph);
|
|
||||||
*/
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
/*
|
|
||||||
if(newlen > (MAX_PICO_FRAME_RX_BUF_SZ-tap->pico_frame_rxbuf_tot)) {
|
|
||||||
DEBUG_ERROR("dropping packet (len = %d) - not enough space left on RX frame buffer", len);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot, &newlen, sizeof(newlen)); // size of frame + meta
|
|
||||||
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen), ðhdr, sizeof(ethhdr)); // new eth header
|
|
||||||
memcpy(tap->pico_frame_rxbuf + tap->pico_frame_rxbuf_tot + sizeof(newlen) + sizeof(ethhdr), data, len); // frame data
|
|
||||||
|
|
||||||
tap->pico_frame_rxbuf_tot += newlen;
|
|
||||||
DEBUG_FLOW(" [ ZTWIRE -> FBUF ] Moved FRAME(sz=%d) into FBUF(sz=%d), data_len=%d, ethhdr.proto=%d", newlen, picotap->pico_frame_rxbuf_tot, len, ethhdr.proto);
|
|
||||||
*/
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called periodically by the stack, this removes data from the locked memory buffer (FBUF) and feeds it into the stack.
|
// Called periodically by the stack, this removes data from the locked memory buffer (FBUF) and feeds it into the stack.
|
||||||
@@ -440,19 +409,18 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
int pico_eth_poll(struct pico_device *dev, int loop_score)
|
int pico_eth_poll(struct pico_device *dev, int loop_score)
|
||||||
{
|
{
|
||||||
//DEBUG_ERROR();
|
|
||||||
// OPTIMIZATION: The copy logic and/or buffer structure should be reworked for better performance after the BETA
|
// OPTIMIZATION: The copy logic and/or buffer structure should be reworked for better performance after the BETA
|
||||||
// NetconEthernetTap *tap = (NetconEthernetTap*)netif->state;
|
// NetconEthernetTap *tap = (NetconEthernetTap*)netif->state;
|
||||||
Mutex::Lock _l(picotap->_pico_frame_rxbuf_m);
|
Mutex::Lock _l(picotap->_pico_frame_rxbuf_m);
|
||||||
unsigned char frame[SDK_MTU];
|
unsigned char frame[SDK_MTU];
|
||||||
int len;
|
int len;
|
||||||
while (picotap->pico_frame_rxbuf_tot > 0 && loop_score > 0) {
|
while (picotap->pico_frame_rxbuf_tot > 0 && loop_score > 0) {
|
||||||
DEBUG_INFO(" [ FBUF -> STACK] Frame buffer SZ=%d", picotap->pico_frame_rxbuf_tot);
|
//DEBUG_FLOW(" [ FBUF -> STACK] Frame buffer SZ=%d", picotap->pico_frame_rxbuf_tot);
|
||||||
memset(frame, 0, sizeof(frame));
|
memset(frame, 0, sizeof(frame));
|
||||||
len = 0;
|
len = 0;
|
||||||
memcpy(&len, picotap->pico_frame_rxbuf, sizeof(len)); // get frame len
|
memcpy(&len, picotap->pico_frame_rxbuf, sizeof(len)); // get frame len
|
||||||
if(len >= 0) {
|
if(len >= 0) {
|
||||||
DEBUG_FLOW(" [ FBUF -> STACK] Moving FRAME of size (%d) from FBUF(sz=%d) into stack",len, picotap->pico_frame_rxbuf_tot-len);
|
//DEBUG_FLOW(" [ FBUF -> STACK] Moving FRAME of size (%d) from FBUF(sz=%d) into stack",len, picotap->pico_frame_rxbuf_tot-len);
|
||||||
memcpy(frame, picotap->pico_frame_rxbuf + sizeof(len), len-(sizeof(len)) ); // get frame data
|
memcpy(frame, picotap->pico_frame_rxbuf + sizeof(len), len-(sizeof(len)) ); // get frame data
|
||||||
memmove(picotap->pico_frame_rxbuf, picotap->pico_frame_rxbuf + len, MAX_PICO_FRAME_RX_BUF_SZ-len); // shift buffer
|
memmove(picotap->pico_frame_rxbuf, picotap->pico_frame_rxbuf + len, MAX_PICO_FRAME_RX_BUF_SZ-len); // shift buffer
|
||||||
picotap->picostack->__pico_stack_recv(dev, (uint8_t*)frame, (len-sizeof(len)));
|
picotap->picostack->__pico_stack_recv(dev, (uint8_t*)frame, (len-sizeof(len)));
|
||||||
@@ -470,7 +438,6 @@ namespace ZeroTier {
|
|||||||
// Creates a new pico_socket and Connection object to represent a new connection to be.
|
// Creates a new pico_socket and Connection object to represent a new connection to be.
|
||||||
Connection *pico_handleSocket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc)
|
Connection *pico_handleSocket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
struct pico_socket * psock;
|
struct pico_socket * psock;
|
||||||
int protocol, protocol_version;
|
int protocol, protocol_version;
|
||||||
|
|
||||||
@@ -494,33 +461,33 @@ namespace ZeroTier {
|
|||||||
*uptr = newConn;
|
*uptr = newConn;
|
||||||
newConn->type = socket_rpc->socket_type;
|
newConn->type = socket_rpc->socket_type;
|
||||||
newConn->sock = sock;
|
newConn->sock = sock;
|
||||||
/*
|
|
||||||
|
/*
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int sendbuff = UNIX_SOCK_BUF_SIZE;
|
int sendbuff = UNIX_SOCK_BUF_SIZE;
|
||||||
socklen_t optlen = sizeof(sendbuff);
|
socklen_t optlen = sizeof(sendbuff);
|
||||||
|
|
||||||
res = setsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_RCVBUF, &sendbuff, sizeof(sendbuff));
|
res = setsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_RCVBUF, &sendbuff, sizeof(sendbuff));
|
||||||
if(res == -1)
|
if(res == -1)
|
||||||
DEBUG_ERROR("Error while setting RX buffer limits");
|
//DEBUG_ERROR("Error while setting RX buffer limits");
|
||||||
res = setsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff));
|
res = setsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff));
|
||||||
if(res == -1)
|
if(res == -1)
|
||||||
DEBUG_ERROR("Error while setting TX buffer limits");
|
//DEBUG_ERROR("Error while setting TX buffer limits");
|
||||||
|
|
||||||
// Get buffer size
|
// Get buffer size
|
||||||
// optlen = sizeof(sendbuff);
|
// optlen = sizeof(sendbuff);
|
||||||
// res = getsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);
|
// res = getsockopt(picotap->_phy.getDescriptor(sock), SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);
|
||||||
// DEBUG_INFO("buflen=%d", sendbuff);
|
// DEBUG_INFO("buflen=%d", sendbuff);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
newConn->local_addr = NULL;
|
newConn->local_addr = NULL;
|
||||||
// newConn->peer_addr = NULL;
|
|
||||||
newConn->picosock = psock;
|
newConn->picosock = psock;
|
||||||
picotap->_Connections.push_back(newConn);
|
picotap->_Connections.push_back(newConn);
|
||||||
memset(newConn->rxbuf, 0, DEFAULT_UDP_RX_BUF_SZ);
|
memset(newConn->rxbuf, 0, DEFAULT_UDP_RX_BUF_SZ);
|
||||||
return newConn;
|
return newConn;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
DEBUG_ERROR("failed to create pico_socket");
|
DEBUG_ERROR("failed to create pico_socket");
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,7 +500,6 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
void pico_handleWrite(Connection *conn)
|
void pico_handleWrite(Connection *conn)
|
||||||
{
|
{
|
||||||
//DEBUG_INFO();
|
|
||||||
if(!conn || !conn->picosock) {
|
if(!conn || !conn->picosock) {
|
||||||
DEBUG_ERROR(" invalid connection");
|
DEBUG_ERROR(" invalid connection");
|
||||||
return;
|
return;
|
||||||
@@ -579,15 +545,14 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
if(conn->type == SOCK_DGRAM) {
|
if(conn->type == SOCK_DGRAM) {
|
||||||
max = DEFAULT_UDP_TX_BUF_SZ;
|
max = DEFAULT_UDP_TX_BUF_SZ;
|
||||||
//DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
|
DEBUG_TRANS("[UDP TX] ---> :: {TX: %.3f%%, RX: %.3f%%, physock=%p} :: %d bytes",
|
||||||
// (float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r);
|
(float)conn->txsz / (float)max, (float)conn->rxsz / max, conn->sock, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instructs the stack to connect to a remote host
|
// Instructs the stack to connect to a remote host
|
||||||
void pico_handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc)
|
void pico_handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc)
|
||||||
{
|
{
|
||||||
//DEBUG_INFO();
|
|
||||||
if(conn->picosock) {
|
if(conn->picosock) {
|
||||||
struct sockaddr_in *addr = (struct sockaddr_in *) &connect_rpc->addr;
|
struct sockaddr_in *addr = (struct sockaddr_in *) &connect_rpc->addr;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -612,15 +577,13 @@ namespace ZeroTier {
|
|||||||
|
|
||||||
memcpy(&(conn->peer_addr), &connect_rpc->addr, sizeof(struct sockaddr_storage));
|
memcpy(&(conn->peer_addr), &connect_rpc->addr, sizeof(struct sockaddr_storage));
|
||||||
|
|
||||||
if(ret == PICO_ERR_EPROTONOSUPPORT) {
|
if(ret == PICO_ERR_EPROTONOSUPPORT)
|
||||||
DEBUG_ERROR("PICO_ERR_EPROTONOSUPPORT");
|
DEBUG_ERROR("PICO_ERR_EPROTONOSUPPORT");
|
||||||
}
|
if(ret == PICO_ERR_EINVAL)
|
||||||
if(ret == PICO_ERR_EINVAL) {
|
|
||||||
DEBUG_ERROR("PICO_ERR_EINVAL");
|
DEBUG_ERROR("PICO_ERR_EINVAL");
|
||||||
}
|
if(ret == PICO_ERR_EHOSTUNREACH)
|
||||||
if(ret == PICO_ERR_EHOSTUNREACH) {
|
|
||||||
DEBUG_ERROR("PICO_ERR_EHOSTUNREACH");
|
DEBUG_ERROR("PICO_ERR_EHOSTUNREACH");
|
||||||
}
|
|
||||||
picotap->sendReturnValue(picotap->_phy.getDescriptor(rpcSock), 0, ERR_OK);
|
picotap->sendReturnValue(picotap->_phy.getDescriptor(rpcSock), 0, ERR_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -628,7 +591,6 @@ namespace ZeroTier {
|
|||||||
// Instructs the stack to bind to a given address
|
// Instructs the stack to bind to a given address
|
||||||
void pico_handleBind(PhySocket *sock, PhySocket *rpcSock, void **uptr, struct bind_st *bind_rpc)
|
void pico_handleBind(PhySocket *sock, PhySocket *rpcSock, void **uptr, struct bind_st *bind_rpc)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
Connection *conn = picotap->getConnection(sock);
|
Connection *conn = picotap->getConnection(sock);
|
||||||
if(!sock) {
|
if(!sock) {
|
||||||
DEBUG_ERROR("invalid connection");
|
DEBUG_ERROR("invalid connection");
|
||||||
@@ -706,26 +668,35 @@ namespace ZeroTier {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked)
|
void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
if(!lwip_invoked) {
|
if(!lwip_invoked) {
|
||||||
// The stack thread writes to RXBUF as well
|
// The stack thread writes to RXBUF as well
|
||||||
picotap->_tcpconns_m.lock();
|
picotap->_tcpconns_m.lock();
|
||||||
picotap->_rx_buf_m.lock();
|
picotap->_rx_buf_m.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
int tot = 0, n = -1;
|
int tot = 0, n = -1, write_attempts = 0;
|
||||||
|
|
||||||
Connection *conn = picotap->getConnection(sock);
|
Connection *conn = picotap->getConnection(sock);
|
||||||
if(conn && conn->rxsz) {
|
if(conn && conn->rxsz) {
|
||||||
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ;
|
float max = conn->type == SOCK_STREAM ? (float)DEFAULT_TCP_RX_BUF_SZ : (float)DEFAULT_UDP_RX_BUF_SZ;
|
||||||
|
|
||||||
if(conn->type==SOCK_DGRAM) {
|
if(conn->type==SOCK_DGRAM) {
|
||||||
//DEBUG_FLOW(" [ ZTSOCK <- RXBUF] attempting write, RXBUF(%d)", conn->rxsz);
|
//DEBUG_ERROR(" [ ZTSOCK <- RXBUF] attempting write, RXBUF(%d)", conn->rxsz);
|
||||||
// Try to write SDK_MTU-sized chunk to app socket
|
// Try to write SDK_MTU-sized chunk to app socket
|
||||||
while(tot < SDK_MTU) {
|
while(tot < SDK_MTU) {
|
||||||
|
write_attempts++;
|
||||||
n = picotap->_phy.streamSend(conn->sock, (conn->rxbuf)+tot, SDK_MTU);
|
n = picotap->_phy.streamSend(conn->sock, (conn->rxbuf)+tot, SDK_MTU);
|
||||||
tot += n;
|
tot += n;
|
||||||
DEBUG_FLOW(" [ ZTSOCK <- RXBUF] wrote = %d, total = %d", n, tot);
|
//DEBUG_ERROR(" [ ZTSOCK <- RXBUF] wrote = %d, total = %d, errno=%d", n, tot, errno);
|
||||||
|
|
||||||
|
// If socket is unavailable, attempt to write N times before giving up
|
||||||
|
if(errno==35) {
|
||||||
|
if(write_attempts == 1024) {
|
||||||
|
n = SDK_MTU; // say we wrote it, even though we didn't (drop packet)
|
||||||
|
tot = SDK_MTU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock);
|
// DEBUG_EXTRA("SOCK_DGRAM, conn=%p, physock=%p", conn, sock);
|
||||||
int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage);
|
int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage);
|
||||||
@@ -765,18 +736,17 @@ namespace ZeroTier {
|
|||||||
picotap->_phy.setNotifyWritable(sock, false);
|
picotap->_phy.setNotifyWritable(sock, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//picotap->_phy.whack();
|
|
||||||
if(!lwip_invoked) {
|
if(!lwip_invoked) {
|
||||||
picotap->_tcpconns_m.unlock();
|
picotap->_tcpconns_m.unlock();
|
||||||
picotap->_rx_buf_m.unlock();
|
picotap->_rx_buf_m.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_FLOW(" [ ZTSOCK <- RXBUF] Emitted (%d) from RXBUF(%d) to socket", tot, conn->rxsz);
|
DEBUG_FLOW(" [ ZTSOCK <- RXBUF] Emitted (%d) from RXBUF(%d) to socket", tot, conn->rxsz);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closes a pico_socket
|
// Closes a pico_socket
|
||||||
void pico_handleClose(PhySocket *sock)
|
void pico_handleClose(PhySocket *sock)
|
||||||
{
|
{
|
||||||
DEBUG_INFO();
|
|
||||||
/*
|
/*
|
||||||
int ret;
|
int ret;
|
||||||
if(conn && conn->picosock) {
|
if(conn && conn->picosock) {
|
||||||
|
|||||||
39
src/tap.cpp
39
src/tap.cpp
@@ -62,8 +62,7 @@
|
|||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
int NetconEthernetTap::sendReturnValue(int fd, int retval, int _errno)
|
int NetconEthernetTap::sendReturnValue(int fd, int retval, int _errno)
|
||||||
{
|
{
|
||||||
//#if !defined(USE_SOCKS_PROXY)
|
//DEBUG_INFO("fd=%d, retval=%d, errno=%d", fd, retval, _errno);
|
||||||
//DEBUG_EXTRA("fd=%d, retval=%d, errno=%d", fd, retval, _errno);
|
|
||||||
int sz = sizeof(char) + sizeof(retval) + sizeof(errno);
|
int sz = sizeof(char) + sizeof(retval) + sizeof(errno);
|
||||||
char retmsg[sz];
|
char retmsg[sz];
|
||||||
memset(&retmsg, 0, sizeof(retmsg));
|
memset(&retmsg, 0, sizeof(retmsg));
|
||||||
@@ -71,9 +70,6 @@ int NetconEthernetTap::sendReturnValue(int fd, int retval, int _errno)
|
|||||||
memcpy(&retmsg[1], &retval, sizeof(retval));
|
memcpy(&retmsg[1], &retval, sizeof(retval));
|
||||||
memcpy(&retmsg[1]+sizeof(retval), &_errno, sizeof(_errno));
|
memcpy(&retmsg[1]+sizeof(retval), &_errno, sizeof(_errno));
|
||||||
return write(fd, &retmsg, sz);
|
return write(fd, &retmsg, sz);
|
||||||
//#else
|
|
||||||
// return 1;
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
// Unpacks the buffer from an RPC command
|
// Unpacks the buffer from an RPC command
|
||||||
void NetconEthernetTap::unloadRPC(void *data, pid_t &pid, pid_t &tid,
|
void NetconEthernetTap::unloadRPC(void *data, pid_t &pid, pid_t &tid,
|
||||||
@@ -296,7 +292,6 @@ Connection *NetconEthernetTap::getConnection(struct pico_socket *sock)
|
|||||||
|
|
||||||
void NetconEthernetTap::closeConnection(PhySocket *sock)
|
void NetconEthernetTap::closeConnection(PhySocket *sock)
|
||||||
{
|
{
|
||||||
DEBUG_EXTRA("physock=%p", sock);
|
|
||||||
Mutex::Lock _l(_close_m);
|
Mutex::Lock _l(_close_m);
|
||||||
// Here we assume _tcpconns_m is already locked by caller
|
// Here we assume _tcpconns_m is already locked by caller
|
||||||
if(!sock) {
|
if(!sock) {
|
||||||
@@ -359,10 +354,11 @@ void NetconEthernetTap::phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_
|
|||||||
|
|
||||||
void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len)
|
void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len)
|
||||||
{
|
{
|
||||||
//DEBUG_EXTRA("physock=%p, len=%d", sock, (int)len);
|
//DEBUG_INFO("physock=%p, len=%d", sock, (int)len);
|
||||||
uint64_t CANARY_num;
|
uint64_t CANARY_num;
|
||||||
pid_t pid, tid;
|
pid_t pid, tid;
|
||||||
ssize_t wlen = len;
|
ssize_t wlen = len;
|
||||||
|
char tmpbuf[SDK_MTU];
|
||||||
char cmd, timestamp[20], CANARY[CANARY_SZ], padding[] = {PADDING};
|
char cmd, timestamp[20], CANARY[CANARY_SZ], padding[] = {PADDING};
|
||||||
void *payload;
|
void *payload;
|
||||||
unsigned char *buf = (unsigned char*)data;
|
unsigned char *buf = (unsigned char*)data;
|
||||||
@@ -384,7 +380,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
|
|||||||
// DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", sock, pid, tid, timestamp, cmd);
|
// DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", sock, pid, tid, timestamp, cmd);
|
||||||
|
|
||||||
if(cmd == RPC_SOCKET) {
|
if(cmd == RPC_SOCKET) {
|
||||||
//DEBUG_INFO("RPC_SOCKET, physock=%p", sock);
|
// DEBUG_INFO("RPC_SOCKET, physock=%p", sock);
|
||||||
// Create new lwip socket and associate it with this sock
|
// Create new lwip socket and associate it with this sock
|
||||||
struct socket_st socket_rpc;
|
struct socket_st socket_rpc;
|
||||||
memcpy(&socket_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct socket_st));
|
memcpy(&socket_rpc, &buf[IDX_PAYLOAD+STRUCT_IDX], sizeof(struct socket_st));
|
||||||
@@ -393,9 +389,11 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
|
|||||||
new_conn->pid = pid; // Merely kept to look up application path/names later, not strictly necessary
|
new_conn->pid = pid; // Merely kept to look up application path/names later, not strictly necessary
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
jobmap[CANARY_num] = std::pair<PhySocket*, void*>(sock, data);
|
memcpy(&tmpbuf,data,len);
|
||||||
|
jobmap[CANARY_num] = std::pair<PhySocket*, void*>(sock, tmpbuf);
|
||||||
|
|
||||||
}
|
}
|
||||||
write(_phy.getDescriptor(sock), "z", 1); // RPC ACK byte to maintain order
|
int nwrit = write(_phy.getDescriptor(sock), "z", 1); // RPC ACK byte to maintain order
|
||||||
}
|
}
|
||||||
// STREAM
|
// STREAM
|
||||||
else {
|
else {
|
||||||
@@ -417,7 +415,6 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
|
|||||||
foundJob = true;
|
foundJob = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = getConnection(sock);
|
conn = getConnection(sock);
|
||||||
if(!conn)
|
if(!conn)
|
||||||
return;
|
return;
|
||||||
@@ -451,21 +448,9 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write data from stream
|
// Write data from stream
|
||||||
if(wlen) {
|
if(wlen) {
|
||||||
/*
|
|
||||||
if(conn->type == SOCK_STREAM) { // We only disable TCP "connections"
|
|
||||||
int softmax = conn->type == SOCK_STREAM ? DEFAULT_TCP_RX_BUF_SZ : DEFAULT_UDP_RX_BUF_SZ;
|
|
||||||
if(conn->txsz > softmax) {
|
|
||||||
_phy.setNotifyReadable(sock, false);
|
|
||||||
conn->disabled = true;
|
|
||||||
}
|
|
||||||
else if (conn->disabled) {
|
|
||||||
conn->disabled = false;
|
|
||||||
_phy.setNotifyReadable(sock, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
conn->txsz += wlen;
|
conn->txsz += wlen;
|
||||||
handleWrite(conn);
|
handleWrite(conn);
|
||||||
}
|
}
|
||||||
@@ -475,7 +460,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
|
|||||||
rpcSock = sockdata.first;
|
rpcSock = sockdata.first;
|
||||||
buf = (unsigned char*)sockdata.second;
|
buf = (unsigned char*)sockdata.second;
|
||||||
unloadRPC(buf, pid, tid, timestamp, CANARY, cmd, payload);
|
unloadRPC(buf, pid, tid, timestamp, CANARY, cmd, payload);
|
||||||
// DEBUG_EXTRA(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", sock, pid, tid, timestamp, cmd);
|
//DEBUG_ERROR(" RPC: physock=%p, (pid=%d, tid=%d, timestamp=%s, cmd=%d)", sock, pid, tid, timestamp, cmd);
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
case RPC_BIND:
|
case RPC_BIND:
|
||||||
//DEBUG_INFO("RPC_BIND, physock=%p", sock);
|
//DEBUG_INFO("RPC_BIND, physock=%p", sock);
|
||||||
@@ -509,12 +494,12 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data,
|
|||||||
jobmap.erase(CANARY_num);
|
jobmap.erase(CANARY_num);
|
||||||
return; // Keep open RPC, we'll use it once in nc_connected to send retval
|
return; // Keep open RPC, we'll use it once in nc_connected to send retval
|
||||||
default:
|
default:
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Mutex::Lock _l(_tcpconns_m);
|
Mutex::Lock _l(_tcpconns_m);
|
||||||
closeConnection(sockdata.first); // close RPC after sending retval, no longer needed
|
closeConnection(sockdata.first); // close RPC after sending retval, no longer needed
|
||||||
jobmap.erase(CANARY_num);
|
jobmap.erase(CANARY_num);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,7 +537,6 @@ void NetconEthernetTap::handleGetpeername(PhySocket *sock, PhySocket *rpcSock, v
|
|||||||
|
|
||||||
Connection * NetconEthernetTap::handleSocket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc)
|
Connection * NetconEthernetTap::handleSocket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc)
|
||||||
{
|
{
|
||||||
DEBUG_ATTN("physock=%p, sock_type=%d", sock, socket_rpc->socket_type);
|
|
||||||
#if defined(SDK_PICOTCP)
|
#if defined(SDK_PICOTCP)
|
||||||
return pico_handleSocket(sock, uptr, socket_rpc);
|
return pico_handleSocket(sock, uptr, socket_rpc);
|
||||||
#endif
|
#endif
|
||||||
@@ -574,7 +558,6 @@ int NetconEthernetTap::handleConnectProxy(PhySocket *sock, struct sockaddr_in *r
|
|||||||
// Connect a stack's PCB/socket/Connection object to a remote host
|
// Connect a stack's PCB/socket/Connection object to a remote host
|
||||||
void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc)
|
void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc)
|
||||||
{
|
{
|
||||||
//DEBUG_ATTN("physock=%p", sock);
|
|
||||||
Mutex::Lock _l(_tcpconns_m);
|
Mutex::Lock _l(_tcpconns_m);
|
||||||
#if defined(SDK_PICOTCP)
|
#if defined(SDK_PICOTCP)
|
||||||
pico_handleConnect(sock, rpcSock, conn, connect_rpc);
|
pico_handleConnect(sock, rpcSock, conn, connect_rpc);
|
||||||
|
|||||||
Reference in New Issue
Block a user