From 96eb0ce49262b5a8a7a99993733d52dbcf135f01 Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Thu, 29 Oct 2015 17:57:59 -0700 Subject: Added state dump, fixed numerous RPC related bugs --- netcon/NetconEthernetTap.cpp | 278 +++++++++++++++++++++++++++++-------------- 1 file changed, 187 insertions(+), 91 deletions(-) (limited to 'netcon/NetconEthernetTap.cpp') diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp index a50eb30e..dd49a186 100644 --- a/netcon/NetconEthernetTap.cpp +++ b/netcon/NetconEthernetTap.cpp @@ -49,9 +49,11 @@ #include "Intercept.h" #include "NetconUtilities.hpp" +#include + #define APPLICATION_POLL_FREQ 20 #define ZT_LWIP_TCP_TIMER_INTERVAL 10 -#define STATUS_TMR_INTERVAL 2000 // How often we check connection statuses +#define STATUS_TMR_INTERVAL 100 // How often we check connection statuses namespace ZeroTier { @@ -85,6 +87,7 @@ NetconEthernetTap::NetconEthernetTap( lwipstack->lwip_init(); _unixListenSocket = _phy.unixListen(sockPath,(void *)this); + dwr(" NetconEthernetTap(): RPC listening on: %d\n", _phy.getDescriptor(_unixListenSocket)); if (!_unixListenSocket) throw std::runtime_error(std::string("unable to bind to ")+sockPath); _thread = Thread::start(this); @@ -184,7 +187,7 @@ void NetconEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType // First pbuf gets ethernet header at start q = p; if (q->len < sizeof(ethhdr)) { - fprintf(stderr,"_put(): Dropped packet: first pbuf smaller than ethernet header\n"); + dwr("_put(): Dropped packet: first pbuf smaller than ethernet header\n"); return; } memcpy(q->payload,ðhdr,sizeof(ethhdr)); @@ -197,14 +200,14 @@ void NetconEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType dataptr += q->len; } } else { - fprintf(stderr, "_put(): Dropped packet: no pbufs available\n"); + dwr("_put(): Dropped packet: no pbufs available\n"); return; } { Mutex::Lock _l2(lwipstack->_lock); if(interface.input(p, &interface) != ERR_OK) { - fprintf(stderr, "_put(): Error while RXing packet (netif->input)\n"); + dwr("_put(): Error while RXing packet (netif->input)\n"); } } } @@ -243,22 +246,84 @@ void NetconEthernetTap::scanMulticastGroups(std::vector &added,s _multicastGroups.swap(newGroups); } -TcpConnection *NetconEthernetTap::getConnectionByPCB(struct tcp_pcb *pcb) +TcpConnection *NetconEthernetTap::getConnectionByTheirFD(PhySocket *sock, int fd) { for(size_t i=0; ipcb == pcb) + if(tcp_connections[i]->perceived_fd == fd && tcp_connections[i]->rpcSock == sock) return tcp_connections[i]; } return NULL; } -TcpConnection *NetconEthernetTap::getConnectionByTheirFD(PhySocket *sock, int fd) +/* + * Dumps service state in 80x25 when debug mode is off + */ +void NetconEthernetTap::compact_dump() { - for(size_t i=0; iperceived_fd == fd && tcp_connections[i]->rpcSock == sock) - return tcp_connections[i]; + /* + //clearscreen(); + refresh(); + clear(); + gotoxy(0,0); + fprintf(stderr, "ZeroTier - Network Containers Service [State Dump]\n\r"); + fprintf(stderr, " RPC Sockets = %d\n\r", rpc_sockets.size()); + fprintf(stderr, " TCP Connections = %d\n\r", tcp_connections.size()); + */ +} + +/* + * Dumps service state + */ +void NetconEthernetTap::dump() +{ + clearscreen(); + gotoxy(0,0); + fprintf(stderr, "\n\n---\n\ndie(): BEGIN SERVICE STATE DUMP\n"); + fprintf(stderr, "*** IF YOU SEE THIS, EMAIL THE DUMP TEXT TO joseph.henry@zerotier.com ***\n"); + fprintf(stderr, " tcp_conns = %d, rpc_socks = %d\n", tcp_connections.size(), rpc_sockets.size()); + + // TODO: Add logic to detect bad mapping conditions + for(size_t i=0; ipid); + if(tcp_connections[j]->rpcSock==rpc_sockets[i]){ + fprintf(stderr, " |\n"); + fprintf(stderr, " | Connection(0x%x):\n", tcp_connections[j]); + fprintf(stderr, " | path\t\t\t= %s\n", buf); + fprintf(stderr, " | perceived_fd\t\t= %d\t(fd)\n", tcp_connections[j]->perceived_fd); + fprintf(stderr, " | their_fd\t\t= %d\t(fd)\n", tcp_connections[j]->their_fd); + fprintf(stderr, " | dataSock(0x%x)\t= %d\t(fd)\n", tcp_connections[j]->dataSock, _phy.getDescriptor(tcp_connections[j]->dataSock)); + fprintf(stderr, " | rpcSock(0x%x)\t= %d\t(fd)\n", tcp_connections[j]->rpcSock, _phy.getDescriptor(tcp_connections[j]->rpcSock)); + fprintf(stderr, " | pending\t\t= %d\n", tcp_connections[j]->pending); + fprintf(stderr, " | listening\t\t= %d\n", tcp_connections[j]->listening); + fprintf(stderr, " \\------pcb(0x%x)->state\t= %d\n", tcp_connections[j]->pcb, tcp_connections[j]->pcb->state); + } + } + } + fprintf(stderr, "\n\ndie(): END SERVICE STATE DUMP\n\n---\n\n"); +} + +/* + * Dumps service state and then exits + */ +void NetconEthernetTap::die(int exret) { + dump(); + exit(exret); } /* @@ -266,7 +331,7 @@ TcpConnection *NetconEthernetTap::getConnectionByTheirFD(PhySocket *sock, int fd */ void NetconEthernetTap::closeConnection(TcpConnection *conn) { - fprintf(stderr, "closeConnection(%x, %d)\n", conn->pcb, _phy.getDescriptor(conn->dataSock)); + fprintf(stderr, " closeConnection(%x, %d)\n", conn->pcb, _phy.getDescriptor(conn->dataSock)); //lwipstack->_tcp_sent(conn->pcb, NULL); //lwipstack->_tcp_recv(conn->pcb, NULL); @@ -319,6 +384,7 @@ void NetconEthernetTap::closeAll() void NetconEthernetTap::threadMain() throw() { + //initscr(); //signal(SIGPIPE, SIG_IGN); uint64_t prev_tcp_time = 0; uint64_t prev_status_time = 0; @@ -345,7 +411,6 @@ void NetconEthernetTap::threadMain() // Main timer loop while (_run) { uint64_t now = OSUtils::now(); - uint64_t since_tcp = now - prev_tcp_time; uint64_t since_etharp = now - prev_etharp_time; uint64_t since_status = now - prev_status_time; @@ -353,9 +418,13 @@ void NetconEthernetTap::threadMain() uint64_t etharp_remaining = ARP_TMR_INTERVAL; uint64_t status_remaining = STATUS_TMR_INTERVAL; + // Connection prunning if (since_status >= STATUS_TMR_INTERVAL) { + //compact_dump(); prev_status_time = now; if(rpc_sockets.size() || tcp_connections.size()) { + + //dump(); /* Here we will periodically check the list of rpc_sockets for those that do not currently have any data connection associated with them. If they are unused, then we will try to read from them, if they fail, we can safely assume @@ -368,14 +437,14 @@ void NetconEthernetTap::threadMain() } else { // Here we should handle the case there there is incoming data (?) - fprintf(stderr, "Listening socketpair closed. Removing RPC connection (%d)\n", + dwr(" tap_thread(): Listening socketpair closed. Removing RPC connection (%d)\n", _phy.getDescriptor(tcp_connections[i]->dataSock)); closeConnection(tcp_connections[i]); } } } } - fprintf(stderr, "tcp_conns = %d, rpc_socks = %d\n", tcp_connections.size(), rpc_sockets.size()); + dwr(" tap_thread(): tcp_conns = %d, rpc_socks = %d\n", tcp_connections.size(), rpc_sockets.size()); for(size_t i=0, associated = 0; irpcSock == rpc_sockets[i]) @@ -383,20 +452,26 @@ void NetconEthernetTap::threadMain() } if(!associated){ // No TCP connections are associated, this is a candidate for removal + int fd = _phy.getDescriptor(rpc_sockets[i]); + fcntl(fd, F_SETFL, O_NONBLOCK); unsigned char tmpbuf[BUF_SZ]; - if(read(_phy.getDescriptor(rpc_sockets[i]),&tmpbuf,BUF_SZ) < 0) { - fprintf(stderr, "run() ---> RPC close(%d)\n", _phy.getDescriptor(rpc_sockets[i])); + int n; + if((n = read(fd,&tmpbuf,BUF_SZ)) < 0) { + dwr(" tap_thread(): RPC close(%d)\n", _phy.getDescriptor(rpc_sockets[i])); closeClient(rpc_sockets[i]); } - else { + // < 0 is failure + // 0 nothing to read, RPC still active + // > 0 RPC data read, handle it + else if (n > 0) { // Handle RPC call, this is rare - fprintf(stderr, "run(): RPC read during connection check\n"); - exit(0); // FIXME: This should be addressed - Raise APPLICATION_POLL_FREQ to make it less likely - phyOnUnixData(rpc_sockets[i],NULL,&tmpbuf,BUF_SZ); + dwr(" tap_thread(): RPC read during connection check (%d bytes)\n", n); + phyOnUnixData(rpc_sockets[i],_phy.getuptr(rpc_sockets[i]),&tmpbuf,BUF_SZ); } } } } + // Main TCP/ETHARP timer section if (since_tcp >= ZT_LWIP_TCP_TIMER_INTERVAL) { prev_tcp_time = now; lwipstack->tcp_tmr(); @@ -444,7 +519,7 @@ void NetconEthernetTap::phyOnFileDescriptorActivity(PhySocket *sock,void **uptr, } } else { - fprintf(stderr, "phyOnFileDescriptorActivity(): PhySocket not readable\n"); + dwr("phyOnFileDescriptorActivity(): PhySocket not readable\n"); } } @@ -452,6 +527,11 @@ void NetconEthernetTap::phyOnFileDescriptorActivity(PhySocket *sock,void **uptr, * Add a new PhySocket for the client connection */ void NetconEthernetTap::phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN) { + if(find(rpc_sockets.begin(), rpc_sockets.end(), sockN) != rpc_sockets.end()){ + dwr("SockN (0x%x) already exists!\n", sockN); + return; + } + dwr("phyOnUnixAccept(): push_back( 0x%x )\n", sockN); rpc_sockets.push_back(sockN); } @@ -464,42 +544,63 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns switch(buf[0]) { case RPC_SOCKET: - fprintf(stderr, "RPC_SOCKET\n"); + dwr("RPC_SOCKET\n"); struct socket_st socket_rpc; - memcpy(&socket_rpc, &buf[1], sizeof(struct socket_st)); - handle_socket(sock, uptr, &socket_rpc); + pid_t pid; + memcpy(&pid, &buf[1], sizeof(pid_t)); // PID for client RPC tracking (only for debug) + memcpy(&socket_rpc, &buf[64], sizeof(struct socket_st)); + if(handle_socket(sock, uptr, &socket_rpc) >= 0) { + fprintf(stderr, "pidmap[...] = %d\n", pid); + pidmap[sock] = pid; + } break; case RPC_LISTEN: - fprintf(stderr, "RPC_LISTEN\n"); + dwr("RPC_LISTEN\n"); struct listen_st listen_rpc; memcpy(&listen_rpc, &buf[1], sizeof(struct listen_st)); handle_listen(sock, uptr, &listen_rpc); break; case RPC_BIND: - fprintf(stderr, "RPC_BIND\n"); + dwr("RPC_BIND\n"); struct bind_st bind_rpc; memcpy(&bind_rpc, &buf[1], sizeof(struct bind_st)); handle_bind(sock, uptr, &bind_rpc); break; case RPC_CONNECT: - fprintf(stderr, "RPC_CONNECT\n"); + dwr("RPC_CONNECT\n"); struct connect_st connect_rpc; memcpy(&connect_rpc, &buf[1], sizeof(struct connect_st)); handle_connect(sock, uptr, &connect_rpc); break; case RPC_MAP: - fprintf(stderr, "RPC_MAP\n"); + dwr("RPC_MAP\n"); handle_retval(sock, uptr, buf); break; case RPC_MAP_REQ: - fprintf(stderr, "RPC_MAP_REQ\n"); + dwr("RPC_MAP_REQ\n"); handle_map_request(sock, uptr, buf); break; + case RPC_I_AM: + dwr("RPC_I_AM\n"); + handle_i_am(sock, uptr, buf); + break; default: break; } } + +void NetconEthernetTap::handle_i_am(PhySocket *sock, void **uptr, unsigned char* buf) +{ + TcpConnection *conn = (TcpConnection*)*uptr; + if(!conn) + return; + int pid; + memcpy(&pid, &buf[1], sizeof(pid)); + dwr(" pid = %d\n", pid); + conn->pid = pid; +} + /* * Send a 'retval' and 'errno' to the client for an RPC over connection->rpcSock */ @@ -510,7 +611,7 @@ int NetconEthernetTap::send_return_value(TcpConnection *conn, int retval, int _e if(n > 0) conn->pending = false; else { - fprintf(stderr, "Unable to send return value to the intercept. Closing connection\n"); + dwr("Unable to send return value to the intercept. Closing connection\n"); closeConnection(conn); } return n; @@ -579,7 +680,7 @@ int NetconEthernetTap::send_return_value(int fd, int retval, int _errno = 0) */ err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { - fprintf(stderr, "nc_accept()\n"); + dwr("nc_accept()\n"); Larg *l = (Larg*)arg; TcpConnection *conn = l->conn; NetconEthernetTap *tap = l->tap; @@ -590,7 +691,7 @@ err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err) if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) { if(errno < 0) { l->tap->send_return_value(conn, -1, errno); - fprintf(stderr, "nc_accept(): unable to create socketpair\n"); + dwr("nc_accept(): unable to create socketpair\n"); return ERR_MEM; } } @@ -600,12 +701,12 @@ err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err) new_tcp_conn->pcb = newpcb; new_tcp_conn->their_fd = fds[1]; tap->tcp_connections.push_back(new_tcp_conn); - fprintf(stderr, "socketpair = {%d, %d}\n", fds[0], fds[1]); + dwr("socketpair = {%d, %d}\n", fds[0], fds[1]); int n, send_fd = tap->_phy.getDescriptor(conn->rpcSock); - fprintf(stderr, "write(%d,...)\n", listening_fd); + dwr("write(%d,...)\n", listening_fd); //int n = write(listening_fd, "z", 1); // accept() in library waits for this byte if((n = send(listening_fd, "z", 1, MSG_NOSIGNAL)) < 0) { - fprintf(stderr, " nc_accept(): Error: [send(listening_fd,...) = MSG_NOSIGNAL].\n"); + dwr(" nc_accept(): Error: [send(listening_fd,...) = MSG_NOSIGNAL].\n"); return -1; } else if(n > 0) { @@ -614,11 +715,11 @@ err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err) new_tcp_conn->pending = true; } else { - fprintf(stderr, "nc_accept(%d): unable to send fd to client\n", listening_fd); + dwr("nc_accept(%d): unable to send fd to client\n", listening_fd); } } else { - fprintf(stderr, "nc_accept(%d): error writing signal byte (send_fd = %d, perceived_fd = %d)\n", listening_fd, send_fd, fds[1]); + dwr("nc_accept(%d): error writing signal byte (send_fd = %d, perceived_fd = %d)\n", listening_fd, send_fd, fds[1]); return -1; } tap->lwipstack->_tcp_arg(newpcb, new Larg(tap, new_tcp_conn)); @@ -630,7 +731,7 @@ err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err) return ERR_OK; } else { - fprintf(stderr, "nc_accept(%d): can't locate Connection object for PCB.\n", listening_fd); + dwr("nc_accept(%d): can't locate Connection object for PCB.\n", listening_fd); } return -1; } @@ -655,16 +756,16 @@ err_t NetconEthernetTap::nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf struct pbuf* q = p; if(!l->conn) { - fprintf(stderr, "nc_recved(): no connection object\n"); + dwr("nc_recved(): no connection object\n"); return ERR_OK; // ? } if(p == NULL) { if(l->conn) { - fprintf(stderr, "nc_recved(): closing connection\n"); + dwr("nc_recved(): closing connection\n"); l->tap->closeConnection(l->conn); } else { - fprintf(stderr, "nc_recved(): can't locate connection via (arg)\n"); + dwr("nc_recved(): can't locate connection via (arg)\n"); } return err; } @@ -674,12 +775,12 @@ err_t NetconEthernetTap::nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf break; // ? if((n = l->tap->_phy.streamSend(l->conn->dataSock,p->payload, p->len)) > 0) { if(n < p->len) { - fprintf(stderr, "nc_recved(): unable to write entire pbuf to buffer\n"); + dwr("nc_recved(): unable to write entire pbuf to buffer\n"); } l->tap->lwipstack->_tcp_recved(tpcb, n); // TODO: would it be more efficient to call this once at the end? } else { - fprintf(stderr, "nc_recved(): No data written to intercept buffer\n"); + dwr("nc_recved(): No data written to intercept buffer\n"); } p = p->next; } @@ -700,52 +801,50 @@ err_t NetconEthernetTap::nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf void NetconEthernetTap::nc_err(void *arg, err_t err) { Larg *l = (Larg*)arg; - //fprintf(stderr, "larg = %x, nc_err() = %d\n", l, err); - if(!l->conn) - fprintf(stderr, "nc_err(): Connection is NULL!\n"); + dwr("nc_err(): Connection is NULL!\n"); if(l->conn) { switch(err) { case ERR_MEM: - fprintf(stderr, "nc_err(): ERR_MEM->ENOMEM\n"); + dwr("nc_err(): ERR_MEM->ENOMEM\n"); l->tap->send_return_value(l->conn, -1, ENOMEM); break; case ERR_BUF: - fprintf(stderr, "nc_err(): ERR_BUF->ENOBUFS\n"); + dwr("nc_err(): ERR_BUF->ENOBUFS\n"); l->tap->send_return_value(l->conn, -1, ENOBUFS); break; case ERR_TIMEOUT: - fprintf(stderr, "nc_err(): ERR_TIMEOUT->ETIMEDOUT\n"); + dwr("nc_err(): ERR_TIMEOUT->ETIMEDOUT\n"); l->tap->send_return_value(l->conn, -1, ETIMEDOUT); break; case ERR_RTE: - fprintf(stderr, "nc_err(): ERR_RTE->ENETUNREACH\n"); + dwr("nc_err(): ERR_RTE->ENETUNREACH\n"); l->tap->send_return_value(l->conn, -1, ENETUNREACH); break; case ERR_INPROGRESS: - fprintf(stderr, "nc_err(): ERR_INPROGRESS->EINPROGRESS\n"); + dwr("nc_err(): ERR_INPROGRESS->EINPROGRESS\n"); l->tap->send_return_value(l->conn, -1, EINPROGRESS); break; case ERR_VAL: - fprintf(stderr, "nc_err(): ERR_VAL->EINVAL\n"); + dwr("nc_err(): ERR_VAL->EINVAL\n"); l->tap->send_return_value(l->conn, -1, EINVAL); break; case ERR_WOULDBLOCK: - fprintf(stderr, "nc_err(): ERR_WOULDBLOCK->EWOULDBLOCK\n"); + dwr("nc_err(): ERR_WOULDBLOCK->EWOULDBLOCK\n"); l->tap->send_return_value(l->conn, -1, EWOULDBLOCK); break; case ERR_USE: - fprintf(stderr, "nc_err(): ERR_USE->EADDRINUSE\n"); + dwr("nc_err(): ERR_USE->EADDRINUSE\n"); l->tap->send_return_value(l->conn, -1, EADDRINUSE); break; case ERR_ISCONN: - fprintf(stderr, "nc_err(): ERR_ISCONN->EISCONN\n"); + dwr("nc_err(): ERR_ISCONN->EISCONN\n"); l->tap->send_return_value(l->conn, -1, EISCONN); break; case ERR_ABRT: - fprintf(stderr, "nc_err(): ERR_ABRT->ECONNREFUSED\n"); + dwr("nc_err(): ERR_ABRT->ECONNREFUSED\n"); l->tap->send_return_value(l->conn, -1, ECONNREFUSED); break; @@ -769,11 +868,11 @@ void NetconEthernetTap::nc_err(void *arg, err_t err) default: break; } - fprintf(stderr, "nc_err(): closing connection\n"); + dwr("nc_err(): closing connection\n"); l->tap->closeConnection(l->conn); } else { - fprintf(stderr, "nc_err(): can't locate connection object for PCB\n"); + dwr("nc_err(): can't locate connection object for PCB\n"); } } @@ -788,11 +887,6 @@ void NetconEthernetTap::nc_err(void *arg, err_t err) err_t NetconEthernetTap::nc_poll(void* arg, struct tcp_pcb *tpcb) { //Larg *l = (Larg*)arg; - - - - - /* Larg *l = (Larg*)arg; TcpConnection *conn = l->conn; @@ -821,7 +915,7 @@ err_t NetconEthernetTap::nc_sent(void* arg, struct tcp_pcb *tpcb, u16_t len) //fprintf(stderr, " nc_sent()\n"); Larg *l = (Larg*)arg; if(len) { - fprintf(stderr, " nc_sent(): ACKING len = %d, setting read-notify = true, (sndbuf = %d)\n", len, l->conn->pcb->snd_buf); + //fprintf(stderr, " nc_sent(): ACKING len = %d, setting read-notify = true, (sndbuf = %d)\n", len, l->conn->pcb->snd_buf); l->tap->_phy.setNotifyReadable(l->conn->dataSock, true); l->tap->_phy.whack(); } @@ -840,7 +934,7 @@ err_t NetconEthernetTap::nc_sent(void* arg, struct tcp_pcb *tpcb, u16_t len) */ err_t NetconEthernetTap::nc_connected(void *arg, struct tcp_pcb *tpcb, err_t err) { - fprintf(stderr, "nc_connected()\n"); + dwr("nc_connected()\n"); Larg *l = (Larg*)arg; l->tap->send_return_value(l->conn, ERR_OK); return ERR_OK; @@ -864,13 +958,13 @@ void NetconEthernetTap::handle_map_request(PhySocket *sock, void **uptr, unsigne for(size_t i=0; irpcSock == conn->rpcSock && tcp_connections[i]->perceived_fd == req_fd){ send_return_value(conn, 1, ERR_OK); // True - fprintf(stderr, " handle_map_request(their=%d): MAPPED (to %d)\n", req_fd, + dwr(" handle_map_request(their=%d): MAPPED (to %d)\n", req_fd, _phy.getDescriptor(tcp_connections[i]->dataSock)); return; } } send_return_value(conn, 0, ERR_OK); // False - fprintf(stderr, " handle_map_request(their=%d): NOT MAPPED\n", req_fd); + dwr(" handle_map_request(their=%d): NOT MAPPED\n", req_fd); } /** @@ -891,7 +985,7 @@ void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, unsigned cha memcpy(&(conn->perceived_fd), &buf[1], sizeof(int)); conn->pending = false; - fprintf(stderr, " handle_retval(): CONN:%x - Mapping [our=%d -> their=%d]\n",conn, + dwr(" handle_retval(): CONN:%x - Mapping [our=%d -> their=%d]\n",conn, _phy.getDescriptor(conn->dataSock), conn->perceived_fd); /* Check for pre-existing connection for this socket --- @@ -908,12 +1002,12 @@ void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, unsigned cha if(tcp_connections[i]->perceived_fd == conn->perceived_fd) { int n; if((n = send(_phy.getDescriptor(tcp_connections[i]->dataSock), "z", 1, MSG_NOSIGNAL)) < 0) { - fprintf(stderr, " handle_retval(): CONN:%x - Socket (%d) already mapped (originally CONN:%x)\n", conn, tcp_connections[i]->perceived_fd, tcp_connections[i]); + dwr(" handle_retval(): CONN:%x - Socket (%d) already mapped (originally CONN:%x)\n", conn, tcp_connections[i]->perceived_fd, tcp_connections[i]); closeConnection(tcp_connections[i]); } else { - fprintf(stderr, " handle_retval(): CONN:%x - This socket is mapped to two different pipes (?). Exiting.\n", conn); - exit(0); + dwr(" handle_retval(): CONN:%x - This socket is mapped to two different pipes (?). Exiting.\n", conn); + die(0); // FIXME: Print service mapping state and exit } } } @@ -973,8 +1067,8 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st d[1] = (ip >> 8) & 0xFF; d[2] = (ip >> 16) & 0xFF; d[3] = (ip >> 24) & 0xFF; - fprintf(stderr, " handle_bind(): error binding to %d.%d.%d.%d : %d\n", d[0],d[1],d[2],d[3], conn_port); - fprintf(stderr, " handle_bind(): err = %d\n", err); + dwr(" handle_bind(): error binding to %d.%d.%d.%d : %d\n", d[0],d[1],d[2],d[3], conn_port); + dwr(" handle_bind(): err = %d\n", err); if(err == ERR_USE) send_return_value(conn, -1, EADDRINUSE); @@ -987,12 +1081,12 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st send_return_value(conn, ERR_OK, ERR_OK); // Success } else { - fprintf(stderr, " handle_bind(): PCB (%x) not in CLOSED state. Ignoring BIND request.\n", conn->pcb); + dwr(" handle_bind(): PCB (%x) not in CLOSED state. Ignoring BIND request.\n", conn->pcb); send_return_value(conn, -1, EINVAL); } } else { - fprintf(stderr, " handle_bind(): can't locate connection for PCB\n"); + dwr(" handle_bind(): can't locate connection for PCB\n"); send_return_value(conn, -1, EBADF); } } @@ -1018,17 +1112,17 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st */ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct listen_st *listen_rpc) { - fprintf(stderr, " handle_listen(their=%d):\n", listen_rpc->sockfd); + dwr(" handle_listen(their=%d):\n", listen_rpc->sockfd); TcpConnection *conn = getConnectionByTheirFD(sock, listen_rpc->sockfd); if(!conn){ - fprintf(stderr, " handle_listen(): unable to locate connection object\n"); + dwr(" handle_listen(): unable to locate connection object\n"); // ? send_return_value(conn, -1, EBADF); return; } - fprintf(stderr, " handle_listen(our=%d -> their=%d)\n", _phy.getDescriptor(conn->dataSock), conn->perceived_fd); + dwr(" handle_listen(our=%d -> their=%d)\n", _phy.getDescriptor(conn->dataSock), conn->perceived_fd); if(conn->pcb->state == LISTEN) { - fprintf(stderr, " handle_listen(): PCB is already in listening state.\n"); + dwr(" handle_listen(): PCB is already in listening state.\n"); return; } struct tcp_pcb* listening_pcb; @@ -1092,22 +1186,22 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste [?] EPROTONOSUPPORT - The protocol type or the specified protocol is not supported within this domain. */ -void NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc) +int NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc) { int rpc_fd = _phy.getDescriptor(sock); struct tcp_pcb *newpcb = lwipstack->tcp_new(); - fprintf(stderr, " handle_socket(): pcb=%x\n", newpcb); + dwr(" handle_socket(): pcb=%x\n", newpcb); if(newpcb != NULL) { ZT_PHY_SOCKFD_TYPE fds[2]; if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) { if(errno < 0) { send_return_value(rpc_fd, -1, errno); - return; + return -1; } } - fprintf(stderr, " handle_socket(): socketpair = {%d, %d}\n", fds[0], fds[1]); + dwr(" handle_socket(): socketpair = {%d, %d}\n", fds[0], fds[1]); TcpConnection *new_conn = new TcpConnection(); new_conn->dataSock = _phy.wrapSocket(fds[0], new_conn); *uptr = new_conn; @@ -1119,11 +1213,13 @@ void NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socke close(fds[1]); // close other end of socketpair // Once the client tells us what its fd is on the other end, we can then complete the mapping new_conn->pending = true; + return 0; } else { sock_fd_write(rpc_fd, -1); // Send a bad fd, to signal error - fprintf(stderr, " handle_socket(): Memory not available for new PCB\n"); + dwr(" handle_socket(): Memory not available for new PCB\n"); send_return_value(rpc_fd, -1, ENOMEM); + return -1; } } @@ -1224,14 +1320,14 @@ void NetconEthernetTap::handle_connect(PhySocket *sock, void **uptr, struct conn // that's it! // - Most instances of a retval for a connect() should happen // in the nc_connect() and nc_err() callbacks! - fprintf(stderr, " handle_connect(): unable to connect\n"); + dwr(" handle_connect(): unable to connect\n"); send_return_value(conn, -1, EAGAIN); } // Everything seems to be ok, but we don't have enough info to retval conn->pending=true; } else { - fprintf(stderr, " handle_connect(): could not locate PCB based on their fd\n"); + dwr(" handle_connect(): could not locate PCB based on their fd\n"); send_return_value(conn, -1, EBADF); } } @@ -1243,12 +1339,12 @@ void NetconEthernetTap::handle_write(TcpConnection *conn) int r; if(!conn) { - fprintf(stderr, " handle_write(): could not locate connection for this fd\n"); + dwr(" handle_write(): could not locate connection for this fd\n"); return; } if(conn->idx < max) { if(!conn->pcb) { - fprintf(stderr, " handle_write(): conn->pcb == NULL. Failed to write.\n"); + dwr(" handle_write(): conn->pcb == NULL. Failed to write.\n"); return; } int sndbuf = conn->pcb->snd_buf; // How much we are currently allowed to write to the connection @@ -1275,7 +1371,7 @@ void NetconEthernetTap::handle_write(TcpConnection *conn) int err = lwipstack->_tcp_write(conn->pcb, &conn->buf, r, TCP_WRITE_FLAG_COPY); lwipstack->_tcp_output(conn->pcb); if(err != ERR_OK) { - fprintf(stderr, " handle_write(): error while writing to PCB, (err = %d)\n", err); + dwr(" handle_write(): error while writing to PCB, (err = %d)\n", err); return; } else { @@ -1288,7 +1384,7 @@ void NetconEthernetTap::handle_write(TcpConnection *conn) } } else { - fprintf(stderr, " handle_write(): LWIP stack full\n"); + dwr(" handle_write(): LWIP stack full\n"); return; } } -- cgit v1.2.3