diff options
author | Joseph Henry <joseph.henry@zerotier.com> | 2015-10-12 16:38:08 -0400 |
---|---|---|
committer | Joseph Henry <joseph.henry@zerotier.com> | 2015-10-12 16:38:08 -0400 |
commit | 6b1a38f14c6d30510d3332039accdc43b5bd5032 (patch) | |
tree | 4e1fcdc2af4a7a15184c46488852a21d061963de /netcon | |
parent | fe8e7ded8ca4693a445e0f3f46de932c88c5deaa (diff) | |
download | infinitytier-6b1a38f14c6d30510d3332039accdc43b5bd5032.tar.gz infinitytier-6b1a38f14c6d30510d3332039accdc43b5bd5032.zip |
Better retval+errno handling
Diffstat (limited to 'netcon')
-rw-r--r-- | netcon/NetconEthernetTap.cpp | 33 | ||||
-rwxr-xr-x | netcon/intercept.c | 57 | ||||
-rwxr-xr-x | netcon/libintercept.so.1.0 | bin | 0 -> 51688 bytes |
3 files changed, 50 insertions, 40 deletions
diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp index 1e74084f..276d481a 100644 --- a/netcon/NetconEthernetTap.cpp +++ b/netcon/NetconEthernetTap.cpp @@ -447,13 +447,13 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns */ int NetconEthernetTap::send_return_value(TcpConnection *conn, int retval, int _errno = 0) { - char retmsg[sizeof(retval) + sizeof(_errno)]; + int sz = sizeof(char) + sizeof(retval) + sizeof(errno); + char retmsg[sz]; memset(&retmsg, '\0', sizeof(retmsg)); retmsg[0]=RPC_RETVAL; - memcpy(&retmsg[1], &retval, sizeof(retval)); + memcpy(&retmsg[1], &retval, sizeof(retval)); memcpy(&retmsg[1]+sizeof(retval), &_errno, sizeof(_errno)); - fprintf(stderr, "errno = %d\n", _errno); - int n = write(_phy.getDescriptor(conn->rpcSock), &retmsg, sizeof(retmsg)); + int n = write(_phy.getDescriptor(conn->rpcSock), &retmsg, sz); if(n > 0) conn->pending = false; else { @@ -695,8 +695,8 @@ err_t NetconEthernetTap::nc_connected(void *arg, struct tcp_pcb *tpcb, err_t err [ ] EACCES - The address is protected, and the user is not the superuser. [X] EADDRINUSE - The given address is already in use. - [ ] EBADF - sockfd is not a valid descriptor. - [ ] EINVAL - The socket is already bound to an address. + [X] EBADF - sockfd is not a valid descriptor. + [X] EINVAL - The socket is already bound to an address. [ ] ENOTSOCK - sockfd is a descriptor for a file, not a socket. [ ] The following errors are specific to UNIX domain (AF_UNIX) sockets: [ ] EACCES - Search permission is denied on a component of the path prefix. (See also path_resolution(7).) @@ -704,16 +704,15 @@ err_t NetconEthernetTap::nc_connected(void *arg, struct tcp_pcb *tpcb, err_t err [ ] EFAULT - addr points outside the user's accessible address space. [ ] EINVAL - The addrlen is wrong, or the socket was not in the AF_UNIX family. [ ] ELOOP - Too many symbolic links were encountered in resolving addr. - [ ] ENAMETOOLONG -s addr is too long. + [ ] ENAMETOOLONG - s addr is too long. [ ] ENOENT - The file does not exist. - [ ] ENOMEM - Insufficient kernel memory was available. + [X] ENOMEM - Insufficient kernel memory was available. [ ] ENOTDIR - A component of the path prefix is not a directory. [ ] EROFS - The socket inode would reside on a read-only file system. */ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st *bind_rpc) { - int _errno; struct sockaddr_in *connaddr; connaddr = (struct sockaddr_in *) &bind_rpc->addr; int conn_port = lwipstack->ntohs(connaddr->sin_port); @@ -725,11 +724,6 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st if(conn) { if(conn->pcb->state == CLOSED){ int err = lwipstack->tcp_bind(conn->pcb, &conn_addr, conn_port); - send_return_value(conn, err, -99); - if(err == ERR_USE) { - _errno = EADDRINUSE; - send_return_value(conn, err, -99); - } if(err != ERR_OK) { int ip = connaddr->sin_addr.s_addr; unsigned char d[4]; @@ -738,11 +732,20 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st 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); - } + if(err == ERR_USE) + send_return_value(conn, -1, EADDRINUSE); + if(err == ERR_MEM) + send_return_value(conn, -1, ENOMEM); + } + else { + send_return_value(conn, ERR_OK, 0); // OK + } } else fprintf(stderr, "handle_bind(): PCB not in CLOSED state. Ignoring BIND request.\n"); + send_return_value(conn, -1, EINVAL); } else fprintf(stderr, "handle_bind(): can't locate connection for PCB\n"); + send_return_value(conn, -1, EBADF); } /* diff --git a/netcon/intercept.c b/netcon/intercept.c index d7caf101..b3e91905 100755 --- a/netcon/intercept.c +++ b/netcon/intercept.c @@ -139,6 +139,11 @@ static char* af_sock_name = "/tmp/.ztnc_e5cd7a9e1c5311ab"; static int thispid; +/* +* +* Check for forking +* +*/ int checkpid() { if(thispid != getpid()) { printf("clone/fork detected. re-initializing this instance.\n"); @@ -149,6 +154,31 @@ int checkpid() { return 0; } +/* +* +* Reads a return value from the service and sets errno (if applicable) +* +*/ +int get_retval() +{ + if(fdret_sock >= 0) { + int retval; + int sz = sizeof(char) + sizeof(retval) + sizeof(errno); + char retbuf[BUF_SZ]; + memset(&retbuf, '\0', sz); + int n_read = read(fdret_sock, &retbuf, sz); + if(n_read > 0) { + memcpy(&retval, &retbuf[1], sizeof(retval)); + memcpy(&errno, &retbuf[1+sizeof(retval)], sizeof(errno)); + return retval; + } + else { + dwr("unable to read connect: return value\n"); + return -1; + } + } +} + #define SLEEP_TIME 0 /*------------------------------------------------------------------------------ @@ -474,7 +504,6 @@ int socket(SOCKET_SIG) { #ifdef DUMMY dwr("socket(fam=%d, type=%d, prot=%d)\n", socket_family, socket_type, protocol); - //usleep(DUMMY_WAIT); return realsocket(socket_family, socket_type, protocol); #else @@ -676,33 +705,11 @@ int bind(BIND_SIG) write(fdret_sock, cmd, BUF_SZ); pthread_mutex_unlock(&lock); - /* - If we successfully wrote the RPC, try to read a return value - - Also get errno value - */ - if(fdret_sock >= 0) { - int retval; - int _errno; - char mynewbuf[BUF_SZ]; - memset(&mynewbuf, '\0', sizeof(mynewbuf)); - int n_read = read(fdret_sock, &mynewbuf, sizeof(mynewbuf)); - if(n_read > 0) { - memcpy(&retval, &mynewbuf[1], sizeof(retval)); - memcpy(&_errno, &mynewbuf[1]+sizeof(retval), sizeof(_errno)); - dwr("errno = %d\n", _errno); - errno = _errno; - pthread_mutex_unlock(&lock); - return retval; - } - else { - pthread_mutex_unlock(&lock); - dwr("unable to read connect: return value\n"); - } - } - return 0; /* FIXME: get real return value */ + return get_retval(); #endif } + /*------------------------------------------------------------------------------ ----------------------------------- accept4() ---------------------------------- ------------------------------------------------------------------------------*/ diff --git a/netcon/libintercept.so.1.0 b/netcon/libintercept.so.1.0 Binary files differnew file mode 100755 index 00000000..f4034ee2 --- /dev/null +++ b/netcon/libintercept.so.1.0 |