summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Henry <joseph.henry@zerotier.com>2015-09-10 20:02:13 -0400
committerJoseph Henry <joseph.henry@zerotier.com>2015-09-10 20:02:13 -0400
commit20beafedc5e62fdd1b6f7d93c735b7a17c4374bb (patch)
tree1f31dd145fa231567882f6ae1ae4468f62bc41c4
parent8d82ac5cc8826e2352e710c579a173f4b4309cd1 (diff)
downloadinfinitytier-20beafedc5e62fdd1b6f7d93c735b7a17c4374bb.tar.gz
infinitytier-20beafedc5e62fdd1b6f7d93c735b7a17c4374bb.zip
refactor almost complete
-rw-r--r--make-linux.mk4
-rwxr-xr-xnetcon/Intercept.h2
-rw-r--r--netcon/NetconEthernetTap.cpp77
-rw-r--r--netcon/NetconEthernetTap.hpp38
-rw-r--r--netcon/NetconService.hpp (renamed from netcon/NetconService.h)29
-rw-r--r--netcon/NetconUtilities.cpp223
-rw-r--r--netcon/NetconUtilities.hpp14
-rw-r--r--osdep/Phy.hpp2
8 files changed, 215 insertions, 174 deletions
diff --git a/make-linux.mk b/make-linux.mk
index 35e7c07e..e30f210c 100644
--- a/make-linux.mk
+++ b/make-linux.mk
@@ -75,7 +75,7 @@ ifeq ($(ZT_DEBUG),1)
DEFS+=-DZT_TRACE
CFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
CXXFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
- LDFLAGS=
+ LDFLAGS=-ldl
STRIP=echo
# The following line enables optimization for the crypto code, since
# C25519 in particular is almost UNUSABLE in -O0 even on a 3ghz box!
@@ -85,7 +85,7 @@ else
CFLAGS+=-Wall -fPIE -fvisibility=hidden -pthread $(INCLUDES) -DNDEBUG $(DEFS)
CXXFLAGS?=-O3 -fstack-protector
CXXFLAGS+=-Wall -fPIE -fvisibility=hidden -fno-rtti -pthread $(INCLUDES) -DNDEBUG $(DEFS)
- LDFLAGS=-pie -Wl,-z,relro,-z,now
+ LDFLAGS=-ldl -pie -Wl,-z,relro,-z,now
STRIP=strip --strip-all
endif
diff --git a/netcon/Intercept.h b/netcon/Intercept.h
index 97075dcb..30d118cf 100755
--- a/netcon/Intercept.h
+++ b/netcon/Intercept.h
@@ -175,6 +175,7 @@ struct shutdown_st
/* LWIP error beautification */
+/*
const char *lwiperror(int n)
{
switch(n)
@@ -215,5 +216,6 @@ const char *lwiperror(int n)
return "UNKNOWN_RET_VAL";
}
}
+*/
#endif
diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp
index 723a5f55..d3deb8ce 100644
--- a/netcon/NetconEthernetTap.cpp
+++ b/netcon/NetconEthernetTap.cpp
@@ -29,6 +29,8 @@
#include <algorithm>
#include <utility>
+#include <dlfcn.h>
+
#include "NetconEthernetTap.hpp"
@@ -43,7 +45,7 @@
#include "lwip/ip_frag.h"
#include "LWIPStack.hpp"
-#include "NetconService.h"
+#include "NetconService.hpp"
#include "Intercept.h"
#include "NetconUtilities.hpp"
@@ -114,6 +116,7 @@ bool NetconEthernetTap::addIp(const InetAddress &ip)
// TODO: alloc IP in LWIP
//netif_set_addr(netif, ipaddr, netmask, gw);
}
+ return true; // TODO: what is exapected?
}
bool NetconEthernetTap::removeIp(const InetAddress &ip)
@@ -194,7 +197,7 @@ NetconClient *NetconEthernetTap::getClientByPCB(struct tcp_pcb *pcb)
void NetconEthernetTap::closeClient(NetconClient *client)
{
// erase from clients vector
- client->close();
+ client->closeClient();
}
@@ -219,7 +222,7 @@ void NetconEthernetTap::threadMain()
unsigned long since_etharp;
struct timeval tv;
- struct timeval tv_sel;
+ //struct timeval tv_sel;
while (_run) {
gettimeofday(&tv, NULL);
@@ -267,7 +270,7 @@ void NetconEthernetTap::phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void *
void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr)
{
- ((NetconClient*)*uptr)->close();
+ ((NetconClient*)*uptr)->closeClient();
}
void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len)
@@ -313,7 +316,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns
handle_bind(client, &bind_rpc);
break;
case RPC_KILL_INTERCEPT:
- client->close();
+ client->closeClient();
break;
case RPC_CONNECT:
struct connect_st connect_rpc;
@@ -361,22 +364,17 @@ int NetconEthernetTap::send_return_value(NetconClient *client, int retval)
--------------------------------- LWIP callbacks -------------------------------
------------------------------------------------------------------------------*/
-err_t NetconEthernetTap::nc_poll(void* arg, struct tcp_pcb *tpcb)
-{
- NetconConnection *c = getConnectionByPCB(tpcb); // TODO: make sure this works, if not, use arg to look up the connection
- if(c)
- handle_write(c);
- return ERR_OK;
-}
-
err_t NetconEthernetTap::nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
+ Larg *l = (Larg*)arg;
+ NetconConnection *c = l->tap->getConnectionByPCB(tpcb);
+ NetconEthernetTap *tap = l->tap;
+
int n;
struct pbuf* q = p;
- NetconConnection *c = getConnectionByPCB(tpcb); // TODO: make sure this works, if not, use arg as "buf sock"
- int our_fd = _phy.getDescriptor(c->sock);
+ int our_fd = tap->_phy.getDescriptor(c->sock);
if(c) {
//dwr(c->owner->tid, "nc_recved(%d)\n", (intptr_t)arg);
@@ -386,47 +384,45 @@ err_t NetconEthernetTap::nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf
return ERR_OK; // ?
}
if(p == NULL) {
- //dwr(c->owner->tid, "nc_recved() = %s\n", lwiperror(err));
- if(c)
//dwr(c->owner->tid, "nc_recved()\n");
if(c) {
//dwr(c->owner->tid, "closing connection\n");
nc_close(tpcb);
close(our_fd); /* TODO: Check logic */
//nc_service->remove_connection(c);
- c->owner->close(c);
+ c->owner->closeConnection(c);
}
else {
- //dwr(-1, "can't locate connection via (arg)\n");
+ // can't locate connection via (arg)
}
return err;
}
q = p;
while(p != NULL) { // Cycle through pbufs and write them to the socket
- //dwr(c->owner->tid, "writing data to mapped sock (%d)\n", c->our_fd);
if(p->len <= 0)
break; // ?
if((n = write(our_fd, p->payload, p->len)) > 0) {
if(n < p->len) {
- //dwr(c->owner->tid, "ERROR: unable to write entire pbuf to buffer\n");
+ // ERROR: unable to write entire pbuf to buffer
}
- lwipstack->tcp_recved(tpcb, n);
+ tap->lwipstack->tcp_recved(tpcb, n);
}
else {
- //dwr(c->owner->tid, "ERROR: No data written to intercept buffer.\n");
+ // Error: No data written to intercept buffer
}
p = p->next;
}
- lwipstack->pbuf_free(q); /* free pbufs */
+ tap->lwipstack->pbuf_free(q); // free pbufs
return ERR_OK;
}
void NetconEthernetTap::nc_err(void *arg, err_t err)
{
- NetconConnection *c = getConnectionByThisFD((intptr)arg);
+ Larg *l = (Larg*)arg;
+ NetconEthernetTap *tap = l->tap;
+ NetconConnection *c = tap->getConnectionByThisFD(tap->_phy.getDescriptor(l->sock));
if(c) {
- //nc_service->remove_connection(c);
- c->owner->close(c);
+ c->owner->closeConnection(c);
//tcp_close(c->pcb);
}
else {
@@ -436,13 +432,14 @@ void NetconEthernetTap::nc_err(void *arg, err_t err)
void NetconEthernetTap::nc_close(struct tcp_pcb* tpcb)
{
- //NetconConnection *c = getConnectionByPCB(tpcb);
+ /*
lwipstack->tcp_arg(tpcb, NULL);
lwipstack->tcp_sent(tpcb, NULL);
lwipstack->tcp_recv(tpcb, NULL);
lwipstack->tcp_err(tpcb, NULL);
lwipstack->tcp_poll(tpcb, NULL, 0);
lwipstack->tcp_close(tpcb);
+ */
}
err_t NetconEthernetTap::nc_send(struct tcp_pcb *tpcb)
@@ -452,17 +449,17 @@ err_t NetconEthernetTap::nc_send(struct tcp_pcb *tpcb)
err_t NetconEthernetTap::nc_sent(void* arg, struct tcp_pcb *tpcb, u16_t len)
{
- //NetconConnection *c = _phy->getConnectionByPCB(tpcb);
- //if(c)
- //c->data_sent += len;
return len;
}
err_t NetconEthernetTap::nc_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
{
- for(int i=0; i<clients.size(); i++) {
- if(clients[i].containsPCB(tpcb)) {
- send_return_value(clients[i],err);
+ Larg *l = (Larg*)arg;
+ NetconEthernetTap *tap = l->tap;
+
+ for(size_t i=0; i<tap->clients.size(); i++) {
+ if(tap->clients[i]->containsPCB(tpcb)) {
+ tap->send_return_value(tap->clients[i],err);
}
}
return err;
@@ -481,14 +478,16 @@ void NetconEthernetTap::handle_bind(NetconClient *client, struct bind_st *bind_r
ip_addr_t conn_addr;
IP4_ADDR(&conn_addr, 192,168,0,2);
+ /*
int ip = connaddr->sin_addr.s_addr;
unsigned char bytes[4];
bytes[0] = ip & 0xFF;
bytes[1] = (ip >> 8) & 0xFF;
bytes[2] = (ip >> 16) & 0xFF;
bytes[3] = (ip >> 24) & 0xFF;
- // "binding to: %d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]
- NetconConnection *c = client->getConnectionByTheirFD(bind_rpc->sockfd);
+ "binding to: %d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]
+ */
+ NetconConnection *c = client->getConnectionByTheirFD(bind_rpc->sockfd);
if(c) {
if(c->pcb->state == CLOSED){
int err = lwipstack->tcp_bind(c->pcb, &conn_addr, conn_port);
@@ -520,8 +519,7 @@ void NetconEthernetTap::handle_listen(NetconClient *client, struct listen_st *li
if(listening_pcb != NULL) {
c->pcb = listening_pcb;
lwipstack->tcp_accept(listening_pcb, nc_accept);
- int our_fd = _phy.getDescriptor(c->sock);
- lwipstack->tcp_arg(listening_pcb, (void*)(intptr_t)our_fd);
+ lwipstack->tcp_arg(listening_pcb, new Larg(this, c->sock));
client->waiting_for_retval=true;
}
else {
@@ -565,14 +563,13 @@ void NetconEthernetTap::handle_connect(NetconClient *client, struct connect_st*
int conn_port = lwipstack->ntohs(connaddr->sin_port);
ip_addr_t conn_addr = convert_ip((struct sockaddr_in *)&connect_rpc->__addr);
NetconConnection *c = client->getConnectionByTheirFD(connect_rpc->__fd);
- int our_fd = _phy.getDescriptor(c->sock);
if(c!= NULL) {
lwipstack->tcp_sent(c->pcb, nc_sent); // FIXME: Move?
lwipstack->tcp_recv(c->pcb, nc_recved);
lwipstack->tcp_err(c->pcb, nc_err);
lwipstack->tcp_poll(c->pcb, nc_poll, APPLICATION_POLL_FREQ);
- lwipstack->tcp_arg(c->pcb,(void*)(intptr_t)our_fd);
+ lwipstack->tcp_arg(c->pcb, new Larg(this, c->sock));
int err = 0;
if((err = lwipstack->tcp_connect(c->pcb,&conn_addr,conn_port, nc_connected)) < 0)
diff --git a/netcon/NetconEthernetTap.hpp b/netcon/NetconEthernetTap.hpp
index c79a11c0..3eb39eb6 100644
--- a/netcon/NetconEthernetTap.hpp
+++ b/netcon/NetconEthernetTap.hpp
@@ -44,7 +44,8 @@
#include "../osdep/Thread.hpp"
#include "../osdep/Phy.hpp"
-#include "NetconService.h"
+#include "NetconService.hpp"
+#include "NetconUtilities.hpp"
namespace ZeroTier {
@@ -84,6 +85,15 @@ public:
throw();
private:
+
+ // RPC handlers (from NetconIntercept)
+ void handle_bind(NetconClient *client, struct bind_st *bind_rpc);
+ void handle_listen(NetconClient *client, struct listen_st *listen_rpc);
+ void handle_retval(NetconClient *client, unsigned char* buf);
+ void handle_socket(NetconClient *client, struct socket_st* socket_rpc);
+ void handle_connect(NetconClient *client, struct connect_st* connect_rpc);
+ void handle_write(NetconConnection *c);
+
void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *from,void *data,unsigned long len);
void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success);
void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from);
@@ -95,10 +105,26 @@ private:
void phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len);
void phyOnUnixWritable(PhySocket *sock,void **uptr);
+ void phyOnSocketPairEndpointClose(void *sock, void **uptr);
+ void phyOnSocketPairEndpointData(PhySocket *sock, void **uptr, void *buf, unsigned long n);
+ void phyOnSocketPairEndpointWritable(PhySocket *sock, void **uptr);
+
+
+
int send_return_value(NetconClient *client, int retval);
// For LWIP Callbacks
- static err_t nc_poll(void *arg, struct tcp_pcb *tpcb);
+ static err_t nc_poll(void* arg, struct tcp_pcb *tpcb)
+ {
+ Larg *l = (Larg*)arg;
+ NetconConnection *c = l->tap->getConnectionByPCB(tpcb);
+ NetconEthernetTap *tap = l->tap;
+ if(c)
+ tap->handle_write(c);
+ return ERR_OK;
+ }
+
+
static err_t nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err);
static err_t nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);
static void nc_err(void *arg, err_t err);
@@ -107,13 +133,7 @@ private:
static err_t nc_sent(void *arg, struct tcp_pcb *tpcb, u16_t len);
static err_t nc_connected(void *arg, struct tcp_pcb *tpcb, err_t err);
- // RPC handlers (from NetconIntercept)
- void handle_bind(NetconClient *client, struct bind_st *bind_rpc);
- void handle_listen(NetconClient *client, struct listen_st *listen_rpc);
- void handle_retval(NetconClient *client, unsigned char* buf);
- void handle_socket(NetconClient *client, struct socket_st* socket_rpc);
- void handle_connect(NetconClient *client, struct connect_st* connect_rpc);
- void handle_write(NetconConnection *c);
+
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void *_arg;
diff --git a/netcon/NetconService.h b/netcon/NetconService.hpp
index 3ca37b11..93431f75 100644
--- a/netcon/NetconService.h
+++ b/netcon/NetconService.hpp
@@ -29,16 +29,29 @@
#include <string>
#include "../osdep/Phy.hpp"
+#include "NetconEthernetTap.hpp"
#include "Intercept.h"
#include "LWIPStack.hpp"
-#ifndef _NETCON_SERVICE_H_
-#define _NETCON_SERVICE_H_
+#ifndef _NETCON_SERVICE_HPP
+#define _NETCON_SERVICE_HPP
using namespace std;
namespace ZeroTier {
+
+ class NetconEthernetTap;
+
+ // Helper class for passing reference to Phy to LWIP callbacks
+ class Larg
+ {
+ public:
+ NetconEthernetTap *tap;
+ PhySocket *sock;
+ Larg(NetconEthernetTap *_tap, PhySocket *_sock) : tap(_tap), sock(_sock) {}
+ };
+
enum NetconConnectionType { RPC, BUFFER };
// prototypes
@@ -103,7 +116,7 @@ namespace ZeroTier {
NetconConnection *getConnectionByPCB(struct tcp_pcb *pcb)
{
for(size_t i=0; i<connections.size(); i++) {
- if(connections[i]->pcb = pcb) { return connections[i]; }
+ if(connections[i]->pcb == pcb) { return connections[i]; }
}
return NULL;
}
@@ -111,17 +124,23 @@ namespace ZeroTier {
NetconConnection *containsPCB(struct tcp_pcb *pcb)
{
for(size_t i=0; i<connections.size(); i++) {
- if(connections[i]->pcb = pcb) { return connections[i]; }
+ if(connections[i]->pcb == pcb) { return connections[i]; }
}
return NULL;
}
- void close()
+ void closeConnection(NetconConnection *c)
{
// close all connections
// -- pcb
// -- PhySocket
}
+
+ void closeClient()
+ {
+
+ }
};
} // namespace ZeroTier
+
#endif
diff --git a/netcon/NetconUtilities.cpp b/netcon/NetconUtilities.cpp
index 8f501ce2..bb870669 100644
--- a/netcon/NetconUtilities.cpp
+++ b/netcon/NetconUtilities.cpp
@@ -7,126 +7,127 @@
#ifndef _NETCON_UTILITIES_CPP
#define _NETCON_UTILITIES_CPP
-
-
-ip_addr_t convert_ip(struct sockaddr_in * addr)
+namespace ZeroTier
{
- ip_addr_t conn_addr;
- struct sockaddr_in *ipv4 = addr;
- short a = ip4_addr1(&(ipv4->sin_addr));
- short b = ip4_addr2(&(ipv4->sin_addr));
- short c = ip4_addr3(&(ipv4->sin_addr));
- short d = ip4_addr4(&(ipv4->sin_addr));
- IP4_ADDR(&conn_addr, a,b,c,d);
- return conn_addr;
-}
-
-ip_addr_t ip_addr_sin(register struct sockaddr_in *sin) {
- ip_addr_t ip;
- *((struct sockaddr_in*) &ip) = *sin;
- return ip;
-}
+ ip_addr_t convert_ip(struct sockaddr_in * addr)
+ {
+ ip_addr_t conn_addr;
+ struct sockaddr_in *ipv4 = addr;
+ short a = ip4_addr1(&(ipv4->sin_addr));
+ short b = ip4_addr2(&(ipv4->sin_addr));
+ short c = ip4_addr3(&(ipv4->sin_addr));
+ short d = ip4_addr4(&(ipv4->sin_addr));
+ IP4_ADDR(&conn_addr, a,b,c,d);
+ return conn_addr;
+ }
-// Functions used to pass file descriptors between processes
+ ip_addr_t ip_addr_sin(register struct sockaddr_in *sin) {
+ ip_addr_t ip;
+ *((struct sockaddr_in*) &ip) = *sin;
+ return ip;
+ }
-ssize_t sock_fd_write(int sock, int fd);
-ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd);
+ // Functions used to pass file descriptors between processes
-ssize_t sock_fd_write(int sock, int fd)
-{
- ssize_t size;
- struct msghdr msg;
- struct iovec iov;
- char buf = '\0';
- int buflen = 1;
+ ssize_t sock_fd_write(int sock, int fd);
+ ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd);
- union
+ ssize_t sock_fd_write(int sock, int fd)
{
- struct cmsghdr cmsghdr;
- char control[CMSG_SPACE(sizeof (int))];
- } cmsgu;
- struct cmsghdr *cmsg;
-
- iov.iov_base = &buf;
- iov.iov_len = buflen;
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- if (fd != -1) {
- msg.msg_control = cmsgu.control;
- msg.msg_controllen = sizeof(cmsgu.control);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_len = CMSG_LEN(sizeof (int));
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- *((int *) CMSG_DATA(cmsg)) = fd;
- } else {
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
+ ssize_t size;
+ struct msghdr msg;
+ struct iovec iov;
+ char buf = '\0';
+ int buflen = 1;
+
+ union
+ {
+ struct cmsghdr cmsghdr;
+ char control[CMSG_SPACE(sizeof (int))];
+ } cmsgu;
+ struct cmsghdr *cmsg;
+
+ iov.iov_base = &buf;
+ iov.iov_len = buflen;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ if (fd != -1) {
+ msg.msg_control = cmsgu.control;
+ msg.msg_controllen = sizeof(cmsgu.control);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_len = CMSG_LEN(sizeof (int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ *((int *) CMSG_DATA(cmsg)) = fd;
+ } else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
+
+ size = sendmsg(sock, &msg, 0);
+ if (size < 0)
+ perror ("sendmsg");
+ return size;
}
- size = sendmsg(sock, &msg, 0);
- if (size < 0)
- perror ("sendmsg");
- return size;
-}
-
-ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd)
-{
- ssize_t size;
-
- if (fd) {
- struct msghdr msg;
- struct iovec iov;
- union
- {
- struct cmsghdr cmsghdr;
- char control[CMSG_SPACE(sizeof (int))];
- } cmsgu;
- struct cmsghdr *cmsg;
-
- iov.iov_base = buf;
- iov.iov_len = bufsize;
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = cmsgu.control;
- msg.msg_controllen = sizeof(cmsgu.control);
- size = recvmsg (sock, &msg, 0);
- if (size < 0) {
- perror ("recvmsg");
- exit(1);
- }
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
- if (cmsg->cmsg_level != SOL_SOCKET) {
- fprintf (stderr, "invalid cmsg_level %d\n",
- cmsg->cmsg_level);
- exit(1);
- }
- if (cmsg->cmsg_type != SCM_RIGHTS) {
- fprintf (stderr, "invalid cmsg_type %d\n",
- cmsg->cmsg_type);
- exit(1);
- }
-
- *fd = *((int *) CMSG_DATA(cmsg));
- } else
- *fd = -1;
- } else {
- size = read (sock, buf, bufsize);
- if (size < 0) {
- perror("read");
- exit(1);
- }
- }
- return size;
+ ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd)
+ {
+ ssize_t size;
+
+ if (fd) {
+ struct msghdr msg;
+ struct iovec iov;
+ union
+ {
+ struct cmsghdr cmsghdr;
+ char control[CMSG_SPACE(sizeof (int))];
+ } cmsgu;
+ struct cmsghdr *cmsg;
+
+ iov.iov_base = buf;
+ iov.iov_len = bufsize;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsgu.control;
+ msg.msg_controllen = sizeof(cmsgu.control);
+ size = recvmsg (sock, &msg, 0);
+ if (size < 0) {
+ perror ("recvmsg");
+ exit(1);
+ }
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
+ if (cmsg->cmsg_level != SOL_SOCKET) {
+ fprintf (stderr, "invalid cmsg_level %d\n",
+ cmsg->cmsg_level);
+ exit(1);
+ }
+ if (cmsg->cmsg_type != SCM_RIGHTS) {
+ fprintf (stderr, "invalid cmsg_type %d\n",
+ cmsg->cmsg_type);
+ exit(1);
+ }
+
+ *fd = *((int *) CMSG_DATA(cmsg));
+ } else
+ *fd = -1;
+ } else {
+ size = read (sock, buf, bufsize);
+ if (size < 0) {
+ perror("read");
+ exit(1);
+ }
+ }
+ return size;
+ }
}
#endif
diff --git a/netcon/NetconUtilities.hpp b/netcon/NetconUtilities.hpp
index 56b0ed94..5ce062f3 100644
--- a/netcon/NetconUtilities.hpp
+++ b/netcon/NetconUtilities.hpp
@@ -2,10 +2,12 @@
#ifndef _NETCON_UTILITIES_H
#define _NETCON_UTILITIES_H
-ip_addr_t convert_ip(struct sockaddr_in * addr);
-ip_addr_t ip_addr_sin(register struct sockaddr_in *sin);
-
-ssize_t sock_fd_write(int sock, int fd);
-ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd);
-
+namespace ZeroTier
+{
+ ip_addr_t convert_ip(struct sockaddr_in * addr);
+ ip_addr_t ip_addr_sin(register struct sockaddr_in *sin);
+
+ ssize_t sock_fd_write(int sock, int fd);
+ ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd);
+}
#endif
diff --git a/osdep/Phy.hpp b/osdep/Phy.hpp
index e4209d3c..7f790e5d 100644
--- a/osdep/Phy.hpp
+++ b/osdep/Phy.hpp
@@ -289,7 +289,7 @@ public:
* @param uptr Pointer to associate with local side of socket pair
* @return PhySocket for local side of socket pair
*/
- static inline PhySocket *createSocketPair(ZT_PHY_SOCKFD_TYPE &remoteSocketDescriptor,void *uptr = (void *)0)
+ inline PhySocket *createSocketPair(ZT_PHY_SOCKFD_TYPE &remoteSocketDescriptor,void *uptr = (void *)0)
{
if (_socks.size() >= ZT_PHY_MAX_SOCKETS)
return (PhySocket *)0;