mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 13:51:26 +02:00
[MINOR] acl: add a new parsing function: parse_dotted_ver
This new function supports one major and one minor and makes an int of them. It is very convenient to compare versions (eg: SSL) just as if they were plain integers, as the comparison functions will still be based on integers.
This commit is contained in:
parent
b686644ad8
commit
4a26d2f2fa
@ -120,6 +120,9 @@ int acl_match_int(struct acl_test *test, struct acl_pattern *pattern);
|
|||||||
/* Parse an integer. It is put both in min and max. */
|
/* Parse an integer. It is put both in min and max. */
|
||||||
int acl_parse_int(const char **text, struct acl_pattern *pattern, int *opaque);
|
int acl_parse_int(const char **text, struct acl_pattern *pattern, int *opaque);
|
||||||
|
|
||||||
|
/* Parse an version. It is put both in min and max. */
|
||||||
|
int acl_parse_dotted_ver(const char **text, struct acl_pattern *pattern, int *opaque);
|
||||||
|
|
||||||
/* Parse a range of integers delimited by either ':' or '-'. If only one
|
/* Parse a range of integers delimited by either ':' or '-'. If only one
|
||||||
* integer is read, it is set as both min and max.
|
* integer is read, it is set as both min and max.
|
||||||
*/
|
*/
|
||||||
|
99
src/acl.c
99
src/acl.c
@ -390,6 +390,105 @@ int acl_parse_int(const char **text, struct acl_pattern *pattern, int *opaque)
|
|||||||
return skip + 1;
|
return skip + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse a range of positive 2-component versions delimited by either ':' or
|
||||||
|
* '-'. The version consists in a major and a minor, both of which must be
|
||||||
|
* smaller than 65536, because internally they will be represented as a 32-bit
|
||||||
|
* integer.
|
||||||
|
* If only one version is read, it is set as both min and max. Just like for
|
||||||
|
* pure integers, an operator may be specified as the prefix, among this list
|
||||||
|
* of 5 :
|
||||||
|
*
|
||||||
|
* 0:eq, 1:gt, 2:ge, 3:lt, 4:le
|
||||||
|
*
|
||||||
|
* The default operator is "eq". It supports range matching. Ranges are
|
||||||
|
* rejected for other operators. The operator may be changed at any time.
|
||||||
|
* The operator is stored in the 'opaque' argument. This allows constructs
|
||||||
|
* such as the following one :
|
||||||
|
*
|
||||||
|
* acl obsolete_ssl ssl_req_proto lt 3
|
||||||
|
* acl unsupported_ssl ssl_req_proto gt 3.1
|
||||||
|
* acl valid_ssl ssl_req_proto 3.0-3.1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int acl_parse_dotted_ver(const char **text, struct acl_pattern *pattern, int *opaque)
|
||||||
|
{
|
||||||
|
signed long long i;
|
||||||
|
unsigned int j, last, skip = 0;
|
||||||
|
const char *ptr = *text;
|
||||||
|
|
||||||
|
|
||||||
|
while (!isdigit((unsigned char)*ptr)) {
|
||||||
|
if (strcmp(ptr, "eq") == 0) *opaque = 0;
|
||||||
|
else if (strcmp(ptr, "gt") == 0) *opaque = 1;
|
||||||
|
else if (strcmp(ptr, "ge") == 0) *opaque = 2;
|
||||||
|
else if (strcmp(ptr, "lt") == 0) *opaque = 3;
|
||||||
|
else if (strcmp(ptr, "le") == 0) *opaque = 4;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
skip++;
|
||||||
|
ptr = text[skip];
|
||||||
|
}
|
||||||
|
|
||||||
|
last = i = 0;
|
||||||
|
while (1) {
|
||||||
|
j = *ptr++;
|
||||||
|
if (j == '.') {
|
||||||
|
/* minor part */
|
||||||
|
if (i >= 65536)
|
||||||
|
return 0;
|
||||||
|
i <<= 16;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((j == '-' || j == ':') && !last) {
|
||||||
|
last++;
|
||||||
|
if (i < 65536)
|
||||||
|
i <<= 16;
|
||||||
|
pattern->val.range.min = i;
|
||||||
|
i = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
j -= '0';
|
||||||
|
if (j > 9)
|
||||||
|
// also catches the terminating zero
|
||||||
|
break;
|
||||||
|
i = (i & 0xFFFF0000) + (i & 0xFFFF) * 10;
|
||||||
|
i += j;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we only got a major version, let's shift it now */
|
||||||
|
if (i < 65536)
|
||||||
|
i <<= 16;
|
||||||
|
|
||||||
|
if (last && *opaque >= 1 && *opaque <= 4)
|
||||||
|
/* having a range with a min or a max is absurd */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!last)
|
||||||
|
pattern->val.range.min = i;
|
||||||
|
pattern->val.range.max = i;
|
||||||
|
|
||||||
|
switch (*opaque) {
|
||||||
|
case 0: /* eq */
|
||||||
|
pattern->val.range.min_set = 1;
|
||||||
|
pattern->val.range.max_set = 1;
|
||||||
|
break;
|
||||||
|
case 1: /* gt */
|
||||||
|
pattern->val.range.min++; /* gt = ge + 1 */
|
||||||
|
case 2: /* ge */
|
||||||
|
pattern->val.range.min_set = 1;
|
||||||
|
pattern->val.range.max_set = 0;
|
||||||
|
break;
|
||||||
|
case 3: /* lt */
|
||||||
|
pattern->val.range.max--; /* lt = le - 1 */
|
||||||
|
case 4: /* le */
|
||||||
|
pattern->val.range.min_set = 0;
|
||||||
|
pattern->val.range.max_set = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return skip + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse an IP address and an optional mask in the form addr[/mask].
|
/* Parse an IP address and an optional mask in the form addr[/mask].
|
||||||
* The addr may either be an IPv4 address or a hostname. The mask
|
* The addr may either be an IPv4 address or a hostname. The mask
|
||||||
* may either be a dotted mask or a number of bits. Returns 1 if OK,
|
* may either be a dotted mask or a number of bits. Returns 1 if OK,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user