Mercurial > hg > nnchat
comparison network.c @ 611:019a54b07f60
Clean up and modularize proxy connection code a bit.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 20 May 2014 05:34:33 +0300 |
parents | 2cc5434a8ce0 |
children | 2cd71b7c1e8e |
comparison
equal
deleted
inserted
replaced
610:224b28e82698 | 611:019a54b07f60 |
---|---|
189 if (conn == NULL) | 189 if (conn == NULL) |
190 return -1; | 190 return -1; |
191 | 191 |
192 th_free(conn->proxy.userid); | 192 th_free(conn->proxy.userid); |
193 conn->proxy.userid = th_strdup(userid); | 193 conn->proxy.userid = th_strdup(userid); |
194 | |
194 th_free(conn->proxy.passwd); | 195 th_free(conn->proxy.passwd); |
195 conn->proxy.passwd = th_strdup(passwd); | 196 conn->proxy.passwd = th_strdup(passwd); |
196 | 197 |
197 return 0; | 198 return 0; |
199 } | |
200 | |
201 | |
202 static int nn_conn_proxy_wait(nn_conn_t *conn) | |
203 { | |
204 int status, tries; | |
205 | |
206 for (status = tries = 1; tries <= 20 && status > 0; tries++) | |
207 { | |
208 #ifdef __WIN32 | |
209 Sleep(50); | |
210 #else | |
211 usleep(50000); | |
212 #endif | |
213 nn_conn_reset(conn); | |
214 status = nn_conn_pull(conn); | |
215 } | |
216 | |
217 if (status < 0) | |
218 nn_conn_err(conn, "Proxy negotiation failed at try %d with network error: %d\n", tries, status); | |
219 else | |
220 nn_conn_err(conn, "Proxy negotiation timed out.\n"); | |
221 | |
222 return status; | |
223 } | |
224 | |
225 | |
226 static BOOL nn_conn_proxy_send(nn_conn_t *conn, void *buf, size_t bufsiz) | |
227 { | |
228 BOOL ret; | |
229 nn_conn_reset(conn); | |
230 if ((ret = nn_conn_send_buf(conn, buf, bufsiz)) == FALSE) | |
231 nn_conn_err(conn, "Error sending SOCKS proxy request.\n"); | |
232 th_free(buf); | |
233 return ret; | |
198 } | 234 } |
199 | 235 |
200 | 236 |
201 int nn_conn_open(nn_conn_t *conn, const int port, const char *host) | 237 int nn_conn_open(nn_conn_t *conn, const int port, const char *host) |
202 { | 238 { |
253 FD_SET(conn->socket, &(conn->sockfds)); | 289 FD_SET(conn->socket, &(conn->sockfds)); |
254 | 290 |
255 // Proxy-specific setup | 291 // Proxy-specific setup |
256 if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A) | 292 if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A) |
257 { | 293 { |
294 struct nn_socks4_res_t *sockres; | |
258 struct nn_socks4_t *socksh; | 295 struct nn_socks4_t *socksh; |
259 size_t bufsiz; | 296 size_t bufsiz; |
260 char *ptr, *buf; | 297 char *ptr, *buf; |
261 int tries, status = -1; | |
262 | 298 |
263 nn_conn_msg(conn, "Initializing SOCKS 4/a proxy negotiation.\n"); | 299 nn_conn_msg(conn, "Initializing SOCKS 4/a proxy negotiation.\n"); |
264 | 300 |
265 bufsiz = sizeof(struct nn_socks4_t) + strlen(conn->proxy.userid) + 1; | 301 bufsiz = sizeof(struct nn_socks4_t) + strlen(conn->proxy.userid) + 1; |
266 if (conn->proxy.type == NN_PROXY_SOCKS4A) | 302 if (conn->proxy.type == NN_PROXY_SOCKS4A) |
288 ptr += strlen(conn->proxy.userid) + 1; | 324 ptr += strlen(conn->proxy.userid) + 1; |
289 strcpy(ptr, conn->host); | 325 strcpy(ptr, conn->host); |
290 } | 326 } |
291 | 327 |
292 // Send request | 328 // Send request |
293 nn_conn_reset(conn); | 329 if (!nn_conn_proxy_send(conn, buf, bufsiz)) |
294 if (!nn_conn_send_buf(conn, buf, bufsiz)) | |
295 { | |
296 th_free(buf); | |
297 nn_conn_err(conn, "Error sending SOCKS proxy request.\n"); | |
298 goto error; | 330 goto error; |
299 } | |
300 th_free(buf); | |
301 | 331 |
302 // Wait for SOCKS server to reply | 332 // Wait for SOCKS server to reply |
303 for (status = tries = 1; tries <= 20 && status > 0; tries++) | 333 if (nn_conn_proxy_wait(conn) != 0) |
304 { | 334 goto error; |
305 #ifdef __WIN32 | 335 |
306 Sleep(50); | 336 sockres = (struct nn_socks4_res_t *) &(conn->buf); |
307 #else | 337 if (sockres->nb != 0) |
308 usleep(50000); | 338 { |
309 #endif | 339 nn_conn_err(conn, "Invalid SOCKS 4 server reply, does not begin with NUL byte (%d).\n", sockres->nb); |
310 nn_conn_reset(conn); | 340 goto error; |
311 status = nn_conn_pull(conn); | 341 } |
312 } | 342 if (sockres->result != 0x5a) |
313 | 343 { |
314 // Check results | 344 char *s = NULL; |
315 if (status == 0) | 345 switch (sockres->result) |
316 { | |
317 struct nn_socks4_res_t *res = (struct nn_socks4_res_t *) &(conn->buf); | |
318 if (res->nb != 0) | |
319 { | 346 { |
320 nn_conn_err(conn, "Invalid SOCKS server reply, does not begin with NUL byte (%d).\n", res->nb); | 347 case 0x5b: s = "Request rejected or failed"; break; |
321 goto error; | 348 case 0x5c: s = "Request failed because client is not running identd (or not reachable from the server)"; break; |
349 case 0x5d: s = "Request failed because client's identd could not confirm the user ID string in the request"; break; | |
350 default: s = "Unknown SOCKS 4 error response"; break; | |
322 } | 351 } |
323 if (res->result != 0x5a) | 352 nn_conn_err(conn, "SOCKS 4 setup failed, 0x%02x: %s.\n", sockres->result, s); |
324 { | |
325 char *s = NULL; | |
326 switch (res->result) | |
327 { | |
328 case 0x5b: s = "Request rejected or failed"; break; | |
329 case 0x5c: s = "Request failed because client is not running identd (or not reachable from the server)"; break; | |
330 case 0x5d: s = "Request failed because client's identd could not confirm the user ID string in the request"; break; | |
331 default: s = "Unknown SOCKS error response"; break; | |
332 } | |
333 nn_conn_err(conn, "SOCKS setup failed, 0x%02x: %s.\n", res->result, s); | |
334 goto error; | |
335 } | |
336 nn_conn_msg(conn, "SOCKS connection established!\n"); | |
337 } | |
338 else if (status < 0) | |
339 { | |
340 nn_conn_err(conn, "Proxy negotiation failed at try %d with network error: %d\n", tries, status); | |
341 goto error; | 353 goto error; |
342 } | 354 } |
343 else | 355 |
344 { | 356 nn_conn_msg(conn, "SOCKS 4 connection established!\n"); |
345 nn_conn_err(conn, "Proxy negotiation timed out.\n"); | |
346 goto error; | |
347 } | |
348 } | 357 } |
349 | 358 |
350 nn_conn_reset(conn); | 359 nn_conn_reset(conn); |
351 conn->status = NN_CONN_OPEN; | 360 conn->status = NN_CONN_OPEN; |
352 return 0; | 361 return 0; |