$OpenBSD: patch-src_TCPTransmitter_cc,v 1.1.1.1 2002/10/28 17:22:17 todd Exp $ $RuOBSD: patch-src_TCPTransmitter_cc,v 1.4 2002/10/26 12:04:30 grange Exp $ --- src/TCPTransmitter.cc.orig Mon Feb 18 01:29:51 2002 +++ src/TCPTransmitter.cc Sat Oct 26 15:51:24 2002 @@ -120,13 +120,15 @@ void TCPTransmitter::connect(const strin // Set autoreconnect and use_ssl _autoreconnect = autoreconnect; _use_ssl = use_ssl; - + +#if 0 #ifdef WITH_IPV6 if (inet_addr(chost.c_str()) != INADDR_NONE) { // IP address in IPv4 notation - convert chost = "::ffff:" + chost; } #endif +#endif #ifdef TRANSMITTER_DEBUG if (_proxy.type == none) @@ -173,7 +175,7 @@ void TCPTransmitter::connect(const strin _host_sockaddr.sin_port = g_htons(cport); #endif // resolve host - _async_resolve(chost.c_str()); + _async_resolve(chost.c_str(), cport); } else { @@ -944,15 +946,26 @@ const string TCPTransmitter::getSocketEr return("Unknown error"); } -void TCPTransmitter::_async_resolve(const gchar* hostname) +void TCPTransmitter::_async_resolve(const gchar* hostname, guint port) { + char p[6]; + struct addrinfo hints; + g_assert(hostname != NULL); // check if hostname is in dotted decimal notation +#if 0 #ifdef WITH_IPV6 if (inet_pton(AF_INET6, hostname, &_host_sockaddr.sin6_addr) != 0) #else if (inet_aton(hostname, &_host_sockaddr.sin_addr) != 0) #endif +#endif + snprintf(p, 5, "%u", port); + p[5] = '\0'; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(hostname, p, &hints, &_res0) == 0) { // all done _hostResolved = true; @@ -1071,65 +1084,76 @@ void TCPTransmitter::_async_resolve(cons void TCPTransmitter::_async_connect() { + struct addrinfo *res; + char hbuf[MAXHOSTNAMELEN]; // connect non-blocking // create socket -#ifdef WITH_IPV6 - _socketfd = socket(PF_INET6, SOCK_STREAM, 0); -#else - _socketfd = socket(PF_INET, SOCK_STREAM, 0); -#endif - if (_socketfd < 0) + _socketfd = -1; + for (res = _res0; res; res = res->ai_next) { - // something nasty happened + _socketfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (_socketfd < 0) + { + // something nasty happened #ifdef TRANSMITTER_DEBUG - cout << "socket() failed: " << strerror(errno) << endl; + cout << "socket() failed: " << strerror(errno) << endl; #endif - handleError(strerror(errno)); - return; - } - _socket_flags = fcntl(_socketfd, F_GETFL, 0); - if (_socket_flags == -1) - { - // not good + handleError(strerror(errno)); + continue; + } + _socket_flags = fcntl(_socketfd, F_GETFL, 0); + if (_socket_flags == -1) + { + // not good #ifdef TRANSMITTER_DEBUG - cout << "fcntl F_GETFL failed on socket: " << strerror(errno) << endl; + cout << "fcntl F_GETFL failed on socket: " << strerror(errno) << endl; #endif - handleError(errSocket); - return; - } - if (fcntl(_socketfd, F_SETFL, _socket_flags | O_NONBLOCK) == -1) - { - // damn! + handleError(errSocket); + continue; + } + if (fcntl(_socketfd, F_SETFL, _socket_flags | O_NONBLOCK) == -1) + { + // damn! #ifdef TRANSMITTER_DEBUG - cout << "fcntl F_SETFL failed on socket: " << strerror(errno) << endl; + cout << "fcntl F_SETFL failed on socket: " << strerror(errno) << endl; #endif - handleError(strerror(errno)); - return; - } + handleError(strerror(errno)); + continue; + } - int one = 1; - if (setsockopt(_socketfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)) < 0) - { + int one = 1; + if (setsockopt(_socketfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)) < 0) + { #ifdef TRANSMITTER_DEBUG - cout << "setsockopt failed: " << strerror(errno) << endl; + cout << "setsockopt failed: " << strerror(errno) << endl; #endif - } + } - // try to connect non-blocking - if (::connect(_socketfd, (struct sockaddr*) (&_host_sockaddr), sizeof(_host_sockaddr)) < 0) - { - if (errno != EINPROGRESS) + // try to connect non-blocking +#ifdef TRANSMITTER_DEBUG + getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); + cout << "Trying " << hbuf << endl; +#endif + if (::connect(_socketfd, res->ai_addr, res->ai_addrlen) < 0) { - // Yikes! + if (errno != EINPROGRESS) + { + // Yikes! #ifdef TRANSMITTER_DEBUG - cout << "connect failed: " << strerror(errno) << endl; + cout << "connect failed: " << strerror(errno) << endl; #endif - handleError(strerror(errno)); - return; + handleError(strerror(errno)); + close(_socketfd); + _socketfd = -1; + continue; + } } + break; } - + if (_socketfd < 0) + return; + _IOChannel = g_io_channel_unix_new(_socketfd); _socket_watchid = g_io_add_watch(_IOChannel, GIOCondition(G_IO_IN | G_IO_OUT | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL),