aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2014-10-28 13:36:15 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2014-10-28 13:36:15 +0000
commitb4ce748572e3097982b951fac69c0e65db8b4118 (patch)
tree3e372ff1f7e9d2ef5e4b7a33e12e34b31e95f1a5
parentd95807104076189411987dcc733a23a94b8812a5 (diff)
downloadrspamd-b4ce748572e3097982b951fac69c0e65db8b4118.tar.gz
rspamd-b4ce748572e3097982b951fac69c0e65db8b4118.zip
Split addr definition from the utils code.
-rw-r--r--src/libutil/CMakeLists.txt4
-rw-r--r--src/libutil/addr.c184
-rw-r--r--src/libutil/addr.h98
-rw-r--r--src/libutil/util.c159
-rw-r--r--src/libutil/util.h79
5 files changed, 295 insertions, 229 deletions
diff --git a/src/libutil/CMakeLists.txt b/src/libutil/CMakeLists.txt
index 7a8b3add5..01c88769b 100644
--- a/src/libutil/CMakeLists.txt
+++ b/src/libutil/CMakeLists.txt
@@ -1,5 +1,7 @@
# Librspamd-util
-SET(LIBRSPAMDUTILSRC aio_event.c
+SET(LIBRSPAMDUTILSRC
+ addr.c
+ aio_event.c
bloom.c
diff.c
fstring.c
diff --git a/src/libutil/addr.c b/src/libutil/addr.c
new file mode 100644
index 000000000..a06dc2662
--- /dev/null
+++ b/src/libutil/addr.c
@@ -0,0 +1,184 @@
+/* Copyright (c) 2014, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "addr.h"
+#include "util.h"
+#include "logger.h"
+
+gboolean
+rspamd_ip_is_valid (rspamd_inet_addr_t *addr)
+{
+ const struct in_addr ip4_any = { INADDR_ANY }, ip4_none = { INADDR_NONE };
+ const struct in6_addr ip6_any = IN6ADDR_ANY_INIT;
+
+ gboolean ret = FALSE;
+
+ if (G_LIKELY (addr->af == AF_INET)) {
+ if (memcmp (&addr->addr.s4.sin_addr, &ip4_any,
+ sizeof (struct in_addr)) != 0 &&
+ memcmp (&addr->addr.s4.sin_addr, &ip4_none,
+ sizeof (struct in_addr)) != 0) {
+ ret = TRUE;
+ }
+ }
+ else if (G_UNLIKELY (addr->af == AF_INET6)) {
+ if (memcmp (&addr->addr.s6.sin6_addr, &ip6_any,
+ sizeof (struct in6_addr)) != 0) {
+ ret = TRUE;
+ }
+ }
+
+ return ret;
+}
+
+gint
+rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t *addr)
+{
+ gint nfd, serrno;
+ socklen_t len = sizeof (addr->addr.ss);
+
+ if ((nfd = accept (sock, &addr->addr.sa, &len)) == -1) {
+ if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
+ return 0;
+ }
+ return -1;
+ }
+
+ addr->slen = len;
+ addr->af = addr->addr.sa.sa_family;
+
+ if (make_socket_nonblocking (nfd) < 0) {
+ goto out;
+ }
+
+ /* Set close on exec */
+ if (fcntl (nfd, F_SETFD, FD_CLOEXEC) == -1) {
+ msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno));
+ goto out;
+ }
+
+ return (nfd);
+
+out:
+ serrno = errno;
+ close (nfd);
+ errno = serrno;
+ return (-1);
+
+}
+
+gboolean
+rspamd_parse_inet_address (rspamd_inet_addr_t *target, const char *src)
+{
+ gboolean ret = FALSE;
+
+ if (inet_pton (AF_INET6, src, &target->addr.s6.sin6_addr) == 1) {
+ target->af = AF_INET6;
+ target->slen = sizeof (target->addr.s6);
+ ret = TRUE;
+ }
+ else if (inet_pton (AF_INET, src, &target->addr.s4.sin_addr) == 1) {
+ target->af = AF_INET;
+ target->slen = sizeof (target->addr.s4);
+ ret = TRUE;
+ }
+
+ target->addr.sa.sa_family = target->af;
+
+ return ret;
+}
+
+const char *
+rspamd_inet_address_to_string (rspamd_inet_addr_t *addr)
+{
+ static char addr_str[INET6_ADDRSTRLEN + 1];
+
+ switch (addr->af) {
+ case AF_INET:
+ return inet_ntop (addr->af, &addr->addr.s4.sin_addr, addr_str,
+ sizeof (addr_str));
+ case AF_INET6:
+ return inet_ntop (addr->af, &addr->addr.s6.sin6_addr, addr_str,
+ sizeof (addr_str));
+ case AF_UNIX:
+ return addr->addr.su.sun_path;
+ }
+
+ return "undefined";
+}
+
+uint16_t
+rspamd_inet_address_get_port (rspamd_inet_addr_t *addr)
+{
+ switch (addr->af) {
+ case AF_INET:
+ return ntohs (addr->addr.s4.sin_port);
+ case AF_INET6:
+ return ntohs (addr->addr.s6.sin6_port);
+ }
+
+ return 0;
+}
+
+void
+rspamd_inet_address_set_port (rspamd_inet_addr_t *addr, uint16_t port)
+{
+ switch (addr->af) {
+ case AF_INET:
+ addr->addr.s4.sin_port = htons (port);
+ break;
+ case AF_INET6:
+ addr->addr.s6.sin6_port = htons (port);
+ break;
+ }
+}
+
+int
+rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type,
+ gboolean async)
+{
+ int fd, r;
+
+ if (addr == NULL) {
+ return -1;
+ }
+
+ fd = rspamd_socket_create (addr->af, type, 0, async);
+ if (fd == -1) {
+ return -1;
+ }
+
+ r = connect (fd, &addr->addr.sa, addr->slen);
+
+ if (r == -1) {
+ if (!async || errno != EINPROGRESS) {
+ close (fd);
+ msg_warn ("connect failed: %d, '%s'", errno,
+ strerror (errno));
+ return -1;
+ }
+ }
+
+ return fd;
+}
diff --git a/src/libutil/addr.h b/src/libutil/addr.h
new file mode 100644
index 000000000..049cc88c3
--- /dev/null
+++ b/src/libutil/addr.h
@@ -0,0 +1,98 @@
+/* Copyright (c) 2014, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef ADDR_H_
+#define ADDR_H_
+
+#include "config.h"
+
+/**
+ * Union that is used for storing sockaddrs
+ */
+union sa_union {
+ struct sockaddr_storage ss;
+ struct sockaddr sa;
+ struct sockaddr_in s4;
+ struct sockaddr_in6 s6;
+ struct sockaddr_un su;
+};
+
+typedef struct _rspamd_inet_addr_s {
+ union sa_union addr;
+ socklen_t slen;
+ int af;
+} rspamd_inet_addr_t;
+
+/**
+ * Try to parse address from string
+ * @param target target to fill
+ * @param src IP string representation
+ * @return TRUE if addr has been parsed
+ */
+gboolean rspamd_parse_inet_address (rspamd_inet_addr_t *target,
+ const char *src);
+
+/**
+ * Returns string representation of inet address
+ * @param addr
+ * @return statically allocated string pointer (not thread safe)
+ */
+const char * rspamd_inet_address_to_string (rspamd_inet_addr_t *addr);
+
+/**
+ * Returns port number for the specified inet address in host byte order
+ * @param addr
+ * @return
+ */
+uint16_t rspamd_inet_address_get_port (rspamd_inet_addr_t *addr);
+
+/**
+ * Set port for inet address
+ */
+void rspamd_inet_address_set_port (rspamd_inet_addr_t *addr, uint16_t port);
+
+/**
+ * Connect to inet_addr address
+ * @param addr
+ * @param async perform operations asynchronously
+ * @return newly created and connected socket
+ */
+int rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type,
+ gboolean async);
+
+/**
+ * Check whether specified ip is valid (not INADDR_ANY or INADDR_NONE) for ipv4 or ipv6
+ * @param ptr pointer to struct in_addr or struct in6_addr
+ * @param af address family (AF_INET or AF_INET6)
+ * @return TRUE if the address is valid
+ */
+gboolean rspamd_ip_is_valid (rspamd_inet_addr_t *addr);
+
+/**
+ * Accept from listening socket filling addr structure
+ * @param sock listening socket
+ * @param addr
+ * @return
+ */
+gint rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t *addr);
+
+#endif /* ADDR_H_ */
diff --git a/src/libutil/util.c b/src/libutil/util.c
index 73ab64453..ec125704f 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -98,7 +98,7 @@ poll_sync_socket (gint fd, gint timeout, short events)
return r;
}
-static gint
+gint
rspamd_socket_create (gint af, gint type, gint protocol, gboolean async)
{
gint fd;
@@ -1973,32 +1973,6 @@ restart:
#endif
}
-gboolean
-rspamd_ip_is_valid (rspamd_inet_addr_t *addr)
-{
- const struct in_addr ip4_any = { INADDR_ANY }, ip4_none = { INADDR_NONE };
- const struct in6_addr ip6_any = IN6ADDR_ANY_INIT;
-
- gboolean ret = FALSE;
-
- if (G_LIKELY (addr->af == AF_INET)) {
- if (memcmp (&addr->addr.s4.sin_addr, &ip4_any,
- sizeof (struct in_addr)) != 0 &&
- memcmp (&addr->addr.s4.sin_addr, &ip4_none,
- sizeof (struct in_addr)) != 0) {
- ret = TRUE;
- }
- }
- else if (G_UNLIKELY (addr->af == AF_INET6)) {
- if (memcmp (&addr->addr.s6.sin6_addr, &ip6_any,
- sizeof (struct in6_addr)) != 0) {
- ret = TRUE;
- }
- }
-
- return ret;
-}
-
/*
* GString ucl emitting functions
*/
@@ -2079,137 +2053,6 @@ rspamd_ucl_emit_gstring (ucl_object_t *obj,
ucl_object_emit_full (obj, emit_type, &func);
}
-gint
-rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t *addr)
-{
- gint nfd, serrno;
- socklen_t len = sizeof (addr->addr.ss);
-
- if ((nfd = accept (sock, &addr->addr.sa, &len)) == -1) {
- if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
- return 0;
- }
- return -1;
- }
-
- addr->slen = len;
- addr->af = addr->addr.sa.sa_family;
-
- if (make_socket_nonblocking (nfd) < 0) {
- goto out;
- }
-
- /* Set close on exec */
- if (fcntl (nfd, F_SETFD, FD_CLOEXEC) == -1) {
- msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno));
- goto out;
- }
-
- return (nfd);
-
-out:
- serrno = errno;
- close (nfd);
- errno = serrno;
- return (-1);
-
-}
-
-gboolean
-rspamd_parse_inet_address (rspamd_inet_addr_t *target, const char *src)
-{
- gboolean ret = FALSE;
-
- if (inet_pton (AF_INET6, src, &target->addr.s6.sin6_addr) == 1) {
- target->af = AF_INET6;
- target->slen = sizeof (target->addr.s6);
- ret = TRUE;
- }
- else if (inet_pton (AF_INET, src, &target->addr.s4.sin_addr) == 1) {
- target->af = AF_INET;
- target->slen = sizeof (target->addr.s4);
- ret = TRUE;
- }
-
- target->addr.sa.sa_family = target->af;
-
- return ret;
-}
-
-const char *
-rspamd_inet_address_to_string (rspamd_inet_addr_t *addr)
-{
- static char addr_str[INET6_ADDRSTRLEN + 1];
-
- switch (addr->af) {
- case AF_INET:
- return inet_ntop (addr->af, &addr->addr.s4.sin_addr, addr_str,
- sizeof (addr_str));
- case AF_INET6:
- return inet_ntop (addr->af, &addr->addr.s6.sin6_addr, addr_str,
- sizeof (addr_str));
- case AF_UNIX:
- return addr->addr.su.sun_path;
- }
-
- return "undefined";
-}
-
-uint16_t
-rspamd_inet_address_get_port (rspamd_inet_addr_t *addr)
-{
- switch (addr->af) {
- case AF_INET:
- return ntohs (addr->addr.s4.sin_port);
- case AF_INET6:
- return ntohs (addr->addr.s6.sin6_port);
- }
-
- return 0;
-}
-
-void
-rspamd_inet_address_set_port (rspamd_inet_addr_t *addr, uint16_t port)
-{
- switch (addr->af) {
- case AF_INET:
- addr->addr.s4.sin_port = htons (port);
- break;
- case AF_INET6:
- addr->addr.s6.sin6_port = htons (port);
- break;
- }
-}
-
-int
-rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type,
- gboolean async)
-{
- int fd, r;
-
- if (addr == NULL) {
- return -1;
- }
-
- fd = rspamd_socket_create (addr->af, type, 0, async);
- if (fd == -1) {
- return -1;
- }
-
- r = connect (fd, &addr->addr.sa, addr->slen);
-
- if (r == -1) {
- if (!async || errno != EINPROGRESS) {
- close (fd);
- msg_warn ("connect failed: %d, '%s'", errno,
- strerror (errno));
- return -1;
- }
- }
-
- return fd;
-}
-
/*
* We use here z-base32 encoding described here:
* http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
diff --git a/src/libutil/util.h b/src/libutil/util.h
index 40d8004e3..ed4e6fcca 100644
--- a/src/libutil/util.h
+++ b/src/libutil/util.h
@@ -7,6 +7,7 @@
#include "printf.h"
#include "fstring.h"
#include "ucl.h"
+#include "addr.h"
struct rspamd_config;
struct rspamd_main;
@@ -15,23 +16,14 @@ struct rspamd_statfile_config;
struct rspamd_classifier_config;
/**
- * Union that is used for storing sockaddrs
- */
-union sa_union {
- struct sockaddr_storage ss;
- struct sockaddr sa;
- struct sockaddr_in s4;
- struct sockaddr_in6 s6;
- struct sockaddr_un su;
-};
-
-typedef struct _rspamd_inet_addr_s {
- union sa_union addr;
- socklen_t slen;
- int af;
-} rspamd_inet_addr_t;
-
-
+ * Create generic socket
+ * @param af address family
+ * @param type socket type
+ * @param protocol socket protocol
+ * @param async set non-blocking on a socket
+ * @return socket FD or -1 in case of error
+ */
+gint rspamd_socket_create (gint af, gint type, gint protocol, gboolean async);
/*
* Create socket and bind or connect it to specified address and port
*/
@@ -418,14 +410,6 @@ gpointer rspamd_str_pool_copy (gconstpointer data, gpointer ud);
gint rspamd_read_passphrase (gchar *buf, gint size, gint rwflag, gpointer key);
/**
- * Check whether specified ip is valid (not INADDR_ANY or INADDR_NONE) for ipv4 or ipv6
- * @param ptr pointer to struct in_addr or struct in6_addr
- * @param af address family (AF_INET or AF_INET6)
- * @return TRUE if the address is valid
- */
-gboolean rspamd_ip_is_valid (rspamd_inet_addr_t *addr);
-
-/**
* Emit UCL object to gstring
* @param obj object to emit
* @param emit_type emitter type
@@ -436,51 +420,6 @@ void rspamd_ucl_emit_gstring (ucl_object_t *obj,
GString *target);
/**
- * Accept from listening socket filling addr structure
- * @param sock listening socket
- * @param addr
- * @return
- */
-gint rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t *addr);
-
-/**
- * Try to parse address from string
- * @param target target to fill
- * @param src IP string representation
- * @return TRUE if addr has been parsed
- */
-gboolean rspamd_parse_inet_address (rspamd_inet_addr_t *target,
- const char *src);
-
-/**
- * Returns string representation of inet address
- * @param addr
- * @return statically allocated string pointer (not thread safe)
- */
-const char * rspamd_inet_address_to_string (rspamd_inet_addr_t *addr);
-
-/**
- * Returns port number for the specified inet address in host byte order
- * @param addr
- * @return
- */
-uint16_t rspamd_inet_address_get_port (rspamd_inet_addr_t *addr);
-
-/**
- * Set port for inet address
- */
-void rspamd_inet_address_set_port (rspamd_inet_addr_t *addr, uint16_t port);
-
-/**
- * Connect to inet_addr address
- * @param addr
- * @param async perform operations asynchronously
- * @return newly created and connected socket
- */
-int rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type,
- gboolean async);
-
-/**
* Encode string using base32 encoding
* @param in input
* @param inlen input length