diff --git a/include/proto/sample.h b/include/proto/sample.h index 77d6c1817..3137948af 100644 --- a/include/proto/sample.h +++ b/include/proto/sample.h @@ -34,5 +34,6 @@ struct sample *sample_fetch_string(struct proxy *px, struct session *l4, void *l unsigned int opt, struct sample_expr *expr); void sample_register_fetches(struct sample_fetch_kw_list *psl); void sample_register_convs(struct sample_conv_kw_list *psl); +const char *sample_src_names(unsigned int use); #endif /* _PROTO_SAMPLE_H */ diff --git a/include/types/sample.h b/include/types/sample.h index 6c19ade13..0e1cd780f 100644 --- a/include/types/sample.h +++ b/include/types/sample.h @@ -3,7 +3,7 @@ * Macros, variables and structures for sample management. * * Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun - * Copyright (C) 2012 Willy Tarreau + * Copyright (C) 2012-2013 Willy Tarreau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -44,15 +44,112 @@ enum { SMP_TYPES /* number of types, must always be last */ }; -/* Sample fetch capabilities are used to declare keywords. Right now only - * the supportd fetch directions are specified. +/* Sample sources are used to establish a relation between fetch keywords and + * the location where they're about to be used. They're reserved for internal + * use and are not meant to be known outside the sample management code. */ enum { - SMP_CAP_REQ = 1 << 0, /* fetch supported on request */ - SMP_CAP_RES = 1 << 1, /* fetch supported on response */ - SMP_CAP_L7 = 1 << 2, /* fetch may require access to L7 */ + SMP_SRC_INTRN, /* internal context-less information */ + SMP_SRC_LISTN, /* listener which accepted the connection */ + SMP_SRC_FTEND, /* frontend which accepted the connection */ + SMP_SRC_L4CLI, /* L4 information about the client */ + SMP_SRC_L5CLI, /* fetch uses client information from embryonic session */ + SMP_SRC_TRACK, /* fetch involves track counters */ + SMP_SRC_L6REQ, /* fetch uses raw information from the request buffer */ + SMP_SRC_HRQHV, /* fetch uses volatile information about HTTP request headers (eg: value) */ + SMP_SRC_HRQHP, /* fetch uses persistent information about HTTP request headers (eg: meth) */ + SMP_SRC_HRQBO, /* fetch uses information about HTTP request body */ + SMP_SRC_BKEND, /* fetch uses information about the backend */ + SMP_SRC_SERVR, /* fetch uses information about the selected server */ + SMP_SRC_L4SRV, /* fetch uses information about the server L4 connection */ + SMP_SRC_L5SRV, /* fetch uses information about the server L5 connection */ + SMP_SRC_L6RES, /* fetch uses raw information from the response buffer */ + SMP_SRC_HRSHV, /* fetch uses volatile information about HTTP response headers (eg: value) */ + SMP_SRC_HRSHP, /* fetch uses persistent information about HTTP response headers (eg: status) */ + SMP_SRC_HRSBO, /* fetch uses information about HTTP response body */ + SMP_SRC_RQFIN, /* final information about request buffer (eg: tot bytes) */ + SMP_SRC_RSFIN, /* final information about response buffer (eg: tot bytes) */ + SMP_SRC_TXFIN, /* final information about the transaction (eg: #comp rate) */ + SMP_SRC_SSFIN, /* final information about the session (eg: #requests, final flags) */ + SMP_SRC_ENTRIES /* nothing after this */ }; +/* SMP_USE_* are flags used to declare fetch keywords. Fetch methods are + * associated with bitfields composed of these values, generally only one, to + * indicate where the contents may be sampled. Some fetches are ambiguous as + * they apply to either the request or the response depending on the context, + * so they will have 2 of these bits (eg: hdr(), payload(), ...). These are + * stored in smp->use. + */ +enum { + SMP_USE_INTRN = 1 << SMP_SRC_INTRN, /* internal context-less information */ + SMP_USE_LISTN = 1 << SMP_SRC_LISTN, /* listener which accepted the connection */ + SMP_USE_FTEND = 1 << SMP_SRC_FTEND, /* frontend which accepted the connection */ + SMP_USE_L4CLI = 1 << SMP_SRC_L4CLI, /* L4 information about the client */ + SMP_USE_L5CLI = 1 << SMP_SRC_L5CLI, /* fetch uses client information from embryonic session */ + SMP_USE_TRACK = 1 << SMP_SRC_TRACK, /* fetch involves track counters */ + SMP_USE_L6REQ = 1 << SMP_SRC_L6REQ, /* fetch uses raw information from the request buffer */ + SMP_USE_HRQHV = 1 << SMP_SRC_HRQHV, /* fetch uses volatile information about HTTP request headers (eg: value) */ + SMP_USE_HRQHP = 1 << SMP_SRC_HRQHP, /* fetch uses persistent information about HTTP request headers (eg: meth) */ + SMP_USE_HRQBO = 1 << SMP_SRC_HRQBO, /* fetch uses information about HTTP request body */ + SMP_USE_BKEND = 1 << SMP_SRC_BKEND, /* fetch uses information about the backend */ + SMP_USE_SERVR = 1 << SMP_SRC_SERVR, /* fetch uses information about the selected server */ + SMP_USE_L4SRV = 1 << SMP_SRC_L4SRV, /* fetch uses information about the server L4 connection */ + SMP_USE_L5SRV = 1 << SMP_SRC_L5SRV, /* fetch uses information about the server L5 connection */ + SMP_USE_L6RES = 1 << SMP_SRC_L6RES, /* fetch uses raw information from the response buffer */ + SMP_USE_HRSHV = 1 << SMP_SRC_HRSHV, /* fetch uses volatile information about HTTP response headers (eg: value) */ + SMP_USE_HRSHP = 1 << SMP_SRC_HRSHP, /* fetch uses persistent information about HTTP response headers (eg: status) */ + SMP_USE_HRSBO = 1 << SMP_SRC_HRSBO, /* fetch uses information about HTTP response body */ + SMP_USE_RQFIN = 1 << SMP_SRC_RQFIN, /* final information about request buffer (eg: tot bytes) */ + SMP_USE_RSFIN = 1 << SMP_SRC_RSFIN, /* final information about response buffer (eg: tot bytes) */ + SMP_USE_TXFIN = 1 << SMP_SRC_TXFIN, /* final information about the transaction (eg: #comp rate) */ + SMP_USE_SSFIN = 1 << SMP_SRC_SSFIN, /* final information about the session (eg: #requests, final flags) */ + + /* This composite one is useful to detect if an hdr_idx needs to be allocated */ + SMP_USE_HTTP_ANY = SMP_USE_HRQHV | SMP_USE_HRQHP | SMP_USE_HRQBO | + SMP_USE_HRSHV | SMP_USE_HRSHP | SMP_USE_HRSBO, +}; + +/* Sample validity is computed from the fetch sources above when keywords + * are registered. Each fetch method may be used at different locations. The + * configuration parser will check whether the fetches are compatible with the + * location where they're used. These are stored in smp->val. + */ +enum { + SMP_VAL___________ = 0, /* Just used as a visual marker */ + SMP_VAL_FE_CON_ACC = 1 << 0, /* FE connection accept rules ("tcp request connection") */ + SMP_VAL_FE_SES_ACC = 1 << 1, /* FE session accept rules (to come soon) */ + SMP_VAL_FE_REQ_CNT = 1 << 2, /* FE request content rules ("tcp request content") */ + SMP_VAL_FE_HRQ_HDR = 1 << 3, /* FE HTTP request headers (rules, headers, monitor, stats, redirect) */ + SMP_VAL_FE_HRQ_BDY = 1 << 4, /* FE HTTP request body */ + SMP_VAL_FE_SET_BCK = 1 << 5, /* FE backend switching rules ("use_backend") */ + SMP_VAL_BE_REQ_CNT = 1 << 6, /* BE request content rules ("tcp request content") */ + SMP_VAL_BE_HRQ_HDR = 1 << 7, /* BE HTTP request headers (rules, headers, monitor, stats, redirect) */ + SMP_VAL_BE_HRQ_BDY = 1 << 8, /* BE HTTP request body */ + SMP_VAL_BE_SET_SRV = 1 << 9, /* BE server switching rules ("use_server", "balance", "force-persist", "stick", ...) */ + SMP_VAL_BE_SRV_CON = 1 << 10, /* BE server connect (eg: "source") */ + SMP_VAL_BE_RES_CNT = 1 << 11, /* BE response content rules ("tcp response content") */ + SMP_VAL_BE_HRS_HDR = 1 << 12, /* BE HTTP response headers (rules, headers) */ + SMP_VAL_BE_HRS_BDY = 1 << 13, /* BE HTTP response body (stick-store rules are there) */ + SMP_VAL_BE_STO_RUL = 1 << 14, /* BE stick-store rules */ + SMP_VAL_FE_RES_CNT = 1 << 15, /* FE response content rules ("tcp response content") */ + SMP_VAL_FE_HRS_HDR = 1 << 16, /* FE HTTP response headers (rules, headers) */ + SMP_VAL_FE_HRS_BDY = 1 << 17, /* FE HTTP response body */ + SMP_VAL_FE_LOG_END = 1 << 18, /* FE log at the end of the txn/session */ + + /* a few combinations to decide what direction to try to fetch (useful for logs) */ + SMP_VAL_REQUEST = SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV, + + SMP_VAL_RESPONSE = SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | SMP_VAL_BE_HRS_HDR | + SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | SMP_VAL_FE_RES_CNT | + SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | SMP_VAL_FE_LOG_END, +}; + +extern const unsigned int fetch_cap[SMP_SRC_ENTRIES]; + /* Sample fetch options are passed to sample fetch functions to add precision * about what is desired : * - fetch direction (req/resp) @@ -145,7 +242,8 @@ struct sample_fetch { int (*val_args)(struct arg *arg_p, char **err_msg); /* argument validation function */ unsigned long out_type; /* output sample type */ - unsigned int cap; /* fetch capabilities (SMP_CAP_*) */ + unsigned int use; /* fetch source (SMP_USE_*) */ + unsigned int val; /* fetch validity (SMP_VAL_*) */ }; /* sample expression */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 8c959debf..a0178e687 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3022,17 +3022,17 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) } if (flags & STK_ON_RSP) { - if (!(expr->fetch->cap & SMP_CAP_RES)) { - Alert("parsing [%s:%d] : '%s': fetch method '%s' can not be used on response.\n", - file, linenum, args[0], expr->fetch->kw); + if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) { + Alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n", + file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use)); err_code |= ERR_ALERT | ERR_FATAL; free(expr); goto out; } } else { - if (!(expr->fetch->cap & SMP_CAP_REQ)) { - Alert("parsing [%s:%d] : '%s': fetch method '%s' can not be used on request.\n", - file, linenum, args[0], expr->fetch->kw); + if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) { + Alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n", + file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use)); err_code |= ERR_ALERT | ERR_FATAL; free(expr); goto out; @@ -3040,7 +3040,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) } /* check if we need to allocate an hdr_idx struct for HTTP parsing */ - if (expr->fetch->cap & SMP_CAP_L7) + if (expr->fetch->use & SMP_USE_HTTP_ANY) curproxy->acl_requires |= ACL_USE_L7_ANY; if (strcmp(args[myidx], "table") == 0) { diff --git a/src/log.c b/src/log.c index 338a98601..45cc67e6c 100644 --- a/src/log.c +++ b/src/log.c @@ -335,15 +335,15 @@ void add_sample_to_logformat_list(char *text, char *arg, int arg_len, struct pro node->arg = my_strndup(arg, arg_len); parse_logformat_var_args(node->arg, node); } - if (expr->fetch->cap & SMP_CAP_REQ) + if (expr->fetch->val & SMP_VAL_REQUEST) node->options |= LOG_OPT_REQ_CAP; /* fetch method is request-compatible */ - if (expr->fetch->cap & SMP_CAP_RES) + if (expr->fetch->val & SMP_VAL_RESPONSE) node->options |= LOG_OPT_RES_CAP; /* fetch method is response-compatible */ /* check if we need to allocate an hdr_idx struct for HTTP parsing */ /* Note, we may also need to set curpx->to_log with certain fetches */ - if (expr->fetch->cap & SMP_CAP_L7) + if (expr->fetch->use & SMP_USE_HTTP_ANY) curpx->acl_requires |= ACL_USE_L7_ANY; /* FIXME: temporary workaround for missing LW_XPRT flag needed with some diff --git a/src/proto_http.c b/src/proto_http.c index 0808e64cf..36965573f 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -9598,17 +9598,17 @@ static struct acl_kw_list acl_kws = {{ },{ /************************************************************************/ /* Note: must not be declared as its list will be overwritten */ 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 }, - { "url_port", smp_fetch_url_port, 0, NULL, SMP_T_UINT, SMP_CAP_L7|SMP_CAP_REQ }, - { "url_param", smp_fetch_url_param, ARG2(1,STR,STR), NULL, SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ }, - { "cookie", smp_fetch_cookie, ARG1(1,STR), NULL, SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ|SMP_CAP_RES }, - { "set-cookie", smp_fetch_cookie, ARG1(1,STR), NULL, SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_RES }, /* deprecated */ + { "hdr", smp_fetch_hdr, ARG2(1,STR,SINT), val_hdr, SMP_T_CSTR, SMP_USE_HRQHV|SMP_USE_HRSHV }, + { "base", smp_fetch_base, 0, NULL, SMP_T_CSTR, SMP_USE_HRQHV }, + { "base32", smp_fetch_base32, 0, NULL, SMP_T_UINT, SMP_USE_HRQHV }, + { "base32+src", smp_fetch_base32_src, 0, NULL, SMP_T_BIN, SMP_USE_HRQHV }, + { "path", smp_fetch_path, 0, NULL, SMP_T_CSTR, SMP_USE_HRQHV }, + { "url", smp_fetch_url, 0, NULL, SMP_T_CSTR, SMP_USE_HRQHV }, + { "url_ip", smp_fetch_url_ip, 0, NULL, SMP_T_IPV4, SMP_USE_HRQHV }, + { "url_port", smp_fetch_url_port, 0, NULL, SMP_T_UINT, SMP_USE_HRQHV }, + { "url_param", smp_fetch_url_param, ARG2(1,STR,STR), NULL, SMP_T_CSTR, SMP_USE_HRQHV }, + { "cookie", smp_fetch_cookie, ARG1(1,STR), NULL, SMP_T_CSTR, SMP_USE_HRQHV|SMP_USE_HRSHV }, + { "set-cookie", smp_fetch_cookie, ARG1(1,STR), NULL, SMP_T_CSTR, SMP_USE_HRSHV }, /* deprecated */ { NULL, NULL, 0, 0, 0 }, }}; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 1e1d076f9..7ad825ee1 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -1043,7 +1043,8 @@ int tcp_exec_req_rules(struct session *s) /* Parse a tcp-response rule. Return a negative value in case of failure */ static int tcp_parse_response_rule(char **args, int arg, int section_type, struct proxy *curpx, struct proxy *defpx, - struct tcp_rule *rule, char **err) + struct tcp_rule *rule, char **err, + unsigned int where) { if (curpx == defpx || !(curpx->cap & PR_CAP_BE)) { memprintf(err, "%s %s is only allowed in 'backend' sections", @@ -1087,8 +1088,9 @@ static int tcp_parse_response_rule(char **args, int arg, int section_type, /* Parse a tcp-request rule. Return a negative value in case of failure */ static int tcp_parse_request_rule(char **args, int arg, int section_type, - struct proxy *curpx, struct proxy *defpx, - struct tcp_rule *rule, char **err) + struct proxy *curpx, struct proxy *defpx, + struct tcp_rule *rule, char **err, + unsigned int where) { if (curpx == defpx) { memprintf(err, "%s %s is not allowed in 'defaults' sections", @@ -1118,16 +1120,16 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type, return -1; } - if (!(expr->fetch->cap & SMP_CAP_REQ)) { + if (!(expr->fetch->val & where)) { memprintf(err, - "'%s %s %s' : fetch method '%s' cannot be used on request", - args[0], args[1], args[kw], trash.str); + "'%s %s %s' : fetch method '%s' extracts information from '%s', none of which is available here", + args[0], args[1], args[kw], args[arg], sample_src_names(expr->fetch->use)); free(expr); return -1; } /* check if we need to allocate an hdr_idx struct for HTTP parsing */ - if (expr->fetch->cap & SMP_CAP_L7) + if (expr->fetch->use & SMP_USE_HTTP_ANY) curpx->acl_requires |= ACL_USE_L7_ANY; if (strcmp(args[arg], "table") == 0) { @@ -1187,6 +1189,7 @@ static int tcp_parse_tcp_rep(char **args, int section_type, struct proxy *curpx, int warn = 0; int arg; struct tcp_rule *rule; + unsigned int where; if (!*args[1]) { memprintf(err, "missing argument for '%s' in %s '%s'", @@ -1222,10 +1225,17 @@ static int tcp_parse_tcp_rep(char **args, int section_type, struct proxy *curpx, rule = calloc(1, sizeof(*rule)); LIST_INIT(&rule->list); arg = 1; + where = 0; if (strcmp(args[1], "content") == 0) { arg++; - if (tcp_parse_response_rule(args, arg, section_type, curpx, defpx, rule, err) < 0) + + if (curpx->cap & PR_CAP_FE) + where |= SMP_VAL_FE_RES_CNT; + if (curpx->cap & PR_CAP_BE) + where |= SMP_VAL_BE_RES_CNT; + + if (tcp_parse_response_rule(args, arg, section_type, curpx, defpx, rule, err, where) < 0) goto error; if (rule->cond && (rule->cond->requires & ACL_USE_L6REQ_VOLATILE)) { @@ -1269,6 +1279,7 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx, int warn = 0; int arg; struct tcp_rule *rule; + unsigned int where; if (!*args[1]) { if (curpx == defpx) @@ -1307,10 +1318,17 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx, rule = calloc(1, sizeof(*rule)); LIST_INIT(&rule->list); arg = 1; + where = 0; if (strcmp(args[1], "content") == 0) { arg++; - if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err) < 0) + + if (curpx->cap & PR_CAP_FE) + where |= SMP_VAL_FE_REQ_CNT; + if (curpx->cap & PR_CAP_BE) + where |= SMP_VAL_BE_REQ_CNT; + + if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, where) < 0) goto error; if (rule->cond && (rule->cond->requires & ACL_USE_RTR_ANY)) { @@ -1326,14 +1344,6 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx, warn++; } - if ((rule->action == TCP_ACT_TRK_SC1 || rule->action == TCP_ACT_TRK_SC2) && - !(rule->act_prm.trk_ctr.expr->fetch->cap & SMP_CAP_REQ)) { - memprintf(err, - "fetch '%s' cannot be used on requests and will be ignored in '%s %s'", - rule->act_prm.trk_ctr.expr->fetch->kw, args[0], args[1]); - warn++; - } - LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list); } else if (strcmp(args[1], "connection") == 0) { @@ -1345,7 +1355,9 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx, goto error; } - if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err) < 0) + where |= SMP_VAL_FE_CON_ACC; + + if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, where) < 0) goto error; if (rule->cond && (rule->cond->requires & (ACL_USE_RTR_ANY|ACL_USE_L6_ANY|ACL_USE_L7_ANY))) { @@ -1369,22 +1381,6 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx, warn++; } - if ((rule->action == TCP_ACT_TRK_SC1 || rule->action == TCP_ACT_TRK_SC2) && - !(rule->act_prm.trk_ctr.expr->fetch->cap & SMP_CAP_REQ)) { - memprintf(err, - "fetch '%s' cannot be used on requests and will be ignored in '%s %s'", - rule->act_prm.trk_ctr.expr->fetch->kw, args[0], args[1]); - warn++; - } - - if ((rule->action == TCP_ACT_TRK_SC1 || rule->action == TCP_ACT_TRK_SC2) && - (rule->act_prm.trk_ctr.expr->fetch->cap & SMP_CAP_L7)) { - memprintf(err, - "fetch '%s' involves some layer7-only criteria which will be ignored in '%s %s'", - rule->act_prm.trk_ctr.expr->fetch->kw, args[0], args[1]); - warn++; - } - LIST_ADDQ(&curpx->tcp_req.l4_rules, &rule->list); } else { @@ -1882,13 +1878,13 @@ static struct acl_kw_list acl_kws = {{ },{ * instance v4/v6 must be declared v4. */ static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{ - { "src", smp_fetch_src, 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 }, - { "dst_port", smp_fetch_dport, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "payload", smp_fetch_payload, ARG2(2,UINT,UINT), val_payload, SMP_T_CBIN, SMP_CAP_REQ|SMP_CAP_RES }, - { "payload_lv", smp_fetch_payload_lv, ARG3(2,UINT,UINT,SINT), val_payload_lv, SMP_T_CBIN, SMP_CAP_REQ|SMP_CAP_RES }, - { "rdp_cookie", smp_fetch_rdp_cookie, ARG1(1,STR), NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES }, - { "src_port", smp_fetch_sport, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, + { "dst", smp_fetch_dst, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI }, + { "dst_port", smp_fetch_dport, 0, NULL, SMP_T_UINT, SMP_USE_L4CLI }, + { "payload", smp_fetch_payload, ARG2(2,UINT,UINT), val_payload, SMP_T_CBIN, SMP_USE_L6REQ|SMP_USE_L6RES }, + { "payload_lv", smp_fetch_payload_lv, ARG3(2,UINT,UINT,SINT), val_payload_lv, SMP_T_CBIN, SMP_USE_L6REQ|SMP_USE_L6RES }, + { "rdp_cookie", smp_fetch_rdp_cookie, ARG1(1,STR), NULL, SMP_T_CSTR, SMP_USE_L6REQ }, + { "src", smp_fetch_src, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI }, + { "src_port", smp_fetch_sport, 0, NULL, SMP_T_UINT, SMP_USE_L4CLI }, { NULL, NULL, 0, 0, 0 }, }}; diff --git a/src/sample.c b/src/sample.c index b3898e0a8..c35e833d2 100644 --- a/src/sample.c +++ b/src/sample.c @@ -36,13 +36,249 @@ static struct sample_conv_kw_list sample_convs = { .list = LIST_HEAD_INIT(sample_convs.list) }; -/* - * Registers the sample fetch keyword list as a list of valid keywords for next - * parsing sessions. +const unsigned int fetch_cap[SMP_SRC_ENTRIES] = { + [SMP_SRC_INTRN] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_LISTN] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_FTEND] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_L4CLI] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_L5CLI] = (SMP_VAL___________ | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_TRACK] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_L6REQ] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________), + + [SMP_SRC_HRQHV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________), + + [SMP_SRC_HRQHP] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT | + SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_HRQBO] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________), + + [SMP_SRC_BKEND] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY | + SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_SERVR] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_L4SRV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_L5SRV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_L6RES] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL___________), + + [SMP_SRC_HRSHV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL___________), + + [SMP_SRC_HRSHP] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT | + SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_HRSBO] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | + SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | + SMP_VAL___________), + + [SMP_SRC_RQFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_RSFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_TXFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL_FE_LOG_END), + + [SMP_SRC_SSFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ | + SMP_VAL_FE_LOG_END), +}; + +static const char *fetch_src_names[SMP_SRC_ENTRIES] = { + [SMP_SRC_INTRN] = "internal state", + [SMP_SRC_LISTN] = "listener", + [SMP_SRC_FTEND] = "frontend", + [SMP_SRC_L4CLI] = "client address", + [SMP_SRC_L5CLI] = "client-side connection", + [SMP_SRC_TRACK] = "track counters", + [SMP_SRC_L6REQ] = "request buffer", + [SMP_SRC_HRQHV] = "HTTP request headers", + [SMP_SRC_HRQHP] = "HTTP request", + [SMP_SRC_HRQBO] = "HTTP request body", + [SMP_SRC_BKEND] = "backend", + [SMP_SRC_SERVR] = "server", + [SMP_SRC_L4SRV] = "server address", + [SMP_SRC_L5SRV] = "server-side connection", + [SMP_SRC_L6RES] = "response buffer", + [SMP_SRC_HRSHV] = "HTTP response headers", + [SMP_SRC_HRSHP] = "HTTP response", + [SMP_SRC_HRSBO] = "HTTP response body", + [SMP_SRC_RQFIN] = "request buffer statistics", + [SMP_SRC_RSFIN] = "response buffer statistics", + [SMP_SRC_TXFIN] = "transaction statistics", + [SMP_SRC_SSFIN] = "session statistics", +}; + +/* fill the trash with a comma-delimited list of source names for the bit + * field which must be composed of a non-null set of SMP_USE_* flags. The return + * value is the pointer to the string in the trash buffer. */ -void sample_register_fetches(struct sample_fetch_kw_list *pfkl) +const char *sample_src_names(unsigned int use) { - LIST_ADDQ(&sample_fetches.list, &pfkl->list); + int bit; + + trash.len = 0; + trash.str[0] = '\0'; + for (bit = 0; bit < SMP_SRC_ENTRIES; bit++) { + if (!(use & ~((1 << bit) - 1))) + break; /* no more bits */ + + if (!(use & (1 << bit))) + continue; /* bit not set */ + + trash.len += snprintf(trash.str + trash.len, trash.size - trash.len, "%s%s", + (use & ((1 << bit) - 1)) ? "," : "", + fetch_src_names[bit]); + } + return trash.str; +} + +/* + * Registers the sample fetch keyword list as a list of valid keywords + * for next parsing sessions. The fetch keywords capabilities are also computed + * from their ->use field. + */ +void sample_register_fetches(struct sample_fetch_kw_list *kwl) +{ + struct sample_fetch *sf; + int bit; + + for (sf = kwl->kw; sf->kw != NULL; sf++) { + for (bit = 0; bit < SMP_SRC_ENTRIES; bit++) + if (sf->use & (1 << bit)) + sf->val |= fetch_cap[bit]; + } + LIST_ADDQ(&sample_fetches.list, &kwl->list); } /* diff --git a/src/ssl_sock.c b/src/ssl_sock.c index b7ca2b420..590c353bd 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -2927,39 +2927,39 @@ static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct * Please take care of keeping this list alphabetically sorted. */ static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{ - { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES }, + { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI }, + { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI }, + { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI }, + { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI }, + { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI }, + { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI }, + { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI }, + { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI }, + { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI }, + { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI }, + { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI }, + { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI }, + { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI }, + { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI }, + { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI }, #ifdef OPENSSL_NPN_NEGOTIATED - { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES }, + { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI }, #endif - { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_CBIN, SMP_CAP_REQ|SMP_CAP_RES }, - { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES }, + { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI }, + { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI }, + { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_CBIN, SMP_USE_L5CLI }, + { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI }, { NULL, NULL, 0, 0, 0 }, }};