summaryrefslogtreecommitdiffstats
path: root/src/libutil/addr.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/addr.h')
-rw-r--r--src/libutil/addr.h356
1 files changed, 356 insertions, 0 deletions
diff --git a/src/libutil/addr.h b/src/libutil/addr.h
new file mode 100644
index 0000000..25a3641
--- /dev/null
+++ b/src/libutil/addr.h
@@ -0,0 +1,356 @@
+/*-
+ * Copyright 2016 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ADDR_H_
+#define ADDR_H_
+
+#include "config.h"
+#include "rdns.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+/* unix sockets */
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#include "mem_pool.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Opaque structure
+ */
+typedef struct rspamd_inet_addr_s rspamd_inet_addr_t;
+
+/**
+ * Returns pointer storage for global singleton (map for local addresses)
+ * @return
+ */
+void **rspamd_inet_library_init(void);
+/**
+ * Returns local addresses singleton
+ * @return
+ */
+void *rspamd_inet_library_get_lib_ctx(void);
+/**
+ * Cleanup library (currently it does nothing)
+ */
+void rspamd_inet_library_destroy(void);
+
+/**
+ * Create new inet address structure based on the address family and opaque init pointer
+ * @param af
+ * @param init
+ * @return new inet addr
+ */
+rspamd_inet_addr_t *rspamd_inet_address_new(int af, const void *init);
+
+/**
+ * Create new inet address structure from struct sockaddr
+ * @param sa
+ * @param slen
+ * @return
+ */
+rspamd_inet_addr_t *rspamd_inet_address_from_sa(const struct sockaddr *sa,
+ socklen_t slen);
+
+/**
+ * Create new inet address from rdns reply
+ * @param rep reply element
+ * @return new ipv4 or ipv6 addr (port is NOT set)
+ */
+rspamd_inet_addr_t *rspamd_inet_address_from_rnds(
+ const struct rdns_reply_entry *rep);
+
+/**
+ * Parse string with ipv6 address of length `len` to `target` which should be
+ * at least sizeof (struct in6_addr)
+ * @param text input string
+ * @param len length of `text` (if 0, then `text` must be zero terminated)
+ * @param target target structure
+ * @return TRUE if the address has been parsed, otherwise `target` content is undefined
+ */
+gboolean rspamd_parse_inet_address_ip6(const guchar *text, gsize len,
+ gpointer target);
+
+enum rspamd_inet_address_parse_flags {
+ RSPAMD_INET_ADDRESS_PARSE_DEFAULT = 0,
+ RSPAMD_INET_ADDRESS_PARSE_REMOTE = 1u << 0u,
+ RSPAMD_INET_ADDRESS_PARSE_NO_UNIX = 1u << 1u,
+ RSPAMD_INET_ADDRESS_PARSE_NO_PORT = 1u << 2u,
+};
+
+/**
+ * Parse string with ipv4 address of length `len` to `target` which should be
+ * at least sizeof (in4_addr_t)
+ * @param text input string
+ * @param len length of `text` (if 0, then `text` must be zero terminated)
+ * @param target target structure
+ * @return TRUE if the address has been parsed, otherwise `target` content is undefined
+ */
+gboolean rspamd_parse_inet_address_ip4(const guchar *text, gsize len,
+ gpointer target);
+
+/**
+ * Parse ipv4 or ipv6 address to a static buffer `target`. Does not support Unix sockets
+ * @param src
+ * @param srclen
+ * @param target
+ * @return
+ */
+gboolean rspamd_parse_inet_address_ip(const char *src,
+ gsize srclen,
+ rspamd_inet_addr_t *target);
+
+/**
+ * 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,
+ gsize srclen,
+ enum rspamd_inet_address_parse_flags how);
+
+/**
+ * Use memory pool allocated inet address
+ * @param src
+ * @param srclen
+ * @param pool
+ * @return
+ */
+rspamd_inet_addr_t *rspamd_parse_inet_address_pool(const char *src,
+ gsize srclen,
+ rspamd_mempool_t *pool,
+ enum rspamd_inet_address_parse_flags how);
+
+/**
+ * Returns string representation of inet address
+ * @param addr
+ * @return statically allocated string pointer (not thread safe)
+ */
+const char *rspamd_inet_address_to_string(const rspamd_inet_addr_t *addr);
+
+/**
+ * Returns pretty string representation of inet address
+ * @param addr
+ * @return statically allocated string pointer (not thread safe)
+ */
+const char *rspamd_inet_address_to_string_pretty(const 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(const rspamd_inet_addr_t *addr);
+
+/**
+ * Returns address family of inet address
+ * @param addr
+ * @return
+ */
+gint rspamd_inet_address_get_af(const rspamd_inet_addr_t *addr);
+
+/**
+ * Returns sockaddr and size for this address
+ * @param addr
+ * @param sz
+ * @return
+ */
+struct sockaddr *rspamd_inet_address_get_sa(const rspamd_inet_addr_t *addr,
+ socklen_t *sz);
+
+/**
+ * Makes a radix key from inet address
+ * @param addr
+ * @param klen
+ * @return
+ */
+guchar *rspamd_inet_address_get_hash_key(const rspamd_inet_addr_t *addr, guint *klen);
+
+/**
+ * Receive data from an unconnected socket and fill the inet_addr structure if needed
+ * @param fd
+ * @param buf
+ * @param len
+ * @param target
+ * @return same as recvfrom(2)
+ */
+gssize rspamd_inet_address_recvfrom(gint fd, void *buf, gsize len, gint fl,
+ rspamd_inet_addr_t **target);
+
+/**
+ * Send data via unconnected socket using the specified inet_addr structure
+ * @param fd
+ * @param buf
+ * @param len
+ * @param target
+ * @return
+ */
+gssize rspamd_inet_address_sendto(gint fd, const void *buf, gsize len, gint fl,
+ const 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(const rspamd_inet_addr_t *addr, gint type,
+ gboolean async);
+
+enum rspamd_inet_address_listen_opts {
+ RSPAMD_INET_ADDRESS_LISTEN_DEFAULT = 0,
+ RSPAMD_INET_ADDRESS_LISTEN_ASYNC = (1u << 0u),
+ RSPAMD_INET_ADDRESS_LISTEN_REUSEPORT = (1u << 1u),
+ RSPAMD_INET_ADDRESS_LISTEN_NOLISTEN = (1u << 2u),
+};
+/**
+ * Listen on a specified inet address
+ * @param addr
+ * @param type
+ * @param opts
+ * @return
+ */
+int rspamd_inet_address_listen(const rspamd_inet_addr_t *addr, gint type,
+ enum rspamd_inet_address_listen_opts opts,
+ gint listen_queue);
+
+/**
+ * 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(const rspamd_inet_addr_t *addr);
+
+typedef void (*rspamd_accept_throttling_handler)(gint, void *);
+
+/**
+ * Accept from listening socket filling addr structure
+ * @param sock listening socket
+ * @param target allocated inet addr structure
+ * @return
+ */
+gint rspamd_accept_from_socket(gint sock,
+ rspamd_inet_addr_t **target,
+ rspamd_accept_throttling_handler hdl,
+ void *hdl_data);
+
+enum rspamd_parse_host_port_result {
+ RSPAMD_PARSE_ADDR_FAIL = 0,
+ RSPAMD_PARSE_ADDR_RESOLVED = 1,
+ RSPAMD_PARSE_ADDR_NUMERIC = 2,
+};
+/**
+ * Parse host[:port[:priority]] line
+ * @param ina host address
+ * @param port port
+ * @param priority priority
+ * @return RSPAMD_PARSE_ADDR_FAIL in case of error, RSPAMD_PARSE_ADDR_NUMERIC in case of pure ip/unix socket
+ */
+enum rspamd_parse_host_port_result
+rspamd_parse_host_port_priority(const gchar *str,
+ GPtrArray **addrs,
+ guint *priority, gchar **name,
+ guint default_port,
+ gboolean allow_listen,
+ rspamd_mempool_t *pool);
+
+/**
+ * Destroy the specified IP address
+ * @param addr
+ */
+void rspamd_inet_address_free(rspamd_inet_addr_t *addr);
+
+/**
+ * Apply the specified mask to an address (ignored for AF_UNIX)
+ * @param addr
+ * @param mask
+ */
+void rspamd_inet_address_apply_mask(rspamd_inet_addr_t *addr, guint mask);
+
+/**
+ * Compare a1 and a2 and return value >0, ==0 and <0 if a1 is more, equal or less than a2 correspondingly
+ * @param a1
+ * @param a2
+ * @return
+ */
+gint rspamd_inet_address_compare(const rspamd_inet_addr_t *a1,
+ const rspamd_inet_addr_t *a2, gboolean compare_ports);
+
+/**
+ * Utility function to compare addresses by in g_ptr_array
+ * @param a1
+ * @param a2
+ * @return
+ */
+gint rspamd_inet_address_compare_ptr(gconstpointer a1,
+ gconstpointer a2);
+
+/**
+ * Performs deep copy of rspamd inet addr
+ * @param addr
+ * @return
+ */
+rspamd_inet_addr_t *rspamd_inet_address_copy(const rspamd_inet_addr_t *addr, rspamd_mempool_t *pool);
+
+/**
+ * Returns hash for inet address (ignoring port)
+ */
+guint rspamd_inet_address_hash(gconstpointer a);
+
+guint rspamd_inet_address_port_hash(gconstpointer a);
+
+/**
+ * Returns true if two address are equal
+ */
+gboolean rspamd_inet_address_equal(gconstpointer a, gconstpointer b);
+
+gboolean rspamd_inet_address_port_equal(gconstpointer a, gconstpointer b);
+
+/**
+ * Returns TRUE if an address belongs to some local address
+ */
+gboolean rspamd_inet_address_is_local(const rspamd_inet_addr_t *addr);
+
+/**
+ * Returns size of storage required to store a complete IP address
+ * @return
+ */
+gsize rspamd_inet_address_storage_size(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ADDR_H_ */