diff options
| author | 2020-11-19 19:43:31 -0500 | |
|---|---|---|
| committer | 2020-11-19 19:43:31 -0500 | |
| commit | 6a0204e95aa5358ef2bf7714559ccd366dba4617 (patch) | |
| tree | 18e4e77b04125f3da8c6b97903d043afe3b5826d /src/libopm | |
| parent | de54987ff29489950322f3408ea91651f4f48b4a (diff) | |
New upstream version 1.1.9.upstream/1.1.9
Diffstat (limited to 'src/libopm')
| -rw-r--r-- | src/libopm/src/config.c | 33 | ||||
| -rw-r--r-- | src/libopm/src/libopm.c | 66 | ||||
| -rw-r--r-- | src/libopm/src/libopm.h | 3 |
3 files changed, 75 insertions, 27 deletions
diff --git a/src/libopm/src/config.c b/src/libopm/src/config.c index dfc4c48..f2d8279 100644 --- a/src/libopm/src/config.c +++ b/src/libopm/src/config.c @@ -24,8 +24,10 @@ #include "setup.h" #include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <sys/socket.h> +#include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -62,7 +64,7 @@ static const OPM_CONFIG_HASH_T HASH[] = OPM_CONFIG_T * libopm_config_create(void) { - const unsigned int num = sizeof(HASH) / sizeof(OPM_CONFIG_HASH_T); + const unsigned int num = sizeof(HASH) / sizeof(HASH[0]); OPM_CONFIG_T *ret; ret = libopm_calloc(sizeof(OPM_CONFIG_T)); @@ -91,7 +93,7 @@ libopm_config_create(void) break; case OPM_TYPE_ADDRESS: - ret->vars[i] = libopm_calloc(sizeof(struct sockaddr_in)); + ret->vars[i] = libopm_calloc(sizeof(struct sockaddr_storage)); break; case OPM_TYPE_STRINGLIST: @@ -119,7 +121,7 @@ libopm_config_create(void) void libopm_config_free(OPM_CONFIG_T *config) { - const unsigned int num = sizeof(HASH) / sizeof(OPM_CONFIG_HASH_T); + const unsigned int num = sizeof(HASH) / sizeof(HASH[0]); OPM_NODE_T *p, *next; OPM_LIST_T *list; @@ -168,7 +170,7 @@ libopm_config_free(OPM_CONFIG_T *config) OPM_ERR_T libopm_config_set(OPM_CONFIG_T *config, unsigned int key, const void *value) { - const unsigned int num = sizeof(HASH) / sizeof(OPM_CONFIG_HASH_T); + const unsigned int num = sizeof(HASH) / sizeof(HASH[0]); OPM_NODE_T *node; if (key >= num) @@ -188,10 +190,29 @@ libopm_config_set(OPM_CONFIG_T *config, unsigned int key, const void *value) break; case OPM_TYPE_ADDRESS: - if (inet_pton(AF_INET, value, &(((struct sockaddr_in *)config->vars[key])->sin_addr)) <= 0) + { + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICHOST; + + if (getaddrinfo(value, NULL, &hints, &res) || res->ai_family != AF_INET) /* XXX: v4 only for now */ + { + if (res) + freeaddrinfo(res); + return OPM_ERR_BADVALUE; /* Return appropriate err code */ + } + + struct sockaddr_storage *const addr = config->vars[key]; + memcpy(addr, res->ai_addr, res->ai_addrlen); + addr->ss_family = res->ai_family; + freeaddrinfo(res); break; + } case OPM_TYPE_STRINGLIST: node = libopm_node_create(libopm_strdup(value)); @@ -218,7 +239,7 @@ libopm_config_set(OPM_CONFIG_T *config, unsigned int key, const void *value) int libopm_config_gettype(int key) { - const unsigned int num = sizeof(HASH) / sizeof(OPM_CONFIG_HASH_T); + const unsigned int num = sizeof(HASH) / sizeof(HASH[0]); for (unsigned int i = 0; i < num; ++i) if (HASH[i].key == key) diff --git a/src/libopm/src/libopm.c b/src/libopm/src/libopm.c index 89b376f..d6118ff 100644 --- a/src/libopm/src/libopm.c +++ b/src/libopm/src/libopm.c @@ -29,10 +29,14 @@ #include <fcntl.h> #include <string.h> #include <stdlib.h> +#include <assert.h> #include <poll.h> #ifdef HAVE_LIBCRYPTO #include <openssl/ssl.h> #endif +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> #include "config.h" #include "libopm.h" @@ -392,24 +396,39 @@ libopm_protocol_config_free(OPM_PROTOCOL_CONFIG_T *protocol) OPM_ERR_T opm_scan(OPM_T *scanner, OPM_REMOTE_T *remote) { - OPM_SCAN_T *scan; /* New scan for OPM_T */ OPM_NODE_T *node; /* Node we'll add scan to when we link it to scans */ - struct in_addr in; + struct addrinfo hints, *res; if (LIST_SIZE(&scanner->protocols) == 0 && LIST_SIZE(&remote->protocols) == 0) return OPM_ERR_NOPROTOCOLS; + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICHOST; + /* * XXX: libopm ideally shouldn't see an IP address in string representation. * Could have been stuffed into the _OPM_REMOTE struct by the caller that * already does getaddrinfo() anyway. */ - if (inet_pton(AF_INET, remote->ip, &in) <= 0) + if (getaddrinfo(remote->ip, NULL, &hints, &res) || res->ai_family != AF_INET) /* XXX: only do v4 for now */ + { + if (res) + freeaddrinfo(res); + return OPM_ERR_BADADDR; + } + + OPM_SCAN_T *scan = libopm_scan_create(scanner, remote); - scan = libopm_scan_create(scanner, remote); - memcpy(&scan->addr.sin_addr, &in, sizeof(scan->addr.sin_addr)); + memcpy(&scan->addr, res->ai_addr, res->ai_addrlen); + scan->addr.ss_family = res->ai_family; + scan->addr_len = res->ai_addrlen; + + freeaddrinfo(res); node = libopm_node_create(scan); libopm_list_add(&scanner->queue, node); @@ -891,19 +910,16 @@ libopm_check_closed(OPM_T *scanner) static void libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) { - struct sockaddr_in *bind_ip; - struct sockaddr_in *addr; /* Outgoing host */ - struct sockaddr_in local_addr; /* For binding */ - - addr = &scan->addr; /* Already have the IP in byte format from opm_scan */ - addr->sin_family = AF_INET; - addr->sin_port = htons(conn->port); + assert(scan->addr.ss_family == AF_INET); - bind_ip = (struct sockaddr_in *)libopm_config(scanner->config, OPM_CONFIG_BIND_IP); + if (scan->addr.ss_family == AF_INET6) + ((struct sockaddr_in6 *)&scan->addr)->sin6_port = htons(conn->port); + else + ((struct sockaddr_in *)&scan->addr)->sin_port = htons(conn->port); - conn->fd = socket(AF_INET, SOCK_STREAM, 0); scanner->fd_use++; /* Increase file descriptor use */ + conn->fd = socket(scan->addr.ss_family, SOCK_STREAM, 0); if (conn->fd == -1) { libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_NOFD); @@ -911,15 +927,25 @@ libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) return; } + struct sockaddr_storage *bind_ip = libopm_config(scanner->config, OPM_CONFIG_BIND_IP); if (bind_ip) { - memset(&local_addr, 0, sizeof(local_addr)); + size_t addr_len; - local_addr.sin_addr.s_addr = bind_ip->sin_addr.s_addr; - local_addr.sin_family = AF_INET; - local_addr.sin_port = htons(0); + if (bind_ip->ss_family == AF_INET6) + { + struct sockaddr_in6 *in = (struct sockaddr_in6 *)bind_ip; + in->sin6_port = htons(0); + addr_len = sizeof(*in); + } + else + { + struct sockaddr_in *in = (struct sockaddr_in *)bind_ip; + in->sin_port = htons(0); + addr_len = sizeof(*in); + } - if (bind(conn->fd, (struct sockaddr *)&local_addr, sizeof(local_addr)) == -1) + if (bind(conn->fd, (const struct sockaddr *)bind_ip, addr_len) == -1) { libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_BIND); conn->state = OPM_STATE_CLOSED; @@ -930,7 +956,7 @@ libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) /* Set socket non blocking */ fcntl(conn->fd, F_SETFL, O_NONBLOCK); - connect(conn->fd, (struct sockaddr *)addr, sizeof(*addr)); + connect(conn->fd, (const struct sockaddr *)&scan->addr, scan->addr_len); #ifdef HAVE_LIBCRYPTO if (conn->protocol->use_tls) diff --git a/src/libopm/src/libopm.h b/src/libopm/src/libopm.h index ca03512..1e0a9cb 100644 --- a/src/libopm/src/libopm.h +++ b/src/libopm/src/libopm.h @@ -29,7 +29,8 @@ typedef int OPM_PROXYREAD_T (OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); struct _OPM_SCAN { - struct sockaddr_in addr; /* Address in byte order of remote client */ + struct sockaddr_storage addr; /* Address in byte order of remote client */ + size_t addr_len; OPM_REMOTE_T *remote; /* Pointed to the OPM_REMOTE_T for this scan, passed by client */ OPM_LIST_T connections; /* List of individual connections of this scan (1 for each protocol) */ }; |
