~ubuntu-branches/ubuntu/trusty/haproxy/trusty-updates

« back to all changes in this revision

Viewing changes to src/checks.c

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Cornet
  • Date: 2009-10-19 22:31:45 UTC
  • mfrom: (1.2.5 upstream)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20091019223145-rymupk5njs544bvp
ImportĀ upstreamĀ versionĀ 1.3.22

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include <proto/fd.h>
37
37
#include <proto/log.h>
38
38
#include <proto/queue.h>
 
39
#include <proto/port_range.h>
39
40
#include <proto/proto_http.h>
40
41
#include <proto/proto_tcp.h>
41
42
#include <proto/proxy.h>
357
358
                                memcpy(s->proxy->check_req + 11, &gmt_time, 4);
358
359
                        }
359
360
 
360
 
#ifndef MSG_NOSIGNAL
361
 
                        ret = send(fd, s->proxy->check_req, s->proxy->check_len, MSG_DONTWAIT);
362
 
#else
363
361
                        ret = send(fd, s->proxy->check_req, s->proxy->check_len, MSG_DONTWAIT | MSG_NOSIGNAL);
364
 
#endif
365
362
                        if (ret == s->proxy->check_len) {
366
363
                                /* we allow up to <timeout.check> if nonzero for a responce */
367
364
                                if (s->proxy->timeout.check)
453
450
                goto out_wakeup;
454
451
        }
455
452
 
456
 
#ifndef MSG_NOSIGNAL
457
 
        len = recv(fd, trash, sizeof(trash), 0);
458
 
#else
459
453
        /* Warning! Linux returns EAGAIN on SO_ERROR if data are still available
460
454
         * but the connection was closed on the remote end. Fortunately, recv still
461
455
         * works correctly and we don't need to do the getsockopt() on linux.
462
456
         */
463
457
        len = recv(fd, trash, sizeof(trash), MSG_NOSIGNAL);
464
 
#endif
465
458
        if (unlikely(len < 0 && errno == EAGAIN)) {
466
459
                /* we want some polling to happen first */
467
460
                fdtab[fd].ev &= ~FD_POLL_IN;
597
590
                                                setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
598
591
                                                           s->iface_name, s->iface_len + 1);
599
592
#endif
600
 
                                        ret = tcpv4_bind_socket(fd, flags, &s->source_addr, remote);
 
593
                                        if (s->sport_range) {
 
594
                                                int bind_attempts = 10; /* should be more than enough to find a spare port */
 
595
                                                struct sockaddr_in src;
 
596
 
 
597
                                                ret = 1;
 
598
                                                src = s->source_addr;
 
599
 
 
600
                                                do {
 
601
                                                        /* note: in case of retry, we may have to release a previously
 
602
                                                         * allocated port, hence this loop's construct.
 
603
                                                         */
 
604
                                                        port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
 
605
                                                        fdtab[fd].port_range = NULL;
 
606
 
 
607
                                                        if (!bind_attempts)
 
608
                                                                break;
 
609
                                                        bind_attempts--;
 
610
 
 
611
                                                        fdtab[fd].local_port = port_range_alloc_port(s->sport_range);
 
612
                                                        if (!fdtab[fd].local_port)
 
613
                                                                break;
 
614
 
 
615
                                                        fdtab[fd].port_range = s->sport_range;
 
616
                                                        src.sin_port = htons(fdtab[fd].local_port);
 
617
 
 
618
                                                        ret = tcpv4_bind_socket(fd, flags, &src, remote);
 
619
                                                } while (ret != 0); /* binding NOK */
 
620
                                        }
 
621
                                        else {
 
622
                                                ret = tcpv4_bind_socket(fd, flags, &s->source_addr, remote);
 
623
                                        }
 
624
 
601
625
                                        if (ret) {
602
626
                                                s->result |= SRV_CHK_ERROR;
603
627
                                                switch (ret) {
682
706
                                        }
683
707
                                }
684
708
                        }
 
709
                        port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
 
710
                        fdtab[fd].port_range = NULL;
685
711
                        close(fd); /* socket creation error */
686
712
                }
687
713