gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r21693 - gnunet/src/gns


From: gnunet
Subject: [GNUnet-SVN] r21693 - gnunet/src/gns
Date: Fri, 1 Jun 2012 14:37:51 +0200

Author: schanzen
Date: 2012-06-01 14:37:50 +0200 (Fri, 01 Jun 2012)
New Revision: 21693

Modified:
   gnunet/src/gns/gns_proxy_proto.h
   gnunet/src/gns/gnunet-gns-proxy.c
Log:
-more


Modified: gnunet/src/gns/gns_proxy_proto.h
===================================================================
--- gnunet/src/gns/gns_proxy_proto.h    2012-06-01 12:03:53 UTC (rev 21692)
+++ gnunet/src/gns/gns_proxy_proto.h    2012-06-01 12:37:50 UTC (rev 21693)
@@ -1,4 +1,6 @@
 
+#define SOCKS_VERSION_5 0x05
+#define SOCKS_AUTH_NONE 0
 
 /* The socks phases */
 enum

Modified: gnunet/src/gns/gnunet-gns-proxy.c
===================================================================
--- gnunet/src/gns/gnunet-gns-proxy.c   2012-06-01 12:03:53 UTC (rev 21692)
+++ gnunet/src/gns/gnunet-gns-proxy.c   2012-06-01 12:37:50 UTC (rev 21693)
@@ -21,20 +21,56 @@
 #include "platform.h"
 #include <gnunet_util_lib.h>
 #include "gns_proxy_proto.h"
+#include "gns.h"
 
 #define GNUNET_GNS_PROXY_PORT 7777
 
+//TODO maybe make this an api call
+/**
+ * Checks if name is in tld
+ *
+ * @param name the name to check
+ * @param tld the TLD to check for
+ * @return GNUNET_YES or GNUNET_NO
+ */
+int
+is_tld(const char* name, const char* tld)
+{
+  int offset = 0;
 
+  if (strlen(name) <= strlen(tld))
+  {
+    return GNUNET_NO;
+  }
+
+  offset = strlen(name)-strlen(tld);
+  if (strcmp (name+offset, tld) != 0)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+               "%s is not in .%s TLD\n", name, tld);
+    return GNUNET_NO;
+  }
+
+  return GNUNET_YES;
+}
+
 struct Socks5Request
 {
   struct Socks5Request *prev;
   struct Socks5Request *next;
 
   struct GNUNET_NETWORK_Handle *sock;
+  struct GNUNET_NETWORK_Handle *remote_sock;
 
   int state;
 
   GNUNET_SCHEDULER_TaskIdentifier rtask;
+  GNUNET_SCHEDULER_TaskIdentifier wtask;
+
+  char rbuf[512];
+  char wbuf[512];
+  unsigned int rbuf_len;
+  unsigned int wbuf_len;
 };
 
 struct Socks5Connections
@@ -50,6 +86,37 @@
 static struct Socks5Connections s5conns;
 
 /**
+ * Write data to socket
+ *
+ * @param cls the closure
+ * @param tc scheduler context
+ */
+static void
+do_write (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct Socks5Request *s5r = cls;
+  unsigned int len = s5r->wbuf_len;
+
+  s5r->wtask = GNUNET_SCHEDULER_NO_TASK;
+
+  if ((NULL != tc->read_ready) &&
+      (GNUNET_NETWORK_fdset_isset (tc->write_ready, s5r->sock)) &&
+      (len = GNUNET_NETWORK_socket_send (s5r->sock, &s5r->wbuf,
+                                         len)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Successfully sent %d bytes to socket\n",
+                len);
+  }
+  else
+  {
+    GNUNET_NETWORK_socket_close (s5r->sock);
+    GNUNET_free(s5r);
+    return;
+  }
+}
+
+/**
  * Read data from incoming connection
  *
  * @param cls the closure
@@ -59,14 +126,26 @@
 do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct Socks5Request *s5r = cls;
-  char rbuf[512];
   unsigned int len;
+  struct socks5_client_hello *c_hello;
+  struct socks5_server_hello *s_hello;
+  struct socks5_client_request *c_req;
+  struct socks5_server_response *s_resp;
 
+  char domain[256];
+  uint8_t dom_len;
+  uint16_t req_port;
+  struct hostent *phost;
+  uint32_t remote_ip;
+  struct sockaddr_in remote_addr;
+  struct in_addr *r_sin_addr;
+
   s5r->rtask = GNUNET_SCHEDULER_NO_TASK;
 
   if ((NULL != tc->write_ready) &&
       (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->sock)) &&
-      (len = GNUNET_NETWORK_socket_recv (s5r->sock, &rbuf, sizeof (rbuf))))
+      (len = GNUNET_NETWORK_socket_recv (s5r->sock, &s5r->rbuf,
+                                         sizeof (s5r->rbuf))))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Successfully read %d bytes from socket\n",
@@ -82,11 +161,131 @@
 
   if (s5r->state == SOCKS5_INIT)
   {
-    //DO sth etc
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "SOCKS5 init\n");
+    c_hello = (struct socks5_client_hello*)&s5r->rbuf;
+
+    GNUNET_assert (c_hello->version == SOCKS_VERSION_5);
+
+    s_hello = (struct socks5_server_hello*)&s5r->wbuf;
+    s5r->wbuf_len = sizeof( struct socks5_server_hello );
+
+    s_hello->version = c_hello->version;
+    s_hello->auth_method = SOCKS_AUTH_NONE;
+
+    /* Write response to client */
+    s5r->wtask = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                                s5r->sock,
+                                                &do_write, s5r);
+
+    s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                                s5r->sock,
+                                                &do_read, s5r);
+
+    s5r->state = SOCKS5_REQUEST;
+    return;
   }
 
-  GNUNET_CONTAINER_DLL_remove (s5conns.head, s5conns.tail, s5r);
+  if (s5r->state == SOCKS5_REQUEST)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Processing SOCKS5 request\n");
+    c_req = (struct socks5_client_request*)&s5r->rbuf;
+    s_resp = (struct socks5_server_response*)&s5r->wbuf;
+    s5r->wbuf_len = sizeof (struct socks5_server_response);
 
+    GNUNET_assert (c_req->addr_type == 3);
+
+    dom_len = *((uint8_t*)(&(c_req->addr_type) + 1));
+    memset(domain, 0, sizeof(domain));
+    strncpy(domain, (char*)(&(c_req->addr_type) + 2), dom_len);
+    req_port = *((uint16_t*)(&(c_req->addr_type) + 2 + dom_len));
+
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Requested connection is %s:%d\n",
+                domain,
+                ntohs(req_port));
+
+    if (is_tld (domain, GNUNET_GNS_TLD) ||
+        is_tld (domain, GNUNET_GNS_TLD_ZKEY))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Requested connection is gnunet tld\n",
+                  domain);
+    }
+    else
+    {
+      phost = (struct hostent*)gethostbyname (domain);
+      if (phost == NULL)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "Resolve %s error!\n", domain );
+        s_resp->version = 0x05;
+        s_resp->reply = 0x01;
+        s5r->wtask = 
+          GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                          s5r->sock,
+                                          &do_write, s5r);
+        //ERROR!
+        //TODO! close socket after the write! schedule task
+        //GNUNET_NETWORK_socket_close (s5r->sock);
+        //GNUNET_free(s5r);
+        return;
+      }
+
+      s5r->remote_sock = GNUNET_NETWORK_socket_create (AF_INET,
+                                                       SOCK_STREAM,
+                                                       0);
+      r_sin_addr = (struct in_addr*)(phost->h_addr);
+      remote_ip = r_sin_addr->s_addr;
+      memset(&remote_addr, 0, sizeof(remote_addr));
+      remote_addr.sin_family = AF_INET;
+      remote_addr.sin_addr.s_addr = remote_ip;
+      remote_addr.sin_port = req_port;
+      
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "target server: %s:%u\n", inet_ntoa(remote_addr.sin_addr),
+                  ntohs(req_port));
+
+      GNUNET_assert ( s5r->remote_sock != NULL );
+
+      if (GNUNET_OK != 
+          GNUNET_NETWORK_socket_connect ( s5r->remote_sock,
+                                          (struct sockaddr*)&remote_addr,
+                                          sizeof (struct sockaddr)))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "socket request error...\n");
+        s_resp->version = 0x05;
+        s_resp->reply = 0x01;
+        s5r->wtask =
+          GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                          s5r->sock,
+                                          &do_write, s5r);
+        //TODO see above
+        return;
+      }
+
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "new remote connection\n");
+
+      s_resp->version = 0x05;
+      s_resp->reply = 0x00;
+      s_resp->reserved = 0x00;
+      s_resp->addr_type = 0x01;
+
+      s5r->state = SOCKS5_DATA_TRANSFER;
+
+      s5r->wtask =
+        GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                        s5r->sock,
+                                        &do_write, s5r);
+
+    }
+  }
+
+  //GNUNET_CONTAINER_DLL_remove (s5conns.head, s5conns.tail, s5r);
+
 }
 
 /**




reply via email to

[Prev in Thread] Current Thread [Next in Thread]