Recode the sockaddr handling, fixing some bugs
This commit is contained in:
parent
293fabc963
commit
611d7dcac3
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
71
src/server.c
71
src/server.c
|
@ -2,6 +2,37 @@
|
|||
#include <lighttpd/base.h>
|
||||
#include <lighttpd/plugin_core.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
45
src/utils.c
45
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 */
|
||||
|
|
13
src/worker.c
13
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue