mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-21 05:43:59 -07:00
Simplify Phy<> to get rid of more indirections.
This commit is contained in:
parent
7576911951
commit
5572b7ffb6
7 changed files with 153 additions and 243 deletions
|
@ -83,15 +83,15 @@ typedef void PhySocket;
|
|||
* Yes there is boost::asio and libuv, but I like small binaries and I hate
|
||||
* build dependencies. Both drag in a whole bunch of pasta with them.
|
||||
*
|
||||
* This implementation takes four functions or function objects as template
|
||||
* paramters:
|
||||
* This class is templated on a pointer to a handler class which must
|
||||
* implement the following functions:
|
||||
*
|
||||
* ON_DATAGRAM_FUNCTION(PhySocket *sock,void **uptr,const struct sockaddr *from,void *data,unsigned long len)
|
||||
* ON_TCP_CONNECT_FUNCTION(PhySocket *sock,void **uptr,bool success)
|
||||
* ON_TCP_ACCEPT_FUNCTION(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from)
|
||||
* ON_TCP_CLOSE_FUNCTION(PhySocket *sock,void **uptr)
|
||||
* ON_TCP_DATA_FUNCTION(PhySocket *sock,void **uptr,void *data,unsigned long len)
|
||||
* ON_TCP_WRITABLE_FUNCTION(PhySocket *sock,void **uptr)
|
||||
* phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *from,void *data,unsigned long len)
|
||||
* phyOnTcpConnect(PhySocket *sock,void **uptr,bool success)
|
||||
* phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from)
|
||||
* phyOnTcpClose(PhySocket *sock,void **uptr)
|
||||
* phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len)
|
||||
* phyOnTcpWritable(PhySocket *sock,void **uptr)
|
||||
*
|
||||
* These templates typically refer to function objects. Templates are used to
|
||||
* avoid the call overhead of indirection, which is surprisingly high for high
|
||||
|
@ -114,22 +114,11 @@ typedef void PhySocket;
|
|||
* This isn't thread-safe with the exception of whack(), which is safe to
|
||||
* call from another thread to abort poll().
|
||||
*/
|
||||
template <
|
||||
typename ON_DATAGRAM_FUNCTION,
|
||||
typename ON_TCP_CONNECT_FUNCTION,
|
||||
typename ON_TCP_ACCEPT_FUNCTION,
|
||||
typename ON_TCP_CLOSE_FUNCTION,
|
||||
typename ON_TCP_DATA_FUNCTION,
|
||||
typename ON_TCP_WRITABLE_FUNCTION >
|
||||
template <typename HANDLER_PTR_TYPE>
|
||||
class Phy
|
||||
{
|
||||
private:
|
||||
ON_DATAGRAM_FUNCTION _datagramHandler;
|
||||
ON_TCP_CONNECT_FUNCTION _tcpConnectHandler;
|
||||
ON_TCP_ACCEPT_FUNCTION _tcpAcceptHandler;
|
||||
ON_TCP_CLOSE_FUNCTION _tcpCloseHandler;
|
||||
ON_TCP_DATA_FUNCTION _tcpDataHandler;
|
||||
ON_TCP_WRITABLE_FUNCTION _tcpWritableHandler;
|
||||
HANDLER_PTR_TYPE _handler;
|
||||
|
||||
enum PhySocketType
|
||||
{
|
||||
|
@ -164,27 +153,11 @@ private:
|
|||
|
||||
public:
|
||||
/**
|
||||
* @param datagramHandler Function or function object to handle UDP or RAW datagrams
|
||||
* @param tcpConnectHandler Handler for outgoing TCP connection attempts (success or failure)
|
||||
* @param tcpAcceptHandler Handler for incoming TCP connections
|
||||
* @param tcpDataHandler Handler for incoming TCP data
|
||||
* @param tcpWritableHandler Handler to be called when TCP sockets are writable (if notification is on)
|
||||
* @param noDelay If true, disable Nagle algorithm on new TCP sockets
|
||||
* @param handler Pointer of type HANDLER_PTR_TYPE to handler
|
||||
* @param noDelay If true, disable TCP NAGLE algorithm on TCP sockets
|
||||
*/
|
||||
Phy(
|
||||
ON_DATAGRAM_FUNCTION datagramHandler,
|
||||
ON_TCP_CONNECT_FUNCTION tcpConnectHandler,
|
||||
ON_TCP_ACCEPT_FUNCTION tcpAcceptHandler,
|
||||
ON_TCP_CLOSE_FUNCTION tcpCloseHandler,
|
||||
ON_TCP_DATA_FUNCTION tcpDataHandler,
|
||||
ON_TCP_WRITABLE_FUNCTION tcpWritableHandler,
|
||||
bool noDelay) :
|
||||
_datagramHandler(datagramHandler),
|
||||
_tcpConnectHandler(tcpConnectHandler),
|
||||
_tcpAcceptHandler(tcpAcceptHandler),
|
||||
_tcpCloseHandler(tcpCloseHandler),
|
||||
_tcpDataHandler(tcpDataHandler),
|
||||
_tcpWritableHandler(tcpWritableHandler)
|
||||
Phy(HANDLER_PTR_TYPE handler,bool noDelay) :
|
||||
_handler(handler)
|
||||
{
|
||||
FD_ZERO(&_readfds);
|
||||
FD_ZERO(&_writefds);
|
||||
|
@ -526,7 +499,7 @@ public:
|
|||
|
||||
if ((callConnectHandler)&&(connected)) {
|
||||
try {
|
||||
_tcpConnectHandler((PhySocket *)&sws,&(sws.uptr),true);
|
||||
_handler->phyOnTcpConnect((PhySocket *)&sws,&(sws.uptr),true);
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
|
||||
|
@ -664,7 +637,7 @@ public:
|
|||
FD_CLR(s->sock,&_exceptfds);
|
||||
#endif
|
||||
try {
|
||||
_tcpConnectHandler((PhySocket *)&(*s),&(s->uptr),true);
|
||||
_handler->phyOnTcpConnect((PhySocket *)&(*s),&(s->uptr),true);
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
}
|
||||
|
@ -678,13 +651,13 @@ public:
|
|||
this->close((PhySocket *)&(*s),true);
|
||||
} else {
|
||||
try {
|
||||
_tcpDataHandler((PhySocket *)&(*s),&(s->uptr),(void *)buf,(unsigned long)n);
|
||||
_handler->phyOnTcpData((PhySocket *)&(*s),&(s->uptr),(void *)buf,(unsigned long)n);
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
}
|
||||
if ((FD_ISSET(s->sock,&wfds))&&(FD_ISSET(s->sock,&_writefds))) {
|
||||
try {
|
||||
_tcpWritableHandler((PhySocket *)&(*s),&(s->uptr));
|
||||
_handler->phyOnTcpWritable((PhySocket *)&(*s),&(s->uptr));
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
break;
|
||||
|
@ -715,7 +688,7 @@ public:
|
|||
sws.uptr = (void *)0;
|
||||
memcpy(&(sws.saddr),&ss,sizeof(struct sockaddr_storage));
|
||||
try {
|
||||
_tcpAcceptHandler((PhySocket *)&(*s),(PhySocket *)&(_socks.back()),&(s->uptr),&(sws.uptr),(const struct sockaddr *)&(sws.saddr));
|
||||
_handler->phyOnTcpAccept((PhySocket *)&(*s),(PhySocket *)&(_socks.back()),&(s->uptr),&(sws.uptr),(const struct sockaddr *)&(sws.saddr));
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
}
|
||||
|
@ -730,7 +703,7 @@ public:
|
|||
long n = (long)::recvfrom(s->sock,buf,sizeof(buf),0,(struct sockaddr *)&ss,&slen);
|
||||
if (n > 0) {
|
||||
try {
|
||||
_datagramHandler((PhySocket *)&(*s),&(s->uptr),(const struct sockaddr *)&ss,(void *)buf,(unsigned long)n);
|
||||
_handler->phyOnDatagram((PhySocket *)&(*s),&(s->uptr),(const struct sockaddr *)&ss,(void *)buf,(unsigned long)n);
|
||||
} catch ( ... ) {}
|
||||
} else if (n < 0)
|
||||
break;
|
||||
|
@ -767,7 +740,7 @@ public:
|
|||
case ZT_PHY_SOCKET_TCP_OUT_PENDING:
|
||||
if (callHandlers) {
|
||||
try {
|
||||
_tcpConnectHandler(sock,&(sws.uptr),false);
|
||||
_handler->phyOnTcpConnect(sock,&(sws.uptr),false);
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
break;
|
||||
|
@ -775,7 +748,7 @@ public:
|
|||
case ZT_PHY_SOCKET_TCP_IN:
|
||||
if (callHandlers) {
|
||||
try {
|
||||
_tcpCloseHandler(sock,&(sws.uptr));
|
||||
_handler->phyOnTcpClose(sock,&(sws.uptr));
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
break;
|
||||
|
@ -805,19 +778,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// Typedefs for using regular naked functions as template parameters to Phy<>
|
||||
typedef void (*Phy_OnDatagramFunctionPtr)(PhySocket *sock,void **uptr,const struct sockaddr *from,void *data,unsigned long len);
|
||||
typedef void (*Phy_OnTcpConnectFunction)(PhySocket *sock,void **uptr,bool success);
|
||||
typedef void (*Phy_OnTcpAcceptFunction)(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from);
|
||||
typedef void (*Phy_OnTcpCloseFunction)(PhySocket *sock,void **uptr);
|
||||
typedef void (*Phy_OnTcpDataFunction)(PhySocket *sock,void **uptr,void *data,unsigned long len);
|
||||
typedef void (*Phy_OnTcpWritableFunction)(PhySocket *sock,void **uptr);
|
||||
|
||||
/**
|
||||
* Phy<> typedef'd to use simple naked function pointers
|
||||
*/
|
||||
typedef Phy<Phy_OnDatagramFunctionPtr,Phy_OnTcpConnectFunction,Phy_OnTcpAcceptFunction,Phy_OnTcpCloseFunction,Phy_OnTcpDataFunction,Phy_OnTcpWritableFunction> SimpleFunctionPhy;
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue