MEDIUM: acl/pattern: factor out the src/dst address fetches

Since pattern_process() is able to automatically cast returned types
into expected types, we can safely use the sample functions to fetch
addresses whatever their family. The lowest castable type must be
declared with the keyword so that config checks pass.

Right now this means that src/dst use the same fetch function for ACLs
and patterns. src6/dst6 have been kept so that configs which explicitly
rely on v6 are properly checked.
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index b2a3adb..e55fd5a 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1380,9 +1380,9 @@
 }
 
 
-/* copy the source IPv4/v6 address into temp_pattern */
+/* fetch the connection's source IPv4/IPv6 address */
 static int
-acl_fetch_src(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_src(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
               const struct arg *args, struct sample *smp)
 {
 	switch (l4->si[0].addr.from.ss_family) {
@@ -1402,19 +1402,6 @@
 	return 1;
 }
 
-/* extract the connection's source ipv4 address */
-static int
-pattern_fetch_src(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
-                  const struct arg *arg_p, struct sample *smp)
-{
-	if (l4->si[0].addr.from.ss_family != AF_INET )
-		return 0;
-
-	smp->type = SMP_T_IPV4;
-	smp->data.ipv4.s_addr = ((struct sockaddr_in *)&l4->si[0].addr.from)->sin_addr.s_addr;
-	return 1;
-}
-
 /* extract the connection's source ipv6 address */
 static int
 pattern_fetch_src6(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
@@ -1441,10 +1428,9 @@
 	return 1;
 }
 
-
-/* set test->ptr to point to the frontend's IPv4/IPv6 address and test->i to the family */
+/* fetch the connection's destination IPv4/IPv6 address */
 static int
-acl_fetch_dst(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_dst(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
               const struct arg *args, struct sample *smp)
 {
 	stream_sock_get_to_addr(&l4->si[0]);
@@ -1466,22 +1452,6 @@
 	return 1;
 }
 
-
-/* extract the connection's destination ipv4 address */
-static int
-pattern_fetch_dst(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
-                  const struct arg *arg_p, struct sample *smp)
-{
-	stream_sock_get_to_addr(&l4->si[0]);
-
-	if (l4->si[0].addr.to.ss_family != AF_INET)
-		return 0;
-
-	smp->type = SMP_T_IPV4;
-	smp->data.ipv4.s_addr = ((struct sockaddr_in *)&l4->si[0].addr.to)->sin_addr.s_addr;
-	return 1;
-}
-
 /* extract the connection's destination ipv6 address */
 static int
 pattern_fetch_dst6(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
@@ -1642,20 +1612,24 @@
  * Please take care of keeping this list alphabetically sorted.
  */
 static struct acl_kw_list acl_kws = {{ },{
-	{ "dst",        acl_parse_ip,    acl_fetch_dst,      acl_match_ip,  ACL_USE_TCP4_PERMANENT|ACL_MAY_LOOKUP, 0 },
+	{ "dst",        acl_parse_ip,    smp_fetch_dst,      acl_match_ip,  ACL_USE_TCP4_PERMANENT|ACL_MAY_LOOKUP, 0 },
 	{ "dst_port",   acl_parse_int,   smp_fetch_dport,    acl_match_int, ACL_USE_TCP_PERMANENT, 0  },
 	{ "req_rdp_cookie",     acl_parse_str, smp_fetch_rdp_cookie,     acl_match_str, ACL_USE_L6REQ_VOLATILE|ACL_MAY_LOOKUP, ARG1(0,STR) },
 	{ "req_rdp_cookie_cnt", acl_parse_int, acl_fetch_rdp_cookie_cnt, acl_match_int, ACL_USE_L6REQ_VOLATILE, ARG1(0,STR) },
-	{ "src",        acl_parse_ip,    acl_fetch_src,      acl_match_ip,  ACL_USE_TCP4_PERMANENT|ACL_MAY_LOOKUP, 0 },
+	{ "src",        acl_parse_ip,    smp_fetch_src,      acl_match_ip,  ACL_USE_TCP4_PERMANENT|ACL_MAY_LOOKUP, 0 },
 	{ "src_port",   acl_parse_int,   smp_fetch_sport,    acl_match_int, ACL_USE_TCP_PERMANENT, 0  },
 	{ NULL, NULL, NULL, NULL },
 }};
 
-/* Note: must not be declared <const> as its list will be overwritten */
+/* Note: must not be declared <const> as its list will be overwritten.
+ * Note: fetches that may return multiple types must be declared as the lowest
+ * common denominator, the type that can be casted into all other ones. For
+ * instance v4/v6 must be declared v4.
+ */
 static struct pattern_fetch_kw_list pattern_fetch_keywords = {{ },{
-	{ "src",         pattern_fetch_src,       0,                      NULL,           SMP_T_IPV4, SMP_CAP_REQ|SMP_CAP_RES },
+	{ "src",         smp_fetch_src,           0,                      NULL,           SMP_T_IPV4, SMP_CAP_REQ|SMP_CAP_RES },
 	{ "src6",        pattern_fetch_src6,      0,                      NULL,           SMP_T_IPV6, SMP_CAP_REQ|SMP_CAP_RES },
-	{ "dst",         pattern_fetch_dst,       0,                      NULL,           SMP_T_IPV4, SMP_CAP_REQ|SMP_CAP_RES },
+	{ "dst",         smp_fetch_dst,           0,                      NULL,           SMP_T_IPV4, SMP_CAP_REQ|SMP_CAP_RES },
 	{ "dst6",        pattern_fetch_dst6,      0,                      NULL,           SMP_T_IPV6, SMP_CAP_REQ|SMP_CAP_RES },
 	{ "dst_port",    smp_fetch_dport,         0,                      NULL,           SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
 	{ "payload",     pattern_fetch_payload,   ARG2(2,UINT,UINT),      val_payload,    SMP_T_CBIN, SMP_CAP_REQ|SMP_CAP_RES },