@ -1,11 +1,11 @@
/**
/**
* @ file nat_detection . c
* @ file nat_detection . c
* @ brief NAT - д е т е к ц и я : STUN - like п р о в е р к а ч е р е з т р е т ь е г о BGP - п и р а .
* @ brief NAT - д е т е к ц и я : STUN - like п р о в е р к а ч е р е з т р е т ь е г о п и р а .
*
*
* С а м о д о с т а т о ч н ы й м о д у л ь :
* С а м о д о с т а т о ч н ы й м о д у л ь :
* - С а м б и н д и т с я н а ETCP_ID_NAT_DETECTION ( 0x02 ) и п р и н и м а е т с в о и п а к е т ы
* - С а м б и н д и т с я н а ETCP_ID_NAT_DETECTION ( 0x02 ) и п р и н и м а е т с в о и п а к е т ы
* - С а м п о д п и с ы в а е т с я н а on_down н о в ы х ETCP - с о е д и н е н и й ( о т м е н а pending )
* - С а м п о д п и с ы в а е т с я н а c onn_up / con n_down н о в ы х ETCP - с о е д и н е н и й
* - П о л у ч а е т trigger_checks и з topo_group п о с л е з а п о л н е н и я senders_list
* - И щ е т т р е т и й у з е л п р я м о в instance - > connections ( б е з п р и в я з к и к BGP - г р у п п е )
*/
*/
# include <stdlib.h>
# include <stdlib.h>
# include <string.h>
# include <string.h>
@ -33,16 +33,16 @@
/* ====== Internal NAT check logic ====== */
/* ====== Internal NAT check logic ====== */
static struct ETCP_CONN * nat_check_find_third_node ( struct TOPO_GROUP * group , struct ETCP_CONN * exclude ) {
static struct ETCP_CONN * nat_check_find_third_node ( struct NAT_DETECTION * nd , struct ETCP_CONN * exclude ) {
if ( ! group | | ! group - > senders_list ) return NULL ;
if ( ! nd | | ! nd - > inst | | ! nd - > inst - > connections ) return NULL ;
struct ll_entry * e = group - > senders_list - > head ;
struct ll_entry * e = nd - > inst - > connections - > head ;
while ( e ) {
while ( e ) {
struct TOPO_GROUP_CONN_ITEM * item = ( struct TOPO_GROUP_CONN_ITEM * ) e - > data ;
struct conn_queue_entry * ce = ( struct conn_queue_entry * ) e - > data ;
if ( item & & it em - > conn & & item - > conn ! = exclude & & item - > conn - > links
if ( c e- > conn & & ce - > conn ! = exclude & & ce - > conn - > links
& & item - > conn - > links - > remote_only_local = = 0
& & ce - > conn - > links - > remote_only_local = = 0
& & item - > conn - > links - > remote_type ! = CFG_SERVER_TYPE_PRIVATE
& & ce - > conn - > links - > remote_type ! = CFG_SERVER_TYPE_PRIVATE
& & item - > conn - > links - > remote_type ! = CFG_SERVER_TYPE_LOCAL )
& & ce - > conn - > links - > remote_type ! = CFG_SERVER_TYPE_LOCAL )
return item - > conn ;
return ce - > conn ;
e = e - > next ;
e = e - > next ;
}
}
return NULL ;
return NULL ;
@ -69,15 +69,14 @@ static void nat_link_check_cb(int success, uint16_t avg_rtt, uint8_t count_sent,
u_free ( na ) ;
u_free ( na ) ;
}
}
static void nat_detection_start_link_check ( struct NAT_DETECTION * nd , struct TOPO_GROUP * group ,
static void nat_detection_start_link_check ( struct NAT_DETECTION * nd , struct ETCP_LINK * link ) {
struct ETCP_LINK * link ) {
if ( ! nd | | ! link | | ! link - > conn | | ! link - > etcp ) return ;
if ( ! nd | | ! group | | ! link | | ! link - > conn | | ! link - > etcp ) return ;
if ( link - > nat_type = = NAT_TYPE_DIRECT ) return ;
if ( link - > nat_type = = NAT_TYPE_DIRECT ) return ;
if ( link - > nat_check_status = = NAT_CHECK_IN_PROGRESS ) return ;
if ( link - > nat_check_status = = NAT_CHECK_IN_PROGRESS ) return ;
if ( link - > conn - > type = = CFG_SERVER_TYPE_PRIVATE | | link - > conn - > type = = CFG_SERVER_TYPE_LOCAL ) {
if ( link - > conn - > type = = CFG_SERVER_TYPE_PRIVATE | | link - > conn - > type = = CFG_SERVER_TYPE_LOCAL ) {
DEBUG_DEBUG ( DEBUG_CATEGORY_BGP , " skip nat check for private/local socket link " ) ; return ;
DEBUG_DEBUG ( DEBUG_CATEGORY_BGP , " skip nat check for private/local socket link " ) ; return ;
}
}
struct ETCP_CONN * third_conn = nat_check_find_third_node ( group , link - > etcp ) ;
struct ETCP_CONN * third_conn = nat_check_find_third_node ( nd , link - > etcp ) ;
if ( ! third_conn ) { DEBUG_DEBUG ( DEBUG_CATEGORY_BGP , " no third node found for link " ) ; return ; }
if ( ! third_conn ) { DEBUG_DEBUG ( DEBUG_CATEGORY_BGP , " no third node found for link " ) ; return ; }
uint32_t target_ip ; uint16_t target_port ;
uint32_t target_ip ; uint16_t target_port ;
@ -92,6 +91,8 @@ static void nat_detection_start_link_check(struct NAT_DETECTION* nd, struct TOPO
ip_to_str ( & target_ip , AF_INET ) . str ) ; return ;
ip_to_str ( & target_ip , AF_INET ) . str ) ; return ;
}
}
struct TOPO_GROUP * group = topo_groups_get_default ( nd - > inst - > topo_groups ) ;
if ( ! group ) return ;
struct nat_check_arg * arg = u_calloc ( 1 , sizeof ( struct nat_check_arg ) ) ;
struct nat_check_arg * arg = u_calloc ( 1 , sizeof ( struct nat_check_arg ) ) ;
if ( ! arg ) return ;
if ( ! arg ) return ;
arg - > link = link ; arg - > nat_ip = target_ip ; arg - > nat_port = target_port ;
arg - > link = link ; arg - > nat_ip = target_ip ; arg - > nat_port = target_port ;
@ -204,12 +205,20 @@ static void nat_detection_handle_nat_check_req(struct NAT_DETECTION* nd, struct
}
}
if ( ! target_link ) return ;
if ( ! target_link ) return ;
if ( target_link - > nat_check_status = = NAT_CHECK_IN_PROGRESS ) return ;
if ( target_link - > nat_check_status = = NAT_CHECK_IN_PROGRESS ) return ;
nat_detection_start_link_check ( nd , group , target_link ) ;
nat_detection_start_link_check ( nd , target_link ) ;
}
}
/* ====== ETCP callbacks (self-registering) ====== */
/* ====== ETCP callbacks (self-registering) ====== */
static void nat_detection_trigger_checks ( struct NAT_DETECTION * nd ) ;
static void nat_detection_on_conn_up ( struct ETCP_CONN * conn , void * arg ) {
struct NAT_DETECTION * nd = ( struct NAT_DETECTION * ) arg ;
if ( ! nd ) return ;
nat_detection_trigger_checks ( nd ) ;
}
static void nat_detection_on_conn_down ( struct ETCP_CONN * conn , void * arg ) {
static void nat_detection_on_conn_down ( struct ETCP_CONN * conn , void * arg ) {
struct NAT_DETECTION * nd = ( struct NAT_DETECTION * ) arg ;
struct NAT_DETECTION * nd = ( struct NAT_DETECTION * ) arg ;
if ( ! nd | | ! conn ) return ;
if ( ! nd | | ! conn ) return ;
@ -225,6 +234,7 @@ static void nat_detection_new_conn_cbk(struct ETCP_CONN* conn, void* arg) {
if ( ! conn | | ! conn - > instance ) return ;
if ( ! conn | | ! conn - > instance ) return ;
struct NAT_DETECTION * nd = ( struct NAT_DETECTION * ) arg ;
struct NAT_DETECTION * nd = ( struct NAT_DETECTION * ) arg ;
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " NAT detection set callbacks: %s " , conn - > log_name ) ;
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " NAT detection set callbacks: %s " , conn - > log_name ) ;
etcp_conn_add_up_cbk ( conn , nat_detection_on_conn_up , nd ) ;
etcp_conn_add_down_cbk ( conn , nat_detection_on_conn_down , nd ) ;
etcp_conn_add_down_cbk ( conn , nat_detection_on_conn_down , nd ) ;
}
}
@ -274,17 +284,17 @@ static void nat_detection_receive_cbk(struct ETCP_CONN* from_conn, struct ll_ent
}
}
/* ====== NAT check trigger (called from topo_group after senders_list updated) ====== */
/* ====== NAT check trigger ====== */
void nat_detection_trigger_checks ( struct NAT_DETECTION * nd , struct TOPO_GROUP * group ) {
static void nat_detection_trigger_checks ( struct NAT_DETECTION * nd ) {
if ( ! nd | | ! group | | ! nd - > inst ) return ;
if ( ! nd | | ! nd - > inst ) return ;
struct ll_entry * entry = nd - > inst - > connections - > head ;
struct ll_entry * entry = nd - > inst - > connections - > head ;
while ( entry ) {
while ( entry ) {
struct conn_queue_entry * ce = ( struct conn_queue_entry * ) entry - > data ;
struct conn_queue_entry * ce = ( struct conn_queue_entry * ) entry - > data ;
struct ETCP_LINK * l = ce - > conn - > links ;
struct ETCP_LINK * l = ce - > conn - > links ;
while ( l ) {
while ( l ) {
if ( l - > initialized & & l - > conn & & l - > nat_check_status < NAT_CHECK_IN_PROGRESS )
if ( l - > initialized & & l - > conn & & l - > nat_check_status < NAT_CHECK_IN_PROGRESS )
nat_detection_start_link_check ( nd , group , l ) ;
nat_detection_start_link_check ( nd , l ) ;
l = l - > next ;
l = l - > next ;
}
}
entry = entry - > next ;
entry = entry - > next ;
@ -319,11 +329,10 @@ void nat_detection_destroy(struct NAT_DETECTION* nd) {
/* ====== Link lifecycle ====== */
/* ====== Link lifecycle ====== */
void nat_detection_link_ready ( struct NAT_DETECTION * nd , struct TOPO_GROUP * group ,
void nat_detection_link_ready ( struct NAT_DETECTION * nd , struct ETCP_LINK * link ) {
struct ETCP_LINK * link ) {
if ( ! nd | | ! link ) return ;
if ( ! nd | | ! group | | ! link ) return ;
if ( link - > nat_check_status < NAT_CHECK_IN_PROGRESS )
if ( link - > nat_check_status < NAT_CHECK_IN_PROGRESS )
nat_detection_start_link_check ( nd , group , link ) ;
nat_detection_start_link_check ( nd , link ) ;
}
}
void nat_detection_cancel_for_conn ( struct NAT_DETECTION * nd , struct ETCP_CONN * conn ) {
void nat_detection_cancel_for_conn ( struct NAT_DETECTION * nd , struct ETCP_CONN * conn ) {
@ -386,21 +395,19 @@ static void nat_detection_send_nat_check_req(struct NAT_DETECTION* nd, struct ET
/* ====== Control API ====== */
/* ====== Control API ====== */
void nat_detection_request_check_all ( struct NAT_DETECTION * nd , struct TOPO_GROUP * group ) {
void nat_detection_request_check_all ( struct NAT_DETECTION * nd ) {
if ( ! nd | | ! group | | ! group - > instance ) return ;
if ( ! nd | | ! nd - > inst ) return ;
int count = 0 ;
struct ll_entry * entry = nd - > inst - > connections - > head ;
struct ll_entry * entry = group - > instance - > connections - > head ;
while ( entry ) {
while ( entry ) {
struct conn_queue_entry * ce = ( struct conn_queue_entry * ) entry - > data ;
struct conn_queue_entry * ce = ( struct conn_queue_entry * ) entry - > data ;
struct ETCP_LINK * link = ce - > conn - > links ;
struct ETCP_LINK * link = ce - > conn - > links ;
while ( link ) {
while ( link ) {
if ( link - > nat_check_status < NAT_CHECK_IN_PROGRESS )
if ( link - > nat_check_status < NAT_CHECK_IN_PROGRESS )
nat_detection_start_link_check ( nd , group , link ) ;
nat_detection_start_link_check ( nd , link ) ;
count + + ; link = link - > next ;
link = link - > next ;
}
}
entry = entry - > next ;
entry = entry - > next ;
}
}
( void ) count ;
}
}