diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-07 01:44:52 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-07 01:44:52 +0000 |
commit | 36006b066f1076707712602359ac84da53d1dffb (patch) | |
tree | a7acdb5c1d88c2325c4463362b8d09341c8f0df7 /src/vpn/gnunet-service-vpn.c | |
parent | 0a671e8ffbff1cb993a1df595b7d0d87a295b4d3 (diff) | |
download | gnunet-36006b066f1076707712602359ac84da53d1dffb.tar.gz gnunet-36006b066f1076707712602359ac84da53d1dffb.zip |
-some more hacking on data structures, documenting open issues
Diffstat (limited to 'src/vpn/gnunet-service-vpn.c')
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 595 |
1 files changed, 288 insertions, 307 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 4ce1fab78..8f0236846 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -27,6 +27,13 @@ | |||
27 | * @author Christian Grothoff | 27 | * @author Christian Grothoff |
28 | * | 28 | * |
29 | * TODO: | 29 | * TODO: |
30 | * - create tunnels | ||
31 | * - implement service message handlers | ||
32 | * - build mesh messages | ||
33 | * - parse mesh replies | ||
34 | * - build IP messages from mesh replies | ||
35 | * - fully implement shutdown code | ||
36 | * - [implement VPN library] | ||
30 | * - add back ICMP support (especially needed for IPv6)o | 37 | * - add back ICMP support (especially needed for IPv6)o |
31 | */ | 38 | */ |
32 | #include "platform.h" | 39 | #include "platform.h" |
@@ -39,23 +46,20 @@ | |||
39 | #include "tcpip_tun.h" | 46 | #include "tcpip_tun.h" |
40 | 47 | ||
41 | 48 | ||
42 | |||
43 | |||
44 | /** | 49 | /** |
45 | * Information we track for each IP address to determine which tunnel | 50 | * Information we track for each IP address to determine which tunnel |
46 | * to send the traffic over to the destination. | 51 | * to send the traffic over to the destination. |
47 | */ | 52 | */ |
48 | struct map_entry | 53 | struct destination_entry |
49 | { | 54 | { |
50 | /** | 55 | /** |
51 | * Information about the tunnel to use; the associated tunnel | 56 | * Information about the tunnel to use, NULL if no tunnel |
52 | * state gives information about the respective local IP that | 57 | * is available right now. |
53 | * this tunnel is used with. | ||
54 | */ | 58 | */ |
55 | struct tunnel_state *ts; | 59 | struct GNUNET_MESH_Tunnel *tunnel; |
56 | 60 | ||
57 | /** | 61 | /** |
58 | * Entry for this entry in the heap. | 62 | * Entry for this entry in the destination_heap. |
59 | */ | 63 | */ |
60 | struct GNUNET_CONTAINER_HeapNode *heap_node; | 64 | struct GNUNET_CONTAINER_HeapNode *heap_node; |
61 | 65 | ||
@@ -75,7 +79,6 @@ struct map_entry | |||
75 | */ | 79 | */ |
76 | union | 80 | union |
77 | { | 81 | { |
78 | |||
79 | /** | 82 | /** |
80 | * The description of the service (only used for service tunnels). | 83 | * The description of the service (only used for service tunnels). |
81 | */ | 84 | */ |
@@ -97,8 +100,7 @@ struct map_entry | |||
97 | struct in6_addr v6; | 100 | struct in6_addr v6; |
98 | } ip; | 101 | } ip; |
99 | 102 | ||
100 | } destination_details; | 103 | } details; |
101 | |||
102 | 104 | ||
103 | }; | 105 | }; |
104 | 106 | ||
@@ -141,6 +143,11 @@ struct tunnel_state | |||
141 | struct GNUNET_MESH_TransmitHandle *th; | 143 | struct GNUNET_MESH_TransmitHandle *th; |
142 | 144 | ||
143 | /** | 145 | /** |
146 | * Entry for this entry in the tunnel_heap. | ||
147 | */ | ||
148 | struct GNUNET_CONTAINER_HeapNode *heap_node; | ||
149 | |||
150 | /** | ||
144 | * Head of list of messages scheduled for transmission. | 151 | * Head of list of messages scheduled for transmission. |
145 | */ | 152 | */ |
146 | struct tunnel_notify_queue *head; | 153 | struct tunnel_notify_queue *head; |
@@ -151,15 +158,18 @@ struct tunnel_state | |||
151 | struct tunnel_notify_queue *tail; | 158 | struct tunnel_notify_queue *tail; |
152 | 159 | ||
153 | /** | 160 | /** |
154 | * Tunnel for which this is the state. | 161 | * Destination to which this tunnel leads. Note that |
162 | * this struct is NOT in the destination_map (but a | ||
163 | * local copy) and that the 'heap_node' should always | ||
164 | * be NULL. | ||
155 | */ | 165 | */ |
156 | struct GNUNET_MESH_Tunnel *tunnel; | 166 | struct destination_entry destination; |
157 | 167 | ||
158 | /** | 168 | /** |
159 | * Address family used on our side of this tunnel | 169 | * GNUNET_NO if this is a tunnel to an Internet-exit, |
160 | * (AF_INET or AF_INET6). | 170 | * GNUNET_YES if this tunnel is to a service. |
161 | */ | 171 | */ |
162 | int af; | 172 | int is_service; |
163 | 173 | ||
164 | /** | 174 | /** |
165 | * IP address of the source on our end. | 175 | * IP address of the source on our end. |
@@ -179,10 +189,32 @@ struct tunnel_state | |||
179 | } source_ip; | 189 | } source_ip; |
180 | 190 | ||
181 | /** | 191 | /** |
182 | * Source port used by the sender. | 192 | * Destination IP address used by the source on our end. |
193 | */ | ||
194 | union | ||
195 | { | ||
196 | /** | ||
197 | * Address if af is AF_INET. | ||
198 | */ | ||
199 | struct in_addr v4; | ||
200 | |||
201 | /** | ||
202 | * Address if af is AF_INET6. | ||
203 | */ | ||
204 | struct in6_addr v6; | ||
205 | |||
206 | } destination_ip; | ||
207 | |||
208 | /** | ||
209 | * Source port used by the sender on our end. | ||
183 | */ | 210 | */ |
184 | uint16_t source_port; | 211 | uint16_t source_port; |
185 | 212 | ||
213 | /** | ||
214 | * Destination port used by the sender on our end. | ||
215 | */ | ||
216 | uint16_t destination_port; | ||
217 | |||
186 | }; | 218 | }; |
187 | 219 | ||
188 | 220 | ||
@@ -197,15 +229,26 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
197 | static struct GNUNET_MESH_Handle *mesh_handle; | 229 | static struct GNUNET_MESH_Handle *mesh_handle; |
198 | 230 | ||
199 | /** | 231 | /** |
200 | * Map from IP address to connection information (mostly with | 232 | * Map from IP address to destination information (possibly with a |
201 | * the respective MESH tunnel handle). | 233 | * MESH tunnel handle for fast setup). |
202 | */ | 234 | */ |
203 | static struct GNUNET_CONTAINER_MultiHashMap *hashmap; | 235 | static struct GNUNET_CONTAINER_MultiHashMap *destination_map; |
204 | 236 | ||
205 | /** | 237 | /** |
206 | * Min-Heap sorted by activity time to expire old mappings. | 238 | * Min-Heap sorted by activity time to expire old mappings. |
207 | */ | 239 | */ |
208 | static struct GNUNET_CONTAINER_Heap *heap; | 240 | static struct GNUNET_CONTAINER_Heap *destination_heap; |
241 | |||
242 | /** | ||
243 | * Map from source and destination address (IP+port) to connection | ||
244 | * information (mostly with the respective MESH tunnel handle). | ||
245 | */ | ||
246 | static struct GNUNET_CONTAINER_MultiHashMap *tunnel_map; | ||
247 | |||
248 | /** | ||
249 | * Min-Heap sorted by activity time to expire old mappings. | ||
250 | */ | ||
251 | static struct GNUNET_CONTAINER_Heap *tunnel_heap; | ||
209 | 252 | ||
210 | /** | 253 | /** |
211 | * The handle to the VPN helper process "gnunet-helper-vpn". | 254 | * The handle to the VPN helper process "gnunet-helper-vpn". |
@@ -221,21 +264,27 @@ static char *vpn_argv[7]; | |||
221 | * If there are more than this number of address-mappings, old ones | 264 | * If there are more than this number of address-mappings, old ones |
222 | * will be removed | 265 | * will be removed |
223 | */ | 266 | */ |
224 | static unsigned long long max_mappings; | 267 | static unsigned long long max_destination_mappings; |
268 | |||
269 | /** | ||
270 | * If there are more than this number of open tunnels, old ones | ||
271 | * will be removed | ||
272 | */ | ||
273 | static unsigned long long max_tunnel_mappings; | ||
225 | 274 | ||
226 | 275 | ||
227 | /** | 276 | /** |
228 | * Compute the key under which we would store an entry in the | 277 | * Compute the key under which we would store an entry in the |
229 | * map for the given IP address. | 278 | * destination_map for the given IP address. |
230 | * | 279 | * |
231 | * @param af address family (AF_INET or AF_INET6) | 280 | * @param af address family (AF_INET or AF_INET6) |
232 | * @param address IP address, struct in_addr or struct in6_addr | 281 | * @param address IP address, struct in_addr or struct in6_addr |
233 | * @param key where to store the key | 282 | * @param key where to store the key |
234 | */ | 283 | */ |
235 | static void | 284 | static void |
236 | get_key_from_ip (int af, | 285 | get_destination_key_from_ip (int af, |
237 | const void *address, | 286 | const void *address, |
238 | GNUNET_HashCode *key) | 287 | GNUNET_HashCode *key) |
239 | { | 288 | { |
240 | switch (af) | 289 | switch (af) |
241 | { | 290 | { |
@@ -257,6 +306,60 @@ get_key_from_ip (int af, | |||
257 | 306 | ||
258 | 307 | ||
259 | /** | 308 | /** |
309 | * Compute the key under which we would store an entry in the | ||
310 | * tunnel_map for the given socket address pair. | ||
311 | * | ||
312 | * @param af address family (AF_INET or AF_INET6) | ||
313 | * @param protocol IPPROTO_TCP or IPPROTO_UDP | ||
314 | * @param source_ip sender's source IP, struct in_addr or struct in6_addr | ||
315 | * @param source_port sender's source port | ||
316 | * @param destination_ip sender's destination IP, struct in_addr or struct in6_addr | ||
317 | * @param destination_port sender's destination port | ||
318 | * @param key where to store the key | ||
319 | */ | ||
320 | static void | ||
321 | get_tunnel_key_from_ips (int af, | ||
322 | uint8_t protocol, | ||
323 | const void *source_ip, | ||
324 | uint16_t source_port, | ||
325 | const void *destination_ip, | ||
326 | uint16_t destination_port, | ||
327 | GNUNET_HashCode *key) | ||
328 | { | ||
329 | char *off; | ||
330 | |||
331 | memset (key, 0, sizeof (GNUNET_HashCode)); | ||
332 | /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash, | ||
333 | so we put the ports in there (and hope for few collisions) */ | ||
334 | off = (char*) key; | ||
335 | memcpy (off, &source_port, sizeof (uint16_t)); | ||
336 | off += sizeof (uint16_t); | ||
337 | memcpy (off, &destination_port, sizeof (uint16_t)); | ||
338 | off += sizeof (uint16_t); | ||
339 | switch (af) | ||
340 | { | ||
341 | case AF_INET: | ||
342 | memcpy (off, source_ip, sizeof (struct in_addr)); | ||
343 | off += sizeof (struct in_addr); | ||
344 | memcpy (off, destination_ip, sizeof (struct in_addr)); | ||
345 | off += sizeof (struct in_addr); | ||
346 | break; | ||
347 | case AF_INET6: | ||
348 | memcpy (off, source_ip, sizeof (struct in6_addr)); | ||
349 | off += sizeof (struct in6_addr); | ||
350 | memcpy (off, destination_ip, sizeof (struct in6_addr)); | ||
351 | off += sizeof (struct in6_addr); | ||
352 | break; | ||
353 | default: | ||
354 | GNUNET_assert (0); | ||
355 | break; | ||
356 | } | ||
357 | memcpy (off, &protocol, sizeof (uint8_t)); | ||
358 | off += sizeof (uint8_t); | ||
359 | } | ||
360 | |||
361 | |||
362 | /** | ||
260 | * Send a message from the message queue via mesh. | 363 | * Send a message from the message queue via mesh. |
261 | * | 364 | * |
262 | * @param cls the 'struct tunnel_state' with the message queue | 365 | * @param cls the 'struct tunnel_state' with the message queue |
@@ -284,7 +387,7 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf) | |||
284 | ret = tnq->len; | 387 | ret = tnq->len; |
285 | GNUNET_free (tnq); | 388 | GNUNET_free (tnq); |
286 | if (NULL != (tnq = ts->head)) | 389 | if (NULL != (tnq = ts->head)) |
287 | ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel, | 390 | ts->th = GNUNET_MESH_notify_transmit_ready (ts->destination.tunnel, |
288 | GNUNET_NO /* cork */, | 391 | GNUNET_NO /* cork */, |
289 | 42 /* priority */, | 392 | 42 /* priority */, |
290 | GNUNET_TIME_UNIT_FOREVER_REL, | 393 | GNUNET_TIME_UNIT_FOREVER_REL, |
@@ -303,15 +406,15 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf) | |||
303 | * @param tnq message to queue | 406 | * @param tnq message to queue |
304 | * @param ts tunnel to queue the message for | 407 | * @param ts tunnel to queue the message for |
305 | */ | 408 | */ |
306 | /* static */ void | 409 | static void |
307 | send_to_to_tunnel (struct tunnel_notify_queue *tnq, | 410 | send_to_tunnel (struct tunnel_notify_queue *tnq, |
308 | struct tunnel_state *ts) | 411 | struct tunnel_state *ts) |
309 | { | 412 | { |
310 | GNUNET_CONTAINER_DLL_insert_tail (ts->head, | 413 | GNUNET_CONTAINER_DLL_insert_tail (ts->head, |
311 | ts->tail, | 414 | ts->tail, |
312 | tnq); | 415 | tnq); |
313 | if (NULL == ts->th) | 416 | if (NULL == ts->th) |
314 | ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel, | 417 | ts->th = GNUNET_MESH_notify_transmit_ready (ts->destination.tunnel, |
315 | GNUNET_NO /* cork */, | 418 | GNUNET_NO /* cork */, |
316 | 42 /* priority */, | 419 | 42 /* priority */, |
317 | GNUNET_TIME_UNIT_FOREVER_REL, | 420 | GNUNET_TIME_UNIT_FOREVER_REL, |
@@ -323,71 +426,86 @@ send_to_to_tunnel (struct tunnel_notify_queue *tnq, | |||
323 | 426 | ||
324 | 427 | ||
325 | /** | 428 | /** |
326 | * Route a packet via mesh to the given destination. Note that | 429 | * Route a packet via mesh to the given destination. |
327 | * the source IP may NOT be the one that the tunnel state | ||
328 | * of the given destination is associated with. If the tunnel | ||
329 | * state is unassociated or identical, it should be used; if | ||
330 | * not, a fresh tunnel YUCK... | ||
331 | * | 430 | * |
332 | * @param destination description of the destination | 431 | * @param destination description of the destination |
333 | * @param af address family on this end (AF_INET or AF_INET6) | 432 | * @param af address family on this end (AF_INET or AF_INET6) |
334 | * @param protocol IPPROTO_TCP or IPPROTO_UDP | 433 | * @param protocol IPPROTO_TCP or IPPROTO_UDP |
335 | * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr) | 434 | * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr) |
435 | * @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr) | ||
336 | * @param payload payload of the packet after the IP header | 436 | * @param payload payload of the packet after the IP header |
337 | * @param payload_length number of bytes in payload | 437 | * @param payload_length number of bytes in payload |
338 | */ | 438 | */ |
339 | static void | 439 | static void |
340 | route_packet (struct map_entry *destination, | 440 | route_packet (struct destination_entry *destination, |
341 | int af, | 441 | int af, |
342 | uint8_t protocol, | 442 | uint8_t protocol, |
343 | const void *source_ip, | 443 | const void *source_ip, |
444 | const void *destination_ip, | ||
344 | const void *payload, | 445 | const void *payload, |
345 | size_t payload_length) | 446 | size_t payload_length) |
346 | { | 447 | { |
347 | #if 0 | 448 | GNUNET_HashCode key; |
348 | // FIXME... | 449 | struct tunnel_state *ts; |
450 | struct tunnel_notify_queue *tnq; | ||
451 | |||
452 | switch (protocol) | ||
453 | { | ||
454 | case IPPROTO_UDP: | ||
455 | { | ||
456 | const struct udp_packet *udp; | ||
349 | 457 | ||
350 | switch (pkt6->nxthdr) | 458 | if (payload_length < sizeof (struct udp_packet)) |
351 | { | 459 | { |
352 | case IPPROTO_UDP: | 460 | /* blame kernel? */ |
353 | pkt6_udp = (struct ip6_udp *) pkt6; | 461 | GNUNET_break (0); |
354 | /* Send dns-packets to the service-dns */ | 462 | return; |
355 | /* fall through */ | 463 | } |
356 | case IPPROTO_TCP: | 464 | udp = payload; |
357 | pkt6_tcp = (struct ip6_tcp *) pkt6; | 465 | get_tunnel_key_from_ips (af, |
358 | 466 | IPPROTO_UDP, | |
359 | if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) | 467 | source_ip, |
360 | { | 468 | ntohs (udp->spt), |
361 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | 469 | destination_ip, |
362 | 470 | ntohs (udp->dpt), | |
363 | GNUNET_assert (me != NULL); | 471 | &key); |
364 | GNUNET_free (key); | 472 | } |
365 | 473 | break; | |
366 | size_t size = | 474 | case IPPROTO_TCP: |
367 | sizeof (struct GNUNET_MESH_Tunnel *) + | 475 | { |
368 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + | 476 | const struct tcp_packet *tcp; |
369 | ntohs (pkt6->ip6_hdr.paylgth); | ||
370 | |||
371 | struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size); | ||
372 | struct GNUNET_MessageHeader *hdr = | ||
373 | (struct GNUNET_MessageHeader *) (cls + 1); | ||
374 | GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1); | ||
375 | |||
376 | hdr->size = | ||
377 | htons (sizeof (struct GNUNET_MessageHeader) + | ||
378 | sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth)); | ||
379 | |||
380 | GNUNET_MESH_ApplicationType app_type = 0; /* fix compiler uninitialized warning... */ | ||
381 | 477 | ||
382 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n", | 478 | if (payload_length < sizeof (struct tcp_packet)) |
383 | me->addrlen); | 479 | { |
384 | if (me->addrlen == 0) | 480 | /* blame kernel? */ |
385 | { | 481 | GNUNET_break (0); |
386 | /* This is a mapping to a gnunet-service */ | 482 | return; |
387 | *hc = me->desc; | 483 | } |
484 | tcp = payload; | ||
485 | get_tunnel_key_from_ips (af, | ||
486 | IPPROTO_TCP, | ||
487 | source_ip, | ||
488 | ntohs (tcp->spt), | ||
489 | destination_ip, | ||
490 | ntohs (tcp->dpt), | ||
491 | &key); | ||
492 | } | ||
493 | break; | ||
494 | default: | ||
495 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
496 | _("Protocol %u not supported, dropping\n"), | ||
497 | (unsigned int) protocol); | ||
498 | return; | ||
499 | } | ||
388 | 500 | ||
389 | if (me->tunnel == NULL && NULL != cls) | 501 | /* find tunnel */ |
390 | { | 502 | ts = GNUNET_CONTAINER_multihashmap_get (tunnel_map, |
503 | &key); | ||
504 | if (NULL == ts) | ||
505 | { | ||
506 | /* create new tunnel */ | ||
507 | // FIXME: create tunnel! | ||
508 | #if 0 | ||
391 | *cls = | 509 | *cls = |
392 | GNUNET_MESH_tunnel_create (mesh_handle, | 510 | GNUNET_MESH_tunnel_create (mesh_handle, |
393 | initialize_tunnel_state (16, NULL), | 511 | initialize_tunnel_state (16, NULL), |
@@ -397,88 +515,51 @@ route_packet (struct map_entry *destination, | |||
397 | (struct GNUNET_PeerIdentity *) | 515 | (struct GNUNET_PeerIdentity *) |
398 | &me->desc); | 516 | &me->desc); |
399 | me->tunnel = *cls; | 517 | me->tunnel = *cls; |
400 | } | ||
401 | else if (NULL != cls) | ||
402 | { | ||
403 | *cls = me->tunnel; | ||
404 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
405 | } | ||
406 | } | ||
407 | else | ||
408 | { | ||
409 | /* This is a mapping to a "real" address */ | ||
410 | struct remote_addr *s = (struct remote_addr *) hc; | ||
411 | |||
412 | s->addrlen = me->addrlen; | ||
413 | memcpy (s->addr, me->addr, me->addrlen); | ||
414 | s->proto = pkt6->ip6_hdr.nxthdr; | ||
415 | if (s->proto == IPPROTO_UDP) | ||
416 | { | ||
417 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP); | ||
418 | memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len)); | ||
419 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY; | ||
420 | } | ||
421 | else if (s->proto == IPPROTO_TCP) | ||
422 | { | ||
423 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP); | ||
424 | memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth)); | ||
425 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY; | ||
426 | } | ||
427 | else | ||
428 | { | ||
429 | GNUNET_assert (0); | ||
430 | } | ||
431 | if (me->tunnel == NULL && NULL != cls) | ||
432 | { | ||
433 | *cls = | ||
434 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
435 | initialize_tunnel_state (16, NULL), | ||
436 | &send_pkt_to_peer, NULL, cls); | ||
437 | |||
438 | GNUNET_MESH_peer_request_connect_by_type (*cls, app_type); | ||
439 | me->tunnel = *cls; | ||
440 | } | ||
441 | else if (NULL != cls) | ||
442 | { | ||
443 | *cls = me->tunnel; | ||
444 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
445 | } | ||
446 | } | ||
447 | } | ||
448 | else | ||
449 | { | ||
450 | char pbuf[INET6_ADDRSTRLEN]; | ||
451 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
452 | "Packet to %s, which has no mapping\n", | ||
453 | inet_ntop (AF_INET6, | ||
454 | &pkt6->ip6_hdr.dadr, | ||
455 | pbuf, | ||
456 | sizeof (pbuf))); | ||
457 | } | ||
458 | break; | ||
459 | |||
460 | case 0x3a: | ||
461 | /* ICMPv6 */ | ||
462 | pkt6_icmp = (struct ip6_icmp *) pkt6; | ||
463 | /* If this packet is an icmp-echo-request and a mapping exists, answer */ | ||
464 | if (pkt6_icmp->icmp_hdr.type == 0x80 && | ||
465 | (key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) | ||
466 | { | ||
467 | GNUNET_free (key); | ||
468 | pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size)); | ||
469 | memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size)); | ||
470 | GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp); | ||
471 | } | ||
472 | break; | ||
473 | } | ||
474 | #endif | 518 | #endif |
519 | } | ||
520 | |||
521 | /* send via tunnel */ | ||
522 | switch (protocol) | ||
523 | { | ||
524 | case IPPROTO_UDP: | ||
525 | if (destination->is_service) | ||
526 | { | ||
527 | tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42); | ||
528 | // FIXME: build message! | ||
529 | } | ||
530 | else | ||
531 | { | ||
532 | tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42); | ||
533 | // FIXME: build message! | ||
534 | } | ||
535 | break; | ||
536 | case IPPROTO_TCP: | ||
537 | if (destination->is_service) | ||
538 | { | ||
539 | tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42); | ||
540 | // FIXME: build message! | ||
541 | } | ||
542 | else | ||
543 | { | ||
544 | tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42); | ||
545 | // FIXME: build message! | ||
546 | } | ||
547 | break; | ||
548 | default: | ||
549 | /* not supported above, how can we get here !? */ | ||
550 | GNUNET_assert (0); | ||
551 | break; | ||
552 | } | ||
553 | send_to_tunnel (tnq, ts); | ||
475 | } | 554 | } |
476 | 555 | ||
477 | 556 | ||
478 | 557 | ||
479 | /** | 558 | /** |
480 | * Receive packets from the helper-process, identify the | 559 | * Receive packets from the helper-process (someone send to the local |
481 | * correct tunnel and forward them on. | 560 | * virtual tunnel interface). Find the destination mapping, and if it |
561 | * exists, identify the correct MESH tunnel (or possibly create it) | ||
562 | * and forward the packet. | ||
482 | * | 563 | * |
483 | * @param cls closure, NULL | 564 | * @param cls closure, NULL |
484 | * @param client NULL | 565 | * @param client NULL |
@@ -491,7 +572,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | |||
491 | const struct tun_header *tun; | 572 | const struct tun_header *tun; |
492 | size_t mlen; | 573 | size_t mlen; |
493 | GNUNET_HashCode key; | 574 | GNUNET_HashCode key; |
494 | struct map_entry *me; | 575 | struct destination_entry *de; |
495 | 576 | ||
496 | mlen = ntohs (message->size); | 577 | mlen = ntohs (message->size); |
497 | if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || | 578 | if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || |
@@ -515,12 +596,12 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | |||
515 | return; | 596 | return; |
516 | } | 597 | } |
517 | pkt6 = (const struct ip6_header *) &tun[1]; | 598 | pkt6 = (const struct ip6_header *) &tun[1]; |
518 | get_key_from_ip (AF_INET6, | 599 | get_destination_key_from_ip (AF_INET6, |
519 | &pkt6->destination_address, | 600 | &pkt6->destination_address, |
520 | &key); | 601 | &key); |
521 | me = GNUNET_CONTAINER_multihashmap_get (hashmap, &key); | 602 | de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key); |
522 | /* FIXME: do we need to guard against hash collision? */ | 603 | /* FIXME: do we need to guard against hash collision? */ |
523 | if (NULL == me) | 604 | if (NULL == de) |
524 | { | 605 | { |
525 | char buf[INET6_ADDRSTRLEN]; | 606 | char buf[INET6_ADDRSTRLEN]; |
526 | 607 | ||
@@ -532,10 +613,11 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | |||
532 | sizeof (buf))); | 613 | sizeof (buf))); |
533 | return; | 614 | return; |
534 | } | 615 | } |
535 | route_packet (me, | 616 | route_packet (de, |
536 | AF_INET6, | 617 | AF_INET6, |
537 | pkt6->next_header, | 618 | pkt6->next_header, |
538 | &pkt6->source_address, | 619 | &pkt6->source_address, |
620 | &pkt6->destination_address, | ||
539 | &pkt6[1], | 621 | &pkt6[1], |
540 | mlen - sizeof (struct ip6_header)); | 622 | mlen - sizeof (struct ip6_header)); |
541 | } | 623 | } |
@@ -551,12 +633,12 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | |||
551 | return; | 633 | return; |
552 | } | 634 | } |
553 | pkt4 = (struct ip4_header *) &tun[1]; | 635 | pkt4 = (struct ip4_header *) &tun[1]; |
554 | get_key_from_ip (AF_INET, | 636 | get_destination_key_from_ip (AF_INET, |
555 | &pkt4->destination_address, | 637 | &pkt4->destination_address, |
556 | &key); | 638 | &key); |
557 | me = GNUNET_CONTAINER_multihashmap_get (hashmap, &key); | 639 | de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key); |
558 | /* FIXME: do we need to guard against hash collision? */ | 640 | /* FIXME: do we need to guard against hash collision? */ |
559 | if (NULL == me) | 641 | if (NULL == de) |
560 | { | 642 | { |
561 | char buf[INET_ADDRSTRLEN]; | 643 | char buf[INET_ADDRSTRLEN]; |
562 | 644 | ||
@@ -574,10 +656,11 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | |||
574 | _("Received IPv4 packet with options (dropping it)\n")); | 656 | _("Received IPv4 packet with options (dropping it)\n")); |
575 | return; | 657 | return; |
576 | } | 658 | } |
577 | route_packet (me, | 659 | route_packet (de, |
578 | AF_INET, | 660 | AF_INET, |
579 | pkt4->protocol, | 661 | pkt4->protocol, |
580 | &pkt4->source_address, | 662 | &pkt4->source_address, |
663 | &pkt4->destination_address, | ||
581 | &pkt4[1], | 664 | &pkt4[1], |
582 | mlen - sizeof (struct ip4_header)); | 665 | mlen - sizeof (struct ip4_header)); |
583 | } | 666 | } |
@@ -591,143 +674,18 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | |||
591 | } | 674 | } |
592 | 675 | ||
593 | 676 | ||
594 | #if 0 | ||
595 | |||
596 | |||
597 | /** | 677 | /** |
598 | * Create a new Address from an answer-packet | 678 | * We got a UDP packet back from the MESH tunnel. Pass it on to the |
599 | */ | 679 | * local virtual interface via the helper. |
600 | static void | 680 | * |
601 | new_ip6addr (struct in6_addr *v6addr, | 681 | * @param cls closure, NULL |
602 | const GNUNET_HashCode * peer, | 682 | * @param tunnel connection to the other end |
603 | const GNUNET_HashCode * service_desc) | 683 | * @param tunnel_ctx pointer to our 'struct TunnelState *' |
604 | { /* {{{ */ | 684 | * @param sender who sent the message |
605 | unsigned char *buf = (unsigned char*) v6addr; | 685 | * @param message the actual message |
606 | char *ipv6addr; | 686 | * @param atsi performance data for the connection |
607 | unsigned long long ipv6prefix; | 687 | * @return GNUNET_OK to keep the connection open, |
608 | 688 | * GNUNET_SYSERR to close it (signal serious error) | |
609 | GNUNET_assert (GNUNET_OK == | ||
610 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", | ||
611 | &ipv6addr)); | ||
612 | GNUNET_assert (GNUNET_OK == | ||
613 | GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", | ||
614 | "IPV6PREFIX", | ||
615 | &ipv6prefix)); | ||
616 | GNUNET_assert (ipv6prefix < 127); | ||
617 | ipv6prefix = (ipv6prefix + 7) / 8; | ||
618 | |||
619 | inet_pton (AF_INET6, ipv6addr, buf); | ||
620 | GNUNET_free (ipv6addr); | ||
621 | |||
622 | int peer_length = 16 - ipv6prefix - 6; | ||
623 | |||
624 | if (peer_length <= 0) | ||
625 | peer_length = 0; | ||
626 | |||
627 | int service_length = 16 - ipv6prefix - peer_length; | ||
628 | |||
629 | if (service_length <= 0) | ||
630 | service_length = 0; | ||
631 | |||
632 | memcpy (buf + ipv6prefix, service_desc, service_length); | ||
633 | memcpy (buf + ipv6prefix + service_length, peer, peer_length); | ||
634 | } | ||
635 | |||
636 | /*}}}*/ | ||
637 | |||
638 | |||
639 | /** | ||
640 | * Create a new Address from an answer-packet | ||
641 | */ | ||
642 | static void | ||
643 | new_ip6addr_remote (struct in6_addr *v6addr, | ||
644 | unsigned char *addr, char addrlen) | ||
645 | { /* {{{ */ | ||
646 | unsigned char *buf = (unsigned char*) v6addr; | ||
647 | char *ipv6addr; | ||
648 | unsigned long long ipv6prefix; | ||
649 | |||
650 | GNUNET_assert (GNUNET_OK == | ||
651 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", | ||
652 | &ipv6addr)); | ||
653 | GNUNET_assert (GNUNET_OK == | ||
654 | GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", | ||
655 | "IPV6PREFIX", | ||
656 | &ipv6prefix)); | ||
657 | GNUNET_assert (ipv6prefix < 127); | ||
658 | ipv6prefix = (ipv6prefix + 7) / 8; | ||
659 | |||
660 | inet_pton (AF_INET6, ipv6addr, buf); | ||
661 | GNUNET_free (ipv6addr); | ||
662 | |||
663 | int local_length = 16 - ipv6prefix; | ||
664 | |||
665 | memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length)); | ||
666 | } | ||
667 | |||
668 | /*}}}*/ | ||
669 | |||
670 | /** | ||
671 | * Create a new Address from an answer-packet | ||
672 | */ | ||
673 | static void | ||
674 | new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen) | ||
675 | { /* {{{ */ | ||
676 | char *ipv4addr; | ||
677 | char *ipv4mask; | ||
678 | |||
679 | GNUNET_assert (GNUNET_OK == | ||
680 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", | ||
681 | &ipv4addr)); | ||
682 | GNUNET_assert (GNUNET_OK == | ||
683 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", | ||
684 | &ipv4mask)); | ||
685 | uint32_t mask; | ||
686 | |||
687 | inet_pton (AF_INET, ipv4addr, buf); | ||
688 | int r = inet_pton (AF_INET, ipv4mask, &mask); | ||
689 | |||
690 | mask = htonl (mask); | ||
691 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r, | ||
692 | mask); | ||
693 | |||
694 | GNUNET_free (ipv4addr); | ||
695 | |||
696 | int c; | ||
697 | |||
698 | if (mask) | ||
699 | { | ||
700 | mask = (mask ^ (mask - 1)) >> 1; | ||
701 | for (c = 0; mask; c++) | ||
702 | { | ||
703 | mask >>= 1; | ||
704 | } | ||
705 | } | ||
706 | else | ||
707 | { | ||
708 | c = CHAR_BIT * sizeof (mask); | ||
709 | } | ||
710 | |||
711 | c = 32 - c; | ||
712 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n", | ||
713 | ipv4mask, c); | ||
714 | |||
715 | GNUNET_free (ipv4mask); | ||
716 | |||
717 | if (c % 8 == 0) | ||
718 | c = c / 8; | ||
719 | else | ||
720 | GNUNET_assert (0); | ||
721 | |||
722 | memcpy (buf + c, addr, GNUNET_MIN (addrlen, 4 - c)); | ||
723 | } | ||
724 | |||
725 | #endif | ||
726 | |||
727 | |||
728 | |||
729 | /** | ||
730 | * FIXME: document. | ||
731 | */ | 689 | */ |
732 | static int | 690 | static int |
733 | receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | 691 | receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, |
@@ -735,6 +693,7 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
735 | const struct GNUNET_MessageHeader *message, | 693 | const struct GNUNET_MessageHeader *message, |
736 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | 694 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) |
737 | { | 695 | { |
696 | // FIXME: parse message, build IP packet, give to TUN! | ||
738 | #if 0 | 697 | #if 0 |
739 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | 698 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); |
740 | struct remote_addr *s = (struct remote_addr *) desc; | 699 | struct remote_addr *s = (struct remote_addr *) desc; |
@@ -903,7 +862,17 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
903 | 862 | ||
904 | 863 | ||
905 | /** | 864 | /** |
906 | * FIXME: document. | 865 | * We got a TCP packet back from the MESH tunnel. Pass it on to the |
866 | * local virtual interface via the helper. | ||
867 | * | ||
868 | * @param cls closure, NULL | ||
869 | * @param tunnel connection to the other end | ||
870 | * @param tunnel_ctx pointer to our 'struct TunnelState *' | ||
871 | * @param sender who sent the message | ||
872 | * @param message the actual message | ||
873 | * @param atsi performance data for the connection | ||
874 | * @return GNUNET_OK to keep the connection open, | ||
875 | * GNUNET_SYSERR to close it (signal serious error) | ||
907 | */ | 876 | */ |
908 | static int | 877 | static int |
909 | receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | 878 | receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, |
@@ -912,6 +881,7 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
912 | const struct GNUNET_MessageHeader *message, | 881 | const struct GNUNET_MessageHeader *message, |
913 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | 882 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) |
914 | { | 883 | { |
884 | // FIXME: parse message, build IP packet, give to TUN! | ||
915 | #if 0 | 885 | #if 0 |
916 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | 886 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); |
917 | struct remote_addr *s = (struct remote_addr *) desc; | 887 | struct remote_addr *s = (struct remote_addr *) desc; |
@@ -1129,6 +1099,7 @@ cleanup (void *cls GNUNET_UNUSED, | |||
1129 | { | 1099 | { |
1130 | unsigned int i; | 1100 | unsigned int i; |
1131 | 1101 | ||
1102 | // FIXME: clean up heaps and maps! | ||
1132 | if (mesh_handle != NULL) | 1103 | if (mesh_handle != NULL) |
1133 | { | 1104 | { |
1134 | GNUNET_MESH_disconnect (mesh_handle); | 1105 | GNUNET_MESH_disconnect (mesh_handle); |
@@ -1176,13 +1147,20 @@ run (void *cls, | |||
1176 | unsigned long long ipv6prefix; | 1147 | unsigned long long ipv6prefix; |
1177 | 1148 | ||
1178 | cfg = cfg_; | 1149 | cfg = cfg_; |
1179 | hashmap = GNUNET_CONTAINER_multihashmap_create (65536); | ||
1180 | heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1181 | |||
1182 | if (GNUNET_OK != | 1150 | if (GNUNET_OK != |
1183 | GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPING", | 1151 | GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPING", |
1184 | &max_mappings)) | 1152 | &max_destination_mappings)) |
1185 | max_mappings = 200; | 1153 | max_destination_mappings = 200; |
1154 | if (GNUNET_OK != | ||
1155 | GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_TUNNELS", | ||
1156 | &max_tunnel_mappings)) | ||
1157 | max_tunnel_mappings = 200; | ||
1158 | |||
1159 | destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2); | ||
1160 | destination_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1161 | tunnel_map = GNUNET_CONTAINER_multihashmap_create (max_tunnel_mappings * 2); | ||
1162 | tunnel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1163 | |||
1186 | 1164 | ||
1187 | vpn_argv[0] = GNUNET_strdup ("vpn-gnunet"); | 1165 | vpn_argv[0] = GNUNET_strdup ("vpn-gnunet"); |
1188 | if (GNUNET_SYSERR == | 1166 | if (GNUNET_SYSERR == |
@@ -1255,6 +1233,9 @@ run (void *cls, | |||
1255 | &tunnel_cleaner, | 1233 | &tunnel_cleaner, |
1256 | handlers, | 1234 | handlers, |
1257 | types); | 1235 | types); |
1236 | // FIXME: register service handlers to allow destination mappings to | ||
1237 | // be created! | ||
1238 | |||
1258 | helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv, | 1239 | helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv, |
1259 | &message_token, NULL); | 1240 | &message_token, NULL); |
1260 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); | 1241 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); |