mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-19 12:10:46 +00:00
MEDIUM: sample: let the cast functions set their output type
This patch allows each sample cast function to specify the sample output type. The goal is to be able to emit an output type IPv4 or IPv6 depending on what is found in the input if the next converter is able to process them both. The patch also adds a new pseudo type called "ADDR". This type is an alias for IPV4 and IPV6 which is only used as an input type by converters who want to express their compatibility with both address formats. It may not be emitted. The goal is to unify as much as possible the processing of IPv4 and IPv6 in order not to add extra keywords for the maps which act as converters, but will match samples like ACLs do with their patterns.
This commit is contained in:
parent
803685fa12
commit
b805f71d1b
@ -35,6 +35,7 @@ enum {
|
||||
SMP_T_BOOL = 0, /* boolean */
|
||||
SMP_T_UINT, /* unsigned 32bits integer type */
|
||||
SMP_T_SINT, /* signed 32bits integer type */
|
||||
SMP_T_ADDR, /* ipv4 or ipv6, only used for input type compatibility */
|
||||
SMP_T_IPV4, /* ipv4 type */
|
||||
SMP_T_IPV6, /* ipv6 type */
|
||||
SMP_T_STR, /* char string type */
|
||||
|
71
src/sample.c
71
src/sample.c
@ -397,6 +397,7 @@ struct sample_conv *find_sample_conv(const char *kw, int len)
|
||||
static int c_ip2int(struct sample *smp)
|
||||
{
|
||||
smp->data.uint = ntohl(smp->data.ipv4.s_addr);
|
||||
smp->type = SMP_T_UINT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -409,6 +410,7 @@ static int c_ip2str(struct sample *smp)
|
||||
|
||||
trash->len = strlen(trash->str);
|
||||
smp->data.str = *trash;
|
||||
smp->type = SMP_T_STR;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -416,6 +418,7 @@ static int c_ip2str(struct sample *smp)
|
||||
static int c_ip2ipv6(struct sample *smp)
|
||||
{
|
||||
v4tov6(&smp->data.ipv6, &smp->data.ipv4);
|
||||
smp->type = SMP_T_IPV6;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -428,6 +431,7 @@ static int c_ipv62str(struct sample *smp)
|
||||
|
||||
trash->len = strlen(trash->str);
|
||||
smp->data.str = *trash;
|
||||
smp->type = SMP_T_STR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -441,6 +445,21 @@ static int c_ipv62ip(struct sample *smp)
|
||||
static int c_int2ip(struct sample *smp)
|
||||
{
|
||||
smp->data.ipv4.s_addr = htonl(smp->data.uint);
|
||||
smp->type = SMP_T_IPV4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int c_str2addr(struct sample *smp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!buf2ip(smp->data.str.str, smp->data.str.len, &smp->data.ipv4)) {
|
||||
ret = inet_pton(AF_INET6, smp->data.str.str, &smp->data.ipv6);
|
||||
if (ret)
|
||||
smp->type = SMP_T_IPV6;
|
||||
return ret;
|
||||
}
|
||||
smp->type = SMP_T_IPV4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -448,12 +467,18 @@ static int c_str2ip(struct sample *smp)
|
||||
{
|
||||
if (!buf2ip(smp->data.str.str, smp->data.str.len, &smp->data.ipv4))
|
||||
return 0;
|
||||
smp->type = SMP_T_IPV4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int c_str2ipv6(struct sample *smp)
|
||||
{
|
||||
return inet_pton(AF_INET6, smp->data.str.str, &smp->data.ipv6);
|
||||
int ret;
|
||||
|
||||
ret = inet_pton(AF_INET6, smp->data.str.str, &smp->data.ipv6);
|
||||
if (ret)
|
||||
smp->type = SMP_T_IPV6;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int c_bin2str(struct sample *smp)
|
||||
@ -469,6 +494,7 @@ static int c_bin2str(struct sample *smp)
|
||||
trash->str[trash->len++] = hextab[c & 0xF];
|
||||
}
|
||||
smp->data.str = *trash;
|
||||
smp->type = SMP_T_STR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -486,16 +512,33 @@ static int c_int2str(struct sample *smp)
|
||||
trash->str = pos;
|
||||
trash->len = strlen(pos);
|
||||
smp->data.str = *trash;
|
||||
smp->type = SMP_T_STR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int c_datadup(struct sample *smp)
|
||||
static inline void _c_datadup(struct sample *smp)
|
||||
{
|
||||
struct chunk *trash = get_trash_chunk();
|
||||
|
||||
trash->len = smp->data.str.len < trash->size ? smp->data.str.len : trash->size;
|
||||
memcpy(trash->str, smp->data.str.str, trash->len);
|
||||
smp->data.str = *trash;
|
||||
}
|
||||
|
||||
static int c_datadup(struct sample *smp)
|
||||
{
|
||||
_c_datadup(smp);
|
||||
if (smp->type == SMP_T_CSTR)
|
||||
smp->type = SMP_T_STR;
|
||||
else
|
||||
smp->type = SMP_T_BIN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int c_bindup(struct sample *smp)
|
||||
{
|
||||
_c_datadup(smp);
|
||||
smp->type = SMP_T_BIN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -520,6 +563,7 @@ static int c_str2int(struct sample *smp)
|
||||
}
|
||||
|
||||
smp->data.uint = ret;
|
||||
smp->type = SMP_T_UINT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -530,16 +574,17 @@ static int c_str2int(struct sample *smp)
|
||||
/*****************************************************************/
|
||||
|
||||
sample_cast_fct sample_casts[SMP_TYPES][SMP_TYPES] = {
|
||||
/* to: BOOL UINT SINT IPV4 IPV6 STR BIN CSTR CBIN */
|
||||
/* from: BOOL */ { c_none, c_none, c_none, NULL, NULL, c_int2str, NULL, c_int2str, NULL },
|
||||
/* UINT */ { c_none, c_none, c_none, c_int2ip, NULL, c_int2str, NULL, c_int2str, NULL },
|
||||
/* SINT */ { c_none, c_none, c_none, c_int2ip, NULL, c_int2str, NULL, c_int2str, NULL },
|
||||
/* IPV4 */ { NULL, c_ip2int, c_ip2int, c_none, c_ip2ipv6, c_ip2str, NULL, c_ip2str, NULL },
|
||||
/* IPV6 */ { NULL, NULL, NULL, NULL, c_none, c_ipv62str, NULL, c_ipv62str, NULL },
|
||||
/* STR */ { c_str2int, c_str2int, c_str2int, c_str2ip, c_str2ipv6, c_none, c_none, c_none, c_none },
|
||||
/* BIN */ { NULL, NULL, NULL, NULL, NULL, c_bin2str, c_none, c_bin2str, c_none },
|
||||
/* CSTR */ { c_str2int, c_str2int, c_str2int, c_str2ip, c_str2ipv6, c_datadup, c_datadup, c_none, c_none },
|
||||
/* CBIN */ { NULL, NULL, NULL, NULL, NULL, c_bin2str, c_datadup, c_bin2str, c_none },
|
||||
/* to: BOOL UINT SINT ADDR IPV4 IPV6 STR BIN CSTR CBIN */
|
||||
/* from: BOOL */ { c_none, c_none, c_none, NULL, NULL, NULL, c_int2str, NULL, c_int2str, NULL, },
|
||||
/* UINT */ { c_none, c_none, c_none, c_int2ip, c_int2ip, NULL, c_int2str, NULL, c_int2str, NULL, },
|
||||
/* SINT */ { c_none, c_none, c_none, c_int2ip, c_int2ip, NULL, c_int2str, NULL, c_int2str, NULL, },
|
||||
/* ADDR */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, },
|
||||
/* IPV4 */ { NULL, c_ip2int, c_ip2int, c_none, c_none, c_ip2ipv6, c_ip2str, NULL, c_ip2str, NULL, },
|
||||
/* IPV6 */ { NULL, NULL, NULL, c_none, NULL, c_none, c_ipv62str, NULL, c_ipv62str, NULL, },
|
||||
/* STR */ { c_str2int, c_str2int, c_str2int, c_str2addr, c_str2ip, c_str2ipv6, c_none, c_none, c_none, c_none, },
|
||||
/* BIN */ { NULL, NULL, NULL, NULL, NULL, NULL, c_bin2str, c_none, c_bin2str, c_none, },
|
||||
/* CSTR */ { c_str2int, c_str2int, c_str2int, c_str2addr, c_str2ip, c_str2ipv6, c_datadup, c_bindup, c_none, c_none, },
|
||||
/* CBIN */ { NULL, NULL, NULL, NULL, NULL, NULL, c_bin2str, c_datadup, c_bin2str, c_none, },
|
||||
};
|
||||
|
||||
/*
|
||||
@ -813,8 +858,6 @@ struct sample *sample_process(struct proxy *px, struct session *l4, void *l7,
|
||||
|
||||
/* OK cast succeeded */
|
||||
|
||||
/* force the output type after a cast */
|
||||
p->type = conv_expr->conv->in_type;
|
||||
if (!conv_expr->conv->process(conv_expr->arg_p, p))
|
||||
return NULL;
|
||||
}
|
||||
|
@ -589,6 +589,7 @@ static sample_to_key_fct sample_to_key[SMP_TYPES][STKTABLE_TYPES] = {
|
||||
/* patt. type: BOOL */ { NULL, NULL, k_int2int, k_int2str, NULL },
|
||||
/* 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 },
|
||||
/* STR */ { k_str2ip, k_str2ipv6, k_str2int, k_str2str, k_str2str },
|
||||
|
Loading…
Reference in New Issue
Block a user