From 611d7dcac36265ddfb2cc75d07564bc9574a56ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Fri, 3 Apr 2009 14:29:55 +0200 Subject: [PATCH] Recode the sockaddr handling, fixing some bugs --- include/lighttpd/connection.h | 5 ++- include/lighttpd/server.h | 11 ++++-- include/lighttpd/sys-socket.h | 4 +- include/lighttpd/typedefs.h | 3 ++ include/lighttpd/utils.h | 8 ++-- include/lighttpd/worker.h | 2 +- src/condition.c | 6 +-- src/connection.c | 11 ++++-- src/modules/mod_accesslog.c | 2 +- src/modules/mod_debug.c | 2 +- src/modules/mod_dirlist.c | 2 +- src/modules/mod_fastcgi.c | 24 ++++++------ src/modules/mod_status.c | 2 +- src/server.c | 71 ++++++++++++++++++++++++++--------- src/utils.c | 45 +++++++++++++++++++--- src/worker.c | 13 ++++--- 16 files changed, 150 insertions(+), 61 deletions(-) diff --git a/include/lighttpd/connection.h b/include/lighttpd/connection.h index f1c440f..5ae8d39 100644 --- a/include/lighttpd/connection.h +++ b/include/lighttpd/connection.h @@ -29,6 +29,7 @@ struct connection { guint idx; /** index in connection table */ server *srv; worker *wrk; + server_socket *srv_sock; connection_state_t state; gboolean response_headers_sent, expect_100_cont; @@ -37,8 +38,8 @@ struct connection { chunkqueue *in, *out; /* link to mainvr->in/out */ ev_io sock_watcher; - sock_addr remote_addr, local_addr; - GString *remote_addr_str, *local_addr_str; + sockaddr_t remote_addr; + GString *remote_addr_str; gboolean is_ssl, keep_alive; vrequest *mainvr; diff --git a/include/lighttpd/server.h b/include/lighttpd/server.h index 6d38c8e..1e82f02 100644 --- a/include/lighttpd/server.h +++ b/include/lighttpd/server.h @@ -11,12 +11,12 @@ typedef enum { SERVER_STOPPING /** stopping: flush logs, don't accept new connections */ } server_state; -struct server_socket; -typedef struct server_socket server_socket; - struct server_socket { + guint refcount; server *srv; ev_io watcher; + sockaddr_t local_addr; + GString *local_addr_str; }; struct server { @@ -36,7 +36,7 @@ struct server { ev_prepare srv_prepare; ev_check srv_check; - GArray *sockets; /** array of (server_socket*) */ + GPtrArray *sockets; /** array of (server_socket*) */ struct modules *modules; @@ -99,4 +99,7 @@ LI_API void server_out_of_fds(server *srv); LI_API guint server_ts_format_add(server *srv, GString* format); +LI_API void server_socket_release(server_socket* sock); +LI_API void server_socket_acquire(server_socket* sock); + #endif diff --git a/include/lighttpd/sys-socket.h b/include/lighttpd/sys-socket.h index e618894..a8474e9 100644 --- a/include/lighttpd/sys-socket.h +++ b/include/lighttpd/sys-socket.h @@ -77,9 +77,9 @@ typedef union { struct sockaddr plain; } sock_addr; -typedef struct { +typedef struct sockaddr_t { socklen_t len; sock_addr *addr; -} sockaddr; +} sockaddr_t; #endif diff --git a/include/lighttpd/typedefs.h b/include/lighttpd/typedefs.h index d44a2b8..28dd221 100644 --- a/include/lighttpd/typedefs.h +++ b/include/lighttpd/typedefs.h @@ -162,6 +162,9 @@ typedef struct response response; struct server; typedef struct server server; +struct server_socket; +typedef struct server_socket server_socket; + /* utils.h */ struct waitqueue_elem; diff --git a/include/lighttpd/utils.h b/include/lighttpd/utils.h index 42aff1a..668f629 100644 --- a/include/lighttpd/utils.h +++ b/include/lighttpd/utils.h @@ -52,10 +52,12 @@ LI_API guint hash_ipv6(gconstpointer key); LI_API GString *mimetype_get(vrequest *vr, GString *filename); /* converts a sock_addr to a human readable string. ipv4 and ipv6 supported. if dest is NULL, a new string will be allocated */ -LI_API GString *sockaddr_to_string(sock_addr *saddr, GString *dest, gboolean showport); +LI_API GString *sockaddr_to_string(sockaddr_t addr, GString *dest, gboolean showport); -LI_API sockaddr sockaddr_from_string(GString *str, guint tcp_default_port); -LI_API void sockaddr_clear(sockaddr *saddr); +LI_API sockaddr_t sockaddr_from_string(GString *str, guint tcp_default_port); +LI_API sockaddr_t sockaddr_local_from_socket(gint fd); +LI_API sockaddr_t sockaddr_remote_from_socket(gint fd); +LI_API void sockaddr_clear(sockaddr_t *saddr); LI_API void gstring_replace_char_with_str_len(GString *gstr, gchar c, gchar *str, guint len); diff --git a/include/lighttpd/worker.h b/include/lighttpd/worker.h index d78ed5b..6d505d9 100644 --- a/include/lighttpd/worker.h +++ b/include/lighttpd/worker.h @@ -106,7 +106,7 @@ LI_API void worker_run(worker *wrk); LI_API void worker_stop(worker *context, worker *wrk); LI_API void worker_exit(worker *context, worker *wrk); -LI_API void worker_new_con(worker *ctx, worker *wrk, sock_addr *remote_addr, int s); +LI_API void worker_new_con(worker *ctx, worker *wrk, sockaddr_t remote_addr, int s, server_socket *srv_sock); LI_API void worker_check_keepalive(worker *wrk); diff --git a/src/condition.c b/src/condition.c index eef605a..7de5d35 100644 --- a/src/condition.c +++ b/src/condition.c @@ -306,7 +306,7 @@ static handler_t condition_check_eval_string(vrequest *vr, condition *cond, gboo switch (cond->lvalue->type) { case COMP_REQUEST_LOCALIP: - val = con->local_addr_str->str; + val = con->srv_sock->local_addr_str->str; break; case COMP_REQUEST_REMOTEIP: val = con->remote_addr_str->str; @@ -506,11 +506,11 @@ static handler_t condition_check_eval_ip(vrequest *vr, condition *cond, gboolean switch (cond->lvalue->type) { case COMP_REQUEST_LOCALIP: - if (!condition_ip_from_socket(&ipval, &con->local_addr)) + if (!condition_ip_from_socket(&ipval, con->srv_sock->local_addr.addr)) return HANDLER_GO_ON; break; case COMP_REQUEST_REMOTEIP: - if (!condition_ip_from_socket(&ipval, &con->remote_addr)) + if (!condition_ip_from_socket(&ipval, con->remote_addr.addr)) return HANDLER_GO_ON; break; case COMP_REQUEST_PATH: diff --git a/src/connection.c b/src/connection.c index 7a3ac84..531b4e4 100644 --- a/src/connection.c +++ b/src/connection.c @@ -321,7 +321,6 @@ connection* connection_new(worker *wrk) { ev_io_set(&con->sock_watcher, -1, 0); con->sock_watcher.data = con; con->remote_addr_str = g_string_sized_new(INET6_ADDRSTRLEN); - con->local_addr_str = g_string_sized_new(INET6_ADDRSTRLEN); con->keep_alive = TRUE; con->raw_in = chunkqueue_new(); @@ -361,6 +360,9 @@ void connection_reset(connection *con) { con->response_headers_sent = FALSE; con->expect_100_cont = FALSE; + server_socket_release(con->srv_sock); + con->srv_sock = NULL; + ev_io_stop(con->wrk->loop, &con->sock_watcher); if (con->sock_watcher.fd != -1) { if (con->raw_in->is_closed) { /* read already shutdown */ @@ -376,7 +378,7 @@ void connection_reset(connection *con) { http_request_parser_reset(&con->req_parser_ctx); g_string_truncate(con->remote_addr_str, 0); - g_string_truncate(con->local_addr_str, 0); + sockaddr_clear(&con->remote_addr); con->keep_alive = TRUE; chunkqueue_reset(con->raw_in); @@ -466,6 +468,9 @@ void connection_free(connection *con) { con->response_headers_sent = FALSE; con->expect_100_cont = FALSE; + server_socket_release(con->srv_sock); + con->srv_sock = NULL; + if (con->wrk) ev_io_stop(con->wrk->loop, &con->sock_watcher); if (con->sock_watcher.fd != -1) { @@ -475,7 +480,7 @@ void connection_free(connection *con) { } ev_io_set(&con->sock_watcher, -1, 0); g_string_free(con->remote_addr_str, TRUE); - g_string_free(con->local_addr_str, TRUE); + sockaddr_clear(&con->remote_addr); con->keep_alive = TRUE; chunkqueue_free(con->raw_in); diff --git a/src/modules/mod_accesslog.c b/src/modules/mod_accesslog.c index 80f7c4b..5b6f877 100644 --- a/src/modules/mod_accesslog.c +++ b/src/modules/mod_accesslog.c @@ -240,7 +240,7 @@ static GString *al_format_log(connection *con, al_data *ald, GArray *format) { g_string_append_len(str, GSTR_LEN(con->remote_addr_str)); break; case AL_FORMAT_LOCAL_ADDR: - g_string_append_len(str, GSTR_LEN(con->local_addr_str)); + g_string_append_len(str, GSTR_LEN(con->srv_sock->local_addr_str)); break; case AL_FORMAT_BYTES_RESPONSE: g_string_append_printf(str, "%jd", vr->out->bytes_out); diff --git a/src/modules/mod_debug.c b/src/modules/mod_debug.c index 7872098..71d4110 100644 --- a/src/modules/mod_debug.c +++ b/src/modules/mod_debug.c @@ -97,7 +97,7 @@ static gpointer debug_collect_func(worker *wrk, gpointer fdata) { cd->is_ssl = c->is_ssl; cd->keep_alive = c->keep_alive; cd->remote_addr_str = g_string_new_len(GSTR_LEN(c->remote_addr_str)); - cd->local_addr_str = g_string_new_len(GSTR_LEN(c->local_addr_str)); + cd->local_addr_str = g_string_new_len(GSTR_LEN(c->srv_sock->local_addr_str)); cd->host = g_string_new_len(GSTR_LEN(c->mainvr->request.uri.host)); cd->path = g_string_new_len(GSTR_LEN(c->mainvr->request.uri.path)); cd->query = g_string_new_len(GSTR_LEN(c->mainvr->request.uri.query)); diff --git a/src/modules/mod_dirlist.c b/src/modules/mod_dirlist.c index 9be0e18..0a71b81 100644 --- a/src/modules/mod_dirlist.c +++ b/src/modules/mod_dirlist.c @@ -208,7 +208,7 @@ static handler_t dirlist(vrequest *vr, gpointer param, gpointer *context) { } /* redirect to scheme + host + path + / + querystring if directory without trailing slash */ /* TODO: local addr if HTTP 1.0 without host header, url encoding */ - host = vr->request.uri.authority->len ? vr->request.uri.authority : vr->con->local_addr_str; + host = vr->request.uri.authority->len ? vr->request.uri.authority : vr->con->srv_sock->local_addr_str; uri = g_string_sized_new( 8 /* https:// */ + host->len + vr->request.uri.orig_path->len + 2 /* /? */ + vr->request.uri.query->len diff --git a/src/modules/mod_fastcgi.c b/src/modules/mod_fastcgi.c index bc56430..983bea5 100644 --- a/src/modules/mod_fastcgi.c +++ b/src/modules/mod_fastcgi.c @@ -87,7 +87,7 @@ struct fastcgi_connection { struct fastcgi_context { gint refcount; - sockaddr socket; + sockaddr_t socket; guint timeout; plugin *plugin; }; @@ -132,7 +132,7 @@ enum FCGI_ProtocolStatus { /**********************************************************************************/ static fastcgi_context* fastcgi_context_new(server *srv, plugin *p, GString *dest_socket) { - sockaddr saddr; + sockaddr_t saddr; fastcgi_context* ctx; saddr = sockaddr_from_string(dest_socket, 0); if (NULL == saddr.addr) { @@ -329,29 +329,29 @@ static void fastcgi_env_create(vrequest *vr, environment_dup *envdup, GString* b fastcgi_env_add(buf, envdup, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1")); { guint port = 0; - switch (con->local_addr.plain.sa_family) { - case AF_INET: port = con->local_addr.ipv4.sin_port; break; + switch (con->srv_sock->local_addr.addr->plain.sa_family) { + case AF_INET: port = con->srv_sock->local_addr.addr->ipv4.sin_port; break; #ifdef HAVE_IPV6 - case AF_INET6: port = con->local_addr.ipv6.sin6_port; break; + case AF_INET6: port = con->srv_sock->local_addr.addr->ipv6.sin6_port; break; #endif } if (port) { - g_string_printf(tmp, "%u", port); + g_string_printf(tmp, "%u", htons(port)); fastcgi_env_add(buf, envdup, CONST_STR_LEN("SERVER_PORT"), GSTR_LEN(tmp)); } } - fastcgi_env_add(buf, envdup, CONST_STR_LEN("SERVER_ADDR"), GSTR_LEN(con->local_addr_str)); + fastcgi_env_add(buf, envdup, CONST_STR_LEN("SERVER_ADDR"), GSTR_LEN(con->srv_sock->local_addr_str)); { guint port = 0; - switch (con->remote_addr.plain.sa_family) { - case AF_INET: port = con->remote_addr.ipv4.sin_port; break; + switch (con->remote_addr.addr->plain.sa_family) { + case AF_INET: port = con->remote_addr.addr->ipv4.sin_port; break; #ifdef HAVE_IPV6 - case AF_INET6: port = con->remote_addr.ipv6.sin6_port; break; + case AF_INET6: port = con->remote_addr.addr->ipv6.sin6_port; break; #endif } if (port) { - g_string_printf(tmp, "%u", port); + g_string_printf(tmp, "%u", htons(port)); fastcgi_env_add(buf, envdup, CONST_STR_LEN("REMOTE_PORT"), GSTR_LEN(tmp)); } } @@ -685,7 +685,7 @@ static handler_t fastcgi_statemachine(vrequest *vr, fastcgi_connection *fcon) { return HANDLER_GO_ON; default: VR_ERROR(vr, "Couldn't connect to '%s': %s", - sockaddr_to_string(fcon->ctx->socket.addr, vr->con->wrk->tmp_str, TRUE)->str, + sockaddr_to_string(fcon->ctx->socket, vr->con->wrk->tmp_str, TRUE)->str, g_strerror(errno)); fastcgi_close(vr, p); vrequest_backend_dead(vr); diff --git a/src/modules/mod_status.c b/src/modules/mod_status.c index 96d98c5..893cd8c 100644 --- a/src/modules/mod_status.c +++ b/src/modules/mod_status.c @@ -204,7 +204,7 @@ static gpointer status_collect_func(worker *wrk, gpointer fdata) { cd->is_ssl = c->is_ssl; cd->keep_alive = c->keep_alive; cd->remote_addr_str = g_string_new_len(GSTR_LEN(c->remote_addr_str)); - cd->local_addr_str = g_string_new_len(GSTR_LEN(c->local_addr_str)); + cd->local_addr_str = g_string_new_len(GSTR_LEN(c->srv_sock->local_addr_str)); cd->host = g_string_new_len(GSTR_LEN(c->mainvr->request.uri.host)); cd->path = g_string_new_len(GSTR_LEN(c->mainvr->request.uri.path)); cd->query = g_string_new_len(GSTR_LEN(c->mainvr->request.uri.query)); diff --git a/src/server.c b/src/server.c index 49c5026..4829433 100644 --- a/src/server.c +++ b/src/server.c @@ -2,6 +2,37 @@ #include #include +static void server_listen_cb(struct ev_loop *loop, ev_io *w, int revents); + +static server_socket* server_socket_new(int fd) { + server_socket *sock = g_slice_new0(server_socket); + + sock->refcount = 1; + sock->watcher.data = sock; + sock->local_addr = sockaddr_local_from_socket(fd); + sock->local_addr_str = g_string_sized_new(0); + sockaddr_to_string(sock->local_addr, sock->local_addr_str, FALSE); + fd_init(fd); + ev_init(&sock->watcher, server_listen_cb); + ev_io_set(&sock->watcher, fd, EV_READ); + return sock; +} + +void server_socket_release(server_socket* sock) { + if (!sock) return; + assert(g_atomic_int_get(&sock->refcount) > 0); + if (g_atomic_int_dec_and_test(&sock->refcount)) { + sockaddr_clear(&sock->local_addr); + g_string_free(sock->local_addr_str, TRUE); + g_slice_free(server_socket, sock); + } +} + +void server_socket_acquire(server_socket* sock) { + assert(g_atomic_int_get(&sock->refcount) > 0); + g_atomic_int_inc(&sock->refcount); +} + static void server_value_free(gpointer _so) { g_slice_free(server_option, _so); } @@ -57,7 +88,7 @@ server* server_new(const gchar *module_dir) { srv->workers = g_array_new(FALSE, TRUE, sizeof(worker*)); - srv->sockets = g_array_new(FALSE, TRUE, sizeof(server_socket*)); + srv->sockets = g_ptr_array_new(); srv->modules = modules_init(srv, module_dir); @@ -131,11 +162,11 @@ void server_free(server* srv) { { guint i; for (i = 0; i < srv->sockets->len; i++) { - server_socket *sock = g_array_index(srv->sockets, server_socket*, i); + server_socket *sock = g_ptr_array_index(srv->sockets, i); close(sock->watcher.fd); - g_slice_free(server_socket, sock); + server_socket_release(sock); } - g_array_free(srv->sockets, TRUE); + g_ptr_array_free(srv->sockets, TRUE); } { @@ -201,15 +232,25 @@ static void server_listen_cb(struct ev_loop *loop, ev_io *w, int revents) { server_socket *sock = (server_socket*) w->data; server *srv = sock->srv; int s; - sock_addr remote_addr; - socklen_t l = sizeof(remote_addr); + sockaddr_t remote_addr; + struct sockaddr sa; + socklen_t l = sizeof(sa); UNUSED(loop); UNUSED(revents); - while (-1 != (s = accept(w->fd, (struct sockaddr*) &remote_addr, &l))) { + while (-1 != (s = accept(w->fd, &sa, &l))) { worker *wrk = srv->main_worker; guint i, min_load = g_atomic_int_get(&wrk->connection_load), sel = 0; + if (l <= sizeof(sa)) { + remote_addr.addr = g_slice_alloc(l); + remote_addr.len = l; + memcpy(remote_addr.addr, &sa, l); + } else { + remote_addr = sockaddr_remote_from_socket(s); + } + l = sizeof(sa); /* reset l */ + fd_init(s); for (i = 1; i < srv->worker_count; i++) { @@ -224,7 +265,8 @@ static void server_listen_cb(struct ev_loop *loop, ev_io *w, int revents) { g_atomic_int_inc((gint*) &wrk->connection_load); /* TRACE(srv, "selected worker %u with load %u", sel, min_load); */ - worker_new_con(srv->main_worker, wrk, &remote_addr, s); + server_socket_acquire(sock); + worker_new_con(srv->main_worker, wrk, remote_addr, s, sock); } #ifdef _WIN32 @@ -253,17 +295,12 @@ static void server_listen_cb(struct ev_loop *loop, ev_io *w, int revents) { } void server_listen(server *srv, int fd) { - server_socket *sock; + server_socket *sock = server_socket_new(fd); - sock = g_slice_new0(server_socket); sock->srv = srv; - sock->watcher.data = sock; - fd_init(fd); - ev_init(&sock->watcher, server_listen_cb); - ev_io_set(&sock->watcher, fd, EV_READ); if (g_atomic_int_get(&srv->state) == SERVER_RUNNING) ev_io_start(srv->main_worker->loop, &sock->watcher); - g_array_append_val(srv->sockets, sock); + g_ptr_array_add(srv->sockets, sock); } void server_start(server *srv) { @@ -283,7 +320,7 @@ void server_start(server *srv) { plugins_prepare_callbacks(srv); for (i = 0; i < srv->sockets->len; i++) { - server_socket *sock = g_array_index(srv->sockets, server_socket*, i); + server_socket *sock = g_ptr_array_index(srv->sockets, i); ev_io_start(srv->main_worker->loop, &sock->watcher); } @@ -307,7 +344,7 @@ void server_stop(server *srv) { if (srv->main_worker) { for (i = 0; i < srv->sockets->len; i++) { - server_socket *sock = g_array_index(srv->sockets, server_socket*, i); + server_socket *sock = g_ptr_array_index(srv->sockets, i); ev_io_stop(srv->main_worker->loop, &sock->watcher); } diff --git a/src/utils.c b/src/utils.c index 110bf4f..513f40b 100644 --- a/src/utils.c +++ b/src/utils.c @@ -432,12 +432,13 @@ GString *mimetype_get(vrequest *vr, GString *filename) { } -GString *sockaddr_to_string(sock_addr *saddr, GString *dest, gboolean showport) { +GString *sockaddr_to_string(sockaddr_t addr, GString *dest, gboolean showport) { gchar *p; guint8 len = 0; guint8 tmp; guint8 tmplen; guint8 oct; + sock_addr *saddr = addr.addr; switch (saddr->plain.sa_family) { case AF_INET: @@ -502,13 +503,13 @@ GString *sockaddr_to_string(sock_addr *saddr, GString *dest, gboolean showport) return dest; } -sockaddr sockaddr_from_string(GString *str, guint tcp_default_port) { +sockaddr_t sockaddr_from_string(GString *str, guint tcp_default_port) { guint32 ipv4; #ifdef HAVE_IPV6 guint8 ipv6[16]; #endif guint16 port = tcp_default_port; - sockaddr saddr = { 0, NULL }; + sockaddr_t saddr = { 0, NULL }; #ifdef HAVE_SYS_UN_H if (0 == strncmp(str->str, "unix:/", 6)) { @@ -539,8 +540,42 @@ sockaddr sockaddr_from_string(GString *str, guint tcp_default_port) { return saddr; } -void sockaddr_clear(sockaddr *saddr) { - g_slice_free1(saddr->len, saddr->addr); +sockaddr_t sockaddr_local_from_socket(gint fd) { + socklen_t l = 0; + static struct sockaddr sa; + struct sockaddr_t saddr = { 0, NULL }; + + if (-1 == getsockname(fd, &sa, &l)) { + return saddr; + } + + saddr.addr = (sock_addr*) g_slice_alloc0(l); + saddr.len = l; + getsockname(fd, (struct sockaddr*) saddr.addr, &l); + + return saddr; +} + +sockaddr_t sockaddr_remote_from_socket(gint fd) { + socklen_t l = 0; + static struct sockaddr sa; + struct sockaddr_t saddr = { 0, NULL }; + + if (-1 == getpeername(fd, &sa, &l)) { + return saddr; + } + + saddr.addr = (sock_addr*) g_slice_alloc0(l); + saddr.len = l; + getpeername(fd, (struct sockaddr*) saddr.addr, &l); + + return saddr; +} + +void sockaddr_clear(sockaddr_t *saddr) { + if (saddr->addr) g_slice_free1(saddr->len, saddr->addr); + saddr->addr = NULL; + saddr->len = 0; } /* unused */ diff --git a/src/worker.c b/src/worker.c index fd0dfab..e7b943a 100644 --- a/src/worker.c +++ b/src/worker.c @@ -196,17 +196,19 @@ static void worker_exit_cb(struct ev_loop *loop, ev_async *w, int revents) { struct worker_new_con_data; typedef struct worker_new_con_data worker_new_con_data; struct worker_new_con_data { - sock_addr remote_addr; + sockaddr_t remote_addr; int s; + server_socket *srv_sock; }; /* new con watcher */ -void worker_new_con(worker *ctx, worker *wrk, sock_addr *remote_addr, int s) { +void worker_new_con(worker *ctx, worker *wrk, sockaddr_t remote_addr, int s, server_socket *srv_sock) { if (ctx == wrk) { connection *con = worker_con_get(wrk); + con->srv_sock = srv_sock; con->state = CON_STATE_REQUEST_START; - con->remote_addr = *remote_addr; + con->remote_addr = remote_addr; ev_io_set(&con->sock_watcher, s, EV_READ); ev_io_start(wrk->loop, &con->sock_watcher); con->ts = CUR_TS(con->wrk); @@ -214,8 +216,9 @@ void worker_new_con(worker *ctx, worker *wrk, sock_addr *remote_addr, int s) { waitqueue_push(&wrk->io_timeout_queue, &con->io_timeout_elem); } else { worker_new_con_data *d = g_slice_new(worker_new_con_data); - d->remote_addr = *remote_addr; + d->remote_addr = remote_addr; d->s = s; + d->srv_sock = srv_sock; g_async_queue_push(wrk->new_con_queue, d); ev_async_send(wrk->loop, &wrk->new_con_watcher); } @@ -228,7 +231,7 @@ static void worker_new_con_cb(struct ev_loop *loop, ev_async *w, int revents) { UNUSED(revents); while (NULL != (d = g_async_queue_try_pop(wrk->new_con_queue))) { - worker_new_con(wrk, wrk, &d->remote_addr, d->s); + worker_new_con(wrk, wrk, d->remote_addr, d->s, d->srv_sock); g_slice_free(worker_new_con_data, d); } }