connect.cc (2087B)
1 #include "backend" 2 3 bool Backend::connect() { 4 PROFILE("Backend::connect"); 5 6 debugmsg("About to connect to back end " << description() << '\n'); 7 8 // Resolve hostname, prepare binding 9 struct sockaddr_in backendaddr; 10 11 backendaddr.sin_family = AF_INET; 12 backendaddr.sin_port = htons(bdef.port()); 13 backendaddr.sin_addr.s_addr = dnsentry.resolve(bdef.server()); 14 15 // Client socket goes into nonblocking mode, so we can connect 16 // and enforce a timeout later. 17 int flags; 18 if ( (flags = fcntl (clsocket.fd(), F_GETFL, 0)) == -1 ) 19 throw Error(string("Failed to get fd flags: ") + strerror(errno)); 20 if (fcntl (clsocket.fd(), F_SETFL, flags | O_NONBLOCK) == -1) 21 throw Error(string("Failed to fd in nonblocking mode: ") + 22 strerror(errno)); 23 24 // Do the connect 25 int conres = ::connect (clsocket.fd(), (struct sockaddr *)&backendaddr, 26 sizeof(backendaddr)); 27 int conerrno = errno; 28 debugmsg("Connect result: " << conres << 29 ", errno: " << conerrno << ' ' << strerror(conerrno) << '\n'); 30 31 // Put socket again in blocking mode. 32 if (fcntl (clsocket.fd(), F_SETFL, flags) == -1) 33 throw Error(string("Failed to put fd in blocking mode: ") + 34 strerror(errno)); 35 36 // Check on the outcome of the connect 37 if (!conres || conerrno == EINPROGRESS) { 38 // Wait for socket to go writable. 39 Fdset fdset (config.backend_write_timeout()); 40 fdset.add (clsocket); 41 fdset.wait_rw(); 42 43 # ifdef CONNECTCHECK_ONLY_WRITABLE 44 if (fdset.writeable(clsocket)) 45 live(true); 46 else { 47 markconnecterror(); 48 live(false); 49 } 50 # else 51 if (fdset.writeable(clsocket) && !fdset.readable(clsocket)) 52 live(true); 53 else { 54 debugmsg("Connect socket writable: " << 55 (fdset.writeable(clsocket) ? "yes" : "no") << 56 ", readable: " << 57 (fdset.readable(clsocket) ? "yes" : "no") << 58 '\n'); 59 markconnecterror(); 60 live(false); 61 } 62 # endif 63 } 64 65 debugmsg("Back end " << description() << " is " << livestr() << 66 " (socket " << clsocket.fd() << ")\n"); 67 68 return (islive); 69 }