# HG changeset patch # User Matti Hamalainen # Date 1400553273 -10800 # Node ID 019a54b07f60f0a774ed9ce035e7184c94b7598c # Parent 224b28e82698678e974a06baecee1cd24670a2c6 Clean up and modularize proxy connection code a bit. diff -r 224b28e82698 -r 019a54b07f60 network.c --- a/network.c Tue May 20 04:49:17 2014 +0300 +++ b/network.c Tue May 20 05:34:33 2014 +0300 @@ -191,6 +191,7 @@ th_free(conn->proxy.userid); conn->proxy.userid = th_strdup(userid); + th_free(conn->proxy.passwd); conn->proxy.passwd = th_strdup(passwd); @@ -198,6 +199,41 @@ } +static int nn_conn_proxy_wait(nn_conn_t *conn) +{ + int status, tries; + + for (status = tries = 1; tries <= 20 && status > 0; tries++) + { +#ifdef __WIN32 + Sleep(50); +#else + usleep(50000); +#endif + nn_conn_reset(conn); + status = nn_conn_pull(conn); + } + + if (status < 0) + nn_conn_err(conn, "Proxy negotiation failed at try %d with network error: %d\n", tries, status); + else + nn_conn_err(conn, "Proxy negotiation timed out.\n"); + + return status; +} + + +static BOOL nn_conn_proxy_send(nn_conn_t *conn, void *buf, size_t bufsiz) +{ + BOOL ret; + nn_conn_reset(conn); + if ((ret = nn_conn_send_buf(conn, buf, bufsiz)) == FALSE) + nn_conn_err(conn, "Error sending SOCKS proxy request.\n"); + th_free(buf); + return ret; +} + + int nn_conn_open(nn_conn_t *conn, const int port, const char *host) { struct sockaddr_in dest; @@ -255,10 +291,10 @@ // Proxy-specific setup if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A) { + struct nn_socks4_res_t *sockres; struct nn_socks4_t *socksh; size_t bufsiz; char *ptr, *buf; - int tries, status = -1; nn_conn_msg(conn, "Initializing SOCKS 4/a proxy negotiation.\n"); @@ -290,61 +326,34 @@ } // Send request - nn_conn_reset(conn); - if (!nn_conn_send_buf(conn, buf, bufsiz)) - { - th_free(buf); - nn_conn_err(conn, "Error sending SOCKS proxy request.\n"); + if (!nn_conn_proxy_send(conn, buf, bufsiz)) goto error; - } - th_free(buf); // Wait for SOCKS server to reply - for (status = tries = 1; tries <= 20 && status > 0; tries++) + if (nn_conn_proxy_wait(conn) != 0) + goto error; + + sockres = (struct nn_socks4_res_t *) &(conn->buf); + if (sockres->nb != 0) + { + nn_conn_err(conn, "Invalid SOCKS 4 server reply, does not begin with NUL byte (%d).\n", sockres->nb); + goto error; + } + if (sockres->result != 0x5a) { -#ifdef __WIN32 - Sleep(50); -#else - usleep(50000); -#endif - nn_conn_reset(conn); - status = nn_conn_pull(conn); + char *s = NULL; + switch (sockres->result) + { + case 0x5b: s = "Request rejected or failed"; break; + case 0x5c: s = "Request failed because client is not running identd (or not reachable from the server)"; break; + case 0x5d: s = "Request failed because client's identd could not confirm the user ID string in the request"; break; + default: s = "Unknown SOCKS 4 error response"; break; + } + nn_conn_err(conn, "SOCKS 4 setup failed, 0x%02x: %s.\n", sockres->result, s); + goto error; } - // Check results - if (status == 0) - { - struct nn_socks4_res_t *res = (struct nn_socks4_res_t *) &(conn->buf); - if (res->nb != 0) - { - nn_conn_err(conn, "Invalid SOCKS server reply, does not begin with NUL byte (%d).\n", res->nb); - goto error; - } - if (res->result != 0x5a) - { - char *s = NULL; - switch (res->result) - { - case 0x5b: s = "Request rejected or failed"; break; - case 0x5c: s = "Request failed because client is not running identd (or not reachable from the server)"; break; - case 0x5d: s = "Request failed because client's identd could not confirm the user ID string in the request"; break; - default: s = "Unknown SOCKS error response"; break; - } - nn_conn_err(conn, "SOCKS setup failed, 0x%02x: %s.\n", res->result, s); - goto error; - } - nn_conn_msg(conn, "SOCKS connection established!\n"); - } - else if (status < 0) - { - nn_conn_err(conn, "Proxy negotiation failed at try %d with network error: %d\n", tries, status); - goto error; - } - else - { - nn_conn_err(conn, "Proxy negotiation timed out.\n"); - goto error; - } + nn_conn_msg(conn, "SOCKS 4 connection established!\n"); } nn_conn_reset(conn);