]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/bindings/net: add interface name to link-local IPv6 addresses
authorOto Šťáva <oto.stava@nic.cz>
Thu, 27 Jan 2022 14:19:02 +0000 (15:19 +0100)
committerOto Šťáva <oto.stava@nic.cz>
Mon, 31 Jan 2022 08:15:12 +0000 (09:15 +0100)
NEWS
daemon/bindings/net.c

diff --git a/NEWS b/NEWS
index e4bc1a74cd948eaaf6fda2329f2dde25d3c2c15f..995345529993f94baa399714545731b4b06d7a37 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Incompatible changes
 Bugfixes
 --------
 - doh2: fix CORS by adding `access-control-allow-origin: *` (!1246)
+- net: fix listen by interface - add interface suffix to link-local IPv6 (!1253)
 
 
 Knot Resolver 5.4.4 (2022-01-05)
index ec9c822c87366777ba1e399e72c47fe8be62bbbd..ff6a6c37dd5288586cd78c0bc9cb1cdffd6208c4 100644 (file)
@@ -5,6 +5,7 @@
 #include "daemon/bindings/impl.h"
 
 #include "contrib/base64.h"
+#include "contrib/cleanup.h"
 #include "daemon/network.h"
 #include "daemon/tls.h"
 
@@ -303,6 +304,18 @@ static int net_close(lua_State *L)
        return 1;
 }
 
+/** Check whether `addr` points to an `AF_INET6` address and whether the address
+ * is link-local. */
+static bool ip6_link_local(struct sockaddr_in6 *addr)
+{
+       if (addr->sin6_family != AF_INET6)
+               return false;
+
+       /* Link-local: https://tools.ietf.org/html/rfc4291#section-2.4 */
+       const uint8_t prefix[] = { 0xFE, 0x80 };
+       return kr_bitcmp((char *) addr->sin6_addr.s6_addr, (char *) prefix, 10) == 0;
+}
+
 /** List available interfaces. */
 static int net_interfaces(lua_State *L)
 {
@@ -333,7 +346,17 @@ static int net_interfaces(lua_State *L)
                } else {
                        buf[0] = '\0';
                }
-               lua_pushstring(L, buf);
+
+               if (ip6_link_local(&iface.address.address6)) {
+                       /* Link-local IPv6: add %interface prefix */
+                       auto_free char *str = NULL;
+                       int ret = asprintf(&str, "%s%%%s", buf, iface.name);
+                       kr_assert(ret > 0);
+                       lua_pushstring(L, str);
+               } else {
+                       lua_pushstring(L, buf);
+               }
+
                lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
                lua_setfield(L, -2, "addr");