@ -1011,8 +1011,7 @@ static void ping_timeout_cbk(void* arg) {
int etcp_send_ping_to_socket ( struct UTUN_INSTANCE * instance , struct ETCP_SOCKET * e_sock ,
int etcp_send_ping_to_socket ( struct UTUN_INSTANCE * instance , struct ETCP_SOCKET * e_sock ,
const uint8_t * peer_pubkey_bin , const struct sockaddr_storage * addr ,
const uint8_t * peer_pubkey_bin , const struct sockaddr_storage * addr ,
int timeout_ms , etcp_ping_callback_t cb , void * user_arg ,
int timeout_ms , etcp_ping_callback_t cb , void * user_arg ,
const uint8_t * user_data , size_t user_data_len ,
const uint8_t * user_data , size_t user_data_len ) {
uint8_t flags ) {
if ( ! instance | | ! e_sock | | ! peer_pubkey_bin | | ! addr | | timeout_ms < = 0 | | ! cb ) {
if ( ! instance | | ! e_sock | | ! peer_pubkey_bin | | ! addr | | timeout_ms < = 0 | | ! cb ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " bad args " ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " bad args " ) ;
return - 1 ;
return - 1 ;
@ -1045,7 +1044,6 @@ int etcp_send_ping_to_socket(struct UTUN_INSTANCE* instance, struct ETCP_SOCKET*
memcpy ( ctx - > user_data , user_data , user_data_len ) ;
memcpy ( ctx - > user_data , user_data , user_data_len ) ;
ctx - > user_data_len = user_data_len ;
ctx - > user_data_len = user_data_len ;
}
}
memcpy ( ctx - > peer_pubkey , peer_pubkey_bin , SC_PUBKEY_SIZE ) ;
struct ETCP_DGRAM * dgram = u_malloc ( PACKET_DATA_SIZE ) ;
struct ETCP_DGRAM * dgram = u_malloc ( PACKET_DATA_SIZE ) ;
if ( ! dgram ) {
if ( ! dgram ) {
if ( ctx - > user_data ) u_free ( ctx - > user_data ) ;
if ( ctx - > user_data ) u_free ( ctx - > user_data ) ;
@ -1058,7 +1056,6 @@ int etcp_send_ping_to_socket(struct UTUN_INSTANCE* instance, struct ETCP_SOCKET*
size_t offset = 0 ;
size_t offset = 0 ;
uint8_t * p = dgram - > data ;
uint8_t * p = dgram - > data ;
* p + + = ETCP_PING ;
* p + + = ETCP_PING ;
* p + + = flags ; // flags
uint64_t nid = htobe64 ( instance - > node_id ) ;
uint64_t nid = htobe64 ( instance - > node_id ) ;
memcpy ( p , & nid , 8 ) ; p + = 8 ;
memcpy ( p , & nid , 8 ) ; p + = 8 ;
uint64_t nonce_be = htobe64 ( ctx - > nonce ) ;
uint64_t nonce_be = htobe64 ( ctx - > nonce ) ;
@ -1118,39 +1115,25 @@ int etcp_send_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubkey_bi
}
}
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " ping N1 [%s] " , sockaddr_storage_to_str ( addr ) . str ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " ping N1 [%s] " , sockaddr_storage_to_str ( addr ) . str ) ;
return etcp_send_ping_to_socket ( instance , e_sock , peer_pubkey_bin , addr , timeout_ms ,
return etcp_send_ping_to_socket ( instance , e_sock , peer_pubkey_bin , addr , timeout_ms ,
cb , user_arg , user_data , user_data_len , 0 ) ;
cb , user_arg , user_data , user_data_len ) ;
}
}
// === Helpers extracted from etcp_connections_read_callback_socket ===
// === Helpers extracted from etcp_connections_read_callback_socket ===
static int handle_ping ( struct ETCP_SOCKET * e_sock , struct ETCP_DGRAM * pkt , const struct sockaddr_storage * addr , const uint8_t * decrypted_pubkey , size_t pkt_len ) {
static int handle_ping ( struct ETCP_SOCKET * e_sock , struct ETCP_DGRAM * pkt , const struct sockaddr_storage * addr , const uint8_t * decrypted_pubkey , size_t pkt_len ) {
if ( pkt_len < 23 ) {
if ( pkt_len < 22 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " PING too short: pkt_len=%zu from %s " , pkt_len , sockaddr_storage_to_str ( addr ) . str ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " PING too short: pkt_len=%zu from %s " , pkt_len , sockaddr_storage_to_str ( addr ) . str ) ;
return 7 ;
return 7 ;
}
}
uint8_t flags = pkt - > data [ 1 ] ;
uint64_t nonce = be64toh ( * ( uint64_t * ) ( pkt - > data + 9 ) ) ;
uint64_t peer_id = be64toh ( * ( uint64_t * ) ( pkt - > data + 2 ) ) ;
uint16_t ulen = be16toh ( * ( uint16_t * ) ( pkt - > data + 17 ) ) ;
uint64_t nonce = be64toh ( * ( uint64_t * ) ( pkt - > data + 10 ) ) ;
const uint8_t * udata = ( ulen > 0 ) ? ( pkt - > data + 19 ) : NULL ;
uint16_t ulen = be16toh ( * ( uint16_t * ) ( pkt - > data + 18 ) ) ;
const uint8_t * udata = ( ulen > 0 ) ? ( pkt - > data + 20 ) : NULL ;
if ( ( flags & ETCP_PING_FLAG_SEND_RTT ) & & ulen > = 2 ) {
uint16_t rtt_val = be16toh ( * ( uint16_t * ) udata ) ;
topo_node_ping_update_rtt ( e_sock - > instance - > topo_groups , peer_id , rtt_val ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " PING rtt=%u from peer=%016llx " , ( unsigned ) rtt_val , ( unsigned long long ) peer_id ) ;
}
uint8_t pong_flags = 0 ;
if ( e_sock - > instance - > topo_groups & & topo_node_ping_request_cbk ( e_sock - > instance - > topo_groups , peer_id ) )
pong_flags | = ETCP_PING_FLAG_WANT_RTT ;
struct ETCP_DGRAM * resp = u_malloc ( PACKET_DATA_SIZE ) ;
struct ETCP_DGRAM * resp = u_malloc ( PACKET_DATA_SIZE ) ;
if ( resp ) {
if ( resp ) {
resp - > link = NULL ;
resp - > link = NULL ;
resp - > noencrypt_len = SC_PUBKEY_ENC_SIZE ;
resp - > noencrypt_len = SC_PUBKEY_ENC_SIZE ;
uint8_t * p = resp - > data ;
uint8_t * p = resp - > data ;
* p + + = ETCP_PONG ;
* p + + = ETCP_PONG ;
* p + + = pong_flags ;
uint64_t nid = htobe64 ( e_sock - > instance - > node_id ) ;
uint64_t nid = htobe64 ( e_sock - > instance - > node_id ) ;
memcpy ( p , & nid , 8 ) ; p + = 8 ;
memcpy ( p , & nid , 8 ) ; p + = 8 ;
uint64_t n = htobe64 ( nonce ) ;
uint64_t n = htobe64 ( nonce ) ;
@ -1169,8 +1152,8 @@ static int handle_ping(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
sc_context_t resp_sc ;
sc_context_t resp_sc ;
sc_init_ctx ( & resp_sc , & e_sock - > instance - > my_keys ) ;
sc_init_ctx ( & resp_sc , & e_sock - > instance - > my_keys ) ;
if ( sc_set_peer_public_key ( & resp_sc , decrypted_pubkey , SC_PEER_PUBKEY_BIN ) = = SC_OK ) {
if ( sc_set_peer_public_key ( & resp_sc , decrypted_pubkey , SC_PEER_PUBKEY_BIN ) = = SC_OK ) {
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " PONG send nonce=%016llx flags=%02x to=%s fd=%d " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " PONG send nonce=%016llx to=%s fd=%d " ,
( unsigned long long ) nonce , ( unsigned ) pong_flags , sockaddr_storage_to_str ( addr ) . str , e_sock - > fd ) ;
( unsigned long long ) nonce , sockaddr_storage_to_str ( addr ) . str , e_sock - > fd ) ;
etcp_send_ping_raw ( resp , e_sock - > fd , & resp_sc , addr ) ;
etcp_send_ping_raw ( resp , e_sock - > fd , & resp_sc , addr ) ;
}
}
u_free ( resp ) ;
u_free ( resp ) ;
@ -1179,28 +1162,22 @@ static int handle_ping(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
return 0 ;
return 0 ;
}
}
static void rtt_send_ping_cb ( int success , uint16_t rtt , void * arg , uint64_t nonce ,
const uint8_t * resp_data , size_t resp_data_len ) {
( void ) success ; ( void ) rtt ; ( void ) arg ; ( void ) nonce ; ( void ) resp_data ; ( void ) resp_data_len ;
}
static int handle_pong ( struct ETCP_SOCKET * e_sock , struct ETCP_DGRAM * pkt , const struct sockaddr_storage * addr , size_t pkt_len ) {
static int handle_pong ( struct ETCP_SOCKET * e_sock , struct ETCP_DGRAM * pkt , const struct sockaddr_storage * addr , size_t pkt_len ) {
if ( pkt_len < 23 ) {
if ( pkt_len < 20 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " PONG too short: pkt_len=%zu from %s " , pkt_len , sockaddr_storage_to_str ( addr ) . str ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " PONG too short: pkt_len=%zu from %s " , pkt_len , sockaddr_storage_to_str ( addr ) . str ) ;
return 7 ;
return 7 ;
}
}
uint8_t flags = pkt - > data [ 1 ] ;
uint64_t nonce = be64toh ( * ( uint64_t * ) ( pkt - > data + 9 ) ) ;
uint64_t nonce = be64toh ( * ( uint64_t * ) ( pkt - > data + 10 ) ) ;
uint16_t ulen = 0 ;
uint16_t ulen = 0 ;
const uint8_t * udata = NULL ;
const uint8_t * udata = NULL ;
if ( pkt - > data_len > = 20 ) {
if ( pkt - > data_len > = 19 ) {
ulen = be16toh ( * ( uint16_t * ) ( pkt - > data + 18 ) ) ;
ulen = be16toh ( * ( uint16_t * ) ( pkt - > data + 17 ) ) ;
if ( ulen > 0 & & pkt - > data_len > = 20 + ulen ) {
if ( ulen > 0 & & pkt - > data_len > = 19 + ulen ) {
udata = pkt - > data + 20 ;
udata = pkt - > data + 19 ;
}
}
}
}
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " PONG recv nonce=%016llx flags=%02x data_len=%u from=%s socket=%s " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " PONG recv nonce=%016llx data_len=%u from=%s socket=%s " ,
( unsigned long long ) nonce , ( unsigned ) flags , ( unsigned ) pkt - > data_len ,
( unsigned long long ) nonce , ( unsigned ) pkt - > data_len ,
sockaddr_storage_to_str ( addr ) . str , e_sock - > name ) ;
sockaddr_storage_to_str ( addr ) . str , e_sock - > name ) ;
struct PING_CONTEXT * ctx = e_sock - > instance - > pending_pings ;
struct PING_CONTEXT * ctx = e_sock - > instance - > pending_pings ;
struct PING_CONTEXT * prev = NULL ;
struct PING_CONTEXT * prev = NULL ;
@ -1216,21 +1193,9 @@ static int handle_pong(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
}
}
uint64_t now = get_time_tb ( ) ;
uint64_t now = get_time_tb ( ) ;
uint16_t rtt = ( now > = ctx - > send_time ) ? ( uint16_t ) ( now - ctx - > send_time ) : 0 ;
uint16_t rtt = ( now > = ctx - > send_time ) ? ( uint16_t ) ( now - ctx - > send_time ) : 0 ;
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " PONG matched nonce=%016llx rtt=%u want_rtt=%d " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_CONNECTION , " PONG matched nonce=%016llx rtt=%u " ,
( unsigned long long ) nonce , ( unsigned ) rtt , ( flags & ETCP_PING_FLAG_WANT_RTT ) ? 1 : 0 ) ;
( unsigned long long ) nonce , ( unsigned ) rtt ) ;
uint64_t pong_peer_id = be64toh ( * ( uint64_t * ) ( pkt - > data + 2 ) ) ;
topo_node_ping_update_rtt ( e_sock - > instance - > topo_groups , pong_peer_id , rtt ) ;
ctx - > cb ( 1 , rtt , ctx - > arg , nonce , udata , ulen ) ;
ctx - > cb ( 1 , rtt , ctx - > arg , nonce , udata , ulen ) ;
if ( ( flags & ETCP_PING_FLAG_WANT_RTT ) & & ctx - > peer_pubkey [ 0 ] ! = 0 ) {
uint8_t rtt_buf [ 2 ] ;
rtt_buf [ 0 ] = ( uint8_t ) ( rtt > > 8 ) ;
rtt_buf [ 1 ] = ( uint8_t ) ( rtt & 0xFF ) ;
etcp_send_ping_to_socket ( e_sock - > instance , e_sock , ctx - > peer_pubkey , addr , 1000 ,
rtt_send_ping_cb , NULL , rtt_buf , 2 , ETCP_PING_FLAG_SEND_RTT ) ;
}
if ( ctx - > user_data ) u_free ( ctx - > user_data ) ;
if ( ctx - > user_data ) u_free ( ctx - > user_data ) ;
u_free ( ctx ) ;
u_free ( ctx ) ;
break ;
break ;
@ -1615,7 +1580,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
pkt - > data_len = pkt_len - 3 ;
pkt - > data_len = pkt_len - 3 ;
pkt - > noencrypt_len = 0 ;
pkt - > noencrypt_len = 0 ;
uint8_t code = pkt - > data [ 0 ] ;
uint8_t code = pkt - > data [ 0 ] ;
uint64_t peer_id = be64toh ( * ( uint64_t * ) ( pkt - > data + 2 ) ) ;
uint64_t peer_id = be64toh ( * ( uint64_t * ) ( pkt - > data + 1 ) ) ;
if ( code = = ETCP_PING ) {
if ( code = = ETCP_PING ) {
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTION , " X25519 decrypted: PING from peer=0x%016llx src=%s " ,
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTION , " X25519 decrypted: PING from peer=0x%016llx src=%s " ,
( unsigned long long ) peer_id , sockaddr_storage_to_str ( & addr ) . str ) ;
( unsigned long long ) peer_id , sockaddr_storage_to_str ( & addr ) . str ) ;