blob: 8abaf1ca5e18ab32b961bec24c0882118e2017e7 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Backend variables and functions.
3 *
Willy Tarreaud825eef2007-05-12 22:35:00 +02004 * Copyright 2000-2007 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
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 <errno.h>
14#include <fcntl.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <syslog.h>
Willy Tarreauf19cf372006-11-14 15:40:51 +010018#include <string.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020019
Willy Tarreau2dd0d472006-06-29 17:53:05 +020020#include <common/compat.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020021#include <common/config.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020022#include <common/time.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020023
24#include <types/buffers.h>
25#include <types/global.h>
26#include <types/polling.h>
27#include <types/proxy.h>
28#include <types/server.h>
29#include <types/session.h>
30
31#include <proto/backend.h>
Willy Tarreau14c8aac2007-05-08 19:46:30 +020032#include <proto/client.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020033#include <proto/fd.h>
Willy Tarreau80587432006-12-24 17:47:20 +010034#include <proto/httperr.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020035#include <proto/log.h>
36#include <proto/proto_http.h>
37#include <proto/queue.h>
38#include <proto/stream_sock.h>
39#include <proto/task.h>
40
Willy Tarreau77074d52006-11-12 23:57:19 +010041#ifdef CONFIG_HAP_CTTPROXY
42#include <import/ip_tproxy.h>
43#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +020044
Willy Tarreau6d1a9882007-01-07 02:03:04 +010045#ifdef CONFIG_HAP_TCPSPLICE
46#include <libtcpsplice.h>
47#endif
48
Willy Tarreaubaaee002006-06-26 02:48:02 +020049/*
50 * This function recounts the number of usable active and backup servers for
51 * proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
52 * This function also recomputes the total active and backup weights.
53 */
54void recount_servers(struct proxy *px)
55{
56 struct server *srv;
57
58 px->srv_act = 0; px->srv_bck = px->tot_wact = px->tot_wbck = 0;
59 for (srv = px->srv; srv != NULL; srv = srv->next) {
60 if (srv->state & SRV_RUNNING) {
61 if (srv->state & SRV_BACKUP) {
62 px->srv_bck++;
Willy Tarreau417fae02007-03-25 21:16:40 +020063 px->tot_wbck += srv->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +020064 } else {
65 px->srv_act++;
Willy Tarreau417fae02007-03-25 21:16:40 +020066 px->tot_wact += srv->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +020067 }
68 }
69 }
70}
71
72/* This function recomputes the server map for proxy px. It
73 * relies on px->tot_wact and px->tot_wbck, so it must be
74 * called after recount_servers(). It also expects px->srv_map
75 * to be initialized to the largest value needed.
76 */
77void recalc_server_map(struct proxy *px)
78{
79 int o, tot, flag;
80 struct server *cur, *best;
81
82 if (px->srv_act) {
83 flag = SRV_RUNNING;
84 tot = px->tot_wact;
85 } else if (px->srv_bck) {
86 flag = SRV_RUNNING | SRV_BACKUP;
87 if (px->options & PR_O_USE_ALL_BK)
88 tot = px->tot_wbck;
89 else
90 tot = 1; /* the first server is enough */
91 } else {
92 px->srv_map_sz = 0;
93 return;
94 }
95
96 /* this algorithm gives priority to the first server, which means that
97 * it will respect the declaration order for equivalent weights, and
98 * that whatever the weights, the first server called will always be
99 * the first declard. This is an important asumption for the backup
100 * case, where we want the first server only.
101 */
102 for (cur = px->srv; cur; cur = cur->next)
103 cur->wscore = 0;
104
105 for (o = 0; o < tot; o++) {
106 int max = 0;
107 best = NULL;
108 for (cur = px->srv; cur; cur = cur->next) {
109 if ((cur->state & (SRV_RUNNING | SRV_BACKUP)) == flag) {
110 int v;
111
112 /* If we are forced to return only one server, we don't want to
113 * go further, because we would return the wrong one due to
114 * divide overflow.
115 */
116 if (tot == 1) {
117 best = cur;
118 break;
119 }
120
Willy Tarreau417fae02007-03-25 21:16:40 +0200121 cur->wscore += cur->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200122 v = (cur->wscore + tot) / tot; /* result between 0 and 3 */
123 if (best == NULL || v > max) {
124 max = v;
125 best = cur;
126 }
127 }
128 }
129 px->srv_map[o] = best;
130 best->wscore -= tot;
131 }
132 px->srv_map_sz = tot;
133}
134
135
136/*
137 * This function marks the session as 'assigned' in direct or dispatch modes,
138 * or tries to assign one in balance mode, according to the algorithm. It does
139 * nothing if the session had already been assigned a server.
140 *
141 * It may return :
142 * SRV_STATUS_OK if everything is OK. s->srv will be valid.
143 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
144 * SRV_STATUS_FULL if all servers are saturated. s->srv = NULL.
145 * SRV_STATUS_INTERNAL for other unrecoverable errors.
146 *
147 * Upon successful return, the session flag SN_ASSIGNED to indicate that it does
148 * not need to be called anymore. This usually means that s->srv can be trusted
149 * in balance and direct modes. This flag is not cleared, so it's to the caller
150 * to clear it if required (eg: redispatch).
151 *
152 */
153
154int assign_server(struct session *s)
155{
156#ifdef DEBUG_FULL
157 fprintf(stderr,"assign_server : s=%p\n",s);
158#endif
159
160 if (s->pend_pos)
161 return SRV_STATUS_INTERNAL;
162
163 if (!(s->flags & SN_ASSIGNED)) {
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200164 if (s->be->options & PR_O_BALANCE) {
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100165 if (s->flags & SN_DIRECT) {
166 s->flags |= SN_ASSIGNED;
167 return SRV_STATUS_OK;
168 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200169 if (!s->be->srv_act && !s->be->srv_bck)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200170 return SRV_STATUS_NOSRV;
171
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200172 if (s->be->options & PR_O_BALANCE_RR) {
173 s->srv = get_server_rr_with_conns(s->be);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200174 if (!s->srv)
175 return SRV_STATUS_FULL;
176 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200177 else if (s->be->options & PR_O_BALANCE_SH) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200178 int len;
179
180 if (s->cli_addr.ss_family == AF_INET)
181 len = 4;
182 else if (s->cli_addr.ss_family == AF_INET6)
183 len = 16;
184 else /* unknown IP family */
185 return SRV_STATUS_INTERNAL;
186
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200187 s->srv = get_server_sh(s->be,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200188 (void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
189 len);
190 }
Willy Tarreau2fcb5002007-05-08 13:35:26 +0200191 else if (s->be->options & PR_O_BALANCE_UH) {
192 /* URI hashing */
193 s->srv = get_server_uh(s->be,
194 s->txn.req.sol + s->txn.req.sl.rq.u,
195 s->txn.req.sl.rq.u_l);
196 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200197 else /* unknown balancing algorithm */
198 return SRV_STATUS_INTERNAL;
199 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200200 else if (!*(int *)&s->be->dispatch_addr.sin_addr &&
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100201 !(s->fe->options & PR_O_TRANSP)) {
Willy Tarreau1a1158b2007-01-20 11:07:46 +0100202 return SRV_STATUS_NOSRV;
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100203 }
204 s->flags |= SN_ASSIGNED;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200205 }
206 return SRV_STATUS_OK;
207}
208
209
210/*
211 * This function assigns a server address to a session, and sets SN_ADDR_SET.
212 * The address is taken from the currently assigned server, or from the
213 * dispatch or transparent address.
214 *
215 * It may return :
216 * SRV_STATUS_OK if everything is OK.
217 * SRV_STATUS_INTERNAL for other unrecoverable errors.
218 *
219 * Upon successful return, the session flag SN_ADDR_SET is set. This flag is
220 * not cleared, so it's to the caller to clear it if required.
221 *
222 */
223int assign_server_address(struct session *s)
224{
225#ifdef DEBUG_FULL
226 fprintf(stderr,"assign_server_address : s=%p\n",s);
227#endif
228
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200229 if ((s->flags & SN_DIRECT) || (s->be->options & PR_O_BALANCE)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200230 /* A server is necessarily known for this session */
231 if (!(s->flags & SN_ASSIGNED))
232 return SRV_STATUS_INTERNAL;
233
234 s->srv_addr = s->srv->addr;
235
236 /* if this server remaps proxied ports, we'll use
237 * the port the client connected to with an offset. */
238 if (s->srv->state & SRV_MAPPORTS) {
Willy Tarreau14c8aac2007-05-08 19:46:30 +0200239 if (!(s->fe->options & PR_O_TRANSP) && !(s->flags & SN_FRT_ADDR_SET))
240 get_frt_addr(s);
241 if (s->frt_addr.ss_family == AF_INET) {
242 s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) +
243 ntohs(((struct sockaddr_in *)&s->frt_addr)->sin_port));
244 } else {
245 s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) +
246 ntohs(((struct sockaddr_in6 *)&s->frt_addr)->sin6_port));
247 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200248 }
249 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200250 else if (*(int *)&s->be->dispatch_addr.sin_addr) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200251 /* connect to the defined dispatch addr */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200252 s->srv_addr = s->be->dispatch_addr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200253 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100254 else if (s->fe->options & PR_O_TRANSP) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200255 /* in transparent mode, use the original dest addr if no dispatch specified */
256 socklen_t salen = sizeof(s->srv_addr);
257
258 if (get_original_dst(s->cli_fd, &s->srv_addr, &salen) == -1) {
259 qfprintf(stderr, "Cannot get original server address.\n");
260 return SRV_STATUS_INTERNAL;
261 }
262 }
Willy Tarreau1a1158b2007-01-20 11:07:46 +0100263 else {
264 /* no server and no LB algorithm ! */
265 return SRV_STATUS_INTERNAL;
266 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200267
268 s->flags |= SN_ADDR_SET;
269 return SRV_STATUS_OK;
270}
271
272
273/* This function assigns a server to session <s> if required, and can add the
274 * connection to either the assigned server's queue or to the proxy's queue.
275 *
276 * Returns :
277 *
278 * SRV_STATUS_OK if everything is OK.
279 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
280 * SRV_STATUS_QUEUED if the connection has been queued.
281 * SRV_STATUS_FULL if the server(s) is/are saturated and the
282 * connection could not be queued.
283 * SRV_STATUS_INTERNAL for other unrecoverable errors.
284 *
285 */
286int assign_server_and_queue(struct session *s)
287{
288 struct pendconn *p;
289 int err;
290
291 if (s->pend_pos)
292 return SRV_STATUS_INTERNAL;
293
294 if (s->flags & SN_ASSIGNED) {
295 /* a server does not need to be assigned, perhaps because we're in
296 * direct mode, or in dispatch or transparent modes where the server
297 * is not needed.
298 */
299 if (s->srv &&
300 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
301 p = pendconn_add(s);
302 if (p)
303 return SRV_STATUS_QUEUED;
304 else
305 return SRV_STATUS_FULL;
306 }
307 return SRV_STATUS_OK;
308 }
309
310 /* a server needs to be assigned */
311 err = assign_server(s);
312 switch (err) {
313 case SRV_STATUS_OK:
314 /* in balance mode, we might have servers with connection limits */
315 if (s->srv &&
316 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
317 p = pendconn_add(s);
318 if (p)
319 return SRV_STATUS_QUEUED;
320 else
321 return SRV_STATUS_FULL;
322 }
323 return SRV_STATUS_OK;
324
325 case SRV_STATUS_FULL:
326 /* queue this session into the proxy's queue */
327 p = pendconn_add(s);
328 if (p)
329 return SRV_STATUS_QUEUED;
330 else
331 return SRV_STATUS_FULL;
332
333 case SRV_STATUS_NOSRV:
334 case SRV_STATUS_INTERNAL:
335 return err;
336 default:
337 return SRV_STATUS_INTERNAL;
338 }
339}
340
341
342/*
343 * This function initiates a connection to the server assigned to this session
344 * (s->srv, s->srv_addr). It will assign a server if none is assigned yet.
345 * It can return one of :
346 * - SN_ERR_NONE if everything's OK
347 * - SN_ERR_SRVTO if there are no more servers
348 * - SN_ERR_SRVCL if the connection was refused by the server
349 * - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
350 * - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
351 * - SN_ERR_INTERNAL for any other purely internal errors
352 * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
353 */
354int connect_server(struct session *s)
355{
356 int fd, err;
357
358 if (!(s->flags & SN_ADDR_SET)) {
359 err = assign_server_address(s);
360 if (err != SRV_STATUS_OK)
361 return SN_ERR_INTERNAL;
362 }
363
364 if ((fd = s->srv_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
365 qfprintf(stderr, "Cannot get a server socket.\n");
366
367 if (errno == ENFILE)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200368 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200369 "Proxy %s reached system FD limit at %d. Please check system tunables.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200370 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200371 else if (errno == EMFILE)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200372 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200373 "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200374 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200375 else if (errno == ENOBUFS || errno == ENOMEM)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200376 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200377 "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200378 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200379 /* this is a resource error */
380 return SN_ERR_RESOURCE;
381 }
382
383 if (fd >= global.maxsock) {
384 /* do not log anything there, it's a normal condition when this option
385 * is used to serialize connections to a server !
386 */
387 Alert("socket(): not enough free sockets. Raise -n argument. Giving up.\n");
388 close(fd);
389 return SN_ERR_PRXCOND; /* it is a configuration limit */
390 }
391
Willy Tarreau6d1a9882007-01-07 02:03:04 +0100392#ifdef CONFIG_HAP_TCPSPLICE
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200393 if ((s->fe->options & s->be->options) & PR_O_TCPSPLICE) {
Willy Tarreau6d1a9882007-01-07 02:03:04 +0100394 /* TCP splicing supported by both FE and BE */
395 tcp_splice_initfd(s->cli_fd, fd);
396 }
397#endif
398
Willy Tarreaubaaee002006-06-26 02:48:02 +0200399 if ((fcntl(fd, F_SETFL, O_NONBLOCK)==-1) ||
400 (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1)) {
401 qfprintf(stderr,"Cannot set client socket to non blocking mode.\n");
402 close(fd);
403 return SN_ERR_INTERNAL;
404 }
405
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200406 if (s->be->options & PR_O_TCP_SRV_KA)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200407 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
408
409 /* allow specific binding :
410 * - server-specific at first
411 * - proxy-specific next
412 */
413 if (s->srv != NULL && s->srv->state & SRV_BIND_SRC) {
414 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
415 if (bind(fd, (struct sockaddr *)&s->srv->source_addr, sizeof(s->srv->source_addr)) == -1) {
416 Alert("Cannot bind to source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200417 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200418 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200419 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200420 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200421 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200422 return SN_ERR_RESOURCE;
423 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100424#ifdef CONFIG_HAP_CTTPROXY
425 if (s->srv->state & SRV_TPROXY_MASK) {
426 struct in_tproxy itp1, itp2;
427 memset(&itp1, 0, sizeof(itp1));
428
429 itp1.op = TPROXY_ASSIGN;
430 switch (s->srv->state & SRV_TPROXY_MASK) {
431 case SRV_TPROXY_ADDR:
432 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
433 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
434 break;
435 case SRV_TPROXY_CLI:
436 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
437 /* fall through */
438 case SRV_TPROXY_CIP:
439 /* FIXME: what can we do if the client connects in IPv6 ? */
440 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
441 break;
442 }
443
444 /* set connect flag on socket */
445 itp2.op = TPROXY_FLAGS;
446 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
447
448 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
449 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
450 Alert("Cannot bind to tproxy source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200451 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100452 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200453 send_log(s->be, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100454 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200455 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100456 return SN_ERR_RESOURCE;
457 }
458 }
459#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200460 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200461 else if (s->be->options & PR_O_BIND_SRC) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200462 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200463 if (bind(fd, (struct sockaddr *)&s->be->source_addr, sizeof(s->be->source_addr)) == -1) {
464 Alert("Cannot bind to source address before connect() for proxy %s. Aborting.\n", s->be->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200465 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200466 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200467 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200468 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200469 return SN_ERR_RESOURCE;
470 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100471#ifdef CONFIG_HAP_CTTPROXY
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200472 if (s->be->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100473 struct in_tproxy itp1, itp2;
474 memset(&itp1, 0, sizeof(itp1));
475
476 itp1.op = TPROXY_ASSIGN;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200477 switch (s->be->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100478 case PR_O_TPXY_ADDR:
479 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
480 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
481 break;
482 case PR_O_TPXY_CLI:
483 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
484 /* fall through */
485 case PR_O_TPXY_CIP:
486 /* FIXME: what can we do if the client connects in IPv6 ? */
487 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
488 break;
489 }
490
491 /* set connect flag on socket */
492 itp2.op = TPROXY_FLAGS;
493 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
494
495 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
496 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
497 Alert("Cannot bind to tproxy source address before connect() for proxy %s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200498 s->be->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100499 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200500 send_log(s->be, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100501 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200502 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100503 return SN_ERR_RESOURCE;
504 }
505 }
506#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200507 }
508
509 if ((connect(fd, (struct sockaddr *)&s->srv_addr, sizeof(s->srv_addr)) == -1) &&
510 (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
511
512 if (errno == EAGAIN || errno == EADDRINUSE) {
513 char *msg;
514 if (errno == EAGAIN) /* no free ports left, try again later */
515 msg = "no free ports";
516 else
517 msg = "local address already in use";
518
519 qfprintf(stderr,"Cannot connect: %s.\n",msg);
520 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200521 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200522 "Connect() failed for server %s/%s: %s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200523 s->be->id, s->srv->id, msg);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200524 return SN_ERR_RESOURCE;
525 } else if (errno == ETIMEDOUT) {
526 //qfprintf(stderr,"Connect(): ETIMEDOUT");
527 close(fd);
528 return SN_ERR_SRVTO;
529 } else {
530 // (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM)
531 //qfprintf(stderr,"Connect(): %d", errno);
532 close(fd);
533 return SN_ERR_SRVCL;
534 }
535 }
536
537 fdtab[fd].owner = s->task;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200538 fdtab[fd].state = FD_STCONN; /* connection in progress */
Willy Tarreaud7971282006-07-29 18:36:34 +0200539 fdtab[fd].cb[DIR_RD].f = &stream_sock_read;
Willy Tarreau54469402006-07-29 16:59:06 +0200540 fdtab[fd].cb[DIR_RD].b = s->rep;
Willy Tarreauf8306d52006-07-29 19:01:31 +0200541 fdtab[fd].cb[DIR_WR].f = &stream_sock_write;
Willy Tarreau54469402006-07-29 16:59:06 +0200542 fdtab[fd].cb[DIR_WR].b = s->req;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200543
Willy Tarreauf161a342007-04-08 16:59:42 +0200544 EV_FD_SET(fd, DIR_WR); /* for connect status */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200545
546 fd_insert(fd);
547 if (s->srv) {
548 s->srv->cur_sess++;
549 if (s->srv->cur_sess > s->srv->cur_sess_max)
550 s->srv->cur_sess_max = s->srv->cur_sess;
551 }
552
Willy Tarreaua8b55e32007-05-13 16:08:19 +0200553 if (!tv_add_ifset(&s->req->cex, &now, &s->be->contimeout))
Willy Tarreaud7971282006-07-29 18:36:34 +0200554 tv_eternity(&s->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200555 return SN_ERR_NONE; /* connection is OK */
556}
557
558
559/*
560 * This function checks the retry count during the connect() job.
561 * It updates the session's srv_state and retries, so that the caller knows
562 * what it has to do. It uses the last connection error to set the log when
563 * it expires. It returns 1 when it has expired, and 0 otherwise.
564 */
565int srv_count_retry_down(struct session *t, int conn_err)
566{
567 /* we are in front of a retryable error */
568 t->conn_retries--;
569 if (t->conn_retries < 0) {
570 /* if not retryable anymore, let's abort */
Willy Tarreaud7971282006-07-29 18:36:34 +0200571 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200572 srv_close_with_err(t, conn_err, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100573 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200574 if (t->srv)
575 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200576 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200577
578 /* We used to have a free connection slot. Since we'll never use it,
579 * we have to inform the server that it may be used by another session.
580 */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200581 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200582 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200583 return 1;
584 }
585 return 0;
586}
587
588
589/*
590 * This function performs the retryable part of the connect() job.
591 * It updates the session's srv_state and retries, so that the caller knows
592 * what it has to do. It returns 1 when it breaks out of the loop, or 0 if
593 * it needs to redispatch.
594 */
595int srv_retryable_connect(struct session *t)
596{
597 int conn_err;
598
599 /* This loop ensures that we stop before the last retry in case of a
600 * redispatchable server.
601 */
602 do {
603 /* initiate a connection to the server */
604 conn_err = connect_server(t);
605 switch (conn_err) {
606
607 case SN_ERR_NONE:
608 //fprintf(stderr,"0: c=%d, s=%d\n", c, s);
609 t->srv_state = SV_STCONN;
610 return 1;
611
612 case SN_ERR_INTERNAL:
Willy Tarreaud7971282006-07-29 18:36:34 +0200613 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200614 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100615 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200616 if (t->srv)
617 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200618 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200619 /* release other sessions waiting for this server */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200620 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200621 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200622 return 1;
623 }
624 /* ensure that we have enough retries left */
625 if (srv_count_retry_down(t, conn_err)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200626 return 1;
627 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200628 } while (t->srv == NULL || t->conn_retries > 0 || !(t->be->options & PR_O_REDISP));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200629
630 /* We're on our last chance, and the REDISP option was specified.
631 * We will ignore cookie and force to balance or use the dispatcher.
632 */
633 /* let's try to offer this slot to anybody */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200634 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200635 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200636
637 if (t->srv)
638 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200639 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200640
641 t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
642 t->srv = NULL; /* it's left to the dispatcher to choose a server */
Willy Tarreau3d300592007-03-18 18:34:41 +0100643 http_flush_cookie_flags(&t->txn);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200644 return 0;
645}
646
647
648/* This function performs the "redispatch" part of a connection attempt. It
649 * will assign a server if required, queue the connection if required, and
650 * handle errors that might arise at this level. It can change the server
651 * state. It will return 1 if it encounters an error, switches the server
652 * state, or has to queue a connection. Otherwise, it will return 0 indicating
653 * that the connection is ready to use.
654 */
655
656int srv_redispatch_connect(struct session *t)
657{
658 int conn_err;
659
660 /* We know that we don't have any connection pending, so we will
661 * try to get a new one, and wait in this state if it's queued
662 */
663 conn_err = assign_server_and_queue(t);
664 switch (conn_err) {
665 case SRV_STATUS_OK:
666 break;
667
668 case SRV_STATUS_NOSRV:
669 /* note: it is guaranteed that t->srv == NULL here */
Willy Tarreaud7971282006-07-29 18:36:34 +0200670 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200671 srv_close_with_err(t, SN_ERR_SRVTO, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100672 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200673 if (t->srv)
674 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200675 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200676
677 return 1;
678
679 case SRV_STATUS_QUEUED:
680 /* FIXME-20060503 : we should use the queue timeout instead */
Willy Tarreaua8b55e32007-05-13 16:08:19 +0200681 if (!tv_add_ifset(&t->req->cex, &now, &t->be->contimeout))
Willy Tarreaud7971282006-07-29 18:36:34 +0200682 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200683 t->srv_state = SV_STIDLE;
684 /* do nothing else and do not wake any other session up */
685 return 1;
686
687 case SRV_STATUS_FULL:
688 case SRV_STATUS_INTERNAL:
689 default:
Willy Tarreaud7971282006-07-29 18:36:34 +0200690 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200691 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100692 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200693 if (t->srv)
694 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200695 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200696
697 /* release other sessions waiting for this server */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200698 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200699 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200700 return 1;
701 }
702 /* if we get here, it's because we got SRV_STATUS_OK, which also
703 * means that the connection has not been queued.
704 */
705 return 0;
706}
707
708
709/*
710 * Local variables:
711 * c-indent-level: 8
712 * c-basic-offset: 8
713 * End:
714 */