]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http: add the "base32+src" fetch method.
authorWilly Tarreau <w@1wt.eu>
Sun, 9 Dec 2012 13:53:32 +0000 (14:53 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 9 Dec 2012 13:53:32 +0000 (14:53 +0100)
This returns the concatenation of the base32 fetch and the src fetch.
The resulting type is of type binary, with a size of 8 or 20 bytes
depending on the source address family. This can be used to track
per-IP, per-URL counters.

doc/configuration.txt
src/proto_http.c

index 8adc3f2e956c028d4bd63acfbba960062ccb29e7..fcbb9ee2ab21335396c24d394edd8abcd8a3cd50 100644 (file)
@@ -9322,6 +9322,11 @@ The list of currently supported pattern fetch functions is the following :
                shorter hash is stored, saving a lot of memory. The output type
                is an unsigned integer.
 
+  base32+src   This returns the concatenation of the base32 fetch above and the
+               src fetch below. The resulting type is of type binary, with a
+               size of 8 or 20 bytes depending on the source address family.
+               This can be used to track per-IP, per-URL counters.
+
   src          This is the source IPv4 address of the client of the session.
                It is of type IPv4 and works on both IPv4 and IPv6 tables.
                On IPv6 tables, IPv4 address is mapped to its IPv6 equivalent,
index b3481aff9e994cdb209b14b63dfcc1e54d584ecb..89b55b30066094d2f05f3e8b8e1c6bab6e3e0e31 100644 (file)
@@ -8538,6 +8538,43 @@ smp_fetch_base32(struct proxy *px, struct session *l4, void *l7, unsigned int op
        return 1;
 }
 
+/* This concatenates the source address with the 32-bit hash of the Host and
+ * URL as returned by smp_fetch_base32(). The idea is to have per-source and
+ * per-url counters. The result is a binary block from 8 to 20 bytes depending
+ * on the source address length. The URL hash is stored before the address so
+ * that in environments where IPv6 is insignificant, truncating the output to
+ * 8 bytes would still work.
+ */
+static int
+smp_fetch_base32_src(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+                     const struct arg *args, struct sample *smp)
+{
+       struct chunk *temp = sample_get_trash_chunk();
+
+       if (!smp_fetch_base32(px, l4, l7, opt, args, smp))
+               return 0;
+
+       memcpy(temp->str + temp->len, &smp->data.uint, sizeof(smp->data.uint));
+       temp->len += sizeof(smp->data.uint);
+
+       switch (l4->si[0].conn->addr.from.ss_family) {
+       case AF_INET:
+               memcpy(temp->str + temp->len, &((struct sockaddr_in *)&l4->si[0].conn->addr.from)->sin_addr, 4);
+               temp->len += 4;
+               break;
+       case AF_INET6:
+               memcpy(temp->str + temp->len, &((struct sockaddr_in6 *)(&l4->si[0].conn->addr.from))->sin6_addr, 16);
+               temp->len += 16;
+               break;
+       default:
+               return 0;
+       }
+
+       smp->data.str = *temp;
+       smp->type = SMP_T_BIN;
+       return 1;
+}
+
 static int
 acl_fetch_proto_http(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                      const struct arg *args, struct sample *smp)
@@ -9160,6 +9197,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
        { "hdr",        smp_fetch_hdr,            ARG2(1,STR,SINT), val_hdr, SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
        { "base",       smp_fetch_base,           0,                NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
        { "base32",     smp_fetch_base32,         0,                NULL,    SMP_T_UINT, SMP_CAP_L7|SMP_CAP_REQ },
+       { "base32+src", smp_fetch_base32_src,     0,                NULL,    SMP_T_BIN,  SMP_CAP_L7|SMP_CAP_REQ },
        { "path",       smp_fetch_path,           0,                NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
        { "url",        smp_fetch_url,            0,                NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
        { "url_ip",     smp_fetch_url_ip,         0,                NULL,    SMP_T_IPV4, SMP_CAP_L7|SMP_CAP_REQ },