MINOR: sample: allow IP address to cast to binary
authorWilly Tarreau <w@1wt.eu>
Tue, 15 Jul 2014 19:03:26 +0000 (21:03 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 15 Jul 2014 19:36:15 +0000 (21:36 +0200)
IP addresses are a perfect example of fixed size data which we could
cast to binary, still it was not allowed by lack of cast function,
eventhough the opposite was allowed in ACLs. Make that possible both
in sample expressions and in stick tables.

src/sample.c
src/stick_table.c

index c260f7e..34f4c1d 100644 (file)
@@ -654,6 +654,27 @@ static int c_meth2str(struct sample *smp)
        return 1;
 }
 
+static int c_addr2bin(struct sample *smp)
+{
+       struct chunk *chk = get_trash_chunk();
+
+       if (smp->type == SMP_T_IPV4) {
+               chk->len = 4;
+               memcpy(chk->str, &smp->data.ipv4, chk->len);
+       }
+       else if (smp->type == SMP_T_IPV6) {
+               chk->len = 16;
+               memcpy(chk->str, &smp->data.ipv6, chk->len);
+       }
+       else
+               return 0;
+
+       smp->data.str = *chk;
+       smp->type = SMP_T_BIN;
+       return 1;
+}
+
+
 /*****************************************************************/
 /*      Sample casts matrix:                                     */
 /*           sample_casts[from type][to type]                    */
@@ -666,8 +687,8 @@ sample_cast_fct sample_casts[SMP_TYPES][SMP_TYPES] = {
 /*       UINT */ { c_none,    c_none,    c_none,    c_int2ip,   c_int2ip, NULL,       c_int2str,  NULL,       NULL,       },
 /*       SINT */ { c_none,    c_none,    c_none,    c_int2ip,   c_int2ip, NULL,       c_int2str,  NULL,       NULL,       },
 /*       ADDR */ { NULL,      NULL,      NULL,      NULL,       NULL,     NULL,       NULL,       NULL,       NULL,       },
-/*       IPV4 */ { NULL,      c_ip2int,  c_ip2int,  c_none,     c_none,   c_ip2ipv6,  c_ip2str,   NULL,       NULL,       },
-/*       IPV6 */ { NULL,      NULL,      NULL,      c_none,     NULL,     c_none,     c_ipv62str, NULL,       NULL,       },
+/*       IPV4 */ { NULL,      c_ip2int,  c_ip2int,  c_none,     c_none,   c_ip2ipv6,  c_ip2str,   c_addr2bin, NULL,       },
+/*       IPV6 */ { NULL,      NULL,      NULL,      c_none,     NULL,     c_none,     c_ipv62str, c_addr2bin, NULL,       },
 /*        STR */ { c_str2int, c_str2int, c_str2int, c_str2addr, c_str2ip, c_str2ipv6, c_none,     c_none,     c_str2meth, },
 /*        BIN */ { NULL,      NULL,      NULL,      NULL,       NULL,     NULL,       c_bin2str,  c_none,     c_str2meth, },
 /*       METH */ { NULL,      NULL,      NULL,      NULL,       NULL,     NULL,       c_meth2str, c_meth2str, c_none,     },
index a6ee77f..1226591 100644 (file)
@@ -518,6 +518,23 @@ static void *k_ip2str(struct sample *smp, union stktable_key_data *kdata, size_t
        return (void *)kdata->buf;
 }
 
+static void *k_ip2bin(struct sample *smp, union stktable_key_data *kdata, size_t *len)
+{
+       if (smp->type == SMP_T_IPV4) {
+               if (*len > 4)
+                       *len = 4;
+               memcpy(kdata->buf, &smp->data.ipv4, *len);
+       }
+       else if (smp->type == SMP_T_IPV6) {
+               if (*len > 16)
+                       *len = 16;
+               memcpy(kdata->buf, &smp->data.ipv6, *len);
+       }
+       else
+               *len = 0;
+       return (void *)kdata->buf;
+}
+
 static void *k_bin2str(struct sample *smp, union stktable_key_data *kdata, size_t *len)
 {
        unsigned char c;
@@ -591,8 +608,8 @@ static sample_to_key_fct sample_to_key[SMP_TYPES][STKTABLE_TYPES] = {
 /*             UINT */ { k_int2ip, NULL,        k_int2int, k_int2str,  NULL      },
 /*             SINT */ { k_int2ip, NULL,        k_int2int, k_int2str,  NULL      },
 /*             ADDR */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   NULL      },
-/*             IPV4 */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   NULL      },
-/*             IPV6 */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   NULL      },
+/*             IPV4 */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   k_ip2bin  },
+/*             IPV6 */ { k_ip2ip,  k_ip2ipv6,   k_ip2int,  k_ip2str,   k_ip2bin  },
 /*              STR */ { k_str2ip, k_str2ipv6,  k_str2int, k_str2str,  k_str2str },
 /*              BIN */ { NULL,     NULL,        NULL,      k_bin2str,  k_str2str },
 };