@ -51,7 +51,6 @@ err_t tapif_init(struct netif *netif)
err_t lwip_eth_tx ( struct netif * netif , struct pbuf * p )
{
DEBUG_INFO ( ) ;
struct pbuf * q ;
char buf [ ZT_MAX_MTU + 32 ] ;
char * bufptr ;
@ -76,6 +75,19 @@ err_t lwip_eth_tx(struct netif *netif, struct pbuf *p)
tap - > _handler ( tap - > _arg , NULL , tap - > _nwid , src_mac , dest_mac ,
ZeroTier : : Utils : : ntoh ( ( uint16_t ) ethhdr - > type ) , 0 , buf + sizeof ( struct eth_hdr ) , totalLength - sizeof ( struct eth_hdr ) ) ;
if ( ZT_DEBUG_LEVEL > = ZT_MSG_TRANSFER ) {
char flagbuf [ 32 ] ;
memset ( & flagbuf , 0 , 32 ) ;
char macBuf [ ZT_MAC_ADDRSTRLEN ] , nodeBuf [ ZT_ID_LEN ] ;
mac2str ( macBuf , ZT_MAC_ADDRSTRLEN , ethhdr - > dest . addr ) ;
ZeroTier : : MAC mac ;
mac . setTo ( ethhdr - > dest . addr , 6 ) ;
mac . toAddress ( tap - > _nwid ) . toString ( nodeBuf ) ;
DEBUG_TRANS ( " len=%5d dst=%s [%s TX <-- %s] proto=0x%04x %s %s " , totalLength , macBuf , nodeBuf , tap - > nodeId ( ) . c_str ( ) ,
ZeroTier : : Utils : : ntoh ( ethhdr - > type ) , beautify_eth_proto_nums ( ZeroTier : : Utils : : ntoh ( ethhdr - > type ) ) , flagbuf ) ;
}
return ERR_OK ;
}
@ -89,7 +101,7 @@ namespace ZeroTier
if ( std : : find ( tap - > _ips . begin ( ) , tap - > _ips . end ( ) , ip ) = = tap - > _ips . end ( ) ) {
tap - > _ips . push_back ( ip ) ;
std : : sort ( tap - > _ips . begin ( ) , tap - > _ips . end ( ) ) ;
char ipbuf [ 64 ] , nmbuf [ 64 ] ;
char ipbuf [ INET6_ADDRSTRLEN ] , nmbuf [ INET6_ADDRSTRLEN ] ;
# if defined(LIBZT_IPV4)
if ( ip . isV4 ( ) ) {
// Set IP
@ -140,12 +152,22 @@ namespace ZeroTier
}
}
int lwIP : : lwip_add_dns_nameserver ( struct sockaddr * addr )
{
return - 1 ;
}
int lwIP : : lwip_del_dns_nameserver ( struct sockaddr * addr )
{
return - 1 ;
}
void lwIP : : lwip_loop ( VirtualTap * tap )
{
DEBUG_INFO ( ) ;
uint64_t prev_tcp_time = 0 , prev_discovery_time = 0 ;
while ( tap - > _run )
{
// DEBUG_INFO();
uint64_t prev_tcp_time = 0 , prev_discovery_time = 0 ;
while ( tap - > _run )
{
uint64_t now = OSUtils : : now ( ) ;
uint64_t since_tcp = now - prev_tcp_time ;
uint64_t since_discovery = now - prev_discovery_time ;
@ -183,7 +205,6 @@ namespace ZeroTier
void lwIP : : lwip_eth_rx ( VirtualTap * tap , const MAC & from , const MAC & to , unsigned int etherType , const void * data , unsigned int len )
{
DEBUG_INFO ( " etherType=%x, len=%d " , etherType , len ) ;
struct pbuf * p , * q ;
if ( ! tap - > _enabled )
return ;
@ -211,6 +232,19 @@ namespace ZeroTier
dataptr + = q - > len ;
}
}
if ( ZT_DEBUG_LEVEL > = ZT_MSG_TRANSFER ) {
char flagbuf [ 32 ] ;
memset ( & flagbuf , 0 , 32 ) ;
char macBuf [ ZT_MAC_ADDRSTRLEN ] , nodeBuf [ ZT_ID_LEN ] ;
mac2str ( macBuf , ZT_MAC_ADDRSTRLEN , ethhdr . dest . addr ) ;
ZeroTier : : MAC mac ;
mac . setTo ( ethhdr . dest . addr , 6 ) ;
mac . toAddress ( tap - > _nwid ) . toString ( nodeBuf ) ;
DEBUG_TRANS ( " len=%5d dst=%s [%s RX --> %s] proto=0x%04x %s %s " , len , macBuf , nodeBuf , tap - > nodeId ( ) . c_str ( ) ,
ZeroTier : : Utils : : ntoh ( ethhdr . type ) , beautify_eth_proto_nums ( ZeroTier : : Utils : : ntoh ( ethhdr . type ) ) , flagbuf ) ;
}
else {
DEBUG_ERROR ( " dropped packet: no pbufs available " ) ;
return ;
@ -260,7 +294,7 @@ namespace ZeroTier
struct sockaddr_in * in4 = ( struct sockaddr_in * ) addr ;
if ( addr - > sa_family = = AF_INET ) {
inet_ntop ( AF_INET , & ( in4 - > sin_addr ) , addrstr , INET_ADDRSTRLEN ) ;
DEBUG_INFO ( " %s:%d " , addrstr , lwip_ntohs ( in4 - > sin_port ) ) ;
DEBUG_EXTRA ( " connecting to %s : %d" , addrstr , lwip_ntohs ( in4 - > sin_port ) ) ;
}
ba = convert_ip ( in4 ) ;
port = lwip_ntohs ( in4 - > sin_port ) ;
@ -271,36 +305,33 @@ namespace ZeroTier
if ( addr - > sa_family = = AF_INET6 ) {
struct sockaddr_in6 * vsaddr6 = ( struct sockaddr_in6 * ) addr ;
inet_ntop ( AF_INET6 , & ( in6 - > sin6_addr ) , addrstr , INET6_ADDRSTRLEN ) ;
DEBUG_INFO ( " %s:%d " , addrstr , lwip_ntohs ( in6 - > sin6_port ) ) ;
DEBUG_EXTRA ( " connecting to %s : %d" , addrstr , lwip_ntohs ( in6 - > sin6_port ) ) ;
}
# endif
DEBUG_INFO ( " addr=%s " , addrstr ) ;
if ( vs - > socket_type = = SOCK_DGRAM ) {
// Generates no network traffic
if ( ( err = udp_connect ( ( struct udp_pcb * ) vs - > pcb , ( ip_addr_t * ) & ba , port ) ) < 0 ) {
DEBUG_ERROR ( " error while connecting to with UDP " ) ;
}
udp_recv ( ( struct udp_pcb * ) vs - > pcb , nc _udp_recved, vs ) ;
udp_recv ( ( struct udp_pcb * ) vs - > pcb , lwip_cb _udp_recved, vs ) ;
return ERR_OK ;
}
if ( vs - > socket_type = = SOCK_STREAM ) {
struct tcp_pcb * tpcb = ( struct tcp_pcb * ) vs - > pcb ;
tcp_sent ( tpcb , nc _sent) ;
tcp_recv ( tpcb , nc _recved) ;
tcp_err ( tpcb , nc _err) ;
tcp_poll ( tpcb , nc _poll, LWIP_APPLICATION_POLL_FREQ ) ;
tcp_sent ( tpcb , lwip_cb _sent) ;
tcp_recv ( tpcb , lwip_cb_tcp _recved) ;
tcp_err ( tpcb , lwip_cb _err) ;
tcp_poll ( tpcb , lwip_cb _poll, LWIP_APPLICATION_POLL_FREQ ) ;
tcp_arg ( tpcb , vs ) ;
//DEBUG_EXTRA(" pcb->state=%x", vs->TCP_pcb->state);
//if(vs->TCP_pcb->state != CLOSED) {
// DEBUG_INFO(" cannot connect using this PCB, PCB!=CLOSED");
// tap->sendReturnValue(tap->_phy.getDescriptor(rpcSock), -1, EAGAIN);
// return;
// DEBUG_INFO(" cannot connect using this PCB, PCB!=CLOSED");
// tap->sendReturnValue(tap->_phy.getDescriptor(rpcSock), -1, EAGAIN);
// return;
//}
if ( ( err = tcp_connect ( tpcb , & ba , port , nc _connected) ) < 0 )
if ( ( err = tcp_connect ( tpcb , & ba , port , lwip_cb _connected) ) < 0 )
{
if ( err = = ERR_ISCONN ) {
// Already in connected state
@ -334,7 +365,7 @@ namespace ZeroTier
// that the SYN packet was enqueued onto the stack properly,
// that's it!
// - Most instances of a retval for a connect() should happen
// in the nc_connect() and nc _err() callbacks!
// in the nc_connect() and lwip_cb _err() callbacks!
DEBUG_ERROR ( " unable to connect " ) ;
errno = EAGAIN ;
return - 1 ;
@ -354,7 +385,7 @@ namespace ZeroTier
struct sockaddr_in * in4 = ( struct sockaddr_in * ) addr ;
if ( addr - > sa_family = = AF_INET ) {
inet_ntop ( AF_INET , & ( in4 - > sin_addr ) , addrstr , INET_ADDRSTRLEN ) ;
DEBUG_INFO ( " %s:%d " , addrstr , lwip_ntohs ( in4 - > sin_port ) ) ;
DEBUG_EXTRA ( " binding to %s : %d" , addrstr , lwip_ntohs ( in4 - > sin_port ) ) ;
}
ba = convert_ip ( in4 ) ;
port = lwip_ntohs ( in4 - > sin_port ) ;
@ -365,7 +396,7 @@ namespace ZeroTier
if ( addr - > sa_family = = AF_INET6 ) {
struct sockaddr_in6 * vsaddr6 = ( struct sockaddr_in6 * ) addr ;
inet_ntop ( AF_INET6 , & ( in6 - > sin6_addr ) , addrstr , INET6_ADDRSTRLEN ) ;
DEBUG_INFO ( " %s:%d " , addrstr , lwip_ntohs ( in6 - > sin6_port ) ) ;
DEBUG_EXTRA ( " binding to %s : %d" , addrstr , lwip_ntohs ( in6 - > sin6_port ) ) ;
}
# endif
if ( vs - > socket_type = = SOCK_DGRAM ) {
@ -376,7 +407,7 @@ namespace ZeroTier
}
else {
// set the recv callback
udp_recv ( ( struct udp_pcb * ) vs - > pcb , nc _udp_recved, new VirtualBindingPair ( tap , vs ) ) ;
udp_recv ( ( struct udp_pcb * ) vs - > pcb , lwip_cb _udp_recved, new VirtualBindingPair ( tap , vs ) ) ;
err = ERR_OK ;
errno = ERR_OK ; // success
}
@ -417,7 +448,7 @@ namespace ZeroTier
# endif
if ( listeningPCB ! = NULL ) {
vs - > pcb = listeningPCB ;
tcp_accept ( listeningPCB , nc _accept) ; // set callback
tcp_accept ( listeningPCB , lwip_cb _accept) ; // set callback
tcp_arg ( listeningPCB , vs ) ;
//fcntl(tap->_phy.getDescriptor(vs->sock), F_SETFL, O_NONBLOCK);
}
@ -446,7 +477,7 @@ namespace ZeroTier
DEBUG_EXTRA ( " vs=%p " , vs ) ;
int err = 0 ;
if ( ! vs ) {
DEBUG_ERROR ( " no VirtualS ocket " ) ;
DEBUG_ERROR ( " no virtual s ocket " ) ;
return - 1 ;
}
if ( ! lwip_invoked ) {
@ -487,14 +518,14 @@ namespace ZeroTier
DEBUG_EXTRA ( " vs=%p, len=%d " , ( void * ) & vs , len ) ;
int err = 0 ;
if ( ! vs ) {
DEBUG_ERROR ( " no VirtualS ocket " ) ;
DEBUG_ERROR ( " no virtual s ocket " ) ;
return - 1 ;
}
if ( vs - > socket_type = = SOCK_DGRAM )
{
DEBUG_ERROR ( " socket_type==SOCK_DGRAM " ) ;
// TODO: Packet re-assembly hasn't yet been tested with lwIP so UDP packets are limited to MTU-sized chunks
int udp_trans_len = std : : min ( ( ssize_t ) vs - > TXbuf - > count ( ) , ( ssize_t ) ZT_MAX_MTU ) ;
int udp_trans_len = std : : min ( ( ssize_t ) vs - > TXbuf - > count ( ) , ( ssize_t ) ZT_MAX_MTU ) ;
DEBUG_EXTRA ( " allocating pbuf chain of size=%d for UDP packet, txsz=%d " , udp_trans_len , vs - > TXbuf - > count ( ) ) ;
struct pbuf * pb = pbuf_alloc ( PBUF_TRANSPORT , udp_trans_len , PBUF_POOL ) ;
if ( ! pb ) {
@ -524,7 +555,7 @@ namespace ZeroTier
int err , r ;
if ( ! sndbuf ) {
// PCB send buffer is full, turn off readability notifications for the
// corresponding PhySocket until nc _sent() is called and confirms that there is
// corresponding PhySocket until lwip_cb _sent() is called and confirms that there is
// now space on the buffer
DEBUG_ERROR ( " lwIP stack is full, sndbuf == 0 " ) ;
vs - > tap - > _phy . setNotifyReadable ( vs - > sock , false ) ;
@ -571,7 +602,7 @@ namespace ZeroTier
// FIXME: check if already closed? vs->TCP_pcb->state != CLOSED
if ( vs - > pcb ) {
//DEBUG_EXTRA("vs=%p, sock=%p, PCB->state = %d",
// (void*)&conn, (void*)&sock, vs->TCP_pcb->state);
// (void*)&conn, (void*)&sock, vs->TCP_pcb->state);
if ( ( ( struct tcp_pcb * ) vs - > pcb ) - > state = = SYN_SENT /*|| vs->TCP_pcb->state == CLOSE_WAIT*/ ) {
DEBUG_EXTRA ( " ignoring close request. invalid PCB state for this operation. sock=%p " , vs - > sock ) ;
return - 1 ;
@ -596,7 +627,7 @@ namespace ZeroTier
/* Callbacks from lwIP stack */
/****************************************************************************/
err_t lwIP : : nc _recved( void * arg , struct tcp_pcb * PCB , struct pbuf * p , err_t err )
err_t lwIP : : lwip_cb_tcp _recved( void * arg , struct tcp_pcb * PCB , struct pbuf * p , err_t err )
{
DEBUG_INFO ( ) ;
VirtualSocket * vs = ( VirtualSocket * ) arg ;
@ -649,12 +680,11 @@ namespace ZeroTier
return ERR_OK ;
}
err_t lwIP : : nc _accept( void * arg , struct tcp_pcb * newPCB , err_t err )
err_t lwIP : : lwip_cb _accept( void * arg , struct tcp_pcb * newPCB , err_t err )
{
VirtualSocket * vs = ( VirtualSocket * ) arg ;
DEBUG_INFO ( " vs=%p " , vs ) ;
//Mutex::Lock _l(vs->tap->_tcpconns_m);
// create and populate new VirtualSocket object
VirtualSocket * new_vs = new VirtualSocket ( ) ;
new_vs - > socket_type = SOCK_STREAM ;
new_vs - > pcb = newPCB ;
@ -666,22 +696,22 @@ namespace ZeroTier
vs - > _AcceptedConnections . push ( new_vs ) ;
// set callbacks
tcp_arg ( newPCB , new_vs ) ;
tcp_recv ( newPCB , nc _recved) ;
tcp_err ( newPCB , nc _err) ;
tcp_sent ( newPCB , nc _sent) ;
tcp_poll ( newPCB , nc _poll, 1 ) ;
tcp_recv ( newPCB , lwip_cb_tcp _recved) ;
tcp_err ( newPCB , lwip_cb _err) ;
tcp_sent ( newPCB , lwip_cb _sent) ;
tcp_poll ( newPCB , lwip_cb _poll, 1 ) ;
// let lwIP know that it can queue additional incoming VirtualSockets
tcp_accepted ( ( struct tcp_pcb * ) vs - > pcb ) ;
return 0 ;
}
void lwIP : : nc _udp_recved( void * arg , struct udp_pcb * upcb , struct pbuf * p , const ip_addr_t * addr , u16_t port )
void lwIP : : lwip_cb _udp_recved( void * arg , struct udp_pcb * upcb , struct pbuf * p , const ip_addr_t * addr , u16_t port )
{
DEBUG_INFO ( ) ;
// to be implemented
}
err_t lwIP : : nc _sent( void * arg , struct tcp_pcb * PCB , u16_t len )
err_t lwIP : : lwip_cb _sent( void * arg , struct tcp_pcb * PCB , u16_t len )
{
DEBUG_EXTRA ( " pcb=%p " , ( void * ) & PCB ) ;
VirtualSocket * vs = ( VirtualSocket * ) arg ;
@ -696,7 +726,7 @@ namespace ZeroTier
return ERR_OK ;
}
err_t lwIP : : nc _connected( void * arg , struct tcp_pcb * PCB , err_t err )
err_t lwIP : : lwip_cb _connected( void * arg , struct tcp_pcb * PCB , err_t err )
{
DEBUG_ATTN ( " pcb=%p " , ( void * ) & PCB ) ;
VirtualSocket * vs = ( VirtualSocket * ) arg ;
@ -706,12 +736,12 @@ namespace ZeroTier
// FIXME: check stack for expected return values
}
err_t lwIP : : nc _poll( void * arg , struct tcp_pcb * PCB )
err_t lwIP : : lwip_cb _poll( void * arg , struct tcp_pcb * PCB )
{
return ERR_OK ;
}
void lwIP : : nc _err( void * arg , err_t err )
void lwIP : : lwip_cb _err( void * arg , err_t err )
{
DEBUG_ERROR ( " err=%d " , err ) ;
VirtualSocket * vs = ( VirtualSocket * ) arg ;