]> source.dussan.org Git - rspamd.git/commitdiff
Rework socket creation logic to support both ipv4 and ipv6 sockets.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 1 Jun 2013 14:52:11 +0000 (15:52 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 1 Jun 2013 14:52:11 +0000 (15:52 +0100)
22 files changed:
lib/client/librspamdclient.c
lib/kvstorage/libkvstorageclient.c
src/cfg_file.h
src/cfg_utils.c
src/cfg_xml.c
src/dns.c
src/dns.h
src/fuzzy_storage.c
src/kvstorage.h
src/lmtp_proto.c
src/lua/lua_http.c
src/lua/lua_upstream.c
src/main.c
src/plugins/fuzzy_check.c
src/plugins/surbl.c
src/plugins/surbl.h
src/smtp_proxy.c
src/smtp_utils.c
src/smtp_utils.h
src/statfile_sync.c
src/util.c
src/util.h

index 0b6cd05d3d2374f03775adf130ae88d34855519b..30410f5039e1f4213ac1dcd627dc956c328138de 100644 (file)
@@ -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;
        }
index 10e9be8a469309db55ee521dc93017eb5acfa5d0..e0971f22a5553501e8c09556f2736614e911885d 100644 (file)
@@ -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;
        }
 
index bb638888da22fc1dbae5f02203a9b0c040cc3977..3b7059786fb9a9b95303bed8aba909a1f2b422b4 100644 (file)
@@ -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
index 4acfead35271a750c0aed5130dc2482969205790..78530218d6cce5fba6755b57861f5c9e3229f1a2 100644 (file)
 
 
 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;
 
index 3d58d128e2103342f1555cb2cad9b6952cd47ab8..a325b3b7a2a98123231a0ea9b215fd035b292946 100644 (file)
@@ -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);
                        }
index 1d4f48b355e52e3e6018524f49ecfac3f44ef262..99e0d7c584d844ef30f6894dad28b514b7972f19 100644 (file)
--- 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);
                }
index 8914ae5b1d30504ab273d7cb969cf21ab2028762..b04aa285f33c3a8727a648e54c89c060dd25c229 100644 (file)
--- 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;
index bfbd43394212a620ceb3412fdc070a1377b5d775..6a064621a2b2efe47942e143a1d4bb9ad58117b7 100644 (file)
@@ -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");
index 6d57def12328b6e2b669e0f3c921df59225ab4ff..05ff866e6a5a2a79722fcf179b3629692752e8b9 100644 (file)
@@ -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 */
index eb92ed7c198cb7305dc920b4f03cc9f60a507dbb..95b8ca13a1e0ef9e78b5718d945d5408c20a82f4 100644 (file)
@@ -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));
index 8fc5c3e2c353d44699cdb6cbb6d5fd3eba7c21c2..7bbe0718739639ec2eb37cc3298ac87c0966c324 100644 (file)
@@ -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);
index 6780a756ab71c7e67829185050689272087fc688..4668047b35c5582c67a75bfb8440999ffdbda36e 100644 (file)
@@ -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) {
index ed72e48bce9e767c6c3a43cd75eb480085430fbb..86f4c74ed0d2950b7f67b7123f9b5154e8311bcf 100644 (file)
@@ -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 {
index 9841638584b2f510ef425d8fab0291403f298f63..d16bc94b07748a52bfa1ddc71dfa2c9fd4f834de 100644 (file)
@@ -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) {
index 57bd257c78ad475a5be593bded3cb1ad55c195f0..1491b1b62fca4f04fcef236dd0598118dec80767 100644 (file)
@@ -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) {
index 950e55bcb8a3315136e28b5e3ea162312e120705..7a2ed58b553f42495c3a0fefd77d695d617026c9 100644 (file)
@@ -20,7 +20,7 @@
 
 struct redirector_upstream {
        struct upstream up;
-       struct in_addr ina;
+       gchar *addr;
        guint16 port;
        gchar *name;
 };
index 4cf7fae9fc93a8fac45dc71f8d07a5afd7dd2e16..e7856898d1f42383f59daf6bd213046139747a57 100644 (file)
@@ -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));
index 4c87b63826a85138f65cdd23fe0b96e49c7034f4..302d7433b1c406183a534db37d25403332f67f4e 100644 (file)
@@ -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;
                        }
index b32b8235e08c8ea9ab0c8b63f6a69bd7ff88690e..b275788042ee5e65730dc5f8e41b3ced02265f8c 100644 (file)
@@ -14,7 +14,7 @@ struct smtp_upstream {
        struct upstream up;
 
        const gchar *name;
-       struct in_addr addr;
+       gchar *addr;
        guint16 port;
        gboolean is_unix;
 };
index 0dc7cbdbcaba539a84c4a2fef5ddaa71ba97d83e..7e3c3be3ceb19e2fd744f62c3a8bed69901b112e 100644 (file)
@@ -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;
index 8d7bf69adc548da56d6e4084a97f1a347d6aa610..4a8f1aa056d956025ddaff4766814f8892521b26 100644 (file)
@@ -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;
index 3dfa851bc6b30625fef7443a4fbb9322f9a31c7d..6d0bdc0989e9e02db5d149637f6bdc900122f75b 100644 (file)
@@ -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);
 
 /*