changeset 615:399ce077b2a0

Factorize more proxy initialization stuff into separate functions.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 20 May 2014 07:15:48 +0300
parents 1fc22e8efd26
children 1ffacd20b88b
files network.c
diffstat 1 files changed, 77 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/network.c	Tue May 20 06:51:52 2014 +0300
+++ b/network.c	Tue May 20 07:15:48 2014 +0300
@@ -240,6 +240,75 @@
 }
 
 
+static int nn_conn_socks4_negotiate(nn_conn_t *conn, const int port, const char *host)
+{
+    struct nn_socks4_res_t *sockres;
+    struct nn_socks4_t *socksh;
+    size_t bufsiz;
+    uint8_t *ptr, *buf;
+
+    (void) host;
+
+    nn_conn_msg(conn, "Initializing SOCKS 4/a proxy negotiation.\n");
+
+    bufsiz = sizeof(struct nn_socks4_t) + strlen(conn->proxy.userid) + 1;
+    if (conn->proxy.type == NN_PROXY_SOCKS4A)
+        bufsiz += strlen(conn->host) + 1;
+
+    if ((ptr = buf = th_malloc(bufsiz)) == NULL)
+    {
+        nn_conn_err(conn, "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n", bufsiz);
+        return FALSE;
+    }
+
+    // Create SOCKS 4 handshake
+    socksh = (struct nn_socks4_t *) buf;
+    socksh->version = 4;
+    socksh->command = NN_PROXY_CMD_CONNECT;
+    socksh->port    = htons(port);
+    socksh->addr    = (conn->proxy.type == NN_PROXY_SOCKS4A) ?  htonl(0x00000032) : conn->addr.s_addr;
+    ptr += sizeof(struct nn_socks4_t);
+
+    strcpy((char *) ptr, conn->proxy.userid);
+
+    if (conn->proxy.type == NN_PROXY_SOCKS4A)
+    {
+        ptr += strlen(conn->proxy.userid) + 1;
+        strcpy((char *)ptr, conn->host);
+    }
+
+    // Send request
+    if (!nn_conn_proxy_send(conn, buf, bufsiz))
+        return FALSE;
+
+    // Wait for SOCKS server to reply
+    if (nn_conn_proxy_wait(conn) != 0)
+        return FALSE;
+
+    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);
+        return FALSE;
+    }
+    if (sockres->result != 0x5a)
+    {
+        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);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+
 int nn_conn_open(nn_conn_t *conn, const int port, const char *host)
 {
     struct sockaddr_in dest;
@@ -261,6 +330,7 @@
 
     if (conn->proxy.type > NN_PROXY_NONE && conn->proxy.type < NN_PROXY_LAST)
     {
+        // If using a proxy, we connect to the proxy server
         dest.sin_port = htons(conn->proxy.port);
         dest.sin_addr = conn->proxy.addr;
 
@@ -295,71 +365,14 @@
     FD_SET(conn->socket, &(conn->sockfds));
 
     // Proxy-specific setup
-    if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A)
+    switch (conn->proxy.type)
     {
-        struct nn_socks4_res_t *sockres;
-        struct nn_socks4_t *socksh;
-        size_t bufsiz;
-        uint8_t *ptr, *buf;
-
-        nn_conn_msg(conn, "Initializing SOCKS 4/a proxy negotiation.\n");
-
-        bufsiz = sizeof(struct nn_socks4_t) + strlen(conn->proxy.userid) + 1;
-        if (conn->proxy.type == NN_PROXY_SOCKS4A)
-            bufsiz += strlen(conn->host) + 1;
-
-        if ((ptr = buf = th_malloc(bufsiz)) == NULL)
-        {
-            conn->err = -1;
-            nn_conn_err(conn, "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n", bufsiz);
-            goto error;
-        }
-
-        // Create SOCKS 5 handshake
-        socksh = (struct nn_socks4_t *) buf;
-        socksh->version = 4;
-        socksh->command = NN_PROXY_CMD_CONNECT;
-        socksh->port    = htons(port);
-        socksh->addr    = (conn->proxy.type == NN_PROXY_SOCKS4A) ?  htonl(0x00000032) : conn->addr.s_addr;
-        ptr += sizeof(struct nn_socks4_t);
-
-        strcpy((char *) ptr, conn->proxy.userid);
-
-        if (conn->proxy.type == NN_PROXY_SOCKS4A)
-        {
-            ptr += strlen(conn->proxy.userid) + 1;
-            strcpy((char *)ptr, conn->host);
-        }
-
-        // Send request
-        if (!nn_conn_proxy_send(conn, buf, bufsiz))
-            goto error;
-
-        // Wait for SOCKS server to reply
-        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)
-        {
-            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;
-        }
-
-        nn_conn_msg(conn, "SOCKS 4 connection established!\n");
+        case NN_PROXY_SOCKS4:
+        case NN_PROXY_SOCKS4A:
+            if (!nn_conn_socks4_negotiate(conn, port, host))
+                goto error;
+            nn_conn_msg(conn, "SOCKS 4 connection established!\n");
+            break;
     }
 
     nn_conn_reset(conn);