aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2013-06-01 15:52:11 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2013-06-01 15:52:11 +0100
commit37845898cbf779c7d3b5664997d0db48968c929c (patch)
treea190b5ee9d152ba60135136bbe8108d7da81166c /src
parent8cc2aee8859731ee2fe280070423f79e7d009ca3 (diff)
downloadrspamd-37845898cbf779c7d3b5664997d0db48968c929c.tar.gz
rspamd-37845898cbf779c7d3b5664997d0db48968c929c.zip
Rework socket creation logic to support both ipv4 and ipv6 sockets.
Diffstat (limited to 'src')
-rw-r--r--src/cfg_file.h10
-rw-r--r--src/cfg_utils.c66
-rw-r--r--src/cfg_xml.c4
-rw-r--r--src/dns.c24
-rw-r--r--src/dns.h1
-rw-r--r--src/fuzzy_storage.c3
-rw-r--r--src/kvstorage.h2
-rw-r--r--src/lmtp_proto.c6
-rw-r--r--src/lua/lua_http.c4
-rw-r--r--src/lua/lua_upstream.c10
-rw-r--r--src/main.c49
-rw-r--r--src/plugins/fuzzy_check.c52
-rw-r--r--src/plugins/surbl.c5
-rw-r--r--src/plugins/surbl.h2
-rw-r--r--src/smtp_proxy.c9
-rw-r--r--src/smtp_utils.c11
-rw-r--r--src/smtp_utils.h2
-rw-r--r--src/statfile_sync.c8
-rw-r--r--src/util.c16
-rw-r--r--src/util.h5
20 files changed, 123 insertions, 166 deletions
diff --git a/src/cfg_file.h b/src/cfg_file.h
index bb638888d..3b7059786 100644
--- a/src/cfg_file.h
+++ b/src/cfg_file.h
@@ -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
diff --git a/src/cfg_utils.c b/src/cfg_utils.c
index 4acfead35..78530218d 100644
--- a/src/cfg_utils.c
+++ b/src/cfg_utils.c
@@ -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;
diff --git a/src/cfg_xml.c b/src/cfg_xml.c
index 3d58d128e..a325b3b7a 100644
--- a/src/cfg_xml.c
+++ b/src/cfg_xml.c
@@ -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);
}
diff --git a/src/dns.c b/src/dns.c
index 1d4f48b35..99e0d7c58 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -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);
}
diff --git a/src/dns.h b/src/dns.h
index 8914ae5b1..b04aa285f 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -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;
diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c
index bfbd43394..6a064621a 100644
--- a/src/fuzzy_storage.c
+++ b/src/fuzzy_storage.c
@@ -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");
diff --git a/src/kvstorage.h b/src/kvstorage.h
index 6d57def12..05ff866e6 100644
--- a/src/kvstorage.h
+++ b/src/kvstorage.h
@@ -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 */
diff --git a/src/lmtp_proto.c b/src/lmtp_proto.c
index eb92ed7c1..95b8ca13a 100644
--- a/src/lmtp_proto.c
+++ b/src/lmtp_proto.c
@@ -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));
diff --git a/src/lua/lua_http.c b/src/lua/lua_http.c
index 8fc5c3e2c..7bbe07187 100644
--- a/src/lua/lua_http.c
+++ b/src/lua/lua_http.c
@@ -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);
diff --git a/src/lua/lua_upstream.c b/src/lua/lua_upstream.c
index 6780a756a..4668047b3 100644
--- a/src/lua/lua_upstream.c
+++ b/src/lua/lua_upstream.c
@@ -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) {
diff --git a/src/main.c b/src/main.c
index ed72e48bc..86f4c74ed 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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 {
diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c
index 984163858..d16bc94b0 100644
--- a/src/plugins/fuzzy_check.c
+++ b/src/plugins/fuzzy_check.c
@@ -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) {
diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c
index 57bd257c7..1491b1b62 100644
--- a/src/plugins/surbl.c
+++ b/src/plugins/surbl.c
@@ -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) {
diff --git a/src/plugins/surbl.h b/src/plugins/surbl.h
index 950e55bcb..7a2ed58b5 100644
--- a/src/plugins/surbl.h
+++ b/src/plugins/surbl.h
@@ -20,7 +20,7 @@
struct redirector_upstream {
struct upstream up;
- struct in_addr ina;
+ gchar *addr;
guint16 port;
gchar *name;
};
diff --git a/src/smtp_proxy.c b/src/smtp_proxy.c
index 4cf7fae9f..e7856898d 100644
--- a/src/smtp_proxy.c
+++ b/src/smtp_proxy.c
@@ -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));
diff --git a/src/smtp_utils.c b/src/smtp_utils.c
index 4c87b6382..302d7433b 100644
--- a/src/smtp_utils.c
+++ b/src/smtp_utils.c
@@ -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;
}
diff --git a/src/smtp_utils.h b/src/smtp_utils.h
index b32b8235e..b27578804 100644
--- a/src/smtp_utils.h
+++ b/src/smtp_utils.h
@@ -14,7 +14,7 @@ struct smtp_upstream {
struct upstream up;
const gchar *name;
- struct in_addr addr;
+ gchar *addr;
guint16 port;
gboolean is_unix;
};
diff --git a/src/statfile_sync.c b/src/statfile_sync.c
index 0dc7cbdbc..7e3c3be3c 100644
--- a/src/statfile_sync.c
+++ b/src/statfile_sync.c
@@ -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;
diff --git a/src/util.c b/src/util.c
index 8d7bf69ad..4a8f1aa05 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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;
diff --git a/src/util.h b/src/util.h
index 3dfa851bc..6d0bdc098 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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);
/*