$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),
