Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 1 | /* |
| 2 | * HTTP protocol analyzer |
| 3 | * |
Willy Tarreau | f68a15a | 2011-01-06 16:53:21 +0100 | [diff] [blame] | 4 | * Copyright 2000-2011 Willy Tarreau <w@1wt.eu> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License |
| 8 | * as published by the Free Software Foundation; either version |
| 9 | * 2 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | */ |
| 12 | |
| 13 | #include <ctype.h> |
| 14 | #include <errno.h> |
| 15 | #include <fcntl.h> |
| 16 | #include <stdio.h> |
| 17 | #include <stdlib.h> |
| 18 | #include <string.h> |
| 19 | #include <syslog.h> |
Willy Tarreau | 4225058 | 2007-04-01 01:30:43 +0200 | [diff] [blame] | 20 | #include <time.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 21 | |
| 22 | #include <sys/socket.h> |
| 23 | #include <sys/stat.h> |
| 24 | #include <sys/types.h> |
| 25 | |
Krzysztof Piotr Oledzki | f9423ae | 2010-01-29 19:26:18 +0100 | [diff] [blame] | 26 | #include <common/base64.h> |
Frédéric Lécaille | a41d531 | 2018-01-29 12:05:07 +0100 | [diff] [blame] | 27 | #include <common/cfgparse.h> |
Willy Tarreau | c7e4238 | 2012-08-24 19:22:53 +0200 | [diff] [blame] | 28 | #include <common/chunk.h> |
Willy Tarreau | 2dd0d47 | 2006-06-29 17:53:05 +0200 | [diff] [blame] | 29 | #include <common/compat.h> |
| 30 | #include <common/config.h> |
Willy Tarreau | a4cd1f5 | 2006-12-16 19:57:26 +0100 | [diff] [blame] | 31 | #include <common/debug.h> |
Willy Tarreau | afba57a | 2018-12-11 13:44:24 +0100 | [diff] [blame] | 32 | #include <common/h1.h> |
Willy Tarreau | 2dd0d47 | 2006-06-29 17:53:05 +0200 | [diff] [blame] | 33 | #include <common/memory.h> |
| 34 | #include <common/mini-clist.h> |
| 35 | #include <common/standard.h> |
Willy Tarreau | 0c303ee | 2008-07-07 00:09:58 +0200 | [diff] [blame] | 36 | #include <common/ticks.h> |
Willy Tarreau | 2dd0d47 | 2006-06-29 17:53:05 +0200 | [diff] [blame] | 37 | #include <common/time.h> |
| 38 | #include <common/uri_auth.h> |
| 39 | #include <common/version.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 40 | |
| 41 | #include <types/capture.h> |
Willy Tarreau | 12207b3 | 2016-11-22 19:48:51 +0100 | [diff] [blame] | 42 | #include <types/cli.h> |
Christopher Faulet | d7c9196 | 2015-04-30 11:48:27 +0200 | [diff] [blame] | 43 | #include <types/filters.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 44 | #include <types/global.h> |
William Lallemand | 9ed6203 | 2016-11-21 17:49:11 +0100 | [diff] [blame] | 45 | #include <types/stats.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 46 | |
Willy Tarreau | 8797c06 | 2007-05-07 00:55:35 +0200 | [diff] [blame] | 47 | #include <proto/acl.h> |
Thierry FOURNIER | 322a124 | 2015-08-19 09:07:47 +0200 | [diff] [blame] | 48 | #include <proto/action.h> |
Willy Tarreau | 61612d4 | 2012-04-19 18:42:05 +0200 | [diff] [blame] | 49 | #include <proto/arg.h> |
Krzysztof Piotr Oledzki | f9423ae | 2010-01-29 19:26:18 +0100 | [diff] [blame] | 50 | #include <proto/auth.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 51 | #include <proto/backend.h> |
Willy Tarreau | c7e4238 | 2012-08-24 19:22:53 +0200 | [diff] [blame] | 52 | #include <proto/channel.h> |
Krzysztof Piotr Oledzki | 97f07b8 | 2009-12-15 22:31:24 +0100 | [diff] [blame] | 53 | #include <proto/checks.h> |
Willy Tarreau | 12207b3 | 2016-11-22 19:48:51 +0100 | [diff] [blame] | 54 | #include <proto/cli.h> |
William Lallemand | 82fe75c | 2012-10-23 10:25:10 +0200 | [diff] [blame] | 55 | #include <proto/compression.h> |
Baptiste Assmann | 333939c | 2019-01-21 08:34:50 +0100 | [diff] [blame] | 56 | #include <proto/dns.h> |
William Lallemand | 9ed6203 | 2016-11-21 17:49:11 +0100 | [diff] [blame] | 57 | #include <proto/stats.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 58 | #include <proto/fd.h> |
Christopher Faulet | d7c9196 | 2015-04-30 11:48:27 +0200 | [diff] [blame] | 59 | #include <proto/filters.h> |
Willy Tarreau | 03fa5df | 2010-05-24 21:02:37 +0200 | [diff] [blame] | 60 | #include <proto/frontend.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 61 | #include <proto/log.h> |
Patrick Hemmer | e3faf02 | 2018-08-22 10:02:00 -0400 | [diff] [blame] | 62 | #include <proto/hlua.h> |
Thierry FOURNIER | ed66c29 | 2013-11-28 11:05:19 +0100 | [diff] [blame] | 63 | #include <proto/pattern.h> |
Willy Tarreau | b686644 | 2008-07-14 23:54:42 +0200 | [diff] [blame] | 64 | #include <proto/proto_tcp.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 65 | #include <proto/proto_http.h> |
Willy Tarreau | 7f062c4 | 2009-03-05 18:43:00 +0100 | [diff] [blame] | 66 | #include <proto/proxy.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 67 | #include <proto/queue.h> |
Willy Tarreau | cd3b094 | 2012-04-27 21:52:18 +0200 | [diff] [blame] | 68 | #include <proto/sample.h> |
Willy Tarreau | 7f062c4 | 2009-03-05 18:43:00 +0100 | [diff] [blame] | 69 | #include <proto/server.h> |
Olivier Houchard | 985f139 | 2018-11-30 17:31:52 +0100 | [diff] [blame] | 70 | #include <proto/session.h> |
Willy Tarreau | 87b0966 | 2015-04-03 00:22:06 +0200 | [diff] [blame] | 71 | #include <proto/stream.h> |
Willy Tarreau | cff6411 | 2008-11-03 06:26:53 +0100 | [diff] [blame] | 72 | #include <proto/stream_interface.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 73 | #include <proto/task.h> |
Baptiste Assmann | fabcbe0 | 2014-04-24 22:16:59 +0200 | [diff] [blame] | 74 | #include <proto/pattern.h> |
Thierry FOURNIER | 4834bc7 | 2015-06-06 19:29:07 +0200 | [diff] [blame] | 75 | #include <proto/vars.h> |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 76 | |
Christopher Faulet | 711ed6a | 2019-07-16 14:16:10 +0200 | [diff] [blame] | 77 | DECLARE_POOL(pool_head_http_txn, "http_txn", sizeof(struct http_txn)); |
| 78 | DECLARE_POOL(pool_head_uniqueid, "uniqueid", UNIQUEID_LEN); |
Willy Tarreau | e92693a | 2012-09-24 21:13:39 +0200 | [diff] [blame] | 79 | |
Christopher Faulet | 711ed6a | 2019-07-16 14:16:10 +0200 | [diff] [blame] | 80 | struct pool_head *pool_head_requri = NULL; |
| 81 | struct pool_head *pool_head_capture = NULL; |
Willy Tarreau | 58f10d7 | 2006-12-04 02:26:12 +0100 | [diff] [blame] | 82 | |
Willy Tarreau | eee5b51 | 2015-04-03 23:46:31 +0200 | [diff] [blame] | 83 | |
| 84 | /* Allocate a new HTTP transaction for stream <s> unless there is one already. |
Christopher Faulet | 711ed6a | 2019-07-16 14:16:10 +0200 | [diff] [blame] | 85 | * In case of allocation failure, everything allocated is freed and NULL is |
| 86 | * returned. Otherwise the new transaction is assigned to the stream and |
| 87 | * returned. |
Willy Tarreau | eee5b51 | 2015-04-03 23:46:31 +0200 | [diff] [blame] | 88 | */ |
| 89 | struct http_txn *http_alloc_txn(struct stream *s) |
| 90 | { |
| 91 | struct http_txn *txn = s->txn; |
| 92 | |
| 93 | if (txn) |
| 94 | return txn; |
| 95 | |
Willy Tarreau | bafbe01 | 2017-11-24 17:34:44 +0100 | [diff] [blame] | 96 | txn = pool_alloc(pool_head_http_txn); |
Willy Tarreau | eee5b51 | 2015-04-03 23:46:31 +0200 | [diff] [blame] | 97 | if (!txn) |
| 98 | return txn; |
| 99 | |
Willy Tarreau | eee5b51 | 2015-04-03 23:46:31 +0200 | [diff] [blame] | 100 | s->txn = txn; |
| 101 | return txn; |
| 102 | } |
| 103 | |
Thierry FOURNIER | fd50f0b | 2015-09-25 18:53:18 +0200 | [diff] [blame] | 104 | void http_txn_reset_req(struct http_txn *txn) |
| 105 | { |
| 106 | txn->req.flags = 0; |
Thierry FOURNIER | fd50f0b | 2015-09-25 18:53:18 +0200 | [diff] [blame] | 107 | txn->req.msg_state = HTTP_MSG_RQBEFORE; /* at the very beginning of the request */ |
| 108 | } |
| 109 | |
| 110 | void http_txn_reset_res(struct http_txn *txn) |
| 111 | { |
| 112 | txn->rsp.flags = 0; |
Thierry FOURNIER | fd50f0b | 2015-09-25 18:53:18 +0200 | [diff] [blame] | 113 | txn->rsp.msg_state = HTTP_MSG_RPBEFORE; /* at the very beginning of the response */ |
| 114 | } |
| 115 | |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 116 | /* |
Willy Tarreau | 87b0966 | 2015-04-03 00:22:06 +0200 | [diff] [blame] | 117 | * Initialize a new HTTP transaction for stream <s>. It is assumed that all |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 118 | * the required fields are properly allocated and that we only need to (re)init |
| 119 | * them. This should be used before processing any new request. |
| 120 | */ |
Willy Tarreau | 87b0966 | 2015-04-03 00:22:06 +0200 | [diff] [blame] | 121 | void http_init_txn(struct stream *s) |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 122 | { |
Willy Tarreau | eee5b51 | 2015-04-03 23:46:31 +0200 | [diff] [blame] | 123 | struct http_txn *txn = s->txn; |
Christopher Faulet | f2824e6 | 2018-10-01 12:12:37 +0200 | [diff] [blame] | 124 | struct conn_stream *cs = objt_cs(s->si[0].end); |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 125 | |
Christopher Faulet | f2824e6 | 2018-10-01 12:12:37 +0200 | [diff] [blame] | 126 | txn->flags = ((cs && cs->flags & CS_FL_NOT_FIRST) |
| 127 | ? (TX_NOT_FIRST|TX_WAIT_NEXT_RQ) |
| 128 | : 0); |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 129 | txn->status = -1; |
Willy Tarreau | c9036c0 | 2019-01-11 19:38:25 +0100 | [diff] [blame] | 130 | *(unsigned int *)txn->cache_hash = 0; |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 131 | |
Willy Tarreau | f64d141 | 2010-10-07 20:06:11 +0200 | [diff] [blame] | 132 | txn->cookie_first_date = 0; |
| 133 | txn->cookie_last_date = 0; |
| 134 | |
Willy Tarreau | eee5b51 | 2015-04-03 23:46:31 +0200 | [diff] [blame] | 135 | txn->srv_cookie = NULL; |
| 136 | txn->cli_cookie = NULL; |
| 137 | txn->uri = NULL; |
| 138 | |
Thierry FOURNIER | fd50f0b | 2015-09-25 18:53:18 +0200 | [diff] [blame] | 139 | http_txn_reset_req(txn); |
| 140 | http_txn_reset_res(txn); |
| 141 | |
Willy Tarreau | 22ec1ea | 2014-11-27 20:45:39 +0100 | [diff] [blame] | 142 | txn->req.chn = &s->req; |
| 143 | txn->rsp.chn = &s->res; |
Krzysztof Piotr Oledzki | f9423ae | 2010-01-29 19:26:18 +0100 | [diff] [blame] | 144 | |
| 145 | txn->auth.method = HTTP_AUTH_UNKNOWN; |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 146 | |
Thierry FOURNIER | 4834bc7 | 2015-06-06 19:29:07 +0200 | [diff] [blame] | 147 | vars_init(&s->vars_txn, SCOPE_TXN); |
| 148 | vars_init(&s->vars_reqres, SCOPE_REQ); |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 149 | } |
| 150 | |
| 151 | /* to be used at the end of a transaction */ |
Willy Tarreau | 87b0966 | 2015-04-03 00:22:06 +0200 | [diff] [blame] | 152 | void http_end_txn(struct stream *s) |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 153 | { |
Willy Tarreau | eee5b51 | 2015-04-03 23:46:31 +0200 | [diff] [blame] | 154 | struct http_txn *txn = s->txn; |
Willy Tarreau | d0d8da9 | 2015-04-04 02:10:38 +0200 | [diff] [blame] | 155 | struct proxy *fe = strm_fe(s); |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 156 | |
| 157 | /* these ones will have been dynamically allocated */ |
Willy Tarreau | bafbe01 | 2017-11-24 17:34:44 +0100 | [diff] [blame] | 158 | pool_free(pool_head_requri, txn->uri); |
| 159 | pool_free(pool_head_capture, txn->cli_cookie); |
| 160 | pool_free(pool_head_capture, txn->srv_cookie); |
| 161 | pool_free(pool_head_uniqueid, s->unique_id); |
Krzysztof Piotr Oledzki | f9423ae | 2010-01-29 19:26:18 +0100 | [diff] [blame] | 162 | |
William Lallemand | a73203e | 2012-03-12 12:48:57 +0100 | [diff] [blame] | 163 | s->unique_id = NULL; |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 164 | txn->uri = NULL; |
| 165 | txn->srv_cookie = NULL; |
| 166 | txn->cli_cookie = NULL; |
Willy Tarreau | 4602363 | 2010-01-07 22:51:47 +0100 | [diff] [blame] | 167 | |
Willy Tarreau | cb7dd01 | 2015-04-03 22:16:32 +0200 | [diff] [blame] | 168 | if (s->req_cap) { |
Willy Tarreau | 4602363 | 2010-01-07 22:51:47 +0100 | [diff] [blame] | 169 | struct cap_hdr *h; |
Willy Tarreau | e36cbcb | 2015-04-03 15:40:56 +0200 | [diff] [blame] | 170 | for (h = fe->req_cap; h; h = h->next) |
Willy Tarreau | bafbe01 | 2017-11-24 17:34:44 +0100 | [diff] [blame] | 171 | pool_free(h->pool, s->req_cap[h->index]); |
Willy Tarreau | cb7dd01 | 2015-04-03 22:16:32 +0200 | [diff] [blame] | 172 | memset(s->req_cap, 0, fe->nb_req_cap * sizeof(void *)); |
Willy Tarreau | 4602363 | 2010-01-07 22:51:47 +0100 | [diff] [blame] | 173 | } |
| 174 | |
Willy Tarreau | cb7dd01 | 2015-04-03 22:16:32 +0200 | [diff] [blame] | 175 | if (s->res_cap) { |
Willy Tarreau | 4602363 | 2010-01-07 22:51:47 +0100 | [diff] [blame] | 176 | struct cap_hdr *h; |
Willy Tarreau | e36cbcb | 2015-04-03 15:40:56 +0200 | [diff] [blame] | 177 | for (h = fe->rsp_cap; h; h = h->next) |
Willy Tarreau | bafbe01 | 2017-11-24 17:34:44 +0100 | [diff] [blame] | 178 | pool_free(h->pool, s->res_cap[h->index]); |
Willy Tarreau | cb7dd01 | 2015-04-03 22:16:32 +0200 | [diff] [blame] | 179 | memset(s->res_cap, 0, fe->nb_rsp_cap * sizeof(void *)); |
Willy Tarreau | 4602363 | 2010-01-07 22:51:47 +0100 | [diff] [blame] | 180 | } |
| 181 | |
Willy Tarreau | cda7f3f | 2018-10-28 13:44:36 +0100 | [diff] [blame] | 182 | if (!LIST_ISEMPTY(&s->vars_txn.head)) |
| 183 | vars_prune(&s->vars_txn, s->sess, s); |
| 184 | if (!LIST_ISEMPTY(&s->vars_reqres.head)) |
| 185 | vars_prune(&s->vars_reqres, s->sess, s); |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 186 | } |
| 187 | |
| 188 | /* to be used at the end of a transaction to prepare a new one */ |
Willy Tarreau | 87b0966 | 2015-04-03 00:22:06 +0200 | [diff] [blame] | 189 | void http_reset_txn(struct stream *s) |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 190 | { |
| 191 | http_end_txn(s); |
| 192 | http_init_txn(s); |
| 193 | |
Thierry FOURNIER | bc4c1ac | 2015-02-25 13:36:14 +0100 | [diff] [blame] | 194 | /* reinitialise the current rule list pointer to NULL. We are sure that |
| 195 | * any rulelist match the NULL pointer. |
| 196 | */ |
| 197 | s->current_rule_list = NULL; |
| 198 | |
Willy Tarreau | d0d8da9 | 2015-04-04 02:10:38 +0200 | [diff] [blame] | 199 | s->be = strm_fe(s); |
| 200 | s->logs.logwait = strm_fe(s)->to_log; |
Willy Tarreau | abcd514 | 2013-06-11 17:18:02 +0200 | [diff] [blame] | 201 | s->logs.level = 0; |
Willy Tarreau | 87b0966 | 2015-04-03 00:22:06 +0200 | [diff] [blame] | 202 | stream_del_srv_conn(s); |
Willy Tarreau | 3fdb366 | 2012-11-12 00:42:33 +0100 | [diff] [blame] | 203 | s->target = NULL; |
Emeric Brun | b982a3d | 2010-01-04 15:45:53 +0100 | [diff] [blame] | 204 | /* re-init store persistence */ |
| 205 | s->store_count = 0; |
Olivier Houchard | a798bf5 | 2019-03-08 18:52:00 +0100 | [diff] [blame] | 206 | s->uniq_id = _HA_ATOMIC_XADD(&global.req_count, 1); |
Emeric Brun | b982a3d | 2010-01-04 15:45:53 +0100 | [diff] [blame] | 207 | |
Willy Tarreau | 22ec1ea | 2014-11-27 20:45:39 +0100 | [diff] [blame] | 208 | s->req.flags |= CF_READ_DONTWAIT; /* one read is usually enough */ |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 209 | |
Willy Tarreau | 739cfba | 2010-01-25 23:11:14 +0100 | [diff] [blame] | 210 | /* We must trim any excess data from the response buffer, because we |
| 211 | * may have blocked an invalid response from a server that we don't |
Joseph Herlant | 5ba8025 | 2018-11-15 09:25:36 -0800 | [diff] [blame] | 212 | * want to accidently forward once we disable the analysers, nor do |
Willy Tarreau | 739cfba | 2010-01-25 23:11:14 +0100 | [diff] [blame] | 213 | * we want those data to come along with next response. A typical |
| 214 | * example of such data would be from a buggy server responding to |
| 215 | * a HEAD with some data, or sending more than the advertised |
| 216 | * content-length. |
| 217 | */ |
Willy Tarreau | f37954d | 2018-06-15 18:31:02 +0200 | [diff] [blame] | 218 | if (unlikely(ci_data(&s->res))) |
Willy Tarreau | c9fa048 | 2018-07-10 17:43:27 +0200 | [diff] [blame] | 219 | b_set_data(&s->res.buf, co_data(&s->res)); |
Willy Tarreau | 739cfba | 2010-01-25 23:11:14 +0100 | [diff] [blame] | 220 | |
Christopher Faulet | c0c672a | 2017-03-28 11:51:33 +0200 | [diff] [blame] | 221 | /* Now we can realign the response buffer */ |
Willy Tarreau | d5b343b | 2018-06-06 06:42:46 +0200 | [diff] [blame] | 222 | c_realign_if_empty(&s->res); |
Christopher Faulet | c0c672a | 2017-03-28 11:51:33 +0200 | [diff] [blame] | 223 | |
Willy Tarreau | d0d8da9 | 2015-04-04 02:10:38 +0200 | [diff] [blame] | 224 | s->req.rto = strm_fe(s)->timeout.client; |
Willy Tarreau | 22ec1ea | 2014-11-27 20:45:39 +0100 | [diff] [blame] | 225 | s->req.wto = TICK_ETERNITY; |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 226 | |
Willy Tarreau | 22ec1ea | 2014-11-27 20:45:39 +0100 | [diff] [blame] | 227 | s->res.rto = TICK_ETERNITY; |
Willy Tarreau | d0d8da9 | 2015-04-04 02:10:38 +0200 | [diff] [blame] | 228 | s->res.wto = strm_fe(s)->timeout.client; |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 229 | |
Willy Tarreau | 22ec1ea | 2014-11-27 20:45:39 +0100 | [diff] [blame] | 230 | s->req.rex = TICK_ETERNITY; |
| 231 | s->req.wex = TICK_ETERNITY; |
| 232 | s->req.analyse_exp = TICK_ETERNITY; |
| 233 | s->res.rex = TICK_ETERNITY; |
| 234 | s->res.wex = TICK_ETERNITY; |
| 235 | s->res.analyse_exp = TICK_ETERNITY; |
Hongbo Long | e39683c | 2017-03-10 18:41:51 +0100 | [diff] [blame] | 236 | s->si[1].hcto = TICK_ETERNITY; |
Willy Tarreau | 0937bc4 | 2009-12-22 15:03:09 +0100 | [diff] [blame] | 237 | } |
Willy Tarreau | 58f10d7 | 2006-12-04 02:26:12 +0100 | [diff] [blame] | 238 | |
| 239 | /* |
Willy Tarreau | baaee00 | 2006-06-26 02:48:02 +0200 | [diff] [blame] | 240 | * Local variables: |
| 241 | * c-indent-level: 8 |
| 242 | * c-basic-offset: 8 |
| 243 | * End: |
| 244 | */ |