aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-02 10:33:24 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-02 10:33:24 +0000
commit6372edeff7c14b4311d6da8b4f8fa2163c11f7db (patch)
tree99a4fffbed1a86bd1867cbdc50a9af15c04b6c49 /src
parentcf88dbef239cb00d1e89c3329a969ee27d6ec7e8 (diff)
downloadgnunet-6372edeff7c14b4311d6da8b4f8fa2163c11f7db.tar.gz
gnunet-6372edeff7c14b4311d6da8b4f8fa2163c11f7db.zip
-dce
Diffstat (limited to 'src')
-rw-r--r--src/vpn/gnunet-daemon-vpn.c573
1 files changed, 210 insertions, 363 deletions
diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c
index c9463184c..6945fc772 100644
--- a/src/vpn/gnunet-daemon-vpn.c
+++ b/src/vpn/gnunet-daemon-vpn.c
@@ -38,56 +38,15 @@
38#include "gnunet_dns_service.h" 38#include "gnunet_dns_service.h"
39 39
40 40
41const struct GNUNET_CONFIGURATION_Handle *cfg;
42struct GNUNET_MESH_Handle *mesh_handle;
43struct GNUNET_CONTAINER_MultiHashMap *hashmap;
44static struct GNUNET_CONTAINER_Heap *heap;
45
46/**
47 * The handle to the helper
48 */
49static struct GNUNET_HELPER_Handle *helper_handle;
50
51/**
52 * Arguments to the exit helper.
53 */
54static char *vpn_argv[7];
55
56struct GNUNET_DNS_Handle *dns_handle;
57
58struct answer_packet_list *answer_proc_head;
59
60struct answer_packet_list *answer_proc_tail;
61
62struct answer_packet_list 41struct answer_packet_list
63{ 42{
64 struct answer_packet_list *next GNUNET_PACKED; 43 struct answer_packet_list *next;
65 struct answer_packet_list *prev GNUNET_PACKED; 44 struct answer_packet_list *prev;
66 struct GNUNET_SERVER_Client *client; 45 struct GNUNET_SERVER_Client *client;
67 struct answer_packet pkt; 46 struct answer_packet pkt;
68}; 47};
69 48
70 49
71void
72send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
73void
74send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
75
76size_t
77send_udp_service (void *cls, size_t size, void *buf);
78
79GNUNET_HashCode *
80address6_mapping_exists (struct in6_addr *v6addr);
81GNUNET_HashCode *
82address4_mapping_exists (uint32_t addr);
83
84unsigned int
85port_in_ports (uint64_t ports, uint16_t port);
86
87void
88send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer,
89 const struct GNUNET_ATS_Information *atsi);
90
91struct map_entry 50struct map_entry
92{ 51{
93 /** The description of the service (used for service) */ 52 /** The description of the service (used for service) */
@@ -116,6 +75,16 @@ struct remote_addr
116 char proto; 75 char proto;
117}; 76};
118 77
78
79struct 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
119struct tunnel_state 88struct tunnel_state
120{ 89{
121 struct GNUNET_MESH_TransmitHandle *th; 90 struct GNUNET_MESH_TransmitHandle *th;
@@ -125,13 +94,29 @@ struct tunnel_state
125}; 94};
126 95
127 96
128struct tunnel_notify_queue 97static const struct GNUNET_CONFIGURATION_Handle *cfg;
129{ 98
130 struct tunnel_notify_queue *next; 99static struct GNUNET_MESH_Handle *mesh_handle;
131 struct tunnel_notify_queue *prev; 100
132 size_t len; 101static struct GNUNET_CONTAINER_MultiHashMap *hashmap;
133 void *cls; 102
134}; 103static struct GNUNET_CONTAINER_Heap *heap;
104
105/**
106 * The handle to the helper
107 */
108static struct GNUNET_HELPER_Handle *helper_handle;
109
110/**
111 * Arguments to the exit helper.
112 */
113static char *vpn_argv[7];
114
115static struct GNUNET_DNS_Handle *dns_handle;
116
117static struct answer_packet_list *answer_proc_head;
118
119static struct answer_packet_list *answer_proc_tail;
135 120
136/** 121/**
137 * If there are at least this many address-mappings, old ones will be removed 122 * If there are at least this many address-mappings, old ones will be removed
@@ -149,10 +134,9 @@ static int ret;
149 */ 134 */
150static struct GNUNET_CONTAINER_MultiHashMap *udp_connections; 135static struct GNUNET_CONTAINER_MultiHashMap *udp_connections;
151 136
152GNUNET_SCHEDULER_TaskIdentifier conn_task; 137static GNUNET_SCHEDULER_TaskIdentifier conn_task;
153
154GNUNET_SCHEDULER_TaskIdentifier shs_task;
155 138
139static GNUNET_SCHEDULER_TaskIdentifier shs_task;
156 140
157/** 141/**
158 * The tunnels that will be used to send tcp- and udp-packets 142 * The tunnels that will be used to send tcp- and udp-packets
@@ -161,6 +145,15 @@ static struct GNUNET_MESH_Tunnel *tcp_tunnel;
161static struct GNUNET_MESH_Tunnel *udp_tunnel; 145static struct GNUNET_MESH_Tunnel *udp_tunnel;
162 146
163 147
148static unsigned int
149port_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
164 157
165/** 158/**
166 * Sets a bit active in a bitArray. 159 * Sets a bit active in a bitArray.
@@ -187,7 +180,7 @@ setBit (char *bitArray, unsigned int bitIdx)
187 * @param bitIdx which bit to test 180 * @param bitIdx which bit to test
188 * @return GNUNET_YES if the bit is set, GNUNET_NO if not. 181 * @return GNUNET_YES if the bit is set, GNUNET_NO if not.
189 */ 182 */
190int 183static int
191testBit (char *bitArray, unsigned int bitIdx) 184testBit (char *bitArray, unsigned int bitIdx)
192{ 185{
193 size_t slot; 186 size_t slot;
@@ -244,7 +237,7 @@ cleanup (void *cls GNUNET_UNUSED,
244/** 237/**
245 * @return the hash of the IP-Address if a mapping exists, NULL otherwise 238 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
246 */ 239 */
247GNUNET_HashCode * 240static GNUNET_HashCode *
248address6_mapping_exists (struct in6_addr *v6addr) 241address6_mapping_exists (struct in6_addr *v6addr)
249{ 242{
250 unsigned char *addr = (unsigned char*) v6addr; 243 unsigned char *addr = (unsigned char*) v6addr;
@@ -269,7 +262,7 @@ address6_mapping_exists (struct in6_addr *v6addr)
269/** 262/**
270 * @return the hash of the IP-Address if a mapping exists, NULL otherwise 263 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
271 */ 264 */
272GNUNET_HashCode * 265static GNUNET_HashCode *
273address4_mapping_exists (uint32_t addr) 266address4_mapping_exists (uint32_t addr)
274{ 267{
275 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode)); 268 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
@@ -307,155 +300,195 @@ initialize_tunnel_state (int addrlen, struct GNUNET_MESH_TransmitHandle *th)
307 return ts; 300 return ts;
308} 301}
309 302
310/**
311 * Send an dns-answer-packet to the helper
312 */
313void
314helper_write (void *cls GNUNET_UNUSED,
315 int status)
316{
317 struct answer_packet_list *ans = answer_proc_head;
318 303
319 if (NULL == ans) 304static void
320 return; 305send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
321 if (GNUNET_SYSERR == status) 306{
307 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
322 return; 308 return;
323 309
324 size_t len = ntohs (ans->pkt.hdr.size); 310 struct ip_icmp *request = cls;
325 311
326 GNUNET_assert (ans->pkt.subtype == GNUNET_DNS_ANSWER_TYPE_IP); 312 struct ip_icmp *response = alloca (ntohs (request->shdr.size));
327 313
328 GNUNET_assert (20 == sizeof (struct ip_hdr)); 314 GNUNET_assert (response != NULL);
329 GNUNET_assert (8 == sizeof (struct udp_pkt)); 315 memset (response, 0, ntohs (request->shdr.size));
330 316
331 size_t data_len = len - sizeof (struct answer_packet) + 1; 317 response->shdr.size = request->shdr.size;
318 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
332 319
333 size_t pkt_len; 320 response->tun.flags = 0;
321 response->tun.type = htons (0x0800);
334 322
335 if (ans->pkt.addrlen == 16) 323 response->ip_hdr.hdr_lngth = 5;
336 { 324 response->ip_hdr.version = 4;
337 size_t net_len = 325 response->ip_hdr.proto = 0x01;
338 sizeof (struct ip6_hdr) + sizeof (struct udp_dns) + data_len; 326 response->ip_hdr.dadr = request->ip_hdr.sadr;
339 pkt_len = 327 response->ip_hdr.sadr = request->ip_hdr.dadr;
340 sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + 328 response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth;
341 net_len; 329
330 response->ip_hdr.chks =
331 GNUNET_CRYPTO_crc16_n ((uint16_t *) & response->ip_hdr, 20);
342 332
343 struct ip6_udp_dns *pkt = alloca (pkt_len); 333 response->icmp_hdr.code = 0;
334 response->icmp_hdr.type = 0x0;
344 335
345 GNUNET_assert (pkt != NULL); 336 /* Magic, more Magic! */
346 memset (pkt, 0, pkt_len); 337 response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
347 338
348 /* set the gnunet-header */ 339 /* Copy the rest of the packet */
349 pkt->shdr.size = htons (pkt_len); 340 memcpy (response + 1, request + 1,
350 pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 341 ntohs (request->shdr.size) - sizeof (struct ip_icmp));
351 342
352 /* set the tun-header (no flags and ethertype of IPv4) */ 343 (void) GNUNET_HELPER_send (helper_handle,
353 pkt->tun.flags = 0; 344 &response->shdr,
354 pkt->tun.type = htons (0x86dd); 345 GNUNET_YES,
346 NULL, NULL);
347 GNUNET_free (request);
348}
355 349
356 memcpy (&pkt->ip6_hdr.sadr, ans->pkt.from, 16);
357 memcpy (&pkt->ip6_hdr.dadr, ans->pkt.to, 16);
358 350
359 /* set the udp-header */ 351static void
360 pkt->udp_dns.udp_hdr.spt = htons (53); 352send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
361 pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port; 353{
362 pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip6_hdr)); 354 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
363 pkt->udp_dns.udp_hdr.crc = 0; 355 return;
364 uint32_t sum = 0;
365 356
366 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->ip6_hdr.sadr, 16); 357 struct ip6_icmp *request = cls;
367 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->ip6_hdr.dadr, 16);
368 uint32_t tmp = (pkt->udp_dns.udp_hdr.len & 0xffff);
369 358
370 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); 359 struct ip6_icmp *response = alloca (ntohs (request->shdr.size));
371 tmp = htons (((pkt->ip6_hdr.nxthdr & 0x00ff)));
372 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
373 360
374 sum = 361 GNUNET_assert (response != NULL);
375 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->udp_dns.udp_hdr, 362 memset (response, 0, ntohs (request->shdr.size));
376 ntohs (net_len - sizeof (struct ip6_hdr)));
377 pkt->udp_dns.udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
378 363
379 pkt->ip6_hdr.version = 6; 364 response->shdr.size = request->shdr.size;
380 pkt->ip6_hdr.paylgth = net_len - sizeof (struct ip6_hdr); 365 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
381 pkt->ip6_hdr.nxthdr = IPPROTO_UDP;
382 pkt->ip6_hdr.hoplmt = 0xff;
383 366
384 memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len); 367 response->tun.flags = 0;
385 (void) GNUNET_HELPER_send (helper_handle, 368 response->tun.type = htons (0x86dd);
386 &pkt->shdr, 369
387 GNUNET_YES, 370 response->ip6_hdr.hoplmt = 255;
388 &helper_write, NULL); 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 */
399static size_t
400send_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");
389 } 419 }
390 else if (ans->pkt.addrlen == 4) 420 else
421 size = 0;
422
423 if (NULL != ts->head)
391 { 424 {
392 size_t net_len = 425 struct tunnel_notify_queue *element = ts->head;
393 sizeof (struct ip_hdr) + sizeof (struct udp_dns) + data_len; 426
394 pkt_len = 427 GNUNET_CONTAINER_DLL_remove (ts->head, ts->tail, element);
395 sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) +
396 net_len;
397
398 struct ip_udp_dns *pkt = alloca (pkt_len);
399
400 GNUNET_assert (pkt != NULL);
401 memset (pkt, 0, pkt_len);
402
403 /* set the gnunet-header */
404 pkt->shdr.size = htons (pkt_len);
405 pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
406
407 /* set the tun-header (no flags and ethertype of IPv4) */
408 pkt->tun.flags = 0;
409 pkt->tun.type = htons (0x0800);
410
411 /* set the ip-header */
412 pkt->ip_hdr.version = 4;
413 pkt->ip_hdr.hdr_lngth = 5;
414 pkt->ip_hdr.diff_serv = 0;
415 pkt->ip_hdr.tot_lngth = htons (net_len);
416 pkt->ip_hdr.ident = 0;
417 pkt->ip_hdr.flags = 0;
418 pkt->ip_hdr.frag_off = 0;
419 pkt->ip_hdr.ttl = 255;
420 pkt->ip_hdr.proto = IPPROTO_UDP;
421 pkt->ip_hdr.chks = 0; /* Will be calculated later */
422
423 memcpy (&pkt->ip_hdr.sadr, ans->pkt.from, 4);
424 memcpy (&pkt->ip_hdr.dadr, ans->pkt.to, 4);
425
426 pkt->ip_hdr.chks =
427 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt->ip_hdr, 5 * 4);
428
429 /* set the udp-header */
430 pkt->udp_dns.udp_hdr.spt = htons (53);
431 pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
432 pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr));
433 pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */
434
435 memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
436 (void) GNUNET_HELPER_send (helper_handle,
437 &pkt->shdr,
438 GNUNET_YES,
439 &helper_write, NULL);
440 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);
441 } 440 }
442 else 441 GNUNET_free (cls);
442
443 return size;
444}
445
446
447static void
448send_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)
443 { 464 {
444 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wrong addrlen = %d\n", 465 ts->th =
445 ans->pkt.addrlen); 466 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
446 GNUNET_assert (0); 467 GNUNET_TIME_relative_divide
447 return; /* convince compiler that we're done here */ 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);
448 } 473 }
474 else
475 {
476 struct tunnel_notify_queue *element = GNUNET_malloc (sizeof *element);
449 477
450 GNUNET_CONTAINER_DLL_remove (answer_proc_head, answer_proc_tail, ans); 478 element->cls = cls;
451 GNUNET_free (ans); 479 element->len = ntohs (hdr->size);
452 480
481 GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, element);
482 }
453} 483}
454 484
485
486
487
455/** 488/**
456 * Receive packets from the helper-process 489 * Receive packets from the helper-process
457 */ 490 */
458void 491static void
459message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, 492message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
460 const struct GNUNET_MessageHeader *message) 493 const struct GNUNET_MessageHeader *message)
461{ 494{
@@ -842,197 +875,11 @@ collect_mappings (void *cls GNUNET_UNUSED,
842 GNUNET_free (me); 875 GNUNET_free (me);
843} 876}
844 877
845void
846send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
847{
848 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
849 return;
850
851 struct ip_icmp *request = cls;
852
853 struct ip_icmp *response = alloca (ntohs (request->shdr.size));
854
855 GNUNET_assert (response != NULL);
856 memset (response, 0, ntohs (request->shdr.size));
857
858 response->shdr.size = request->shdr.size;
859 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
860
861 response->tun.flags = 0;
862 response->tun.type = htons (0x0800);
863
864 response->ip_hdr.hdr_lngth = 5;
865 response->ip_hdr.version = 4;
866 response->ip_hdr.proto = 0x01;
867 response->ip_hdr.dadr = request->ip_hdr.sadr;
868 response->ip_hdr.sadr = request->ip_hdr.dadr;
869 response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth;
870
871 response->ip_hdr.chks =
872 GNUNET_CRYPTO_crc16_n ((uint16_t *) & response->ip_hdr, 20);
873
874 response->icmp_hdr.code = 0;
875 response->icmp_hdr.type = 0x0;
876
877 /* Magic, more Magic! */
878 response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
879
880 /* Copy the rest of the packet */
881 memcpy (response + 1, request + 1,
882 ntohs (request->shdr.size) - sizeof (struct ip_icmp));
883
884 (void) GNUNET_HELPER_send (helper_handle,
885 &response->shdr,
886 GNUNET_YES,
887 NULL, NULL);
888 GNUNET_free (request);
889}
890
891void
892send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
893{
894 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
895 return;
896
897 struct ip6_icmp *request = cls;
898
899 struct ip6_icmp *response = alloca (ntohs (request->shdr.size));
900
901 GNUNET_assert (response != NULL);
902 memset (response, 0, ntohs (request->shdr.size));
903
904 response->shdr.size = request->shdr.size;
905 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
906
907 response->tun.flags = 0;
908 response->tun.type = htons (0x86dd);
909
910 response->ip6_hdr.hoplmt = 255;
911 response->ip6_hdr.paylgth = request->ip6_hdr.paylgth;
912 response->ip6_hdr.nxthdr = 0x3a;
913 response->ip6_hdr.version = 6;
914 memcpy (&response->ip6_hdr.sadr, &request->ip6_hdr.dadr, 16);
915 memcpy (&response->ip6_hdr.dadr, &request->ip6_hdr.sadr, 16);
916
917 response->icmp_hdr.code = 0;
918 response->icmp_hdr.type = 0x81;
919
920 /* Magic, more Magic! */
921 response->icmp_hdr.chks = request->icmp_hdr.chks - 0x1;
922
923 /* Copy the rest of the packet */
924 memcpy (response + 1, request + 1,
925 ntohs (request->shdr.size) - sizeof (struct ip6_icmp));
926
927 (void) GNUNET_HELPER_send (helper_handle,
928 &response->shdr,
929 GNUNET_YES,
930 NULL, NULL);
931 GNUNET_free (request);
932}
933
934/**
935 * cls is the pointer to a GNUNET_MessageHeader that is
936 * followed by the service-descriptor and the packet that should be sent;
937 */
938static size_t
939send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
940{
941 struct GNUNET_MESH_Tunnel **tunnel = cls;
942
943 struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
944
945 ts->th = NULL;
946
947 if (NULL != buf)
948 {
949 struct GNUNET_MessageHeader *hdr =
950 (struct GNUNET_MessageHeader *) (tunnel + 1);
951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
952 "send_pkt_to_peer_notify_callback: buf = %x; size = %u;\n", buf,
953 size);
954 GNUNET_assert (size >= ntohs (hdr->size));
955 memcpy (buf, hdr, ntohs (hdr->size));
956 size = ntohs (hdr->size);
957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n");
958 }
959 else
960 size = 0;
961
962 if (NULL != ts->head)
963 {
964 struct tunnel_notify_queue *element = ts->head;
965
966 GNUNET_CONTAINER_DLL_remove (ts->head, ts->tail, element);
967
968 ts->th =
969 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
970 GNUNET_TIME_relative_divide
971 (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
972 (const struct GNUNET_PeerIdentity *)
973 NULL, element->len,
974 send_pkt_to_peer_notify_callback,
975 element->cls);
976
977 /* save the handle */
978 GNUNET_free (element);
979 }
980 GNUNET_free (cls);
981
982 return size;
983}
984
985unsigned int
986port_in_ports (uint64_t ports, uint16_t port)
987{
988 uint16_t *ps = (uint16_t *) & ports;
989
990 return ports == 0 || ps[0] == port || ps[1] == port || ps[2] == port ||
991 ps[3] == port;
992}
993
994void
995send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer,
996 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
997{
998 /* peer == NULL means that all peers in this request are connected */
999 if (peer == NULL)
1000 return;
1001 struct GNUNET_MESH_Tunnel **tunnel = cls;
1002 struct GNUNET_MessageHeader *hdr =
1003 (struct GNUNET_MessageHeader *) (tunnel + 1);
1004
1005 GNUNET_assert (NULL != tunnel);
1006 GNUNET_assert (NULL != *tunnel);
1007
1008 struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
1009
1010 if (NULL == ts->th)
1011 {
1012 ts->th =
1013 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
1014 GNUNET_TIME_relative_divide
1015 (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
1016 (const struct GNUNET_PeerIdentity *)
1017 NULL, ntohs (hdr->size),
1018 send_pkt_to_peer_notify_callback,
1019 cls);
1020 }
1021 else
1022 {
1023 struct tunnel_notify_queue *element = GNUNET_malloc (sizeof *element);
1024
1025 element->cls = cls;
1026 element->len = ntohs (hdr->size);
1027
1028 GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, element);
1029 }
1030}
1031 878
1032/** 879/**
1033 * Create a new Address from an answer-packet 880 * Create a new Address from an answer-packet
1034 */ 881 */
1035void 882static void
1036new_ip6addr (struct in6_addr *v6addr, 883new_ip6addr (struct in6_addr *v6addr,
1037 const GNUNET_HashCode * peer, 884 const GNUNET_HashCode * peer,
1038 const GNUNET_HashCode * service_desc) 885 const GNUNET_HashCode * service_desc)
@@ -1074,7 +921,7 @@ new_ip6addr (struct in6_addr *v6addr,
1074/** 921/**
1075 * Create a new Address from an answer-packet 922 * Create a new Address from an answer-packet
1076 */ 923 */
1077void 924static void
1078new_ip6addr_remote (struct in6_addr *v6addr, 925new_ip6addr_remote (struct in6_addr *v6addr,
1079 unsigned char *addr, char addrlen) 926 unsigned char *addr, char addrlen)
1080{ /* {{{ */ 927{ /* {{{ */
@@ -1105,7 +952,7 @@ new_ip6addr_remote (struct in6_addr *v6addr,
1105/** 952/**
1106 * Create a new Address from an answer-packet 953 * Create a new Address from an answer-packet
1107 */ 954 */
1108void 955static void
1109new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen) 956new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
1110{ /* {{{ */ 957{ /* {{{ */
1111 char *ipv4addr; 958 char *ipv4addr;
@@ -1166,7 +1013,7 @@ new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
1166 * At the moment this means "inventing" and IPv6-Address for .gnunet-services and 1013 * At the moment this means "inventing" and IPv6-Address for .gnunet-services and
1167 * doing nothing for "real" services. 1014 * doing nothing for "real" services.
1168 */ 1015 */
1169void 1016static void
1170process_answer (void *cls, 1017process_answer (void *cls,
1171 const struct answer_packet *pkt) 1018 const struct answer_packet *pkt)
1172{ 1019{