diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2012-04-27 20:51:56 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2012-04-27 20:51:56 +0400 |
commit | 8fe7e64dfae9c4da3a6b38769bf5d54d46d50beb (patch) | |
tree | c750b1e0a00803fe329977943275be6c4d433d2a /lib | |
parent | fe5e1614f36236654623667df4f317ae5e5e1806 (diff) | |
download | rspamd-8fe7e64dfae9c4da3a6b38769bf5d54d46d50beb.tar.gz rspamd-8fe7e64dfae9c4da3a6b38769bf5d54d46d50beb.zip |
* Add ability to specify dnsbls for smtp_proxy.
Fix handling of params with the same name in configuration.
Add ability for rspamc to bind on a local address.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/client/librspamdclient.c | 48 | ||||
-rw-r--r-- | lib/client/librspamdclient.h | 7 |
2 files changed, 42 insertions, 13 deletions
diff --git a/lib/client/librspamdclient.c b/lib/client/librspamdclient.c index 6351175bc..dac49b5ae 100644 --- a/lib/client/librspamdclient.c +++ b/lib/client/librspamdclient.c @@ -49,6 +49,7 @@ struct rspamd_client { guint servers_num; guint connect_timeout; guint read_timeout; + struct in_addr *bind_addr; }; struct rspamd_connection { @@ -110,11 +111,12 @@ poll_sync_socket (gint fd, gint timeout, short events) } static gint -make_inet_socket (gint family, struct in_addr *addr, u_short port, gboolean is_server, gboolean async) +lib_make_inet_socket (gint family, struct in_addr *addr, struct in_addr *local_addr, + u_short port, gboolean is_server, gboolean async) { gint fd, r, optlen, on = 1, s_error; gint serrno; - struct sockaddr_in sin; + struct sockaddr_in sin, local; /* Create socket */ fd = socket (AF_INET, family, 0); @@ -140,6 +142,18 @@ make_inet_socket (gint family, struct in_addr *addr, u_short port, gboolean is_s sin.sin_port = htons (port); sin.sin_addr.s_addr = addr->s_addr; + if (!is_server && local_addr != NULL) { + /* Bind to local addr */ + memset (&local, 0, sizeof (struct sockaddr_in)); + memcpy (&local.sin_addr,local_addr, sizeof (struct in_addr)); + local.sin_family = AF_INET; + setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (gint)); + if (bind (fd, (struct sockaddr *)&local, sizeof (local)) == -1) { + msg_warn ("bind/connect failed: %d, '%s'", errno, strerror (errno)); + goto out; + } + } + if (is_server) { setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (gint)); r = bind (fd, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); @@ -188,16 +202,10 @@ make_inet_socket (gint family, struct in_addr *addr, u_short port, gboolean is_s return (-1); } -gint -make_tcp_socket (struct in_addr *addr, u_short port, gboolean is_server, gboolean async) -{ - return make_inet_socket (SOCK_STREAM, addr, port, is_server, async); -} - -gint -make_udp_socket (struct in_addr *addr, u_short port, gboolean is_server, gboolean async) +static gint +lib_make_tcp_socket (struct in_addr *addr, struct in_addr *local_addr, u_short port, gboolean is_server, gboolean async) { - return make_inet_socket (SOCK_DGRAM, addr, port, is_server, async); + return lib_make_inet_socket (SOCK_STREAM, addr, local_addr, port, is_server, async); } /** Private functions **/ @@ -262,7 +270,7 @@ rspamd_connect_random_server (struct rspamd_client *client, gboolean is_control, new->connection_time = now; new->client = client; /* Create socket */ - new->socket = make_tcp_socket (&selected->addr, + new->socket = lib_make_tcp_socket (&selected->addr, client->bind_addr, is_control ? selected->controller_port : selected->client_port, FALSE, TRUE); if (new->socket == -1) { @@ -1228,7 +1236,7 @@ rspamd_read_controller_greeting (struct rspamd_connection *c, GError **err) * Init rspamd client library */ struct rspamd_client* -rspamd_client_init (void) +rspamd_client_init_binded (const struct in_addr *addr) { struct rspamd_client *client; @@ -1236,9 +1244,20 @@ rspamd_client_init (void) client->read_timeout = DEFAULT_READ_TIMEOUT; client->connect_timeout = DEFAULT_CONNECT_TIMEOUT; + if (addr != NULL) { + client->bind_addr = g_malloc (sizeof (struct in_addr)); + memcpy (client->bind_addr, addr, sizeof (struct in_addr)); + } + return client; } +struct rspamd_client* +rspamd_client_init (void) +{ + return rspamd_client_init_binded (NULL); +} + /* * Add rspamd server */ @@ -1969,5 +1988,8 @@ rspamd_free_result (struct rspamd_result *result) void rspamd_client_close (struct rspamd_client *client) { + if (client->bind_addr) { + g_free (client->bind_addr); + } g_free (client); } diff --git a/lib/client/librspamdclient.h b/lib/client/librspamdclient.h index 54695a34d..6eea8627e 100644 --- a/lib/client/librspamdclient.h +++ b/lib/client/librspamdclient.h @@ -28,6 +28,8 @@ struct rspamd_metric { struct rspamd_connection; struct rspamd_client; +struct in_addr; + /** * Result of scan */ @@ -44,6 +46,11 @@ struct rspamd_result { struct rspamd_client* rspamd_client_init (void); /* + * Init rspamd client library and bind it + */ +struct rspamd_client* rspamd_client_init_binded (const struct in_addr *local_addr); + +/* * Add rspamd server */ gboolean rspamd_add_server (struct rspamd_client* client, const gchar *host, |