@@ -34,6 +34,13 @@ struct udp_context {
3434 struct wss_proxy_context * wss_context ;
3535};
3636
37+ struct server_context {
38+ struct evconnlistener * listener ;
39+ evutil_socket_t udp_sock ;
40+ struct event * udp_event ;
41+ struct udp_context udp_context ;
42+ };
43+
3744static unsigned long bufferevent_udp_hash (const bufferevent_udp * a ) {
3845 socklen_t i , max ;
3946 unsigned long result = a -> socklen ;
@@ -52,7 +59,7 @@ static int bufferevent_udp_cmp(const bufferevent_udp *a, const bufferevent_udp *
5259 return memcmp (a -> sockaddr , b -> sockaddr , a -> socklen );
5360}
5461
55- static int init_raw_addr (struct sockaddr_storage * sockaddr , int * socklen , int * udp_port ) {
62+ static int init_raw_addr (struct sockaddr_storage * sockaddr , int * socklen ) {
5663 int port ;
5764 char * end ;
5865 const char * local_host = getenv ("SS_LOCAL_HOST" );
@@ -75,14 +82,7 @@ static int init_raw_addr(struct sockaddr_storage *sockaddr, int *socklen, int *u
7582 }
7683
7784 set_port (sockaddr , port );
78-
79- * udp_port = find_udp_port (port );
80-
81- if (* udp_port > 0 ) {
82- LOGI ("raw server tcp://%s:%d, udp://%s:%d" , local_host , port , local_host , * udp_port );
83- } else {
84- LOGI ("raw server %s:%d" , local_host , port );
85- }
85+ LOGI ("raw server %s:%d" , local_host , port );
8686 return 0 ;
8787}
8888
@@ -387,26 +387,26 @@ static void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd,
387387 }
388388}
389389
390- static evutil_socket_t init_udp_sock (const struct sockaddr * sa , int socklen ) {
391- evutil_socket_t sock = socket (sa -> sa_family , SOCK_DGRAM , 0 );
390+ static evutil_socket_t init_udp_sock (const struct sockaddr * sockaddr , int socklen ) {
391+ evutil_socket_t sock = socket (sockaddr -> sa_family , SOCK_DGRAM , 0 );
392392 if (sock < 0 ) {
393- LOGE ("cannot create udp socket" );
393+ LOGE ("cannot create udp socket for %d" , get_port ( sockaddr ) );
394394 goto error ;
395395 }
396396 if (evutil_make_socket_nonblocking (sock ) < 0 ) {
397- LOGE ("cannot make udp socket nonblocking" );
397+ LOGE ("cannot make udp socket nonblocking for %d" , get_port ( sockaddr ) );
398398 goto error ;
399399 }
400400 if (evutil_make_socket_closeonexec (sock ) < 0 ) {
401- LOGE ("cannot make udp socket closeonexec" );
401+ LOGE ("cannot make udp socket closeonexec for %d" , get_port ( sockaddr ) );
402402 goto error ;
403403 }
404404 if (evutil_make_listen_socket_reuseable (sock ) < 0 ) {
405- LOGE ("cannot make udp socket reuseable" );
405+ LOGE ("cannot make udp socket reuseable for %d" , get_port ( sockaddr ) );
406406 goto error ;
407407 }
408- if (bind (sock , sa , socklen ) < 0 ) {
409- LOGE ("cannot bind udp socket" );
408+ if (bind (sock , sockaddr , socklen ) < 0 ) {
409+ LOGE ("cannot bind udp socket for %d" , get_port ( sockaddr ) );
410410 goto error ;
411411 }
412412 return sock ;
@@ -490,21 +490,68 @@ static void udp_read_cb(evutil_socket_t sock, short event, void *ctx) {
490490 }
491491}
492492
493+ static void server_context_free (const struct server_context * server_context ) {
494+ if (server_context -> listener ) {
495+ evconnlistener_free (server_context -> listener );
496+ }
497+ if (server_context -> udp_sock > 0 ) {
498+ evutil_closesocket (server_context -> udp_sock );
499+ }
500+ if (server_context -> udp_context .hash ) {
501+ lh_bufferevent_udp_free (server_context -> udp_context .hash );
502+ }
503+ if (server_context -> udp_event ) {
504+ event_free (server_context -> udp_event );
505+ }
506+ }
507+
508+ static int init_server_context (struct server_context * server_context , struct event_base * base ,
509+ struct wss_proxy_context * wss_context , struct sockaddr * sockaddr , int socklen ) {
510+ unsigned flags = LEV_OPT_CLOSE_ON_FREE | LEV_OPT_CLOSE_ON_EXEC | LEV_OPT_REUSEABLE ;
511+ server_context -> listener = evconnlistener_new_bind (base , accept_conn_cb , wss_context , flags , -1 ,
512+ sockaddr , socklen );
513+ if (!server_context -> listener ) {
514+ LOGE ("cannot listen to raw for %d" , get_port (sockaddr ));
515+ goto error ;
516+ }
517+
518+ server_context -> udp_sock = init_udp_sock (sockaddr , socklen );
519+ if (server_context -> udp_sock < 0 ) {
520+ goto error ;
521+ }
522+
523+ server_context -> udp_context .hash = lh_bufferevent_udp_new (bufferevent_udp_hash , bufferevent_udp_cmp );
524+ if (!server_context -> udp_context .hash ) {
525+ LOGE ("cannot create lhash for %d" , get_port (sockaddr ));
526+ goto error ;
527+ }
528+ server_context -> udp_context .base = base ;
529+ server_context -> udp_context .wss_context = wss_context ;
530+
531+ server_context -> udp_event = event_new (base , server_context -> udp_sock , EV_READ | EV_PERSIST , udp_read_cb ,
532+ & (server_context -> udp_context ));
533+ if (!server_context -> udp_event ) {
534+ LOGE ("cannot create event for %d" , get_port (sockaddr ));
535+ goto error ;
536+ }
537+
538+ event_add (server_context -> udp_event , NULL );
539+ return 0 ;
540+ error :
541+ server_context_free (server_context );
542+ return 1 ;
543+ }
544+
493545int main () {
494546 int code = 1 ;
495547 struct event_base * base = NULL ;
496548 struct event_config * cfg = NULL ;
497549 struct event * event_parent = NULL , * event_sigquit = NULL ;
498- struct evconnlistener * listener = NULL ;
499- struct sockaddr_storage raw_addr , udp_raw_addr ;
500- int socklen ;
550+ struct sockaddr_storage raw_addr , extra_raw_addr ;
551+ struct server_context server_context , extra_server_context ;
552+ int socklen , extra_port ;
501553 struct wss_proxy_context wss_context ;
502- evutil_socket_t sock = 0 ;
503- struct event * udp_event = NULL ;
504- struct udp_context udp_context ;
505- int udp_port = 0 ;
506554
507- memset (& udp_context , 0 , sizeof (struct udp_context ));
508555 memset (& wss_context , 0 , sizeof (wss_context ));
509556 if (init_wss_addr (& wss_context .server )) {
510557 return 1 ;
@@ -532,7 +579,7 @@ int main() {
532579
533580 socklen = sizeof (raw_addr );
534581 memset (& raw_addr , 0 , socklen );
535- if (init_raw_addr (& raw_addr , & socklen , & udp_port )) {
582+ if (init_raw_addr (& raw_addr , & socklen )) {
536583 return 1 ;
537584 }
538585
@@ -554,32 +601,24 @@ int main() {
554601 goto error ;
555602 }
556603
557- listener = evconnlistener_new_bind (base , accept_conn_cb , & wss_context ,
558- LEV_OPT_CLOSE_ON_FREE | LEV_OPT_CLOSE_ON_EXEC | LEV_OPT_REUSEABLE ,
559- -1 , (struct sockaddr * ) & raw_addr , socklen );
560- if (!listener ) {
561- LOGE ("cannot listen to raw" );
604+ memset (& server_context , 0 , sizeof (server_context ));
605+ if (init_server_context (& server_context , base , & wss_context , (struct sockaddr * ) & raw_addr , socklen )) {
562606 goto error ;
563607 }
564608
565- if (udp_port < 0 ) {
566- goto start ;
567- }
568- memcpy (& udp_raw_addr , & raw_addr , socklen );
569- if (udp_port > 0 ) {
570- set_port (& udp_raw_addr , udp_port );
571- }
572- sock = init_udp_sock ((struct sockaddr * ) & udp_raw_addr , socklen );
573- if (sock < 0 ) {
574- goto error ;
609+ extra_port = find_option_port ("extra-listen-port" , 0 );
610+ if (extra_port > 0 ) {
611+ memset (& extra_server_context , 0 , sizeof (server_context ));
612+ memcpy (& extra_raw_addr , & raw_addr , socklen );
613+ set_port (& extra_raw_addr , extra_port );
614+ if (init_server_context (& extra_server_context , base , & wss_context ,
615+ (struct sockaddr * ) & extra_raw_addr , socklen )) {
616+ LOGW ("cannot listen to extra port %d" , extra_port );
617+ } else {
618+ LOGI ("extra raw server %s:%d" , getenv ("SS_LOCAL_HOST" ), extra_port );
619+ }
575620 }
576- udp_context .hash = lh_bufferevent_udp_new (bufferevent_udp_hash , bufferevent_udp_cmp );
577- udp_context .base = base ;
578- udp_context .wss_context = & wss_context ;
579- udp_event = event_new (base , sock , EV_READ | EV_PERSIST , udp_read_cb , & udp_context );
580- event_add (udp_event , NULL );
581621
582- start :
583622#ifdef OPENSSL_VERSION_STRING
584623 snprintf (wss_context .user_agent , sizeof (wss_context .user_agent ), "wss-proxy-client/%s libevent/%s OpenSSL/%s" ,
585624 WSS_PROXY_VERSION , event_get_version (), OpenSSL_version (OPENSSL_VERSION_STRING ));
@@ -607,18 +646,8 @@ int main() {
607646 if (event_sigquit ) {
608647 event_free (event_sigquit );
609648 }
610- if (udp_context .hash ) {
611- lh_bufferevent_udp_free (udp_context .hash );
612- }
613- if (listener ) {
614- evconnlistener_free (listener );
615- }
616- if (sock > 0 ) {
617- evutil_closesocket (sock );
618- }
619- if (udp_event ) {
620- event_free (udp_event );
621- }
649+ server_context_free (& server_context );
650+ server_context_free (& extra_server_context );
622651 if (base ) {
623652 event_base_free (base );
624653 }
0 commit comments