crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs

backendconnect.c (3487B)


      1 /*************************************************************************
      2  * This file is part of Crosroads 1.23, a load balancer and fail over
      3  * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL.
      4  * Visit http://crossroads.e-tunity.com for information.
      5  *************************************************************************/
      6 #include "crossroads.h"
      7 
      8 static jmp_buf jmpbuf;
      9 static int timeout;
     10 
     11 static void alarmhandler (int sig) {
     12     alarm(0);
     13     timeout++;
     14     if (program_stage != stage_retrying)
     15 	msg ("Service %s: Alarm went off while connecting to back end",
     16 	     activeservice->name);
     17     longjmp (jmpbuf, 1);
     18 }
     19 
     20 
     21 int backend_connect () {
     22     int backend_sock;
     23     struct sockaddr_in servername;
     24 
     25     if ( (backend_sock = socket (PF_INET, SOCK_STREAM, 0)) < 0 ) {
     26 	if (program_stage != stage_retrying) {
     27 	    error ("Service %s: failed to create socket "
     28 		   "for backend communication: %s",
     29 		   activeservice->name, strerror(errno));
     30 	} else {
     31 	    warning ("Service %s: failed to create socket "
     32 		     "for backend communication: %s",
     33 		     activeservice->name, strerror(errno));
     34 	    return (-1);
     35 	}
     36     }
     37     
     38     if (init_sockaddr (&servername,
     39 		       activeservice->backend[current_backend].server,
     40 		       activeservice->backend[current_backend].port)) {
     41 	/* The hostname is unusable.. */
     42 	warning ("Service %s: unknown host %s",
     43 		 activeservice->name,
     44 		 activeservice->backend[current_backend].server);
     45 	mark_activity (0, 0, st_unavailable);
     46 	return (-2);
     47     }
     48     if (program_stage != stage_retrying)
     49 	msg ("Service %s: Network socket to %s:%d initialized",
     50 	     activeservice->name, 
     51 	     activeservice->backend[current_backend].server,
     52 	     activeservice->backend[current_backend].port);
     53 
     54     signal (SIGALRM, alarmhandler);
     55     timeout = 0;
     56     alarm (CONNECT_TIMEOUT);
     57     
     58     if (!setjmp (jmpbuf)) {
     59 	/* First time around, try connecting */
     60 	if (connect (backend_sock, (struct sockaddr *) &servername,
     61 		     sizeof(servername)) < 0) {
     62 	    /* This backend is unusable.
     63 	     * Either connect() has failed (connection refused) or it got
     64 	     * interrupted by the SIGALRM
     65 	     */
     66 	    close (backend_sock);
     67 	    alarm(0);
     68 	    signal (SIGALRM, SIG_DFL);
     69 	    
     70 	    if (timeout) {
     71 		if (program_stage != stage_retrying)
     72 		    warning ("Service %s: server %s:%d not usable"
     73 			     " due to timeout",
     74 			     activeservice->name,
     75 			     activeservice->backend[current_backend].server,
     76 			     activeservice->backend[current_backend].port);
     77 	    }  else {
     78 		if (program_stage != stage_retrying)
     79 		    warning ("Service %s: server %s:%d: cannot connect: %s",
     80 			     activeservice->name,
     81 			     activeservice->backend[current_backend].server,
     82 			     activeservice->backend[current_backend].port,
     83 			     strerror(errno));
     84 	    }
     85 	    mark_activity (0, 0, st_unavailable);
     86 	    return (-3);
     87 	} else {
     88 	    msg ("Service %s: connection to back end %s succeeded",
     89 		 activeservice->name, 
     90 		 activeservice->backend[current_backend].server);
     91 	}
     92     } else {
     93 	/* Got here because of longjmp from the signal handler,
     94 	 * this MUST be a timeout
     95 	 */
     96 	if (program_stage != stage_retrying)
     97 	    warning ("Service %s: Server %s not usable due to timeout",
     98 		     activeservice->name, 
     99 		     activeservice->backend[current_backend].server);
    100 	close (backend_sock);
    101 	alarm(0);
    102 	signal (SIGALRM, SIG_DFL);
    103 	mark_activity (0, 0, st_unavailable);
    104 	return (-4);
    105     }
    106 
    107     alarm(0);
    108     signal (SIGALRM, SIG_DFL);
    109     return (backend_sock);
    110 }