From ece770d29305f4bbc02bfb8479742c1afa233706 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Fri, 1 Jun 2012 11:09:12 +0000 Subject: [PATCH] -add new proxy code --- src/gns/Makefile.am | 12 ++- src/gns/gns_proxy_proto.h | 87 +++++++++++++++ src/gns/gnunet-gns-proxy.c | 214 +++++++++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 src/gns/gns_proxy_proto.h create mode 100644 src/gns/gnunet-gns-proxy.c diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 2e28a6a90..33b10c2bb 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am @@ -31,7 +31,8 @@ endif bin_PROGRAMS = \ gnunet-service-gns \ $(DO_FCFSD) \ - gnunet-gns + gnunet-gns \ + gnunet-gns-proxy #noinst_PROGRAMS = \ # gnunet-gns-lookup @@ -203,6 +204,15 @@ gnunet_gns_LDADD = \ gnunet_gns_DEPENDENCIES = \ libgnunetgns.la +gnunet_gns_proxy_SOURCES = \ + gnunet-gns-proxy.c +gnunet_gns_proxy_LDADD = \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) +gnunet_gns_proxy_DEPENDENCIES = \ + libgnunetgns.la + gnunet_service_gns_SOURCES = \ gnunet-service-gns.c \ gnunet-service-gns_resolver.c \ diff --git a/src/gns/gns_proxy_proto.h b/src/gns/gns_proxy_proto.h new file mode 100644 index 000000000..85a203d7d --- /dev/null +++ b/src/gns/gns_proxy_proto.h @@ -0,0 +1,87 @@ + + +/* The socks phases */ +enum +{ + SOCKS5_INIT, + SOCKS5_REQUEST, + SOCKS5_DATA_TRANSFER +}; + +/* Client hello */ +struct socks5_client_hello +{ + uint8_t version; + uint8_t num_auth_methods; + char* auth_methods; +}; + +/* Client socks request */ +struct socks5_client_request +{ + uint8_t version; + uint8_t command; + uint8_t resvd; + uint8_t addr_type; + /* + * followed by either an ip4/ipv6 address + * or a domain name with a length field in front + */ +}; + +/* Server hello */ +struct socks5_server_hello +{ + uint8_t version; + uint8_t auth_method; +}; + +#define BUF_WAIT_FOR_CURL 0 +#define BUF_WAIT_FOR_MHD 1 + +/* Struct used to store connection + * information + */ +struct socks5_bridge +{ + int fd; + struct socks5_bridge* remote_end; + struct sockaddr addr; + socklen_t addr_len; + char host[256]; + int status; + + /* This is an ssl bridge? */ + int use_ssl; + + /* if use_ssl=1 we have a daemon associated */ + struct MHD_Daemon *ssl_daemon; + + /* http url + host */ + char* full_url; + + /* handle to curl */ + //CURL* curl; + + /* is response html? */ + int res_is_html; + + /* buffer structures */ + pthread_t thread; + pthread_mutex_t m_done; + int is_done; + pthread_mutex_t m_buf; + //char MHD_CURL_BUF[CURL_MAX_WRITE_SIZE]; + size_t MHD_CURL_BUF_SIZE; + int MHD_CURL_BUF_STATUS; +}; + +/* Server response to client requests */ +struct socks5_server_response +{ + uint8_t version; + uint8_t reply; + uint8_t reserved; + uint8_t addr_type; + uint8_t add_port[18]; +}; diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c new file mode 100644 index 000000000..a2e4ee6a5 --- /dev/null +++ b/src/gns/gnunet-gns-proxy.c @@ -0,0 +1,214 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "platform.h" +#include +#include "gns_proxy_proto.h" + +#define GNUNET_GNS_PROXY_PORT 7777 + + +struct Socks5Request +{ + struct Socks5Request *prev; + struct Socks5Request *next; + + struct GNUNET_NETWORK_Handle *sock; + + int state; + + GNUNET_SCHEDULER_TaskIdentifier rtask; +}; + +struct Socks5Connections +{ + struct Socks5Request *head; + struct Socks5Request *tail; +}; + + +unsigned long port = GNUNET_GNS_PROXY_PORT; +static struct GNUNET_NETWORK_Handle *lsock; +GNUNET_SCHEDULER_TaskIdentifier ltask; +static struct Socks5Connections s5conns; + +/** + * Read data from incoming connection + * + * @param cls the closure + * @param tc the scheduler context + */ +static void +do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Socks5Request *s5r = cls; + char rbuf[512]; + unsigned int len; + + 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)))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Successfully read %d bytes from socket\n", + len); + } + else + { + //ERROR! + GNUNET_NETWORK_socket_close (s5r->sock); + GNUNET_free(s5r); + return; + } + + if (s5r->state == SOCKS5_INIT) + { + //DO sth etc + } + + GNUNET_CONTAINER_DLL_remove (s5conns.head, s5conns.tail, s5r); + +} + +/** + * Accept new incoming connections + * + * @param cls the closure + * @param tc the scheduler context + */ +static void +do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_NETWORK_Handle *s; + struct Socks5Request *s5r; + + ltask = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + + ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + lsock, + &do_accept, NULL); + + s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); + + if (NULL == s) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept"); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got an inbound connection, waiting for data\n"); + + s5r = GNUNET_malloc (sizeof (struct Socks5Request)); + s5r->sock = s; + s5r->state = SOCKS5_INIT; + s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_read, s5r); + GNUNET_CONTAINER_DLL_insert (s5conns.head, s5conns.tail, s5r); +} + +/** + * Main function that will be run + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct sockaddr_in sa; + + memset (&sa, 0, sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons (port); +#if HAVE_SOCKADDR_IN_SIN_LEN + sa.sin_len = sizeof (sa); +#endif + + lsock = GNUNET_NETWORK_socket_create (AF_INET, + SOCK_STREAM, + 0); + + if ((NULL == lsock) || + (GNUNET_OK != + GNUNET_NETWORK_socket_bind (lsock, (const struct sockaddr *) &sa, + sizeof (sa)))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to create listen socket bound to `%s'", + GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa))); + if (NULL != lsock) + GNUNET_NETWORK_socket_close (lsock); + return; + } + + if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock, 5)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to listen on socket bound to `%s'", + GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa))); + return; + } + + ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + lsock, &do_accept, NULL); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Proxy listens on port %u\n", + port); + +} + +/** + * The main function for gnunet-gns-proxy. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'p', "port", NULL, + gettext_noop ("listen on specified port"), 1, + &GNUNET_GETOPT_set_string, &port}, + GNUNET_GETOPT_OPTION_END + }; + + int ret; + + GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL); + ret = + (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy", + _("GNUnet GNS proxy"), + options, + &run, NULL)) ? 0 : 1; + return ret; +} -- 2.25.1