Skip to content

Commit 689f0e7

Browse files
committed
client: support extra-listen-port
1 parent 51375b2 commit 689f0e7

File tree

4 files changed

+95
-65
lines changed

4 files changed

+95
-65
lines changed

common.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ uint16_t get_http_port(struct evhttp_connection *evcon) {
7373
}
7474
#endif
7575

76-
uint16_t get_port(struct sockaddr *sockaddr) {
76+
uint16_t get_port(const struct sockaddr *sockaddr) {
7777
if (sockaddr->sa_family == AF_INET6) {
7878
return ntohs(((struct sockaddr_in6 *) sockaddr)->sin6_port);
7979
} else {
@@ -167,10 +167,10 @@ const char *find_option(const char *options, const char *key, const char *no_val
167167
return NULL;
168168
}
169169

170-
int find_udp_port(int default_port) {
170+
int find_option_port(const char *key, int default_port) {
171171
char *end;
172172
const char *value;
173-
value = find_option(getenv("SS_PLUGIN_OPTIONS"), "udp-port", NULL);
173+
value = find_option(getenv("SS_PLUGIN_OPTIONS"), key, NULL);
174174
if (value != NULL) {
175175
int port = (int) strtol(value, &end, 10);
176176
if (port <= 0 || port > 65535 || (*end != '\0' && *end != ';')) {

common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ uint16_t get_peer_port(struct bufferevent *bev);
9393
uint16_t get_http_port(struct evhttp_connection *evcon);
9494
#endif
9595

96-
uint16_t get_port(struct sockaddr *sockaddr);
96+
uint16_t get_port(const struct sockaddr *sockaddr);
9797

9898
void set_port(struct sockaddr_storage *sockaddr, uint16_t port);
9999

@@ -122,7 +122,7 @@ enum log_level get_log_level(void);
122122

123123
const char *find_option(const char *options, const char *key, const char *no_value);
124124

125-
int find_udp_port(int default_port);
125+
int find_option_port(const char *key, int default_port);
126126

127127
int init_event_signal(struct event_base *base, struct event **event_parent, struct event **event_sigquit);
128128

wss-proxy-client.c

Lines changed: 88 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
3744
static 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+
493545
int 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
}

wss-proxy-server.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static int init_raw_info(struct raw_server_info *raw_server_info) {
7272
return EINVAL;
7373
}
7474

75-
raw_server_info->udp_port = find_udp_port(raw_server_info->port);
75+
raw_server_info->udp_port = find_option_port("udp-port", raw_server_info->port);
7676

7777
if (raw_server_info->udp_port > 0) {
7878
LOGI("raw client tcp://%s:%d, udp://%s:%d", raw_server_info->addr, raw_server_info->port,
@@ -172,6 +172,7 @@ static struct bufferevent *init_udp_client(struct event_base *base, struct raw_s
172172
}
173173
data = calloc(1, sizeof(struct bufferevent_udp));
174174
if (data == NULL) {
175+
LOGE("cannot calloc for udp socket");
175176
goto error;
176177
}
177178
data->sock = sock;

0 commit comments

Comments
 (0)