mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-20 04:37:04 +00:00
MINOR: server: generalize sni expr parsing
Two functions exists for server sni sample expression parsing. This is confusing so this commit aims at clarifying this. Functions are renamed with the following identifiers. First function is named parse_srv_expr() and can be used during parsing. Besides expression parsing, it has ensure sample fetch validity in the context of a server line. Second function is renamed _parse_srv_expr() and is used internally by parse_srv_expr(). It only implements sample parsing without extra checks. It is already use for server instantiation derived from server-template as checks were already performed. Also, it is now used in http-client code as SNI is a fixed string. Finally, both functions are generalized to remove any reference to SNI. This will allow to reuse it to parse other server keywords which use an expression. This will be the case for the future keyword pool-conn-name.
This commit is contained in:
parent
b9f67a46a2
commit
91001422b4
@ -26,9 +26,11 @@
|
||||
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/applet-t.h>
|
||||
#include <haproxy/arg-t.h>
|
||||
#include <haproxy/freq_ctr.h>
|
||||
#include <haproxy/proxy-t.h>
|
||||
#include <haproxy/resolvers-t.h>
|
||||
#include <haproxy/sample-t.h>
|
||||
#include <haproxy/server-t.h>
|
||||
#include <haproxy/task.h>
|
||||
#include <haproxy/thread-t.h>
|
||||
@ -48,7 +50,8 @@ void srv_settings_init(struct server *srv);
|
||||
void srv_settings_cpy(struct server *srv, const struct server *src, int srv_tmpl);
|
||||
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, const struct proxy *defproxy, int parse_flags);
|
||||
int srv_update_addr(struct server *s, void *ip, int ip_sin_family, struct server_inetaddr_updater updater);
|
||||
int server_parse_sni_expr(struct server *newsrv, struct proxy *px, char **err);
|
||||
struct sample_expr *_parse_srv_expr(char *expr, struct arg_list *args_px,
|
||||
const char *file, int linenum, char **err);
|
||||
int server_set_inetaddr(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater, struct buffer *msg);
|
||||
int server_set_inetaddr_warn(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater);
|
||||
void server_get_inetaddr(struct server *s, struct server_inetaddr *inetaddr);
|
||||
|
@ -1389,9 +1389,12 @@ static int httpclient_postcheck_proxy(struct proxy *curproxy)
|
||||
/* init the SNI expression */
|
||||
/* always use the host header as SNI, without the port */
|
||||
srv_ssl->sni_expr = strdup("req.hdr(host),field(1,:)");
|
||||
err_code |= server_parse_sni_expr(srv_ssl, curproxy, &errmsg);
|
||||
if (err_code & ERR_CODE) {
|
||||
memprintf(&errmsg, "failed to configure sni: %s.", errmsg);
|
||||
srv_ssl->ssl_ctx.sni = _parse_srv_expr(srv_ssl->sni_expr,
|
||||
&curproxy->conf.args,
|
||||
NULL, 0, NULL);
|
||||
if (!srv_ssl->ssl_ctx.sni) {
|
||||
memprintf(&errmsg, "failed to configure sni.");
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
69
src/server.c
69
src/server.c
@ -2429,42 +2429,56 @@ const char *server_parse_maxconn_change_request(struct server *sv,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct sample_expr *srv_sni_sample_parse_expr(struct server *srv, struct proxy *px,
|
||||
const char *file, int linenum, char **err)
|
||||
/* Interpret <expr> as sample expression. This function is reserved for
|
||||
* internal server allocation. On parsing use parse_srv_expr() for extra sample
|
||||
* check validity.
|
||||
*
|
||||
* Returns the allocated sample on success or NULL on error.
|
||||
*/
|
||||
struct sample_expr *_parse_srv_expr(char *expr, struct arg_list *args_px,
|
||||
const char *file, int linenum, char **err)
|
||||
{
|
||||
int idx;
|
||||
const char *args[] = {
|
||||
srv->sni_expr,
|
||||
expr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
idx = 0;
|
||||
px->conf.args.ctx = ARGC_SRV;
|
||||
args_px->ctx = ARGC_SRV;
|
||||
|
||||
return sample_parse_expr((char **)args, &idx, file, linenum, err, &px->conf.args, NULL);
|
||||
return sample_parse_expr((char **)args, &idx, file, linenum, err, args_px, NULL);
|
||||
}
|
||||
|
||||
int server_parse_sni_expr(struct server *newsrv, struct proxy *px, char **err)
|
||||
/* Interpret <str> if not empty as a sample expression and store it into <out>.
|
||||
* Contrary to _parse_srv_expr(), fetch scope validity is checked to ensure it
|
||||
* is valid on a server line context. It also updates <px> HTTP mode
|
||||
* requirement depending on fetch method used.
|
||||
*
|
||||
* Returns 0 on success else non zero.
|
||||
*/
|
||||
static int parse_srv_expr(char *str, struct sample_expr **out, struct proxy *px,
|
||||
char **err)
|
||||
{
|
||||
struct sample_expr *expr;
|
||||
|
||||
expr = srv_sni_sample_parse_expr(newsrv, px, px->conf.file, px->conf.line, err);
|
||||
if (!expr) {
|
||||
memprintf(err, "error detected while parsing sni expression : %s", *err);
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
expr = _parse_srv_expr(str, &px->conf.args, px->conf.file, px->conf.line, err);
|
||||
if (!expr)
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
|
||||
memprintf(err, "error detected while parsing sni expression : "
|
||||
" fetch method '%s' extracts information from '%s', "
|
||||
memprintf(err, "fetch method '%s' extracts information from '%s', "
|
||||
"none of which is available here.",
|
||||
newsrv->sni_expr, sample_src_names(expr->fetch->use));
|
||||
str, sample_src_names(expr->fetch->use));
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
|
||||
release_sample_expr(newsrv->ssl_ctx.sni);
|
||||
newsrv->ssl_ctx.sni = expr;
|
||||
release_sample_expr(*out);
|
||||
*out = expr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3106,7 +3120,7 @@ static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
|
||||
srv_prepare_for_resolution(newsrv, srv->hostname);
|
||||
|
||||
if (newsrv->sni_expr) {
|
||||
newsrv->ssl_ctx.sni = srv_sni_sample_parse_expr(newsrv, px, NULL, 0, NULL);
|
||||
newsrv->ssl_ctx.sni = _parse_srv_expr(srv->sni_expr, &px->conf.args, NULL, 0, NULL);
|
||||
if (!newsrv->ssl_ctx.sni)
|
||||
goto err;
|
||||
}
|
||||
@ -3495,25 +3509,6 @@ out:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
/* This function is first intended to be used through parse_server to
|
||||
* initialize a new server on startup.
|
||||
*/
|
||||
static int _srv_parse_sni_expr_init(char **args, int cur_arg,
|
||||
struct server *srv, struct proxy *proxy,
|
||||
char **errmsg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!srv->sni_expr)
|
||||
return 0;
|
||||
|
||||
ret = server_parse_sni_expr(srv, proxy, errmsg);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Server initializations finalization.
|
||||
* Initialize health check, agent check, SNI expression and outgoing TLVs if enabled.
|
||||
* Must not be called for a default server instance.
|
||||
@ -3540,9 +3535,9 @@ static int _srv_parse_finalize(char **args, int cur_arg,
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
if ((ret = _srv_parse_sni_expr_init(args, cur_arg, srv, px, &errmsg)) != 0) {
|
||||
if ((ret = parse_srv_expr(srv->sni_expr, &srv->ssl_ctx.sni, px, &errmsg))) {
|
||||
if (errmsg) {
|
||||
ha_alert("%s\n", errmsg);
|
||||
ha_alert("error detected while parsing sni expression : %s.\n", errmsg);
|
||||
free(errmsg);
|
||||
}
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user