diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-02 10:33:24 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-02 10:33:24 +0000 |
commit | 6372edeff7c14b4311d6da8b4f8fa2163c11f7db (patch) | |
tree | 99a4fffbed1a86bd1867cbdc50a9af15c04b6c49 /src | |
parent | cf88dbef239cb00d1e89c3329a969ee27d6ec7e8 (diff) | |
download | gnunet-6372edeff7c14b4311d6da8b4f8fa2163c11f7db.tar.gz gnunet-6372edeff7c14b4311d6da8b4f8fa2163c11f7db.zip |
-dce
Diffstat (limited to 'src')
-rw-r--r-- | src/vpn/gnunet-daemon-vpn.c | 573 |
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 | ||
41 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
42 | struct GNUNET_MESH_Handle *mesh_handle; | ||
43 | struct GNUNET_CONTAINER_MultiHashMap *hashmap; | ||
44 | static struct GNUNET_CONTAINER_Heap *heap; | ||
45 | |||
46 | /** | ||
47 | * The handle to the helper | ||
48 | */ | ||
49 | static struct GNUNET_HELPER_Handle *helper_handle; | ||
50 | |||
51 | /** | ||
52 | * Arguments to the exit helper. | ||
53 | */ | ||
54 | static char *vpn_argv[7]; | ||
55 | |||
56 | struct GNUNET_DNS_Handle *dns_handle; | ||
57 | |||
58 | struct answer_packet_list *answer_proc_head; | ||
59 | |||
60 | struct answer_packet_list *answer_proc_tail; | ||
61 | |||
62 | struct answer_packet_list | 41 | struct 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 | ||
71 | void | ||
72 | send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
73 | void | ||
74 | send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
75 | |||
76 | size_t | ||
77 | send_udp_service (void *cls, size_t size, void *buf); | ||
78 | |||
79 | GNUNET_HashCode * | ||
80 | address6_mapping_exists (struct in6_addr *v6addr); | ||
81 | GNUNET_HashCode * | ||
82 | address4_mapping_exists (uint32_t addr); | ||
83 | |||
84 | unsigned int | ||
85 | port_in_ports (uint64_t ports, uint16_t port); | ||
86 | |||
87 | void | ||
88 | send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
89 | const struct GNUNET_ATS_Information *atsi); | ||
90 | |||
91 | struct map_entry | 50 | struct 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 | |||
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 | |||
119 | struct tunnel_state | 88 | struct 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 | ||
128 | struct tunnel_notify_queue | 97 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
129 | { | 98 | |
130 | struct tunnel_notify_queue *next; | 99 | static struct GNUNET_MESH_Handle *mesh_handle; |
131 | struct tunnel_notify_queue *prev; | 100 | |
132 | size_t len; | 101 | static struct GNUNET_CONTAINER_MultiHashMap *hashmap; |
133 | void *cls; | 102 | |
134 | }; | 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; | ||
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 | */ |
150 | static struct GNUNET_CONTAINER_MultiHashMap *udp_connections; | 135 | static struct GNUNET_CONTAINER_MultiHashMap *udp_connections; |
151 | 136 | ||
152 | GNUNET_SCHEDULER_TaskIdentifier conn_task; | 137 | static GNUNET_SCHEDULER_TaskIdentifier conn_task; |
153 | |||
154 | GNUNET_SCHEDULER_TaskIdentifier shs_task; | ||
155 | 138 | ||
139 | static 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; | |||
161 | static struct GNUNET_MESH_Tunnel *udp_tunnel; | 145 | static struct GNUNET_MESH_Tunnel *udp_tunnel; |
162 | 146 | ||
163 | 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 | |||
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 | */ |
190 | int | 183 | static int |
191 | testBit (char *bitArray, unsigned int bitIdx) | 184 | testBit (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 | */ |
247 | GNUNET_HashCode * | 240 | static GNUNET_HashCode * |
248 | address6_mapping_exists (struct in6_addr *v6addr) | 241 | address6_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 | */ |
272 | GNUNET_HashCode * | 265 | static GNUNET_HashCode * |
273 | address4_mapping_exists (uint32_t addr) | 266 | address4_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 | */ | ||
313 | void | ||
314 | helper_write (void *cls GNUNET_UNUSED, | ||
315 | int status) | ||
316 | { | ||
317 | struct answer_packet_list *ans = answer_proc_head; | ||
318 | 303 | ||
319 | if (NULL == ans) | 304 | static void |
320 | return; | 305 | send_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 */ | 351 | static void |
360 | pkt->udp_dns.udp_hdr.spt = htons (53); | 352 | send_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 | */ | ||
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"); | ||
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 | |||
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) | ||
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 | */ |
458 | void | 491 | static void |
459 | message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | 492 | message_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 | ||
845 | void | ||
846 | send_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 | |||
891 | void | ||
892 | send_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 | */ | ||
938 | static size_t | ||
939 | send_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 | |||
985 | unsigned int | ||
986 | port_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 | |||
994 | void | ||
995 | send_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 | */ |
1035 | void | 882 | static void |
1036 | new_ip6addr (struct in6_addr *v6addr, | 883 | new_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 | */ |
1077 | void | 924 | static void |
1078 | new_ip6addr_remote (struct in6_addr *v6addr, | 925 | new_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 | */ |
1108 | void | 955 | static void |
1109 | new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen) | 956 | new_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 | */ |
1169 | void | 1016 | static void |
1170 | process_answer (void *cls, | 1017 | process_answer (void *cls, |
1171 | const struct answer_packet *pkt) | 1018 | const struct answer_packet *pkt) |
1172 | { | 1019 | { |