@ -282,19 +282,6 @@ static struct stcp_server* create_iface_tcp_socket(struct AUTO_SOCKET* as, uint3
for ( int attempt = 0 ; attempt < max_att ; attempt + + ) {
uint16_t port = ( attempt = = 0 & & saved_port ) ? saved_port : random_port ( ) ;
struct stcp_server * tsrv = stcp_server_listen ( & scfg , port , tcp_server_on_link , inst ) ;
if ( ! tsrv ) {
if ( attempt = = 0 & & saved_port )
DEBUG_WARN ( DEBUG_CATEGORY_AS , " [as] TCP reuse port failed if=%s fam=%d port=%u — trying random " , ifname , family , port ) ;
else
DEBUG_WARN ( DEBUG_CATEGORY_AS , " [as] TCP socket create failed if=%s fam=%d port=%u att=%d err=%d " ,
ifname , family , port , attempt + 1 , socket_get_error ( ) ) ;
if ( socket_get_error ( ) ! = EADDRINUSE ) return NULL ;
continue ;
}
stcp_server_list_add ( inst , tsrv ) ;
struct CFG_SERVER server ;
memset ( & server , 0 , sizeof ( server ) ) ;
snprintf ( server . name , sizeof ( server . name ) , " as_%s_%s_tcp " , ifname , family = = AF_INET6 ? " v6 " : " v4 " ) ;
@ -303,27 +290,37 @@ static struct stcp_server* create_iface_tcp_socket(struct AUTO_SOCKET* as, uint3
server . transport = 1 ;
if ( family = = AF_INET ) {
struct sockaddr_in * sin = ( struct sockaddr_in * ) & server . ip ;
sin - > sin_family = AF_INET ;
sin - > sin_addr . s_addr = INADDR_ANY ;
sin - > sin_port = htons ( port ) ;
sin - > sin_family = AF_INET ; sin - > sin_addr . s_addr = INADDR_ANY ; sin - > sin_port = htons ( port ) ;
} else {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) & server . ip ;
sin6 - > sin6_family = AF_INET6 ;
sin6 - > sin6_addr = in6addr_any ;
sin6 - > sin6_port = htons ( port ) ;
sin6 - > sin6_family = AF_INET6 ; sin6 - > sin6_addr = in6addr_any ; sin6 - > sin6_port = htons ( port ) ;
}
struct TCP_SOCKET * ts = tcp_socket_add ( inst , & server ) ;
{ const struct sockaddr_storage * ia = ( ts & & ts - > interface_addr . ss_family ) ? & ts - > interface_addr : & ts - > local_addr ;
if ( ! ts | | ( ia - > ss_family = = AF_INET & & ( ( struct sockaddr_in * ) ia ) - > sin_addr . s_addr = = INADDR_ANY ) | |
( ia - > ss_family = = AF_INET6 & & IN6_IS_ADDR_UNSPECIFIED ( & ( ( struct sockaddr_in6 * ) ia ) - > sin6_addr ) ) ) {
struct ETCP_SOCKET * ts = tcp_socket_add ( inst , & server ) ;
if ( ! ts ) { DEBUG_WARN ( DEBUG_CATEGORY_AS , " [as] TCP tcp_socket_add failed if=%s fam=%d port=%u " , ifname , family , port ) ; continue ; }
{ const struct sockaddr_storage * ia = ( ts - > interface_addr . ss_family ) ? & ts - > interface_addr : & ts - > local_addr ;
if ( ( ia - > ss_family = = AF_INET & & ( ( const struct sockaddr_in * ) ia ) - > sin_addr . s_addr = = INADDR_ANY ) | |
( ia - > ss_family = = AF_INET6 & & IN6_IS_ADDR_UNSPECIFIED ( & ( ( const struct sockaddr_in6 * ) ia ) - > sin6_addr ) ) ) {
DEBUG_INFO ( DEBUG_CATEGORY_AS , " [as] TCP socket %s has null addr — removing " , server . name ) ;
if ( ts ) tcp_socket_remove ( ts ) ;
stcp_server_list_remove ( inst , tsrv ) ;
stcp_link_server_destroy ( tsrv ) ; continue ;
tcp_socket_remove ( ts ) ; continue ;
}
}
struct stcp_server * tsrv = stcp_server_listen ( & scfg , port , tcp_server_on_link , ts ) ;
if ( ! tsrv ) {
if ( attempt = = 0 & & saved_port )
DEBUG_WARN ( DEBUG_CATEGORY_AS , " [as] TCP reuse port failed if=%s fam=%d port=%u — trying random " , ifname , family , port ) ;
else
DEBUG_WARN ( DEBUG_CATEGORY_AS , " [as] TCP socket create failed if=%s fam=%d port=%u att=%d err=%d " ,
ifname , family , port , attempt + 1 , socket_get_error ( ) ) ;
tcp_socket_remove ( ts ) ;
if ( socket_get_error ( ) ! = EADDRINUSE ) return NULL ;
continue ;
}
stcp_server_list_add ( inst , tsrv ) ;
save_port_to_db ( as , ifname , family , AS_PROTO_TCP , port ) ;
DEBUG_INFO ( DEBUG_CATEGORY_AS , " [as] TCP socket created: if=%s(%u) type=%d port=%u " , ifname , ifindex , type , port ) ;
@ -413,12 +410,12 @@ static void remove_iface_sockets(struct AUTO_SOCKET* as, uint32_t ifindex) {
if ( ifa - > v4_tcp ) {
DEBUG_INFO ( DEBUG_CATEGORY_AS , " [as] removing v4 TCP socket ifidx=%u " , ifindex ) ;
{ uint16_t v4_port = load_port_from_db ( as , ifname , AF_INET , AS_PROTO_TCP ) ;
struct TCP_SOCKET * * tsp = & as - > instance - > tcp_sockets ;
struct E TCP_SOCKET* * tsp = & as - > instance - > tcp_sockets ;
while ( * tsp ) {
uint16_t tsp_port = 0 ;
const struct sockaddr_storage * addr = ( * tsp ) - > interface_addr . ss_family ? & ( * tsp ) - > interface_addr : & ( * tsp ) - > local_addr ;
if ( addr - > ss_family = = AF_INET ) tsp_port = ntohs ( ( ( struct sockaddr_in * ) addr ) - > sin_port ) ;
if ( tsp_port = = v4_port & & v4_port > 0 ) { struct TCP_SOCKET * rm = * tsp ; * tsp = rm - > next ; u_free ( rm ) ; break ; }
if ( tsp_port = = v4_port & & v4_port > 0 ) { struct E TCP_SOCKET* rm = * tsp ; * tsp = rm - > next ; u_free ( rm ) ; break ; }
tsp = & ( * tsp ) - > next ;
}
}
@ -429,12 +426,12 @@ static void remove_iface_sockets(struct AUTO_SOCKET* as, uint32_t ifindex) {
if ( ifa - > v6_tcp ) {
DEBUG_INFO ( DEBUG_CATEGORY_AS , " [as] removing v6 TCP socket ifidx=%u " , ifindex ) ;
{ uint16_t v6_port = load_port_from_db ( as , ifname , AF_INET6 , AS_PROTO_TCP ) ;
struct TCP_SOCKET * * tsp = & as - > instance - > tcp_sockets ;
struct E TCP_SOCKET* * tsp = & as - > instance - > tcp_sockets ;
while ( * tsp ) {
uint16_t tsp_port = 0 ;
const struct sockaddr_storage * addr = ( * tsp ) - > interface_addr . ss_family ? & ( * tsp ) - > interface_addr : & ( * tsp ) - > local_addr ;
if ( addr - > ss_family = = AF_INET6 ) tsp_port = ntohs ( ( ( struct sockaddr_in6 * ) addr ) - > sin6_port ) ;
if ( tsp_port = = v6_port & & v6_port > 0 ) { struct TCP_SOCKET * rm = * tsp ; * tsp = rm - > next ; u_free ( rm ) ; break ; }
if ( tsp_port = = v6_port & & v6_port > 0 ) { struct E TCP_SOCKET* rm = * tsp ; * tsp = rm - > next ; u_free ( rm ) ; break ; }
tsp = & ( * tsp ) - > next ;
}
}
@ -711,10 +708,10 @@ static void reconcile_iface(struct AUTO_SOCKET* as, uint32_t ifindex, const char
DEBUG_INFO ( DEBUG_CATEGORY_AS , " [as] v4 TCP removed: %s ifidx=%u " , ifname , ifindex ) ;
{ char buf [ IFNAMSIZ ] ; const char * nm = if_indextoname ( ifindex , buf ) ? buf : ifname ;
uint16_t p = load_port_from_db ( as , nm , AF_INET , AS_PROTO_TCP ) ;
struct TCP_SOCKET * * tsp = & as - > instance - > tcp_sockets ;
struct E TCP_SOCKET* * tsp = & as - > instance - > tcp_sockets ;
while ( * tsp ) { uint16_t tp = 0 ; const struct sockaddr_storage * a = ( * tsp ) - > interface_addr . ss_family ? & ( * tsp ) - > interface_addr : & ( * tsp ) - > local_addr ;
if ( a - > ss_family = = AF_INET ) tp = ntohs ( ( ( struct sockaddr_in * ) a ) - > sin_port ) ;
if ( tp = = p & & p > 0 ) { struct TCP_SOCKET * rm = * tsp ; * tsp = rm - > next ; u_free ( rm ) ; break ; } tsp = & ( * tsp ) - > next ; }
if ( tp = = p & & p > 0 ) { struct E TCP_SOCKET* rm = * tsp ; * tsp = rm - > next ; u_free ( rm ) ; break ; } tsp = & ( * tsp ) - > next ; }
}
stcp_server_list_remove ( as - > instance , srv ) ;
stcp_link_server_destroy ( srv ) ;
@ -734,10 +731,10 @@ static void reconcile_iface(struct AUTO_SOCKET* as, uint32_t ifindex, const char
DEBUG_INFO ( DEBUG_CATEGORY_AS , " [as] v6 TCP removed: %s ifidx=%u " , ifname , ifindex ) ;
{ char buf [ IFNAMSIZ ] ; const char * nm = if_indextoname ( ifindex , buf ) ? buf : ifname ;
uint16_t p = load_port_from_db ( as , nm , AF_INET6 , AS_PROTO_TCP ) ;
struct TCP_SOCKET * * tsp = & as - > instance - > tcp_sockets ;
struct E TCP_SOCKET* * tsp = & as - > instance - > tcp_sockets ;
while ( * tsp ) { uint16_t tp = 0 ; const struct sockaddr_storage * a = ( * tsp ) - > interface_addr . ss_family ? & ( * tsp ) - > interface_addr : & ( * tsp ) - > local_addr ;
if ( a - > ss_family = = AF_INET6 ) tp = ntohs ( ( ( struct sockaddr_in6 * ) a ) - > sin6_port ) ;
if ( tp = = p & & p > 0 ) { struct TCP_SOCKET * rm = * tsp ; * tsp = rm - > next ; u_free ( rm ) ; break ; } tsp = & ( * tsp ) - > next ; }
if ( tp = = p & & p > 0 ) { struct E TCP_SOCKET* rm = * tsp ; * tsp = rm - > next ; u_free ( rm ) ; break ; } tsp = & ( * tsp ) - > next ; }
}
stcp_server_list_remove ( as - > instance , srv ) ;
stcp_link_server_destroy ( srv ) ;