@ -445,6 +445,18 @@ es_err:
static void etcp_connections_read_callback ( int fd , void * arg ) {
static void etcp_connections_read_callback ( int fd , void * arg ) {
// !!!!!! DANGER: в этой функции ПРЕДЕЛЬНАЯ АККУРАТНОСТЬ. Если кажется что не туда указатель то невнимательно аланизировал !!!!!
// !!!!!! DANGER: в этой функции ПРЕДЕЛЬНАЯ АККУРАТНОСТЬ. Если кажется что не туда указатель то невнимательно аланизировал !!!!!
// НЕ РУИНИТЬ (uint8_t*)&pkt->timestamp - это правильно !!!!
// НЕ РУИНИТЬ (uint8_t*)&pkt->timestamp - это правильно !!!!
//
// Ошибки функции (errorcode):
// 1 - пакет слишком маленький для init (< SC_PUBKEY_SIZE)
// 2 - не удалось установить peer public key при init
// 3 - не удалось расшифровать init пакет
// 4 - не init пакет (неверный код)
// 5 - коллизия peer ID и ключей
// 6 - не удалось расшифровать обычный пакет
// 13 - переполнение при парсинге пакета
// 46 - расшифрованный пакет слишком маленький (< 3 байта)
// 55 - не удалось создать подключение
// 66 - не удалось создать линк
struct ETCP_SOCKET * e_sock = ( struct ETCP_SOCKET * ) arg ;
struct ETCP_SOCKET * e_sock = ( struct ETCP_SOCKET * ) arg ;
if ( ! e_sock ) return ;
if ( ! e_sock ) return ;
@ -458,6 +470,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
if ( recv_len < = 0 ) {
if ( recv_len < = 0 ) {
printf ( " [ETCP] recvfrom failed or no data, recv_len=%zd, errno=%d \n " , recv_len , errno ) ;
printf ( " [ETCP] recvfrom failed or no data, recv_len=%zd, errno=%d \n " , recv_len , errno ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " etcp_connections_read_callback: recvfrom failed, error=%zd, errno=%d " , recv_len , errno ) ;
return ;
return ;
}
}
@ -476,7 +489,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
if ( link = = NULL ) { // пробуем расшифровать, возможно это init
if ( link = = NULL ) { // пробуем расшифровать, возможно это init
// printf("[ETCP DEBUG] No existing link found, trying to decrypt as INIT packet\n");
// printf("[ETCP DEBUG] No existing link found, trying to decrypt as INIT packet\n");
struct secure_channel sc ;
struct secure_channel sc ;
if ( recv_len < = SC_PUBKEY_SIZE ) { errorcode = 1 ; goto ec_fr ; }
if ( recv_len < = SC_PUBKEY_SIZE ) { errorcode = 1 ; DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " etcp_connections_read_callback: packet too small for init, size=%zd " , recv_len ) ; goto ec_fr ; }
sc_init_ctx ( & sc , & e_sock - > instance - > my_keys ) ;
sc_init_ctx ( & sc , & e_sock - > instance - > my_keys ) ;
// printf("[ETCP DEBUG] Extracting peer public key from position %ld, total packet size=%zd\n", recv_len-SC_PUBKEY_SIZE, recv_len);
// printf("[ETCP DEBUG] Extracting peer public key from position %ld, total packet size=%zd\n", recv_len-SC_PUBKEY_SIZE, recv_len);
// printf("[ETCP DEBUG] Last 64 bytes of packet (PUBKEY): ");
// printf("[ETCP DEBUG] Last 64 bytes of packet (PUBKEY): ");
@ -504,7 +517,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
} * ack_hdr = ( void * ) & pkt - > data [ 0 ] ;
} * ack_hdr = ( void * ) & pkt - > data [ 0 ] ;
uint64_t peer_id ;
uint64_t peer_id ;
memcpy ( & peer_id , & ack_hdr - > id [ 0 ] , 8 ) ;
memcpy ( & peer_id , & ack_hdr - > id [ 0 ] , 8 ) ;
if ( ack_hdr - > code ! = ETCP_INIT_REQUEST & & ack_hdr - > code ! = ETCP_CHANNEL_INIT ) { errorcode = 4 ; goto ec_fr ; } // не init
if ( ack_hdr - > code ! = ETCP_INIT_REQUEST & & ack_hdr - > code ! = ETCP_CHANNEL_INIT ) { errorcode = 4 ; DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " etcp_connections_read_callback: not an init packet, code=%02x " , ack_hdr - > code ) ; goto ec_fr ; } // не init
struct ETCP_CONN * conn = e_sock - > instance - > connections ;
struct ETCP_CONN * conn = e_sock - > instance - > connections ;
while ( conn ) { // ищем есть ли подключение к этому пиру
while ( conn ) { // ищем есть ли подключение к этому пиру
@ -516,15 +529,15 @@ static void etcp_connections_read_callback(int fd, void* arg) {
if ( ! conn | | conn - > peer_node_id ! = peer_id ) { // создаём новое
if ( ! conn | | conn - > peer_node_id ! = peer_id ) { // создаём новое
new_conn = 1 ;
new_conn = 1 ;
conn = etcp_connection_create ( e_sock - > instance ) ;
conn = etcp_connection_create ( e_sock - > instance ) ;
if ( ! conn ) { errorcode = 55 ; goto ec_fr ; } // облом
if ( ! conn ) { errorcode = 55 ; DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " etcp_connections_read_callback: failed to create connection " ) ; goto ec_fr ; } // облом
memcpy ( & conn - > crypto_ctx , & sc , sizeof ( sc ) ) ; // добавляем ключ
memcpy ( & conn - > crypto_ctx , & sc , sizeof ( sc ) ) ; // добавляем ключ
conn - > peer_node_id = peer_id ;
conn - > peer_node_id = peer_id ;
}
}
else { // check keys если существующее подключение
else { // check keys если существующее подключение
if ( memcmp ( conn - > crypto_ctx . peer_public_key , sc . peer_public_key , SC_PUBKEY_SIZE ) ) { errorcode = 5 ; goto ec_fr ; } // коллизия - peer id совпал а ключи разные.
if ( memcmp ( conn - > crypto_ctx . peer_public_key , sc . peer_public_key , SC_PUBKEY_SIZE ) ) { errorcode = 5 ; DEBUG_ERROR ( DEBUG_CATEGORY_CRYPTO , " etcp_connections_read_callback: peer key mismatch for node %llu " , ( unsigned long long ) peer_id ) ; goto ec_fr ; } // коллизия - peer id совпал а ключи разные.
}
}
struct ETCP_LINK * link = etcp_link_new ( conn , e_sock , & addr , 1 ) ;
struct ETCP_LINK * link = etcp_link_new ( conn , e_sock , & addr , 1 ) ;
if ( ! link ) { if ( new_conn ) etcp_connection_close ( conn ) ; errorcode = 66 ; goto ec_fr ; } // облом
if ( ! link ) { if ( new_conn ) etcp_connection_close ( conn ) ; errorcode = 66 ; DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " etcp_connections_read_callback: failed to create link for connection " ) ; goto ec_fr ; } // облом
if ( ack_hdr - > code = = 0x02 ) etcp_conn_reset ( conn ) ;
if ( ack_hdr - > code = = 0x02 ) etcp_conn_reset ( conn ) ;
struct {
struct {
@ -553,7 +566,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
errorcode = 6 ;
errorcode = 6 ;
goto ec_fr ;
goto ec_fr ;
}
}
if ( pkt_len < 3 ) { errorcode = 46 ; goto ec_fr ; }
if ( pkt_len < 3 ) { errorcode = 46 ; DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " etcp_connections_read_callback: decrypted packet too small, size=%zu " , pkt_len ) ; goto ec_fr ; }
pkt - > data_len = pkt_len - 2 ;
pkt - > data_len = pkt_len - 2 ;
pkt - > noencrypt_len = 0 ;
pkt - > noencrypt_len = 0 ;
pkt - > link = link ;
pkt - > link = link ;
@ -572,7 +585,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
server_node_id = ( server_node_id < < 8 ) | pkt - > data [ offset + + ] ;
server_node_id = ( server_node_id < < 8 ) | pkt - > data [ offset + + ] ;
}
}
link - > mtu = ( pkt - > data [ offset + + ] < < 8 ) | pkt - > data [ offset + + ] ;
link - > mtu = ( pkt - > data [ offset + + ] < < 8 ) | pkt - > data [ offset + + ] ;
if ( offset > pkt_len ) { errorcode = 13 ; goto ec_fr ; }
if ( offset > pkt_len ) { errorcode = 13 ; DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " etcp_connections_read_callback: packet parsing overflow, offset=%zu, pkt_len=%zu " , offset , pkt_len ) ; goto ec_fr ; }
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTION , " Received INIT_RESPONSE from server_node_id=%llu, mtu=%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTION , " Received INIT_RESPONSE from server_node_id=%llu, mtu=%d " ,
( unsigned long long ) server_node_id , link - > mtu ) ;
( unsigned long long ) server_node_id , link - > mtu ) ;
@ -601,7 +614,6 @@ static void etcp_connections_read_callback(int fd, void* arg) {
ec_fr :
ec_fr :
printf ( " etcp_connections_read_callback: error %d \n " , errorcode ) ;
printf ( " etcp_connections_read_callback: error %d \n " , errorcode ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_CRYPTO , " etcp_connections_read_callback: error %d " , errorcode ) ;
e_sock - > pkt_format_errors + + ;
e_sock - > pkt_format_errors + + ;
e_sock - > errorcode = errorcode ;
e_sock - > errorcode = errorcode ;
memory_pool_free ( e_sock - > instance - > pkt_pool , pkt ) ;
memory_pool_free ( e_sock - > instance - > pkt_pool , pkt ) ;