glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / util / test_socks.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2015, 2016 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14 */
15 /**
16  * @file util/test_socks.c
17  * @brief tests for socks.c
18  */
19 #include "platform.h"
20 #include "gnunet_util_lib.h"
21
22
23 #define PORT 35124
24
25 #define MYNAME "test_sockst"
26
27 static struct GNUNET_MQ_Handle *mq;
28
29 static struct GNUNET_SERVER_Handle *server;
30
31 static struct GNUNET_CONFIGURATION_Handle *cfg;
32
33 #define MY_TYPE 130
34
35 struct CopyContext
36 {
37   struct GNUNET_SERVER_Client *client;
38   struct GNUNET_MessageHeader *cpy;
39 };
40
41 static size_t
42 copy_msg (void *cls, size_t size, void *buf)
43 {
44   struct CopyContext *ctx = cls;
45   struct GNUNET_MessageHeader *cpy = ctx->cpy;
46
47   GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (cpy->size));
48   GNUNET_assert (size >= ntohs (cpy->size));
49   GNUNET_memcpy (buf, cpy, ntohs (cpy->size));
50   GNUNET_SERVER_receive_done (ctx->client, GNUNET_OK);
51   GNUNET_free (cpy);
52   GNUNET_free (ctx);
53   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message bounced back to client\n");
54   return sizeof (struct GNUNET_MessageHeader);
55 }
56
57
58 /**
59  * Callback that just bounces the message back to the sender.
60  */
61 static void
62 echo_cb (void *cls, struct GNUNET_SERVER_Client *client,
63          const struct GNUNET_MessageHeader *message)
64 {
65   struct CopyContext *cc;
66   struct GNUNET_MessageHeader *cpy;
67
68   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
69               "Receiving message from client, bouncing back\n");
70   GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (message->size));
71   cc = GNUNET_new (struct CopyContext);
72   cc->client = client;
73   cpy = GNUNET_malloc (ntohs (message->size));
74   GNUNET_memcpy (cpy, message, ntohs (message->size));
75   cc->cpy = cpy;
76   GNUNET_assert (NULL !=
77                  GNUNET_SERVER_notify_transmit_ready (client,
78                                                       ntohs (message->size),
79                                                       GNUNET_TIME_UNIT_SECONDS,
80                                                       &copy_msg, cc));
81 }
82
83
84 static struct GNUNET_SERVER_MessageHandler handlers[] = {
85   {&echo_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
86   {NULL, NULL, 0, 0}
87 };
88
89
90 static void
91 handle_bounce (void *cls,
92                const struct GNUNET_MessageHeader *got)
93 {
94   int *ok = cls;
95
96   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
97               "Receiving bounce, checking content\n");
98   GNUNET_assert (NULL != got);
99   GNUNET_MQ_destroy (mq);
100   mq = NULL;
101   GNUNET_SERVER_destroy (server);
102   server = NULL;
103   *ok = 0;
104 }
105
106
107 /**
108  * Generic error handler, called with the appropriate error code and
109  * the same closure specified at the creation of the message queue.
110  * Not every message queue implementation supports an error handler.
111  *
112  * @param cls closure with the `struct GNUNET_STATISTICS_Handle *`
113  * @param error error code
114  */
115 static void
116 mq_error_handler (void *cls,
117                   enum GNUNET_MQ_Error error)
118 {
119   GNUNET_assert (0); /* should never happen */
120 }
121
122
123 static void
124 task (void *cls)
125 {
126   struct sockaddr_in sa;
127   struct sockaddr *sap[2];
128   socklen_t slens[2];
129   struct GNUNET_MQ_Envelope *env;
130   struct GNUNET_MessageHeader *msg;
131   struct GNUNET_MQ_MessageHandler chandlers[] = {
132     GNUNET_MQ_hd_fixed_size (bounce,
133                              MY_TYPE,
134                              struct GNUNET_MessageHeader,
135                              cls),
136     GNUNET_MQ_handler_end ()
137   };
138
139   /* test IPC between client and server */
140   sap[0] = (struct sockaddr *) &sa;
141   slens[0] = sizeof (sa);
142   sap[1] = NULL;
143   slens[1] = 0;
144   memset (&sa, 0, sizeof (sa));
145 #if HAVE_SOCKADDR_IN_SIN_LEN
146   sa.sin_len = sizeof (sa);
147 #endif
148   sa.sin_family = AF_INET;
149   sa.sin_port = htons (PORT);
150   server =
151       GNUNET_SERVER_create (NULL, NULL, sap, slens,
152                             GNUNET_TIME_relative_multiply
153                             (GNUNET_TIME_UNIT_MILLISECONDS, 10000), GNUNET_NO);
154   GNUNET_assert (server != NULL);
155   handlers[0].callback_cls = cls;
156   handlers[1].callback_cls = cls;
157   GNUNET_SERVER_add_handlers (server, handlers);
158   mq = GNUNET_CLIENT_connect (cfg,
159                               MYNAME,
160                               chandlers,
161                               &mq_error_handler,
162                               NULL);
163   GNUNET_assert (NULL != mq);
164   env = GNUNET_MQ_msg (msg,
165                        MY_TYPE);
166   GNUNET_MQ_send (mq,
167                   env);
168 }
169
170
171 int
172 main (int argc, char *argv[])
173 {
174   int ok;
175   int status;
176   const char *socksport = "1081";
177
178   GNUNET_log_setup ("test_client",
179                     "WARNING",
180                     NULL);
181
182   pid_t pid = fork();
183   GNUNET_assert (pid >= 0);
184   if (pid == 0)
185   {
186     execlp ("ssh",
187             "ssh","-D",socksport,
188             "-o","BatchMode yes",
189             "-o","UserKnownHostsFile /tmp/gnunet_test_socks_ssh_garbage",
190             "-o","StrictHostKeyChecking no",
191             "127.0.0.1","-N",(char*)NULL);
192     perror ("execlp (\"ssh\",\"ssh\",...,\"-D\",\"1081\",\"127.0.0.1\",\"-N\") ");
193     printf (""
194 "Please ensure you have ssh installed and have sshd installed and running :\n"
195 "\tsudo apt-get install openssh-client openssh-server\n"
196 "If you run Tor as a network proxy then Tor might prevent ssh from connecting\n"
197 "to localhost.  Please either run  make check  from an unproxied user, or else\n"
198 "add these lines to the beginning of your ~/.ssh/config file :"
199 "\tHost 127.0.0.1 localhost\n"
200 "\t  CheckHostIP no\n"
201 "\t  Protocol 2\n"
202 "\t  ProxyCommand nc 127.0.0.1 22\n");
203     kill (getppid(), SIGALRM);
204     return 1;
205   }
206   if (0 != sleep (1))
207   {
208     /* sleep interrupted, likely SIGALRM, failure to
209        launch child, terminate */
210     printf (""
211 "Please ensure you have ssh installed and have sshd installed and running :\n"
212 "\tsudo apt-get install openssh-client openssh-server\n"
213 "If you run Tor as a network proxy then Tor might prevent ssh from connecting\n"
214 "to localhost.  Please either run  make check  from an unproxied user, or else\n"
215 "add these lines to the beginning of your ~/.ssh/config file :"
216 "\tHost 127.0.0.1 localhost\n"
217 "\t  CheckHostIP no\n"
218 "\t  Protocol 2\n"
219 "\t  ProxyCommand nc 127.0.0.1 22\n");
220     return 77;
221   }
222   /* check if child exec()ed but died */
223   if (0 != waitpid (pid, &status, WNOHANG))
224   {
225     printf (""
226 "If you run Tor as a network proxy then Tor might prevent ssh from connecting\n"
227 "to localhost.  Please either run  make check  from an unproxied user, or else\n"
228 "add these lines to the beginning of your ~/.ssh/config file :"
229 "\tHost 127.0.0.1 localhost\n"
230 "\t  CheckHostIP no\n"
231 "\t  Protocol 2\n"
232 "\t  ProxyCommand nc 127.0.0.1 22\n");
233     return 77;
234   }
235
236   cfg = GNUNET_CONFIGURATION_create ();
237   GNUNET_CONFIGURATION_set_value_string (cfg, MYNAME, "SOCKSHOST", "127.0.0.1");
238   GNUNET_CONFIGURATION_set_value_string (cfg, MYNAME, "SOCKSPORT", socksport);
239   GNUNET_CONFIGURATION_set_value_number (cfg, MYNAME, "PORT", PORT);
240   GNUNET_CONFIGURATION_set_value_string (cfg, MYNAME, "HOSTNAME", "127.0.0.1");
241   ok = 1;
242   GNUNET_SCHEDULER_run (&task, &ok);
243   GNUNET_CONFIGURATION_destroy (cfg);
244
245   GNUNET_break (0 == kill (pid, SIGTERM));
246   GNUNET_break (pid == waitpid (pid, &status, 0));
247   return ok;
248 }
249
250 /* end of test_socks.c */