summaryrefslogtreecommitdiff
path: root/netcon
diff options
context:
space:
mode:
authorJoseph Henry <joseph.henry@zerotier.com>2015-10-12 16:38:08 -0400
committerJoseph Henry <joseph.henry@zerotier.com>2015-10-12 16:38:08 -0400
commit6b1a38f14c6d30510d3332039accdc43b5bd5032 (patch)
tree4e1fcdc2af4a7a15184c46488852a21d061963de /netcon
parentfe8e7ded8ca4693a445e0f3f46de932c88c5deaa (diff)
downloadinfinitytier-6b1a38f14c6d30510d3332039accdc43b5bd5032.tar.gz
infinitytier-6b1a38f14c6d30510d3332039accdc43b5bd5032.zip
Better retval+errno handling
Diffstat (limited to 'netcon')
-rw-r--r--netcon/NetconEthernetTap.cpp33
-rwxr-xr-xnetcon/intercept.c57
-rwxr-xr-xnetcon/libintercept.so.1.0bin0 -> 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
new file mode 100755
index 00000000..f4034ee2
--- /dev/null
+++ b/netcon/libintercept.so.1.0
Binary files differ