From 37845898cbf779c7d3b5664997d0db48968c929c Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 1 Jun 2013 15:52:11 +0100 Subject: [PATCH] Rework socket creation logic to support both ipv4 and ipv6 sockets. --- lib/client/librspamdclient.c | 3 +- lib/kvstorage/libkvstorageclient.c | 4 +- src/cfg_file.h | 10 ++--- src/cfg_utils.c | 66 +++++++++++++++++++++--------- src/cfg_xml.c | 4 +- src/dns.c | 24 ++++++----- src/dns.h | 1 - src/fuzzy_storage.c | 3 +- src/kvstorage.h | 2 +- src/lmtp_proto.c | 6 ++- src/lua/lua_http.c | 4 +- src/lua/lua_upstream.c | 10 ++--- src/main.c | 49 ++++------------------ src/plugins/fuzzy_check.c | 52 +++++------------------ src/plugins/surbl.c | 5 ++- src/plugins/surbl.h | 2 +- src/smtp_proxy.c | 9 +--- src/smtp_utils.c | 11 +---- src/smtp_utils.h | 2 +- src/statfile_sync.c | 8 ++-- src/util.c | 16 ++++---- src/util.h | 5 ++- 22 files changed, 127 insertions(+), 169 deletions(-) diff --git a/lib/client/librspamdclient.c b/lib/client/librspamdclient.c index 0b6cd05d3..30410f503 100644 --- a/lib/client/librspamdclient.c +++ b/lib/client/librspamdclient.c @@ -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; } diff --git a/lib/kvstorage/libkvstorageclient.c b/lib/kvstorage/libkvstorageclient.c index 10e9be8a4..e0971f22a 100644 --- a/lib/kvstorage/libkvstorageclient.c +++ b/lib/kvstorage/libkvstorageclient.c @@ -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; } 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, " slave" EOL); rspamd_fprintf (f, " %s:%d" 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, " %T" 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); /* -- 2.39.5