]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: server: prepare parsing for dynamic servers
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 8 Mar 2021 16:08:01 +0000 (17:08 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 18 Mar 2021 14:51:12 +0000 (15:51 +0100)
Prepare the server parsing API to support dynamic servers.
- define a new parsing flag to be used for dynamic servers
- each keyword contains a new field dynamic_ok to indicate if it can be
  used for a dynamic server. For now, no keyword are supported.
- do not copy settings from the default server for a new dynamic server.
- a dynamic server is created in a maintenance mode and requires an
  explicit 'enable server' command.
- a new server flag named SRV_F_DYNAMIC is created. This flag is set for
  all servers created at runtime. It might be useful later, for example
  to know if a server can be purged.

include/haproxy/server-t.h
src/cfgparse-ssl.c
src/cfgparse-tcp.c
src/check.c
src/server.c

index 647cdae3dbd13efd4667be7628eb33617f743381..714e248725a46a6c4b961d08ad7bc87cad8a5579 100644 (file)
@@ -148,6 +148,7 @@ enum srv_initaddr {
 #define SRV_F_FASTOPEN     0x0200        /* Use TCP Fast Open to connect to server */
 #define SRV_F_SOCKS4_PROXY 0x0400        /* this server uses SOCKS4 proxy */
 #define SRV_F_NO_RESOLUTION 0x0800       /* disable runtime DNS resolution on this server */
+#define SRV_F_DYNAMIC      0x1000        /* dynamic server instantiated at runtime */
 
 /* configured server options for send-proxy (server->pp_opts) */
 #define SRV_PP_V1               0x0001   /* proxy protocol version 1 */
@@ -418,6 +419,7 @@ struct srv_kw {
        int (*parse)(char **args, int *cur_arg, struct proxy *px, struct server *srv, char **err);
        int skip; /* nb min of args to skip, for use when kw is not handled */
        int default_ok; /* non-zero if kw is supported in default-server section */
+       int dynamic_ok; /* non-zero if kw is supported in add server cli command */
 };
 
 /*
@@ -436,7 +438,8 @@ struct srv_kw_list {
 #define SRV_PARSE_TEMPLATE        0x02    /* 'server-template' keyword */
 #define SRV_PARSE_IN_PEER_SECTION 0x04    /* keyword in a peer section */
 #define SRV_PARSE_PARSE_ADDR      0x08    /* required to parse the server address in the second argument */
-#define SRV_PARSE_INITIAL_RESOLVE 0x10    /* resolve immediately the fqdn to an ip address */
+#define SRV_PARSE_DYNAMIC         0x10    /* dynamic server created at runtime with cli */
+#define SRV_PARSE_INITIAL_RESOLVE 0x20    /* resolve immediately the fqdn to an ip address */
 
 #endif /* _HAPROXY_SERVER_T_H */
 
index 9ac3702e4920e51a6d72c7e53afabf954a7e8f6e..4f05ce1c5867368044828c720dc33dcfc7f57c75 100644 (file)
@@ -1808,45 +1808,45 @@ INITCALL1(STG_REGISTER, bind_register_keywords, &bind_kws);
  * not enabled.
  */
 static struct srv_kw_list srv_kws = { "SSL", { }, {
-       { "allow-0rtt",              srv_parse_allow_0rtt,         0, 1 }, /* Allow using early data on this server */
-       { "alpn",                    srv_parse_alpn,               1, 1 }, /* Set ALPN supported protocols */
-       { "ca-file",                 srv_parse_ca_file,            1, 1 }, /* set CAfile to process verify server cert */
-       { "check-alpn",              srv_parse_alpn,               1, 1 }, /* Set ALPN used for checks */
-       { "check-sni",               srv_parse_check_sni,          1, 1 }, /* set SNI */
-       { "check-ssl",               srv_parse_check_ssl,          0, 1 }, /* enable SSL for health checks */
-       { "ciphers",                 srv_parse_ciphers,            1, 1 }, /* select the cipher suite */
+       { "allow-0rtt",              srv_parse_allow_0rtt,         0, 1, 0 }, /* Allow using early data on this server */
+       { "alpn",                    srv_parse_alpn,               1, 1, 0 }, /* Set ALPN supported protocols */
+       { "ca-file",                 srv_parse_ca_file,            1, 1, 0 }, /* set CAfile to process verify server cert */
+       { "check-alpn",              srv_parse_alpn,               1, 1, 0 }, /* Set ALPN used for checks */
+       { "check-sni",               srv_parse_check_sni,          1, 1, 0 }, /* set SNI */
+       { "check-ssl",               srv_parse_check_ssl,          0, 1, 0 }, /* enable SSL for health checks */
+       { "ciphers",                 srv_parse_ciphers,            1, 1, 0 }, /* select the cipher suite */
 #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
-       { "ciphersuites",            srv_parse_ciphersuites,       1, 1 }, /* select the cipher suite */
+       { "ciphersuites",            srv_parse_ciphersuites,       1, 1, 0 }, /* select the cipher suite */
 #endif
-       { "crl-file",                srv_parse_crl_file,           1, 1 }, /* set certificate revocation list file use on server cert verify */
-       { "crt",                     srv_parse_crt,                1, 1 }, /* set client certificate */
-       { "force-sslv3",             srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
-       { "force-tlsv10",            srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
-       { "force-tlsv11",            srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
-       { "force-tlsv12",            srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
-       { "force-tlsv13",            srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
-       { "no-check-ssl",            srv_parse_no_check_ssl,       0, 1 }, /* disable SSL for health checks */
-       { "no-send-proxy-v2-ssl",    srv_parse_no_send_proxy_ssl,  0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
-       { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn,   0, 1 }, /* do not send PROXY protocol header v2 with CN */
-       { "no-ssl",                  srv_parse_no_ssl,             0, 1 }, /* disable SSL processing */
-       { "no-ssl-reuse",            srv_parse_no_ssl_reuse,       0, 1 }, /* disable session reuse */
-       { "no-sslv3",                srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
-       { "no-tlsv10",               srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
-       { "no-tlsv11",               srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
-       { "no-tlsv12",               srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
-       { "no-tlsv13",               srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
-       { "no-tls-tickets",          srv_parse_no_tls_tickets,     0, 1 }, /* disable session resumption tickets */
-       { "npn",                     srv_parse_npn,                1, 1 }, /* Set NPN supported protocols */
-       { "send-proxy-v2-ssl",       srv_parse_send_proxy_ssl,     0, 1 }, /* send PROXY protocol header v2 with SSL info */
-       { "send-proxy-v2-ssl-cn",    srv_parse_send_proxy_cn,      0, 1 }, /* send PROXY protocol header v2 with CN */
-       { "sni",                     srv_parse_sni,                1, 1 }, /* send SNI extension */
-       { "ssl",                     srv_parse_ssl,                0, 1 }, /* enable SSL processing */
-       { "ssl-min-ver",             srv_parse_tls_method_minmax,  1, 1 }, /* minimum version */
-       { "ssl-max-ver",             srv_parse_tls_method_minmax,  1, 1 }, /* maximum version */
-       { "ssl-reuse",               srv_parse_ssl_reuse,          0, 1 }, /* enable session reuse */
-       { "tls-tickets",             srv_parse_tls_tickets,        0, 1 }, /* enable session resumption tickets */
-       { "verify",                  srv_parse_verify,             1, 1 }, /* set SSL verify method */
-       { "verifyhost",              srv_parse_verifyhost,         1, 1 }, /* require that SSL cert verifies for hostname */
+       { "crl-file",                srv_parse_crl_file,           1, 1, 0 }, /* set certificate revocation list file use on server cert verify */
+       { "crt",                     srv_parse_crt,                1, 1, 0 }, /* set client certificate */
+       { "force-sslv3",             srv_parse_tls_method_options, 0, 1, 0 }, /* force SSLv3 */
+       { "force-tlsv10",            srv_parse_tls_method_options, 0, 1, 0 }, /* force TLSv10 */
+       { "force-tlsv11",            srv_parse_tls_method_options, 0, 1, 0 }, /* force TLSv11 */
+       { "force-tlsv12",            srv_parse_tls_method_options, 0, 1, 0 }, /* force TLSv12 */
+       { "force-tlsv13",            srv_parse_tls_method_options, 0, 1, 0 }, /* force TLSv13 */
+       { "no-check-ssl",            srv_parse_no_check_ssl,       0, 1, 0 }, /* disable SSL for health checks */
+       { "no-send-proxy-v2-ssl",    srv_parse_no_send_proxy_ssl,  0, 1, 0 }, /* do not send PROXY protocol header v2 with SSL info */
+       { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn,   0, 1, 0 }, /* do not send PROXY protocol header v2 with CN */
+       { "no-ssl",                  srv_parse_no_ssl,             0, 1, 0 }, /* disable SSL processing */
+       { "no-ssl-reuse",            srv_parse_no_ssl_reuse,       0, 1, 0 }, /* disable session reuse */
+       { "no-sslv3",                srv_parse_tls_method_options, 0, 0, 0 }, /* disable SSLv3 */
+       { "no-tlsv10",               srv_parse_tls_method_options, 0, 0, 0 }, /* disable TLSv10 */
+       { "no-tlsv11",               srv_parse_tls_method_options, 0, 0, 0 }, /* disable TLSv11 */
+       { "no-tlsv12",               srv_parse_tls_method_options, 0, 0, 0 }, /* disable TLSv12 */
+       { "no-tlsv13",               srv_parse_tls_method_options, 0, 0, 0 }, /* disable TLSv13 */
+       { "no-tls-tickets",          srv_parse_no_tls_tickets,     0, 1, 0 }, /* disable session resumption tickets */
+       { "npn",                     srv_parse_npn,                1, 1, 0 }, /* Set NPN supported protocols */
+       { "send-proxy-v2-ssl",       srv_parse_send_proxy_ssl,     0, 1, 0 }, /* send PROXY protocol header v2 with SSL info */
+       { "send-proxy-v2-ssl-cn",    srv_parse_send_proxy_cn,      0, 1, 0 }, /* send PROXY protocol header v2 with CN */
+       { "sni",                     srv_parse_sni,                1, 1, 0 }, /* send SNI extension */
+       { "ssl",                     srv_parse_ssl,                0, 1, 0 }, /* enable SSL processing */
+       { "ssl-min-ver",             srv_parse_tls_method_minmax,  1, 1, 0 }, /* minimum version */
+       { "ssl-max-ver",             srv_parse_tls_method_minmax,  1, 1, 0 }, /* maximum version */
+       { "ssl-reuse",               srv_parse_ssl_reuse,          0, 1, 0 }, /* enable session reuse */
+       { "tls-tickets",             srv_parse_tls_tickets,        0, 1, 0 }, /* enable session resumption tickets */
+       { "verify",                  srv_parse_verify,             1, 1, 0 }, /* set SSL verify method */
+       { "verifyhost",              srv_parse_verifyhost,         1, 1, 0 }, /* require that SSL cert verifies for hostname */
        { NULL, NULL, 0, 0 },
 }};
 
index e7868e6bf26cec08138e5fbf83ca6343e04449fb..a15a110ef5489966974ed7eb110ca66d289b9c56 100644 (file)
@@ -282,7 +282,7 @@ INITCALL1(STG_REGISTER, bind_register_keywords, &bind_kws);
 
 static struct srv_kw_list srv_kws = { "TCP", { }, {
 #ifdef TCP_USER_TIMEOUT
-       { "tcp-ut",        srv_parse_tcp_ut,        1,  1 }, /* set TCP user timeout on server */
+       { "tcp-ut",        srv_parse_tcp_ut,        1,  1,  0 }, /* set TCP user timeout on server */
 #endif
        { NULL, NULL, 0 },
 }};
index 2642d584a6cb83ede4cac66a9d1cad2871fb16b4..c32e940c3a4d4b5e6db17e535aa0ee06a4339cb2 100644 (file)
@@ -2083,25 +2083,25 @@ static int srv_parse_check_port(char **args, int *cur_arg, struct proxy *curpx,
 }
 
 static struct srv_kw_list srv_kws = { "CHK", { }, {
-       { "addr",                srv_parse_addr,                1,  1 }, /* IP address to send health to or to probe from agent-check */
-       { "agent-addr",          srv_parse_agent_addr,          1,  1 }, /* Enable an auxiliary agent check */
-       { "agent-check",         srv_parse_agent_check,         0,  1 }, /* Enable agent checks */
-       { "agent-inter",         srv_parse_agent_inter,         1,  1 }, /* Set the interval between two agent checks */
-       { "agent-port",          srv_parse_agent_port,          1,  1 }, /* Set the TCP port used for agent checks. */
-       { "agent-send",          srv_parse_agent_send,          1,  1 }, /* Set string to send to agent. */
-       { "check",               srv_parse_check,               0,  1 }, /* Enable health checks */
-       { "check-proto",         srv_parse_check_proto,         1,  1 }, /* Set the mux protocol for health checks  */
-       { "check-send-proxy",    srv_parse_check_send_proxy,    0,  1 }, /* Enable PROXY protocol for health checks */
-       { "check-via-socks4",    srv_parse_check_via_socks4,    0,  1 }, /* Enable socks4 proxy for health checks */
-       { "no-agent-check",      srv_parse_no_agent_check,      0,  1 }, /* Do not enable any auxiliary agent check */
-       { "no-check",            srv_parse_no_check,            0,  1 }, /* Disable health checks */
-       { "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1 }, /* Disable PROXY protocol for health checks */
-       { "rise",                srv_parse_check_rise,          1,  1 }, /* Set rise value for health checks */
-       { "fall",                srv_parse_check_fall,          1,  1 }, /* Set fall value for health checks */
-       { "inter",               srv_parse_check_inter,         1,  1 }, /* Set inter value for health checks */
-       { "fastinter",           srv_parse_check_fastinter,     1,  1 }, /* Set fastinter value for health checks */
-       { "downinter",           srv_parse_check_downinter,     1,  1 }, /* Set downinter value for health checks */
-       { "port",                srv_parse_check_port,          1,  1 }, /* Set the TCP port used for health checks. */
+       { "addr",                srv_parse_addr,                1,  1,  0 }, /* IP address to send health to or to probe from agent-check */
+       { "agent-addr",          srv_parse_agent_addr,          1,  1,  0 }, /* Enable an auxiliary agent check */
+       { "agent-check",         srv_parse_agent_check,         0,  1,  0 }, /* Enable agent checks */
+       { "agent-inter",         srv_parse_agent_inter,         1,  1,  0 }, /* Set the interval between two agent checks */
+       { "agent-port",          srv_parse_agent_port,          1,  1,  0 }, /* Set the TCP port used for agent checks. */
+       { "agent-send",          srv_parse_agent_send,          1,  1,  0 }, /* Set string to send to agent. */
+       { "check",               srv_parse_check,               0,  1,  0 }, /* Enable health checks */
+       { "check-proto",         srv_parse_check_proto,         1,  1,  0 }, /* Set the mux protocol for health checks  */
+       { "check-send-proxy",    srv_parse_check_send_proxy,    0,  1,  0 }, /* Enable PROXY protocol for health checks */
+       { "check-via-socks4",    srv_parse_check_via_socks4,    0,  1,  0 }, /* Enable socks4 proxy for health checks */
+       { "no-agent-check",      srv_parse_no_agent_check,      0,  1,  0 }, /* Do not enable any auxiliary agent check */
+       { "no-check",            srv_parse_no_check,            0,  1,  0 }, /* Disable health checks */
+       { "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1,  0 }, /* Disable PROXY protocol for health checks */
+       { "rise",                srv_parse_check_rise,          1,  1,  0 }, /* Set rise value for health checks */
+       { "fall",                srv_parse_check_fall,          1,  1,  0 }, /* Set fall value for health checks */
+       { "inter",               srv_parse_check_inter,         1,  1,  0 }, /* Set inter value for health checks */
+       { "fastinter",           srv_parse_check_fastinter,     1,  1,  0 }, /* Set fastinter value for health checks */
+       { "downinter",           srv_parse_check_downinter,     1,  1,  0 }, /* Set downinter value for health checks */
+       { "port",                srv_parse_check_port,          1,  1,  0 }, /* Set the TCP port used for health checks. */
        { NULL, NULL, 0 },
 }};
 
index 3c26243f0c26a48e9bcbc7e7c37b267de0d5a95a..ec9e6e69112ab5febfff1c0702124bda39834c1a 100644 (file)
@@ -1626,48 +1626,48 @@ void srv_compute_all_admin_states(struct proxy *px)
  * Note: -1 as ->skip value means that the number of arguments are variable.
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
-       { "backup",              srv_parse_backup,              0,  1 }, /* Flag as backup server */
-       { "cookie",              srv_parse_cookie,              1,  1 }, /* Assign a cookie to the server */
-       { "disabled",            srv_parse_disabled,            0,  1 }, /* Start the server in 'disabled' state */
-       { "enabled",             srv_parse_enabled,             0,  1 }, /* Start the server in 'enabled' state */
-       { "error-limit",         srv_parse_error_limit,         1,  1 }, /* Configure the consecutive count of check failures to consider a server on error */
-       { "id",                  srv_parse_id,                  1,  0 }, /* set id# of server */
-       { "init-addr",           srv_parse_init_addr,           1,  1 }, /* */
-       { "log-proto",           srv_parse_log_proto,           1,  1 }, /* Set the protocol for event messages, only relevant in a ring section */
-       { "maxconn",             srv_parse_maxconn,             1,  1 }, /* Set the max number of concurrent connection */
-       { "maxqueue",            srv_parse_maxqueue,            1,  1 }, /* Set the max number of connection to put in queue */
-       { "max-reuse",           srv_parse_max_reuse,           1,  1 }, /* Set the max number of requests on a connection, -1 means unlimited */
-       { "minconn",             srv_parse_minconn,             1,  1 }, /* Enable a dynamic maxconn limit */
-       { "namespace",           srv_parse_namespace,           1,  1 }, /* Namespace the server socket belongs to (if supported) */
-       { "no-backup",           srv_parse_no_backup,           0,  1 }, /* Flag as non-backup server */
-       { "no-send-proxy",       srv_parse_no_send_proxy,       0,  1 }, /* Disable use of PROXY V1 protocol */
-       { "no-send-proxy-v2",    srv_parse_no_send_proxy_v2,    0,  1 }, /* Disable use of PROXY V2 protocol */
-       { "no-tfo",              srv_parse_no_tfo,              0,  1 }, /* Disable use of TCP Fast Open */
-       { "non-stick",           srv_parse_non_stick,           0,  1 }, /* Disable stick-table persistence */
-       { "observe",             srv_parse_observe,             1,  1 }, /* Enables health adjusting based on observing communication with the server */
-       { "on-error",            srv_parse_on_error,            1,  1 }, /* Configure the action on check failure */
-       { "on-marked-down",      srv_parse_on_marked_down,      1,  1 }, /* Configure the action when a server is marked down */
-       { "on-marked-up",        srv_parse_on_marked_up,        1,  1 }, /* Configure the action when a server is marked up */
-       { "pool-low-conn",       srv_parse_pool_low_conn,       1,  1 }, /* Set the min number of orphan idle connecbefore being allowed to pick from other threads */
-       { "pool-max-conn",       srv_parse_pool_max_conn,       1,  1 }, /* Set the max number of orphan idle connections, -1 means unlimited */
-       { "pool-purge-delay",    srv_parse_pool_purge_delay,    1,  1 }, /* Set the time before we destroy orphan idle connections, defaults to 1s */
-       { "proto",               srv_parse_proto,               1,  1 }, /* Set the proto to use for all outgoing connections */
-       { "proxy-v2-options",    srv_parse_proxy_v2_options,    1,  1 }, /* options for send-proxy-v2 */
-       { "redir",               srv_parse_redir,               1,  1 }, /* Enable redirection mode */
-       { "resolve-net",         srv_parse_resolve_net,         1,  1 }, /* Set the prefered network range for name resolution */
-       { "resolve-opts",        srv_parse_resolve_opts,        1,  1 }, /* Set options for name resolution */
-       { "resolve-prefer",      srv_parse_resolve_prefer,      1,  1 }, /* Set the prefered family for name resolution */
-       { "resolvers",           srv_parse_resolvers,           1,  1 }, /* Configure the resolver to use for name resolution */
-       { "send-proxy",          srv_parse_send_proxy,          0,  1 }, /* Enforce use of PROXY V1 protocol */
-       { "send-proxy-v2",       srv_parse_send_proxy_v2,       0,  1 }, /* Enforce use of PROXY V2 protocol */
-       { "slowstart",           srv_parse_slowstart,           1,  1 }, /* Set the warm-up timer for a previously failed server */
-       { "source",              srv_parse_source,             -1,  1 }, /* Set the source address to be used to connect to the server */
-       { "stick",               srv_parse_stick,               0,  1 }, /* Enable stick-table persistence */
-       { "tfo",                 srv_parse_tfo,                 0,  1 }, /* enable TCP Fast Open of server */
-       { "track",               srv_parse_track,               1,  1 }, /* Set the current state of the server, tracking another one */
-       { "socks4",              srv_parse_socks4,              1,  1 }, /* Set the socks4 proxy of the server*/
-       { "usesrc",              srv_parse_usesrc,              0,  1 }, /* safe-guard against usesrc without preceding <source> keyword */
-       { "weight",              srv_parse_weight,              1,  1 }, /* Set the load-balancing weight */
+       { "backup",              srv_parse_backup,              0,  1,  0 }, /* Flag as backup server */
+       { "cookie",              srv_parse_cookie,              1,  1,  0 }, /* Assign a cookie to the server */
+       { "disabled",            srv_parse_disabled,            0,  1,  0 }, /* Start the server in 'disabled' state */
+       { "enabled",             srv_parse_enabled,             0,  1,  0 }, /* Start the server in 'enabled' state */
+       { "error-limit",         srv_parse_error_limit,         1,  1,  0 }, /* Configure the consecutive count of check failures to consider a server on error */
+       { "id",                  srv_parse_id,                  1,  0,  0 }, /* set id# of server */
+       { "init-addr",           srv_parse_init_addr,           1,  1,  0 }, /* */
+       { "log-proto",           srv_parse_log_proto,           1,  1,  0 }, /* Set the protocol for event messages, only relevant in a ring section */
+       { "maxconn",             srv_parse_maxconn,             1,  1,  0 }, /* Set the max number of concurrent connection */
+       { "maxqueue",            srv_parse_maxqueue,            1,  1,  0 }, /* Set the max number of connection to put in queue */
+       { "max-reuse",           srv_parse_max_reuse,           1,  1,  0 }, /* Set the max number of requests on a connection, -1 means unlimited */
+       { "minconn",             srv_parse_minconn,             1,  1,  0 }, /* Enable a dynamic maxconn limit */
+       { "namespace",           srv_parse_namespace,           1,  1,  0 }, /* Namespace the server socket belongs to (if supported) */
+       { "no-backup",           srv_parse_no_backup,           0,  1,  0 }, /* Flag as non-backup server */
+       { "no-send-proxy",       srv_parse_no_send_proxy,       0,  1,  0 }, /* Disable use of PROXY V1 protocol */
+       { "no-send-proxy-v2",    srv_parse_no_send_proxy_v2,    0,  1,  0 }, /* Disable use of PROXY V2 protocol */
+       { "no-tfo",              srv_parse_no_tfo,              0,  1,  0 }, /* Disable use of TCP Fast Open */
+       { "non-stick",           srv_parse_non_stick,           0,  1,  0 }, /* Disable stick-table persistence */
+       { "observe",             srv_parse_observe,             1,  1,  0 }, /* Enables health adjusting based on observing communication with the server */
+       { "on-error",            srv_parse_on_error,            1,  1,  0 }, /* Configure the action on check failure */
+       { "on-marked-down",      srv_parse_on_marked_down,      1,  1,  0 }, /* Configure the action when a server is marked down */
+       { "on-marked-up",        srv_parse_on_marked_up,        1,  1,  0 }, /* Configure the action when a server is marked up */
+       { "pool-low-conn",       srv_parse_pool_low_conn,       1,  1,  0 }, /* Set the min number of orphan idle connecbefore being allowed to pick from other threads */
+       { "pool-max-conn",       srv_parse_pool_max_conn,       1,  1,  0 }, /* Set the max number of orphan idle connections, -1 means unlimited */
+       { "pool-purge-delay",    srv_parse_pool_purge_delay,    1,  1,  0 }, /* Set the time before we destroy orphan idle connections, defaults to 1s */
+       { "proto",               srv_parse_proto,               1,  1,  0 }, /* Set the proto to use for all outgoing connections */
+       { "proxy-v2-options",    srv_parse_proxy_v2_options,    1,  1,  0 }, /* options for send-proxy-v2 */
+       { "redir",               srv_parse_redir,               1,  1,  0 }, /* Enable redirection mode */
+       { "resolve-net",         srv_parse_resolve_net,         1,  1,  0 }, /* Set the prefered network range for name resolution */
+       { "resolve-opts",        srv_parse_resolve_opts,        1,  1,  0 }, /* Set options for name resolution */
+       { "resolve-prefer",      srv_parse_resolve_prefer,      1,  1,  0 }, /* Set the prefered family for name resolution */
+       { "resolvers",           srv_parse_resolvers,           1,  1,  0 }, /* Configure the resolver to use for name resolution */
+       { "send-proxy",          srv_parse_send_proxy,          0,  1,  0 }, /* Enforce use of PROXY V1 protocol */
+       { "send-proxy-v2",       srv_parse_send_proxy_v2,       0,  1,  0 }, /* Enforce use of PROXY V2 protocol */
+       { "slowstart",           srv_parse_slowstart,           1,  1,  0 }, /* Set the warm-up timer for a previously failed server */
+       { "source",              srv_parse_source,             -1,  1,  0 }, /* Set the source address to be used to connect to the server */
+       { "stick",               srv_parse_stick,               0,  1,  0 }, /* Enable stick-table persistence */
+       { "tfo",                 srv_parse_tfo,                 0,  1,  0 }, /* enable TCP Fast Open of server */
+       { "track",               srv_parse_track,               1,  1,  0 }, /* Set the current state of the server, tracking another one */
+       { "socks4",              srv_parse_socks4,              1,  1,  0 }, /* Set the socks4 proxy of the server*/
+       { "usesrc",              srv_parse_usesrc,              0,  1,  0 }, /* safe-guard against usesrc without preceding <source> keyword */
+       { "weight",              srv_parse_weight,              1,  1,  0 }, /* Set the load-balancing weight */
        { NULL, NULL, 0 },
 }};
 
@@ -2212,8 +2212,12 @@ void free_server(struct server *srv)
        srv = NULL;
 }
 
-/* This function is first intented to be used through parse_server to
- * initialize a new server on startup.
+/*
+ * Parse as much as possible such a range string argument: low[-high]
+ * Set <nb_low> and <nb_high> values so that they may be reused by this loop
+ * for(int i = nb_low; i <= nb_high; i++)... with nb_low >= 1.
+ * Fails if 'low' < 0 or 'high' is present and not higher than 'low'.
+ * Returns 0 if succeeded, -1 if not.
  */
 static int _srv_parse_tmpl_range(struct server *srv, const char *arg,
                                  int *nb_low, int *nb_high)
@@ -2399,6 +2403,9 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
                        newsrv->tmpl_info.nb_high = tmpl_range_high;
                }
 
+               if (parse_flags & SRV_PARSE_DYNAMIC)
+                       newsrv->flags |= SRV_F_DYNAMIC;
+
                /* Note: for a server template, its id is its prefix.
                 * This is a temporary id which will be used for server allocations to come
                 * after parsing.
@@ -2466,8 +2473,18 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
 
                (*cur_arg)++;
  skip_addr:
-               /* Copy default server settings to new server settings. */
-               srv_settings_cpy(newsrv, &curproxy->defsrv, 0);
+               if (!(parse_flags & SRV_PARSE_DYNAMIC)) {
+                       /* Copy default server settings to new server */
+                       srv_settings_cpy(newsrv, &curproxy->defsrv, 0);
+               } else {
+                       /* Initialize dynamic server weight to 1 */
+                       newsrv->uweight = newsrv->iweight = 1;
+
+                       /* A dynamic server is disabled on startup */
+                       newsrv->next_admin = SRV_ADMF_FMAINT;
+                       newsrv->next_state = SRV_ST_STOPPED;
+                       server_recalc_eweight(newsrv, 0);
+               }
                HA_SPIN_INIT(&newsrv->lock);
        }
        else {
@@ -2529,6 +2546,12 @@ static int _srv_parse_kw(struct server *srv, char **args, int *cur_arg,
                err_code = ERR_ALERT;
                goto out;
        }
+       else if ((parse_flags & SRV_PARSE_DYNAMIC) && !kw->dynamic_ok) {
+               memprintf(errmsg, "'%s' option is not accepted for dynamic server",
+                         args[*cur_arg]);
+               err_code |= ERR_ALERT;
+               goto out;
+       }
 
        err_code = kw->parse(args, cur_arg, curproxy, srv, errmsg);
 
@@ -2569,7 +2592,7 @@ static int _srv_parse_sni_expr_init(char **args, int cur_arg,
  */
 static int _srv_parse_finalize(char **args, int cur_arg,
                                struct server *srv, struct proxy *px,
-                               char **errmsg)
+                               int parse_flags, char **errmsg)
 {
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
        int ret;
@@ -2591,10 +2614,16 @@ static int _srv_parse_finalize(char **args, int cur_arg,
                return ret;
 #endif
 
-       if (srv->flags & SRV_F_BACKUP)
-               px->srv_bck++;
-       else
-               px->srv_act++;
+       /* A dynamic server is disabled on startup. It must not be counted as
+        * an active backend entry.
+        */
+       if (!(parse_flags & SRV_PARSE_DYNAMIC)) {
+               if (srv->flags & SRV_F_BACKUP)
+                       px->srv_bck++;
+               else
+                       px->srv_act++;
+       }
+
        srv_lb_commit_status(srv);
 
        return 0;
@@ -2660,7 +2689,7 @@ int parse_server(const char *file, int linenum, char **args,
        }
 
        if (!(parse_flags & SRV_PARSE_DEFAULT_SERVER)) {
-               err_code |= _srv_parse_finalize(args, cur_arg, newsrv, curproxy, &errmsg);
+               err_code |= _srv_parse_finalize(args, cur_arg, newsrv, curproxy, parse_flags, &errmsg);
                if (err_code) {
                        display_parser_err(file, linenum, args, cur_arg, err_code, &errmsg);
                        free(errmsg);