]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/utils kr_straddr_split(): tweak meaning, use more
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 25 Jan 2019 19:20:22 +0000 (20:20 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 11 Feb 2019 15:29:49 +0000 (16:29 +0100)
Now we don't rewrite the port-splitters in command line by zero bytes.
That was confusing the output of some SW showing the command-line
of running kresd.

NEWS
daemon/bindings/net.c
daemon/main.c
lib/utils.c
lib/utils.h

diff --git a/NEWS b/NEWS
index 9af226c360b4b3545e54696b6b522a830cdceed1..2dd52d63dc2ad491522d363a1d3469d06d0f4942 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@ Improvements
 - policy module: policy.rpz() will watch the file for changes by default
 - packaging: lua cqueues added to default dependencies where available
 
+Module API changes
+------------------
+- kr_straddr_split() changed API a bit (compiler will catch that)
+
 
 Knot Resolver 3.2.1 (2019-01-10)
 ================================
index 82b3beb99237a3003836e8c657274893a5696adc..a5622f0268b04e341c3257767f72cab5b8018741 100644 (file)
@@ -373,17 +373,14 @@ static int net_tls_client(lua_State *L)
                lua_error(L);
        }
 
-       char addr[INET6_ADDRSTRLEN];
-       uint16_t port = 0;
-       if (kr_straddr_split(full_addr, addr, sizeof(addr), &port) != kr_ok()) {
+       char buf[INET6_ADDRSTRLEN + 1];
+       uint16_t port = 853;
+       const char *addr = kr_straddr_split(full_addr, buf, &port);
+       if (!addr) {
                format_error(L, "invalid IP address");
                lua_error(L);
        }
 
-       if (port == 0) {
-               port = 853;
-       }
-
        if (!pin_exists && !hostname_exists) {
                int r = tls_client_params_set(&net->tls_client_params,
                                              addr, port, NULL,
@@ -494,17 +491,14 @@ static int net_tls_client_clear(lua_State *L)
 
        const char *full_addr = lua_tostring(L, 1);
 
-       char addr[INET6_ADDRSTRLEN];
-       uint16_t port = 0;
-       if (kr_straddr_split(full_addr, addr, sizeof(addr), &port) != kr_ok()) {
+       char buf[INET6_ADDRSTRLEN + 1];
+       uint16_t port = 853;
+       const char *addr = kr_straddr_split(full_addr, buf, &port);
+       if (!addr) {
                format_error(L, "invalid IP address");
                lua_error(L);
        }
 
-       if (port == 0) {
-               port = 853;
-       }
-
        int r = tls_client_params_clear(&net->tls_client_params, addr, port);
        if (r != 0) {
                lua_pushstring(L, kr_strerror(r));
index c2ebe491572872eba32fb857f22b95d059ca66fa..447de21deb38d86402f50a4869e9029e18699b31 100644 (file)
@@ -337,20 +337,6 @@ end:
        #pragma GCC diagnostic pop
 }
 
-/** Split away port from the address. */
-static const char *set_addr(char *addr, int *port)
-{
-       char *p = strchr(addr, '@');
-       if (!p) {
-               p = strchr(addr, '#');
-       }
-       if (p) {
-               *port = strtol(p + 1, NULL, 10);
-               *p = '\0';
-       }
-
-       return addr;
-}
 
 /*
  * Server operation.
@@ -641,20 +627,21 @@ static int bind_fds(struct network *net, fd_array_t *fd_set, bool tls) {
        return ret;
 }
 
-static int bind_sockets(struct network *net, addr_array_t *addr_set, bool tls) {       
+static int bind_sockets(struct network *net, addr_array_t *addr_set, bool tls) {
        uint32_t flags = tls ? NET_TCP|NET_TLS : NET_UDP|NET_TCP;
-       int ret = 0;
        for (size_t i = 0; i < addr_set->len; ++i) {
-               int port = tls ? KR_DNS_TLS_PORT : KR_DNS_PORT;
-               const char *addr = set_addr(addr_set->at[i], &port);
-               ret = network_listen(net, addr, (uint16_t)port, flags);
+               uint16_t port = tls ? KR_DNS_TLS_PORT : KR_DNS_PORT;
+               char buf[INET6_ADDRSTRLEN + 1];
+               const char *addr = kr_straddr_split(addr_set->at[i], buf, &port);
+               /* NULL will result into kr_strerror(EINVAL) -> correct. */
+               int ret = network_listen(net, addr, (uint16_t)port, flags);
                if (ret != 0) {
-                       kr_log_error("[system] bind to '%s@%d' %s%s\n", 
+                       kr_log_error("[system] bind to '%s@%d' %s%s\n",
                                addr, port, tls ? "(TLS) " : "", kr_strerror(ret));
-                       break;
+                       return ret;
                }
        }
-       return ret;
+       return kr_ok();
 }
 
 int main(int argc, char **argv)
index fe9ab03b5895fcdae569d4d0aa3cdce955fd5dad..2625b6191afb67435f9fb7edac34e187a5d1c0cf 100644 (file)
@@ -491,55 +491,29 @@ int kr_straddr_subnet(void *dst, const char *addr)
        return bit_len;
 }
 
-int kr_straddr_split(const char *addr, char *buf, size_t buflen, uint16_t *port)
+const char * kr_straddr_split(const char *addr, char *buf, uint16_t *port)
 {
-       const int base = 10;
-       long p = 0;
-       size_t addrlen = strlen(addr);
-       char *p_start = strchr(addr, '@');
-       char *p_end;
-
-       if (!p_start) {
+       assert(addr && buf && port);
+       /* Find where port number starts. */
+       const char *p_start = strchr(addr, '@');
+       if (!p_start)
                p_start = strchr(addr, '#');
-       }
-
-       if (p_start) {
-               if (p_start[1] != '\0'){
-                       p = strtol(p_start + 1, &p_end, base);
-                       if (*p_end != '\0' || p <= 0 || p > UINT16_MAX) {
-                               return kr_error(EINVAL);
-                       }
-               }
-               addrlen = p_start - addr;
-       }
-
-       /* Check if address is valid. */
-       if (addrlen >= INET6_ADDRSTRLEN) {
-               return kr_error(EINVAL);
-       }
-
-       char str[INET6_ADDRSTRLEN];
-       struct sockaddr_storage ss;
-
-       memcpy(str, addr, addrlen); str[addrlen] = '\0';
-
-       int family = kr_straddr_family(str);
-       if (family == kr_error(EINVAL) || !inet_pton(family, str, &ss)) {
-               return kr_error(EINVAL);
-       }
-
-       /* Address and port contains valid values, return it to caller */
-       if (buf) {
-               if (addrlen >= buflen) {
-                       return kr_error(ENOSPC);
-               }
-               memcpy(buf, addr, addrlen); buf[addrlen] = '\0';
-       }
-       if (port) {
-               *port = (uint16_t)p;
-       }
-
-       return kr_ok();
+       if (!p_start) /* No port specified -> no need to copy anything. */
+               return addr;
+       if (p_start[1] == '\0') /* Don't accept empty port string. */
+               return NULL;
+       /* Check the port number. */
+       char *p_end;
+       long p = strtol(p_start + 1, &p_end, 10);
+       if (*p_end != '\0' || p <= 0 || p > UINT16_MAX)
+               return NULL;
+       *port = p;
+       /* We need to copy the address. */
+       const size_t addrlen = p_start - addr;
+       if (addrlen > INET6_ADDRSTRLEN)
+               return NULL;
+       memcpy(buf, addr, addrlen); buf[addrlen] = '\0';
+       return buf;
 }
 
 int kr_straddr_join(const char *addr, uint16_t port, char *buf, size_t *buflen)
index 21eabac80a7ceefd3facc83ceebca18ea28d6d64..9b20afb4e0223c73af6be3e38abfd95ddb863bc4 100644 (file)
@@ -303,16 +303,17 @@ struct sockaddr * kr_straddr_socket(const char *addr, int port);
 KR_EXPORT
 int kr_straddr_subnet(void *dst, const char *addr);
 
-/** Splits ip address specified as "addr@port" or "addr#port" into addr and port
-  * and performs validation.
-  * @note if #port part isn't present, then port will be set to 0.
-  *       buf and\or port can be set to NULL.
 * @return kr_error(EINVAL) - addr part doesn't contains valid ip address or
 *                            #port part is out-of-range (either < 0 either > UINT16_MAX)
-  *         kr_error(ENOSP)  - buflen is too small
 */
+/** Splits ip address specified as "addr@port" or "addr#port" into addr and port.
+ * \param addr zero-terminated input
+ * \param buf buffer in case we need to copy the address;
+ *             length > MIN(strlen(addr), INET6_ADDRSTRLEN + 1)
* \param port[out] written in case it's specified in addr
* \return pointer to address without port (zero-terminated string)
+ * \note Typically you follow this by kr_straddr_socket().
+ */
 KR_EXPORT
-int kr_straddr_split(const char *addr, char *buf, size_t buflen, uint16_t *port);
+const char * kr_straddr_split(const char *addr, char *buf, uint16_t *port);
+
 /** Formats ip address and port in "addr#port" format.
   * and performs validation.
   * @note Port always formatted as five-character string with leading zeros.