aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-01 11:09:12 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-01 11:09:12 +0000
commitece770d29305f4bbc02bfb8479742c1afa233706 (patch)
treec5df2ca74b92cd999b2a10d66f9ca0454e4f636f /src
parente1b8d8139a6e87901fbaec0e3b94451ac0701f1a (diff)
downloadgnunet-ece770d29305f4bbc02bfb8479742c1afa233706.tar.gz
gnunet-ece770d29305f4bbc02bfb8479742c1afa233706.zip
-add new proxy code
Diffstat (limited to 'src')
-rw-r--r--src/gns/Makefile.am12
-rw-r--r--src/gns/gns_proxy_proto.h87
-rw-r--r--src/gns/gnunet-gns-proxy.c214
3 files changed, 312 insertions, 1 deletions
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
31bin_PROGRAMS = \ 31bin_PROGRAMS = \
32 gnunet-service-gns \ 32 gnunet-service-gns \
33 $(DO_FCFSD) \ 33 $(DO_FCFSD) \
34 gnunet-gns 34 gnunet-gns \
35 gnunet-gns-proxy
35 36
36#noinst_PROGRAMS = \ 37#noinst_PROGRAMS = \
37# gnunet-gns-lookup 38# gnunet-gns-lookup
@@ -203,6 +204,15 @@ gnunet_gns_LDADD = \
203gnunet_gns_DEPENDENCIES = \ 204gnunet_gns_DEPENDENCIES = \
204 libgnunetgns.la 205 libgnunetgns.la
205 206
207gnunet_gns_proxy_SOURCES = \
208 gnunet-gns-proxy.c
209gnunet_gns_proxy_LDADD = \
210 $(top_builddir)/src/gns/libgnunetgns.la \
211 $(top_builddir)/src/util/libgnunetutil.la \
212 $(GN_LIBINTL)
213gnunet_gns_proxy_DEPENDENCIES = \
214 libgnunetgns.la
215
206gnunet_service_gns_SOURCES = \ 216gnunet_service_gns_SOURCES = \
207 gnunet-service-gns.c \ 217 gnunet-service-gns.c \
208 gnunet-service-gns_resolver.c \ 218 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 @@
1
2
3/* The socks phases */
4enum
5{
6 SOCKS5_INIT,
7 SOCKS5_REQUEST,
8 SOCKS5_DATA_TRANSFER
9};
10
11/* Client hello */
12struct socks5_client_hello
13{
14 uint8_t version;
15 uint8_t num_auth_methods;
16 char* auth_methods;
17};
18
19/* Client socks request */
20struct socks5_client_request
21{
22 uint8_t version;
23 uint8_t command;
24 uint8_t resvd;
25 uint8_t addr_type;
26 /*
27 * followed by either an ip4/ipv6 address
28 * or a domain name with a length field in front
29 */
30};
31
32/* Server hello */
33struct socks5_server_hello
34{
35 uint8_t version;
36 uint8_t auth_method;
37};
38
39#define BUF_WAIT_FOR_CURL 0
40#define BUF_WAIT_FOR_MHD 1
41
42/* Struct used to store connection
43 * information
44 */
45struct socks5_bridge
46{
47 int fd;
48 struct socks5_bridge* remote_end;
49 struct sockaddr addr;
50 socklen_t addr_len;
51 char host[256];
52 int status;
53
54 /* This is an ssl bridge? */
55 int use_ssl;
56
57 /* if use_ssl=1 we have a daemon associated */
58 struct MHD_Daemon *ssl_daemon;
59
60 /* http url + host */
61 char* full_url;
62
63 /* handle to curl */
64 //CURL* curl;
65
66 /* is response html? */
67 int res_is_html;
68
69 /* buffer structures */
70 pthread_t thread;
71 pthread_mutex_t m_done;
72 int is_done;
73 pthread_mutex_t m_buf;
74 //char MHD_CURL_BUF[CURL_MAX_WRITE_SIZE];
75 size_t MHD_CURL_BUF_SIZE;
76 int MHD_CURL_BUF_STATUS;
77};
78
79/* Server response to client requests */
80struct socks5_server_response
81{
82 uint8_t version;
83 uint8_t reply;
84 uint8_t reserved;
85 uint8_t addr_type;
86 uint8_t add_port[18];
87};
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 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include "platform.h"
22#include <gnunet_util_lib.h>
23#include "gns_proxy_proto.h"
24
25#define GNUNET_GNS_PROXY_PORT 7777
26
27
28struct Socks5Request
29{
30 struct Socks5Request *prev;
31 struct Socks5Request *next;
32
33 struct GNUNET_NETWORK_Handle *sock;
34
35 int state;
36
37 GNUNET_SCHEDULER_TaskIdentifier rtask;
38};
39
40struct Socks5Connections
41{
42 struct Socks5Request *head;
43 struct Socks5Request *tail;
44};
45
46
47unsigned long port = GNUNET_GNS_PROXY_PORT;
48static struct GNUNET_NETWORK_Handle *lsock;
49GNUNET_SCHEDULER_TaskIdentifier ltask;
50static struct Socks5Connections s5conns;
51
52/**
53 * Read data from incoming connection
54 *
55 * @param cls the closure
56 * @param tc the scheduler context
57 */
58static void
59do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
60{
61 struct Socks5Request *s5r = cls;
62 char rbuf[512];
63 unsigned int len;
64
65 s5r->rtask = GNUNET_SCHEDULER_NO_TASK;
66
67 if ((NULL != tc->write_ready) &&
68 (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->sock)) &&
69 (len = GNUNET_NETWORK_socket_recv (s5r->sock, &rbuf, sizeof (rbuf))))
70 {
71 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
72 "Successfully read %d bytes from socket\n",
73 len);
74 }
75 else
76 {
77 //ERROR!
78 GNUNET_NETWORK_socket_close (s5r->sock);
79 GNUNET_free(s5r);
80 return;
81 }
82
83 if (s5r->state == SOCKS5_INIT)
84 {
85 //DO sth etc
86 }
87
88 GNUNET_CONTAINER_DLL_remove (s5conns.head, s5conns.tail, s5r);
89
90}
91
92/**
93 * Accept new incoming connections
94 *
95 * @param cls the closure
96 * @param tc the scheduler context
97 */
98static void
99do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
100{
101 struct GNUNET_NETWORK_Handle *s;
102 struct Socks5Request *s5r;
103
104 ltask = GNUNET_SCHEDULER_NO_TASK;
105 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
106 return;
107
108 ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
109 lsock,
110 &do_accept, NULL);
111
112 s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
113
114 if (NULL == s)
115 {
116 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept");
117 return;
118 }
119
120 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
121 "Got an inbound connection, waiting for data\n");
122
123 s5r = GNUNET_malloc (sizeof (struct Socks5Request));
124 s5r->sock = s;
125 s5r->state = SOCKS5_INIT;
126 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
127 s5r->sock,
128 &do_read, s5r);
129 GNUNET_CONTAINER_DLL_insert (s5conns.head, s5conns.tail, s5r);
130}
131
132/**
133 * Main function that will be run
134 *
135 * @param cls closure
136 * @param args remaining command-line arguments
137 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
138 * @param cfg configuration
139 */
140static void
141run (void *cls, char *const *args, const char *cfgfile,
142 const struct GNUNET_CONFIGURATION_Handle *cfg)
143{
144 struct sockaddr_in sa;
145
146 memset (&sa, 0, sizeof (sa));
147 sa.sin_family = AF_INET;
148 sa.sin_port = htons (port);
149#if HAVE_SOCKADDR_IN_SIN_LEN
150 sa.sin_len = sizeof (sa);
151#endif
152
153 lsock = GNUNET_NETWORK_socket_create (AF_INET,
154 SOCK_STREAM,
155 0);
156
157 if ((NULL == lsock) ||
158 (GNUNET_OK !=
159 GNUNET_NETWORK_socket_bind (lsock, (const struct sockaddr *) &sa,
160 sizeof (sa))))
161 {
162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
163 "Failed to create listen socket bound to `%s'",
164 GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa)));
165 if (NULL != lsock)
166 GNUNET_NETWORK_socket_close (lsock);
167 return;
168 }
169
170 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock, 5))
171 {
172 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
173 "Failed to listen on socket bound to `%s'",
174 GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa)));
175 return;
176 }
177
178 ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
179 lsock, &do_accept, NULL);
180
181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
182 "Proxy listens on port %u\n",
183 port);
184
185}
186
187/**
188 * The main function for gnunet-gns-proxy.
189 *
190 * @param argc number of arguments from the command line
191 * @param argv command line arguments
192 * @return 0 ok, 1 on error
193 */
194int
195main (int argc, char *const *argv)
196{
197 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
198 {'p', "port", NULL,
199 gettext_noop ("listen on specified port"), 1,
200 &GNUNET_GETOPT_set_string, &port},
201 GNUNET_GETOPT_OPTION_END
202 };
203
204 int ret;
205
206 GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL);
207 ret =
208 (GNUNET_OK ==
209 GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy",
210 _("GNUnet GNS proxy"),
211 options,
212 &run, NULL)) ? 0 : 1;
213 return ret;
214}