diff --git a/plugins/fastrouter/fastrouter.c b/plugins/fastrouter/fastrouter.c index 09d216a4..9d66657a 100644 --- a/plugins/fastrouter/fastrouter.c +++ b/plugins/fastrouter/fastrouter.c @@ -22,6 +22,7 @@ #define LONG_ARGS_FASTROUTER_USE_CODE_STRING 150008 #define LONG_ARGS_FASTROUTER_TOLERANCE 150009 #define LONG_ARGS_FASTROUTER_STATS 150010 +#define LONG_ARGS_FASTROUTER_ZERG 150011 #define FASTROUTER_STATUS_FREE 0 #define FASTROUTER_STATUS_CONNECTING 1 @@ -39,6 +40,7 @@ void fastrouter_send_stats(int); struct uwsgi_fastrouter_socket { char *name; int fd; + char *zerg; struct uwsgi_fastrouter_socket *next; }; @@ -93,7 +95,7 @@ static void fastrouter_go_cheap(void) { } -static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name) { +static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name, int fd) { struct uwsgi_fastrouter_socket *uwsgi_sock = ufr.sockets, *old_uwsgi_sock; @@ -113,6 +115,12 @@ static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name) { memset(uwsgi_sock, 0, sizeof(struct uwsgi_fastrouter_socket)); uwsgi_sock->name = name; + if (name) { + uwsgi_sock->fd = -1; + } + else { + uwsgi_sock->fd = fd; + } return uwsgi_sock; } @@ -121,6 +129,7 @@ static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name) { struct option fastrouter_options[] = { {"fastrouter", required_argument, 0, LONG_ARGS_FASTROUTER}, + {"fastrouter-zerg", required_argument, 0, LONG_ARGS_FASTROUTER_ZERG}, {"fastrouter-use-cache", no_argument, &ufr.use_cache, 1}, {"fastrouter-use-pattern", required_argument, 0, LONG_ARGS_FASTROUTER_USE_PATTERN}, {"fastrouter-use-base", required_argument, 0, LONG_ARGS_FASTROUTER_USE_BASE}, @@ -333,7 +342,10 @@ void fastrouter_loop() { struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets; while(ufr_sock) { - if (ufr_sock->name[0] == '=') { + if (ufr_sock->fd > -1) { + ufr_sock->name = uwsgi_getsockname(ufr_sock->fd); + } + else if (ufr_sock->name[0] == '=') { int shared_socket = atoi(ufr_sock->name+1); if (shared_socket >= 0) { ufr_sock->fd = uwsgi_get_shared_socket_fd_by_num(shared_socket); @@ -352,7 +364,12 @@ void fastrouter_loop() { } } - uwsgi_log("uwsgi fastrouter/proxy bound on %s\n", ufr_sock->name); + if (ufr_sock->zerg) { + uwsgi_log("uwsgi fastrouter/proxy bound on %s (from zerg server %s)\n", ufr_sock->name, ufr_sock->zerg); + } + else { + uwsgi_log("uwsgi fastrouter/proxy bound on %s\n", ufr_sock->name); + } if (!ufr.cheap) { event_queue_add_fd_read(ufr.queue, ufr_sock->fd); @@ -792,10 +809,32 @@ int fastrouter_opt(int i, char *optarg) { char *cs; char *cs_code; char *cs_func; + int zerg_fd; + int *zerg; + int j; + struct uwsgi_fastrouter_socket *fr_sock; switch(i) { case LONG_ARGS_FASTROUTER: - uwsgi_fastrouter_new_socket(generate_socket_name(optarg)); + uwsgi_fastrouter_new_socket(generate_socket_name(optarg), -1); + return 1; + case LONG_ARGS_FASTROUTER_ZERG: + zerg_fd = uwsgi_connect(optarg, 30, 0); + if (zerg_fd < 0) { + uwsgi_log("--- unable to connect to zerg server ---\n"); + exit(1); + } + zerg = uwsgi_attach_fd(zerg_fd, 8, "uwsgi-zerg", 11); + if (zerg == NULL) { + uwsgi_log("--- invalid data received from zerg-server ---\n"); + exit(1); + } + close(zerg_fd); + for(j=0;j<8;j++) { + if (zerg[j] == -1) break; + fr_sock = uwsgi_fastrouter_new_socket(NULL, zerg[j]); + fr_sock->zerg = optarg; + } return 1; case LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER: ufr.subscription_server = optarg; diff --git a/socket.c b/socket.c index 7a722094..6e4b1f66 100644 --- a/socket.c +++ b/socket.c @@ -2,6 +2,43 @@ extern struct uwsgi_server uwsgi; +char *uwsgi_getsockname(int fd) { + + socklen_t socket_type_len = sizeof(struct sockaddr_un); + union uwsgi_sockaddr usa; + union uwsgi_sockaddr_ptr gsa; + char computed_port[6]; + char ipv4a[INET_ADDRSTRLEN + 1]; + + gsa.sa = (struct sockaddr *) &usa; + + if (!getsockname(fd, gsa.sa, &socket_type_len)) { + if (gsa.sa->sa_family == AF_UNIX) { + if (usa.sa_un.sun_path[0] == 0) { + return uwsgi_concat2("@", usa.sa_un.sun_path+1); + } + else { + return uwsgi_str(usa.sa_un.sun_path); + } + } + else { + memset(ipv4a, 0, INET_ADDRSTRLEN + 1); + memset(computed_port, 0, 6); + if (snprintf(computed_port, 6, "%d", ntohs(gsa.sa_in->sin_port)) > 0) { + if (inet_ntop(AF_INET, (const void *) &gsa.sa_in->sin_addr.s_addr, ipv4a, INET_ADDRSTRLEN)) { + if (!strcmp("0.0.0.0", ipv4a)) { + return uwsgi_concat2(":", computed_port); + } + else { + return uwsgi_concat3(ipv4a, ":", computed_port); + } + } + } + } + } + return NULL; +} + int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abstract_socket) { int serverfd; diff --git a/uwsgi.h b/uwsgi.h index 0a74047b..cce57013 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2570,6 +2570,8 @@ void uwsgi_build_cap(char *); void uwsgi_register_logger(char *, ssize_t (*func)(struct uwsgi_logger *, char *, size_t)); struct uwsgi_logger *uwsgi_get_logger(char *); +char *uwsgi_getsockname(int); + #ifdef UWSGI_AS_SHARED_LIBRARY int uwsgi_init(int, char **, char **); #endif