changeset 116:bc540c5bfaf9

More work on network module.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 21 Jun 2014 23:19:57 +0300
parents 13f001f1ad6e
children bfae4758fa6f
files th_network.c th_network.h
diffstat 2 files changed, 51 insertions(+), 122 deletions(-) [+]
line wrap: on
line diff
--- a/th_network.c	Sat Jun 21 23:11:36 2014 +0300
+++ b/th_network.c	Sat Jun 21 23:19:57 2014 +0300
@@ -21,24 +21,6 @@
 };
 
 
-struct th_socks4_t
-{
-    uint8_t version;
-    uint8_t command;
-    in_port_t port;
-    in_addr_t addr;
-} __attribute__((__packed__));
-
-
-struct th_socks4_res_t
-{
-    uint8_t nb;
-    uint8_t result;
-    in_port_t port;
-    in_addr_t addr;
-} __attribute__((__packed__));
-
-
 static const char *th_proxy_types[] =
 {
     "none",
@@ -212,89 +194,63 @@
 }
 
 
-static int th_conn_proxy_send(th_conn_t *conn, void *buf, size_t bufsiz)
+static int th_conn_proxy_send(th_conn_t *conn, th_growbuf_t *buf)
 {
     int ret;
     th_conn_reset(conn);
-    ret = th_conn_send_buf(conn, buf, bufsiz);
+    ret = th_conn_send_buf(conn, (void *) buf->data, buf->len);
     th_free(buf);
     return ret;
 }
 
 
-static uint8_t* th_conn_bufmalloc(th_conn_t *conn, const size_t bufsiz)
-{
-    uint8_t *buf;
-
-    if ((buf = th_malloc(bufsiz)) == NULL)
-    {
-        th_conn_err(conn, THERR_MALLOC,
-            "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n",
-            bufsiz);
-
-        return NULL;
-    }
-    
-    return buf;
-}
-
-
 static int th_conn_socks4_negotiate(th_conn_t *conn, const int port, const char *host)
 {
-    struct th_socks4_res_t *sockres;
-    struct th_socks4_t *socksh;
-    size_t bufsiz;
-    uint8_t *ptr, *buf;
+    th_growbuf_t buf;
+    uint8_t *ptr;
     int err = THERR_INIT_FAIL;
 
     (void) host;
 
     th_conn_msg(conn, THLOG_INFO, "Initializing SOCKS 4/a proxy negotiation.\n");
 
-    bufsiz = sizeof(struct th_socks4_t) + strlen(conn->proxy.userid) + 1;
+    // Create SOCKS 4 handshake
+    th_growbuf_init(&buf, 128);
+    th_growbuf_put_u8(&buf, 4);  // Protocol version
+    th_growbuf_put_u8(&buf, TH_PROXY_CMD_CONNECT); // Command
+    th_growbuf_put_u16_be(&buf, port);
     if (conn->proxy.type == TH_PROXY_SOCKS4A)
-        bufsiz += strlen(conn->host) + 1;
-
-    if ((ptr = buf = th_conn_bufmalloc(conn, bufsiz)) == NULL)
-        return conn->err;
+        th_growbuf_put_u32_be(&buf, 0x00000032);
+    else
+        th_growbuf_put_str(&buf, (uint8_t *) &(conn->addr.s_addr), sizeof(conn->addr.s_addr));
 
-    // Create SOCKS 4 handshake
-    socksh = (struct th_socks4_t *) buf;
-    socksh->version = 4;
-    socksh->command = TH_PROXY_CMD_CONNECT;
-    socksh->port    = htons(port);
-    socksh->addr    = (conn->proxy.type == TH_PROXY_SOCKS4A) ?  htonl(0x00000032) : conn->addr.s_addr;
-    ptr += sizeof(struct th_socks4_t);
-
-    strcpy((char *) ptr, conn->proxy.userid);
-
+    th_growbuf_puts(&buf, conn->proxy.userid, TRUE);
     if (conn->proxy.type == TH_PROXY_SOCKS4A)
-    {
-        ptr += strlen(conn->proxy.userid) + 1;
-        strcpy((char *)ptr, conn->host);
-    }
+        th_growbuf_puts(&buf, conn->host, TRUE);
 
     // Send request
-    if ((err = th_conn_proxy_send(conn, buf, bufsiz)) != THERR_OK)
+    if ((err = th_conn_proxy_send(conn, &buf)) != THERR_OK)
         return err;
 
     // Wait for SOCKS server to reply
     if (th_conn_proxy_wait(conn) != TH_CONN_DATA_AVAIL)
         return err;
 
-    sockres = (struct th_socks4_res_t *) &(conn->buf);
-    if (sockres->nb != 0)
+    ptr = (uint8_t*) conn->buf;
+    if (*ptr != 0)
     {
         err = THERR_INIT_FAIL;
         th_conn_err(conn, err,
-            "Invalid SOCKS 4 server reply, does not begin with NUL byte (%d).\n", sockres->nb);
+            "Invalid SOCKS 4 server reply, does not begin with NUL byte (%d).\n",
+            *ptr);
         return err;
     }
 
-    if (sockres->result != 0x5a)
+    ptr++;
+    if (*ptr != 0x5a)
     {
         const char *s = NULL;
-        switch (sockres->result)
+        switch (*ptr)
         {
             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;
@@ -303,9 +259,7 @@
         }
 
         err = THERR_INIT_FAIL;
-        th_conn_err(conn, err,
-            "SOCKS 4 setup failed, 0x%02x: %s.\n",
-            sockres->result, s);
+        th_conn_err(conn, err, "SOCKS 4 setup failed, 0x%02x: %s.\n", *ptr, s);
         return err;
     }
 
@@ -315,8 +269,9 @@
 
 static int th_conn_socks5_negotiate(th_conn_t *conn, const int port, const char *host)
 {
-    size_t bufsiz, userid_len = 0, passwd_len = 0;
-    uint8_t *ptr, *buf;
+    size_t userid_len = 0, passwd_len = 0;
+    th_growbuf_t buf;
+    uint8_t *ptr;
     int avail, auth, err = THERR_INIT_FAIL;
 
     th_conn_msg(conn, THLOG_INFO, "Initializing SOCKS 5 proxy negotiation.\n");
@@ -358,25 +313,15 @@
             goto out;
     }
 
-    bufsiz = 2 + avail;
-    if ((ptr = buf = th_conn_bufmalloc(conn, bufsiz)) == NULL)
-        return conn->err;
 
     // Form handshake packet
-    *ptr++ = 0x05;   // Protocol version
-    *ptr++ = avail;  // # of available auth methods
-    switch (conn->proxy.auth_type)
-    {
-        case TH_PROXY_AUTH_NONE:
-            *ptr++ = TH_SOCKS5_AUTH_NONE;
-
-        case TH_PROXY_AUTH_USER:
-            *ptr++ = TH_SOCKS5_AUTH_USER;
-            break;
-    }
+    th_growbuf_init(&buf, 0);
+    th_growbuf_put_u8(&buf, 0x05);   // Protocol version
+    th_growbuf_put_u8(&buf, avail);  // # of available auth methods
+    th_growbuf_put_u8(&buf, auth);
 
     // Send request
-    if ((err = th_conn_proxy_send(conn, buf, bufsiz)) != THERR_OK)
+    if ((err = th_conn_proxy_send(conn, &buf)) != THERR_OK)
         goto out;
 
     // Wait for SOCKS server to reply
@@ -405,22 +350,16 @@
     if (auth == TH_SOCKS5_AUTH_USER)
     {
         // Attempt user/pass authentication (RFC 1929)
-        bufsiz = 1 + 1 + 1 + userid_len + passwd_len;
-        if ((ptr = buf = th_conn_bufmalloc(conn, bufsiz)) == NULL)
-            return FALSE;
-
-        *ptr++ = 0x01;
-
-        *ptr++ = userid_len;
-        memcpy(ptr, conn->proxy.userid, userid_len);
-        ptr += userid_len;
-
-        *ptr++ = passwd_len;
-        memcpy(ptr, conn->proxy.passwd, passwd_len);
-        ptr += passwd_len;
+        th_growbuf_init(&buf, 256);
+        
+        th_growbuf_put_u8(&buf, 0x01);
+        th_growbuf_put_u8(&buf, userid_len);
+        th_growbuf_puts(&buf, conn->proxy.userid, FALSE);
+        th_growbuf_put_u8(&buf, passwd_len);
+        th_growbuf_puts(&buf, conn->proxy.passwd, FALSE);
 
         // Send request
-        if ((err = th_conn_proxy_send(conn, buf, bufsiz)) != THERR_OK)
+        if ((err = th_conn_proxy_send(conn, &buf)) != THERR_OK)
             goto out;
 
         // Wait for SOCKS server to reply
@@ -457,28 +396,17 @@
 
 #if 0
     // Form client connection request packet
-    bufsiz = 4;
-    
-    if ((ptr = buf = th_malloc(bufsiz)) == NULL)
-    {
-        th_conn_err(conn, THERR_MALLOC,
-            "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n", bufsiz);
-        return FALSE;
-    }
+    th_growbuf_init(&buf, 128);
 
-    *ptr++ = 0x05;   // Protocol version
-    *ptr++ = cmd;
-    *ptr++ = 0x00;
-    *ptr++ = SOCKS5_ADDR_IPV4;
-
-    memcpy(ptr, conn->addr.s_addr, sizeof(conn->addr.s_addr));
-    ptr += sizeof(conn->addr.s_addr);
-    tmpPort = htons(port);
-    memcpy(ptr, tmpPort, sizeof(tmpPort));
-
+    th_growbuf_put_u8(&buf, 0x05); // Protocol version
+    th_growbuf_put_u8(&buf, cmd);
+    th_growbuf_put_u8(&buf, 0x00);
+    th_growbuf_put_u8(&buf, SOCKS5_ADDR_IPV4);
+    th_growbuf_put_str(&buf, conn->addr.s_addr, sizeof(conn->addr.s_addr));
+    th_growbuf_put_u16_be(&buf, port);
 
     // Send request
-    if ((err = th_conn_proxy_send(conn, buf, bufsiz)) != THERR_OK)
+    if ((err = th_conn_proxy_send(conn, &buf)) != THERR_OK)
         goto out;
 
     // Wait for SOCKS server to reply
@@ -513,6 +441,7 @@
 #endif
 
 out:
+    th_growbuf_free(&buf);
 
     return THERR_OK;
 }
@@ -648,10 +577,10 @@
 }
 
 
-int th_conn_send_buf(th_conn_t *conn, const char *buf, const size_t len)
+int th_conn_send_buf(th_conn_t *conn, const void *buf, const size_t len)
 {
     size_t bufLeft = len;
-    const char *bufPtr = buf;
+    const uint8_t *bufPtr = (uint8_t *) buf;
 
     while (bufLeft > 0)
     {
--- a/th_network.h	Sat Jun 21 23:11:36 2014 +0300
+++ b/th_network.h	Sat Jun 21 23:19:57 2014 +0300
@@ -136,7 +136,7 @@
 void        th_conn_reset(th_conn_t *);
 
 int         th_conn_pull(th_conn_t *);
-int         th_conn_send_buf(th_conn_t *, const char *buf, const size_t len);
+int         th_conn_send_buf(th_conn_t *, const void *buf, const size_t len);
 BOOL        th_conn_check(th_conn_t *);