mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 03:53:44 +02:00
started refactor
This commit is contained in:
parent
750352836f
commit
3802d37d29
3 changed files with 34 additions and 300 deletions
|
@ -78,13 +78,10 @@ NetconEthernetTap::NetconEthernetTap(
|
||||||
if(!lwipstack) // TODO double check this check
|
if(!lwipstack) // TODO double check this check
|
||||||
throw std::runtime_error("unable to load lwip lib.");
|
throw std::runtime_error("unable to load lwip lib.");
|
||||||
lwipstack->lwip_init();
|
lwipstack->lwip_init();
|
||||||
nc_service = new NetconService(lwipstack, sockPath); // Netcon Service
|
|
||||||
|
|
||||||
_unixListenSocket = _phy.unixListen(sockPath,(void *)this);
|
_unixListenSocket = _phy.unixListen(sockPath,(void *)this);
|
||||||
if (!_unixListenSocket)
|
if (!_unixListenSocket)
|
||||||
throw std::runtime_error(std::string("unable to bind to ")+sockPath);
|
throw std::runtime_error(std::string("unable to bind to ")+sockPath);
|
||||||
else
|
|
||||||
_unixListenSocket.uptr = (void*) new NetconSocket(_unixListenSocket.sock, NetconSocketType.RPC);
|
|
||||||
_thread = Thread::start(this);
|
_thread = Thread::start(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,15 +229,18 @@ void NetconEthernetTap::phyOnTcpWritable(PhySocket *sock,void **uptr) {}
|
||||||
|
|
||||||
void NetconEthernetTap::phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN)
|
void NetconEthernetTap::phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN)
|
||||||
{
|
{
|
||||||
|
_phy.setuptr(sockN, new NIntercept());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr)
|
void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr)
|
||||||
{
|
{
|
||||||
|
NIntercept *h = (NIntercept*)_phy.getuptr(sock);
|
||||||
|
h->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len)
|
void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len)
|
||||||
{
|
{
|
||||||
Phy<NetconEthernetTap*>::PhySocketImpl &sws = *(reinterpret_cast<Phy<NetconEthernetTap*>::PhySocketImpl *>(sock));
|
NIntercept *h = (NIntercept*)_phy.getuptr(sock);
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
nc_service->possible_state_change = true;
|
nc_service->possible_state_change = true;
|
||||||
|
@ -621,7 +621,7 @@ void NetconEthernetTap::handle_connect(NetconIntercept *h, struct connect_st* co
|
||||||
//dwr(-1, "connect(): TCP_SNDBUF = %d\n", tcp_sndbuf(nc->pcb));
|
//dwr(-1, "connect(): TCP_SNDBUF = %d\n", tcp_sndbuf(nc->pcb));
|
||||||
lwipstack->tcp_sent(c->pcb, nc_sent); // FIXME: Move?
|
lwipstack->tcp_sent(c->pcb, nc_sent); // FIXME: Move?
|
||||||
lwipstack->tcp_recv(c->pcb, nc_recved);
|
lwipstack->tcp_recv(c->pcb, nc_recved);
|
||||||
lwipstack->tcp_err(c->pcb, ZeroTier::NetconEthernetTap::nc_err);
|
lwipstack->tcp_err(c->pcb, nc_err);
|
||||||
lwipstack->tcp_poll(c->pcb, nc_poll, APPLICATION_POLL_FREQ);
|
lwipstack->tcp_poll(c->pcb, nc_poll, APPLICATION_POLL_FREQ);
|
||||||
lwipstack->tcp_arg(c->pcb,(void*)(intptr_t)c->our_fd);
|
lwipstack->tcp_arg(c->pcb,(void*)(intptr_t)c->our_fd);
|
||||||
|
|
||||||
|
|
|
@ -37,308 +37,23 @@ using namespace std;
|
||||||
|
|
||||||
enum NetconSocketType { RPC, BUFFER };
|
enum NetconSocketType { RPC, BUFFER };
|
||||||
|
|
||||||
class NetconIntercept;
|
class NConnection
|
||||||
class NetconConnection;
|
{
|
||||||
class NetconSocket;
|
|
||||||
|
|
||||||
class NetconSocket{
|
|
||||||
int fd;
|
|
||||||
NetconSocketType type;
|
NetconSocketType type;
|
||||||
|
struct tcp_pcb *pcb;
|
||||||
|
PhySocket *sock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Client
|
||||||
class NetconConnection
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
vector<NConnection*> connections;
|
||||||
|
|
||||||
int tid;
|
void close()
|
||||||
int our_fd;
|
|
||||||
int their_fd; /* what the user app sees -- and what they will send us */
|
|
||||||
struct tcp_pcb *pcb; /* for handling lwIP calls/data */
|
|
||||||
bool unacked;
|
|
||||||
|
|
||||||
unsigned char *write_buf; /* we need this reference so we can grab data from the buffer during a lwip-poll callback */
|
|
||||||
long unsigned int write_count;
|
|
||||||
long unsigned int write_total;
|
|
||||||
|
|
||||||
unsigned char buf[DEFAULT_READ_BUFFER_SIZE];
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
unsigned long data_acked;
|
|
||||||
unsigned long data_sent;
|
|
||||||
unsigned long data_read;
|
|
||||||
unsigned long data_recvd;
|
|
||||||
|
|
||||||
NetconIntercept* owner;
|
|
||||||
|
|
||||||
NetconConnection(NetconIntercept* owner,
|
|
||||||
int tid,
|
|
||||||
int our_fd,
|
|
||||||
int their_fd,
|
|
||||||
struct tcp_pcb *pcb)
|
|
||||||
:
|
|
||||||
write_total(0),
|
|
||||||
write_count(0),
|
|
||||||
write_buf(NULL),
|
|
||||||
owner(owner),
|
|
||||||
tid(tid),
|
|
||||||
our_fd(our_fd),
|
|
||||||
their_fd(their_fd),
|
|
||||||
pcb(pcb)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
class NetconIntercept
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// State (this needs to be evaluated)
|
|
||||||
NetconConnection *unmapped_conn;
|
|
||||||
bool waiting_for_retval;
|
|
||||||
|
|
||||||
// Connections created for this intercept
|
|
||||||
vector<NetconConnection*> owned_connections;
|
|
||||||
|
|
||||||
int tid; /* just for uniqueness */
|
|
||||||
int rpc;
|
|
||||||
|
|
||||||
NetconIntercept(int tid, int rpc)
|
|
||||||
:
|
|
||||||
waiting_for_retval(false),
|
|
||||||
unmapped_conn(NULL),
|
|
||||||
tid(tid),
|
|
||||||
rpc(rpc)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define POLL_SZ ZT_PHY_MAX_SOCKETS+(ZT_PHY_MAX_INTERCEPTS*2)+2
|
|
||||||
class NetconService
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
LWIPStack *ls;
|
|
||||||
|
|
||||||
// TODO: shall replace with map
|
|
||||||
vector<NetconIntercept*> intercepts;
|
|
||||||
vector<NetconConnection*> connections;
|
|
||||||
|
|
||||||
/* fd_sets for main I/O polling */
|
|
||||||
fd_set fdset;
|
|
||||||
fd_set exfdset;
|
|
||||||
int maxfd;
|
|
||||||
size_t sz;
|
|
||||||
int tapfd;
|
|
||||||
|
|
||||||
// Sets of file descriptors we will poll() on
|
|
||||||
int default_rpc_pipe;
|
|
||||||
struct pollfd allfds[POLL_SZ];
|
|
||||||
int alltypes[POLL_SZ];
|
|
||||||
|
|
||||||
/* cached fd_sets */
|
|
||||||
bool possible_state_change;
|
|
||||||
fd_set cached_fdset;
|
|
||||||
fd_set cached_exfdset;
|
|
||||||
int cached_alltypes[POLL_SZ];
|
|
||||||
int cached_maxfd;
|
|
||||||
int cached_sz;
|
|
||||||
|
|
||||||
NetconService(LWIPStack *ls, string _handle)
|
|
||||||
:
|
|
||||||
ls(ls),
|
|
||||||
maxfd(0),
|
|
||||||
sz(0),
|
|
||||||
possible_state_change(true)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/* Assemble single poll list */
|
|
||||||
void assemble_fd_sets()
|
|
||||||
{
|
{
|
||||||
sz = 2 + connections.size() + intercepts.size();
|
// close all connections
|
||||||
// initialize
|
// -- pcb
|
||||||
for(size_t i=0; i<sz; i++){
|
// -- PhySocket
|
||||||
allfds[i].fd = 0;
|
|
||||||
allfds[i].events = 0;
|
|
||||||
}
|
|
||||||
int idx = 0;
|
|
||||||
// default rpc fd
|
|
||||||
allfds[0].fd = default_rpc_pipe;
|
|
||||||
allfds[0].events = POLLIN;
|
|
||||||
alltypes[0] = 1;
|
|
||||||
// netif fd
|
|
||||||
allfds[1].fd=tapfd;
|
|
||||||
allfds[1].events = POLLIN;
|
|
||||||
alltypes[1] = 2;
|
|
||||||
// buffers
|
|
||||||
for(size_t i=0; i<connections.size(); i++) {
|
|
||||||
idx = i + 2;
|
|
||||||
allfds[idx].fd = connections[i]->our_fd;
|
|
||||||
allfds[idx].events = POLLIN;
|
|
||||||
alltypes[idx] = 3;
|
|
||||||
}
|
|
||||||
// established connections
|
|
||||||
for(size_t i=0; i<intercepts.size(); i++) {
|
|
||||||
idx = i + connections.size() + 2;
|
|
||||||
allfds[idx].fd = intercepts[i]->rpc;
|
|
||||||
allfds[idx].events = POLLIN;
|
|
||||||
alltypes[idx] = 4;
|
|
||||||
}
|
|
||||||
FD_ZERO(&fdset);
|
|
||||||
FD_ZERO(&exfdset);
|
|
||||||
// populate master fd_set
|
|
||||||
for(size_t i=0; i<sz; i++) {
|
|
||||||
FD_SET(allfds[i].fd, &fdset);
|
|
||||||
FD_SET(allfds[i].fd, &exfdset);
|
|
||||||
}
|
|
||||||
// get maxfd
|
|
||||||
for(size_t i=0; i<sz; i++)
|
|
||||||
{
|
|
||||||
if(allfds[i].fd > maxfd)
|
|
||||||
maxfd = allfds[i].fd;
|
|
||||||
}
|
|
||||||
// cache copy of valid fd_set
|
|
||||||
possible_state_change = false;
|
|
||||||
memcpy(&cached_fdset, &fdset, sizeof(fdset));
|
|
||||||
memcpy(&cached_exfdset, &exfdset, sizeof(exfdset));
|
|
||||||
memcpy(&cached_alltypes, &alltypes, sizeof(alltypes));
|
|
||||||
cached_maxfd = maxfd;
|
|
||||||
cached_sz = sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NetconConnection *get_connection_by_pcb(struct tcp_pcb *pcb) {
|
|
||||||
for(size_t i=0; i<connections.size(); i++) {
|
|
||||||
if(connections[i]->pcb == pcb) {
|
|
||||||
return connections[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetconConnection *get_connection_by_buf_sock(int fd) {
|
|
||||||
for(size_t i=0; i<connections.size(); i++) {
|
|
||||||
if(connections[i]->our_fd==fd) {
|
|
||||||
return connections[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: This will be a common operation and thus should be done via
|
|
||||||
// some sort of hashing, not iterative lookup.
|
|
||||||
NetconIntercept *get_intercept_by_pcb(struct tcp_pcb* pcb) {
|
|
||||||
for(size_t i=0; i<connections.size(); i++) {
|
|
||||||
if(connections[i]->pcb==pcb) {
|
|
||||||
return connections[i]->owner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NetconIntercept *get_intercept_by_rpc(int af) {
|
|
||||||
for(size_t i=0; i<intercepts.size(); i++) {
|
|
||||||
if(intercepts[i]->rpc==af) {
|
|
||||||
return intercepts[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetconConnection *get_connection_by_that_fd(NetconIntercept* h, int fd)
|
|
||||||
{
|
|
||||||
for(size_t i=0; i<h->owned_connections.size(); i++) {
|
|
||||||
if(h->owned_connections[i]->their_fd==fd) {
|
|
||||||
return h->owned_connections[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetconConnection *get_connection_by_this_fd(int fd)
|
|
||||||
{
|
|
||||||
for(size_t i=0; i<connections.size(); i++) {
|
|
||||||
if(connections[i]->our_fd==fd) {
|
|
||||||
return connections[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetconConnection *get_connection_by_that_fd(int fd)
|
|
||||||
{
|
|
||||||
for(size_t i=0; i<connections.size(); i++) {
|
|
||||||
if(connections[i]->their_fd==fd) {
|
|
||||||
return connections[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetconConnection *add_connection(NetconIntercept* owner,
|
|
||||||
int tid,
|
|
||||||
int our_fd,
|
|
||||||
int their_fd,
|
|
||||||
struct tcp_pcb* pcb)
|
|
||||||
{
|
|
||||||
possible_state_change = true;
|
|
||||||
if(connections.size() >= ZT_PHY_MAX_SOCKETS) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
NetconConnection *new_conn = new NetconConnection(owner, tid, our_fd, their_fd, pcb);
|
|
||||||
connections.push_back(new_conn);
|
|
||||||
|
|
||||||
NetconIntercept *h;
|
|
||||||
for(size_t i=0; i<intercepts.size(); i++) {
|
|
||||||
if(intercepts[i]->tid == tid) {
|
|
||||||
h = intercepts[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(h)
|
|
||||||
h->owned_connections.push_back(new_conn);
|
|
||||||
return new_conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes a Connection from the Service and updates poll lists
|
|
||||||
void remove_connection(NetconConnection *c)
|
|
||||||
{
|
|
||||||
possible_state_change = true;
|
|
||||||
for(size_t i=0; i<connections.size(); i++) {
|
|
||||||
if(c == connections[i]) {
|
|
||||||
close(connections[i]->our_fd);
|
|
||||||
ls->tcp_close(c->pcb);
|
|
||||||
delete c;
|
|
||||||
connections.erase(connections.begin() + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int add_intercept(int listen_sock) {
|
|
||||||
possible_state_change = true;
|
|
||||||
int accept_socket = accept(listen_sock, NULL, NULL);
|
|
||||||
intercepts.push_back(new NetconIntercept(999, accept_socket));
|
|
||||||
return accept_socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Removes an Intercept from the Service
|
|
||||||
bool remove_intercept(NetconIntercept *h)
|
|
||||||
{
|
|
||||||
possible_state_change = true;
|
|
||||||
// remove all connections owned by this Intercept
|
|
||||||
for(size_t i=0; i<h->owned_connections.size(); i++) {
|
|
||||||
remove_connection(h->owned_connections[i]);
|
|
||||||
}
|
|
||||||
// find and remove Intercept
|
|
||||||
for(size_t i=0; i<intercepts.size(); i++)
|
|
||||||
{
|
|
||||||
if(h == intercepts[i]) {
|
|
||||||
delete intercepts[i];
|
|
||||||
intercepts.erase(intercepts.begin() + i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,25 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void *getuptr(PhySocket *sock)
|
||||||
|
{
|
||||||
|
PhySocketImpl &sws = *(reinterpret_cast<PhySocketImpl *>(sock));
|
||||||
|
return sws.uptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setuptr(PhySocket *sock, void *obj)
|
||||||
|
{
|
||||||
|
PhySocketImpl &sws = *(reinterpret_cast<PhySocketImpl *>(sock));
|
||||||
|
sws.uptr = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Number of open sockets
|
* @return Number of open sockets
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue