]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
mod-rrl: simplify endian-independent adrress operations
authorDaniel Salzman <daniel.salzman@nic.cz>
Fri, 29 Mar 2019 12:33:42 +0000 (13:33 +0100)
committerDaniel Salzman <daniel.salzman@nic.cz>
Tue, 2 Apr 2019 16:40:14 +0000 (18:40 +0200)
src/knot/modules/rrl/functions.c
tests/modules/test_rrl.c

index ee76a431d2ed7025e23ec379878811414f1a3189..3e4be126e0dcc1a2bdd054ba5cb552f4e33199be 100644 (file)
 
 /* Hopscotch defines. */
 #define HOP_LEN (sizeof(unsigned)*8)
-/* Limits */
-#define RRL_CLSBLK_MAXLEN (4 + 8 + 1 + 256)
+/* Limits (class, ipv6 remote, dname) */
+#define RRL_CLSBLK_MAXLEN (1 + 8 + 255)
 /* CIDR block prefix lengths for v4/v6 */
-#define RRL_V4_PREFIX ((uint32_t)0x00ffffff)         /* /24 */
-#define RRL_V6_PREFIX ((uint64_t)0x00ffffffffffffff) /* /56 */
+#define RRL_V4_PREFIX_LEN 3 /* /24 */
+#define RRL_V6_PREFIX_LEN 7 /* /56 */
 /* Defaults */
 #define RRL_SSTART 2 /* 1/Nth of the rate for slow start */
 #define RRL_PSIZE_LARGE 1024
@@ -166,25 +166,13 @@ static int rrl_classify(uint8_t *dst, size_t maxlen, const struct sockaddr_stora
        /* Address (in network byteorder, adjust masks). */
        uint64_t netblk = 0;
        if (remote->ss_family == AF_INET6) {
-               uint64_t netmask = 0; // Create endian-independent netmask from integer macro.
-               for (int i = 0; i < sizeof(uint64_t); i++) {
-                       *((uint8_t *)&netmask + i) = (RRL_V6_PREFIX >> (8 * i)) & 0xff;
-               }
                struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)remote;
-               netblk = *((uint64_t *)(&ipv6->sin6_addr)) & netmask;
+               memcpy(&netblk, &ipv6->sin6_addr, RRL_V6_PREFIX_LEN);
        } else {
-               uint32_t netmask = 0; // Create endian-independent netmask from integer macro.
-               for (int i = 0; i < sizeof(uint32_t); i++) {
-                       *((uint8_t *)&netmask + i) = (RRL_V4_PREFIX >> (8 * i)) & 0xff;
-               }
                struct sockaddr_in *ipv4 = (struct sockaddr_in *)remote;
-               // Write to the left part of netblk, endian-independently.
-               *((uint32_t *)&netblk) = ((uint32_t)ipv4->sin_addr.s_addr) & netmask;
-       }
-       if (blklen + sizeof(netblk) > maxlen) {
-               return KNOT_ESPACE;
+               memcpy(&netblk, &ipv4->sin_addr, RRL_V4_PREFIX_LEN);
        }
-       memcpy(dst + blklen, (void *)&netblk, sizeof(netblk));
+       memcpy(dst + blklen, &netblk, sizeof(netblk));
        blklen += sizeof(netblk);
 
        /* Name */
index 9e2b71e333d3a4f54826f055154100a25c35f1bf..6a5210fc7fd7adca4ea701285ac165be3ad9a782 100644 (file)
@@ -145,7 +145,7 @@ int main(int argc, char *argv[])
 
        /* 3. Endian-independent hash input buffer. */
        uint8_t buf[RRL_CLSBLK_MAXLEN];
-       // CLS_LARGE + remote + dname wire length + dname wire.
+       // CLS_LARGE + remote + dname wire.
        uint8_t expectedv4[] = "\x10\x01\x02\x03\x00\x00\x00\x00\x00\x04""beef";
        rrl_classify(buf, sizeof(buf), &addr, &rq, qname);
        is_int(0, memcmp(buf, expectedv4, sizeof(expectedv4)), "rrl: IPv4 hash input buffer");