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 }