blob: bb5705008bc3caeb924f43e948fad6b7081385f1 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Backend variables and functions.
3 *
4 * Copyright 2000-2006 Willy Tarreau <w@1wt.eu>
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 <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>
32#include <proto/fd.h>
Willy Tarreau80587432006-12-24 17:47:20 +010033#include <proto/httperr.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020034#include <proto/log.h>
35#include <proto/proto_http.h>
36#include <proto/queue.h>
37#include <proto/stream_sock.h>
38#include <proto/task.h>
39
Willy Tarreau77074d52006-11-12 23:57:19 +010040#ifdef CONFIG_HAP_CTTPROXY
41#include <import/ip_tproxy.h>
42#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +020043
Willy Tarreau6d1a9882007-01-07 02:03:04 +010044#ifdef CONFIG_HAP_TCPSPLICE
45#include <libtcpsplice.h>
46#endif
47
Willy Tarreaubaaee002006-06-26 02:48:02 +020048/*
49 * This function recounts the number of usable active and backup servers for
50 * proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
51 * This function also recomputes the total active and backup weights.
52 */
53void recount_servers(struct proxy *px)
54{
55 struct server *srv;
56
57 px->srv_act = 0; px->srv_bck = px->tot_wact = px->tot_wbck = 0;
58 for (srv = px->srv; srv != NULL; srv = srv->next) {
59 if (srv->state & SRV_RUNNING) {
60 if (srv->state & SRV_BACKUP) {
61 px->srv_bck++;
Willy Tarreau417fae02007-03-25 21:16:40 +020062 px->tot_wbck += srv->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +020063 } else {
64 px->srv_act++;
Willy Tarreau417fae02007-03-25 21:16:40 +020065 px->tot_wact += srv->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +020066 }
67 }
68 }
69}
70
71/* This function recomputes the server map for proxy px. It
72 * relies on px->tot_wact and px->tot_wbck, so it must be
73 * called after recount_servers(). It also expects px->srv_map
74 * to be initialized to the largest value needed.
75 */
76void recalc_server_map(struct proxy *px)
77{
78 int o, tot, flag;
79 struct server *cur, *best;
80
81 if (px->srv_act) {
82 flag = SRV_RUNNING;
83 tot = px->tot_wact;
84 } else if (px->srv_bck) {
85 flag = SRV_RUNNING | SRV_BACKUP;
86 if (px->options & PR_O_USE_ALL_BK)
87 tot = px->tot_wbck;
88 else
89 tot = 1; /* the first server is enough */
90 } else {
91 px->srv_map_sz = 0;
92 return;
93 }
94
95 /* this algorithm gives priority to the first server, which means that
96 * it will respect the declaration order for equivalent weights, and
97 * that whatever the weights, the first server called will always be
98 * the first declard. This is an important asumption for the backup
99 * case, where we want the first server only.
100 */
101 for (cur = px->srv; cur; cur = cur->next)
102 cur->wscore = 0;
103
104 for (o = 0; o < tot; o++) {
105 int max = 0;
106 best = NULL;
107 for (cur = px->srv; cur; cur = cur->next) {
108 if ((cur->state & (SRV_RUNNING | SRV_BACKUP)) == flag) {
109 int v;
110
111 /* If we are forced to return only one server, we don't want to
112 * go further, because we would return the wrong one due to
113 * divide overflow.
114 */
115 if (tot == 1) {
116 best = cur;
117 break;
118 }
119
Willy Tarreau417fae02007-03-25 21:16:40 +0200120 cur->wscore += cur->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200121 v = (cur->wscore + tot) / tot; /* result between 0 and 3 */
122 if (best == NULL || v > max) {
123 max = v;
124 best = cur;
125 }
126 }
127 }
128 px->srv_map[o] = best;
129 best->wscore -= tot;
130 }
131 px->srv_map_sz = tot;
132}
133
134
135/*
136 * This function marks the session as 'assigned' in direct or dispatch modes,
137 * or tries to assign one in balance mode, according to the algorithm. It does
138 * nothing if the session had already been assigned a server.
139 *
140 * It may return :
141 * SRV_STATUS_OK if everything is OK. s->srv will be valid.
142 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
143 * SRV_STATUS_FULL if all servers are saturated. s->srv = NULL.
144 * SRV_STATUS_INTERNAL for other unrecoverable errors.
145 *
146 * Upon successful return, the session flag SN_ASSIGNED to indicate that it does
147 * not need to be called anymore. This usually means that s->srv can be trusted
148 * in balance and direct modes. This flag is not cleared, so it's to the caller
149 * to clear it if required (eg: redispatch).
150 *
151 */
152
153int assign_server(struct session *s)
154{
155#ifdef DEBUG_FULL
156 fprintf(stderr,"assign_server : s=%p\n",s);
157#endif
158
159 if (s->pend_pos)
160 return SRV_STATUS_INTERNAL;
161
162 if (!(s->flags & SN_ASSIGNED)) {
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200163 if (s->be->options & PR_O_BALANCE) {
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100164 if (s->flags & SN_DIRECT) {
165 s->flags |= SN_ASSIGNED;
166 return SRV_STATUS_OK;
167 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200168 if (!s->be->srv_act && !s->be->srv_bck)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200169 return SRV_STATUS_NOSRV;
170
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200171 if (s->be->options & PR_O_BALANCE_RR) {
172 s->srv = get_server_rr_with_conns(s->be);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200173 if (!s->srv)
174 return SRV_STATUS_FULL;
175 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200176 else if (s->be->options & PR_O_BALANCE_SH) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200177 int len;
178
179 if (s->cli_addr.ss_family == AF_INET)
180 len = 4;
181 else if (s->cli_addr.ss_family == AF_INET6)
182 len = 16;
183 else /* unknown IP family */
184 return SRV_STATUS_INTERNAL;
185
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200186 s->srv = get_server_sh(s->be,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200187 (void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
188 len);
189 }
Willy Tarreau2fcb5002007-05-08 13:35:26 +0200190 else if (s->be->options & PR_O_BALANCE_UH) {
191 /* URI hashing */
192 s->srv = get_server_uh(s->be,
193 s->txn.req.sol + s->txn.req.sl.rq.u,
194 s->txn.req.sl.rq.u_l);
195 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200196 else /* unknown balancing algorithm */
197 return SRV_STATUS_INTERNAL;
198 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200199 else if (!*(int *)&s->be->dispatch_addr.sin_addr &&
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100200 !(s->fe->options & PR_O_TRANSP)) {
Willy Tarreau1a1158b2007-01-20 11:07:46 +0100201 return SRV_STATUS_NOSRV;
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100202 }
203 s->flags |= SN_ASSIGNED;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200204 }
205 return SRV_STATUS_OK;
206}
207
208
209/*
210 * This function assigns a server address to a session, and sets SN_ADDR_SET.
211 * The address is taken from the currently assigned server, or from the
212 * dispatch or transparent address.
213 *
214 * It may return :
215 * SRV_STATUS_OK if everything is OK.
216 * SRV_STATUS_INTERNAL for other unrecoverable errors.
217 *
218 * Upon successful return, the session flag SN_ADDR_SET is set. This flag is
219 * not cleared, so it's to the caller to clear it if required.
220 *
221 */
222int assign_server_address(struct session *s)
223{
224#ifdef DEBUG_FULL
225 fprintf(stderr,"assign_server_address : s=%p\n",s);
226#endif
227
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200228 if ((s->flags & SN_DIRECT) || (s->be->options & PR_O_BALANCE)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200229 /* A server is necessarily known for this session */
230 if (!(s->flags & SN_ASSIGNED))
231 return SRV_STATUS_INTERNAL;
232
233 s->srv_addr = s->srv->addr;
234
235 /* if this server remaps proxied ports, we'll use
236 * the port the client connected to with an offset. */
237 if (s->srv->state & SRV_MAPPORTS) {
238 struct sockaddr_in sockname;
239 socklen_t namelen = sizeof(sockname);
240
Willy Tarreau73de9892006-11-30 11:40:23 +0100241 if (!(s->fe->options & PR_O_TRANSP) ||
Willy Tarreaubaaee002006-06-26 02:48:02 +0200242 get_original_dst(s->cli_fd, (struct sockaddr_in *)&sockname, &namelen) == -1)
243 getsockname(s->cli_fd, (struct sockaddr *)&sockname, &namelen);
244 s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) + ntohs(sockname.sin_port));
245 }
246 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200247 else if (*(int *)&s->be->dispatch_addr.sin_addr) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200248 /* connect to the defined dispatch addr */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200249 s->srv_addr = s->be->dispatch_addr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200250 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100251 else if (s->fe->options & PR_O_TRANSP) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200252 /* in transparent mode, use the original dest addr if no dispatch specified */
253 socklen_t salen = sizeof(s->srv_addr);
254
255 if (get_original_dst(s->cli_fd, &s->srv_addr, &salen) == -1) {
256 qfprintf(stderr, "Cannot get original server address.\n");
257 return SRV_STATUS_INTERNAL;
258 }
259 }
Willy Tarreau1a1158b2007-01-20 11:07:46 +0100260 else {
261 /* no server and no LB algorithm ! */
262 return SRV_STATUS_INTERNAL;
263 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200264
265 s->flags |= SN_ADDR_SET;
266 return SRV_STATUS_OK;
267}
268
269
270/* This function assigns a server to session <s> if required, and can add the
271 * connection to either the assigned server's queue or to the proxy's queue.
272 *
273 * Returns :
274 *
275 * SRV_STATUS_OK if everything is OK.
276 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
277 * SRV_STATUS_QUEUED if the connection has been queued.
278 * SRV_STATUS_FULL if the server(s) is/are saturated and the
279 * connection could not be queued.
280 * SRV_STATUS_INTERNAL for other unrecoverable errors.
281 *
282 */
283int assign_server_and_queue(struct session *s)
284{
285 struct pendconn *p;
286 int err;
287
288 if (s->pend_pos)
289 return SRV_STATUS_INTERNAL;
290
291 if (s->flags & SN_ASSIGNED) {
292 /* a server does not need to be assigned, perhaps because we're in
293 * direct mode, or in dispatch or transparent modes where the server
294 * is not needed.
295 */
296 if (s->srv &&
297 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
298 p = pendconn_add(s);
299 if (p)
300 return SRV_STATUS_QUEUED;
301 else
302 return SRV_STATUS_FULL;
303 }
304 return SRV_STATUS_OK;
305 }
306
307 /* a server needs to be assigned */
308 err = assign_server(s);
309 switch (err) {
310 case SRV_STATUS_OK:
311 /* in balance mode, we might have servers with connection limits */
312 if (s->srv &&
313 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
314 p = pendconn_add(s);
315 if (p)
316 return SRV_STATUS_QUEUED;
317 else
318 return SRV_STATUS_FULL;
319 }
320 return SRV_STATUS_OK;
321
322 case SRV_STATUS_FULL:
323 /* queue this session into the proxy's queue */
324 p = pendconn_add(s);
325 if (p)
326 return SRV_STATUS_QUEUED;
327 else
328 return SRV_STATUS_FULL;
329
330 case SRV_STATUS_NOSRV:
331 case SRV_STATUS_INTERNAL:
332 return err;
333 default:
334 return SRV_STATUS_INTERNAL;
335 }
336}
337
338
339/*
340 * This function initiates a connection to the server assigned to this session
341 * (s->srv, s->srv_addr). It will assign a server if none is assigned yet.
342 * It can return one of :
343 * - SN_ERR_NONE if everything's OK
344 * - SN_ERR_SRVTO if there are no more servers
345 * - SN_ERR_SRVCL if the connection was refused by the server
346 * - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
347 * - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
348 * - SN_ERR_INTERNAL for any other purely internal errors
349 * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
350 */
351int connect_server(struct session *s)
352{
353 int fd, err;
354
355 if (!(s->flags & SN_ADDR_SET)) {
356 err = assign_server_address(s);
357 if (err != SRV_STATUS_OK)
358 return SN_ERR_INTERNAL;
359 }
360
361 if ((fd = s->srv_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
362 qfprintf(stderr, "Cannot get a server socket.\n");
363
364 if (errno == ENFILE)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200365 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200366 "Proxy %s reached system FD limit at %d. Please check system tunables.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200367 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200368 else if (errno == EMFILE)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200369 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200370 "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200371 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200372 else if (errno == ENOBUFS || errno == ENOMEM)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200373 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200374 "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200375 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200376 /* this is a resource error */
377 return SN_ERR_RESOURCE;
378 }
379
380 if (fd >= global.maxsock) {
381 /* do not log anything there, it's a normal condition when this option
382 * is used to serialize connections to a server !
383 */
384 Alert("socket(): not enough free sockets. Raise -n argument. Giving up.\n");
385 close(fd);
386 return SN_ERR_PRXCOND; /* it is a configuration limit */
387 }
388
Willy Tarreau6d1a9882007-01-07 02:03:04 +0100389#ifdef CONFIG_HAP_TCPSPLICE
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200390 if ((s->fe->options & s->be->options) & PR_O_TCPSPLICE) {
Willy Tarreau6d1a9882007-01-07 02:03:04 +0100391 /* TCP splicing supported by both FE and BE */
392 tcp_splice_initfd(s->cli_fd, fd);
393 }
394#endif
395
Willy Tarreaubaaee002006-06-26 02:48:02 +0200396 if ((fcntl(fd, F_SETFL, O_NONBLOCK)==-1) ||
397 (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1)) {
398 qfprintf(stderr,"Cannot set client socket to non blocking mode.\n");
399 close(fd);
400 return SN_ERR_INTERNAL;
401 }
402
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200403 if (s->be->options & PR_O_TCP_SRV_KA)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200404 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
405
406 /* allow specific binding :
407 * - server-specific at first
408 * - proxy-specific next
409 */
410 if (s->srv != NULL && s->srv->state & SRV_BIND_SRC) {
411 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
412 if (bind(fd, (struct sockaddr *)&s->srv->source_addr, sizeof(s->srv->source_addr)) == -1) {
413 Alert("Cannot bind to source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200414 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200415 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200416 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200417 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200418 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200419 return SN_ERR_RESOURCE;
420 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100421#ifdef CONFIG_HAP_CTTPROXY
422 if (s->srv->state & SRV_TPROXY_MASK) {
423 struct in_tproxy itp1, itp2;
424 memset(&itp1, 0, sizeof(itp1));
425
426 itp1.op = TPROXY_ASSIGN;
427 switch (s->srv->state & SRV_TPROXY_MASK) {
428 case SRV_TPROXY_ADDR:
429 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
430 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
431 break;
432 case SRV_TPROXY_CLI:
433 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
434 /* fall through */
435 case SRV_TPROXY_CIP:
436 /* FIXME: what can we do if the client connects in IPv6 ? */
437 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
438 break;
439 }
440
441 /* set connect flag on socket */
442 itp2.op = TPROXY_FLAGS;
443 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
444
445 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
446 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
447 Alert("Cannot bind to tproxy source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200448 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100449 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200450 send_log(s->be, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100451 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200452 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100453 return SN_ERR_RESOURCE;
454 }
455 }
456#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200457 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200458 else if (s->be->options & PR_O_BIND_SRC) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200459 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200460 if (bind(fd, (struct sockaddr *)&s->be->source_addr, sizeof(s->be->source_addr)) == -1) {
461 Alert("Cannot bind to source address before connect() for proxy %s. Aborting.\n", s->be->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200462 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200463 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200464 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200465 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200466 return SN_ERR_RESOURCE;
467 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100468#ifdef CONFIG_HAP_CTTPROXY
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200469 if (s->be->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100470 struct in_tproxy itp1, itp2;
471 memset(&itp1, 0, sizeof(itp1));
472
473 itp1.op = TPROXY_ASSIGN;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200474 switch (s->be->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100475 case PR_O_TPXY_ADDR:
476 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
477 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
478 break;
479 case PR_O_TPXY_CLI:
480 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
481 /* fall through */
482 case PR_O_TPXY_CIP:
483 /* FIXME: what can we do if the client connects in IPv6 ? */
484 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
485 break;
486 }
487
488 /* set connect flag on socket */
489 itp2.op = TPROXY_FLAGS;
490 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
491
492 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
493 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
494 Alert("Cannot bind to tproxy source address before connect() for proxy %s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200495 s->be->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100496 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200497 send_log(s->be, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100498 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200499 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100500 return SN_ERR_RESOURCE;
501 }
502 }
503#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200504 }
505
506 if ((connect(fd, (struct sockaddr *)&s->srv_addr, sizeof(s->srv_addr)) == -1) &&
507 (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
508
509 if (errno == EAGAIN || errno == EADDRINUSE) {
510 char *msg;
511 if (errno == EAGAIN) /* no free ports left, try again later */
512 msg = "no free ports";
513 else
514 msg = "local address already in use";
515
516 qfprintf(stderr,"Cannot connect: %s.\n",msg);
517 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200518 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200519 "Connect() failed for server %s/%s: %s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200520 s->be->id, s->srv->id, msg);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200521 return SN_ERR_RESOURCE;
522 } else if (errno == ETIMEDOUT) {
523 //qfprintf(stderr,"Connect(): ETIMEDOUT");
524 close(fd);
525 return SN_ERR_SRVTO;
526 } else {
527 // (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM)
528 //qfprintf(stderr,"Connect(): %d", errno);
529 close(fd);
530 return SN_ERR_SRVCL;
531 }
532 }
533
534 fdtab[fd].owner = s->task;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200535 fdtab[fd].state = FD_STCONN; /* connection in progress */
Willy Tarreaud7971282006-07-29 18:36:34 +0200536 fdtab[fd].cb[DIR_RD].f = &stream_sock_read;
Willy Tarreau54469402006-07-29 16:59:06 +0200537 fdtab[fd].cb[DIR_RD].b = s->rep;
Willy Tarreauf8306d52006-07-29 19:01:31 +0200538 fdtab[fd].cb[DIR_WR].f = &stream_sock_write;
Willy Tarreau54469402006-07-29 16:59:06 +0200539 fdtab[fd].cb[DIR_WR].b = s->req;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200540
Willy Tarreauf161a342007-04-08 16:59:42 +0200541 EV_FD_SET(fd, DIR_WR); /* for connect status */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200542
543 fd_insert(fd);
544 if (s->srv) {
545 s->srv->cur_sess++;
546 if (s->srv->cur_sess > s->srv->cur_sess_max)
547 s->srv->cur_sess_max = s->srv->cur_sess;
548 }
549
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200550 if (s->be->contimeout)
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200551 tv_ms_add(&s->req->cex, &now, s->be->contimeout);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200552 else
Willy Tarreaud7971282006-07-29 18:36:34 +0200553 tv_eternity(&s->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200554 return SN_ERR_NONE; /* connection is OK */
555}
556
557
558/*
559 * This function checks the retry count during the connect() job.
560 * It updates the session's srv_state and retries, so that the caller knows
561 * what it has to do. It uses the last connection error to set the log when
562 * it expires. It returns 1 when it has expired, and 0 otherwise.
563 */
564int srv_count_retry_down(struct session *t, int conn_err)
565{
566 /* we are in front of a retryable error */
567 t->conn_retries--;
568 if (t->conn_retries < 0) {
569 /* if not retryable anymore, let's abort */
Willy Tarreaud7971282006-07-29 18:36:34 +0200570 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200571 srv_close_with_err(t, conn_err, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100572 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200573 if (t->srv)
574 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200575 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200576
577 /* We used to have a free connection slot. Since we'll never use it,
578 * we have to inform the server that it may be used by another session.
579 */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200580 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200581 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200582 return 1;
583 }
584 return 0;
585}
586
587
588/*
589 * This function performs the retryable part of the connect() job.
590 * It updates the session's srv_state and retries, so that the caller knows
591 * what it has to do. It returns 1 when it breaks out of the loop, or 0 if
592 * it needs to redispatch.
593 */
594int srv_retryable_connect(struct session *t)
595{
596 int conn_err;
597
598 /* This loop ensures that we stop before the last retry in case of a
599 * redispatchable server.
600 */
601 do {
602 /* initiate a connection to the server */
603 conn_err = connect_server(t);
604 switch (conn_err) {
605
606 case SN_ERR_NONE:
607 //fprintf(stderr,"0: c=%d, s=%d\n", c, s);
608 t->srv_state = SV_STCONN;
609 return 1;
610
611 case SN_ERR_INTERNAL:
Willy Tarreaud7971282006-07-29 18:36:34 +0200612 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200613 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100614 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200615 if (t->srv)
616 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200617 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200618 /* release other sessions waiting for this server */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200619 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200620 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200621 return 1;
622 }
623 /* ensure that we have enough retries left */
624 if (srv_count_retry_down(t, conn_err)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200625 return 1;
626 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200627 } while (t->srv == NULL || t->conn_retries > 0 || !(t->be->options & PR_O_REDISP));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200628
629 /* We're on our last chance, and the REDISP option was specified.
630 * We will ignore cookie and force to balance or use the dispatcher.
631 */
632 /* let's try to offer this slot to anybody */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200633 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200634 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200635
636 if (t->srv)
637 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200638 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200639
640 t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
641 t->srv = NULL; /* it's left to the dispatcher to choose a server */
Willy Tarreau3d300592007-03-18 18:34:41 +0100642 http_flush_cookie_flags(&t->txn);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200643 return 0;
644}
645
646
647/* This function performs the "redispatch" part of a connection attempt. It
648 * will assign a server if required, queue the connection if required, and
649 * handle errors that might arise at this level. It can change the server
650 * state. It will return 1 if it encounters an error, switches the server
651 * state, or has to queue a connection. Otherwise, it will return 0 indicating
652 * that the connection is ready to use.
653 */
654
655int srv_redispatch_connect(struct session *t)
656{
657 int conn_err;
658
659 /* We know that we don't have any connection pending, so we will
660 * try to get a new one, and wait in this state if it's queued
661 */
662 conn_err = assign_server_and_queue(t);
663 switch (conn_err) {
664 case SRV_STATUS_OK:
665 break;
666
667 case SRV_STATUS_NOSRV:
668 /* note: it is guaranteed that t->srv == NULL here */
Willy Tarreaud7971282006-07-29 18:36:34 +0200669 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200670 srv_close_with_err(t, SN_ERR_SRVTO, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100671 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200672 if (t->srv)
673 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200674 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200675
676 return 1;
677
678 case SRV_STATUS_QUEUED:
679 /* FIXME-20060503 : we should use the queue timeout instead */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200680 if (t->be->contimeout)
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200681 tv_ms_add(&t->req->cex, &now, t->be->contimeout);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200682 else
Willy Tarreaud7971282006-07-29 18:36:34 +0200683 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200684 t->srv_state = SV_STIDLE;
685 /* do nothing else and do not wake any other session up */
686 return 1;
687
688 case SRV_STATUS_FULL:
689 case SRV_STATUS_INTERNAL:
690 default:
Willy Tarreaud7971282006-07-29 18:36:34 +0200691 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200692 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100693 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200694 if (t->srv)
695 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200696 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200697
698 /* release other sessions waiting for this server */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200699 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200700 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200701 return 1;
702 }
703 /* if we get here, it's because we got SRV_STATUS_OK, which also
704 * means that the connection has not been queued.
705 */
706 return 0;
707}
708
709
710/*
711 * Local variables:
712 * c-indent-level: 8
713 * c-basic-offset: 8
714 * End:
715 */