upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/btfrv.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/btfrv.cpp')
-rw-r--r--src/btfrv.cpp41
1 files changed, 26 insertions, 15 deletions
diff --git a/src/btfrv.cpp b/src/btfrv.cpp
index d4f079f..133eb89 100644
--- a/src/btfrv.cpp
+++ b/src/btfrv.cpp
@@ -102,31 +102,42 @@ static SOCKET ConnectTo(const char* host, unsigned short port)
102#else 102#else
103 struct addrinfo hints, *res = NULL; 103 struct addrinfo hints, *res = NULL;
104 memset(&hints, 0, sizeof(hints)); 104 memset(&hints, 0, sizeof(hints));
105 hints.ai_family = AF_INET; 105 hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 (some relays are v6-only)
106 hints.ai_socktype = SOCK_STREAM; 106 hints.ai_socktype = SOCK_STREAM;
107 char portstr[16]; sprintf(portstr, "%u", (unsigned)port); 107 char portstr[16]; sprintf(portstr, "%u", (unsigned)port);
108 if (getaddrinfo(host, portstr, &hints, &res) != 0 || !res) return INVALID_SOCKET; 108 if (getaddrinfo(host, portstr, &hints, &res) != 0 || !res) return INVALID_SOCKET;
109 SOCKET s = BtfSocketTag(socket(res->ai_family, res->ai_socktype, res->ai_protocol), SOCK_RV_DIAL);
110 if (s == INVALID_SOCKET) { freeaddrinfo(res); return INVALID_SOCKET; }
111 109
112 // Apply a short timeout only for the connect() and initial handshake so an 110 // Try each resolved address until one connects.
113 // unresponsive relay doesn't block the thread. Once the tunnel is live the 111 SOCKET s = INVALID_SOCKET;
114 // timeout is cleared -- a forwarding pipe must block indefinitely on recv(). 112 for (struct addrinfo* rp = res; rp != NULL; rp = rp->ai_next)
113 {
114 s = BtfSocketTag(socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol), SOCK_RV_DIAL);
115 if (s == INVALID_SOCKET)
116 continue;
117
118 // Apply a short timeout only for the connect() and initial handshake so an
119 // unresponsive relay doesn't block the thread. Once the tunnel is live the
120 // timeout is cleared -- a forwarding pipe must block indefinitely on recv().
115#ifdef _WIN32 121#ifdef _WIN32
116 DWORD tvShort = 10000; 122 DWORD tvShort = 10000;
117 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tvShort, sizeof(tvShort)); 123 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tvShort, sizeof(tvShort));
118 setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char*)&tvShort, sizeof(tvShort)); 124 setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char*)&tvShort, sizeof(tvShort));
119#else 125#else
120 struct timeval tvShort; tvShort.tv_sec = 10; tvShort.tv_usec = 0; 126 struct timeval tvShort; tvShort.tv_sec = 10; tvShort.tv_usec = 0;
121 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tvShort, sizeof(tvShort)); 127 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tvShort, sizeof(tvShort));
122 setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tvShort, sizeof(tvShort)); 128 setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&tvShort, sizeof(tvShort));
123#endif 129#endif
124 130
125 if (connect(s, res->ai_addr, (int)res->ai_addrlen) != 0) 131 if (connect(s, rp->ai_addr, (int)rp->ai_addrlen) != 0)
126 { 132 {
127 CLOSESOCK(s); freeaddrinfo(res); return INVALID_SOCKET; 133 CLOSESOCK(s);
134 s = INVALID_SOCKET;
135 continue;
136 }
137 break;
128 } 138 }
129 freeaddrinfo(res); 139 freeaddrinfo(res);
140 if (s == INVALID_SOCKET) return INVALID_SOCKET;
130#endif 141#endif
131 142
132 // Clear the timeout -- the socket is now a live tunnel and must not 143 // Clear the timeout -- the socket is now a live tunnel and must not