diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-15 20:41:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-15 20:41:40 +0000 |
commit | 1574e0f8c2a55363c024a95f440ba7be647efbe1 (patch) | |
tree | 5e4507d9aa404ac983c5774b71b25ec6174ee7cc /src/vpn | |
parent | 5ec7048ed9ffeddbe06e34a31d388080fae143e5 (diff) | |
download | gnunet-1574e0f8c2a55363c024a95f440ba7be647efbe1.tar.gz gnunet-1574e0f8c2a55363c024a95f440ba7be647efbe1.zip |
-removing legacy dns/vpn/exit code and renaming -new versions to current
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/Makefile.am | 25 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-exit.c | 1501 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-vpn.c | 1808 | ||||
-rw-r--r-- | src/vpn/test-conf.conf | 276 |
4 files changed, 1 insertions, 3609 deletions
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am index be28949c5..bb0993c66 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am | |||
@@ -30,23 +30,12 @@ lib_LTLIBRARIES = \ | |||
30 | 30 | ||
31 | 31 | ||
32 | bin_PROGRAMS = \ | 32 | bin_PROGRAMS = \ |
33 | gnunet-daemon-exit gnunet-daemon-vpn $(VPNBIN) gnunet-service-vpn gnunet-vpn | 33 | $(VPNBIN) gnunet-service-vpn gnunet-vpn |
34 | 34 | ||
35 | 35 | ||
36 | gnunet_helper_vpn_SOURCES = \ | 36 | gnunet_helper_vpn_SOURCES = \ |
37 | gnunet-helper-vpn.c | 37 | gnunet-helper-vpn.c |
38 | 38 | ||
39 | gnunet_daemon_vpn_SOURCES = \ | ||
40 | gnunet-daemon-vpn.c | ||
41 | gnunet_daemon_vpn_LDADD = \ | ||
42 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
43 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
44 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
45 | $(top_builddir)/src/mesh/libgnunetmesh.la \ | ||
46 | $(top_builddir)/src/dns/libgnunetdnsparser.la \ | ||
47 | $(top_builddir)/src/dns/libgnunetdns.la \ | ||
48 | $(GN_LIBINTL) | ||
49 | |||
50 | gnunet_service_vpn_SOURCES = \ | 39 | gnunet_service_vpn_SOURCES = \ |
51 | gnunet-service-vpn.c | 40 | gnunet-service-vpn.c |
52 | gnunet_service_vpn_LDADD = \ | 41 | gnunet_service_vpn_LDADD = \ |
@@ -57,15 +46,6 @@ gnunet_service_vpn_LDADD = \ | |||
57 | gnunet_service_vpn_CFLAGS = \ | 46 | gnunet_service_vpn_CFLAGS = \ |
58 | -I$(top_srcdir)/src/exit $(CFLAGS) | 47 | -I$(top_srcdir)/src/exit $(CFLAGS) |
59 | 48 | ||
60 | gnunet_daemon_exit_SOURCES = \ | ||
61 | gnunet-daemon-exit.c | ||
62 | gnunet_daemon_exit_LDADD = \ | ||
63 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
64 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
65 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
66 | $(top_builddir)/src/mesh/libgnunetmesh.la \ | ||
67 | $(GN_LIBINTL) | ||
68 | |||
69 | gnunet_vpn_SOURCES = \ | 49 | gnunet_vpn_SOURCES = \ |
70 | gnunet-vpn.c | 50 | gnunet-vpn.c |
71 | gnunet_vpn_LDADD = \ | 51 | gnunet_vpn_LDADD = \ |
@@ -94,6 +74,3 @@ endif | |||
94 | # $(top_builddir)/src/transport/libgnunettransport.la \ | 74 | # $(top_builddir)/src/transport/libgnunettransport.la \ |
95 | # $(top_builddir)/src/util/libgnunetutil.la | 75 | # $(top_builddir)/src/util/libgnunetutil.la |
96 | 76 | ||
97 | EXTRA_DIST = \ | ||
98 | gnunet-vpn-packet.h \ | ||
99 | test-conf.conf | ||
diff --git a/src/vpn/gnunet-daemon-exit.c b/src/vpn/gnunet-daemon-exit.c deleted file mode 100644 index 6d5dc7797..000000000 --- a/src/vpn/gnunet-daemon-exit.c +++ /dev/null | |||
@@ -1,1501 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010, 2012 Christian Grothoff | ||
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 | /** | ||
22 | * @file vpn/gnunet-daemon-exit.c | ||
23 | * @brief | ||
24 | * @author Philipp Toelke | ||
25 | */ | ||
26 | #include <platform.h> | ||
27 | #include <gnunet_common.h> | ||
28 | #include <gnunet_program_lib.h> | ||
29 | #include <gnunet_protocols.h> | ||
30 | #include <gnunet_applications.h> | ||
31 | #include <gnunet_mesh_service.h> | ||
32 | #include <gnunet_constants.h> | ||
33 | #include <string.h> | ||
34 | |||
35 | #include "gnunet-vpn-packet.h" | ||
36 | |||
37 | |||
38 | struct remote_addr | ||
39 | { | ||
40 | char addrlen; | ||
41 | unsigned char addr[16]; | ||
42 | char proto; | ||
43 | }; | ||
44 | |||
45 | /** | ||
46 | * This struct is saved into the services-hashmap | ||
47 | */ | ||
48 | struct redirect_service | ||
49 | { | ||
50 | /** | ||
51 | * One of 4 or 6 | ||
52 | */ | ||
53 | unsigned int version; | ||
54 | uint16_t my_port; | ||
55 | uint16_t remote_port; | ||
56 | |||
57 | union | ||
58 | { | ||
59 | struct | ||
60 | { | ||
61 | char ip4address[4]; | ||
62 | } v4; | ||
63 | struct | ||
64 | { | ||
65 | char ip6address[16]; | ||
66 | } v6; | ||
67 | }; | ||
68 | }; | ||
69 | |||
70 | struct redirect_info | ||
71 | { | ||
72 | /** | ||
73 | * The source-address of this connection. When a packet to this address is | ||
74 | * received, this tunnel is used to forward it. ipv4-addresses will be put | ||
75 | * here left-aligned */ | ||
76 | char addr[16]; | ||
77 | /** | ||
78 | * The source-port of this connection | ||
79 | */ | ||
80 | uint16_t pt; | ||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * This struct is saved into {tcp,udp}_connections; | ||
85 | */ | ||
86 | struct redirect_state | ||
87 | { | ||
88 | struct GNUNET_MESH_Tunnel *tunnel; | ||
89 | GNUNET_HashCode desc; | ||
90 | struct redirect_service *serv; | ||
91 | struct remote_addr remote; | ||
92 | |||
93 | struct GNUNET_CONTAINER_HeapNode *heap_node; | ||
94 | struct GNUNET_CONTAINER_MultiHashMap *hashmap; | ||
95 | GNUNET_HashCode hash; | ||
96 | |||
97 | enum { SERVICE, REMOTE } type; | ||
98 | |||
99 | /** | ||
100 | * The source-address and -port of this connection | ||
101 | */ | ||
102 | struct redirect_info redirect_info; | ||
103 | }; | ||
104 | |||
105 | struct tunnel_notify_queue | ||
106 | { | ||
107 | struct tunnel_notify_queue *next; | ||
108 | struct tunnel_notify_queue *prev; | ||
109 | void *cls; | ||
110 | size_t len; | ||
111 | }; | ||
112 | |||
113 | struct tunnel_state | ||
114 | { | ||
115 | struct tunnel_notify_queue *head; | ||
116 | struct tunnel_notify_queue *tail; | ||
117 | struct GNUNET_MESH_TransmitHandle *th; | ||
118 | }; | ||
119 | |||
120 | |||
121 | /** | ||
122 | * The handle to the configuration used throughout the process | ||
123 | */ | ||
124 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
125 | |||
126 | /** | ||
127 | * The handle to the helper | ||
128 | */ | ||
129 | static struct GNUNET_HELPER_Handle *helper_handle; | ||
130 | |||
131 | /** | ||
132 | * Arguments to the exit helper. | ||
133 | */ | ||
134 | static char *exit_argv[7]; | ||
135 | |||
136 | /** | ||
137 | * Final status code. | ||
138 | */ | ||
139 | static int ret; | ||
140 | |||
141 | /** | ||
142 | * The handle to mesh | ||
143 | */ | ||
144 | static struct GNUNET_MESH_Handle *mesh_handle; | ||
145 | |||
146 | /** | ||
147 | * This hashmaps contains the mapping from peer, service-descriptor, | ||
148 | * source-port and destination-port to a struct redirect_state | ||
149 | */ | ||
150 | static struct GNUNET_CONTAINER_MultiHashMap *udp_connections; | ||
151 | |||
152 | static struct GNUNET_CONTAINER_Heap *udp_connections_heap; | ||
153 | |||
154 | static struct GNUNET_CONTAINER_MultiHashMap *tcp_connections; | ||
155 | |||
156 | static struct GNUNET_CONTAINER_Heap *tcp_connections_heap; | ||
157 | |||
158 | /** | ||
159 | * If there are at least this many udp-Connections, old ones will be removed | ||
160 | */ | ||
161 | static long long unsigned int max_udp_connections = 200; | ||
162 | |||
163 | /** | ||
164 | * If there are at least this many tcp-Connections, old ones will be removed | ||
165 | */ | ||
166 | static long long unsigned int max_tcp_connections = 200; | ||
167 | |||
168 | /** | ||
169 | * This hashmaps saves interesting things about the configured UDP services | ||
170 | */ | ||
171 | static struct GNUNET_CONTAINER_MultiHashMap *udp_services; | ||
172 | |||
173 | /** | ||
174 | * This hashmaps saves interesting things about the configured TCP services | ||
175 | */ | ||
176 | |||
177 | static struct GNUNET_CONTAINER_MultiHashMap *tcp_services; | ||
178 | |||
179 | |||
180 | /** | ||
181 | * Function that frees everything from a hashmap | ||
182 | */ | ||
183 | static int | ||
184 | free_iterate (void *cls GNUNET_UNUSED, | ||
185 | const GNUNET_HashCode * hash GNUNET_UNUSED, void *value) | ||
186 | { | ||
187 | GNUNET_free (value); | ||
188 | return GNUNET_YES; | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * Function scheduled as very last function, cleans up after us | ||
193 | */ | ||
194 | static void | ||
195 | cleanup (void *cls GNUNET_UNUSED, | ||
196 | const struct GNUNET_SCHEDULER_TaskContext *tskctx) | ||
197 | { | ||
198 | unsigned int i; | ||
199 | |||
200 | GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)); | ||
201 | if (mesh_handle != NULL) | ||
202 | { | ||
203 | GNUNET_MESH_disconnect (mesh_handle); | ||
204 | mesh_handle = NULL; | ||
205 | } | ||
206 | if (helper_handle != NULL) | ||
207 | { | ||
208 | GNUNET_HELPER_stop (helper_handle); | ||
209 | helper_handle = NULL; | ||
210 | } | ||
211 | GNUNET_CONTAINER_multihashmap_iterate (udp_connections, &free_iterate, NULL); | ||
212 | GNUNET_CONTAINER_multihashmap_iterate (tcp_connections, &free_iterate, NULL); | ||
213 | for (i=0;i<5;i++) | ||
214 | GNUNET_free_non_null (exit_argv[i]); | ||
215 | } | ||
216 | |||
217 | static void * | ||
218 | new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
219 | const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED, | ||
220 | const struct GNUNET_ATS_Information *ats GNUNET_UNUSED) | ||
221 | { | ||
222 | struct tunnel_state *s = GNUNET_malloc (sizeof *s); | ||
223 | |||
224 | s->head = NULL; | ||
225 | s->tail = NULL; | ||
226 | s->th = NULL; | ||
227 | return s; | ||
228 | } | ||
229 | |||
230 | static void | ||
231 | clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel, | ||
232 | void *tunnel_ctx) | ||
233 | { | ||
234 | GNUNET_free (tunnel_ctx); | ||
235 | } | ||
236 | |||
237 | static void | ||
238 | collect_connections (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
239 | { | ||
240 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | ||
241 | return; | ||
242 | |||
243 | |||
244 | struct GNUNET_CONTAINER_Heap *heap = cls; | ||
245 | |||
246 | struct redirect_state *state = GNUNET_CONTAINER_heap_remove_root (heap); | ||
247 | |||
248 | /* This is free()ed memory! */ | ||
249 | state->heap_node = NULL; | ||
250 | |||
251 | /* FIXME! GNUNET_MESH_close_tunnel(state->tunnel); */ | ||
252 | |||
253 | GNUNET_assert (GNUNET_OK == | ||
254 | GNUNET_CONTAINER_multihashmap_remove (state->hashmap, | ||
255 | &state->hash, state)); | ||
256 | |||
257 | GNUNET_free (state); | ||
258 | } | ||
259 | |||
260 | static void | ||
261 | hash_redirect_info (GNUNET_HashCode * hash, struct redirect_info *u_i, | ||
262 | size_t addrlen) | ||
263 | { | ||
264 | |||
265 | /* the gnunet hashmap only uses the first sizeof(unsigned int) of the hash | ||
266 | * | ||
267 | * build the hash out of the last bytes of the address and the 2 bytes of | ||
268 | * the port | ||
269 | */ | ||
270 | memcpy (hash, &u_i->pt, sizeof (u_i->pt)); | ||
271 | memcpy (((unsigned char *) hash) + 2, | ||
272 | u_i->addr + (addrlen - (sizeof (unsigned int) - 2)), | ||
273 | (sizeof (unsigned int) - 2)); | ||
274 | memset (((unsigned char *) hash) + sizeof (unsigned int), 0, | ||
275 | sizeof (GNUNET_HashCode) - sizeof (unsigned int)); | ||
276 | } | ||
277 | |||
278 | /** | ||
279 | * cls is the pointer to a GNUNET_MessageHeader that is | ||
280 | * followed by the service-descriptor and the udp-packet that should be sent; | ||
281 | */ | ||
282 | static size_t | ||
283 | send_udp_to_peer_notify_callback (void *cls, size_t size, void *buf) | ||
284 | { | ||
285 | struct GNUNET_MESH_Tunnel **tunnel = cls; | ||
286 | |||
287 | GNUNET_MESH_tunnel_set_data (*tunnel, NULL); | ||
288 | struct GNUNET_MessageHeader *hdr = | ||
289 | (struct GNUNET_MessageHeader *) (tunnel + 1); | ||
290 | GNUNET_assert (size >= ntohs (hdr->size)); | ||
291 | memcpy (buf, hdr, ntohs (hdr->size)); | ||
292 | size = ntohs (hdr->size); | ||
293 | |||
294 | struct tunnel_state *s = GNUNET_MESH_tunnel_get_data (*tunnel); | ||
295 | |||
296 | if (NULL != s->head) | ||
297 | { | ||
298 | struct tunnel_notify_queue *element = s->head; | ||
299 | |||
300 | GNUNET_CONTAINER_DLL_remove (s->head, s->tail, element); | ||
301 | |||
302 | s->th = | ||
303 | GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42, | ||
304 | GNUNET_TIME_relative_divide | ||
305 | (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2), | ||
306 | (const struct GNUNET_PeerIdentity *) | ||
307 | NULL, element->len, | ||
308 | send_udp_to_peer_notify_callback, | ||
309 | element->cls); | ||
310 | |||
311 | /* save the handle */ | ||
312 | GNUNET_free (element); | ||
313 | } | ||
314 | |||
315 | GNUNET_free (cls); | ||
316 | |||
317 | return size; | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * @brief Handles an UDP-Packet received from the helper. | ||
322 | * | ||
323 | * @param udp A pointer to the Packet | ||
324 | * @param dadr The IP-Destination-address | ||
325 | * @param addrlen The length of the address | ||
326 | */ | ||
327 | static void | ||
328 | udp_from_helper (struct udp_pkt *udp, unsigned char *dadr, size_t addrlen) | ||
329 | { | ||
330 | struct redirect_info u_i; | ||
331 | struct GNUNET_MESH_Tunnel *tunnel; | ||
332 | uint32_t len; | ||
333 | struct GNUNET_MessageHeader *msg; | ||
334 | |||
335 | memset (&u_i, 0, sizeof (struct redirect_info)); | ||
336 | |||
337 | memcpy (&u_i.addr, dadr, addrlen); | ||
338 | |||
339 | u_i.pt = udp->dpt; | ||
340 | |||
341 | /* get tunnel and service-descriptor from this */ | ||
342 | GNUNET_HashCode hash; | ||
343 | |||
344 | hash_redirect_info (&hash, &u_i, addrlen); | ||
345 | |||
346 | struct redirect_state *state = | ||
347 | GNUNET_CONTAINER_multihashmap_get (udp_connections, &hash); | ||
348 | |||
349 | /* Mark this connection as freshly used */ | ||
350 | GNUNET_CONTAINER_heap_update_cost (udp_connections_heap, state->heap_node, | ||
351 | GNUNET_TIME_absolute_get ().abs_value); | ||
352 | |||
353 | tunnel = state->tunnel; | ||
354 | |||
355 | if (state->type == SERVICE) | ||
356 | { | ||
357 | /* check if spt == serv.remote if yes: set spt = serv.myport ("nat") */ | ||
358 | if (ntohs (udp->spt) == state->serv->remote_port) | ||
359 | { | ||
360 | udp->spt = htons (state->serv->my_port); | ||
361 | } | ||
362 | else | ||
363 | { | ||
364 | /* otherwise the answer came from a different port (tftp does this) | ||
365 | * add this new port to the list of all services, so that the packets | ||
366 | * coming back from the client to this new port will be routed correctly | ||
367 | */ | ||
368 | struct redirect_service *serv = | ||
369 | GNUNET_malloc (sizeof (struct redirect_service)); | ||
370 | memcpy (serv, state->serv, sizeof (struct redirect_service)); | ||
371 | serv->my_port = ntohs (udp->spt); | ||
372 | serv->remote_port = ntohs (udp->spt); | ||
373 | uint16_t *desc = alloca (sizeof (GNUNET_HashCode) + 2); | ||
374 | |||
375 | memcpy ((GNUNET_HashCode *) (desc + 1), &state->desc, | ||
376 | sizeof (GNUNET_HashCode)); | ||
377 | *desc = ntohs (udp->spt); | ||
378 | GNUNET_assert (GNUNET_OK == | ||
379 | GNUNET_CONTAINER_multihashmap_put (udp_services, | ||
380 | (GNUNET_HashCode *) | ||
381 | desc, serv, | ||
382 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
383 | |||
384 | state->serv = serv; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | /* send udp-packet back */ | ||
389 | len = | ||
390 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + | ||
391 | ntohs (udp->len); | ||
392 | struct GNUNET_MESH_Tunnel **ctunnel = | ||
393 | GNUNET_malloc (sizeof (struct GNUNET_MESH_TUNNEL *) + len); | ||
394 | *ctunnel = tunnel; | ||
395 | msg = (struct GNUNET_MessageHeader *) (ctunnel + 1); | ||
396 | msg->size = htons (len); | ||
397 | msg->type = | ||
398 | htons (state->type == | ||
399 | SERVICE ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK : | ||
400 | GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK); | ||
401 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (msg + 1); | ||
402 | |||
403 | if (state->type == SERVICE) | ||
404 | memcpy (desc, &state->desc, sizeof (GNUNET_HashCode)); | ||
405 | else | ||
406 | memcpy (desc, &state->remote, sizeof (struct remote_addr)); | ||
407 | void *_udp = desc + 1; | ||
408 | |||
409 | memcpy (_udp, udp, ntohs (udp->len)); | ||
410 | |||
411 | struct tunnel_state *s = GNUNET_MESH_tunnel_get_data (tunnel); | ||
412 | |||
413 | if (NULL == s->th) | ||
414 | { | ||
415 | /* No notify is pending */ | ||
416 | s->th = | ||
417 | GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO, 42, | ||
418 | GNUNET_TIME_relative_divide | ||
419 | (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2), | ||
420 | (const struct GNUNET_PeerIdentity *) | ||
421 | NULL, len, | ||
422 | send_udp_to_peer_notify_callback, | ||
423 | ctunnel); | ||
424 | } | ||
425 | else | ||
426 | { | ||
427 | struct tunnel_notify_queue *element = | ||
428 | GNUNET_malloc (sizeof (struct tunnel_notify_queue)); | ||
429 | element->cls = ctunnel; | ||
430 | element->len = len; | ||
431 | |||
432 | GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, element); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | /** | ||
437 | * @brief Handles a TCP-Packet received from the helper. | ||
438 | * | ||
439 | * @param tcp A pointer to the Packet | ||
440 | * @param dadr The IP-Destination-address | ||
441 | * @param addrlen The length of the address | ||
442 | * @param pktlen the length of the packet, including its header | ||
443 | */ | ||
444 | static void | ||
445 | tcp_from_helper (struct tcp_pkt *tcp, unsigned char *dadr, size_t addrlen, | ||
446 | size_t pktlen) | ||
447 | { | ||
448 | struct redirect_info u_i; | ||
449 | struct GNUNET_MESH_Tunnel *tunnel; | ||
450 | uint32_t len; | ||
451 | struct GNUNET_MessageHeader *msg; | ||
452 | |||
453 | memset (&u_i, 0, sizeof (struct redirect_info)); | ||
454 | |||
455 | memcpy (&u_i.addr, dadr, addrlen); | ||
456 | u_i.pt = tcp->dpt; | ||
457 | |||
458 | /* get tunnel and service-descriptor from this */ | ||
459 | GNUNET_HashCode hash; | ||
460 | |||
461 | hash_redirect_info (&hash, &u_i, addrlen); | ||
462 | |||
463 | struct redirect_state *state = | ||
464 | GNUNET_CONTAINER_multihashmap_get (tcp_connections, &hash); | ||
465 | |||
466 | if (state == NULL) | ||
467 | { | ||
468 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
469 | "No mapping for this connection; hash is %x\n", | ||
470 | *((uint32_t *) & hash)); | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | /* Mark this connection as freshly used */ | ||
475 | GNUNET_CONTAINER_heap_update_cost (tcp_connections_heap, state->heap_node, | ||
476 | GNUNET_TIME_absolute_get ().abs_value); | ||
477 | |||
478 | tunnel = state->tunnel; | ||
479 | |||
480 | if (state->type == SERVICE) | ||
481 | { | ||
482 | /* check if spt == serv.remote if yes: set spt = serv.myport ("nat") */ | ||
483 | if (ntohs (tcp->spt) == state->serv->remote_port) | ||
484 | { | ||
485 | tcp->spt = htons (state->serv->my_port); | ||
486 | } | ||
487 | else | ||
488 | { | ||
489 | // This is an illegal packet. | ||
490 | return; | ||
491 | } | ||
492 | } | ||
493 | |||
494 | /* send tcp-packet back */ | ||
495 | len = | ||
496 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + pktlen; | ||
497 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "len: %d\n", pktlen); | ||
498 | struct GNUNET_MESH_Tunnel **ctunnel = | ||
499 | GNUNET_malloc (sizeof (struct GNUNET_MESH_TUNNEL *) + len); | ||
500 | *ctunnel = tunnel; | ||
501 | msg = (struct GNUNET_MessageHeader *) (ctunnel + 1); | ||
502 | msg->size = htons (len); | ||
503 | msg->type = | ||
504 | htons (state->type == | ||
505 | SERVICE ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK : | ||
506 | GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK); | ||
507 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (msg + 1); | ||
508 | |||
509 | if (state->type == SERVICE) | ||
510 | memcpy (desc, &state->desc, sizeof (GNUNET_HashCode)); | ||
511 | else | ||
512 | memcpy (desc, &state->remote, sizeof (struct remote_addr)); | ||
513 | void *_tcp = desc + 1; | ||
514 | |||
515 | memcpy (_tcp, tcp, pktlen); | ||
516 | |||
517 | struct tunnel_state *s = GNUNET_MESH_tunnel_get_data (tunnel); | ||
518 | |||
519 | if (NULL == s->th) | ||
520 | { | ||
521 | /* No notify is pending */ | ||
522 | s->th = | ||
523 | GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO, 42, | ||
524 | GNUNET_TIME_relative_divide | ||
525 | (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2), | ||
526 | (const struct GNUNET_PeerIdentity *) | ||
527 | NULL, len, | ||
528 | send_udp_to_peer_notify_callback, | ||
529 | ctunnel); | ||
530 | } | ||
531 | else | ||
532 | { | ||
533 | struct tunnel_notify_queue *element = | ||
534 | GNUNET_malloc (sizeof (struct tunnel_notify_queue)); | ||
535 | element->cls = ctunnel; | ||
536 | element->len = len; | ||
537 | |||
538 | GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, element); | ||
539 | } | ||
540 | } | ||
541 | |||
542 | |||
543 | /** | ||
544 | * Receive packets from the helper-process | ||
545 | */ | ||
546 | static void | ||
547 | message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | ||
548 | const struct GNUNET_MessageHeader *message) | ||
549 | { | ||
550 | GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
551 | |||
552 | struct tun_pkt *pkt_tun = (struct tun_pkt *) message; | ||
553 | |||
554 | /* ethertype is ipv6 */ | ||
555 | if (ntohs (pkt_tun->tun.type) == 0x86dd) | ||
556 | { | ||
557 | struct ip6_pkt *pkt6 = (struct ip6_pkt *) pkt_tun; | ||
558 | |||
559 | if (IPPROTO_UDP == pkt6->ip6_hdr.nxthdr) | ||
560 | udp_from_helper (&((struct ip6_udp *) pkt6)->udp_hdr, | ||
561 | (unsigned char *) &pkt6->ip6_hdr.dadr, 16); | ||
562 | else if (IPPROTO_TCP == pkt6->ip6_hdr.nxthdr) | ||
563 | tcp_from_helper (&((struct ip6_tcp *) pkt6)->tcp_hdr, | ||
564 | (unsigned char *) &pkt6->ip6_hdr.dadr, 16, | ||
565 | ntohs (pkt6->ip6_hdr.paylgth)); | ||
566 | } | ||
567 | else if (ntohs (pkt_tun->tun.type) == 0x0800) | ||
568 | { | ||
569 | struct ip_pkt *pkt4 = (struct ip_pkt *) pkt_tun; | ||
570 | |||
571 | if (IPPROTO_UDP == pkt4->ip_hdr.proto) | ||
572 | udp_from_helper (&((struct ip_udp *) pkt4)->udp_hdr, | ||
573 | (unsigned char *) &pkt4->ip_hdr.dadr, 4); | ||
574 | else if (IPPROTO_TCP == pkt4->ip_hdr.proto) | ||
575 | { | ||
576 | size_t pktlen = ntohs (pkt4->ip_hdr.tot_lngth); | ||
577 | |||
578 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tot: %d\n", pktlen); | ||
579 | pktlen -= 4 * pkt4->ip_hdr.hdr_lngth; | ||
580 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-hdr: %d\n", pktlen); | ||
581 | tcp_from_helper (&((struct ip_tcp *) pkt4)->tcp_hdr, | ||
582 | (unsigned char *) &pkt4->ip_hdr.dadr, 4, pktlen); | ||
583 | } | ||
584 | } | ||
585 | else | ||
586 | { | ||
587 | return; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | /** | ||
592 | * Reads the configuration servicecfg and populates udp_services | ||
593 | * | ||
594 | * @param cls unused | ||
595 | * @param section name of section in config, equal to hostname | ||
596 | */ | ||
597 | static void | ||
598 | read_service_conf (void *cls GNUNET_UNUSED, const char *section) | ||
599 | { | ||
600 | if ((strlen (section) < 8) || | ||
601 | (0 != strcmp (".gnunet.", section + (strlen (section) - 8)))) | ||
602 | return; | ||
603 | |||
604 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing dns-name %d %s %s\n", | ||
605 | strlen (section), section, section + (strlen (section) - 8)); | ||
606 | |||
607 | char *cpy; | ||
608 | char *redirect; | ||
609 | char *hostname; | ||
610 | char *hostport; | ||
611 | uint16_t *desc = alloca (sizeof (GNUNET_HashCode) + 2); | ||
612 | |||
613 | GNUNET_CRYPTO_hash (section, strlen (section) + 1, | ||
614 | (GNUNET_HashCode *) (desc + 1)); | ||
615 | |||
616 | #define TCP 2 | ||
617 | #define UDP 1 | ||
618 | |||
619 | int proto = UDP; | ||
620 | |||
621 | do | ||
622 | { | ||
623 | if (proto == UDP && | ||
624 | (GNUNET_OK != | ||
625 | GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS", | ||
626 | &cpy))) | ||
627 | goto next; | ||
628 | else if (proto == TCP && | ||
629 | (GNUNET_OK != | ||
630 | GNUNET_CONFIGURATION_get_value_string (cfg, section, | ||
631 | "TCP_REDIRECTS", &cpy))) | ||
632 | goto next; | ||
633 | |||
634 | for (redirect = strtok (cpy, " "); redirect != NULL; | ||
635 | redirect = strtok (NULL, " ")) | ||
636 | { | ||
637 | if (NULL == (hostname = strstr (redirect, ":"))) | ||
638 | { | ||
639 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
640 | "Warning: option %s is not formatted correctly!\n", | ||
641 | redirect); | ||
642 | continue; | ||
643 | } | ||
644 | hostname[0] = '\0'; | ||
645 | hostname++; | ||
646 | if (NULL == (hostport = strstr (hostname, ":"))) | ||
647 | { | ||
648 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
649 | "Warning: option %s is not formatted correctly!\n", | ||
650 | redirect); | ||
651 | continue; | ||
652 | } | ||
653 | hostport[0] = '\0'; | ||
654 | hostport++; | ||
655 | |||
656 | int local_port = atoi (redirect); | ||
657 | |||
658 | if (!((local_port > 0) && (local_port < 65536))) | ||
659 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
660 | "Warning: %s is not a correct port.", redirect); | ||
661 | |||
662 | *desc = local_port; | ||
663 | |||
664 | struct redirect_service *serv = | ||
665 | GNUNET_malloc (sizeof (struct redirect_service)); | ||
666 | serv->my_port = local_port; | ||
667 | |||
668 | if (0 == strcmp ("localhost4", hostname)) | ||
669 | { | ||
670 | serv->version = 4; | ||
671 | |||
672 | char *ip4addr; | ||
673 | |||
674 | GNUNET_assert (GNUNET_OK == | ||
675 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", | ||
676 | "IPV4ADDR", | ||
677 | &ip4addr)); | ||
678 | GNUNET_assert (1 == inet_pton (AF_INET, ip4addr, serv->v4.ip4address)); | ||
679 | GNUNET_free (ip4addr); | ||
680 | } | ||
681 | else if (0 == strcmp ("localhost6", hostname)) | ||
682 | { | ||
683 | serv->version = 6; | ||
684 | |||
685 | char *ip6addr; | ||
686 | |||
687 | GNUNET_assert (GNUNET_OK == | ||
688 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", | ||
689 | "IPV6ADDR", | ||
690 | &ip6addr)); | ||
691 | GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, serv->v6.ip6address)); | ||
692 | GNUNET_free (ip6addr); | ||
693 | } | ||
694 | else | ||
695 | { | ||
696 | struct addrinfo *res; | ||
697 | |||
698 | int ret = getaddrinfo (hostname, NULL, NULL, &res); | ||
699 | |||
700 | if (ret != 0) | ||
701 | { | ||
702 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No addresses found for %s!\n", | ||
703 | hostname); | ||
704 | GNUNET_free (serv); | ||
705 | continue; | ||
706 | } | ||
707 | else | ||
708 | { | ||
709 | char buf[256]; | ||
710 | struct addrinfo *c = res; | ||
711 | |||
712 | if (c) | ||
713 | { | ||
714 | if (c->ai_family == AF_INET) | ||
715 | { | ||
716 | serv->version = 4; | ||
717 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
718 | "Found %s as address for %s\n", | ||
719 | inet_ntop (c->ai_family, | ||
720 | &((struct sockaddr_in *) (c-> | ||
721 | ai_addr))->sin_addr, | ||
722 | (char *) &buf, 256), hostname); | ||
723 | memcpy (serv->v4.ip4address, | ||
724 | &((struct sockaddr_in *) (c->ai_addr))->sin_addr, 4); | ||
725 | } | ||
726 | else if (c->ai_family == AF_INET6) | ||
727 | { | ||
728 | serv->version = 6; | ||
729 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
730 | "Found %s as address for %s\n", | ||
731 | inet_ntop (c->ai_family, | ||
732 | &((struct sockaddr_in6 *) (c-> | ||
733 | ai_addr))->sin6_addr, | ||
734 | (char *) &buf, 256), hostname); | ||
735 | memcpy (serv->v6.ip6address, | ||
736 | &((struct sockaddr_in6 *) (c->ai_addr))->sin6_addr, 16); | ||
737 | } | ||
738 | } | ||
739 | else | ||
740 | { | ||
741 | freeaddrinfo (res); | ||
742 | GNUNET_free (serv); | ||
743 | continue; | ||
744 | } | ||
745 | freeaddrinfo (res); | ||
746 | } | ||
747 | } | ||
748 | serv->remote_port = atoi (hostport); | ||
749 | if (UDP == proto) | ||
750 | GNUNET_assert (GNUNET_OK == | ||
751 | GNUNET_CONTAINER_multihashmap_put (udp_services, | ||
752 | (GNUNET_HashCode *) | ||
753 | desc, serv, | ||
754 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
755 | else | ||
756 | GNUNET_assert (GNUNET_OK == | ||
757 | GNUNET_CONTAINER_multihashmap_put (tcp_services, | ||
758 | (GNUNET_HashCode *) | ||
759 | desc, serv, | ||
760 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
761 | |||
762 | } | ||
763 | GNUNET_free (cpy); | ||
764 | next: | ||
765 | proto = (proto == UDP) ? TCP : UDP; | ||
766 | } | ||
767 | while (proto != UDP); | ||
768 | } | ||
769 | |||
770 | |||
771 | |||
772 | static void | ||
773 | prepare_ipv4_packet (size_t len, uint16_t pktlen, void *payload, | ||
774 | uint16_t protocol, void *ipaddress, void *tunnel, | ||
775 | struct redirect_state *state, struct ip_pkt *pkt4) | ||
776 | { | ||
777 | uint32_t tmp, tmp2; | ||
778 | |||
779 | pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
780 | pkt4->shdr.size = htons (len); | ||
781 | pkt4->tun.flags = 0; | ||
782 | pkt4->tun.type = htons (0x0800); | ||
783 | |||
784 | memcpy (&pkt4->data, payload, pktlen); | ||
785 | |||
786 | pkt4->ip_hdr.version = 4; | ||
787 | pkt4->ip_hdr.hdr_lngth = 5; | ||
788 | pkt4->ip_hdr.diff_serv = 0; | ||
789 | pkt4->ip_hdr.tot_lngth = htons (20 + pktlen); | ||
790 | pkt4->ip_hdr.ident = 0; | ||
791 | pkt4->ip_hdr.flags = 0; | ||
792 | pkt4->ip_hdr.frag_off = 0; | ||
793 | pkt4->ip_hdr.ttl = 255; | ||
794 | pkt4->ip_hdr.proto = protocol; | ||
795 | pkt4->ip_hdr.chks = 0; /* Will be calculated later */ | ||
796 | |||
797 | memcpy (&pkt4->ip_hdr.dadr, ipaddress, sizeof (struct in_addr)); | ||
798 | |||
799 | /* Generate a new src-address */ | ||
800 | char *ipv4addr; | ||
801 | char *ipv4mask; | ||
802 | |||
803 | GNUNET_assert (GNUNET_OK == | ||
804 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR", | ||
805 | &ipv4addr)); | ||
806 | GNUNET_assert (GNUNET_OK == | ||
807 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK", | ||
808 | &ipv4mask)); | ||
809 | inet_pton (AF_INET, ipv4addr, &tmp); | ||
810 | inet_pton (AF_INET, ipv4mask, &tmp2); | ||
811 | GNUNET_free (ipv4addr); | ||
812 | GNUNET_free (ipv4mask); | ||
813 | |||
814 | /* This should be a noop */ | ||
815 | tmp = tmp & tmp2; | ||
816 | |||
817 | tmp |= ntohl (*((uint32_t *) tunnel)) & (~tmp2); | ||
818 | |||
819 | pkt4->ip_hdr.sadr.s_addr = tmp; | ||
820 | |||
821 | memcpy (&state->redirect_info.addr, &tmp, 4); | ||
822 | if (IPPROTO_UDP == protocol) | ||
823 | { | ||
824 | struct ip_udp *pkt4_udp = (struct ip_udp *) pkt4; | ||
825 | |||
826 | state->redirect_info.pt = pkt4_udp->udp_hdr.spt; | ||
827 | |||
828 | pkt4_udp->udp_hdr.crc = 0; /* Optional for IPv4 */ | ||
829 | } | ||
830 | else if (IPPROTO_TCP == protocol) | ||
831 | { | ||
832 | struct ip_tcp *pkt4_tcp = (struct ip_tcp *) pkt4; | ||
833 | |||
834 | state->redirect_info.pt = pkt4_tcp->tcp_hdr.spt; | ||
835 | |||
836 | pkt4_tcp->tcp_hdr.crc = 0; | ||
837 | uint32_t sum = 0; | ||
838 | |||
839 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.sadr, sizeof (struct in_addr)); | ||
840 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.dadr, sizeof (struct in_addr)); | ||
841 | |||
842 | tmp = (protocol << 16) | (0xffff & pktlen); | ||
843 | |||
844 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "line: %08x, %x \n", tmp, | ||
845 | (0xffff & pktlen)); | ||
846 | |||
847 | tmp = htonl (tmp); | ||
848 | |||
849 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
850 | |||
851 | sum = | ||
852 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt4_tcp->tcp_hdr, | ||
853 | pktlen); | ||
854 | pkt4_tcp->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
855 | } | ||
856 | |||
857 | pkt4->ip_hdr.chks = | ||
858 | GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4); | ||
859 | } | ||
860 | |||
861 | static void | ||
862 | prepare_ipv6_packet (size_t len, uint16_t pktlen, void *payload, | ||
863 | uint16_t protocol, void *ipaddress, void *tunnel, | ||
864 | struct redirect_state *state, struct ip6_pkt *pkt6) | ||
865 | { | ||
866 | uint32_t tmp; | ||
867 | |||
868 | pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
869 | pkt6->shdr.size = htons (len); | ||
870 | pkt6->tun.flags = 0; | ||
871 | |||
872 | pkt6->tun.type = htons (0x86dd); | ||
873 | |||
874 | memcpy (&pkt6->data, payload, pktlen); | ||
875 | |||
876 | pkt6->ip6_hdr.version = 6; | ||
877 | pkt6->ip6_hdr.nxthdr = protocol; | ||
878 | pkt6->ip6_hdr.paylgth = htons (pktlen); | ||
879 | pkt6->ip6_hdr.hoplmt = 64; | ||
880 | |||
881 | memcpy (&pkt6->ip6_hdr.dadr, ipaddress, sizeof (struct in6_addr)); | ||
882 | |||
883 | /* Generate a new src-address | ||
884 | * This takes as much from the address of the tunnel as fits into | ||
885 | * the host-mask*/ | ||
886 | char *ipv6addr; | ||
887 | unsigned long long ipv6prefix; | ||
888 | |||
889 | GNUNET_assert (GNUNET_OK == | ||
890 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR", | ||
891 | &ipv6addr)); | ||
892 | GNUNET_assert (GNUNET_OK == | ||
893 | GNUNET_CONFIGURATION_get_value_number (cfg, "exit", | ||
894 | "IPV6PREFIX", | ||
895 | &ipv6prefix)); | ||
896 | GNUNET_assert (ipv6prefix < 127); | ||
897 | ipv6prefix = (ipv6prefix + 7) / 8; | ||
898 | |||
899 | inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.sadr); | ||
900 | GNUNET_free (ipv6addr); | ||
901 | |||
902 | if (ipv6prefix < (16 - sizeof (void *))) | ||
903 | ipv6prefix = 16 - sizeof (void *); | ||
904 | |||
905 | unsigned int offset = ipv6prefix - (16 - sizeof (void *)); | ||
906 | |||
907 | memcpy ((((char *) &pkt6->ip6_hdr.sadr)) + ipv6prefix, | ||
908 | ((char *) &tunnel) + offset, 16 - ipv6prefix); | ||
909 | |||
910 | /* copy the needed information into the state */ | ||
911 | memcpy (&state->redirect_info.addr, &pkt6->ip6_hdr.sadr, 16); | ||
912 | |||
913 | if (IPPROTO_UDP == protocol) | ||
914 | { | ||
915 | struct ip6_udp *pkt6_udp = (struct ip6_udp *) pkt6; | ||
916 | |||
917 | state->redirect_info.pt = pkt6_udp->udp_hdr.spt; | ||
918 | |||
919 | pkt6_udp->udp_hdr.crc = 0; | ||
920 | uint32_t sum = 0; | ||
921 | |||
922 | sum = | ||
923 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6_udp->ip6_hdr.sadr, | ||
924 | 16); | ||
925 | sum = | ||
926 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6_udp->ip6_hdr.dadr, | ||
927 | 16); | ||
928 | tmp = (htons (pktlen) & 0xffff); | ||
929 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
930 | tmp = htons (((pkt6_udp->ip6_hdr.nxthdr & 0x00ff))); | ||
931 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
932 | |||
933 | sum = | ||
934 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6_udp->udp_hdr, | ||
935 | ntohs (pkt6_udp->udp_hdr.len)); | ||
936 | pkt6_udp->udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
937 | } | ||
938 | else if (IPPROTO_TCP == protocol) | ||
939 | { | ||
940 | struct ip6_tcp *pkt6_tcp = (struct ip6_tcp *) pkt6; | ||
941 | |||
942 | state->redirect_info.pt = pkt6_tcp->tcp_hdr.spt; | ||
943 | |||
944 | pkt6_tcp->tcp_hdr.crc = 0; | ||
945 | uint32_t sum = 0; | ||
946 | |||
947 | sum = | ||
948 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16); | ||
949 | sum = | ||
950 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16); | ||
951 | tmp = htonl (pktlen); | ||
952 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
953 | tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff))); | ||
954 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
955 | |||
956 | sum = | ||
957 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6_tcp->tcp_hdr, | ||
958 | ntohs (pkt6->ip6_hdr.paylgth)); | ||
959 | pkt6_tcp->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
960 | } | ||
961 | } | ||
962 | |||
963 | /** | ||
964 | * The messages are one GNUNET_HashCode for the service followed by a struct tcp_pkt | ||
965 | */ | ||
966 | static int | ||
967 | receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
968 | void **tunnel_ctx GNUNET_UNUSED, | ||
969 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
970 | const struct GNUNET_MessageHeader *message, | ||
971 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
972 | { | ||
973 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received TCP-Packet\n"); | ||
974 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
975 | struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1); | ||
976 | uint16_t pkt_len = | ||
977 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - | ||
978 | sizeof (GNUNET_HashCode); | ||
979 | |||
980 | /** Get the configuration from the services-hashmap. | ||
981 | * | ||
982 | * Which service is needed only depends on the service-descriptor and the | ||
983 | * destination-port | ||
984 | */ | ||
985 | uint16_t *tcp_desc = alloca (sizeof (GNUNET_HashCode) + 2); | ||
986 | |||
987 | memcpy (tcp_desc + 1, desc, sizeof (GNUNET_HashCode)); | ||
988 | *tcp_desc = ntohs (pkt->dpt); | ||
989 | struct redirect_service *serv = | ||
990 | GNUNET_CONTAINER_multihashmap_get (tcp_services, | ||
991 | (GNUNET_HashCode *) tcp_desc); | ||
992 | |||
993 | if (NULL == serv) | ||
994 | { | ||
995 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "No service found for TCP dpt %d!\n", | ||
996 | *tcp_desc); | ||
997 | return GNUNET_YES; | ||
998 | } | ||
999 | |||
1000 | pkt->dpt = htons (serv->remote_port); | ||
1001 | |||
1002 | /* | ||
1003 | * At this point it would be possible to check against some kind of ACL. | ||
1004 | */ | ||
1005 | |||
1006 | size_t len; | ||
1007 | |||
1008 | /* Prepare the state. | ||
1009 | * This will be saved in the hashmap, so that the receiving procedure knows | ||
1010 | * through which tunnel this connection has to be routed. | ||
1011 | */ | ||
1012 | struct redirect_state *state = GNUNET_malloc (sizeof (struct redirect_state)); | ||
1013 | |||
1014 | state->tunnel = tunnel; | ||
1015 | state->serv = serv; | ||
1016 | state->type = SERVICE; | ||
1017 | state->hashmap = tcp_connections; | ||
1018 | memcpy (&state->desc, desc, sizeof (GNUNET_HashCode)); | ||
1019 | |||
1020 | len = | ||
1021 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
1022 | sizeof (struct ip6_hdr) + pkt_len; | ||
1023 | { | ||
1024 | char buf[len]; | ||
1025 | |||
1026 | memset (buf, 0, len); | ||
1027 | switch (serv->version) | ||
1028 | { | ||
1029 | case 4: | ||
1030 | prepare_ipv4_packet (len, pkt_len, pkt, IPPROTO_TCP, &serv->v4.ip4address, | ||
1031 | tunnel, state, (struct ip_pkt *) buf); | ||
1032 | break; | ||
1033 | case 6: | ||
1034 | prepare_ipv6_packet (len, pkt_len, pkt, IPPROTO_TCP, &serv->v6.ip6address, | ||
1035 | tunnel, state, (struct ip6_pkt *) buf); | ||
1036 | |||
1037 | break; | ||
1038 | default: | ||
1039 | GNUNET_assert (0); | ||
1040 | break; | ||
1041 | } | ||
1042 | |||
1043 | hash_redirect_info (&state->hash, &state->redirect_info, | ||
1044 | serv->version == 4 ? 4 : 16); | ||
1045 | |||
1046 | if (GNUNET_NO == | ||
1047 | GNUNET_CONTAINER_multihashmap_contains (tcp_connections, &state->hash)) | ||
1048 | { | ||
1049 | GNUNET_CONTAINER_multihashmap_put (tcp_connections, &state->hash, state, | ||
1050 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1051 | |||
1052 | state->heap_node = | ||
1053 | GNUNET_CONTAINER_heap_insert (tcp_connections_heap, state, | ||
1054 | GNUNET_TIME_absolute_get ().abs_value); | ||
1055 | |||
1056 | if (GNUNET_CONTAINER_heap_get_size (tcp_connections_heap) > | ||
1057 | max_tcp_connections) | ||
1058 | GNUNET_SCHEDULER_add_now (collect_connections, tcp_connections_heap); | ||
1059 | } | ||
1060 | else | ||
1061 | GNUNET_free (state); | ||
1062 | |||
1063 | /* FIXME: here, flow-control with mesh would be nice to have... */ | ||
1064 | (void) GNUNET_HELPER_send (helper_handle, | ||
1065 | (const struct GNUNET_MessageHeader*) buf, | ||
1066 | GNUNET_YES, | ||
1067 | NULL, NULL); | ||
1068 | } | ||
1069 | return GNUNET_YES; | ||
1070 | } | ||
1071 | |||
1072 | |||
1073 | static int | ||
1074 | receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1075 | void **tunnel_ctx GNUNET_UNUSED, | ||
1076 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
1077 | const struct GNUNET_MessageHeader *message, | ||
1078 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1079 | { | ||
1080 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
1081 | struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1); | ||
1082 | struct remote_addr *s = (struct remote_addr *) desc; | ||
1083 | char *buf; | ||
1084 | size_t len; | ||
1085 | uint16_t pkt_len = | ||
1086 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - | ||
1087 | sizeof (GNUNET_HashCode); | ||
1088 | |||
1089 | struct redirect_state *state = GNUNET_malloc (sizeof (struct redirect_state)); | ||
1090 | |||
1091 | state->tunnel = tunnel; | ||
1092 | state->type = REMOTE; | ||
1093 | state->hashmap = tcp_connections; | ||
1094 | memcpy (&state->remote, s, sizeof (struct remote_addr)); | ||
1095 | |||
1096 | len = | ||
1097 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
1098 | sizeof (struct ip6_hdr) + pkt_len; | ||
1099 | buf = alloca (len); | ||
1100 | |||
1101 | memset (buf, 0, len); | ||
1102 | |||
1103 | switch (s->addrlen) | ||
1104 | { | ||
1105 | case 4: | ||
1106 | prepare_ipv4_packet (len, pkt_len, pkt, IPPROTO_TCP, &s->addr, tunnel, | ||
1107 | state, (struct ip_pkt *) buf); | ||
1108 | break; | ||
1109 | case 16: | ||
1110 | prepare_ipv6_packet (len, pkt_len, pkt, IPPROTO_TCP, &s->addr, tunnel, | ||
1111 | state, (struct ip6_pkt *) buf); | ||
1112 | break; | ||
1113 | default: | ||
1114 | GNUNET_free (state); | ||
1115 | return GNUNET_SYSERR; | ||
1116 | } | ||
1117 | |||
1118 | hash_redirect_info (&state->hash, &state->redirect_info, s->addrlen); | ||
1119 | |||
1120 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Packet from remote; hash is %x\n", | ||
1121 | *((uint32_t *) & state->hash)); | ||
1122 | |||
1123 | if (GNUNET_NO == | ||
1124 | GNUNET_CONTAINER_multihashmap_contains (tcp_connections, &state->hash)) | ||
1125 | { | ||
1126 | GNUNET_CONTAINER_multihashmap_put (tcp_connections, &state->hash, state, | ||
1127 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1128 | |||
1129 | state->heap_node = | ||
1130 | GNUNET_CONTAINER_heap_insert (tcp_connections_heap, state, | ||
1131 | GNUNET_TIME_absolute_get ().abs_value); | ||
1132 | |||
1133 | if (GNUNET_CONTAINER_heap_get_size (tcp_connections_heap) > | ||
1134 | max_tcp_connections) | ||
1135 | GNUNET_SCHEDULER_add_now (collect_connections, tcp_connections_heap); | ||
1136 | } | ||
1137 | else | ||
1138 | GNUNET_free (state); | ||
1139 | |||
1140 | /* FIXME: here, flow-control with mesh would be nice to have... */ | ||
1141 | (void) GNUNET_HELPER_send (helper_handle, | ||
1142 | (const struct GNUNET_MessageHeader*) buf, | ||
1143 | GNUNET_YES, | ||
1144 | NULL, NULL); | ||
1145 | return GNUNET_YES; | ||
1146 | |||
1147 | } | ||
1148 | |||
1149 | static int | ||
1150 | receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1151 | void **tunnel_ctx GNUNET_UNUSED, | ||
1152 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
1153 | const struct GNUNET_MessageHeader *message, | ||
1154 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1155 | { | ||
1156 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
1157 | struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); | ||
1158 | struct remote_addr *s = (struct remote_addr *) desc; | ||
1159 | char *buf; | ||
1160 | size_t len; | ||
1161 | |||
1162 | GNUNET_assert (ntohs (pkt->len) == | ||
1163 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - | ||
1164 | sizeof (GNUNET_HashCode)); | ||
1165 | |||
1166 | /* Prepare the state. | ||
1167 | * This will be saved in the hashmap, so that the receiving procedure knows | ||
1168 | * through which tunnel this connection has to be routed. | ||
1169 | */ | ||
1170 | struct redirect_state *state = GNUNET_malloc (sizeof (struct redirect_state)); | ||
1171 | |||
1172 | state->tunnel = tunnel; | ||
1173 | state->hashmap = udp_connections; | ||
1174 | state->type = REMOTE; | ||
1175 | memcpy (&state->remote, s, sizeof (struct remote_addr)); | ||
1176 | |||
1177 | len = | ||
1178 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
1179 | sizeof (struct ip6_hdr) + ntohs (pkt->len); | ||
1180 | buf = alloca (len); | ||
1181 | |||
1182 | memset (buf, 0, len); | ||
1183 | |||
1184 | switch (s->addrlen) | ||
1185 | { | ||
1186 | case 4: | ||
1187 | prepare_ipv4_packet (len, ntohs (pkt->len), pkt, IPPROTO_UDP, &s->addr, | ||
1188 | tunnel, state, (struct ip_pkt *) buf); | ||
1189 | break; | ||
1190 | case 16: | ||
1191 | prepare_ipv6_packet (len, ntohs (pkt->len), pkt, IPPROTO_UDP, &s->addr, | ||
1192 | tunnel, state, (struct ip6_pkt *) buf); | ||
1193 | break; | ||
1194 | default: | ||
1195 | GNUNET_assert (0); | ||
1196 | break; | ||
1197 | } | ||
1198 | |||
1199 | hash_redirect_info (&state->hash, &state->redirect_info, s->addrlen); | ||
1200 | |||
1201 | if (GNUNET_NO == | ||
1202 | GNUNET_CONTAINER_multihashmap_contains (udp_connections, &state->hash)) | ||
1203 | { | ||
1204 | GNUNET_CONTAINER_multihashmap_put (udp_connections, &state->hash, state, | ||
1205 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1206 | |||
1207 | state->heap_node = | ||
1208 | GNUNET_CONTAINER_heap_insert (udp_connections_heap, state, | ||
1209 | GNUNET_TIME_absolute_get ().abs_value); | ||
1210 | |||
1211 | if (GNUNET_CONTAINER_heap_get_size (udp_connections_heap) > | ||
1212 | max_udp_connections) | ||
1213 | GNUNET_SCHEDULER_add_now (collect_connections, udp_connections_heap); | ||
1214 | } | ||
1215 | else | ||
1216 | GNUNET_free (state); | ||
1217 | |||
1218 | (void) GNUNET_HELPER_send (helper_handle, | ||
1219 | (const struct GNUNET_MessageHeader*) buf, | ||
1220 | GNUNET_YES, | ||
1221 | NULL, NULL); | ||
1222 | return GNUNET_YES; | ||
1223 | } | ||
1224 | |||
1225 | /** | ||
1226 | * The messages are one GNUNET_HashCode for the service, followed by a struct udp_pkt | ||
1227 | */ | ||
1228 | static int | ||
1229 | receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1230 | void **tunnel_ctx, | ||
1231 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
1232 | const struct GNUNET_MessageHeader *message, | ||
1233 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1234 | { | ||
1235 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
1236 | struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); | ||
1237 | |||
1238 | GNUNET_assert (ntohs (pkt->len) == | ||
1239 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - | ||
1240 | sizeof (GNUNET_HashCode)); | ||
1241 | |||
1242 | /* Get the configuration from the hashmap */ | ||
1243 | uint16_t *udp_desc = alloca (sizeof (GNUNET_HashCode) + 2); | ||
1244 | |||
1245 | memcpy (udp_desc + 1, desc, sizeof (GNUNET_HashCode)); | ||
1246 | *udp_desc = ntohs (pkt->dpt); | ||
1247 | struct redirect_service *serv = | ||
1248 | GNUNET_CONTAINER_multihashmap_get (udp_services, | ||
1249 | (GNUNET_HashCode *) udp_desc); | ||
1250 | |||
1251 | if (NULL == serv) | ||
1252 | { | ||
1253 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "No service found for UDP dpt %d!\n", | ||
1254 | *udp_desc); | ||
1255 | return GNUNET_YES; | ||
1256 | } | ||
1257 | |||
1258 | pkt->dpt = htons (serv->remote_port); | ||
1259 | |||
1260 | /* | ||
1261 | * At this point it would be possible to check against some kind of ACL. | ||
1262 | */ | ||
1263 | |||
1264 | char *buf; | ||
1265 | size_t len; | ||
1266 | |||
1267 | /* Prepare the state. | ||
1268 | * This will be saved in the hashmap, so that the receiving procedure knows | ||
1269 | * through which tunnel this connection has to be routed. | ||
1270 | */ | ||
1271 | struct redirect_state *state = GNUNET_malloc (sizeof (struct redirect_state)); | ||
1272 | |||
1273 | state->tunnel = tunnel; | ||
1274 | state->serv = serv; | ||
1275 | state->type = SERVICE; | ||
1276 | state->hashmap = udp_connections; | ||
1277 | memcpy (&state->desc, desc, sizeof (GNUNET_HashCode)); | ||
1278 | |||
1279 | len = | ||
1280 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
1281 | sizeof (struct ip6_hdr) + ntohs (pkt->len); | ||
1282 | buf = alloca (len); | ||
1283 | |||
1284 | memset (buf, 0, len); | ||
1285 | |||
1286 | switch (serv->version) | ||
1287 | { | ||
1288 | case 4: | ||
1289 | prepare_ipv4_packet (len, ntohs (pkt->len), pkt, IPPROTO_UDP, | ||
1290 | &serv->v4.ip4address, tunnel, state, | ||
1291 | (struct ip_pkt *) buf); | ||
1292 | break; | ||
1293 | case 6: | ||
1294 | prepare_ipv6_packet (len, ntohs (pkt->len), pkt, IPPROTO_UDP, | ||
1295 | &serv->v6.ip6address, tunnel, state, | ||
1296 | (struct ip6_pkt *) buf); | ||
1297 | |||
1298 | break; | ||
1299 | default: | ||
1300 | GNUNET_assert (0); | ||
1301 | break; | ||
1302 | } | ||
1303 | |||
1304 | hash_redirect_info (&state->hash, &state->redirect_info, | ||
1305 | serv->version == 4 ? 4 : 16); | ||
1306 | |||
1307 | if (GNUNET_NO == | ||
1308 | GNUNET_CONTAINER_multihashmap_contains (udp_connections, &state->hash)) | ||
1309 | { | ||
1310 | GNUNET_CONTAINER_multihashmap_put (udp_connections, &state->hash, state, | ||
1311 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1312 | |||
1313 | state->heap_node = | ||
1314 | GNUNET_CONTAINER_heap_insert (udp_connections_heap, state, | ||
1315 | GNUNET_TIME_absolute_get ().abs_value); | ||
1316 | |||
1317 | if (GNUNET_CONTAINER_heap_get_size (udp_connections_heap) > | ||
1318 | max_udp_connections) | ||
1319 | GNUNET_SCHEDULER_add_now (collect_connections, udp_connections_heap); | ||
1320 | } | ||
1321 | else | ||
1322 | GNUNET_free (state); | ||
1323 | |||
1324 | (void) GNUNET_HELPER_send (helper_handle, | ||
1325 | (const struct GNUNET_MessageHeader*) buf, | ||
1326 | GNUNET_YES, | ||
1327 | NULL, NULL); | ||
1328 | return GNUNET_YES; | ||
1329 | } | ||
1330 | |||
1331 | static void | ||
1332 | connect_to_mesh () | ||
1333 | { | ||
1334 | int udp, tcp; | ||
1335 | int handler_idx, app_idx; | ||
1336 | |||
1337 | udp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_UDP"); | ||
1338 | tcp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_TCP"); | ||
1339 | |||
1340 | static struct GNUNET_MESH_MessageHandler handlers[] = { | ||
1341 | {receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP, 0}, | ||
1342 | {receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP, 0}, | ||
1343 | {NULL, 0, 0}, | ||
1344 | {NULL, 0, 0}, | ||
1345 | {NULL, 0, 0} | ||
1346 | }; | ||
1347 | |||
1348 | static GNUNET_MESH_ApplicationType apptypes[] = { | ||
1349 | GNUNET_APPLICATION_TYPE_END, | ||
1350 | GNUNET_APPLICATION_TYPE_END, | ||
1351 | GNUNET_APPLICATION_TYPE_END | ||
1352 | }; | ||
1353 | |||
1354 | app_idx = 0; | ||
1355 | handler_idx = 2; | ||
1356 | |||
1357 | if (GNUNET_YES == udp) | ||
1358 | { | ||
1359 | handlers[handler_idx].callback = receive_udp_remote; | ||
1360 | handlers[handler_idx].expected_size = 0; | ||
1361 | handlers[handler_idx].type = GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP; | ||
1362 | apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY; | ||
1363 | handler_idx++; | ||
1364 | app_idx++; | ||
1365 | } | ||
1366 | |||
1367 | if (GNUNET_YES == tcp) | ||
1368 | { | ||
1369 | handlers[handler_idx].callback = receive_tcp_remote; | ||
1370 | handlers[handler_idx].expected_size = 0; | ||
1371 | handlers[handler_idx].type = GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP; | ||
1372 | apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY; | ||
1373 | handler_idx++; | ||
1374 | app_idx++; | ||
1375 | } | ||
1376 | |||
1377 | mesh_handle = | ||
1378 | GNUNET_MESH_connect (cfg, 42, NULL, new_tunnel, clean_tunnel, handlers, | ||
1379 | apptypes); | ||
1380 | } | ||
1381 | |||
1382 | |||
1383 | |||
1384 | /** | ||
1385 | * @brief Main function that will be run by the scheduler. | ||
1386 | * | ||
1387 | * @param cls closure | ||
1388 | * @param args remaining command-line arguments | ||
1389 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
1390 | * @param cfg_ configuration | ||
1391 | */ | ||
1392 | static void | ||
1393 | run (void *cls, char *const *args GNUNET_UNUSED, | ||
1394 | const char *cfgfile GNUNET_UNUSED, | ||
1395 | const struct GNUNET_CONFIGURATION_Handle *cfg_) | ||
1396 | { | ||
1397 | char *ifname; | ||
1398 | char *ipv6addr; | ||
1399 | char *ipv6prefix; | ||
1400 | char *ipv4addr; | ||
1401 | char *ipv4mask; | ||
1402 | |||
1403 | cfg = cfg_; | ||
1404 | connect_to_mesh (); | ||
1405 | udp_connections = GNUNET_CONTAINER_multihashmap_create (65536); | ||
1406 | udp_connections_heap = | ||
1407 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1408 | tcp_connections = GNUNET_CONTAINER_multihashmap_create (65536); | ||
1409 | tcp_connections_heap = | ||
1410 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1411 | udp_services = GNUNET_CONTAINER_multihashmap_create (65536); | ||
1412 | tcp_services = GNUNET_CONTAINER_multihashmap_create (65536); | ||
1413 | if (GNUNET_OK != | ||
1414 | GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_UDP_CONNECTIONS", | ||
1415 | &max_udp_connections)) | ||
1416 | max_udp_connections = 1024; | ||
1417 | if (GNUNET_OK != | ||
1418 | GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_TCP_CONNECTIONS", | ||
1419 | &max_tcp_connections)) | ||
1420 | max_tcp_connections = 256; | ||
1421 | GNUNET_CONFIGURATION_iterate_sections (cfg, read_service_conf, NULL); | ||
1422 | |||
1423 | if (GNUNET_SYSERR == | ||
1424 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IFNAME", &ifname)) | ||
1425 | { | ||
1426 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1427 | "No entry 'IFNAME' in configuration!\n"); | ||
1428 | exit (1); | ||
1429 | } | ||
1430 | |||
1431 | if (GNUNET_SYSERR == | ||
1432 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR", | ||
1433 | &ipv6addr)) | ||
1434 | { | ||
1435 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1436 | "No entry 'IPV6ADDR' in configuration!\n"); | ||
1437 | exit (1); | ||
1438 | } | ||
1439 | |||
1440 | if (GNUNET_SYSERR == | ||
1441 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX", | ||
1442 | &ipv6prefix)) | ||
1443 | { | ||
1444 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1445 | "No entry 'IPV6PREFIX' in configuration!\n"); | ||
1446 | exit (1); | ||
1447 | } | ||
1448 | |||
1449 | if (GNUNET_SYSERR == | ||
1450 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR", | ||
1451 | &ipv4addr)) | ||
1452 | { | ||
1453 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1454 | "No entry 'IPV4ADDR' in configuration!\n"); | ||
1455 | exit (1); | ||
1456 | } | ||
1457 | |||
1458 | if (GNUNET_SYSERR == | ||
1459 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK", | ||
1460 | &ipv4mask)) | ||
1461 | { | ||
1462 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1463 | "No entry 'IPV4MASK' in configuration!\n"); | ||
1464 | exit (1); | ||
1465 | } | ||
1466 | exit_argv[0] = GNUNET_strdup ("exit-gnunet"); | ||
1467 | exit_argv[1] = ifname; | ||
1468 | exit_argv[2] = ipv6addr; | ||
1469 | exit_argv[3] = ipv6prefix; | ||
1470 | exit_argv[4] = ipv4addr; | ||
1471 | exit_argv[5] = ipv4mask; | ||
1472 | exit_argv[6] = NULL; | ||
1473 | helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", exit_argv, | ||
1474 | &message_token, NULL); | ||
1475 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); | ||
1476 | } | ||
1477 | |||
1478 | |||
1479 | /** | ||
1480 | * The main function | ||
1481 | * | ||
1482 | * @param argc number of arguments from the command line | ||
1483 | * @param argv command line arguments | ||
1484 | * @return 0 ok, 1 on error | ||
1485 | */ | ||
1486 | int | ||
1487 | main (int argc, char *const *argv) | ||
1488 | { | ||
1489 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
1490 | GNUNET_GETOPT_OPTION_END | ||
1491 | }; | ||
1492 | |||
1493 | return (GNUNET_OK == | ||
1494 | GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit", | ||
1495 | gettext_noop | ||
1496 | ("Daemon to run to provide an IP exit node for the VPN"), | ||
1497 | options, &run, NULL)) ? ret : 1; | ||
1498 | } | ||
1499 | |||
1500 | |||
1501 | /* end of gnunet-daemon-exit.c */ | ||
diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c deleted file mode 100644 index 6945fc772..000000000 --- a/src/vpn/gnunet-daemon-vpn.c +++ /dev/null | |||
@@ -1,1808 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010 Christian Grothoff | ||
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 | /** | ||
22 | * @file vpn/gnunet-daemon-vpn.c | ||
23 | * @brief | ||
24 | * @author Philipp Toelke | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_getopt_lib.h" | ||
28 | #include "gnunet_program_lib.h" | ||
29 | #include "gnunet-vpn-packet.h" | ||
30 | #include "gnunet_common.h" | ||
31 | #include "gnunet_protocols.h" | ||
32 | #include "gnunet_applications.h" | ||
33 | #include <gnunet_mesh_service.h> | ||
34 | #include "gnunet_client_lib.h" | ||
35 | #include "gnunet_container_lib.h" | ||
36 | #include "gnunet_constants.h" | ||
37 | #include <block_dns.h> | ||
38 | #include "gnunet_dns_service.h" | ||
39 | |||
40 | |||
41 | struct answer_packet_list | ||
42 | { | ||
43 | struct answer_packet_list *next; | ||
44 | struct answer_packet_list *prev; | ||
45 | struct GNUNET_SERVER_Client *client; | ||
46 | struct answer_packet pkt; | ||
47 | }; | ||
48 | |||
49 | |||
50 | struct map_entry | ||
51 | { | ||
52 | /** The description of the service (used for service) */ | ||
53 | struct GNUNET_vpn_service_descriptor desc; | ||
54 | |||
55 | /** The real address of the service (used for remote) */ | ||
56 | char addrlen; | ||
57 | char addr[16]; | ||
58 | |||
59 | struct GNUNET_MESH_Tunnel *tunnel; | ||
60 | uint16_t namelen; | ||
61 | char additional_ports[8192]; | ||
62 | |||
63 | struct GNUNET_CONTAINER_HeapNode *heap_node; | ||
64 | GNUNET_HashCode hash; | ||
65 | /** | ||
66 | * After this struct the name is located in DNS-Format! | ||
67 | */ | ||
68 | }; | ||
69 | |||
70 | |||
71 | struct remote_addr | ||
72 | { | ||
73 | char addrlen; | ||
74 | unsigned char addr[16]; | ||
75 | char proto; | ||
76 | }; | ||
77 | |||
78 | |||
79 | struct tunnel_notify_queue | ||
80 | { | ||
81 | struct tunnel_notify_queue *next; | ||
82 | struct tunnel_notify_queue *prev; | ||
83 | size_t len; | ||
84 | void *cls; | ||
85 | }; | ||
86 | |||
87 | |||
88 | struct tunnel_state | ||
89 | { | ||
90 | struct GNUNET_MESH_TransmitHandle *th; | ||
91 | struct tunnel_notify_queue *head, *tail; | ||
92 | |||
93 | int addrlen; | ||
94 | }; | ||
95 | |||
96 | |||
97 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
98 | |||
99 | static struct GNUNET_MESH_Handle *mesh_handle; | ||
100 | |||
101 | static struct GNUNET_CONTAINER_MultiHashMap *hashmap; | ||
102 | |||
103 | static struct GNUNET_CONTAINER_Heap *heap; | ||
104 | |||
105 | /** | ||
106 | * The handle to the helper | ||
107 | */ | ||
108 | static struct GNUNET_HELPER_Handle *helper_handle; | ||
109 | |||
110 | /** | ||
111 | * Arguments to the exit helper. | ||
112 | */ | ||
113 | static char *vpn_argv[7]; | ||
114 | |||
115 | static struct GNUNET_DNS_Handle *dns_handle; | ||
116 | |||
117 | static struct answer_packet_list *answer_proc_head; | ||
118 | |||
119 | static struct answer_packet_list *answer_proc_tail; | ||
120 | |||
121 | /** | ||
122 | * If there are at least this many address-mappings, old ones will be removed | ||
123 | */ | ||
124 | static long long unsigned int max_mappings = 200; | ||
125 | |||
126 | /** | ||
127 | * Final status code. | ||
128 | */ | ||
129 | static int ret; | ||
130 | |||
131 | /** | ||
132 | * This hashmap contains the mapping from peer, service-descriptor, | ||
133 | * source-port and destination-port to a socket | ||
134 | */ | ||
135 | static struct GNUNET_CONTAINER_MultiHashMap *udp_connections; | ||
136 | |||
137 | static GNUNET_SCHEDULER_TaskIdentifier conn_task; | ||
138 | |||
139 | static GNUNET_SCHEDULER_TaskIdentifier shs_task; | ||
140 | |||
141 | /** | ||
142 | * The tunnels that will be used to send tcp- and udp-packets | ||
143 | */ | ||
144 | static struct GNUNET_MESH_Tunnel *tcp_tunnel; | ||
145 | static struct GNUNET_MESH_Tunnel *udp_tunnel; | ||
146 | |||
147 | |||
148 | static unsigned int | ||
149 | port_in_ports (uint64_t ports, uint16_t port) | ||
150 | { | ||
151 | uint16_t *ps = (uint16_t *) & ports; | ||
152 | |||
153 | return ports == 0 || ps[0] == port || ps[1] == port || ps[2] == port || | ||
154 | ps[3] == port; | ||
155 | } | ||
156 | |||
157 | |||
158 | /** | ||
159 | * Sets a bit active in a bitArray. | ||
160 | * | ||
161 | * @param bitArray memory area to set the bit in | ||
162 | * @param bitIdx which bit to set | ||
163 | */ | ||
164 | static void | ||
165 | setBit (char *bitArray, unsigned int bitIdx) | ||
166 | { | ||
167 | size_t arraySlot; | ||
168 | unsigned int targetBit; | ||
169 | |||
170 | arraySlot = bitIdx / 8; | ||
171 | targetBit = (1L << (bitIdx % 8)); | ||
172 | bitArray[arraySlot] |= targetBit; | ||
173 | } | ||
174 | |||
175 | |||
176 | /** | ||
177 | * Checks if a bit is active in the bitArray | ||
178 | * | ||
179 | * @param bitArray memory area to set the bit in | ||
180 | * @param bitIdx which bit to test | ||
181 | * @return GNUNET_YES if the bit is set, GNUNET_NO if not. | ||
182 | */ | ||
183 | static int | ||
184 | testBit (char *bitArray, unsigned int bitIdx) | ||
185 | { | ||
186 | size_t slot; | ||
187 | unsigned int targetBit; | ||
188 | |||
189 | slot = bitIdx / 8; | ||
190 | targetBit = (1L << (bitIdx % 8)); | ||
191 | if (bitArray[slot] & targetBit) | ||
192 | return GNUNET_YES; | ||
193 | else | ||
194 | return GNUNET_NO; | ||
195 | } | ||
196 | |||
197 | |||
198 | /** | ||
199 | * Function scheduled as very last function, cleans up after us | ||
200 | *{{{ | ||
201 | */ | ||
202 | static void | ||
203 | cleanup (void *cls GNUNET_UNUSED, | ||
204 | const struct GNUNET_SCHEDULER_TaskContext *tskctx) | ||
205 | { | ||
206 | unsigned int i; | ||
207 | |||
208 | GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)); | ||
209 | /* close the connection to the service-dns */ | ||
210 | GNUNET_DNS_disconnect (dns_handle); | ||
211 | if (mesh_handle != NULL) | ||
212 | { | ||
213 | GNUNET_MESH_disconnect (mesh_handle); | ||
214 | mesh_handle = NULL; | ||
215 | } | ||
216 | if (helper_handle != NULL) | ||
217 | { | ||
218 | GNUNET_HELPER_stop (helper_handle); | ||
219 | helper_handle = NULL; | ||
220 | } | ||
221 | if (GNUNET_SCHEDULER_NO_TASK != shs_task) | ||
222 | { | ||
223 | GNUNET_SCHEDULER_cancel (shs_task); | ||
224 | shs_task = GNUNET_SCHEDULER_NO_TASK; | ||
225 | } | ||
226 | if (GNUNET_SCHEDULER_NO_TASK != conn_task) | ||
227 | { | ||
228 | GNUNET_SCHEDULER_cancel (conn_task); | ||
229 | conn_task = GNUNET_SCHEDULER_NO_TASK; | ||
230 | } | ||
231 | for (i=0;i<5;i++) | ||
232 | GNUNET_free_non_null (vpn_argv[i]); | ||
233 | } | ||
234 | |||
235 | /*}}}*/ | ||
236 | |||
237 | /** | ||
238 | * @return the hash of the IP-Address if a mapping exists, NULL otherwise | ||
239 | */ | ||
240 | static GNUNET_HashCode * | ||
241 | address6_mapping_exists (struct in6_addr *v6addr) | ||
242 | { | ||
243 | unsigned char *addr = (unsigned char*) v6addr; | ||
244 | GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode)); | ||
245 | unsigned char *k = (unsigned char *) key; | ||
246 | |||
247 | memset (key, 0, sizeof (GNUNET_HashCode)); | ||
248 | unsigned int i; | ||
249 | |||
250 | for (i = 0; i < 16; i++) | ||
251 | k[15 - i] = addr[i]; | ||
252 | |||
253 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key)) | ||
254 | return key; | ||
255 | else | ||
256 | { | ||
257 | GNUNET_free (key); | ||
258 | return NULL; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * @return the hash of the IP-Address if a mapping exists, NULL otherwise | ||
264 | */ | ||
265 | static GNUNET_HashCode * | ||
266 | address4_mapping_exists (uint32_t addr) | ||
267 | { | ||
268 | GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode)); | ||
269 | |||
270 | memset (key, 0, sizeof (GNUNET_HashCode)); | ||
271 | unsigned char *c = (unsigned char *) &addr; | ||
272 | unsigned char *k = (unsigned char *) key; | ||
273 | unsigned int i; | ||
274 | |||
275 | for (i = 0; i < 4; i++) | ||
276 | k[3 - i] = c[i]; | ||
277 | |||
278 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
279 | "a4_m_e: getting with key %08x, addr is %08x, %d.%d.%d.%d\n", | ||
280 | *((uint32_t *) (key)), addr, c[0], c[1], c[2], c[3]); | ||
281 | |||
282 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key)) | ||
283 | return key; | ||
284 | else | ||
285 | { | ||
286 | GNUNET_free (key); | ||
287 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mapping not found!\n"); | ||
288 | return NULL; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | |||
293 | static void * | ||
294 | initialize_tunnel_state (int addrlen, struct GNUNET_MESH_TransmitHandle *th) | ||
295 | { | ||
296 | struct tunnel_state *ts = GNUNET_malloc (sizeof *ts); | ||
297 | |||
298 | ts->addrlen = addrlen; | ||
299 | ts->th = th; | ||
300 | return ts; | ||
301 | } | ||
302 | |||
303 | |||
304 | static void | ||
305 | send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
306 | { | ||
307 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | ||
308 | return; | ||
309 | |||
310 | struct ip_icmp *request = cls; | ||
311 | |||
312 | struct ip_icmp *response = alloca (ntohs (request->shdr.size)); | ||
313 | |||
314 | GNUNET_assert (response != NULL); | ||
315 | memset (response, 0, ntohs (request->shdr.size)); | ||
316 | |||
317 | response->shdr.size = request->shdr.size; | ||
318 | response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
319 | |||
320 | response->tun.flags = 0; | ||
321 | response->tun.type = htons (0x0800); | ||
322 | |||
323 | response->ip_hdr.hdr_lngth = 5; | ||
324 | response->ip_hdr.version = 4; | ||
325 | response->ip_hdr.proto = 0x01; | ||
326 | response->ip_hdr.dadr = request->ip_hdr.sadr; | ||
327 | response->ip_hdr.sadr = request->ip_hdr.dadr; | ||
328 | response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth; | ||
329 | |||
330 | response->ip_hdr.chks = | ||
331 | GNUNET_CRYPTO_crc16_n ((uint16_t *) & response->ip_hdr, 20); | ||
332 | |||
333 | response->icmp_hdr.code = 0; | ||
334 | response->icmp_hdr.type = 0x0; | ||
335 | |||
336 | /* Magic, more Magic! */ | ||
337 | response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8; | ||
338 | |||
339 | /* Copy the rest of the packet */ | ||
340 | memcpy (response + 1, request + 1, | ||
341 | ntohs (request->shdr.size) - sizeof (struct ip_icmp)); | ||
342 | |||
343 | (void) GNUNET_HELPER_send (helper_handle, | ||
344 | &response->shdr, | ||
345 | GNUNET_YES, | ||
346 | NULL, NULL); | ||
347 | GNUNET_free (request); | ||
348 | } | ||
349 | |||
350 | |||
351 | static void | ||
352 | send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
353 | { | ||
354 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | ||
355 | return; | ||
356 | |||
357 | struct ip6_icmp *request = cls; | ||
358 | |||
359 | struct ip6_icmp *response = alloca (ntohs (request->shdr.size)); | ||
360 | |||
361 | GNUNET_assert (response != NULL); | ||
362 | memset (response, 0, ntohs (request->shdr.size)); | ||
363 | |||
364 | response->shdr.size = request->shdr.size; | ||
365 | response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
366 | |||
367 | response->tun.flags = 0; | ||
368 | response->tun.type = htons (0x86dd); | ||
369 | |||
370 | response->ip6_hdr.hoplmt = 255; | ||
371 | response->ip6_hdr.paylgth = request->ip6_hdr.paylgth; | ||
372 | response->ip6_hdr.nxthdr = 0x3a; | ||
373 | response->ip6_hdr.version = 6; | ||
374 | memcpy (&response->ip6_hdr.sadr, &request->ip6_hdr.dadr, 16); | ||
375 | memcpy (&response->ip6_hdr.dadr, &request->ip6_hdr.sadr, 16); | ||
376 | |||
377 | response->icmp_hdr.code = 0; | ||
378 | response->icmp_hdr.type = 0x81; | ||
379 | |||
380 | /* Magic, more Magic! */ | ||
381 | response->icmp_hdr.chks = request->icmp_hdr.chks - 0x1; | ||
382 | |||
383 | /* Copy the rest of the packet */ | ||
384 | memcpy (response + 1, request + 1, | ||
385 | ntohs (request->shdr.size) - sizeof (struct ip6_icmp)); | ||
386 | |||
387 | (void) GNUNET_HELPER_send (helper_handle, | ||
388 | &response->shdr, | ||
389 | GNUNET_YES, | ||
390 | NULL, NULL); | ||
391 | GNUNET_free (request); | ||
392 | } | ||
393 | |||
394 | |||
395 | /** | ||
396 | * cls is the pointer to a GNUNET_MessageHeader that is | ||
397 | * followed by the service-descriptor and the packet that should be sent; | ||
398 | */ | ||
399 | static size_t | ||
400 | send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf) | ||
401 | { | ||
402 | struct GNUNET_MESH_Tunnel **tunnel = cls; | ||
403 | |||
404 | struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel); | ||
405 | |||
406 | ts->th = NULL; | ||
407 | |||
408 | if (NULL != buf) | ||
409 | { | ||
410 | struct GNUNET_MessageHeader *hdr = | ||
411 | (struct GNUNET_MessageHeader *) (tunnel + 1); | ||
412 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
413 | "send_pkt_to_peer_notify_callback: buf = %x; size = %u;\n", buf, | ||
414 | size); | ||
415 | GNUNET_assert (size >= ntohs (hdr->size)); | ||
416 | memcpy (buf, hdr, ntohs (hdr->size)); | ||
417 | size = ntohs (hdr->size); | ||
418 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n"); | ||
419 | } | ||
420 | else | ||
421 | size = 0; | ||
422 | |||
423 | if (NULL != ts->head) | ||
424 | { | ||
425 | struct tunnel_notify_queue *element = ts->head; | ||
426 | |||
427 | GNUNET_CONTAINER_DLL_remove (ts->head, ts->tail, element); | ||
428 | |||
429 | ts->th = | ||
430 | GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42, | ||
431 | GNUNET_TIME_relative_divide | ||
432 | (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2), | ||
433 | (const struct GNUNET_PeerIdentity *) | ||
434 | NULL, element->len, | ||
435 | send_pkt_to_peer_notify_callback, | ||
436 | element->cls); | ||
437 | |||
438 | /* save the handle */ | ||
439 | GNUNET_free (element); | ||
440 | } | ||
441 | GNUNET_free (cls); | ||
442 | |||
443 | return size; | ||
444 | } | ||
445 | |||
446 | |||
447 | static void | ||
448 | send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
449 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
450 | { | ||
451 | /* peer == NULL means that all peers in this request are connected */ | ||
452 | if (peer == NULL) | ||
453 | return; | ||
454 | struct GNUNET_MESH_Tunnel **tunnel = cls; | ||
455 | struct GNUNET_MessageHeader *hdr = | ||
456 | (struct GNUNET_MessageHeader *) (tunnel + 1); | ||
457 | |||
458 | GNUNET_assert (NULL != tunnel); | ||
459 | GNUNET_assert (NULL != *tunnel); | ||
460 | |||
461 | struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel); | ||
462 | |||
463 | if (NULL == ts->th) | ||
464 | { | ||
465 | ts->th = | ||
466 | GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42, | ||
467 | GNUNET_TIME_relative_divide | ||
468 | (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2), | ||
469 | (const struct GNUNET_PeerIdentity *) | ||
470 | NULL, ntohs (hdr->size), | ||
471 | send_pkt_to_peer_notify_callback, | ||
472 | cls); | ||
473 | } | ||
474 | else | ||
475 | { | ||
476 | struct tunnel_notify_queue *element = GNUNET_malloc (sizeof *element); | ||
477 | |||
478 | element->cls = cls; | ||
479 | element->len = ntohs (hdr->size); | ||
480 | |||
481 | GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, element); | ||
482 | } | ||
483 | } | ||
484 | |||
485 | |||
486 | |||
487 | |||
488 | /** | ||
489 | * Receive packets from the helper-process | ||
490 | */ | ||
491 | static void | ||
492 | message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | ||
493 | const struct GNUNET_MessageHeader *message) | ||
494 | { | ||
495 | GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
496 | |||
497 | struct tun_pkt *pkt_tun = (struct tun_pkt *) message; | ||
498 | GNUNET_HashCode *key; | ||
499 | |||
500 | /* ethertype is ipv6 */ | ||
501 | if (ntohs (pkt_tun->tun.type) == 0x86dd) | ||
502 | { | ||
503 | struct ip6_pkt *pkt6 = (struct ip6_pkt *) message; | ||
504 | |||
505 | GNUNET_assert (pkt6->ip6_hdr.version == 6); | ||
506 | struct ip6_tcp *pkt6_tcp; | ||
507 | struct ip6_udp *pkt6_udp; | ||
508 | struct ip6_icmp *pkt6_icmp; | ||
509 | |||
510 | pkt6_udp = NULL; /* make compiler happy */ | ||
511 | switch (pkt6->ip6_hdr.nxthdr) | ||
512 | { | ||
513 | case IPPROTO_UDP: | ||
514 | pkt6_udp = (struct ip6_udp *) pkt6; | ||
515 | /* Send dns-packets to the service-dns */ | ||
516 | if (ntohs (pkt6_udp->udp_hdr.dpt) == 53) | ||
517 | { | ||
518 | /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */ | ||
519 | GNUNET_DNS_queue_request_v6 (dns_handle, | ||
520 | &pkt6->ip6_hdr.dadr, | ||
521 | &pkt6->ip6_hdr.sadr, | ||
522 | ntohs (pkt6_udp->udp_hdr.spt), | ||
523 | ntohs (pkt6_udp->udp_hdr.len) - 8, | ||
524 | (const void*) pkt6_udp->data); | ||
525 | |||
526 | break; | ||
527 | } | ||
528 | /* fall through */ | ||
529 | case IPPROTO_TCP: | ||
530 | pkt6_tcp = (struct ip6_tcp *) pkt6; | ||
531 | |||
532 | if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) | ||
533 | { | ||
534 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
535 | |||
536 | GNUNET_assert (me != NULL); | ||
537 | GNUNET_free (key); | ||
538 | |||
539 | size_t size = | ||
540 | sizeof (struct GNUNET_MESH_Tunnel *) + | ||
541 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + | ||
542 | ntohs (pkt6->ip6_hdr.paylgth); | ||
543 | |||
544 | struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size); | ||
545 | struct GNUNET_MessageHeader *hdr = | ||
546 | (struct GNUNET_MessageHeader *) (cls + 1); | ||
547 | GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1); | ||
548 | |||
549 | hdr->size = | ||
550 | htons (sizeof (struct GNUNET_MessageHeader) + | ||
551 | sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth)); | ||
552 | |||
553 | GNUNET_MESH_ApplicationType app_type = 0; /* fix compiler uninitialized warning... */ | ||
554 | |||
555 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n", | ||
556 | me->addrlen); | ||
557 | if (me->addrlen == 0) | ||
558 | { | ||
559 | /* This is a mapping to a gnunet-service */ | ||
560 | memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode)); | ||
561 | |||
562 | if (IPPROTO_UDP == pkt6->ip6_hdr.nxthdr && | ||
563 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) && | ||
564 | (port_in_ports (me->desc.ports, pkt6_udp->udp_hdr.dpt) || | ||
565 | testBit (me->additional_ports, ntohs (pkt6_udp->udp_hdr.dpt)))) | ||
566 | { | ||
567 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP); | ||
568 | |||
569 | memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len)); | ||
570 | |||
571 | } | ||
572 | else if (IPPROTO_TCP == pkt6->ip6_hdr.nxthdr && | ||
573 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP)) | ||
574 | && (port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt))) | ||
575 | { | ||
576 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP); | ||
577 | |||
578 | memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth)); | ||
579 | |||
580 | } | ||
581 | else | ||
582 | { | ||
583 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pip: %d\n", | ||
584 | port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt)); | ||
585 | GNUNET_assert (0); | ||
586 | } | ||
587 | if (me->tunnel == NULL && NULL != cls) | ||
588 | { | ||
589 | *cls = | ||
590 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
591 | initialize_tunnel_state (16, NULL), | ||
592 | &send_pkt_to_peer, NULL, cls); | ||
593 | |||
594 | GNUNET_MESH_peer_request_connect_add (*cls, | ||
595 | (struct GNUNET_PeerIdentity *) | ||
596 | &me->desc.peer); | ||
597 | me->tunnel = *cls; | ||
598 | } | ||
599 | else if (NULL != cls) | ||
600 | { | ||
601 | *cls = me->tunnel; | ||
602 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
603 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
604 | "Queued to send IPv6 to peer %x, type %d\n", | ||
605 | *((unsigned int *) &me->desc.peer), ntohs (hdr->type)); | ||
606 | } | ||
607 | } | ||
608 | else | ||
609 | { | ||
610 | /* This is a mapping to a "real" address */ | ||
611 | struct remote_addr *s = (struct remote_addr *) hc; | ||
612 | |||
613 | s->addrlen = me->addrlen; | ||
614 | memcpy (s->addr, me->addr, me->addrlen); | ||
615 | s->proto = pkt6->ip6_hdr.nxthdr; | ||
616 | if (s->proto == IPPROTO_UDP) | ||
617 | { | ||
618 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP); | ||
619 | memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len)); | ||
620 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY; | ||
621 | if (NULL != udp_tunnel) | ||
622 | me->tunnel = udp_tunnel; | ||
623 | } | ||
624 | else if (s->proto == IPPROTO_TCP) | ||
625 | { | ||
626 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP); | ||
627 | memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth)); | ||
628 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY; | ||
629 | if (NULL != tcp_tunnel) | ||
630 | me->tunnel = tcp_tunnel; | ||
631 | } | ||
632 | else | ||
633 | { | ||
634 | GNUNET_assert (0); | ||
635 | } | ||
636 | if (me->tunnel == NULL && NULL != cls) | ||
637 | { | ||
638 | *cls = | ||
639 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
640 | initialize_tunnel_state (16, NULL), | ||
641 | &send_pkt_to_peer, NULL, cls); | ||
642 | |||
643 | GNUNET_MESH_peer_request_connect_by_type (*cls, app_type); | ||
644 | me->tunnel = *cls; | ||
645 | if (GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY == app_type) | ||
646 | udp_tunnel = *cls; | ||
647 | else if (GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY == app_type) | ||
648 | tcp_tunnel = *cls; | ||
649 | } | ||
650 | else if (NULL != cls) | ||
651 | { | ||
652 | *cls = me->tunnel; | ||
653 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
654 | } | ||
655 | } | ||
656 | } | ||
657 | else | ||
658 | { | ||
659 | char pbuf[INET6_ADDRSTRLEN]; | ||
660 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
661 | "Packet to %s, which has no mapping\n", | ||
662 | inet_ntop (AF_INET6, | ||
663 | &pkt6->ip6_hdr.dadr, | ||
664 | pbuf, | ||
665 | sizeof (pbuf))); | ||
666 | } | ||
667 | break; | ||
668 | case 0x3a: | ||
669 | /* ICMPv6 */ | ||
670 | pkt6_icmp = (struct ip6_icmp *) pkt6; | ||
671 | /* If this packet is an icmp-echo-request and a mapping exists, answer */ | ||
672 | if (pkt6_icmp->icmp_hdr.type == 0x80 && | ||
673 | (key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) | ||
674 | { | ||
675 | GNUNET_free (key); | ||
676 | pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size)); | ||
677 | memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size)); | ||
678 | GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp); | ||
679 | } | ||
680 | break; | ||
681 | } | ||
682 | } | ||
683 | /* ethertype is ipv4 */ | ||
684 | else if (ntohs (pkt_tun->tun.type) == 0x0800) | ||
685 | { | ||
686 | struct ip_pkt *pkt = (struct ip_pkt *) message; | ||
687 | struct ip_udp *udp = (struct ip_udp *) message; | ||
688 | struct ip_tcp *pkt_tcp; | ||
689 | struct ip_udp *pkt_udp; | ||
690 | struct ip_icmp *pkt_icmp; | ||
691 | |||
692 | GNUNET_assert (pkt->ip_hdr.version == 4); | ||
693 | |||
694 | /* Send dns-packets to the service-dns */ | ||
695 | if (pkt->ip_hdr.proto == IPPROTO_UDP && ntohs (udp->udp_hdr.dpt) == 53) | ||
696 | { | ||
697 | GNUNET_DNS_queue_request_v4 (dns_handle, | ||
698 | &pkt->ip_hdr.dadr, | ||
699 | &pkt->ip_hdr.sadr, | ||
700 | ntohs (udp->udp_hdr.spt), | ||
701 | ntohs (udp->udp_hdr.len) - 8, | ||
702 | (const void*) udp->data); | ||
703 | } | ||
704 | else | ||
705 | { | ||
706 | uint32_t dadr = pkt->ip_hdr.dadr.s_addr; | ||
707 | unsigned char *c = (unsigned char *) &dadr; | ||
708 | |||
709 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Packet to %d.%d.%d.%d, proto %x\n", | ||
710 | c[0], c[1], c[2], c[3], pkt->ip_hdr.proto); | ||
711 | switch (pkt->ip_hdr.proto) | ||
712 | { | ||
713 | case IPPROTO_TCP: | ||
714 | case IPPROTO_UDP: | ||
715 | pkt_tcp = (struct ip_tcp *) pkt; | ||
716 | pkt_udp = (struct ip_udp *) pkt; | ||
717 | |||
718 | if ((key = address4_mapping_exists (dadr)) != NULL) | ||
719 | { | ||
720 | struct map_entry *me = | ||
721 | GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
722 | GNUNET_assert (me != NULL); | ||
723 | GNUNET_free (key); | ||
724 | |||
725 | size_t size = | ||
726 | sizeof (struct GNUNET_MESH_Tunnel *) + | ||
727 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + | ||
728 | ntohs (pkt->ip_hdr.tot_lngth) - 4 * pkt->ip_hdr.hdr_lngth; | ||
729 | |||
730 | struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size); | ||
731 | struct GNUNET_MessageHeader *hdr = | ||
732 | (struct GNUNET_MessageHeader *) (cls + 1); | ||
733 | GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1); | ||
734 | |||
735 | hdr->size = | ||
736 | htons (sizeof (struct GNUNET_MessageHeader) + | ||
737 | sizeof (GNUNET_HashCode) + ntohs (pkt->ip_hdr.tot_lngth) - | ||
738 | 4 * pkt->ip_hdr.hdr_lngth); | ||
739 | |||
740 | GNUNET_MESH_ApplicationType app_type = 0; /* make compiler happy */ | ||
741 | |||
742 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n", | ||
743 | me->addrlen); | ||
744 | if (me->addrlen == 0) | ||
745 | { | ||
746 | /* This is a mapping to a gnunet-service */ | ||
747 | memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode)); | ||
748 | |||
749 | if ((IPPROTO_UDP == pkt->ip_hdr.proto) && | ||
750 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) && | ||
751 | (port_in_ports (me->desc.ports, pkt_udp->udp_hdr.dpt) || | ||
752 | testBit (me->additional_ports, ntohs (pkt_udp->udp_hdr.dpt)))) | ||
753 | { | ||
754 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP); | ||
755 | |||
756 | memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len)); | ||
757 | |||
758 | } | ||
759 | else if ((IPPROTO_TCP == pkt->ip_hdr.proto) && | ||
760 | (me-> | ||
761 | desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP)) | ||
762 | && (port_in_ports (me->desc.ports, pkt_tcp->tcp_hdr.dpt))) | ||
763 | { | ||
764 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP); | ||
765 | |||
766 | memcpy (hc + 1, &pkt_tcp->tcp_hdr, | ||
767 | ntohs (pkt->ip_hdr.tot_lngth) - | ||
768 | 4 * pkt->ip_hdr.hdr_lngth); | ||
769 | |||
770 | } | ||
771 | if (me->tunnel == NULL && NULL != cls) | ||
772 | { | ||
773 | *cls = | ||
774 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
775 | initialize_tunnel_state (4, NULL), | ||
776 | send_pkt_to_peer, NULL, cls); | ||
777 | GNUNET_MESH_peer_request_connect_add (*cls, | ||
778 | (struct GNUNET_PeerIdentity | ||
779 | *) &me->desc.peer); | ||
780 | me->tunnel = *cls; | ||
781 | } | ||
782 | else if (NULL != cls) | ||
783 | { | ||
784 | *cls = me->tunnel; | ||
785 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
786 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
787 | "Queued to send IPv4 to peer %x, type %d\n", | ||
788 | *((unsigned int *) &me->desc.peer), | ||
789 | ntohs (hdr->type)); | ||
790 | } | ||
791 | } | ||
792 | else | ||
793 | { | ||
794 | /* This is a mapping to a "real" address */ | ||
795 | struct remote_addr *s = (struct remote_addr *) hc; | ||
796 | |||
797 | s->addrlen = me->addrlen; | ||
798 | memcpy (s->addr, me->addr, me->addrlen); | ||
799 | s->proto = pkt->ip_hdr.proto; | ||
800 | if (s->proto == IPPROTO_UDP) | ||
801 | { | ||
802 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP); | ||
803 | memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len)); | ||
804 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY; | ||
805 | } | ||
806 | else if (s->proto == IPPROTO_TCP) | ||
807 | { | ||
808 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP); | ||
809 | memcpy (hc + 1, &pkt_tcp->tcp_hdr, | ||
810 | ntohs (pkt->ip_hdr.tot_lngth) - | ||
811 | 4 * pkt->ip_hdr.hdr_lngth); | ||
812 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY; | ||
813 | } | ||
814 | else | ||
815 | GNUNET_assert (0); | ||
816 | if (me->tunnel == NULL && NULL != cls) | ||
817 | { | ||
818 | *cls = | ||
819 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
820 | initialize_tunnel_state (4, NULL), | ||
821 | send_pkt_to_peer, NULL, cls); | ||
822 | |||
823 | GNUNET_MESH_peer_request_connect_by_type (*cls, app_type); | ||
824 | me->tunnel = *cls; | ||
825 | } | ||
826 | else if (NULL != cls) | ||
827 | { | ||
828 | *cls = me->tunnel; | ||
829 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
830 | } | ||
831 | } | ||
832 | } | ||
833 | else | ||
834 | { | ||
835 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
836 | "Packet to %x which has no mapping\n", dadr); | ||
837 | } | ||
838 | break; | ||
839 | case 0x01: | ||
840 | /* ICMP */ | ||
841 | pkt_icmp = (struct ip_icmp *) pkt; | ||
842 | if (pkt_icmp->icmp_hdr.type == 0x8 && | ||
843 | (key = address4_mapping_exists (dadr)) != NULL) | ||
844 | { | ||
845 | GNUNET_free (key); | ||
846 | pkt_icmp = GNUNET_malloc (ntohs (pkt->shdr.size)); | ||
847 | memcpy (pkt_icmp, pkt, ntohs (pkt->shdr.size)); | ||
848 | GNUNET_SCHEDULER_add_now (&send_icmp4_response, pkt_icmp); | ||
849 | } | ||
850 | break; | ||
851 | } | ||
852 | } | ||
853 | } | ||
854 | } | ||
855 | |||
856 | |||
857 | |||
858 | static void | ||
859 | collect_mappings (void *cls GNUNET_UNUSED, | ||
860 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
861 | { | ||
862 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | ||
863 | return; | ||
864 | |||
865 | struct map_entry *me = GNUNET_CONTAINER_heap_remove_root (heap); | ||
866 | |||
867 | /* This is free()ed memory! */ | ||
868 | me->heap_node = NULL; | ||
869 | |||
870 | /* FIXME! GNUNET_MESH_close_tunnel(me->tunnel); */ | ||
871 | |||
872 | GNUNET_assert (GNUNET_YES == | ||
873 | GNUNET_CONTAINER_multihashmap_remove (hashmap, &me->hash, me)); | ||
874 | |||
875 | GNUNET_free (me); | ||
876 | } | ||
877 | |||
878 | |||
879 | /** | ||
880 | * Create a new Address from an answer-packet | ||
881 | */ | ||
882 | static void | ||
883 | new_ip6addr (struct in6_addr *v6addr, | ||
884 | const GNUNET_HashCode * peer, | ||
885 | const GNUNET_HashCode * service_desc) | ||
886 | { /* {{{ */ | ||
887 | unsigned char *buf = (unsigned char*) v6addr; | ||
888 | char *ipv6addr; | ||
889 | unsigned long long ipv6prefix; | ||
890 | |||
891 | GNUNET_assert (GNUNET_OK == | ||
892 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", | ||
893 | &ipv6addr)); | ||
894 | GNUNET_assert (GNUNET_OK == | ||
895 | GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", | ||
896 | "IPV6PREFIX", | ||
897 | &ipv6prefix)); | ||
898 | GNUNET_assert (ipv6prefix < 127); | ||
899 | ipv6prefix = (ipv6prefix + 7) / 8; | ||
900 | |||
901 | inet_pton (AF_INET6, ipv6addr, buf); | ||
902 | GNUNET_free (ipv6addr); | ||
903 | |||
904 | int peer_length = 16 - ipv6prefix - 6; | ||
905 | |||
906 | if (peer_length <= 0) | ||
907 | peer_length = 0; | ||
908 | |||
909 | int service_length = 16 - ipv6prefix - peer_length; | ||
910 | |||
911 | if (service_length <= 0) | ||
912 | service_length = 0; | ||
913 | |||
914 | memcpy (buf + ipv6prefix, service_desc, service_length); | ||
915 | memcpy (buf + ipv6prefix + service_length, peer, peer_length); | ||
916 | } | ||
917 | |||
918 | /*}}}*/ | ||
919 | |||
920 | |||
921 | /** | ||
922 | * Create a new Address from an answer-packet | ||
923 | */ | ||
924 | static void | ||
925 | new_ip6addr_remote (struct in6_addr *v6addr, | ||
926 | unsigned char *addr, char addrlen) | ||
927 | { /* {{{ */ | ||
928 | unsigned char *buf = (unsigned char*) v6addr; | ||
929 | char *ipv6addr; | ||
930 | unsigned long long ipv6prefix; | ||
931 | |||
932 | GNUNET_assert (GNUNET_OK == | ||
933 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", | ||
934 | &ipv6addr)); | ||
935 | GNUNET_assert (GNUNET_OK == | ||
936 | GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", | ||
937 | "IPV6PREFIX", | ||
938 | &ipv6prefix)); | ||
939 | GNUNET_assert (ipv6prefix < 127); | ||
940 | ipv6prefix = (ipv6prefix + 7) / 8; | ||
941 | |||
942 | inet_pton (AF_INET6, ipv6addr, buf); | ||
943 | GNUNET_free (ipv6addr); | ||
944 | |||
945 | int local_length = 16 - ipv6prefix; | ||
946 | |||
947 | memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length)); | ||
948 | } | ||
949 | |||
950 | /*}}}*/ | ||
951 | |||
952 | /** | ||
953 | * Create a new Address from an answer-packet | ||
954 | */ | ||
955 | static void | ||
956 | new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen) | ||
957 | { /* {{{ */ | ||
958 | char *ipv4addr; | ||
959 | char *ipv4mask; | ||
960 | |||
961 | GNUNET_assert (GNUNET_OK == | ||
962 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", | ||
963 | &ipv4addr)); | ||
964 | GNUNET_assert (GNUNET_OK == | ||
965 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", | ||
966 | &ipv4mask)); | ||
967 | uint32_t mask; | ||
968 | |||
969 | inet_pton (AF_INET, ipv4addr, buf); | ||
970 | int r = inet_pton (AF_INET, ipv4mask, &mask); | ||
971 | |||
972 | mask = htonl (mask); | ||
973 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r, | ||
974 | mask); | ||
975 | |||
976 | GNUNET_free (ipv4addr); | ||
977 | |||
978 | int c; | ||
979 | |||
980 | if (mask) | ||
981 | { | ||
982 | mask = (mask ^ (mask - 1)) >> 1; | ||
983 | for (c = 0; mask; c++) | ||
984 | { | ||
985 | mask >>= 1; | ||
986 | } | ||
987 | } | ||
988 | else | ||
989 | { | ||
990 | c = CHAR_BIT * sizeof (mask); | ||
991 | } | ||
992 | |||
993 | c = 32 - c; | ||
994 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n", | ||
995 | ipv4mask, c); | ||
996 | |||
997 | GNUNET_free (ipv4mask); | ||
998 | |||
999 | if (c % 8 == 0) | ||
1000 | c = c / 8; | ||
1001 | else | ||
1002 | GNUNET_assert (0); | ||
1003 | |||
1004 | memcpy (buf + c, addr, GNUNET_MIN (addrlen, 4 - c)); | ||
1005 | } | ||
1006 | |||
1007 | /*}}}*/ | ||
1008 | |||
1009 | /** | ||
1010 | * This gets scheduled with cls pointing to an answer_packet and does everything | ||
1011 | * needed in order to send it to the helper. | ||
1012 | * | ||
1013 | * At the moment this means "inventing" and IPv6-Address for .gnunet-services and | ||
1014 | * doing nothing for "real" services. | ||
1015 | */ | ||
1016 | static void | ||
1017 | process_answer (void *cls, | ||
1018 | const struct answer_packet *pkt) | ||
1019 | { | ||
1020 | struct answer_packet_list *list; | ||
1021 | |||
1022 | /* This answer is about a .gnunet-service | ||
1023 | * | ||
1024 | * It contains an almost complete DNS-Response, we have to fill in the ip | ||
1025 | * at the offset pkt->addroffset | ||
1026 | */ | ||
1027 | if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE) | ||
1028 | { | ||
1029 | |||
1030 | GNUNET_HashCode key; | ||
1031 | |||
1032 | memset (&key, 0, sizeof (GNUNET_HashCode)); | ||
1033 | |||
1034 | list = | ||
1035 | GNUNET_malloc (htons (pkt->hdr.size) + | ||
1036 | sizeof (struct answer_packet_list) - | ||
1037 | sizeof (struct answer_packet)); | ||
1038 | memcpy (&list->pkt, pkt, htons (pkt->hdr.size)); | ||
1039 | |||
1040 | unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset); | ||
1041 | unsigned char *k = (unsigned char *) &key; | ||
1042 | |||
1043 | new_ip6addr ((struct in6_addr*) c, | ||
1044 | &pkt->service_descr.peer, | ||
1045 | &pkt->service_descr.service_descriptor); | ||
1046 | /* | ||
1047 | * Copy the newly generated ip-address to the key backwarts (as only the first part is hashed) | ||
1048 | */ | ||
1049 | unsigned int i; | ||
1050 | |||
1051 | for (i = 0; i < 16; i++) | ||
1052 | k[15 - i] = c[i]; | ||
1053 | |||
1054 | uint16_t namelen = strlen ((char *) pkt->data + 12) + 1; | ||
1055 | |||
1056 | struct map_entry *value = | ||
1057 | GNUNET_malloc (sizeof (struct map_entry) + namelen); | ||
1058 | char *name = (char *) (value + 1); | ||
1059 | |||
1060 | value->namelen = namelen; | ||
1061 | memcpy (name, pkt->data + 12, namelen); | ||
1062 | |||
1063 | memcpy (&value->desc, &pkt->service_descr, | ||
1064 | sizeof (struct GNUNET_vpn_service_descriptor)); | ||
1065 | |||
1066 | memset (value->additional_ports, 0, 8192); | ||
1067 | |||
1068 | memcpy (&value->hash, &key, sizeof (GNUNET_HashCode)); | ||
1069 | |||
1070 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key)) | ||
1071 | { | ||
1072 | GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value, | ||
1073 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1074 | |||
1075 | value->heap_node = | ||
1076 | GNUNET_CONTAINER_heap_insert (heap, value, | ||
1077 | GNUNET_TIME_absolute_get ().abs_value); | ||
1078 | if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings) | ||
1079 | GNUNET_SCHEDULER_add_now (collect_mappings, NULL); | ||
1080 | } | ||
1081 | else | ||
1082 | GNUNET_free (value); | ||
1083 | |||
1084 | |||
1085 | list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP; | ||
1086 | |||
1087 | |||
1088 | } | ||
1089 | else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REV) | ||
1090 | { | ||
1091 | GNUNET_HashCode key; | ||
1092 | |||
1093 | memset (&key, 0, sizeof key); | ||
1094 | unsigned char *k = (unsigned char *) &key; | ||
1095 | const unsigned char *s = pkt->data + 12; | ||
1096 | int i = 0; | ||
1097 | |||
1098 | /* Whoever designed the reverse IPv6-lookup is batshit insane */ | ||
1099 | for (i = 0; i < 16; i++) | ||
1100 | { | ||
1101 | unsigned char c1 = s[(4 * i) + 1]; | ||
1102 | unsigned char c2 = s[(4 * i) + 3]; | ||
1103 | |||
1104 | if (c1 <= '9') | ||
1105 | k[i] = c1 - '0'; | ||
1106 | else | ||
1107 | k[i] = c1 - 87; /* 87 is the difference between 'a' and 10 */ | ||
1108 | if (c2 <= '9') | ||
1109 | k[i] += 16 * (c2 - '0'); | ||
1110 | else | ||
1111 | k[i] += 16 * (c2 - 87); | ||
1112 | } | ||
1113 | |||
1114 | struct map_entry *map_entry = | ||
1115 | GNUNET_CONTAINER_multihashmap_get (hashmap, &key); | ||
1116 | uint16_t offset = ntohs (pkt->addroffset); | ||
1117 | |||
1118 | if (map_entry == NULL) | ||
1119 | return; | ||
1120 | |||
1121 | GNUNET_CONTAINER_heap_update_cost (heap, map_entry->heap_node, | ||
1122 | GNUNET_TIME_absolute_get ().abs_value); | ||
1123 | |||
1124 | |||
1125 | unsigned short namelen = htons (map_entry->namelen); | ||
1126 | char *name = (char *) (map_entry + 1); | ||
1127 | |||
1128 | list = | ||
1129 | GNUNET_malloc (sizeof (struct answer_packet_list) - | ||
1130 | sizeof (struct answer_packet) + offset + 2 + | ||
1131 | ntohs (namelen)); | ||
1132 | |||
1133 | struct answer_packet *rpkt = &list->pkt; | ||
1134 | |||
1135 | /* The offset points to the first byte belonging to the address */ | ||
1136 | memcpy (rpkt, pkt, offset - 1); | ||
1137 | |||
1138 | rpkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP; | ||
1139 | rpkt->hdr.size = ntohs (offset + 2 + ntohs (namelen)); | ||
1140 | |||
1141 | memcpy (((char *) rpkt) + offset, &namelen, 2); | ||
1142 | memcpy (((char *) rpkt) + offset + 2, name, ntohs (namelen)); | ||
1143 | |||
1144 | } | ||
1145 | else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP) | ||
1146 | { | ||
1147 | list = | ||
1148 | GNUNET_malloc (htons (pkt->hdr.size) + | ||
1149 | sizeof (struct answer_packet_list) - | ||
1150 | sizeof (struct answer_packet)); | ||
1151 | memcpy (&list->pkt, pkt, htons (pkt->hdr.size)); | ||
1152 | } | ||
1153 | else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA) | ||
1154 | { | ||
1155 | |||
1156 | GNUNET_HashCode key; | ||
1157 | |||
1158 | memset (&key, 0, sizeof (GNUNET_HashCode)); | ||
1159 | |||
1160 | list = | ||
1161 | GNUNET_malloc (htons (pkt->hdr.size) + | ||
1162 | sizeof (struct answer_packet_list) - | ||
1163 | sizeof (struct answer_packet)); | ||
1164 | |||
1165 | memcpy (&list->pkt, pkt, htons (pkt->hdr.size)); | ||
1166 | list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP; | ||
1167 | |||
1168 | unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (list->pkt.addroffset); | ||
1169 | |||
1170 | new_ip6addr_remote ((struct in6_addr*) c, | ||
1171 | list->pkt.addr, list->pkt.addrsize); | ||
1172 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1173 | "New mapping to %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", | ||
1174 | c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], | ||
1175 | c[10], c[11], c[12], c[13], c[14], c[15]); | ||
1176 | unsigned char *k = (unsigned char *) &key; | ||
1177 | |||
1178 | /* | ||
1179 | * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table) | ||
1180 | */ | ||
1181 | unsigned int i; | ||
1182 | |||
1183 | for (i = 0; i < 16; i++) | ||
1184 | k[15 - i] = c[i]; | ||
1185 | |||
1186 | uint16_t namelen = strlen ((char *) pkt->data + 12) + 1; | ||
1187 | |||
1188 | struct map_entry *value = | ||
1189 | GNUNET_malloc (sizeof (struct map_entry) + namelen); | ||
1190 | char *name = (char *) (value + 1); | ||
1191 | |||
1192 | value->namelen = namelen; | ||
1193 | memcpy (name, pkt->data + 12, namelen); | ||
1194 | |||
1195 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n", | ||
1196 | pkt->addrsize); | ||
1197 | value->addrlen = pkt->addrsize; | ||
1198 | memcpy (&value->addr, &pkt->addr, pkt->addrsize); | ||
1199 | memset (value->additional_ports, 0, 8192); | ||
1200 | |||
1201 | memcpy (&value->hash, &key, sizeof (GNUNET_HashCode)); | ||
1202 | |||
1203 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key)) | ||
1204 | { | ||
1205 | GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value, | ||
1206 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1207 | value->heap_node = | ||
1208 | GNUNET_CONTAINER_heap_insert (heap, value, | ||
1209 | GNUNET_TIME_absolute_get ().abs_value); | ||
1210 | if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings) | ||
1211 | GNUNET_SCHEDULER_add_now (collect_mappings, NULL); | ||
1212 | } | ||
1213 | else | ||
1214 | GNUNET_free (value); | ||
1215 | |||
1216 | |||
1217 | } | ||
1218 | else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A) | ||
1219 | { | ||
1220 | list = | ||
1221 | GNUNET_malloc (htons (pkt->hdr.size) + | ||
1222 | sizeof (struct answer_packet_list) - | ||
1223 | sizeof (struct answer_packet)); | ||
1224 | |||
1225 | memcpy (&list->pkt, pkt, htons (pkt->hdr.size)); | ||
1226 | list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP; | ||
1227 | |||
1228 | GNUNET_HashCode key; | ||
1229 | |||
1230 | memset (&key, 0, sizeof (GNUNET_HashCode)); | ||
1231 | |||
1232 | unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset); | ||
1233 | |||
1234 | new_ip4addr_remote (c, list->pkt.addr, pkt->addrsize); | ||
1235 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New mapping to %d.%d.%d.%d\n", c[0], | ||
1236 | c[1], c[2], c[3]); | ||
1237 | unsigned char *k = (unsigned char *) &key; | ||
1238 | |||
1239 | /* | ||
1240 | * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table) | ||
1241 | */ | ||
1242 | unsigned int i; | ||
1243 | |||
1244 | for (i = 0; i < 4; i++) | ||
1245 | k[3 - i] = c[i]; | ||
1246 | |||
1247 | uint16_t namelen = strlen ((char *) pkt->data + 12) + 1; | ||
1248 | |||
1249 | struct map_entry *value = | ||
1250 | GNUNET_malloc (sizeof (struct map_entry) + namelen); | ||
1251 | char *name = (char *) (value + 1); | ||
1252 | |||
1253 | value->namelen = namelen; | ||
1254 | memcpy (name, pkt->data + 12, namelen); | ||
1255 | |||
1256 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n", | ||
1257 | pkt->addrsize); | ||
1258 | value->addrlen = pkt->addrsize; | ||
1259 | memcpy (&value->addr, &pkt->addr, pkt->addrsize); | ||
1260 | memset (value->additional_ports, 0, 8192); | ||
1261 | |||
1262 | memcpy (&value->hash, &key, sizeof (GNUNET_HashCode)); | ||
1263 | |||
1264 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key)) | ||
1265 | { | ||
1266 | GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value, | ||
1267 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1268 | value->heap_node = | ||
1269 | GNUNET_CONTAINER_heap_insert (heap, value, | ||
1270 | GNUNET_TIME_absolute_get ().abs_value); | ||
1271 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1272 | "Mapping is saved in the hashmap with key %08x.\n", | ||
1273 | *((uint32_t *) (&key))); | ||
1274 | if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings) | ||
1275 | GNUNET_SCHEDULER_add_now (collect_mappings, NULL); | ||
1276 | } | ||
1277 | else | ||
1278 | GNUNET_free (value); | ||
1279 | |||
1280 | } | ||
1281 | else | ||
1282 | { | ||
1283 | GNUNET_break (0); | ||
1284 | return; | ||
1285 | } | ||
1286 | |||
1287 | GNUNET_CONTAINER_DLL_insert_after (answer_proc_head, answer_proc_tail, | ||
1288 | answer_proc_tail, list); | ||
1289 | |||
1290 | } | ||
1291 | |||
1292 | |||
1293 | /** | ||
1294 | * @brief Add the port to the list of additional ports in the map_entry | ||
1295 | * | ||
1296 | * @param me the map_entry | ||
1297 | * @param port the port in host-byte-order | ||
1298 | */ | ||
1299 | static void | ||
1300 | add_additional_port (struct map_entry *me, uint16_t port) | ||
1301 | { | ||
1302 | setBit (me->additional_ports, port); | ||
1303 | } | ||
1304 | |||
1305 | static int | ||
1306 | receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1307 | void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender, | ||
1308 | const struct GNUNET_MessageHeader *message, | ||
1309 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1310 | { | ||
1311 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
1312 | struct remote_addr *s = (struct remote_addr *) desc; | ||
1313 | struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); | ||
1314 | const struct GNUNET_PeerIdentity *other = sender; | ||
1315 | struct tunnel_state *ts = *tunnel_ctx; | ||
1316 | |||
1317 | if (16 == ts->addrlen) | ||
1318 | { | ||
1319 | size_t size = | ||
1320 | sizeof (struct ip6_udp) + ntohs (pkt->len) - 1 - | ||
1321 | sizeof (struct udp_pkt); | ||
1322 | |||
1323 | struct ip6_udp *pkt6 = alloca (size); | ||
1324 | |||
1325 | GNUNET_assert (pkt6 != NULL); | ||
1326 | |||
1327 | if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK) | ||
1328 | new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc); | ||
1329 | else | ||
1330 | new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen); | ||
1331 | |||
1332 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1333 | "Relaying calc:%d gnu:%d udp:%d bytes!\n", size, | ||
1334 | ntohs (message->size), ntohs (pkt->len)); | ||
1335 | |||
1336 | pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1337 | pkt6->shdr.size = htons (size); | ||
1338 | |||
1339 | pkt6->tun.flags = 0; | ||
1340 | pkt6->tun.type = htons (0x86dd); | ||
1341 | |||
1342 | pkt6->ip6_hdr.version = 6; | ||
1343 | pkt6->ip6_hdr.tclass_h = 0; | ||
1344 | pkt6->ip6_hdr.tclass_l = 0; | ||
1345 | pkt6->ip6_hdr.flowlbl = 0; | ||
1346 | pkt6->ip6_hdr.paylgth = pkt->len; | ||
1347 | pkt6->ip6_hdr.nxthdr = IPPROTO_UDP; | ||
1348 | pkt6->ip6_hdr.hoplmt = 0xff; | ||
1349 | |||
1350 | { | ||
1351 | char *ipv6addr; | ||
1352 | |||
1353 | GNUNET_assert (GNUNET_OK == | ||
1354 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", | ||
1355 | "IPV6ADDR", | ||
1356 | &ipv6addr)); | ||
1357 | inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr); | ||
1358 | GNUNET_free (ipv6addr); | ||
1359 | } | ||
1360 | memcpy (&pkt6->udp_hdr, pkt, ntohs (pkt->len)); | ||
1361 | |||
1362 | GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr); | ||
1363 | |||
1364 | GNUNET_assert (key != NULL); | ||
1365 | |||
1366 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
1367 | |||
1368 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, | ||
1369 | GNUNET_TIME_absolute_get ().abs_value); | ||
1370 | |||
1371 | GNUNET_free (key); | ||
1372 | |||
1373 | GNUNET_assert (me != NULL); | ||
1374 | if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK) | ||
1375 | { | ||
1376 | GNUNET_assert (me->desc. | ||
1377 | service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)); | ||
1378 | if (!port_in_ports (me->desc.ports, pkt6->udp_hdr.spt) && | ||
1379 | !testBit (me->additional_ports, ntohs (pkt6->udp_hdr.spt))) | ||
1380 | { | ||
1381 | add_additional_port (me, ntohs (pkt6->udp_hdr.spt)); | ||
1382 | } | ||
1383 | } | ||
1384 | |||
1385 | pkt6->udp_hdr.crc = 0; | ||
1386 | uint32_t sum = 0; | ||
1387 | |||
1388 | sum = | ||
1389 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16); | ||
1390 | sum = | ||
1391 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16); | ||
1392 | uint32_t tmp = (pkt6->udp_hdr.len & 0xffff); | ||
1393 | |||
1394 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
1395 | tmp = htons (((pkt6->ip6_hdr.nxthdr & 0x00ff))); | ||
1396 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
1397 | |||
1398 | sum = | ||
1399 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->udp_hdr, | ||
1400 | ntohs (pkt->len)); | ||
1401 | pkt6->udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1402 | |||
1403 | (void) GNUNET_HELPER_send (helper_handle, | ||
1404 | &pkt6->shdr, | ||
1405 | GNUNET_YES, | ||
1406 | NULL, NULL); | ||
1407 | } | ||
1408 | else | ||
1409 | { | ||
1410 | size_t size = | ||
1411 | sizeof (struct ip_udp) + ntohs (pkt->len) - 1 - sizeof (struct udp_pkt); | ||
1412 | |||
1413 | struct ip_udp *pkt4 = alloca (size); | ||
1414 | |||
1415 | GNUNET_assert (pkt4 != NULL); | ||
1416 | |||
1417 | GNUNET_assert (ntohs (message->type) == | ||
1418 | GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK); | ||
1419 | uint32_t sadr; | ||
1420 | |||
1421 | new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen); | ||
1422 | pkt4->ip_hdr.sadr.s_addr = sadr; | ||
1423 | |||
1424 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1425 | "Relaying calc:%d gnu:%d udp:%d bytes!\n", size, | ||
1426 | ntohs (message->size), ntohs (pkt->len)); | ||
1427 | |||
1428 | pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1429 | pkt4->shdr.size = htons (size); | ||
1430 | |||
1431 | pkt4->tun.flags = 0; | ||
1432 | pkt4->tun.type = htons (0x0800); | ||
1433 | |||
1434 | pkt4->ip_hdr.version = 4; | ||
1435 | pkt4->ip_hdr.hdr_lngth = 5; | ||
1436 | pkt4->ip_hdr.diff_serv = 0; | ||
1437 | pkt4->ip_hdr.tot_lngth = htons (20 + ntohs (pkt->len)); | ||
1438 | pkt4->ip_hdr.ident = 0; | ||
1439 | pkt4->ip_hdr.flags = 0; | ||
1440 | pkt4->ip_hdr.frag_off = 0; | ||
1441 | pkt4->ip_hdr.ttl = 255; | ||
1442 | pkt4->ip_hdr.proto = IPPROTO_UDP; | ||
1443 | pkt4->ip_hdr.chks = 0; /* Will be calculated later */ | ||
1444 | |||
1445 | { | ||
1446 | char *ipv4addr; | ||
1447 | uint32_t dadr; | ||
1448 | |||
1449 | GNUNET_assert (GNUNET_OK == | ||
1450 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", | ||
1451 | "IPV4ADDR", | ||
1452 | &ipv4addr)); | ||
1453 | inet_pton (AF_INET, ipv4addr, &dadr); | ||
1454 | GNUNET_free (ipv4addr); | ||
1455 | pkt4->ip_hdr.dadr.s_addr = dadr; | ||
1456 | } | ||
1457 | memcpy (&pkt4->udp_hdr, pkt, ntohs (pkt->len)); | ||
1458 | |||
1459 | GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr); | ||
1460 | |||
1461 | GNUNET_assert (key != NULL); | ||
1462 | |||
1463 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
1464 | |||
1465 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, | ||
1466 | GNUNET_TIME_absolute_get ().abs_value); | ||
1467 | |||
1468 | GNUNET_free (key); | ||
1469 | |||
1470 | GNUNET_assert (me != NULL); | ||
1471 | |||
1472 | pkt4->udp_hdr.crc = 0; /* Optional for IPv4 */ | ||
1473 | |||
1474 | pkt4->ip_hdr.chks = | ||
1475 | GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4); | ||
1476 | |||
1477 | (void) GNUNET_HELPER_send (helper_handle, | ||
1478 | &pkt4->shdr, | ||
1479 | GNUNET_YES, | ||
1480 | NULL, NULL); | ||
1481 | } | ||
1482 | |||
1483 | return GNUNET_OK; | ||
1484 | } | ||
1485 | |||
1486 | static int | ||
1487 | receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1488 | void **tunnel_ctx, | ||
1489 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
1490 | const struct GNUNET_MessageHeader *message, | ||
1491 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1492 | { | ||
1493 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
1494 | struct remote_addr *s = (struct remote_addr *) desc; | ||
1495 | struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1); | ||
1496 | const struct GNUNET_PeerIdentity *other = sender; | ||
1497 | struct tunnel_state *ts = *tunnel_ctx; | ||
1498 | |||
1499 | size_t pktlen = | ||
1500 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - | ||
1501 | sizeof (GNUNET_HashCode); | ||
1502 | |||
1503 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1504 | "Received TCP-Packet back, addrlen = %d\n", s->addrlen); | ||
1505 | |||
1506 | if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK || | ||
1507 | ts->addrlen == 16) | ||
1508 | { | ||
1509 | size_t size = pktlen + sizeof (struct ip6_tcp) - 1; | ||
1510 | |||
1511 | struct ip6_tcp *pkt6 = alloca (size); | ||
1512 | |||
1513 | memset (pkt6, 0, size); | ||
1514 | |||
1515 | GNUNET_assert (pkt6 != NULL); | ||
1516 | |||
1517 | if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK) | ||
1518 | new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc); | ||
1519 | else | ||
1520 | new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen); | ||
1521 | |||
1522 | pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1523 | pkt6->shdr.size = htons (size); | ||
1524 | |||
1525 | pkt6->tun.flags = 0; | ||
1526 | pkt6->tun.type = htons (0x86dd); | ||
1527 | |||
1528 | pkt6->ip6_hdr.version = 6; | ||
1529 | pkt6->ip6_hdr.tclass_h = 0; | ||
1530 | pkt6->ip6_hdr.tclass_l = 0; | ||
1531 | pkt6->ip6_hdr.flowlbl = 0; | ||
1532 | pkt6->ip6_hdr.paylgth = htons (pktlen); | ||
1533 | pkt6->ip6_hdr.nxthdr = IPPROTO_TCP; | ||
1534 | pkt6->ip6_hdr.hoplmt = 0xff; | ||
1535 | |||
1536 | { | ||
1537 | char *ipv6addr; | ||
1538 | |||
1539 | GNUNET_assert (GNUNET_OK == | ||
1540 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", | ||
1541 | "IPV6ADDR", | ||
1542 | &ipv6addr)); | ||
1543 | inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr); | ||
1544 | GNUNET_free (ipv6addr); | ||
1545 | } | ||
1546 | memcpy (&pkt6->tcp_hdr, pkt, pktlen); | ||
1547 | |||
1548 | GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr); | ||
1549 | |||
1550 | GNUNET_assert (key != NULL); | ||
1551 | |||
1552 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
1553 | |||
1554 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, | ||
1555 | GNUNET_TIME_absolute_get ().abs_value); | ||
1556 | |||
1557 | GNUNET_free (key); | ||
1558 | |||
1559 | GNUNET_assert (me != NULL); | ||
1560 | if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK) | ||
1561 | GNUNET_assert (me->desc. | ||
1562 | service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP)); | ||
1563 | |||
1564 | pkt6->tcp_hdr.crc = 0; | ||
1565 | uint32_t sum = 0; | ||
1566 | uint32_t tmp; | ||
1567 | |||
1568 | sum = | ||
1569 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16); | ||
1570 | sum = | ||
1571 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16); | ||
1572 | tmp = htonl (pktlen); | ||
1573 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
1574 | tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff))); | ||
1575 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
1576 | |||
1577 | sum = | ||
1578 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->tcp_hdr, | ||
1579 | ntohs (pkt6->ip6_hdr.paylgth)); | ||
1580 | pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1581 | |||
1582 | (void) GNUNET_HELPER_send (helper_handle, | ||
1583 | &pkt6->shdr, | ||
1584 | GNUNET_YES, | ||
1585 | NULL, NULL); | ||
1586 | } | ||
1587 | else | ||
1588 | { | ||
1589 | size_t size = pktlen + sizeof (struct ip_tcp) - 1; | ||
1590 | |||
1591 | struct ip_tcp *pkt4 = alloca (size); | ||
1592 | |||
1593 | GNUNET_assert (pkt4 != NULL); | ||
1594 | memset (pkt4, 0, size); | ||
1595 | |||
1596 | GNUNET_assert (ntohs (message->type) == | ||
1597 | GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK); | ||
1598 | uint32_t sadr; | ||
1599 | |||
1600 | new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen); | ||
1601 | pkt4->ip_hdr.sadr.s_addr = sadr; | ||
1602 | |||
1603 | pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1604 | pkt4->shdr.size = htons (size); | ||
1605 | |||
1606 | pkt4->tun.flags = 0; | ||
1607 | pkt4->tun.type = htons (0x0800); | ||
1608 | |||
1609 | pkt4->ip_hdr.version = 4; | ||
1610 | pkt4->ip_hdr.hdr_lngth = 5; | ||
1611 | pkt4->ip_hdr.diff_serv = 0; | ||
1612 | pkt4->ip_hdr.tot_lngth = htons (20 + pktlen); | ||
1613 | pkt4->ip_hdr.ident = 0; | ||
1614 | pkt4->ip_hdr.flags = 0; | ||
1615 | pkt4->ip_hdr.frag_off = 0; | ||
1616 | pkt4->ip_hdr.ttl = 255; | ||
1617 | pkt4->ip_hdr.proto = IPPROTO_TCP; | ||
1618 | pkt4->ip_hdr.chks = 0; /* Will be calculated later */ | ||
1619 | |||
1620 | { | ||
1621 | char *ipv4addr; | ||
1622 | uint32_t dadr; | ||
1623 | |||
1624 | GNUNET_assert (GNUNET_OK == | ||
1625 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", | ||
1626 | "IPV4ADDR", | ||
1627 | &ipv4addr)); | ||
1628 | inet_pton (AF_INET, ipv4addr, &dadr); | ||
1629 | GNUNET_free (ipv4addr); | ||
1630 | pkt4->ip_hdr.dadr.s_addr = dadr; | ||
1631 | } | ||
1632 | |||
1633 | memcpy (&pkt4->tcp_hdr, pkt, pktlen); | ||
1634 | |||
1635 | GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr); | ||
1636 | |||
1637 | GNUNET_assert (key != NULL); | ||
1638 | |||
1639 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
1640 | |||
1641 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, | ||
1642 | GNUNET_TIME_absolute_get ().abs_value); | ||
1643 | |||
1644 | GNUNET_free (key); | ||
1645 | |||
1646 | GNUNET_assert (me != NULL); | ||
1647 | pkt4->tcp_hdr.crc = 0; | ||
1648 | uint32_t sum = 0; | ||
1649 | uint32_t tmp; | ||
1650 | |||
1651 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.sadr, 4); | ||
1652 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.dadr, 4); | ||
1653 | |||
1654 | tmp = (0x06 << 16) | (0xffff & pktlen); // 0x06 for TCP? | ||
1655 | |||
1656 | tmp = htonl (tmp); | ||
1657 | |||
1658 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
1659 | |||
1660 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt4->tcp_hdr, pktlen); | ||
1661 | pkt4->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1662 | |||
1663 | pkt4->ip_hdr.chks = | ||
1664 | GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4); | ||
1665 | |||
1666 | (void) GNUNET_HELPER_send (helper_handle, | ||
1667 | &pkt4->shdr, | ||
1668 | GNUNET_YES, | ||
1669 | NULL, NULL); | ||
1670 | |||
1671 | } | ||
1672 | |||
1673 | return GNUNET_OK; | ||
1674 | } | ||
1675 | |||
1676 | static void * | ||
1677 | new_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel, | ||
1678 | const struct GNUNET_PeerIdentity *initiator, | ||
1679 | const struct GNUNET_ATS_Information *atsi) | ||
1680 | { | ||
1681 | /* Why should anyone open an inbound tunnel to vpn? */ | ||
1682 | GNUNET_break (0); | ||
1683 | return NULL; | ||
1684 | } | ||
1685 | |||
1686 | static void | ||
1687 | cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel_ctx) | ||
1688 | { | ||
1689 | /* Why should anyone open an inbound tunnel to vpn? */ | ||
1690 | GNUNET_break (0); | ||
1691 | } | ||
1692 | |||
1693 | /** | ||
1694 | * Main function that will be run by the scheduler. | ||
1695 | * | ||
1696 | * @param cls closure | ||
1697 | * @param args remaining command-line arguments | ||
1698 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
1699 | * @param cfg_ configuration | ||
1700 | */ | ||
1701 | static void | ||
1702 | run (void *cls, char *const *args GNUNET_UNUSED, | ||
1703 | const char *cfgfile GNUNET_UNUSED, | ||
1704 | const struct GNUNET_CONFIGURATION_Handle *cfg_) | ||
1705 | { | ||
1706 | static const struct GNUNET_MESH_MessageHandler handlers[] = { | ||
1707 | {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK, 0}, | ||
1708 | {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK, 0}, | ||
1709 | {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK, 0}, | ||
1710 | {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0}, | ||
1711 | {NULL, 0, 0} | ||
1712 | }; | ||
1713 | static const GNUNET_MESH_ApplicationType types[] = { | ||
1714 | GNUNET_APPLICATION_TYPE_END | ||
1715 | }; | ||
1716 | char *ifname; | ||
1717 | char *ipv6addr; | ||
1718 | char *ipv6prefix; | ||
1719 | char *ipv4addr; | ||
1720 | char *ipv4mask; | ||
1721 | |||
1722 | mesh_handle = | ||
1723 | GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers, | ||
1724 | types); | ||
1725 | cfg = cfg_; | ||
1726 | hashmap = GNUNET_CONTAINER_multihashmap_create (65536); | ||
1727 | heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1728 | GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPINGg", | ||
1729 | &max_mappings); | ||
1730 | udp_connections = GNUNET_CONTAINER_multihashmap_create (65536); | ||
1731 | dns_handle = GNUNET_DNS_connect (cfg, | ||
1732 | &process_answer, | ||
1733 | NULL); | ||
1734 | if (GNUNET_SYSERR == | ||
1735 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname)) | ||
1736 | { | ||
1737 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1738 | "No entry 'IFNAME' in configuration!\n"); | ||
1739 | exit (1); | ||
1740 | } | ||
1741 | |||
1742 | if (GNUNET_SYSERR == | ||
1743 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", &ipv6addr)) | ||
1744 | { | ||
1745 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1746 | "No entry 'IPV6ADDR' in configuration!\n"); | ||
1747 | exit (1); | ||
1748 | } | ||
1749 | |||
1750 | if (GNUNET_SYSERR == | ||
1751 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX", | ||
1752 | &ipv6prefix)) | ||
1753 | { | ||
1754 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1755 | "No entry 'IPV6PREFIX' in configuration!\n"); | ||
1756 | exit (1); | ||
1757 | } | ||
1758 | |||
1759 | if (GNUNET_SYSERR == | ||
1760 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", &ipv4addr)) | ||
1761 | { | ||
1762 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1763 | "No entry 'IPV4ADDR' in configuration!\n"); | ||
1764 | exit (1); | ||
1765 | } | ||
1766 | |||
1767 | if (GNUNET_SYSERR == | ||
1768 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", &ipv4mask)) | ||
1769 | { | ||
1770 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1771 | "No entry 'IPV4MASK' in configuration!\n"); | ||
1772 | exit (1); | ||
1773 | } | ||
1774 | |||
1775 | vpn_argv[0] = GNUNET_strdup ("vpn-gnunet"); | ||
1776 | vpn_argv[1] = ifname; | ||
1777 | vpn_argv[2] = ipv6addr; | ||
1778 | vpn_argv[3] = ipv6prefix; | ||
1779 | vpn_argv[4] = ipv4addr; | ||
1780 | vpn_argv[5] = ipv4mask; | ||
1781 | vpn_argv[6] = NULL; | ||
1782 | |||
1783 | helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv, | ||
1784 | &message_token, NULL); | ||
1785 | GNUNET_DNS_restart_hijack (dns_handle); | ||
1786 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); | ||
1787 | } | ||
1788 | |||
1789 | /** | ||
1790 | * The main function to obtain template from gnunetd. | ||
1791 | * | ||
1792 | * @param argc number of arguments from the command line | ||
1793 | * @param argv command line arguments | ||
1794 | * @return 0 ok, 1 on error | ||
1795 | */ | ||
1796 | int | ||
1797 | main (int argc, char *const *argv) | ||
1798 | { | ||
1799 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
1800 | GNUNET_GETOPT_OPTION_END | ||
1801 | }; | ||
1802 | |||
1803 | return (GNUNET_OK == | ||
1804 | GNUNET_PROGRAM_run (argc, argv, "vpn", gettext_noop ("help text"), | ||
1805 | options, &run, NULL)) ? ret : 1; | ||
1806 | } | ||
1807 | |||
1808 | /* end of gnunet-daemon-vpn.c */ | ||
diff --git a/src/vpn/test-conf.conf b/src/vpn/test-conf.conf deleted file mode 100644 index b805c7c94..000000000 --- a/src/vpn/test-conf.conf +++ /dev/null | |||
@@ -1,276 +0,0 @@ | |||
1 | [PATHS] | ||
2 | SERVICEHOME = ~/.gnunet/ | ||
3 | # SERVICEHOME = /var/lib/gnunet/ | ||
4 | # DEFAULTCONFIG = /etc/gnunet.conf | ||
5 | # If 'DEFAULTCONFIG' is not defined, the current | ||
6 | # configuration file is assumed to be the default, | ||
7 | # which is what we want by default... | ||
8 | |||
9 | [gnunetd] | ||
10 | HOSTKEY = $SERVICEHOME/.hostkey | ||
11 | |||
12 | [TESTING] | ||
13 | WEAKRANDOM = NO | ||
14 | |||
15 | [client] | ||
16 | HOME = $SERVICEHOME | ||
17 | |||
18 | [transport-tcp] | ||
19 | PORT = 2086 | ||
20 | TIMEOUT = 300s | ||
21 | # MAXBUF = | ||
22 | # DISABLEV6 = | ||
23 | # BINDTO = | ||
24 | # ACCEPT_FROM = | ||
25 | # ACCEPT_FROM6 = | ||
26 | # REJECT_FROM = | ||
27 | # REJECT_FROM6 = | ||
28 | |||
29 | [dht] | ||
30 | AUTOSTART = YES | ||
31 | DEBUG = YES | ||
32 | PORT = 2095 | ||
33 | HOSTNAME = localhost | ||
34 | HOME = $SERVICEHOME | ||
35 | CONFIG = $DEFAULTCONFIG | ||
36 | BINARY = gnunet-service-dht | ||
37 | ACCEPT_FROM = 127.0.0.1; | ||
38 | ACCEPT_FROM6 = ::1; | ||
39 | UNIXPATH = /tmp/gnunet-service-dht.sock | ||
40 | # DISABLE_SOCKET_FORWARDING = NO | ||
41 | # DEBUG = YES | ||
42 | # USERNAME = | ||
43 | # MAXBUF = | ||
44 | # TIMEOUT = | ||
45 | # DISABLEV6 = | ||
46 | # BINDTO = | ||
47 | # REJECT_FROM = | ||
48 | # REJECT_FROM6 = | ||
49 | # PREFIX = | ||
50 | |||
51 | [dhtcache] | ||
52 | QUOTA = 1 MB | ||
53 | DATABASE = sqlite | ||
54 | |||
55 | [arm] | ||
56 | PORT = 2087 | ||
57 | HOSTNAME = localhost | ||
58 | HOME = $SERVICEHOME | ||
59 | CONFIG = $DEFAULTCONFIG | ||
60 | BINARY = gnunet-service-arm | ||
61 | ACCEPT_FROM = 127.0.0.1; | ||
62 | ACCEPT_FROM6 = ::1; | ||
63 | DEFAULTSERVICES = core transport dht vpn dns | ||
64 | UNIXPATH = /tmp/gnunet-service-arm.sock | ||
65 | # GLOBAL_POSTFIX = -l $SERVICEHOME/{}-logs | ||
66 | # GLOBAL_PREFIX = | ||
67 | # USERNAME = | ||
68 | # MAXBUF = | ||
69 | # TIMEOUT = | ||
70 | # DISABLEV6 = | ||
71 | # BINDTO = | ||
72 | # REJECT_FROM = | ||
73 | # REJECT_FROM6 = | ||
74 | # PREFIX = | ||
75 | |||
76 | [statistics] | ||
77 | AUTOSTART = YES | ||
78 | PORT = 2088 | ||
79 | HOSTNAME = localhost | ||
80 | HOME = $SERVICEHOME | ||
81 | CONFIG = $DEFAULTCONFIG | ||
82 | BINARY = gnunet-service-statistics | ||
83 | ACCEPT_FROM = 127.0.0.1; | ||
84 | ACCEPT_FROM6 = ::1; | ||
85 | UNIXPATH = /tmp/gnunet-service-statistics.sock | ||
86 | # USERNAME = | ||
87 | # MAXBUF = | ||
88 | # TIMEOUT = | ||
89 | # DISABLEV6 = | ||
90 | # BINDTO = | ||
91 | # REJECT_FROM = | ||
92 | # REJECT_FROM6 = | ||
93 | # PREFIX = | ||
94 | |||
95 | [resolver] | ||
96 | AUTOSTART = YES | ||
97 | PORT = 2089 | ||
98 | HOSTNAME = localhost | ||
99 | HOME = $SERVICEHOME | ||
100 | CONFIG = $DEFAULTCONFIG | ||
101 | BINARY = gnunet-service-resolver | ||
102 | ACCEPT_FROM = 127.0.0.1; | ||
103 | ACCEPT_FROM6 = ::1; | ||
104 | UNIXPATH = /tmp/gnunet-service-resolver.sock | ||
105 | # USERNAME = | ||
106 | # MAXBUF = | ||
107 | # TIMEOUT = | ||
108 | # DISABLEV6 = | ||
109 | # BINDTO = | ||
110 | # REJECT_FROM = | ||
111 | # REJECT_FROM6 = | ||
112 | # PREFIX = | ||
113 | |||
114 | [peerinfo] | ||
115 | AUTOSTART = YES | ||
116 | PORT = 2090 | ||
117 | HOSTNAME = localhost | ||
118 | HOME = $SERVICEHOME | ||
119 | CONFIG = $DEFAULTCONFIG | ||
120 | BINARY = gnunet-service-peerinfo | ||
121 | ACCEPT_FROM = 127.0.0.1; | ||
122 | ACCEPT_FROM6 = ::1; | ||
123 | UNIXPATH = /tmp/gnunet-service-peerinfo.sock | ||
124 | # USERNAME = | ||
125 | # MAXBUF = | ||
126 | # TIMEOUT = | ||
127 | # DISABLEV6 = | ||
128 | # BINDTO = | ||
129 | # REJECT_FROM = | ||
130 | # REJECT_FROM6 = | ||
131 | # PREFIX = | ||
132 | HOSTS = $SERVICEHOME/data/hosts/ | ||
133 | TRUST = $SERVICEHOME/data/credit/ | ||
134 | |||
135 | |||
136 | [transport] | ||
137 | AUTOSTART = YES | ||
138 | PORT = 2091 | ||
139 | HOSTNAME = localhost | ||
140 | HOME = $SERVICEHOME | ||
141 | CONFIG = $DEFAULTCONFIG | ||
142 | BINARY = gnunet-service-transport | ||
143 | NEIGHBOUR_LIMIT = 50 | ||
144 | ACCEPT_FROM = 127.0.0.1; | ||
145 | ACCEPT_FROM6 = ::1; | ||
146 | PLUGINS = tcp | ||
147 | UNIXPATH = /tmp/gnunet-service-transport.sock | ||
148 | # USERNAME = | ||
149 | # MAXBUF = | ||
150 | # TIMEOUT = | ||
151 | # DISABLEV6 = | ||
152 | # BINDTO = | ||
153 | # REJECT_FROM = | ||
154 | # REJECT_FROM6 = | ||
155 | # PREFIX = | ||
156 | |||
157 | [ats] | ||
158 | WAN_QUOTA_IN = 64 kiB | ||
159 | WAN_QUOTA_OUT = 64 kiB | ||
160 | |||
161 | [core] | ||
162 | AUTOSTART = YES | ||
163 | PORT = 2092 | ||
164 | HOSTNAME = localhost | ||
165 | HOME = $SERVICEHOME | ||
166 | CONFIG = $DEFAULTCONFIG | ||
167 | BINARY = gnunet-service-core | ||
168 | ACCEPT_FROM = 127.0.0.1; | ||
169 | ACCEPT_FROM6 = ::1; | ||
170 | UNIXPATH = /tmp/gnunet-service-core.sock | ||
171 | # DEBUG = YES | ||
172 | # USERNAME = | ||
173 | # MAXBUF = | ||
174 | # TIMEOUT = | ||
175 | # DISABLEV6 = | ||
176 | # BINDTO = | ||
177 | # REJECT_FROM = | ||
178 | # REJECT_FROM6 = | ||
179 | # PREFIX = | ||
180 | |||
181 | |||
182 | [topology] | ||
183 | MINIMUM-FRIENDS = 0 | ||
184 | FRIENDS-ONLY = NO | ||
185 | AUTOCONNECT = YES | ||
186 | TARGET-CONNECTION-COUNT = 16 | ||
187 | FRIENDS = $SERVICEHOME/friends | ||
188 | CONFIG = $DEFAULTCONFIG | ||
189 | BINARY = gnunet-daemon-topology | ||
190 | |||
191 | [hostlist] | ||
192 | # port for hostlist http server | ||
193 | AUTOSTART = NO | ||
194 | HTTPPORT = 8080 | ||
195 | DEBUG = YES | ||
196 | HOME = $SERVICEHOME | ||
197 | HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data | ||
198 | CONFIG = $DEFAULTCONFIG | ||
199 | BINARY = gnunet-daemon-hostlist | ||
200 | # consider having "-e" as default as well once implemented | ||
201 | OPTIONS = -p -e -a | ||
202 | SERVERS = # http://v9.gnunet.org:58080/ | ||
203 | # proxy for downloading hostlists | ||
204 | HTTP-PROXY = | ||
205 | |||
206 | [vpn] | ||
207 | CONFIG = $DEFAULTCONFIG | ||
208 | BINARY = gnunet-daemon-vpn | ||
209 | DEBUG = YES | ||
210 | |||
211 | [datastore] | ||
212 | AUTOSTART = YES | ||
213 | UNIXPATH = /tmp/gnunet-service-datastore.sock | ||
214 | PORT = 2093 | ||
215 | HOSTNAME = localhost | ||
216 | HOME = $SERVICEHOME | ||
217 | CONFIG = $DEFAULTCONFIG | ||
218 | BINARY = gnunet-service-datastore | ||
219 | ACCEPT_FROM = 127.0.0.1; | ||
220 | ACCEPT_FROM6 = ::1; | ||
221 | QUOTA = 100 MB | ||
222 | BLOOMFILTER = $SERVICEHOME/fs/bloomfilter | ||
223 | DATABASE = sqlite | ||
224 | |||
225 | [datastore-sqlite] | ||
226 | FILENAME = $SERVICEHOME/datastore/sqlite.db | ||
227 | |||
228 | [fs] | ||
229 | AUTOSTART = YES | ||
230 | INDEXDB = $SERVICEHOME/idxinfo.lst | ||
231 | IDENTITY_DIR = $SERVICEHOME/identities/ | ||
232 | STATE_DIR = $SERVICEHOME/persistence/ | ||
233 | PORT = 2094 | ||
234 | HOSTNAME = localhost | ||
235 | HOME = $SERVICEHOME | ||
236 | CONFIG = $DEFAULTCONFIG | ||
237 | BINARY = gnunet-service-fs | ||
238 | ACCEPT_FROM = 127.0.0.1; | ||
239 | ACCEPT_FROM6 = ::1; | ||
240 | ACTIVEMIGRATION = YES | ||
241 | UNIXPATH = /tmp/gnunet-service-fs.sock | ||
242 | # DEBUG = YES | ||
243 | |||
244 | [dns] | ||
245 | AUTOSTART = YES | ||
246 | PORT = 2098 | ||
247 | HOSTNAME = localhost | ||
248 | HOME = $SERVICEHOME | ||
249 | CONFIG = $DEFAULTCONFIG | ||
250 | BINARY = gnunet-service-dns | ||
251 | ACCEPT_FROM = 127.0.0.1; | ||
252 | ACCEPT_FROM6 = ::1; | ||
253 | # quotas are in bytes per second now! | ||
254 | TOTAL_QUOTA_IN = 65536 | ||
255 | TOTAL_QUOTA_OUT = 65536 | ||
256 | UNIXPATH = /tmp/gnunet-service-dns.sock | ||
257 | DEBUG = YES | ||
258 | # USERNAME = | ||
259 | # MAXBUF = | ||
260 | # TIMEOUT = | ||
261 | # DISABLEV6 = | ||
262 | # BINDTO = | ||
263 | # REJECT_FROM = | ||
264 | # REJECT_FROM6 = | ||
265 | # PREFIX = | ||
266 | |||
267 | [block] | ||
268 | PLUGINS = fs dns | ||
269 | |||
270 | |||
271 | |||
272 | |||
273 | [nse] | ||
274 | AUTOSTART = NO | ||
275 | |||
276 | |||