2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 #include <gnunet_util_lib.h>
23 #include "gns_proxy_proto.h"
25 #define GNUNET_GNS_PROXY_PORT 7777
30 struct Socks5Request *prev;
31 struct Socks5Request *next;
33 struct GNUNET_NETWORK_Handle *sock;
37 GNUNET_SCHEDULER_TaskIdentifier rtask;
40 struct Socks5Connections
42 struct Socks5Request *head;
43 struct Socks5Request *tail;
47 unsigned long port = GNUNET_GNS_PROXY_PORT;
48 static struct GNUNET_NETWORK_Handle *lsock;
49 GNUNET_SCHEDULER_TaskIdentifier ltask;
50 static struct Socks5Connections s5conns;
53 * Read data from incoming connection
55 * @param cls the closure
56 * @param tc the scheduler context
59 do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
61 struct Socks5Request *s5r = cls;
65 s5r->rtask = GNUNET_SCHEDULER_NO_TASK;
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))))
71 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
72 "Successfully read %d bytes from socket\n",
78 GNUNET_NETWORK_socket_close (s5r->sock);
83 if (s5r->state == SOCKS5_INIT)
88 GNUNET_CONTAINER_DLL_remove (s5conns.head, s5conns.tail, s5r);
93 * Accept new incoming connections
95 * @param cls the closure
96 * @param tc the scheduler context
99 do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
101 struct GNUNET_NETWORK_Handle *s;
102 struct Socks5Request *s5r;
104 ltask = GNUNET_SCHEDULER_NO_TASK;
105 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
108 ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
112 s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
116 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept");
120 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
121 "Got an inbound connection, waiting for data\n");
123 s5r = GNUNET_malloc (sizeof (struct Socks5Request));
125 s5r->state = SOCKS5_INIT;
126 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
129 GNUNET_CONTAINER_DLL_insert (s5conns.head, s5conns.tail, s5r);
133 * Main function that will be run
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
141 run (void *cls, char *const *args, const char *cfgfile,
142 const struct GNUNET_CONFIGURATION_Handle *cfg)
144 struct sockaddr_in sa;
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);
153 lsock = GNUNET_NETWORK_socket_create (AF_INET,
157 if ((NULL == lsock) ||
159 GNUNET_NETWORK_socket_bind (lsock, (const struct sockaddr *) &sa,
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)));
166 GNUNET_NETWORK_socket_close (lsock);
170 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock, 5))
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)));
178 ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
179 lsock, &do_accept, NULL);
181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
182 "Proxy listens on port %u\n",
188 * The main function for gnunet-gns-proxy.
190 * @param argc number of arguments from the command line
191 * @param argv command line arguments
192 * @return 0 ok, 1 on error
195 main (int argc, char *const *argv)
197 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
199 gettext_noop ("listen on specified port"), 1,
200 &GNUNET_GETOPT_set_string, &port},
201 GNUNET_GETOPT_OPTION_END
206 GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL);
209 GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy",
210 _("GNUnet GNS proxy"),
212 &run, NULL)) ? 0 : 1;