@@ -123,7 +123,8 @@ rspamd_connect_specific_server (struct rspamd_client *client, gboolean is_contro | |||
new->connection_time = time (NULL); | |||
new->client = client; | |||
/* Create socket */ | |||
new->socket = make_universal_stream_socket (serv->host, is_control ? serv->controller_port : serv->client_port, TRUE, FALSE, TRUE); | |||
new->socket = make_universal_socket (serv->host, is_control ? serv->controller_port : serv->client_port, | |||
SOCK_STREAM, TRUE, FALSE, TRUE); | |||
if (new->socket == -1) { | |||
goto err; | |||
} |
@@ -788,7 +788,7 @@ rspamd_kvstorage_connect_async (const gchar *host, | |||
gint sock; | |||
/* Here we do NOT try to resolve hostname */ | |||
if ((sock = make_universal_stream_socket (host, port, TRUE, FALSE, TRUE)) == -1) { | |||
if ((sock = make_universal_socket (host, port, SOCK_STREAM, TRUE, FALSE, TRUE)) == -1) { | |||
return KVSTORAGE_ERROR_SERVER_ERROR; | |||
} | |||
@@ -974,7 +974,7 @@ rspamd_kvstorage_connect_sync (const gchar *host, | |||
struct rspamd_kvstorage_connection *new; | |||
gint sock; | |||
if ((sock = make_universal_stream_socket (host, port, FALSE, FALSE, TRUE)) == -1) { | |||
if ((sock = make_universal_socket (host, port, SOCK_STREAM, FALSE, FALSE, TRUE)) == -1) { | |||
return KVSTORAGE_ERROR_INTERNAL_ERROR; | |||
} | |||
@@ -194,7 +194,7 @@ enum sync_affinity { | |||
struct statfile_binlog_params { | |||
enum sync_affinity affinity; | |||
time_t rotate_time; | |||
struct in_addr master_addr; | |||
gchar *master_addr; | |||
guint16 master_port; | |||
}; | |||
@@ -253,7 +253,7 @@ struct worker_conf { | |||
worker_t *worker; /**< pointer to worker type */ | |||
GQuark type; /**< type of worker */ | |||
gchar *bind_host; /**< bind line */ | |||
struct in_addr bind_addr; /**< bind address in case of TCP socket */ | |||
gchar *bind_addr; /**< bind address in case of TCP socket */ | |||
guint16 bind_port; /**< bind port in case of TCP socket */ | |||
guint16 bind_family; /**< bind type (AF_UNIX or AF_INET) */ | |||
guint16 count; /**< number of workers */ | |||
@@ -382,7 +382,7 @@ struct config_file { | |||
* @param priority priority | |||
* @return TRUE if string was parsed | |||
*/ | |||
gboolean parse_host_port_priority (const gchar *str, struct in_addr *ina, guint16 *port, guint *priority); | |||
gboolean parse_host_port_priority (memory_pool_t *pool, const gchar *str, gchar **addr, guint16 *port, guint *priority); | |||
/** | |||
* Parse host:port line | |||
@@ -390,7 +390,7 @@ gboolean parse_host_port_priority (const gchar *str, struct in_addr *ina, guint1 | |||
* @param port port | |||
* @return TRUE if string was parsed | |||
*/ | |||
gboolean parse_host_port (const gchar *str, struct in_addr *ina, guint16 *port); | |||
gboolean parse_host_port (memory_pool_t *pool, const gchar *str, gchar **addr, guint16 *port); | |||
/** | |||
* Parse host:priority line | |||
@@ -398,7 +398,7 @@ gboolean parse_host_port (const gchar *str, struct in_addr *ina, guint16 *port); | |||
* @param priority priority | |||
* @return TRUE if string was parsed | |||
*/ | |||
gboolean parse_host_priority (const gchar *str, struct in_addr *ina, guint *priority); | |||
gboolean parse_host_priority (memory_pool_t *pool, const gchar *str, gchar **addr, guint *priority); | |||
/** | |||
* Parse bind credits |
@@ -44,11 +44,16 @@ | |||
gboolean | |||
parse_host_port_priority (const gchar *str, struct in_addr *ina, guint16 *port, guint *priority) | |||
parse_host_port_priority (memory_pool_t *pool, const gchar *str, gchar **addr, guint16 *port, guint *priority) | |||
{ | |||
gchar **tokens, *err_str, *cur_tok; | |||
struct hostent *hent; | |||
struct addrinfo hints, *res; | |||
guint port_parsed, priority_parsed, saved_errno = errno; | |||
gint r; | |||
union { | |||
struct sockaddr_in v4; | |||
struct sockaddr_in6 v6; | |||
} addr_holder; | |||
tokens = g_strsplit_set (str, ":", 0); | |||
if (!tokens || !tokens[0]) { | |||
@@ -56,22 +61,43 @@ parse_host_port_priority (const gchar *str, struct in_addr *ina, guint16 *port, | |||
} | |||
/* Now try to parse host and write address to ina */ | |||
if (!inet_aton (tokens[0], ina)) { | |||
if (strcmp (tokens[0], "*") == 0) { | |||
/* Special case */ | |||
ina->s_addr = htonl (INADDR_ANY); | |||
memset (&hints, 0, sizeof (hints)); | |||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ | |||
hints.ai_socktype = SOCK_STREAM; /* Type of the socket */ | |||
hints.ai_flags = 0; | |||
hints.ai_protocol = 0; /* Any protocol */ | |||
hints.ai_canonname = NULL; | |||
hints.ai_addr = NULL; | |||
hints.ai_next = NULL; | |||
if (strcmp (tokens[0], "*") == 0) { | |||
cur_tok = NULL; | |||
hints.ai_flags |= AI_PASSIVE; | |||
} | |||
else { | |||
cur_tok = tokens[0]; | |||
} | |||
if ((r = getaddrinfo (cur_tok, NULL, &hints, &res)) == 0) { | |||
*addr = memory_pool_alloc (pool, INET6_ADDRSTRLEN); | |||
memcpy (&addr_holder, res->ai_addr, MIN (sizeof (addr_holder), res->ai_addrlen)); | |||
if (res->ai_family == AF_INET) { | |||
if (pool != NULL) { | |||
*addr = memory_pool_alloc (pool, INET_ADDRSTRLEN + 1); | |||
} | |||
inet_ntop (res->ai_family, &addr_holder.v4.sin_addr, *addr, INET_ADDRSTRLEN + 1); | |||
} | |||
else { | |||
/* Try to call gethostbyname */ | |||
hent = gethostbyname (tokens[0]); | |||
if (hent == NULL) { | |||
msg_warn ("cannot resolve %s", tokens[0]); | |||
goto err; | |||
} | |||
else { | |||
memcpy (ina, hent->h_addr, sizeof (struct in_addr)); | |||
if (pool != NULL) { | |||
*addr = memory_pool_alloc (pool, INET6_ADDRSTRLEN + 1); | |||
} | |||
inet_ntop (res->ai_family, &addr_holder.v6.sin6_addr, *addr, INET6_ADDRSTRLEN + 1); | |||
} | |||
freeaddrinfo (res); | |||
} | |||
else { | |||
msg_err ("address resolution for %s failed: %s", tokens[0], gai_strerror (r)); | |||
goto err; | |||
} | |||
if (tokens[1] != NULL) { | |||
/* Port part */ | |||
@@ -121,15 +147,15 @@ err: | |||
} | |||
gboolean | |||
parse_host_port (const gchar *str, struct in_addr *ina, guint16 *port) | |||
parse_host_port (memory_pool_t *pool, const gchar *str, gchar **addr, guint16 *port) | |||
{ | |||
return parse_host_port_priority (str, ina, port, NULL); | |||
return parse_host_port_priority (pool, str, addr, port, NULL); | |||
} | |||
gboolean | |||
parse_host_priority (const gchar *str, struct in_addr *ina, guint *priority) | |||
parse_host_priority (memory_pool_t *pool, const gchar *str, gchar **addr, guint *priority) | |||
{ | |||
return parse_host_port_priority (str, ina, NULL, priority); | |||
return parse_host_port_priority (pool, str, addr, NULL, priority); | |||
} | |||
gint | |||
@@ -137,7 +163,7 @@ parse_bind_line (struct config_file *cfg, struct worker_conf *cf, gchar *str) | |||
{ | |||
gchar **host; | |||
guint16 *family, *port; | |||
struct in_addr *addr; | |||
gchar **addr; | |||
if (str == NULL) | |||
return 0; | |||
@@ -182,7 +208,7 @@ parse_bind_line (struct config_file *cfg, struct worker_conf *cf, gchar *str) | |||
return 1; | |||
} | |||
else { | |||
if (parse_host_port (str, addr, port)) { | |||
if (parse_host_port (cfg->cfg_pool, str, addr, port)) { | |||
*host = memory_pool_strdup (cfg->cfg_pool, str); | |||
*family = AF_INET; | |||
@@ -1655,7 +1655,7 @@ handle_statfile_binlog_master (struct config_file *cfg, struct rspamd_xml_userda | |||
st->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params)); | |||
} | |||
if (!parse_host_port (data, &st->binlog->master_addr, &st->binlog->master_port)) { | |||
if (!parse_host_port (cfg->cfg_pool, data, &st->binlog->master_addr, &st->binlog->master_port)) { | |||
msg_err ("cannot parse master address: %s", data); | |||
return FALSE; | |||
} | |||
@@ -2849,7 +2849,7 @@ xml_dump_classifiers (struct config_file *cfg, FILE *f) | |||
else if (st->binlog->affinity == AFFINITY_SLAVE) { | |||
rspamd_fprintf (f, " <binlog>slave</binlog>" EOL); | |||
rspamd_fprintf (f, " <binlog_master>%s:%d</binlog_master>" EOL, | |||
inet_ntoa (st->binlog->master_addr), (gint)ntohs (st->binlog->master_port)); | |||
st->binlog->master_addr, (gint)ntohs (st->binlog->master_port)); | |||
} | |||
rspamd_fprintf (f, " <binlog_rotate>%T</binlog_rotate>" EOL, st->binlog->rotate_time); | |||
} |
@@ -47,6 +47,8 @@ static const unsigned damp = 700; | |||
static const unsigned initial_n = 128; | |||
static const unsigned initial_bias = 72; | |||
static const gint dns_port = 53; | |||
#ifdef HAVE_ARC4RANDOM | |||
#define DNS_RANDOM arc4random | |||
@@ -1306,7 +1308,7 @@ dns_timer_cb (gint fd, short what, void *arg) | |||
} | |||
if (req->server->sock == -1) { | |||
req->server->sock = make_udp_socket (&req->server->addr, htons (53), FALSE, TRUE); | |||
req->server->sock = make_universal_socket (req->server->name, dns_port, SOCK_DGRAM, TRUE, FALSE, FALSE); | |||
} | |||
req->sock = req->server->sock; | |||
@@ -1467,7 +1469,7 @@ make_dns_request (struct rspamd_dns_resolver *resolver, | |||
} | |||
if (req->server->sock == -1) { | |||
req->server->sock = make_udp_socket (&req->server->addr, htons (53), FALSE, TRUE); | |||
req->server->sock = make_universal_socket (req->server->name, dns_port, SOCK_DGRAM, TRUE, FALSE, FALSE); | |||
} | |||
req->sock = req->server->sock; | |||
@@ -1509,10 +1511,9 @@ make_dns_request (struct rspamd_dns_resolver *resolver, | |||
static gboolean | |||
parse_resolv_conf (struct rspamd_dns_resolver *resolver) | |||
{ | |||
FILE *r; | |||
gchar buf[BUFSIZ], *p; | |||
struct rspamd_dns_server *new; | |||
struct in_addr addr; | |||
FILE *r; | |||
gchar buf[BUFSIZ], *p, addr_holder[16]; | |||
struct rspamd_dns_server *new; | |||
r = fopen (RESOLV_CONF, "r"); | |||
@@ -1534,10 +1535,10 @@ parse_resolv_conf (struct rspamd_dns_resolver *resolver) | |||
continue; | |||
} | |||
else { | |||
if (inet_aton (p, &addr) != 0) { | |||
if (inet_pton (AF_INET6, p, addr_holder) == 1 || | |||
inet_pton (AF_INET, p, addr_holder) == 1) { | |||
new = &resolver->servers[resolver->servers_num]; | |||
new->name = memory_pool_strdup (resolver->static_pool, p); | |||
memcpy (&new->addr, &addr, sizeof (struct in_addr)); | |||
resolver->servers_num ++; | |||
} | |||
else { | |||
@@ -1572,7 +1573,7 @@ dns_resolver_init (struct event_base *ev_base, struct config_file *cfg) | |||
{ | |||
GList *cur; | |||
struct rspamd_dns_resolver *new; | |||
gchar *begin, *p, *err; | |||
gchar *begin, *p, *err, addr_holder[16]; | |||
gint priority, i; | |||
struct rspamd_dns_server *serv; | |||
@@ -1628,7 +1629,8 @@ dns_resolver_init (struct event_base *ev_base, struct config_file *cfg) | |||
priority = 0; | |||
} | |||
serv = &new->servers[new->servers_num]; | |||
if (inet_aton (begin, &serv->addr) != 0) { | |||
if (inet_pton (AF_INET6, p, addr_holder) == 1 || | |||
inet_pton (AF_INET, p, addr_holder) == 1) { | |||
serv->name = memory_pool_strdup (new->static_pool, begin); | |||
serv->up.priority = priority; | |||
new->servers_num ++; | |||
@@ -1653,7 +1655,7 @@ dns_resolver_init (struct event_base *ev_base, struct config_file *cfg) | |||
/* Now init all servers */ | |||
for (i = 0; i < new->servers_num; i ++) { | |||
serv = &new->servers[i]; | |||
serv->sock = make_udp_socket (&serv->addr, 53, FALSE, TRUE); | |||
serv->sock = make_universal_socket (serv->name, dns_port, SOCK_DGRAM, TRUE, FALSE, FALSE); | |||
if (serv->sock == -1) { | |||
msg_warn ("cannot create socket to server %s", serv->name); | |||
} |
@@ -22,7 +22,6 @@ typedef void (*dns_callback_type) (struct rspamd_dns_reply *reply, gpointer arg) | |||
*/ | |||
struct rspamd_dns_server { | |||
struct upstream up; /**< upstream structure */ | |||
struct in_addr addr; /**< address of DNS server */ | |||
gchar *name; /**< name of DNS server */ | |||
gint sock; /**< persistent socket */ | |||
struct event ev; |
@@ -827,7 +827,8 @@ start_fuzzy (struct rspamd_worker *worker) | |||
signal_add (&sev, NULL); | |||
/* Listen event */ | |||
while ((worker->cf->listen_sock = make_udp_socket (&worker->cf->bind_addr, worker->cf->bind_port, TRUE, TRUE)) == -1) { | |||
while ((worker->cf->listen_sock = | |||
make_universal_socket (worker->cf->bind_addr, worker->cf->bind_port, SOCK_DGRAM, TRUE, TRUE, FALSE)) == -1) { | |||
sleep (1); | |||
if (++retries > MAX_RETRIES) { | |||
msg_err ("cannot bind to socket, exiting"); |
@@ -100,7 +100,7 @@ enum rspamd_kv_flags { | |||
struct rspamd_kv_element { | |||
time_t age; /*< age of element */ | |||
guint32 expire; /*< expire of element */ | |||
enum rspamd_kv_flags flags; /*< element flags */ | |||
gint flags; /*< element flags */ | |||
gsize size; /*< size of element */ | |||
TAILQ_ENTRY (rspamd_kv_element) entry; /*< list entry */ | |||
guint keylen; /*< length of key */ |
@@ -416,6 +416,7 @@ mta_read_socket (f_str_t * in, void *arg) | |||
return FALSE; | |||
} | |||
cd->state = LMTP_WANT_CLOSING; | |||
break; | |||
case LMTP_WANT_CLOSING: | |||
if (!parse_mta_str (in, cd)) { | |||
msg_warn ("message not delivered"); | |||
@@ -452,10 +453,11 @@ lmtp_deliver_mta (struct worker_task *task) | |||
if (task->cfg->deliver_family == AF_UNIX) { | |||
un = alloca (sizeof (struct sockaddr_un)); | |||
sock = make_unix_socket (task->cfg->deliver_host, un, FALSE, TRUE); | |||
sock = make_unix_socket (task->cfg->deliver_host, un, SOCK_STREAM, FALSE, TRUE); | |||
} | |||
else { | |||
sock = make_tcp_socket (&task->cfg->deliver_addr, task->cfg->deliver_port, FALSE, TRUE); | |||
sock = make_universal_socket (task->cfg->deliver_host, task->cfg->deliver_port, | |||
SOCK_STREAM, TRUE, FALSE, TRUE); | |||
} | |||
if (sock == -1) { | |||
msg_warn ("cannot create socket for %s, %s", task->cfg->deliver_host, strerror (errno)); |
@@ -302,7 +302,7 @@ lua_http_dns_callback (struct rspamd_dns_reply *reply, gpointer arg) | |||
elt = reply->elements->data; | |||
memcpy (&ina, &elt->a.addr[0], sizeof (struct in_addr)); | |||
ud->fd = make_universal_stream_socket (inet_ntoa (ina), ud->port, TRUE, FALSE, FALSE); | |||
ud->fd = make_universal_socket (inet_ntoa (ina), ud->port, SOCK_STREAM, TRUE, FALSE, FALSE); | |||
if (ud->fd == -1) { | |||
lua_http_push_error (450, ud); | |||
@@ -473,7 +473,7 @@ lua_http_make_request_common_new (lua_State *L, struct rspamd_async_session *ses | |||
return 1; | |||
} | |||
ud->fd = make_universal_stream_socket (inet_ntoa (ina), ud->port, TRUE, FALSE, FALSE); | |||
ud->fd = make_universal_socket (inet_ntoa (ina), ud->port, SOCK_STREAM, TRUE, FALSE, FALSE); | |||
if (ud->fd == -1) { | |||
luaL_unref (L, LUA_REGISTRYINDEX, cbref); |
@@ -86,7 +86,7 @@ struct lua_upstream { | |||
struct upstream up; | |||
gchar *def; | |||
guint16 port; | |||
struct in_addr addr; | |||
gchar addr[INET6_ADDRSTRLEN]; | |||
}; | |||
static struct lua_upstream * | |||
@@ -113,7 +113,7 @@ lua_upstream_create (lua_State *L) | |||
if (def) { | |||
new = g_slice_alloc0 (sizeof (struct lua_upstream)); | |||
new->def = g_strdup (def); | |||
if (!parse_host_port_priority (new->def, &new->addr, &new->port, &new->up.priority)) { | |||
if (!parse_host_port_priority (NULL, new->def, (gchar **)&new->addr, &new->port, &new->up.priority)) { | |||
g_free (new->def); | |||
g_slice_free1 (sizeof (struct lua_upstream), new); | |||
lua_pushnil (L); | |||
@@ -157,7 +157,7 @@ lua_upstream_get_ip (lua_State *L) | |||
struct lua_upstream *up = lua_check_upstream (L); | |||
if (up) { | |||
lua_pushinteger (L, up->addr.s_addr); | |||
lua_pushstring (L, up->addr); | |||
} | |||
else { | |||
lua_pushnil (L); | |||
@@ -177,7 +177,7 @@ lua_upstream_get_ip_string (lua_State *L) | |||
struct lua_upstream *up = lua_check_upstream (L); | |||
if (up) { | |||
lua_pushstring (L, inet_ntoa (up->addr)); | |||
lua_pushstring (L, up->addr); | |||
} | |||
else { | |||
lua_pushnil (L); | |||
@@ -319,7 +319,7 @@ lua_upstream_list_create (lua_State *L) | |||
for (i = 0; i < new->count; i ++) { | |||
cur = &new->upstreams[i]; | |||
if (!parse_host_port_priority (tokens[i], &cur->addr, &cur->port, &cur->up.priority)) { | |||
if (!parse_host_port_priority (NULL, tokens[i], (gchar **)&cur->addr, &cur->port, &cur->up.priority)) { | |||
goto err; | |||
} | |||
if (cur->port == 0) { |
@@ -552,22 +552,11 @@ dump_cfg_vars (struct config_file *cfg) | |||
} | |||
static gint | |||
create_listen_socket (struct in_addr *addr, gint port, gint family, gchar *path) | |||
create_listen_socket (const gchar *addr, gint port, gint family) | |||
{ | |||
gint listen_sock = -1; | |||
struct sockaddr_un *un_addr; | |||
/* Create listen socket */ | |||
if (family == AF_INET) { | |||
if ((listen_sock = make_tcp_socket (addr, port, TRUE, TRUE)) == -1) { | |||
msg_err ("cannot create tcp listen socket. %s", strerror (errno)); | |||
} | |||
} | |||
else { | |||
un_addr = (struct sockaddr_un *)alloca (sizeof (struct sockaddr_un)); | |||
if (!un_addr || (listen_sock = make_unix_socket (path, un_addr, TRUE, TRUE)) == -1) { | |||
msg_err ("cannot create unix listen socket. %s", strerror (errno)); | |||
} | |||
} | |||
listen_sock = make_universal_socket (addr, port, SOCK_STREAM, TRUE, TRUE, TRUE); | |||
if (listen_sock != -1) { | |||
if (listen (listen_sock, -1) == -1) { | |||
@@ -595,32 +584,12 @@ fork_delayed (struct rspamd_main *rspamd) | |||
} | |||
static inline uintptr_t | |||
make_listen_key (struct in_addr *addr, gint port, gint family, gchar *path) | |||
make_listen_key (const gchar *addr, gint port, gint family) | |||
{ | |||
uintptr_t res = 0; | |||
gchar *key; | |||
if (family == AF_INET) { | |||
/* Make fnv hash from bytes of addr and port */ | |||
key = (gchar *)&addr->s_addr; | |||
while (key - (gchar *)&addr->s_addr < (gint)sizeof (addr->s_addr)) { | |||
res ^= (gchar)*key++; | |||
res += (res << 1) + (res << 4) + (res << 7) + (res << 8) + (res << 24); | |||
} | |||
key = (gchar *)&port; | |||
while (key - (gchar *)&port < (gint)sizeof (addr->s_addr)) { | |||
res ^= (gchar)*key++; | |||
res += (res << 1) + (res << 4) + (res << 7) + (res << 8) + (res << 24); | |||
} | |||
} | |||
else { | |||
/* Make fnv hash from bytes of path */ | |||
key = path; | |||
while (*key) { | |||
res ^= (gchar)*key++; | |||
res += (res << 1) + (res << 4) + (res << 7) + (res << 8) + (res << 24); | |||
} | |||
} | |||
res = murmur32_hash (addr, strlen (addr)); | |||
res ^= murmur32_hash ((guchar *)&port, sizeof (gint)); | |||
return res; | |||
} | |||
@@ -644,14 +613,14 @@ spawn_workers (struct rspamd_main *rspamd) | |||
else { | |||
if (cf->worker->has_socket) { | |||
if ((p = g_hash_table_lookup (listen_sockets, GINT_TO_POINTER ( | |||
make_listen_key (&cf->bind_addr, cf->bind_port, cf->bind_family, cf->bind_host)))) == NULL) { | |||
make_listen_key (cf->bind_host, cf->bind_port, cf->bind_family)))) == NULL) { | |||
/* Create listen socket */ | |||
listen_sock = create_listen_socket (&cf->bind_addr, cf->bind_port, cf->bind_family, cf->bind_host); | |||
listen_sock = create_listen_socket (cf->bind_host, cf->bind_port, cf->bind_family); | |||
if (listen_sock == -1) { | |||
exit (-errno); | |||
} | |||
g_hash_table_insert (listen_sockets, GINT_TO_POINTER ( | |||
make_listen_key (&cf->bind_addr, cf->bind_port, cf->bind_family, cf->bind_host)), | |||
make_listen_key (cf->bind_host, cf->bind_port, cf->bind_family)), | |||
GINT_TO_POINTER (listen_sock)); | |||
} | |||
else { |
@@ -62,7 +62,7 @@ | |||
struct storage_server { | |||
struct upstream up; | |||
gchar *name; | |||
struct in_addr addr; | |||
gchar *addr; | |||
guint16 port; | |||
}; | |||
@@ -237,10 +237,9 @@ fuzzy_check_content_type (GMimeContentType *type) | |||
static void | |||
parse_servers_string (gchar *str) | |||
{ | |||
gchar **strvec, *p, portbuf[6], *name; | |||
gint num, i, j, port; | |||
struct hostent *hent; | |||
struct in_addr addr; | |||
gchar **strvec; | |||
gint i, num; | |||
struct storage_server *cur; | |||
strvec = g_strsplit_set (str, ",", 0); | |||
num = g_strv_length (strvec); | |||
@@ -250,43 +249,14 @@ parse_servers_string (gchar *str) | |||
for (i = 0; i < num; i++) { | |||
g_strstrip (strvec[i]); | |||
if ((p = strchr (strvec[i], ':')) != NULL) { | |||
j = 0; | |||
p++; | |||
while (g_ascii_isdigit (*(p + j)) && j < (gint)sizeof (portbuf) - 1) { | |||
portbuf[j] = *(p + j); | |||
j++; | |||
cur = &fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num]; | |||
if (parse_host_port (fuzzy_module_ctx->fuzzy_pool, strvec[i], &cur->addr, &cur->port)) { | |||
if (cur->port == 0) { | |||
cur->port = DEFAULT_PORT; | |||
} | |||
portbuf[j] = '\0'; | |||
port = atoi (portbuf); | |||
} | |||
else { | |||
/* Default http port */ | |||
port = DEFAULT_PORT; | |||
} | |||
name = memory_pool_alloc (fuzzy_module_ctx->fuzzy_pool, p - strvec[i]); | |||
rspamd_strlcpy (name, strvec[i], p - strvec[i]); | |||
if (!inet_aton (name, &addr)) { | |||
/* Resolve using dns */ | |||
hent = gethostbyname (name); | |||
if (hent == NULL) { | |||
msg_info ("cannot resolve: %s", name); | |||
continue; | |||
} | |||
else { | |||
fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].port = port; | |||
fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].name = name; | |||
memcpy (&fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].addr, hent->h_addr, sizeof (struct in_addr)); | |||
fuzzy_module_ctx->servers_num++; | |||
} | |||
} | |||
else { | |||
fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].port = port; | |||
fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].name = name; | |||
memcpy (&fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].addr, &addr, sizeof (struct in_addr)); | |||
cur->name = memory_pool_strdup (fuzzy_module_ctx->fuzzy_pool, strvec[i]); | |||
fuzzy_module_ctx->servers_num++; | |||
} | |||
} | |||
g_strfreev (strvec); | |||
@@ -653,7 +623,7 @@ register_fuzzy_call (struct worker_task *task, fuzzy_hash_t *h) | |||
DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, h->hash_pipe, sizeof (h->hash_pipe)); | |||
#endif | |||
if (selected) { | |||
if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) { | |||
if ((sock = make_universal_socket (selected->addr, selected->port, SOCK_DGRAM, TRUE, FALSE, FALSE)) == -1) { | |||
msg_warn ("cannot connect to %s, %d, %s", selected->name, errno, strerror (errno)); | |||
} | |||
else { | |||
@@ -782,7 +752,7 @@ register_fuzzy_controller_call (struct controller_session *session, struct worke | |||
#endif | |||
if (selected) { | |||
/* Create UDP socket */ | |||
if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) { | |||
if ((sock = make_universal_socket (selected->addr, selected->port, SOCK_DGRAM, TRUE, FALSE, FALSE)) == -1) { | |||
msg_warn ("cannot connect to %s, %d, %s", selected->name, errno, strerror (errno)); | |||
session->state = STATE_REPLY; | |||
if (session->restful) { |
@@ -313,7 +313,8 @@ surbl_module_config (struct config_file *cfg) | |||
idx = 0; | |||
i --; | |||
for (; i >= 0; i --) { | |||
if (! parse_host_port (strvec[i], &surbl_module_ctx->redirectors[idx].ina, | |||
if (! parse_host_port (surbl_module_ctx->surbl_pool, | |||
strvec[i], &surbl_module_ctx->redirectors[idx].addr, | |||
&surbl_module_ctx->redirectors[idx].port)) { | |||
msg_warn ("invalid redirector definition: %s", strvec[idx]); | |||
} | |||
@@ -922,7 +923,7 @@ register_redirector_call (struct uri *url, struct worker_task *task, | |||
DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS); | |||
if (selected) { | |||
s = make_tcp_socket (&selected->ina, selected->port, FALSE, TRUE); | |||
s = make_universal_socket (selected->addr, selected->port, SOCK_STREAM, TRUE, FALSE, FALSE); | |||
} | |||
if (s == -1) { |
@@ -20,7 +20,7 @@ | |||
struct redirector_upstream { | |||
struct upstream up; | |||
struct in_addr ina; | |||
gchar *addr; | |||
guint16 port; | |||
gchar *name; | |||
}; |
@@ -439,7 +439,6 @@ static gboolean | |||
create_smtp_proxy_upstream_connection (struct smtp_proxy_session *session) | |||
{ | |||
struct smtp_upstream *selected; | |||
struct sockaddr_un *un; | |||
/* Try to select upstream */ | |||
selected = (struct smtp_upstream *)get_upstream_round_robin (session->ctx->upstreams, | |||
@@ -453,13 +452,7 @@ create_smtp_proxy_upstream_connection (struct smtp_proxy_session *session) | |||
session->upstream = selected; | |||
/* Now try to create socket */ | |||
if (selected->is_unix) { | |||
un = alloca (sizeof (struct sockaddr_un)); | |||
session->upstream_sock = make_unix_socket (selected->name, un, FALSE, TRUE); | |||
} | |||
else { | |||
session->upstream_sock = make_tcp_socket (&selected->addr, selected->port, FALSE, TRUE); | |||
} | |||
session->upstream_sock = make_universal_socket (selected->name, selected->port, SOCK_STREAM, TRUE, FALSE, FALSE); | |||
if (session->upstream_sock == -1) { | |||
msg_err ("cannot make a connection to %s", selected->name); | |||
upstream_fail (&selected->up, time (NULL)); |
@@ -62,7 +62,6 @@ gboolean | |||
create_smtp_upstream_connection (struct smtp_session *session) | |||
{ | |||
struct smtp_upstream *selected; | |||
struct sockaddr_un *un; | |||
/* Try to select upstream */ | |||
selected = (struct smtp_upstream *)get_upstream_round_robin (session->ctx->upstreams, | |||
@@ -76,13 +75,7 @@ create_smtp_upstream_connection (struct smtp_session *session) | |||
session->upstream = selected; | |||
/* Now try to create socket */ | |||
if (selected->is_unix) { | |||
un = alloca (sizeof (struct sockaddr_un)); | |||
session->upstream_sock = make_unix_socket (selected->name, un, FALSE, TRUE); | |||
} | |||
else { | |||
session->upstream_sock = make_tcp_socket (&selected->addr, selected->port, FALSE, TRUE); | |||
} | |||
session->upstream_sock = make_universal_socket (selected->addr, selected->port, SOCK_STREAM, TRUE, FALSE, FALSE); | |||
if (session->upstream_sock == -1) { | |||
msg_err ("cannot make a connection to %s", selected->name); | |||
upstream_fail (&selected->up, session->session_time); | |||
@@ -355,7 +348,7 @@ parse_upstreams_line (memory_pool_t *pool, struct smtp_upstream *upstreams, cons | |||
(*count) ++; | |||
} | |||
else { | |||
if (! parse_host_port (p, &cur->addr, &cur->port)) { | |||
if (! parse_host_port (pool, p, &cur->addr, &cur->port)) { | |||
g_strfreev (strv); | |||
return FALSE; | |||
} |
@@ -14,7 +14,7 @@ struct smtp_upstream { | |||
struct upstream up; | |||
const gchar *name; | |||
struct in_addr addr; | |||
gchar *addr; | |||
guint16 port; | |||
gboolean is_unix; | |||
}; |
@@ -263,8 +263,9 @@ sync_timer_callback (gint fd, short what, void *ud) | |||
return; | |||
} | |||
if ((ctx->sock = make_tcp_socket (&ctx->st->binlog->master_addr, ctx->st->binlog->master_port, FALSE, TRUE)) == -1) { | |||
msg_info ("cannot connect to %s", inet_ntoa (ctx->st->binlog->master_addr)); | |||
if ((ctx->sock = make_universal_socket (ctx->st->binlog->master_addr, ctx->st->binlog->master_port, | |||
SOCK_STREAM, TRUE, FALSE, TRUE)) == -1) { | |||
msg_info ("cannot connect to %s", ctx->st->binlog->master_addr); | |||
return; | |||
} | |||
/* Now create and activate dispatcher */ | |||
@@ -284,8 +285,7 @@ add_statfile_watch (statfile_pool_t *pool, struct statfile *st, struct config_fi | |||
struct rspamd_sync_ctx *ctx; | |||
guint32 jittered_interval; | |||
if (st->binlog->master_addr.s_addr != INADDR_NONE && | |||
st->binlog->master_addr.s_addr != INADDR_ANY) { | |||
if (st->binlog->master_addr != NULL) { | |||
ctx = memory_pool_alloc (pool->pool, sizeof (struct rspamd_sync_ctx)); | |||
ctx->st = st; | |||
ctx->timeout = cfg->statfile_sync_timeout; |
@@ -87,7 +87,7 @@ poll_sync_socket (gint fd, gint timeout, short events) | |||
} | |||
static gint | |||
make_inet_socket (gint family, struct addrinfo *addr, gboolean is_server, gboolean async) | |||
make_inet_socket (gint type, struct addrinfo *addr, gboolean is_server, gboolean async) | |||
{ | |||
gint fd, r, optlen, on = 1, s_error; | |||
struct addrinfo *cur; | |||
@@ -95,7 +95,7 @@ make_inet_socket (gint family, struct addrinfo *addr, gboolean is_server, gboole | |||
cur = addr; | |||
while (cur) { | |||
/* Create socket */ | |||
fd = socket (cur->ai_protocol, family, 0); | |||
fd = socket (cur->ai_protocol, type, 0); | |||
if (fd == -1) { | |||
msg_warn ("socket failed: %d, '%s'", errno, strerror (errno)); | |||
goto out; | |||
@@ -207,7 +207,7 @@ accept_from_socket (gint listen_sock, struct sockaddr *addr, socklen_t * len) | |||
} | |||
gint | |||
make_unix_socket (const gchar *path, struct sockaddr_un *addr, gboolean is_server, gboolean async) | |||
make_unix_socket (const gchar *path, struct sockaddr_un *addr, gint type, gboolean is_server, gboolean async) | |||
{ | |||
gint fd, s_error, r, optlen, serrno, on = 1; | |||
@@ -221,7 +221,7 @@ make_unix_socket (const gchar *path, struct sockaddr_un *addr, gboolean is_serve | |||
addr->sun_len = SUN_LEN (addr); | |||
#endif | |||
fd = socket (PF_LOCAL, SOCK_STREAM, 0); | |||
fd = socket (PF_LOCAL, type, 0); | |||
if (fd == -1) { | |||
msg_warn ("socket failed: %d, '%s'", errno, strerror (errno)); | |||
@@ -294,7 +294,7 @@ make_unix_socket (const gchar *path, struct sockaddr_un *addr, gboolean is_serve | |||
* @param try_resolve try name resolution for a socket (BLOCKING) | |||
*/ | |||
gint | |||
make_universal_stream_socket (const gchar *credits, guint16 port, gboolean async, gboolean is_server, gboolean try_resolve) | |||
make_universal_socket (const gchar *credits, guint16 port, gint type, gboolean async, gboolean is_server, gboolean try_resolve) | |||
{ | |||
struct sockaddr_un un; | |||
struct stat st; | |||
@@ -306,7 +306,7 @@ make_universal_stream_socket (const gchar *credits, guint16 port, gboolean async | |||
r = stat (credits, &st); | |||
if (is_server) { | |||
if (r == -1) { | |||
return make_unix_socket (credits, &un, is_server, async); | |||
return make_unix_socket (credits, &un, type, is_server, async); | |||
} | |||
else { | |||
/* Unix socket exists, it must be unlinked first */ | |||
@@ -327,7 +327,7 @@ make_universal_stream_socket (const gchar *credits, guint16 port, gboolean async | |||
return -1; | |||
} | |||
else { | |||
return make_unix_socket (credits, &un, is_server, async); | |||
return make_unix_socket (credits, &un, type, is_server, async); | |||
} | |||
} | |||
} | |||
@@ -336,7 +336,7 @@ make_universal_stream_socket (const gchar *credits, guint16 port, gboolean async | |||
/* TCP related part */ | |||
memset (&hints, 0, sizeof (hints)); | |||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ | |||
hints.ai_socktype = SOCK_STREAM; /* Stream socket */ | |||
hints.ai_socktype = type; /* Type of the socket */ | |||
hints.ai_flags = is_server ? AI_PASSIVE : 0; | |||
hints.ai_protocol = 0; /* Any protocol */ | |||
hints.ai_canonname = NULL; |
@@ -29,17 +29,18 @@ gint accept_from_socket (gint listen_sock, struct sockaddr *addr, socklen_t *len | |||
/* | |||
* Create and bind or connect unix socket | |||
*/ | |||
gint make_unix_socket (const gchar *, struct sockaddr_un *, gboolean is_server, gboolean async); | |||
gint make_unix_socket (const gchar *, struct sockaddr_un *, gint type, gboolean is_server, gboolean async); | |||
/** | |||
* Make universal stream socket | |||
* @param credits host, ip or path to unix socket | |||
* @param port port (used for network sockets) | |||
* @param type type of socket (SO_STREAM or SO_DGRAM) | |||
* @param async make this socket asynced | |||
* @param is_server make this socket as server socket | |||
* @param try_resolve try name resolution for a socket (BLOCKING) | |||
*/ | |||
gint make_universal_stream_socket (const gchar *credits, guint16 port, | |||
gint make_universal_socket (const gchar *credits, guint16 port, gint type, | |||
gboolean async, gboolean is_server, gboolean try_resolve); | |||
/* |