@@ -2190,7 +2190,7 @@ rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t *addr) | |||
socklen_t len = sizeof (addr->addr.ss); | |||
if ((nfd = accept (sock, &addr->addr.sa, &len)) == -1) { | |||
if (errno == EAGAIN) { | |||
if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { | |||
return 0; | |||
} | |||
return -1; | |||
@@ -2218,6 +2218,56 @@ rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t *addr) | |||
return (-1); | |||
} | |||
/* | |||
* vi:ts=4 | |||
*/ | |||
gboolean | |||
rspamd_parse_inet_address (rspamd_inet_addr_t *target, const char *src) | |||
{ | |||
gboolean ret = FALSE; | |||
if (inet_pton (AF_INET6, src, &target->addr.s6.sin6_addr) == 1) { | |||
target->af = AF_INET6; | |||
target->slen = sizeof (target->addr.s6); | |||
ret = TRUE; | |||
} | |||
else if (inet_pton (AF_INET, src, &target->addr.s4.sin_addr) == 1) { | |||
target->af = AF_INET; | |||
target->slen = sizeof (target->addr.s4); | |||
ret = TRUE; | |||
} | |||
target->addr.sa.sa_family = target->af; | |||
return ret; | |||
} | |||
const char* | |||
rspamd_inet_address_to_string (rspamd_inet_addr_t *addr) | |||
{ | |||
static char addr_str[INET6_ADDRSTRLEN + 1]; | |||
switch (addr->af) { | |||
case AF_INET: | |||
return inet_ntop (addr->af, &addr->addr.s4.sin_addr, addr_str, | |||
sizeof (addr_str)); | |||
case AF_INET6: | |||
return inet_ntop (addr->af, &addr->addr.s6.sin6_addr, addr_str, | |||
sizeof (addr_str)); | |||
case AF_UNIX: | |||
return addr->addr.su.sun_path; | |||
} | |||
return "undefined"; | |||
} | |||
uint16_t | |||
rspamd_inet_address_get_port (rspamd_inet_addr_t *addr) | |||
{ | |||
switch (addr->af) { | |||
case AF_INET: | |||
return addr->addr.s4.sin_port; | |||
case AF_INET6: | |||
return addr->addr.s6.sin6_port; | |||
} | |||
return 0; | |||
} |
@@ -466,4 +466,26 @@ void rspamd_ucl_emit_gstring (ucl_object_t *obj, enum ucl_emitter emit_type, GSt | |||
*/ | |||
gint rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t *addr); | |||
/** | |||
* Try to parse address from string | |||
* @param target target to fill | |||
* @param src IP string representation | |||
* @return TRUE if addr has been parsed | |||
*/ | |||
gboolean rspamd_parse_inet_address (rspamd_inet_addr_t *target, const char *src); | |||
/** | |||
* Returns string representation of inet address | |||
* @param addr | |||
* @return statically allocated string pointer (not thread safe) | |||
*/ | |||
const char* rspamd_inet_address_to_string (rspamd_inet_addr_t *addr); | |||
/** | |||
* Returns port number for the specified inet address in host byte order | |||
* @param addr | |||
* @return | |||
*/ | |||
uint16_t rspamd_inet_address_get_port (rspamd_inet_addr_t *addr); | |||
#endif |
@@ -298,12 +298,9 @@ accept_socket (gint fd, short what, void *arg) | |||
{ | |||
struct rspamd_worker *worker = (struct rspamd_worker *) arg; | |||
struct rspamd_worker_ctx *ctx; | |||
union sa_union su; | |||
struct rspamd_task *new_task; | |||
char ip_str[INET6_ADDRSTRLEN + 1]; | |||
socklen_t addrlen = sizeof (su); | |||
gint nfd; | |||
rspamd_inet_addr_t addr; | |||
gint nfd; | |||
ctx = worker->ctx; | |||
@@ -313,48 +310,30 @@ accept_socket (gint fd, short what, void *arg) | |||
} | |||
if ((nfd = | |||
accept_from_socket (fd, &su.sa, &addrlen)) == -1) { | |||
rspamd_accept_from_socket (fd, &addr)) == -1) { | |||
msg_warn ("accept failed: %s", strerror (errno)); | |||
return; | |||
} | |||
/* Check for EAGAIN */ | |||
if (nfd == 0){ | |||
if (nfd == 0) { | |||
return; | |||
} | |||
new_task = construct_task (worker); | |||
if (su.sa.sa_family == AF_UNIX) { | |||
msg_info ("accepted connection from unix socket"); | |||
new_task->client_addr.s_addr = INADDR_NONE; | |||
} | |||
else if (su.sa.sa_family == AF_INET) { | |||
msg_info ("accepted connection from %s port %d", | |||
inet_ntoa (su.s4.sin_addr), ntohs (su.s4.sin_port)); | |||
memcpy (&new_task->client_addr, &su.s4.sin_addr, | |||
sizeof (struct in_addr)); | |||
} | |||
else if (su.sa.sa_family == AF_INET6) { | |||
msg_info ("accepted connection from %s port %d", | |||
inet_ntop (su.sa.sa_family, &su.s6.sin6_addr, ip_str, sizeof (ip_str)), | |||
ntohs (su.s6.sin6_port)); | |||
} | |||
msg_info ("accepted connection from %s port %d", | |||
rspamd_inet_address_to_string (&addr), | |||
rspamd_inet_address_get_port (&addr)); | |||
/* Copy some variables */ | |||
new_task->sock = nfd; | |||
new_task->is_mime = ctx->is_mime; | |||
new_task->allow_learn = ctx->allow_learn; | |||
memcpy (&new_task->client_addr, &addr, sizeof (addr)); | |||
worker->srv->stat->connections_count++; | |||
new_task->resolver = ctx->resolver; | |||
#if 0 | |||
/* Set up dispatcher */ | |||
new_task->dispatcher = | |||
rspamd_create_dispatcher (ctx->ev_base, nfd, BUFFER_LINE, read_socket, write_socket, | |||
err_socket, &ctx->io_tv, (void *) new_task); | |||
new_task->dispatcher->peer_addr = new_task->client_addr.s_addr; | |||
#endif | |||
new_task->http_conn = rspamd_http_connection_new (rspamd_worker_body_handler, | |||
rspamd_worker_error_handler, rspamd_worker_finish_handler, 0, RSPAMD_HTTP_SERVER); | |||
new_task->ev_base = ctx->ev_base; |