diff -Nru haproxy-1.5.12/CHANGELOG haproxy-1.5.13/CHANGELOG --- haproxy-1.5.12/CHANGELOG 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/CHANGELOG 2015-06-26 10:20:45.000000000 +0000 @@ -1,6 +1,37 @@ ChangeLog : =========== +2015/06/26 : 1.5.13 + - BUG/MINOR: check: fix tcpcheck error message + - CLEANUP: deinit: remove codes for cleaning p->block_rules + - DOC: Update doc about weight, act and bck fields in the statistics + - MINOR: ssl: add a destructor to free allocated SSL ressources + - BUG/MEDIUM: ssl: fix tune.ssl.default-dh-param value being overwritten + - MEDIUM: ssl: replace standards DH groups with custom ones + - BUG/MINOR: debug: display (null) in place of "meth" + - BUG/MINOR: cfgparse: fix typo in 'option httplog' error message + - BUG/MEDIUM: cfgparse: segfault when userlist is misused + - BUG/MEDIUM: stats: properly initialize the scope before dumping stats + - BUG/MEDIUM: http: don't forward client shutdown without NOLINGER except for tunnels + - CLEANUP: checks: fix double usage of cur / current_step in tcp-checks + - BUG/MEDIUM: checks: do not dereference head of a tcp-check at the end + - CLEANUP: checks: simplify the loop processing of tcp-checks + - BUG/MAJOR: checks: always check for end of list before proceeding + - BUG/MEDIUM: checks: do not dereference a list as a tcpcheck struct + - BUG/MEDIUM: peers: apply a random reconnection timeout + - BUG/MINOR: ssl: fix smp_fetch_ssl_fc_session_id + - MEDIUM: init: don't stop proxies in parent process when exiting + - MINOR: peers: store the pointer to the signal handler + - MEDIUM: peers: unregister peers that were never started + - MEDIUM: config: propagate the table's process list to the peers sections + - MEDIUM: init: stop any peers section not bound to the correct process + - MEDIUM: config: validate that peers sections are bound to exactly one process + - MAJOR: peers: allow peers section to be used with nbproc > 1 + - DOC: relax the peers restriction to single-process + - CLEANUP: config: fix misleading information in error message. + - MINOR: config: report the number of processes using a peers section in the error case + - BUG/MEDIUM: config: properly compute the default number of processes for a proxy + 2015/05/02 : 1.5.12 - BUG/MINOR: ssl: Display correct filename in error message - DOC: Fix L4TOUT typo in documentation diff -Nru haproxy-1.5.12/debian/changelog haproxy-1.5.13/debian/changelog --- haproxy-1.5.12/debian/changelog 2015-05-02 14:47:08.000000000 +0000 +++ haproxy-1.5.13/debian/changelog 2015-06-27 18:52:16.000000000 +0000 @@ -1,3 +1,22 @@ +haproxy (1.5.13-1) unstable; urgency=medium + + * New upstream stable release including the following fixes: + - MAJOR: peers: allow peers section to be used with nbproc > 1 + - BUG/MAJOR: checks: always check for end of list before proceeding + - MEDIUM: ssl: replace standards DH groups with custom ones + - BUG/MEDIUM: ssl: fix tune.ssl.default-dh-param value being overwritten + - BUG/MEDIUM: cfgparse: segfault when userlist is misused + - BUG/MEDIUM: stats: properly initialize the scope before dumping stats + - BUG/MEDIUM: http: don't forward client shutdown without NOLINGER + except for tunnels + - BUG/MEDIUM: checks: do not dereference head of a tcp-check at the end + - BUG/MEDIUM: checks: do not dereference a list as a tcpcheck struct + - BUG/MEDIUM: peers: apply a random reconnection timeout + - BUG/MEDIUM: config: properly compute the default number of processes + for a proxy + + -- Vincent Bernat Sat, 27 Jun 2015 20:52:07 +0200 + haproxy (1.5.12-1) unstable; urgency=medium * New upstream stable release including the following fixes: diff -Nru haproxy-1.5.12/doc/configuration.txt haproxy-1.5.13/doc/configuration.txt --- haproxy-1.5.12/doc/configuration.txt 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/doc/configuration.txt 2015-06-26 10:20:45.000000000 +0000 @@ -2,9 +2,9 @@ HAProxy Configuration Manual ---------------------- - version 1.5.12 + version 1.5.13 willy tarreau - 2015/05/02 + 2015/06/26 This document covers the configuration language as implemented in the version @@ -6911,7 +6911,8 @@ automatically learned from the local peer (old process) during a soft restart. - NOTE : peers can't be used in multi-process mode. + NOTE : each peers section may be referenced only by tables + belonging to the same unique process. defines the maximum duration of an entry in the table since it was last created, refreshed or matched. The expiration delay is @@ -13240,9 +13241,9 @@ server. The server value counts the number of times that server was switched away from. 17. status [LFBS]: status (UP/DOWN/NOLB/MAINT/MAINT(via)...) - 18. weight [..BS]: server weight (server), total weight (backend) - 19. act [..BS]: server is active (server), number of active servers (backend) - 20. bck [..BS]: server is backup (server), number of backup servers (backend) + 18. weight [..BS]: total weight (backend), server weight (server) + 19. act [..BS]: number of active servers (backend), server is active (server) + 20. bck [..BS]: number of backup servers (backend), server is backup (server) 21. chkfail [...S]: number of failed checks. (Only counts checks failed when the server is up.) 22. chkdown [..BS]: number of UP->DOWN transitions. The backend counter counts diff -Nru haproxy-1.5.12/examples/haproxy.spec haproxy-1.5.13/examples/haproxy.spec --- haproxy-1.5.12/examples/haproxy.spec 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/examples/haproxy.spec 2015-06-26 10:20:45.000000000 +0000 @@ -1,6 +1,6 @@ Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability environments Name: haproxy -Version: 1.5.12 +Version: 1.5.13 Release: 1 License: GPL Group: System Environment/Daemons @@ -76,6 +76,9 @@ %attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name} %changelog +* Fri Jun 26 2015 Willy Tarreau +- updated to 1.5.13 + * Sat May 2 2015 Willy Tarreau - updated to 1.5.12 diff -Nru haproxy-1.5.12/include/types/peers.h haproxy-1.5.13/include/types/peers.h --- haproxy-1.5.12/include/types/peers.h 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/include/types/peers.h 2015-06-26 10:20:45.000000000 +0000 @@ -56,6 +56,7 @@ struct shared_table { struct stktable *table; /* stick table to sync */ struct task *sync_task; /* main sync task */ + struct sig_handler *sighandler; /* signal handler */ struct peer_session *local_session; /* local peer session */ struct peer_session *sessions; /* peer sessions list */ unsigned int flags; /* current table resync state */ diff -Nru haproxy-1.5.12/README haproxy-1.5.13/README --- haproxy-1.5.12/README 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/README 2015-06-26 10:20:45.000000000 +0000 @@ -1,9 +1,9 @@ ---------------------- HAProxy how-to ---------------------- - version 1.5.12 + version 1.5.13 willy tarreau - 2015/05/02 + 2015/06/26 1) How to build it diff -Nru haproxy-1.5.12/src/cfgparse.c haproxy-1.5.13/src/cfgparse.c --- haproxy-1.5.12/src/cfgparse.c 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/src/cfgparse.c 2015-06-26 10:20:45.000000000 +0000 @@ -1841,6 +1841,7 @@ curpeers->peers_fe->options2 |= PR_O2_INDEPSTR | PR_O2_SMARTCON | PR_O2_SMARTACC; curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file); curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum; + curpeers->peers_fe->bind_proc = 0; /* will be filled by users */ bind_conf = bind_conf_alloc(&curpeers->peers_fe->conf.bind, file, linenum, args[2]); @@ -3792,7 +3793,7 @@ curproxy->options2 |= PR_O2_CLFLOG; logformat = clf_http_log_format; } else { - Alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[2]); + Alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]); err_code |= ERR_ALERT | ERR_FATAL; goto out; } @@ -4362,18 +4363,16 @@ const char *ptr_arg; int cur_arg; struct tcpcheck_rule *tcpcheck; - struct list *l; /* check if first rule is also a 'connect' action */ - l = (struct list *)&curproxy->tcpcheck_rules; - if (l->p != l->n) { - tcpcheck = (struct tcpcheck_rule *)l->n; - if (tcpcheck && tcpcheck->action != TCPCHK_ACT_CONNECT) { - Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n", - file, linenum); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } + tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list); + + if (&tcpcheck->list != &curproxy->tcpcheck_rules + && tcpcheck->action != TCPCHK_ACT_CONNECT) { + Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n", + file, linenum); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; } cur_arg = 2; @@ -5670,6 +5669,9 @@ goto out; } + if (!userlist) + goto out; + for (ag = userlist->groups; ag; ag = ag->next) if (!strcmp(ag->name, args[1])) { Warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n", @@ -5720,6 +5722,8 @@ err_code |= ERR_ALERT | ERR_FATAL; goto out; } + if (!userlist) + goto out; for (newuser = userlist->users; newuser; newuser = newuser->next) if (!strcmp(newuser->user, args[1])) { @@ -6166,12 +6170,6 @@ } } - if (global.nbproc > 1 && curproxy->table.peers.name) { - Alert("Proxy '%s': peers can't be used in multi-process mode (nbproc > 1).\n", - curproxy->id); - cfgerr++; - } - switch (curproxy->mode) { case PR_MODE_HEALTH: cfgerr += proxy_cfg_ensure_no_http(curproxy); @@ -7110,23 +7108,23 @@ list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) { unsigned long mask; - mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL; + mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc); curproxy->bind_proc |= mask; } if (!curproxy->bind_proc) - curproxy->bind_proc = ~0UL; + curproxy->bind_proc = nbits(global.nbproc); } if (global.stats_fe) { list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) { unsigned long mask; - mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL; + mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc); global.stats_fe->bind_proc |= mask; } if (!global.stats_fe->bind_proc) - global.stats_fe->bind_proc = ~0UL; + global.stats_fe->bind_proc = nbits(global.nbproc); } /* propagate bindings from frontends to backends. Don't do it if there @@ -7143,7 +7141,7 @@ for (curproxy = proxy; curproxy; curproxy = curproxy->next) { if (curproxy->bind_proc) continue; - curproxy->bind_proc = ~0UL; + curproxy->bind_proc = nbits(global.nbproc); } /*******************************************************/ @@ -7396,13 +7394,18 @@ global.last_checks |= cfg_opts2[optnum].checks; } + /* compute the required process bindings for the peers */ + for (curproxy = proxy; curproxy; curproxy = curproxy->next) + if (curproxy->table.peers.p) + curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc; + if (peers) { struct peers *curpeers = peers, **last; struct peer *p, *pb; - /* Remove all peers sections which don't have a valid listener. - * This can happen when a peers section is never referenced and - * does not contain a local peer. + /* Remove all peers sections which don't have a valid listener, + * which are not used by any table, or which are bound to more + * than one process. */ last = &peers; while (*last) { @@ -7418,6 +7421,18 @@ Warning("Removing incomplete section 'peers %s' (no peer named '%s').\n", curpeers->id, localpeer); } + else if (popcount(curpeers->peers_fe->bind_proc) != 1) { + /* either it's totally stopped or too much used */ + if (curpeers->peers_fe->bind_proc) { + Alert("Peers section '%s': peers referenced by sections " + "running in different processes (%d different ones). " + "Check global.nbproc and all tables' bind-process " + "settings.\n", curpeers->id, popcount(curpeers->peers_fe->bind_proc)); + cfgerr++; + } + stop_proxy(curpeers->peers_fe); + curpeers->peers_fe = NULL; + } else { last = &curpeers->next; continue; diff -Nru haproxy-1.5.12/src/checks.c haproxy-1.5.13/src/checks.c --- haproxy-1.5.12/src/checks.c 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/src/checks.c 2015-06-26 10:20:45.000000000 +0000 @@ -614,7 +614,7 @@ } else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_EXPECT) { if (check->last_started_step->string) - chunk_appendf(chk, " (string '%s')", check->last_started_step->string); + chunk_appendf(chk, " (expect string '%s')", check->last_started_step->string); else if (check->last_started_step->expect_regex) chunk_appendf(chk, " (expect regex)"); } @@ -1444,7 +1444,10 @@ quickack = check->type == 0 || check->type == PR_O2_TCPCHK_CHK; if (check->type == PR_O2_TCPCHK_CHK && !LIST_ISEMPTY(&s->proxy->tcpcheck_rules)) { - struct tcpcheck_rule *r = (struct tcpcheck_rule *) s->proxy->tcpcheck_rules.n; + struct tcpcheck_rule *r; + + r = LIST_NEXT(&s->proxy->tcpcheck_rules, struct tcpcheck_rule *, list); + /* if first step is a 'connect', then tcpcheck_main must run it */ if (r->action == TCPCHK_ACT_CONNECT) { tcpcheck_main(conn); @@ -1859,7 +1862,7 @@ static void tcpcheck_main(struct connection *conn) { char *contentptr; - struct tcpcheck_rule *cur, *next; + struct tcpcheck_rule *next; int done = 0, ret = 0; struct check *check = conn->owner; struct server *s = check->server; @@ -1916,25 +1919,23 @@ check->bo->o = 0; check->bi->p = check->bi->data; check->bi->i = 0; - cur = check->current_step = LIST_ELEM(head->n, struct tcpcheck_rule *, list); + check->current_step = LIST_ELEM(head->n, struct tcpcheck_rule *, list); t->expire = tick_add(now_ms, MS_TO_TICKS(check->inter)); if (s->proxy->timeout.check) t->expire = tick_add_ifset(now_ms, s->proxy->timeout.check); } - /* keep on processing step */ - else { - cur = check->current_step; - } /* It's only the rules which will enable send/recv */ __conn_data_stop_both(conn); while (1) { - /* we have to try to flush the output buffer before reading, at the end, - * or if we're about to send a string that does not fit in the remaining space. + /* We have to try to flush the output buffer before reading, at + * the end, or if we're about to send a string that does not fit + * in the remaining space. That explains why we break out of the + * loop after this control. */ if (check->bo->o && - (&cur->list == head || + (&check->current_step->list == head || check->current_step->action != TCPCHK_ACT_SEND || check->current_step->string_len >= buffer_total_space(check->bo))) { @@ -1944,19 +1945,18 @@ __conn_data_stop_both(conn); goto out_end_tcpcheck; } - goto out_need_io; + break; } } - /* did we reach the end ? If so, let's check that everything was sent */ - if (&cur->list == head) { - if (check->bo->o) - goto out_need_io; + if (&check->current_step->list == head) break; - } - /* have 'next' point to the next rule or NULL if we're on the last one */ - next = (struct tcpcheck_rule *)cur->list.n; + /* have 'next' point to the next rule or NULL if we're on the + * last one, connect() needs this. + */ + next = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); + if (&next->list == head) next = NULL; @@ -2058,8 +2058,10 @@ } /* allow next rule */ - cur = (struct tcpcheck_rule *)cur->list.n; - check->current_step = cur; + check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); + + if (&check->current_step->list == head) + break; /* don't do anything until the connection is established */ if (!(conn->flags & CO_FL_CONNECTED)) { @@ -2113,8 +2115,10 @@ *check->bo->p = '\0'; /* to make gdb output easier to read */ /* go to next rule and try to send */ - cur = (struct tcpcheck_rule *)cur->list.n; - check->current_step = cur; + check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); + + if (&check->current_step->list == head) + break; } /* end 'send' */ else if (check->current_step->action == TCPCHK_ACT_EXPECT) { if (unlikely(check->result == CHK_RES_FAILED)) @@ -2134,7 +2138,7 @@ } } else - goto out_need_io; + break; } /* mark the step as started */ @@ -2167,14 +2171,14 @@ goto out_end_tcpcheck; } - if (!done && (cur->string != NULL) && (check->bi->i < cur->string_len) ) + if (!done && (check->current_step->string != NULL) && (check->bi->i < check->current_step->string_len) ) continue; /* try to read more */ tcpcheck_expect: - if (cur->string != NULL) - ret = my_memmem(contentptr, check->bi->i, cur->string, cur->string_len) != NULL; - else if (cur->expect_regex != NULL) - ret = regex_exec(cur->expect_regex, contentptr); + if (check->current_step->string != NULL) + ret = my_memmem(contentptr, check->bi->i, check->current_step->string, check->current_step->string_len) != NULL; + else if (check->current_step->expect_regex != NULL) + ret = regex_exec(check->current_step->expect_regex, contentptr); if (!ret && !done) continue; /* try to read more */ @@ -2182,11 +2186,11 @@ /* matched */ if (ret) { /* matched but we did not want to => ERROR */ - if (cur->inverse) { + if (check->current_step->inverse) { /* we were looking for a string */ - if (cur->string != NULL) { + if (check->current_step->string != NULL) { chunk_printf(&trash, "TCPCHK matched unwanted content '%s' at step %d", - cur->string, tcpcheck_get_step_id(s)); + check->current_step->string, tcpcheck_get_step_id(s)); } else { /* we were looking for a regex */ @@ -2198,8 +2202,12 @@ } /* matched and was supposed to => OK, next step */ else { - cur = (struct tcpcheck_rule*)cur->list.n; - check->current_step = cur; + /* allow next rule */ + check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); + + if (&check->current_step->list == head) + break; + if (check->current_step->action == TCPCHK_ACT_EXPECT) goto tcpcheck_expect; __conn_data_stop_recv(conn); @@ -2208,9 +2216,13 @@ else { /* not matched */ /* not matched and was not supposed to => OK, next step */ - if (cur->inverse) { - cur = (struct tcpcheck_rule*)cur->list.n; - check->current_step = cur; + if (check->current_step->inverse) { + /* allow next rule */ + check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); + + if (&check->current_step->list == head) + break; + if (check->current_step->action == TCPCHK_ACT_EXPECT) goto tcpcheck_expect; __conn_data_stop_recv(conn); @@ -2218,9 +2230,9 @@ /* not matched but was supposed to => ERROR */ else { /* we were looking for a string */ - if (cur->string != NULL) { + if (check->current_step->string != NULL) { chunk_printf(&trash, "TCPCHK did not match content '%s' at step %d", - cur->string, tcpcheck_get_step_id(s)); + check->current_step->string, tcpcheck_get_step_id(s)); } else { /* we were looking for a regex */ @@ -2234,14 +2246,20 @@ } /* end expect */ } /* end loop over double chained step list */ - set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)"); - goto out_end_tcpcheck; + /* We're waiting for some I/O to complete, we've reached the end of the + * rules, or both. Do what we have to do, otherwise we're done. + */ + if (&check->current_step->list == head && !check->bo->o) { + set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)"); + goto out_end_tcpcheck; + } - out_need_io: + /* warning, current_step may now point to the head */ if (check->bo->o) __conn_data_want_send(conn); - if (check->current_step->action == TCPCHK_ACT_EXPECT) + if (&check->current_step->list != head && + check->current_step->action == TCPCHK_ACT_EXPECT) __conn_data_want_recv(conn); return; @@ -2257,7 +2275,6 @@ conn->flags |= CO_FL_ERROR; __conn_data_stop_both(conn); - return; } diff -Nru haproxy-1.5.12/src/dumpstats.c haproxy-1.5.13/src/dumpstats.c --- haproxy-1.5.12/src/dumpstats.c 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/src/dumpstats.c 2015-06-26 10:20:45.000000000 +0000 @@ -1109,6 +1109,8 @@ arg++; } + appctx->ctx.stats.scope_str = 0; + appctx->ctx.stats.scope_len = 0; appctx->ctx.stats.flags = 0; if (strcmp(args[0], "show") == 0) { if (strcmp(args[1], "stat") == 0) { diff -Nru haproxy-1.5.12/src/haproxy.c haproxy-1.5.13/src/haproxy.c --- haproxy-1.5.12/src/haproxy.c 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/src/haproxy.c 2015-06-26 10:20:45.000000000 +0000 @@ -216,7 +216,7 @@ void display_version() { printf("HA-Proxy version " HAPROXY_VERSION " " HAPROXY_DATE"\n"); - printf("Copyright 2000-2015 Willy Tarreau \n\n"); + printf("Copyright 2000-2015 Willy Tarreau \n\n"); } void display_build_opts() @@ -1020,12 +1020,6 @@ free(cwl); } - list_for_each_entry_safe(cond, condb, &p->block_rules, list) { - LIST_DEL(&cond->list); - prune_acl_cond(cond); - free(cond); - } - list_for_each_entry_safe(cond, condb, &p->mon_fail_cond, list) { LIST_DEL(&cond->list); prune_acl_cond(cond); @@ -1554,6 +1548,7 @@ if (global.mode & (MODE_DAEMON | MODE_SYSTEMD)) { struct proxy *px; + struct peers *curpeers; int ret = 0; int *children = calloc(global.nbproc, sizeof(int)); int proc; @@ -1594,6 +1589,15 @@ free(global.chroot); global.chroot = NULL; free(global.pidfile); global.pidfile = NULL; + if (proc == global.nbproc) { + if (global.mode & MODE_SYSTEMD) { + protocol_unbind_all(); + for (proc = 0; proc < global.nbproc; proc++) + while (waitpid(children[proc], NULL, 0) == -1 && errno == EINTR); + } + exit(0); /* parent must leave */ + } + /* we might have to unbind some proxies from some processes */ px = proxy; while (px != NULL) { @@ -1604,13 +1608,17 @@ px = px->next; } - if (proc == global.nbproc) { - if (global.mode & MODE_SYSTEMD) { - protocol_unbind_all(); - for (proc = 0; proc < global.nbproc; proc++) - while (waitpid(children[proc], NULL, 0) == -1 && errno == EINTR); - } - exit(0); /* parent must leave */ + /* we might have to unbind some peers sections from some processes */ + for (curpeers = peers; curpeers; curpeers = curpeers->next) { + if (!curpeers->peers_fe) + continue; + + if (curpeers->peers_fe->bind_proc & (1UL << proc)) + continue; + + stop_proxy(curpeers->peers_fe); + /* disable this peer section so that it kills itself */ + curpeers->peers_fe = NULL; } free(children); diff -Nru haproxy-1.5.12/src/peers.c haproxy-1.5.13/src/peers.c --- haproxy-1.5.12/src/peers.c 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/src/peers.c 2015-06-26 10:20:45.000000000 +0000 @@ -1063,6 +1063,7 @@ { struct stream_interface *oldsi = NULL; struct appctx *appctx = NULL; + struct peer_session *ps; int i; for (i = 0; i <= 1; i++) { @@ -1079,6 +1080,14 @@ if (!appctx) return; + ps = (struct peer_session *)appctx->ctx.peers.ptr; + /* we're killing a connection, we must apply a random delay before + * retrying otherwise the other end will do the same and we can loop + * for a while. + */ + if (ps) + ps->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + random() % 2000)); + /* call release to reinit resync states if needed */ peer_session_release(oldsi); appctx->st0 = PEER_SESS_ST_END; @@ -1328,6 +1337,15 @@ task->expire = TICK_ETERNITY; + if (!st->sessions->peer->peers->peers_fe) { + /* this one was never started, kill it */ + signal_unregister_handler(st->sighandler); + st->table->sync_task = NULL; + task_delete(st->sync_task); + task_free(st->sync_task); + return NULL; + } + if (!stopping) { /* Normal case (not soft stop)*/ if (((st->flags & SHTABLE_RESYNC_STATEMASK) == SHTABLE_RESYNC_FROMLOCAL) && @@ -1352,8 +1370,8 @@ if (!ps->session) { /* no active session */ if (ps->statuscode == 0 || - ps->statuscode == PEER_SESS_SC_SUCCESSCODE || ((ps->statuscode == PEER_SESS_SC_CONNECTCODE || + ps->statuscode == PEER_SESS_SC_SUCCESSCODE || ps->statuscode == PEER_SESS_SC_CONNECTEDCODE) && tick_is_expired(ps->reconnect, now_ms))) { /* connection never tried @@ -1364,8 +1382,7 @@ /* retry a connect */ ps->session = peer_session_create(ps->peer, ps); } - else if (ps->statuscode == PEER_SESS_SC_CONNECTCODE || - ps->statuscode == PEER_SESS_SC_CONNECTEDCODE) { + else if (!tick_is_expired(ps->reconnect, now_ms)) { /* If previous session failed during connection * but reconnection timer is not expired */ @@ -1516,8 +1533,8 @@ st->sync_task->process = process_peer_sync; st->sync_task->expire = TICK_ETERNITY; st->sync_task->context = (void *)st; - table->sync_task =st->sync_task; - signal_register_task(0, table->sync_task, 0); + table->sync_task = st->sync_task; + st->sighandler = signal_register_task(0, table->sync_task, 0); task_wakeup(st->sync_task, TASK_WOKEN_INIT); } diff -Nru haproxy-1.5.12/src/proto_http.c haproxy-1.5.13/src/proto_http.c --- haproxy-1.5.12/src/proto_http.c 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/src/proto_http.c 2015-06-26 10:20:45.000000000 +0000 @@ -5452,9 +5452,10 @@ msg->sov -= msg->next; msg->next = 0; - /* for keep-alive we don't want to forward closes on DONE */ - if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL || - (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) + /* we don't want to forward closes on DONE except in + * tunnel mode. + */ + if ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) channel_dont_close(req); if (http_resync_states(s)) { /* some state changes occurred, maybe the analyser @@ -5478,10 +5479,15 @@ * want to monitor the client's connection and forward * any shutdown notification to the server, which will * decide whether to close or to go on processing the - * request. + * request. We only do that in tunnel mode, and not in + * other modes since it can be abused to exhaust source + * ports. */ if (s->be->options & PR_O_ABRT_CLOSE) { channel_auto_read(req); + if ((req->flags & (CF_SHUTR|CF_READ_NULL)) && + ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN)) + s->si[1].flags |= SI_FL_NOLINGER; channel_auto_close(req); } else if (s->txn.meth == HTTP_METH_POST) { diff -Nru haproxy-1.5.12/src/sample.c haproxy-1.5.13/src/sample.c --- haproxy-1.5.12/src/sample.c 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/src/sample.c 2015-06-26 10:20:45.000000000 +0000 @@ -40,6 +40,7 @@ [SMP_T_IPV6] = "ipv6", [SMP_T_STR] = "str", [SMP_T_BIN] = "bin", + [SMP_T_METH] = "meth", }; /* static sample used in sample_process() when

is NULL */ diff -Nru haproxy-1.5.12/src/ssl_sock.c haproxy-1.5.13/src/ssl_sock.c --- haproxy-1.5.12/src/ssl_sock.c 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/src/ssl_sock.c 2015-06-26 10:20:45.000000000 +0000 @@ -47,6 +47,9 @@ #ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB #include #endif +#ifndef OPENSSL_NO_DH +#include +#endif #include #include @@ -107,10 +110,10 @@ int totalsslconns = 0; #ifndef OPENSSL_NO_DH +static int ssl_dh_ptr_index = -1; static DH *local_dh_1024 = NULL; static DH *local_dh_2048 = NULL; static DH *local_dh_4096 = NULL; -static DH *local_dh_8192 = NULL; #endif /* OPENSSL_NO_DH */ #ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB @@ -762,32 +765,28 @@ static DH * ssl_get_dh_1024(void) { -#if OPENSSL_VERSION_NUMBER < 0x0090801fL - static const unsigned char rfc_2409_prime_1024[] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, - 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, - 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, - 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, - 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, - 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, - 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, - 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, - 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, - 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - }; -#endif + static unsigned char dh1024_p[]={ + 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7, + 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3, + 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9, + 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96, + 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D, + 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17, + 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B, + 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94, + 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC, + 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E, + 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B, + }; + static unsigned char dh1024_g[]={ + 0x02, + }; + DH *dh = DH_new(); if (dh) { -#if OPENSSL_VERSION_NUMBER >= 0x0090801fL - dh->p = get_rfc2409_prime_1024(NULL); -#else - dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL); -#endif - /* See RFC 2409, Section 6 "Oakley Groups" - for the reason why 2 is used as generator. - */ - BN_dec2bn(&dh->g, "2"); + dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL); + dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL); + if (!dh->p || !dh->g) { DH_free(dh); dh = NULL; @@ -798,43 +797,39 @@ static DH *ssl_get_dh_2048(void) { -#if OPENSSL_VERSION_NUMBER < 0x0090801fL - static const unsigned char rfc_3526_prime_2048[] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, - 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, - 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, - 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, - 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, - 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, - 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, - 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, - 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, - 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, - 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, - 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, - 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, - 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, - 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, - 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B, - 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2, - 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9, - 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C, - 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10, - 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - }; -#endif + static unsigned char dh2048_p[]={ + 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59, + 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24, + 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66, + 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10, + 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B, + 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23, + 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC, + 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E, + 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77, + 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A, + 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66, + 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74, + 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E, + 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40, + 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93, + 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43, + 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88, + 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1, + 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17, + 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB, + 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41, + 0xB7,0x1F,0x77,0xF3, + }; + static unsigned char dh2048_g[]={ + 0x02, + }; + DH *dh = DH_new(); if (dh) { -#if OPENSSL_VERSION_NUMBER >= 0x0090801fL - dh->p = get_rfc3526_prime_2048(NULL); -#else - dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL); -#endif - /* See RFC 3526, Section 3 "2048-bit MODP Group" - for the reason why 2 is used as generator. - */ - BN_dec2bn(&dh->g, "2"); + dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL); + dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL); + if (!dh->p || !dh->g) { DH_free(dh); dh = NULL; @@ -845,175 +840,60 @@ static DH *ssl_get_dh_4096(void) { -#if OPENSSL_VERSION_NUMBER < 0x0090801fL - static const unsigned char rfc_3526_prime_4096[] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, - 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, - 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, - 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, - 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, - 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, - 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, - 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, - 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, - 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, - 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, - 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, - 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, - 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, - 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, - 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B, - 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2, - 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9, - 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C, - 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10, - 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D, - 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64, - 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57, - 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7, - 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0, - 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B, - 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73, - 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C, - 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0, - 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31, - 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20, - 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7, - 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18, - 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA, - 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB, - 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6, - 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F, - 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED, - 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76, - 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9, - 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC, - 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + static unsigned char dh4096_p[]={ + 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11, + 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68, + 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD, + 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B, + 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B, + 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47, + 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15, + 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35, + 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79, + 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3, + 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC, + 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52, + 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C, + 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A, + 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41, + 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55, + 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52, + 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66, + 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E, + 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47, + 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2, + 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73, + 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13, + 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10, + 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14, + 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD, + 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E, + 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48, + 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01, + 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60, + 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC, + 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41, + 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8, + 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B, + 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23, + 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE, + 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD, + 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03, + 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08, + 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5, + 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F, + 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67, + 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B, }; -#endif - DH *dh = DH_new(); - if (dh) { -#if OPENSSL_VERSION_NUMBER >= 0x0090801fL - dh->p = get_rfc3526_prime_4096(NULL); -#else - dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL); -#endif - /* See RFC 3526, Section 5 "4096-bit MODP Group" - for the reason why 2 is used as generator. - */ - BN_dec2bn(&dh->g, "2"); - if (!dh->p || !dh->g) { - DH_free(dh); - dh = NULL; - } - } - return dh; -} + static unsigned char dh4096_g[]={ + 0x02, + }; -static DH *ssl_get_dh_8192(void) -{ -#if OPENSSL_VERSION_NUMBER < 0x0090801fL - static const unsigned char rfc_3526_prime_8192[] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, - 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, - 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, - 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, - 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, - 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, - 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, - 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, - 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, - 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, - 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, - 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, - 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, - 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, - 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, - 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B, - 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2, - 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9, - 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C, - 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10, - 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D, - 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64, - 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57, - 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7, - 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0, - 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B, - 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73, - 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C, - 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0, - 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31, - 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20, - 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7, - 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18, - 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA, - 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB, - 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6, - 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F, - 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED, - 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76, - 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9, - 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC, - 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92, - 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2, - 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD, - 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F, - 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31, - 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB, - 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B, - 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51, - 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF, - 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15, - 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6, - 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31, - 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3, - 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7, - 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA, - 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2, - 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28, - 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D, - 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C, - 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7, - 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE, - 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E, - 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4, - 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0, - 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00, - 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93, - 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68, - 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB, - 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9, - 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8, - 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B, - 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F, - 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A, - 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8, - 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36, - 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5, - 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1, - 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3, - 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92, - 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E, - 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47, - 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2, - 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71, - 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - }; -#endif DH *dh = DH_new(); if (dh) { -#if OPENSSL_VERSION_NUMBER >= 0x0090801fL - dh->p = get_rfc3526_prime_8192(NULL); -#else - dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL); -#endif - /* See RFC 3526, Section 7 "8192-bit MODP Group" - for the reason why 2 is used as generator. - */ - BN_dec2bn(&dh->g, "2"); + dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL); + dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL); + if (!dh->p || !dh->g) { DH_free(dh); dh = NULL; @@ -1041,10 +921,7 @@ keylen = global.tune.ssl_default_dh_param; } - if (keylen >= 8192) { - dh = local_dh_8192; - } - else if (keylen >= 4096) { + if (keylen >= 4096) { dh = local_dh_4096; } else if (keylen >= 2048) { @@ -1076,10 +953,12 @@ if (dh) { ret = 1; SSL_CTX_set_tmp_dh(ctx, dh); - /* Setting ssl default dh param to the size of the static DH params - found in the file. This way we know that there is no use - complaining later about ssl-default-dh-param not being set. */ - global.tune.ssl_default_dh_param = DH_size(dh) * 8; + + if (ssl_dh_ptr_index >= 0) { + /* store a pointer to the DH params to avoid complaining about + ssl-default-dh-param not being set for this SSL_CTX */ + SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh); + } } else { /* Clear openssl global errors stack */ @@ -1274,6 +1153,12 @@ * the tree, so it will be discovered and cleaned in time. */ #ifndef OPENSSL_NO_DH + /* store a NULL pointer to indicate we have not yet loaded + a custom DH param file */ + if (ssl_dh_ptr_index >= 0) { + SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL); + } + ret = ssl_sock_load_dh_params(ctx, path); if (ret < 0) { if (err) @@ -1593,7 +1478,9 @@ /* If tune.ssl.default-dh-param has not been set and no static DH params were in the certificate file. */ - if (global.tune.ssl_default_dh_param == 0) { + if (global.tune.ssl_default_dh_param == 0 && + (ssl_dh_ptr_index == -1 || + SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) { ciphers = ctx->cipher_list; if (ciphers) { @@ -1629,10 +1516,6 @@ if (local_dh_4096 == NULL) { local_dh_4096 = ssl_get_dh_4096(); } - if (global.tune.ssl_default_dh_param >= 8192 && - local_dh_8192 == NULL) { - local_dh_8192 = ssl_get_dh_8192(); - } } } } @@ -3657,7 +3540,7 @@ return 0; smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len); - if (!smp->data.str.str || !&smp->data.str.len) + if (!smp->data.str.str || !smp->data.str.len) return 0; return 1; @@ -4715,8 +4598,43 @@ bind_register_keywords(&bind_kws); srv_register_keywords(&srv_kws); cfg_register_keywords(&cfg_kws); + +#ifndef OPENSSL_NO_DH + ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); +#endif } +__attribute__((destructor)) +static void __ssl_sock_deinit(void) +{ +#ifndef OPENSSL_NO_DH + if (local_dh_1024) { + DH_free(local_dh_1024); + local_dh_1024 = NULL; + } + + if (local_dh_2048) { + DH_free(local_dh_2048); + local_dh_2048 = NULL; + } + + if (local_dh_4096) { + DH_free(local_dh_4096); + local_dh_4096 = NULL; + } +#endif + + ERR_remove_state(0); + ERR_free_strings(); + + EVP_cleanup(); + +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + CRYPTO_cleanup_all_ex_data(); +#endif +} + + /* * Local variables: * c-indent-level: 8 diff -Nru haproxy-1.5.12/VERDATE haproxy-1.5.13/VERDATE --- haproxy-1.5.12/VERDATE 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/VERDATE 2015-06-26 10:20:45.000000000 +0000 @@ -1,2 +1,2 @@ $Format:%ci$ -2015/05/02 +2015/06/23 diff -Nru haproxy-1.5.12/VERSION haproxy-1.5.13/VERSION --- haproxy-1.5.12/VERSION 2015-05-02 13:20:38.000000000 +0000 +++ haproxy-1.5.13/VERSION 2015-06-26 10:20:45.000000000 +0000 @@ -1 +1 @@ -1.5.12 +1.5.13