2017-07-29 20:32:26 +08:00
# include "common.h"
# include "network.h"
2017-09-23 02:40:23 -05:00
# include "connection.h"
2017-09-23 03:35:28 -05:00
# include "misc.h"
2017-07-24 21:18:58 +08:00
# include "log.h"
2017-08-11 12:25:04 +08:00
# include "lib/md5.h"
2017-08-22 11:00:44 -05:00
# include "encrypt.h"
2017-10-30 07:21:27 -05:00
# include "fd_manager.h"
2017-07-26 18:00:45 +08:00
2017-11-07 01:07:32 -06:00
2017-11-06 03:00:16 -06:00
char hb_buf [ buf_len ] ;
2017-11-11 01:15:50 -06:00
2018-02-24 17:26:29 -06:00
int on_epoll_recv_event = 0 ; //TODO, just a flag to help detect epoll infinite shoot
2017-09-24 03:14:08 -05:00
2017-08-27 03:31:22 -05:00
int client_on_timer ( conn_info_t & conn_info ) //for client. called when a timer is ready in epoll
2017-07-11 18:01:11 +08:00
{
2017-07-29 00:22:26 +08:00
packet_info_t & send_info = conn_info . raw_info . send_info ;
packet_info_t & recv_info = conn_info . raw_info . recv_info ;
raw_info_t & raw_info = conn_info . raw_info ;
2017-08-04 03:29:53 +08:00
conn_info . blob - > conv_manager . clear_inactive ( ) ;
2017-07-26 06:29:40 +08:00
mylog ( log_trace , " timer! \n " ) ;
2017-08-04 03:29:53 +08:00
2017-08-08 15:49:11 +08:00
mylog ( log_trace , " roller my %d,oppsite %d,%lld \n " , int ( conn_info . my_roller ) , int ( conn_info . oppsite_roller ) , conn_info . last_oppsite_roller_time ) ;
2017-08-04 03:29:53 +08:00
mylog ( log_trace , " <client_on_timer,send_info.ts_ack= %u> \n " , send_info . ts_ack ) ;
2018-02-24 17:26:29 -06:00
if ( raw_info . disabled )
{
conn_info . state . client_current_state = client_idle ;
conn_info . my_id = get_true_random_number_nz ( ) ;
2017-08-20 16:28:23 +08:00
2018-02-24 17:26:29 -06:00
mylog ( log_info , " state back to client_idle \n " ) ;
}
2017-08-20 16:28:23 +08:00
2017-08-02 18:57:27 +08:00
if ( conn_info . state . client_current_state = = client_idle )
2017-07-11 18:01:11 +08:00
{
2018-02-24 17:26:29 -06:00
raw_info . rst_received = 0 ;
raw_info . disabled = 0 ;
2017-07-30 23:18:37 +08:00
fail_time_counter + + ;
2017-08-05 10:03:40 +08:00
if ( max_fail_time > 0 & & fail_time_counter > max_fail_time )
2017-07-30 23:18:37 +08:00
{
2017-08-04 18:35:51 +08:00
mylog ( log_fatal , " max_fail_time exceed \n " ) ;
2017-08-04 11:51:39 +08:00
myexit ( - 1 ) ;
2017-07-30 23:18:37 +08:00
}
2017-08-04 03:29:53 +08:00
conn_info . blob - > anti_replay . re_init ( ) ;
2017-08-02 18:57:27 +08:00
conn_info . my_id = get_true_random_number_nz ( ) ; ///todo no need to do this everytime
2017-07-26 06:29:40 +08:00
2018-02-24 17:26:29 -06:00
2017-08-17 23:40:17 +08:00
u32_t new_ip = 0 ;
2017-09-23 03:05:23 -05:00
if ( ! force_source_ip & & get_src_adress ( new_ip , remote_ip_uint32 , remote_port ) = = 0 )
2017-08-17 23:40:17 +08:00
{
2017-08-18 00:23:18 +08:00
if ( new_ip ! = source_ip_uint32 )
2017-08-17 23:40:17 +08:00
{
2017-08-18 00:50:56 +08:00
mylog ( log_info , " source ip changed from %s to " , my_ntoa ( source_ip_uint32 ) ) ;
2017-08-18 00:23:18 +08:00
log_bare ( log_info , " %s \n " , my_ntoa ( new_ip ) ) ;
source_ip_uint32 = new_ip ;
2017-08-17 23:40:17 +08:00
send_info . src_ip = new_ip ;
}
}
2017-08-02 18:57:27 +08:00
if ( source_port = = 0 )
2017-07-24 10:54:05 +08:00
{
2017-09-23 03:05:23 -05:00
send_info . src_port = client_bind_to_a_new_port ( bind_fd , local_ip_uint32 ) ;
2017-07-24 10:54:05 +08:00
}
2017-07-26 06:29:40 +08:00
else
{
2017-08-02 18:57:27 +08:00
send_info . src_port = source_port ;
2017-07-26 06:29:40 +08:00
}
2017-07-22 16:19:06 +08:00
2017-08-02 18:57:27 +08:00
if ( raw_mode = = mode_icmp )
2017-07-22 16:19:06 +08:00
{
2017-08-02 18:57:27 +08:00
send_info . dst_port = send_info . src_port ;
2017-07-22 16:19:06 +08:00
}
2017-07-17 23:45:24 +08:00
2017-08-02 18:57:27 +08:00
mylog ( log_info , " using port %d \n " , send_info . src_port ) ;
2017-07-28 00:15:10 +08:00
init_filter ( send_info . src_port ) ;
2017-07-11 18:01:11 +08:00
2017-08-02 18:57:27 +08:00
if ( raw_mode = = mode_icmp | | raw_mode = = mode_udp )
2017-07-22 01:19:13 +08:00
{
2017-08-02 18:57:27 +08:00
conn_info . state . client_current_state = client_handshake1 ;
2017-07-31 20:09:45 +08:00
2017-08-02 18:57:27 +08:00
mylog ( log_info , " state changed from client_idle to client_pre_handshake \n " ) ;
2017-07-22 01:19:13 +08:00
}
2017-08-02 18:57:27 +08:00
if ( raw_mode = = mode_faketcp )
2017-07-22 01:19:13 +08:00
{
2017-08-02 18:57:27 +08:00
conn_info . state . client_current_state = client_tcp_handshake ;
mylog ( log_info , " state changed from client_idle to client_tcp_handshake \n " ) ;
2017-08-04 04:22:16 +08:00
2017-07-22 01:19:13 +08:00
}
2017-08-02 18:57:27 +08:00
conn_info . last_state_time = get_current_time ( ) ;
2017-08-04 05:27:47 +08:00
conn_info . last_hb_sent_time = 0 ;
2017-08-02 18:57:27 +08:00
//dont return;
2017-07-11 18:01:11 +08:00
}
2017-08-03 23:32:19 +08:00
if ( conn_info . state . client_current_state = = client_tcp_handshake ) //send and resend syn
2017-07-11 18:01:11 +08:00
{
2017-07-31 19:50:05 +08:00
assert ( raw_mode = = mode_faketcp ) ;
2017-08-02 18:57:27 +08:00
if ( get_current_time ( ) - conn_info . last_state_time > client_handshake_timeout )
{
conn_info . state . client_current_state = client_idle ;
2017-08-03 23:32:19 +08:00
mylog ( log_info , " state back to client_idle from client_tcp_handshake \n " ) ;
2017-08-02 18:57:27 +08:00
return 0 ;
}
2017-08-04 05:27:47 +08:00
else if ( get_current_time ( ) - conn_info . last_hb_sent_time > client_retry_interval )
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
2017-08-03 23:32:19 +08:00
if ( raw_mode = = mode_faketcp )
{
2017-08-04 05:27:47 +08:00
if ( conn_info . last_hb_sent_time = = 0 )
2017-08-03 23:32:19 +08:00
{
2017-08-04 04:22:16 +08:00
send_info . psh = 0 ;
send_info . syn = 1 ;
send_info . ack = 0 ;
send_info . ts_ack = 0 ;
send_info . seq = get_true_random_number ( ) ;
send_info . ack_seq = get_true_random_number ( ) ;
2017-08-03 23:32:19 +08:00
}
}
2017-08-02 18:57:27 +08:00
2017-08-04 03:29:53 +08:00
send_raw0 ( raw_info , 0 , 0 ) ;
2017-08-02 18:57:27 +08:00
2017-08-04 05:27:47 +08:00
conn_info . last_hb_sent_time = get_current_time ( ) ;
2017-08-03 23:32:19 +08:00
mylog ( log_info , " (re)sent tcp syn \n " ) ;
2017-07-20 16:34:43 +08:00
return 0 ;
2017-07-11 18:01:11 +08:00
}
2017-08-02 18:57:27 +08:00
else
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
return 0 ;
2017-07-11 18:01:11 +08:00
}
2017-08-03 23:32:19 +08:00
return 0 ;
2017-07-11 18:01:11 +08:00
}
2017-08-03 23:32:19 +08:00
else if ( conn_info . state . client_current_state = = client_handshake1 ) //send and resend handshake1
2017-07-11 18:01:11 +08:00
{
2017-07-30 18:09:51 +08:00
if ( get_current_time ( ) - conn_info . last_state_time > client_handshake_timeout )
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
conn_info . state . client_current_state = client_idle ;
2017-08-03 23:32:19 +08:00
mylog ( log_info , " state back to client_idle from client_handshake1 \n " ) ;
2017-07-20 16:34:43 +08:00
return 0 ;
2017-07-30 18:09:51 +08:00
2017-07-11 18:01:11 +08:00
}
2017-08-04 05:27:47 +08:00
else if ( get_current_time ( ) - conn_info . last_hb_sent_time > client_retry_interval )
2017-07-11 18:01:11 +08:00
{
2017-08-03 23:32:19 +08:00
2017-07-26 06:29:40 +08:00
if ( raw_mode = = mode_faketcp )
2017-07-22 01:19:13 +08:00
{
2017-08-04 05:27:47 +08:00
if ( conn_info . last_hb_sent_time = = 0 )
2017-08-03 23:32:19 +08:00
{
2017-08-04 03:29:53 +08:00
send_info . seq + + ;
2017-08-03 23:32:19 +08:00
send_info . ack_seq = recv_info . seq + 1 ;
send_info . ts_ack = recv_info . ts ;
2017-09-06 01:37:14 -05:00
raw_info . reserved_send_seq = send_info . seq ;
2017-08-03 23:32:19 +08:00
}
2017-09-06 01:37:14 -05:00
send_info . seq = raw_info . reserved_send_seq ;
2017-08-02 18:57:27 +08:00
send_info . psh = 0 ;
send_info . syn = 0 ;
send_info . ack = 1 ;
2017-08-04 03:29:53 +08:00
send_raw0 ( raw_info , 0 , 0 ) ;
2017-08-03 23:32:19 +08:00
send_handshake ( raw_info , conn_info . my_id , 0 , const_id ) ;
2017-09-06 01:31:29 -05:00
send_info . seq + = raw_info . send_info . data_len ;
2017-07-22 01:19:13 +08:00
}
2017-08-03 23:32:19 +08:00
else
{
2017-08-04 03:29:53 +08:00
send_handshake ( raw_info , conn_info . my_id , 0 , const_id ) ;
2017-08-03 23:32:19 +08:00
if ( raw_mode = = mode_icmp )
2018-06-09 09:04:00 -05:00
send_info . my_icmp_seq + + ;
2017-08-03 23:32:19 +08:00
}
2017-08-04 05:27:47 +08:00
conn_info . last_hb_sent_time = get_current_time ( ) ;
2017-08-03 23:32:19 +08:00
mylog ( log_info , " (re)sent handshake1 \n " ) ;
2017-08-02 18:57:27 +08:00
return 0 ;
}
else
{
return 0 ;
2017-07-11 18:01:11 +08:00
}
2017-08-03 23:32:19 +08:00
return 0 ;
2017-07-11 18:01:11 +08:00
}
2017-08-03 23:32:19 +08:00
else if ( conn_info . state . client_current_state = = client_handshake2 )
2017-07-19 16:11:12 +08:00
{
2017-07-30 18:09:51 +08:00
if ( get_current_time ( ) - conn_info . last_state_time > client_handshake_timeout )
2017-07-19 16:11:12 +08:00
{
2017-08-02 18:57:27 +08:00
conn_info . state . client_current_state = client_idle ;
2017-08-03 23:32:19 +08:00
mylog ( log_info , " state back to client_idle from client_handshake2 \n " ) ;
2017-08-02 18:57:27 +08:00
return 0 ;
}
2017-08-04 05:27:47 +08:00
else if ( get_current_time ( ) - conn_info . last_hb_sent_time > client_retry_interval )
2017-08-02 18:57:27 +08:00
{
2017-08-03 23:32:19 +08:00
if ( raw_mode = = mode_faketcp )
{
2017-08-04 05:27:47 +08:00
if ( conn_info . last_hb_sent_time = = 0 )
2017-08-03 23:32:19 +08:00
{
2017-09-06 01:31:29 -05:00
send_info . ack_seq = recv_info . seq + raw_info . recv_info . data_len ;
2017-08-03 23:32:19 +08:00
send_info . ts_ack = recv_info . ts ;
2017-09-06 01:37:14 -05:00
raw_info . reserved_send_seq = send_info . seq ;
2017-08-03 23:32:19 +08:00
}
2017-09-06 01:37:14 -05:00
send_info . seq = raw_info . reserved_send_seq ;
2017-08-03 23:32:19 +08:00
send_handshake ( raw_info , conn_info . my_id , conn_info . oppsite_id , const_id ) ;
2017-09-06 01:31:29 -05:00
send_info . seq + = raw_info . send_info . data_len ;
2017-08-03 23:32:19 +08:00
}
else
{
2017-08-04 03:29:53 +08:00
send_handshake ( raw_info , conn_info . my_id , conn_info . oppsite_id , const_id ) ;
2017-08-03 23:32:19 +08:00
if ( raw_mode = = mode_icmp )
2018-06-09 09:04:00 -05:00
send_info . my_icmp_seq + + ;
2017-08-03 23:32:19 +08:00
}
2017-08-04 05:27:47 +08:00
conn_info . last_hb_sent_time = get_current_time ( ) ;
2017-08-03 23:32:19 +08:00
mylog ( log_info , " (re)sent handshake2 \n " ) ;
2017-07-20 16:34:43 +08:00
return 0 ;
2017-08-03 23:32:19 +08:00
2017-07-19 16:11:12 +08:00
}
else
{
2017-08-02 18:57:27 +08:00
return 0 ;
2017-07-19 16:11:12 +08:00
}
2017-08-03 23:32:19 +08:00
return 0 ;
2017-07-19 16:11:12 +08:00
}
2017-08-03 23:32:19 +08:00
else if ( conn_info . state . client_current_state = = client_ready )
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
fail_time_counter = 0 ;
2017-08-04 17:12:23 +08:00
mylog ( log_trace , " time %llu,%llu \n " , get_current_time ( ) , conn_info . last_state_time ) ;
2017-07-30 05:53:30 +08:00
if ( get_current_time ( ) - conn_info . last_hb_recv_time > client_conn_timeout )
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
conn_info . state . client_current_state = client_idle ;
2017-07-29 00:22:26 +08:00
conn_info . my_id = get_true_random_number_nz ( ) ;
2017-08-13 02:14:50 +08:00
mylog ( log_info , " state back to client_idle from client_ready bc of server-->client direction timeout \n " ) ;
2017-07-11 18:01:11 +08:00
return 0 ;
}
2017-07-19 06:05:08 +08:00
2017-08-08 15:49:11 +08:00
if ( get_current_time ( ) - conn_info . last_oppsite_roller_time > client_conn_uplink_timeout )
{
conn_info . state . client_current_state = client_idle ;
conn_info . my_id = get_true_random_number_nz ( ) ;
2017-08-13 02:14:50 +08:00
mylog ( log_info , " state back to client_idle from client_ready bc of client-->server direction timeout \n " ) ;
2017-08-08 15:49:11 +08:00
}
2017-07-12 16:46:02 +08:00
2017-11-11 01:58:21 -06:00
if ( get_current_time ( ) - conn_info . last_hb_sent_time < heartbeat_interval )
{
return 0 ;
}
2017-07-23 06:24:32 +08:00
2017-11-11 01:58:21 -06:00
2017-08-03 23:32:19 +08:00
mylog ( log_debug , " heartbeat sent <%x,%x> \n " , conn_info . oppsite_id , conn_info . my_id ) ;
2017-07-12 16:46:02 +08:00
2017-11-07 01:07:32 -06:00
if ( hb_mode = = 0 )
send_safer ( conn_info , ' h ' , hb_buf , 0 ) ; /////////////send
else
send_safer ( conn_info , ' h ' , hb_buf , hb_len ) ;
2017-07-29 00:22:26 +08:00
conn_info . last_hb_sent_time = get_current_time ( ) ;
2017-08-03 23:32:19 +08:00
return 0 ;
}
else
{
mylog ( log_fatal , " unknown state,this shouldnt happen. \n " ) ;
2017-08-04 11:51:39 +08:00
myexit ( - 1 ) ;
2017-07-11 18:01:11 +08:00
}
2017-07-23 02:57:32 +08:00
return 0 ;
2017-07-11 18:01:11 +08:00
}
2017-08-27 03:31:22 -05:00
int client_on_raw_recv ( conn_info_t & conn_info ) //called when raw fd received a packet.
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
char * data ; int data_len ;
packet_info_t & send_info = conn_info . raw_info . send_info ;
packet_info_t & recv_info = conn_info . raw_info . recv_info ;
raw_info_t & raw_info = conn_info . raw_info ;
2017-08-04 03:29:53 +08:00
mylog ( log_trace , " <client_on_raw_recv,send_info.ts_ack= %u> \n " , send_info . ts_ack ) ;
2017-08-02 18:57:27 +08:00
if ( conn_info . state . client_current_state = = client_idle )
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
recv ( raw_recv_fd , 0 , 0 , 0 ) ;
2017-07-11 18:01:11 +08:00
}
2017-08-03 23:32:19 +08:00
else if ( conn_info . state . client_current_state = = client_tcp_handshake ) //received syn ack
2017-07-11 18:01:11 +08:00
{
2017-08-03 23:32:19 +08:00
assert ( raw_mode = = mode_faketcp ) ;
2017-08-04 03:29:53 +08:00
if ( recv_raw0 ( raw_info , data , data_len ) < 0 )
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
return - 1 ;
}
if ( recv_info . src_ip ! = send_info . dst_ip | | recv_info . src_port ! = send_info . dst_port )
{
mylog ( log_debug , " unexpected adress %x %x %d %d \n " , recv_info . src_ip , send_info . dst_ip , recv_info . src_port , send_info . dst_port ) ;
return - 1 ;
}
if ( data_len = = 0 & & raw_info . recv_info . syn = = 1 & & raw_info . recv_info . ack = = 1 )
{
2017-08-03 23:32:19 +08:00
if ( recv_info . ack_seq ! = send_info . seq + 1 )
2017-08-02 18:57:27 +08:00
{
mylog ( log_debug , " seq ack_seq mis match \n " ) ;
return - 1 ;
}
conn_info . state . client_current_state = client_handshake1 ;
2017-08-03 23:32:19 +08:00
mylog ( log_info , " state changed from client_tcp_handshake to client_handshake1 \n " ) ;
2017-08-02 18:57:27 +08:00
conn_info . last_state_time = get_current_time ( ) ;
2017-08-04 05:27:47 +08:00
conn_info . last_hb_sent_time = 0 ;
2017-08-02 20:54:32 +08:00
client_on_timer ( conn_info ) ;
2017-08-02 18:57:27 +08:00
return 0 ;
2017-07-11 18:01:11 +08:00
}
else
{
2017-08-02 18:57:27 +08:00
mylog ( log_debug , " unexpected packet type,expected:syn ack \n " ) ;
return - 1 ;
2017-07-11 18:01:11 +08:00
}
}
2017-08-03 23:32:19 +08:00
else if ( conn_info . state . client_current_state = = client_handshake1 ) //recevied respond of handshake1
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
if ( recv_bare ( raw_info , data , data_len ) ! = 0 )
{
mylog ( log_debug , " recv_bare failed! \n " ) ;
return - 1 ;
}
if ( recv_info . src_ip ! = send_info . dst_ip | | recv_info . src_port ! = send_info . dst_port )
2017-07-19 16:11:12 +08:00
{
2017-08-02 18:57:27 +08:00
mylog ( log_debug , " unexpected adress %x %x %d %d \n " , recv_info . src_ip , send_info . dst_ip , recv_info . src_port , send_info . dst_port ) ;
return - 1 ;
2017-07-19 16:11:12 +08:00
}
2017-08-02 18:57:27 +08:00
if ( data_len < int ( 3 * sizeof ( id_t ) ) )
2017-07-19 16:11:12 +08:00
{
2017-08-02 18:57:27 +08:00
mylog ( log_debug , " too short to be a handshake \n " ) ;
return - 1 ;
2017-07-19 16:11:12 +08:00
}
2017-08-31 10:36:33 -05:00
id_t tmp_oppsite_id ;
memcpy ( & tmp_oppsite_id , & data [ 0 ] , sizeof ( tmp_oppsite_id ) ) ;
tmp_oppsite_id = ntohl ( tmp_oppsite_id ) ;
id_t tmp_my_id ;
memcpy ( & tmp_my_id , & data [ sizeof ( id_t ) ] , sizeof ( tmp_my_id ) ) ;
tmp_my_id = ntohl ( tmp_my_id ) ;
id_t tmp_oppsite_const_id ;
memcpy ( & tmp_oppsite_const_id , & data [ sizeof ( id_t ) * 2 ] , sizeof ( tmp_oppsite_const_id ) ) ;
tmp_oppsite_const_id = ntohl ( tmp_oppsite_const_id ) ;
2017-07-19 16:11:12 +08:00
2017-08-02 18:57:27 +08:00
if ( tmp_my_id ! = conn_info . my_id )
2017-07-11 18:01:11 +08:00
{
2017-08-02 18:57:27 +08:00
mylog ( log_debug , " tmp_my_id doesnt match \n " ) ;
return - 1 ;
}
2017-08-03 23:32:19 +08:00
2017-08-04 03:29:53 +08:00
if ( raw_mode = = mode_faketcp )
{
if ( recv_info . ack_seq ! = send_info . seq )
{
mylog ( log_debug , " seq ack_seq mis match \n " ) ;
return - 1 ;
}
if ( recv_info . seq ! = send_info . ack_seq )
{
mylog ( log_debug , " seq ack_seq mis match \n " ) ;
return - 1 ;
}
}
2017-08-02 18:57:27 +08:00
conn_info . oppsite_id = tmp_oppsite_id ;
2017-07-19 00:27:20 +08:00
2017-08-03 23:32:19 +08:00
mylog ( log_info , " changed state from to client_handshake1 to client_handshake2,my_id is %x,oppsite id is %x \n " , conn_info . my_id , conn_info . oppsite_id ) ;
2017-07-19 16:11:12 +08:00
2017-08-02 18:57:27 +08:00
conn_info . state . client_current_state = client_handshake2 ;
conn_info . last_state_time = get_current_time ( ) ;
2017-08-04 05:27:47 +08:00
conn_info . last_hb_sent_time = 0 ;
2017-08-02 20:54:32 +08:00
client_on_timer ( conn_info ) ;
2017-08-02 18:57:27 +08:00
return 0 ;
}
2017-08-03 23:32:19 +08:00
else if ( conn_info . state . client_current_state = = client_handshake2 | | conn_info . state . client_current_state = = client_ready ) //received heartbeat or data
2017-08-02 18:57:27 +08:00
{
2017-08-08 15:49:11 +08:00
char type ;
if ( recv_safer ( conn_info , type , data , data_len ) ! = 0 )
2017-08-02 18:57:27 +08:00
{
mylog ( log_debug , " recv_safer failed! \n " ) ;
return - 1 ;
}
if ( recv_info . src_ip ! = send_info . dst_ip | | recv_info . src_port ! = send_info . dst_port )
{
mylog ( log_warn , " unexpected adress %x %x %d %d,this shouldnt happen. \n " , recv_info . src_ip , send_info . dst_ip , recv_info . src_port , send_info . dst_port ) ;
return - 1 ;
2017-07-11 18:01:11 +08:00
}
2017-08-02 18:57:27 +08:00
if ( conn_info . state . client_current_state = = client_handshake2 )
2017-08-03 23:32:19 +08:00
{
mylog ( log_info , " changed state from to client_handshake2 to client_ready \n " ) ;
2017-08-02 18:57:27 +08:00
conn_info . state . client_current_state = client_ready ;
2017-08-04 05:27:47 +08:00
conn_info . last_hb_sent_time = 0 ;
conn_info . last_hb_recv_time = get_current_time ( ) ;
2017-08-08 15:49:11 +08:00
conn_info . last_oppsite_roller_time = conn_info . last_hb_recv_time ;
2017-08-04 05:27:47 +08:00
client_on_timer ( conn_info ) ;
2017-08-03 23:32:19 +08:00
}
2017-11-06 03:00:16 -06:00
if ( data_len > = 0 & & type = = ' h ' )
2017-07-19 06:05:08 +08:00
{
2017-11-11 01:07:28 -06:00
mylog ( log_debug , " [hb]heart beat received,oppsite_roller=%d \n " , int ( conn_info . oppsite_roller ) ) ;
2017-08-02 18:57:27 +08:00
conn_info . last_hb_recv_time = get_current_time ( ) ;
2017-07-19 06:05:08 +08:00
return 0 ;
}
2017-08-08 15:49:11 +08:00
else if ( data_len > = int ( sizeof ( u32_t ) ) & & type = = ' d ' )
2017-08-02 18:57:27 +08:00
{
mylog ( log_trace , " received a data from fake tcp,len:%d \n " , data_len ) ;
2017-07-19 06:05:08 +08:00
2017-11-07 01:07:32 -06:00
if ( hb_mode = = 0 )
conn_info . last_hb_recv_time = get_current_time ( ) ;
2017-07-23 06:24:32 +08:00
2017-08-31 10:36:33 -05:00
u32_t tmp_conv_id ;
memcpy ( & tmp_conv_id , & data [ 0 ] , sizeof ( tmp_conv_id ) ) ;
tmp_conv_id = ntohl ( tmp_conv_id ) ;
2017-07-19 06:05:08 +08:00
2017-08-04 03:29:53 +08:00
if ( ! conn_info . blob - > conv_manager . is_conv_used ( tmp_conv_id ) )
2017-08-02 18:57:27 +08:00
{
mylog ( log_info , " unknow conv %d,ignore \n " , tmp_conv_id ) ;
return 0 ;
}
2017-07-11 18:01:11 +08:00
2017-08-04 03:29:53 +08:00
conn_info . blob - > conv_manager . update_active_time ( tmp_conv_id ) ;
2017-07-11 18:01:11 +08:00
2017-08-04 17:12:23 +08:00
u64_t u64 = conn_info . blob - > conv_manager . find_u64_by_conv ( tmp_conv_id ) ;
2017-07-11 18:01:11 +08:00
2017-08-15 13:03:22 +08:00
sockaddr_in tmp_sockaddr = { 0 } ;
2017-07-11 18:01:11 +08:00
2017-08-02 18:57:27 +08:00
tmp_sockaddr . sin_family = AF_INET ;
tmp_sockaddr . sin_addr . s_addr = ( u64 > > 32u ) ;
2017-07-11 18:01:11 +08:00
2017-08-02 18:57:27 +08:00
tmp_sockaddr . sin_port = htons ( uint16_t ( ( u64 < < 32u ) > > 32u ) ) ;
2017-07-11 18:01:11 +08:00
2017-07-28 19:47:30 +08:00
2017-08-08 15:49:11 +08:00
int ret = sendto ( udp_fd , data + sizeof ( u32_t ) , data_len - ( sizeof ( u32_t ) ) , 0 , ( struct sockaddr * ) & tmp_sockaddr , sizeof ( tmp_sockaddr ) ) ;
2017-07-28 19:47:30 +08:00
2017-08-02 18:57:27 +08:00
if ( ret < 0 )
{
mylog ( log_warn , " sento returned %d \n " , ret ) ;
2018-06-06 21:12:28 -05:00
2017-08-02 18:57:27 +08:00
}
mylog ( log_trace , " %s :%d \n " , inet_ntoa ( tmp_sockaddr . sin_addr ) , ntohs ( tmp_sockaddr . sin_port ) ) ;
mylog ( log_trace , " %d byte sent \n " , ret ) ;
}
else
{
mylog ( log_warn , " unknown packet,this shouldnt happen. \n " ) ;
return - 1 ;
}
2017-07-28 19:47:30 +08:00
2017-08-02 18:57:27 +08:00
return 0 ;
}
else
{
2017-08-03 23:32:19 +08:00
mylog ( log_fatal , " unknown state,this shouldnt happen. \n " ) ;
2017-08-04 11:51:39 +08:00
myexit ( - 1 ) ;
2017-07-28 19:47:30 +08:00
}
return 0 ;
}
2018-06-07 06:24:31 -05:00
void udp_accept_cb ( struct ev_loop * loop , struct ev_io * watcher , int revents )
{
char buf [ buf_len ] ;
conn_info_t & conn_info = * ( ( conn_info_t * ) watcher - > data ) ; ;
int recv_len ;
struct sockaddr_in udp_new_addr_in = { 0 } ;
socklen_t udp_new_addr_len = sizeof ( sockaddr_in ) ;
if ( ( recv_len = recvfrom ( udp_fd , buf , max_data_len + 1 , 0 ,
( struct sockaddr * ) & udp_new_addr_in , & udp_new_addr_len ) ) = = - 1 ) {
mylog ( log_error , " recv_from error,this shouldnt happen at client \n " ) ;
myexit ( 1 ) ;
} ;
if ( recv_len = = max_data_len + 1 )
{
mylog ( log_warn , " huge packet, data_len > %d,dropped \n " , max_data_len ) ;
return ;
}
if ( recv_len > = mtu_warn )
{
mylog ( log_warn , " huge packet,data len=%d (>=%d).strongly suggested to set a smaller mtu at upper level,to get rid of this warn \n " , recv_len , mtu_warn ) ;
}
mylog ( log_trace , " Received packet from %s:%d,len: %d \n " , inet_ntoa ( udp_new_addr_in . sin_addr ) ,
ntohs ( udp_new_addr_in . sin_port ) , recv_len ) ;
u64_t u64 = ( ( u64_t ( udp_new_addr_in . sin_addr . s_addr ) ) < < 32u ) + ntohs ( udp_new_addr_in . sin_port ) ;
u32_t conv ;
if ( ! conn_info . blob - > conv_manager . is_u64_used ( u64 ) )
{
if ( conn_info . blob - > conv_manager . get_size ( ) > = max_conv_num )
{
mylog ( log_warn , " ignored new udp connect bc max_conv_num exceed \n " ) ;
return ;
}
conv = conn_info . blob - > conv_manager . get_new_conv ( ) ;
conn_info . blob - > conv_manager . insert_conv ( conv , u64 ) ;
mylog ( log_info , " new packet from %s:%d,conv_id=%x \n " , inet_ntoa ( udp_new_addr_in . sin_addr ) , ntohs ( udp_new_addr_in . sin_port ) , conv ) ;
}
else
{
conv = conn_info . blob - > conv_manager . find_conv_by_u64 ( u64 ) ;
}
conn_info . blob - > conv_manager . update_active_time ( conv ) ;
if ( conn_info . state . client_current_state = = client_ready )
{
send_data_safer ( conn_info , buf , recv_len , conv ) ;
}
}
void raw_recv_cb ( struct ev_loop * loop , struct ev_io * watcher , int revents )
2017-07-11 18:01:11 +08:00
{
2018-06-07 06:24:31 -05:00
conn_info_t & conn_info = * ( ( conn_info_t * ) watcher - > data ) ;
client_on_raw_recv ( conn_info ) ;
}
void clear_timer_cb ( struct ev_loop * loop , struct ev_timer * watcher , int revents )
{
conn_info_t & conn_info = * ( ( conn_info_t * ) watcher - > data ) ;
//u64_t value;
//read(timer_fd, &value, 8);
client_on_timer ( conn_info ) ;
mylog ( log_trace , " epoll_trigger_counter: %d \n " , epoll_trigger_counter ) ;
epoll_trigger_counter = 0 ;
}
void fifo_cb ( struct ev_loop * loop , struct ev_io * watcher , int revents )
{
conn_info_t & conn_info = * ( ( conn_info_t * ) watcher - > data ) ;
char buf [ buf_len ] ;
int fifo_fd = watcher - > fd ;
int len = read ( fifo_fd , buf , sizeof ( buf ) ) ;
if ( len < 0 )
{
mylog ( log_warn , " fifo read failed len=%d,errno=%s \n " , len , strerror ( errno ) ) ;
return ;
}
buf [ len ] = 0 ;
while ( len > = 1 & & buf [ len - 1 ] = = ' \n ' )
buf [ len - 1 ] = 0 ;
mylog ( log_info , " got data from fifo,len=%d,s=[%s] \n " , len , buf ) ;
if ( strcmp ( buf , " reconnect " ) = = 0 )
{
mylog ( log_info , " received command: reconnect \n " ) ;
conn_info . state . client_current_state = client_idle ;
conn_info . my_id = get_true_random_number_nz ( ) ;
}
else
{
mylog ( log_info , " unknown command \n " ) ;
}
2017-08-21 20:26:55 +08:00
2018-06-07 06:24:31 -05:00
}
2017-08-21 20:26:55 +08:00
2018-06-07 06:24:31 -05:00
int client_event_loop ( )
{
2017-07-23 01:27:39 +08:00
char buf [ buf_len ] ;
2017-07-29 00:22:26 +08:00
conn_info_t conn_info ;
conn_info . my_id = get_true_random_number_nz ( ) ;
2017-07-29 21:22:13 +08:00
2017-07-30 03:46:28 +08:00
conn_info . prepare ( ) ;
2017-07-29 00:22:26 +08:00
packet_info_t & send_info = conn_info . raw_info . send_info ;
packet_info_t & recv_info = conn_info . raw_info . recv_info ;
2017-10-25 01:03:38 +08:00
2017-08-18 00:23:18 +08:00
if ( source_ip_uint32 = = 0 )
2017-07-24 02:22:33 +08:00
{
2017-07-26 06:29:40 +08:00
mylog ( log_info , " get_src_adress called \n " ) ;
2018-01-30 08:18:16 -06:00
if ( retry_on_error = = 0 )
2017-07-24 02:22:33 +08:00
{
2018-01-30 08:18:16 -06:00
if ( get_src_adress ( source_ip_uint32 , remote_ip_uint32 , remote_port ) ! = 0 )
{
2018-01-30 09:16:51 -06:00
mylog ( log_fatal , " the trick to auto get source ip failed, maybe you dont have internet access \n " ) ;
2018-01-30 08:18:16 -06:00
myexit ( - 1 ) ;
}
2017-07-24 02:22:33 +08:00
}
2018-01-30 08:18:16 -06:00
else
{
int ok = 0 ;
while ( ! ok )
{
if ( get_src_adress ( source_ip_uint32 , remote_ip_uint32 , remote_port ) ! = 0 )
{
2018-01-30 09:16:51 -06:00
mylog ( log_warn , " the trick to auto get source ip failed, maybe you dont have internet access, retry in %d seconds \n " , retry_on_error_interval ) ;
2018-01-30 08:18:16 -06:00
sleep ( retry_on_error_interval ) ;
}
else
{
ok = 1 ;
}
}
2017-07-24 02:22:33 +08:00
}
2018-01-30 08:18:16 -06:00
2017-07-24 02:22:33 +08:00
}
in_addr tmp ;
2017-08-18 00:23:18 +08:00
tmp . s_addr = source_ip_uint32 ;
2017-07-26 06:29:40 +08:00
mylog ( log_info , " source ip = %s \n " , inet_ntoa ( tmp ) ) ;
2017-07-24 02:22:33 +08:00
//printf("done\n");
2017-09-23 03:05:23 -05:00
if ( try_to_list_and_bind ( bind_fd , local_ip_uint32 , source_port ) ! = 0 )
2017-07-24 10:54:05 +08:00
{
2017-07-26 06:29:40 +08:00
mylog ( log_fatal , " bind to source_port:%d fail \n " , source_port ) ;
2017-08-04 11:51:39 +08:00
myexit ( - 1 ) ;
2017-07-24 10:54:05 +08:00
}
2017-07-28 00:15:10 +08:00
send_info . src_port = source_port ;
2017-08-18 00:23:18 +08:00
send_info . src_ip = source_ip_uint32 ;
2017-07-23 01:27:39 +08:00
2017-07-11 18:01:11 +08:00
int i , j , k ; int ret ;
2017-08-21 20:26:55 +08:00
2017-07-11 18:01:11 +08:00
2017-08-18 00:23:18 +08:00
send_info . dst_ip = remote_ip_uint32 ;
2017-07-28 00:15:10 +08:00
send_info . dst_port = remote_port ;
2017-07-11 18:01:11 +08:00
2017-07-12 16:46:02 +08:00
udp_fd = socket ( AF_INET , SOCK_DGRAM , IPPROTO_UDP ) ;
2017-09-24 03:14:08 -05:00
set_buf_size ( udp_fd , socket_buf_size , force_socket_buf ) ;
2017-07-19 06:05:08 +08:00
2017-07-11 18:01:11 +08:00
int yes = 1 ;
2017-08-15 13:03:22 +08:00
struct sockaddr_in local_me = { 0 } ;
2017-07-11 18:01:11 +08:00
socklen_t slen = sizeof ( sockaddr_in ) ;
local_me . sin_family = AF_INET ;
local_me . sin_port = htons ( local_port ) ;
2017-08-18 00:23:18 +08:00
local_me . sin_addr . s_addr = local_ip_uint32 ;
2017-07-13 15:40:58 +08:00
2017-07-11 18:01:11 +08:00
if ( bind ( udp_fd , ( struct sockaddr * ) & local_me , slen ) = = - 1 ) {
2017-07-26 06:29:40 +08:00
mylog ( log_fatal , " socket bind error \n " ) ;
2017-08-04 11:51:39 +08:00
myexit ( 1 ) ;
2017-07-11 18:01:11 +08:00
}
setnonblocking ( udp_fd ) ;
2017-07-28 19:47:30 +08:00
2018-06-07 06:24:31 -05:00
//epollfd = epoll_create1(0);
2017-07-13 15:40:58 +08:00
2018-06-07 06:24:31 -05:00
//const int max_events = 4096;
//struct epoll_event ev, events[max_events];
//if (epollfd < 0) {
// mylog(log_fatal,"epoll return %d\n", epollfd);
// myexit(-1);
//}
struct ev_loop * loop = ev_default_loop ( 0 ) ;
assert ( loop ! = NULL ) ;
//ev.events = EPOLLIN;
//ev.data.u64 = udp_fd;
//ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, udp_fd, &ev);
//if (ret!=0) {
// mylog(log_fatal,"add udp_listen_fd error\n");
// myexit(-1);
//}
struct ev_io udp_accept_watcher ;
udp_accept_watcher . data = & conn_info ;
ev_io_init ( & udp_accept_watcher , udp_accept_cb , udp_fd , EV_READ ) ;
ev_io_start ( loop , & udp_accept_watcher ) ;
//ev.events = EPOLLIN;
//ev.data.u64 = raw_recv_fd;
//ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, raw_recv_fd, &ev);
//if (ret!= 0) {
// mylog(log_fatal,"add raw_fd error\n");
// myexit(-1);
//}
struct ev_io raw_watcher ;
raw_watcher . data = & conn_info ;
ev_io_init ( & raw_watcher , raw_recv_cb , raw_recv_fd , EV_READ ) ;
ev_io_start ( loop , & raw_watcher ) ;
2017-07-11 18:01:11 +08:00
int unbind = 1 ;
2017-07-28 11:31:37 +08:00
2018-06-07 06:24:31 -05:00
//set_timer(epollfd,timer_fd);
struct ev_timer clear_timer ;
clear_timer . data = & conn_info ;
ev_timer_init ( & clear_timer , clear_timer_cb , 0 , timer_interval / 1000.0 ) ;
ev_timer_start ( loop , & clear_timer ) ;
2017-07-28 00:15:10 +08:00
mylog ( log_debug , " send_raw : from %x %d to %x %d \n " , send_info . src_ip , send_info . src_port , send_info . dst_ip , send_info . dst_port ) ;
2017-10-24 09:04:47 -05:00
int fifo_fd = - 1 ;
2018-06-07 06:24:31 -05:00
struct ev_io fifo_watcher ;
fifo_watcher . data = & conn_info ;
2017-10-24 09:04:47 -05:00
if ( fifo_file [ 0 ] ! = 0 )
{
fifo_fd = create_fifo ( fifo_file ) ;
2018-06-07 06:24:31 -05:00
//ev.events = EPOLLIN;
//ev.data.u64 = fifo_fd;
//ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, fifo_fd, &ev);
//if (ret!= 0) {
// mylog(log_fatal,"add fifo_fd to epoll error %s\n",strerror(errno));
// myexit(-1);
//}
ev_io_init ( & fifo_watcher , fifo_cb , fifo_fd , EV_READ ) ;
ev_io_start ( loop , & fifo_watcher ) ;
2017-10-24 09:04:47 -05:00
mylog ( log_info , " fifo_file=%s \n " , fifo_file ) ;
}
2018-06-07 06:24:31 -05:00
ev_run ( loop , 0 ) ;
/*
2017-07-11 18:01:11 +08:00
while ( 1 ) ////////////////////////
{
2017-08-04 23:08:45 +08:00
if ( about_to_exit ) myexit ( 0 ) ;
2017-07-31 09:25:59 +08:00
epoll_trigger_counter + + ;
2017-07-11 18:01:11 +08:00
int nfds = epoll_wait ( epollfd , events , max_events , 180 * 1000 ) ;
if ( nfds < 0 ) { //allow zero
2017-08-05 10:03:40 +08:00
if ( errno = = EINTR )
{
2017-11-23 09:35:33 -06:00
mylog ( log_info , " epoll interrupted by signal,continue \n " ) ;
2017-08-05 10:03:40 +08:00
}
else
{
2017-11-23 09:56:20 -06:00
mylog ( log_fatal , " epoll_wait return %d,%s \n " , nfds , strerror ( errno ) ) ;
2017-08-05 10:03:40 +08:00
myexit ( - 1 ) ;
}
2017-07-11 18:01:11 +08:00
}
2017-07-30 13:39:18 +08:00
int idx ;
for ( idx = 0 ; idx < nfds ; + + idx ) {
2017-08-04 17:12:23 +08:00
if ( events [ idx ] . data . u64 = = ( u64_t ) raw_recv_fd )
2017-07-11 18:01:11 +08:00
{
2017-07-23 04:17:06 +08:00
iphdr * iph ; tcphdr * tcph ;
2018-06-07 06:24:31 -05:00
2017-07-11 18:01:11 +08:00
}
2017-08-04 17:12:23 +08:00
else if ( events [ idx ] . data . u64 = = ( u64_t ) timer_fd )
2017-07-11 18:01:11 +08:00
{
2018-06-07 06:24:31 -05:00
2017-07-11 18:01:11 +08:00
}
2017-10-23 11:38:22 -05:00
else if ( events [ idx ] . data . u64 = = ( u64_t ) fifo_fd )
{
}
2017-08-04 17:12:23 +08:00
else if ( events [ idx ] . data . u64 = = ( u64_t ) udp_fd )
2017-07-11 18:01:11 +08:00
{
2017-07-13 15:40:58 +08:00
2017-07-11 18:01:11 +08:00
}
2017-07-31 09:25:59 +08:00
else
{
mylog ( log_fatal , " unknown fd,this should never happen \n " ) ;
2017-08-04 11:51:39 +08:00
myexit ( - 1 ) ;
2017-07-31 09:25:59 +08:00
}
2017-07-11 18:01:11 +08:00
}
2018-06-07 06:24:31 -05:00
} */
2017-07-11 18:01:11 +08:00
return 0 ;
}
2017-07-13 15:40:58 +08:00
2018-06-12 10:08:41 -05:00
void sigpipe_cb ( struct ev_loop * l , ev_signal * w , int revents )
{
mylog ( log_info , " got sigpipe, ignored " ) ;
}
void sigterm_cb ( struct ev_loop * l , ev_signal * w , int revents )
{
mylog ( log_info , " got sigterm, exit " ) ;
myexit ( 0 ) ;
}
void sigint_cb ( struct ev_loop * l , ev_signal * w , int revents )
{
mylog ( log_info , " got sigint, exit " ) ;
myexit ( 0 ) ;
}
2017-07-26 19:47:52 +08:00
int main ( int argc , char * argv [ ] )
{
2018-06-12 10:08:41 -05:00
//libnet_t *l; /* the libnet context */
//char errbuf[LIBNET_ERRBUF_SIZE];
2018-06-09 09:04:00 -05:00
2018-06-12 10:08:41 -05:00
//l = libnet_init(LIBNET_RAW4, NULL, errbuf);
2018-06-09 09:04:00 -05:00
2017-07-29 20:32:26 +08:00
dup2 ( 1 , 2 ) ; //redirect stderr to stdout
2018-06-12 10:08:41 -05:00
//signal(SIGINT, signal_handler);
//signal(SIGHUP, signal_handler);
//signal(SIGKILL, signal_handler);
//signal(SIGTERM, signal_handler);
//signal(SIGQUIT, signal_handler);
struct ev_loop * loop = ev_default_loop ( 0 ) ;
ev_signal signal_watcher_sigpipe ;
ev_signal_init ( & signal_watcher_sigpipe , sigpipe_cb , SIGPIPE ) ;
ev_signal_start ( loop , & signal_watcher_sigpipe ) ;
ev_signal signal_watcher_sigterm ;
ev_signal_init ( & signal_watcher_sigterm , sigterm_cb , SIGTERM ) ;
ev_signal_start ( loop , & signal_watcher_sigterm ) ;
ev_signal signal_watcher_sigint ;
ev_signal_init ( & signal_watcher_sigint , sigint_cb , SIGINT ) ;
ev_signal_start ( loop , & signal_watcher_sigint ) ;
2017-08-04 18:35:51 +08:00
2017-08-23 07:01:21 -05:00
pre_process_arg ( argc , argv ) ;
2017-07-26 19:20:15 +08:00
2017-08-17 23:40:17 +08:00
if ( geteuid ( ) ! = 0 )
{
2018-02-24 17:26:29 -06:00
mylog ( log_warn , " root check failed, it seems like you are using a non-root account. we can try to continue, but it may fail. If you want to run udp2raw as non-root, you have to add iptables rule manually, and grant udp2raw CAP_NET_RAW capability, check README.md in repo for more info. \n " ) ;
2017-12-14 11:25:48 -06:00
}
else
{
mylog ( log_warn , " you can run udp2raw with non-root account for better security. check README.md in repo for more info. \n " ) ;
2017-08-17 23:40:17 +08:00
}
2018-06-05 11:26:55 -05:00
local_ip_uint32 = inet_addr ( local_ip ) ;
source_ip_uint32 = inet_addr ( source_ip ) ;
2018-06-06 19:50:42 -05:00
mylog ( log_info , " remote_ip=[%s], make sure this is a vaild IP address \n " , remote_ip ) ;
strcpy ( remote_ip , remote_address ) ;
remote_ip_uint32 = inet_addr ( remote_ip ) ;
2018-06-05 12:57:25 -05:00
2017-07-29 20:32:26 +08:00
init_random_number_fd ( ) ;
srand ( get_true_random_number_nz ( ) ) ;
2017-07-21 20:30:27 +08:00
const_id = get_true_random_number_nz ( ) ;
2017-07-19 06:05:08 +08:00
2017-07-29 20:32:26 +08:00
mylog ( log_info , " const_id:%x \n " , const_id ) ;
2017-07-11 18:01:11 +08:00
2017-07-24 11:31:21 +08:00
char tmp [ 1000 ] = " " ;
2017-07-26 08:51:05 +08:00
strcat ( tmp , key_string ) ;
2017-07-24 11:31:21 +08:00
strcat ( tmp , " key1 " ) ;
2017-07-23 22:16:16 +08:00
2017-07-24 11:31:21 +08:00
md5 ( ( uint8_t * ) tmp , strlen ( tmp ) , ( uint8_t * ) key ) ;
2017-08-05 17:31:07 +08:00
iptables_rule ( ) ;
2017-08-21 20:26:55 +08:00
init_raw_socket ( ) ;
2017-07-26 06:29:40 +08:00
if ( program_mode = = client_mode )
2017-07-11 18:01:11 +08:00
{
2017-07-21 20:30:27 +08:00
client_event_loop ( ) ;
2017-07-11 18:01:11 +08:00
}
else
{
2018-06-06 19:50:42 -05:00
mylog ( log_fatal , " server mode not supported in portable version \n " ) ;
myexit ( - 1 ) ;
//server_event_loop();
2017-07-11 18:01:11 +08:00
}
return 0 ;
}