185 lines
5.5 KiB
Plaintext
185 lines
5.5 KiB
Plaintext
$OpenBSD: patch-src_TCPTransmitter_cc,v 1.2 2004/01/05 02:04:54 espie Exp $
|
|
$RuOBSD: patch-src_TCPTransmitter_cc,v 1.4 2002/10/26 12:04:30 grange Exp $
|
|
--- src/TCPTransmitter.cc.orig 2002-02-17 23:29:51.000000000 +0100
|
|
+++ src/TCPTransmitter.cc 2004-01-05 03:01:58.000000000 +0100
|
|
@@ -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),
|
|
@@ -1338,7 +1362,7 @@ const string TCPTransmitter::getsockname
|
|
}
|
|
}
|
|
|
|
-void TCPTransmitter::setProxy(const string &ptype, const string &host, guint port, const string &user, const string &password, bool tryOther = true)
|
|
+void TCPTransmitter::setProxy(const string &ptype, const string &host, guint port, const string &user, const string &password, bool tryOther/*=true*/)
|
|
{
|
|
if (_state != Offline)
|
|
{
|