aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2012-04-27 20:51:56 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2012-04-27 20:51:56 +0400
commit8fe7e64dfae9c4da3a6b38769bf5d54d46d50beb (patch)
treec750b1e0a00803fe329977943275be6c4d433d2a /lib
parentfe5e1614f36236654623667df4f317ae5e5e1806 (diff)
downloadrspamd-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.c48
-rw-r--r--lib/client/librspamdclient.h7
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,