aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns-proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-gns-proxy.c')
-rw-r--r--src/gns/gnunet-gns-proxy.c214
1 files changed, 214 insertions, 0 deletions
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}