@ -122,10 +122,6 @@ static err_t tcp_output_cb(void *arg, struct pbuf *p, uint32_t src_ip, uint32_t
uint32_t sip , dip ; memcpy ( & sip , buf + 12 , 4 ) ; memcpy ( & dip , buf + 16 , 4 ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_TRAFFIC , " TUN_WRITE_ERR ret=%zd len=%u ip_total=%u " , wr , len , ip_total ) ;
}
} else if ( proxy - > ip_fd > = 0 ) {
buf [ 0 ] = ( len > > 8 ) & 0xFF ; buf [ 1 ] = len & 0xFF ;
pbuf_copy_partial ( p , buf + 2 , len , 0 ) ;
ssize_t n = write ( proxy - > ip_fd , buf , 2 + len ) ; ( void ) n ;
}
return LERR_OK ;
}
@ -340,48 +336,8 @@ static void tcp_proxy_ensure_outbound_listen(struct tcp_proxy* p, uint16_t dport
}
// ====================================================================
// Input: IP packet → lwip_tcp
// Input: IP packet → lwip_tcp (from TUN output_queue)
// ====================================================================
static void tcp_proxy_raw_read ( int fd , void * arg ) {
( void ) fd ; struct tcp_proxy * p = ( struct tcp_proxy * ) arg ;
ssize_t n ;
if ( p - > raw_need = = 0 ) {
n = read ( p - > ip_fd , p - > raw_buf + p - > raw_pos , 2 - p - > raw_pos ) ;
if ( n < = 0 ) { if ( n < 0 & & errno = = EAGAIN ) return ; p - > raw_pos = 0 ; return ; }
p - > raw_pos + = n ;
if ( p - > raw_pos < 2 ) return ;
p - > raw_need = ( ( uint16_t ) p - > raw_buf [ 0 ] < < 8 ) | p - > raw_buf [ 1 ] ;
if ( p - > raw_need = = 0 | | p - > raw_need > 2000 ) { p - > raw_pos = 0 ; return ; }
p - > raw_pos = 0 ;
}
n = read ( p - > ip_fd , p - > raw_buf + 2 + p - > raw_pos , p - > raw_need - p - > raw_pos ) ;
if ( n < = 0 ) { if ( n < 0 & & errno = = EAGAIN ) return ; p - > raw_pos = p - > raw_need = 0 ; return ; }
p - > raw_pos + = n ;
if ( p - > raw_pos < p - > raw_need ) return ;
uint8_t * pkt = p - > raw_buf + 2 ;
size_t remaining = p - > raw_need ;
p - > raw_pos = 0 ; p - > raw_need = 0 ;
if ( ! tcp_proxy_handle_non_tcp ( p , pkt , remaining ) ) {
uint8_t proto = pkt [ 9 ] ;
if ( proto = = IPPROTO_TCP ) {
uint16_t ip_hdr_len = ( pkt [ 0 ] & 0x0F ) * 4 ;
uint16_t ip_total = ( ( uint16_t ) pkt [ 2 ] < < 8 ) | pkt [ 3 ] ;
if ( ip_hdr_len > = 20 & & ip_total > = ip_hdr_len & & ( size_t ) ip_total < = remaining ) {
uint16_t dport_net ; memcpy ( & dport_net , pkt + ip_hdr_len + 2 , 2 ) ;
tcp_proxy_ensure_outbound_listen ( p , dport_net ) ;
uint32_t src_ip , dst_ip ;
memcpy ( & src_ip , pkt + 12 , 4 ) ; memcpy ( & dst_ip , pkt + 16 , 4 ) ;
uint16_t tcp_len = ip_total - ip_hdr_len ;
struct pbuf * pb = pbuf_alloc ( PBUF_RAW , tcp_len ) ;
if ( pb ) { pbuf_take ( pb , pkt + ip_hdr_len , tcp_len ) ; lwip_tcp_input ( p - > lwip , pb , src_ip , dst_ip ) ; }
}
}
}
}
static void tcp_proxy_tun_input ( struct ll_queue * q , void * arg ) {
struct tcp_proxy * p = ( struct tcp_proxy * ) arg ;
struct ll_entry * entry = queue_data_get ( q ) ;
@ -552,36 +508,28 @@ void tcp_proxy_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
struct tcp_proxy * tcp_proxy_create ( struct UTUN_INSTANCE * inst , struct UASYNC * ua ,
const char * tun_name , const char * tun_ip , int mtu , int test_mode ,
struct tcp_proxy_mapping_config * mappings , int mapping_count ,
int use_tun , int ip_fd , uint64_t via_node_id )
uint64_t via_node_id )
{
if ( ! ua ) { DEBUG_ERROR ( DEBUG_CATEGORY_SOCKET , " tcp_proxy_create: ua is NULL " ) ; return NULL ; }
if ( ! tun_name | | ! tun_ip ) { DEBUG_ERROR ( DEBUG_CATEGORY_SOCKET , " tcp_proxy_create: tun name/ip required " ) ; return NULL ; }
struct tcp_proxy * p = u_calloc ( 1 , sizeof ( struct tcp_proxy ) ) ;
if ( ! p ) { DEBUG_ERROR ( DEBUG_CATEGORY_SOCKET , " tcp_proxy_create: u_calloc failed " ) ; return NULL ; }
p - > inst = inst ; p - > ua = ua ; p - > ip_fd = - 1 ; p - > next_stream_id = 1 ;
p - > inst = inst ; p - > ua = ua ; p - > next_stream_id = 1 ;
p - > via_node_id = via_node_id ;
p - > ip_fd_mode = ! use_tun ;
p - > mappings = mappings ; p - > mapping_count = mapping_count ;
p - > entry_pool = memory_pool_init ( sizeof ( struct ll_entry ) ) ;
if ( ! p - > entry_pool ) { DEBUG_ERROR ( DEBUG_CATEGORY_SOCKET , " tcp_proxy_create: memory_pool_init failed " ) ; u_free ( p ) ; return NULL ; }
if ( use_tun ) {
if ( ! tun_name | | ! tun_ip ) { DEBUG_ERROR ( DEBUG_CATEGORY_SOCKET , " tcp_proxy_create: tun name/ip required " ) ; memory_pool_destroy ( p - > entry_pool ) ; u_free ( p ) ; return NULL ; }
p - > tun = tun_init_nat ( ua , tun_name , tun_ip , mtu > 0 ? mtu : 1500 , test_mode ) ;
if ( ! p - > tun ) { DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " tcp_proxy: failed to create TUN %s " , tun_name ) ; memory_pool_destroy ( p - > entry_pool ) ; u_free ( p ) ; return NULL ; }
queue_set_callback ( p - > tun - > output_queue , tcp_proxy_tun_input , p ) ;
} else {
p - > ip_fd = ip_fd ;
p - > ip_fd_id = uasync_add_socket ( ua , ip_fd , tcp_proxy_raw_read , NULL , NULL , p ) ;
if ( ! p - > ip_fd_id ) { DEBUG_ERROR ( DEBUG_CATEGORY_SOCKET , " tcp_proxy: uasync_add_socket for ip_fd failed " ) ; memory_pool_destroy ( p - > entry_pool ) ; u_free ( p ) ; return NULL ; }
}
p - > tun = tun_init_nat ( ua , tun_name , tun_ip , mtu > 0 ? mtu : 1500 , test_mode ) ;
if ( ! p - > tun ) { DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " tcp_proxy: failed to create TUN %s " , tun_name ) ; memory_pool_destroy ( p - > entry_pool ) ; u_free ( p ) ; return NULL ; }
queue_set_callback ( p - > tun - > output_queue , tcp_proxy_tun_input , p ) ;
p - > lwip = lwip_tcp_init ( ua , tcp_output_cb , p ) ;
if ( ! p - > lwip ) {
DEBUG_ERROR ( DEBUG_CATEGORY_SOCKET , " tcp_proxy_create: lwip_tcp_init failed " ) ;
if ( p - > ip_fd_id ) uasync_remove_socket ( ua , p - > ip_fd_id ) ;
if ( p - > tun ) tun_close ( p - > tun ) ;
tun_close ( p - > tun ) ;
memory_pool_destroy ( p - > entry_pool ) ; u_free ( p ) ; return NULL ;
}
@ -609,7 +557,7 @@ struct tcp_proxy* tcp_proxy_create(struct UTUN_INSTANCE* inst, struct UASYNC* ua
}
}
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TCP proxy created: use_tun=%d mappings=%d via_node=%016llx " , use_tun , mapping_count , ( unsigned long long ) via_node_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TCP proxy created: mappings=%d via_node=%016llx " , mapping_count , ( unsigned long long ) via_node_id ) ;
return p ;
}
@ -636,7 +584,6 @@ void tcp_proxy_destroy(struct tcp_proxy* p) {
}
p - > conns = NULL ;
if ( p - > ip_fd_id ) { uasync_remove_socket ( p - > ua , p - > ip_fd_id ) ; p - > ip_fd_id = NULL ; }
if ( p - > tun ) tun_close ( p - > tun ) ;
if ( p - > entry_pool ) memory_pool_destroy ( p - > entry_pool ) ;
u_free ( p ) ;