changeset 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 224b28e82698
children 59588bbf8d55
files network.c
diffstat 1 files changed, 59 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- 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);