aboutsummaryrefslogtreecommitdiff
path: root/src/exit
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-05 23:31:09 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-05 23:31:09 +0000
commitcdfe91f4823e6733e588acd1bbc5cb6c1a197938 (patch)
treeb3aaeb1208fbe0645488928899cfcd795f9ea3b7 /src/exit
parent6c55b81a839385015d43b8ea313e2ee11f834502 (diff)
downloadgnunet-cdfe91f4823e6733e588acd1bbc5cb6c1a197938.tar.gz
gnunet-cdfe91f4823e6733e588acd1bbc5cb6c1a197938.zip
-working on exit data structures
Diffstat (limited to 'src/exit')
-rw-r--r--src/exit/gnunet-daemon-exit.c533
1 files changed, 281 insertions, 252 deletions
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index e6730ccdb..4986b9344 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -138,9 +138,9 @@ struct dns_header
138GNUNET_NETWORK_STRUCT_END 138GNUNET_NETWORK_STRUCT_END
139 139
140/** 140/**
141 * Information about a remote address. 141 * Information about an address.
142 */ 142 */
143struct remote_addr 143struct SocketAddress
144{ 144{
145 /** 145 /**
146 * AF_INET or AF_INET6. 146 * AF_INET or AF_INET6.
@@ -162,64 +162,112 @@ struct remote_addr
162 */ 162 */
163 struct in6_addr ipv6; 163 struct in6_addr ipv6;
164 } address; 164 } address;
165
166 /**
167 * Remote port, in host byte order!
168 */
169 uint16_t port;
170 165
171 /** 166 /**
172 * IPPROTO_TCP or IPPROTO_UDP; 167 * IPPROTO_TCP or IPPROTO_UDP;
173 */ 168 */
174 uint8_t proto; 169 uint8_t proto;
175 170
171 /**
172 * Remote port, in host byte order!
173 */
174 uint16_t port;
175
176}; 176};
177 177
178/** 178/**
179 * This struct is saved into the services-hashmap 179 * This struct is saved into the services-hashmap to represent
180 * a service this peer is specifically offering an exit for
181 * (for a specific domain name).
180 */ 182 */
181struct redirect_service 183struct LocalService
182{ 184{
183 185
184 /** 186 /**
185 * Remote address to use for the service. 187 * Remote address to use for the service.
186 */ 188 */
187 struct remote_addr address; 189 struct SocketAddress address;
188 190
189 /** 191 /**
190 * Descriptor for this service (also key of this entry in the service hash map). 192 * DNS name of the service.
191 */ 193 */
192 GNUNET_HashCode desc; 194 char *name;
193 195
194 /** 196 /**
195 * Port I am listening on within GNUnet for this service, in host byte order. 197 * Port I am listening on within GNUnet for this service, in host
198 * byte order. (as we may redirect ports).
196 */ 199 */
197 uint16_t my_port; 200 uint16_t my_port;
198 201
199}; 202};
200 203
201/** 204/**
202 * Information we use to track a connection. 205 * Information we use to track a connection (the classical 6-tuple of
206 * IP-version, protocol, source-IP, destination-IP, source-port and
207 * destinatin-port.
208 */
209struct RedirectInformation
210{
211
212 /**
213 * Address information for the other party (equivalent of the
214 * arguments one would give to "connect").
215 */
216 struct SocketAddress remote_address;
217
218 /**
219 * Address information we used locally (AF and proto must match
220 * "remote_address"). Equivalent of the arguments one would give to
221 * "bind".
222 */
223 struct SocketAddress local_address;
224
225 /*
226 Note 1: additional information might be added here in the
227 future to support protocols that require special handling,
228 such as ftp/tftp
229
230 Note 2: we might also sometimes not match on all components
231 of the tuple, to support protocols where things do not always
232 fully map.
233 */
234};
235
236
237/**
238 * Queue of messages to a tunnel.
203 */ 239 */
204struct redirect_info 240struct TunnelMessageQueue
205{ 241{
242 /**
243 * This is a doubly-linked list.
244 */
245 struct TunnelMessageQueue *next;
206 246
207 /** 247 /**
208 * Address information for the other party. 248 * This is a doubly-linked list.
209 */ 249 */
210 struct remote_addr remote_address; 250 struct TunnelMessageQueue *prev;
211 251
212 /** 252 /**
213 * The source-port of this connection, in host byte order 253 * Payload to send via the tunnel.
214 */ 254 */
215 uint16_t source_port; 255 const void *payload;
216 256
257 /**
258 * Number of bytes in 'payload'.
259 */
260 size_t len;
217}; 261};
218 262
263
219/** 264/**
220 * This struct is saved into {tcp,udp}_connections; 265 * This struct is saved into connections_map to allow finding the
266 * right tunnel given an IP packet from TUN. It is also associated
267 * with the tunnel's closure so we can find it again for the next
268 * message from the tunnel.
221 */ 269 */
222struct redirect_state 270struct TunnelState
223{ 271{
224 /** 272 /**
225 * Mesh tunnel that is used for this connection. 273 * Mesh tunnel that is used for this connection.
@@ -239,51 +287,28 @@ struct redirect_state
239 /** 287 /**
240 * Associated service record, or NULL for no service. 288 * Associated service record, or NULL for no service.
241 */ 289 */
242 struct redirect_service *serv; 290 struct LocalService *serv;
243
244 /**
245 * Source port we use for this connection. FIXME: needed? used?
246 */
247 uint16_t source_port__;
248 291
249};
250
251/**
252 * Queue of messages to a tunnel.
253 */
254struct tunnel_notify_queue
255{
256 /** 292 /**
257 * This is a doubly-linked list. 293 * Head of DLL of messages for this tunnel.
258 */ 294 */
259 struct tunnel_notify_queue *next; 295 struct TunnelMessageQueue *head;
260 296
261 /** 297 /**
262 * This is a doubly-linked list. 298 * Tail of DLL of messages for this tunnel.
263 */ 299 */
264 struct tunnel_notify_queue *prev; 300 struct TunnelMessageQueue *tail;
265 301
266 /** 302 /**
267 * Payload to send via the tunnel. 303 * Active tunnel transmission request (or NULL).
268 */ 304 */
269 const void *payload; 305 struct GNUNET_MESH_TransmitHandle *th;
270 306
271 /** 307 /**
272 * Number of bytes in 'cls'. 308 * Primary redirection information for this connection.
273 */ 309 */
274 size_t len; 310 struct RedirectInformation ri;
275};
276 311
277
278/**
279 * Information we track per mesh tunnel.
280 */
281struct tunnel_state
282{
283 struct tunnel_notify_queue *head;
284 struct tunnel_notify_queue *tail;
285 struct GNUNET_MESH_TransmitHandle *th;
286 struct GNUNET_MESH_Tunnel *tunnel;
287}; 312};
288 313
289 314
@@ -308,18 +333,13 @@ static char *exit_argv[7];
308static unsigned long long ipv6prefix; 333static unsigned long long ipv6prefix;
309 334
310/** 335/**
311 * Final status code.
312 */
313static int ret;
314
315/**
316 * The handle to mesh 336 * The handle to mesh
317 */ 337 */
318static struct GNUNET_MESH_Handle *mesh_handle; 338static struct GNUNET_MESH_Handle *mesh_handle;
319 339
320/** 340/**
321 * This hashmaps contains the mapping from peer, service-descriptor, 341 * This hashmaps contains the mapping from peer, service-descriptor,
322 * source-port and destination-port to a struct redirect_state 342 * source-port and destination-port to a struct TunnelState
323 */ 343 */
324static struct GNUNET_CONTAINER_MultiHashMap *connections_map; 344static struct GNUNET_CONTAINER_MultiHashMap *connections_map;
325 345
@@ -352,13 +372,14 @@ static struct GNUNET_CONTAINER_MultiHashMap *tcp_services;
352 * @param ri information about the connection 372 * @param ri information about the connection
353 */ 373 */
354static void 374static void
355hash_redirect_info (GNUNET_HashCode * hash, 375hash_redirect_info (GNUNET_HashCode *hash,
356 const struct redirect_info *ri) 376 const struct RedirectInformation *ri)
357{ 377{
358 char *off; 378 char *off;
359 379
360 memset (hash, 0, sizeof (GNUNET_HashCode)); 380 memset (hash, 0, sizeof (GNUNET_HashCode));
361 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash */ 381 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
382 so we put the IP address in there (and hope for few collisions) */
362 off = (char*) hash; 383 off = (char*) hash;
363 switch (ri->remote_address.af) 384 switch (ri->remote_address.af)
364 { 385 {
@@ -374,8 +395,78 @@ hash_redirect_info (GNUNET_HashCode * hash,
374 GNUNET_assert (0); 395 GNUNET_assert (0);
375 } 396 }
376 memcpy (off, &ri->remote_address.port, sizeof (uint16_t)); 397 memcpy (off, &ri->remote_address.port, sizeof (uint16_t));
398 off += sizeof (uint16_t);
399 switch (ri->local_address.af)
400 {
401 case AF_INET:
402 memcpy (off, &ri->local_address.address.ipv4, sizeof (struct in_addr));
403 off += sizeof (struct in_addr);
404 break;
405 case AF_INET6:
406 memcpy (off, &ri->local_address.address.ipv6, sizeof (struct in6_addr));
407 off += sizeof (struct in_addr);
408 break;
409 default:
410 GNUNET_assert (0);
411 }
412 memcpy (off, &ri->local_address.port, sizeof (uint16_t));
413 off += sizeof (uint16_t);
377 memcpy (off, &ri->remote_address.proto, sizeof (uint8_t)); 414 memcpy (off, &ri->remote_address.proto, sizeof (uint8_t));
378 memcpy (off, &ri->source_port, sizeof (uint8_t)); 415 off += sizeof (uint8_t);
416}
417
418
419/**
420 * Get our connection tracking state. Warns if it does not exists,
421 * refreshes the timestamp if it does exist.
422 *
423 * @param af address family
424 * @param protocol IPPROTO_UDP or IPPROTO_TCP
425 * @param destination_ip target IP
426 * @param destination_port target port
427 * @param local_ip local IP
428 * @param local_port local port
429 * @param state_key set to hash's state if non-NULL
430 * @return NULL if we have no tracking information for this tuple
431 */
432static struct TunnelState *
433get_redirect_state (int af,
434 int protocol,
435 const void *destination_ip,
436 uint16_t destination_port,
437 const void *local_ip,
438 uint16_t local_port,
439 GNUNET_HashCode *state_key)
440{
441 struct RedirectInformation ri;
442 GNUNET_HashCode key;
443 struct TunnelState *state;
444
445 ri.remote_address.af = af;
446 if (af == AF_INET)
447 ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
448 else
449 ri.remote_address.address.ipv6 = * ((struct in6_addr*) destination_ip);
450 ri.remote_address.port = destination_port;
451 ri.remote_address.proto = protocol;
452 ri.local_address.af = af;
453 if (af == AF_INET)
454 ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
455 else
456 ri.local_address.address.ipv6 = * ((struct in6_addr*) local_ip);
457 ri.local_address.port = local_port;
458 ri.local_address.proto = protocol;
459 hash_redirect_info (&key, &ri);
460 if (NULL != state_key)
461 *state_key = key;
462 state = GNUNET_CONTAINER_multihashmap_get (connections_map, &key);
463 if (NULL == state)
464 return NULL;
465 /* Mark this connection as freshly used */
466 GNUNET_CONTAINER_heap_update_cost (connections_heap,
467 state->heap_node,
468 GNUNET_TIME_absolute_get ().abs_value);
469 return state;
379} 470}
380 471
381 472
@@ -388,7 +479,7 @@ hash_redirect_info (GNUNET_HashCode * hash,
388 * @param dpt destination port 479 * @param dpt destination port
389 * @return NULL if we are not aware of such a service 480 * @return NULL if we are not aware of such a service
390 */ 481 */
391struct redirect_service * 482struct LocalService *
392find_service (struct GNUNET_CONTAINER_MultiHashMap *service_map, 483find_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
393 const GNUNET_HashCode *desc, 484 const GNUNET_HashCode *desc,
394 uint16_t dpt) 485 uint16_t dpt)
@@ -415,8 +506,9 @@ free_service_record (void *cls,
415 const GNUNET_HashCode *key, 506 const GNUNET_HashCode *key,
416 void *value) 507 void *value)
417{ 508{
418 struct redirect_service *service = value; 509 struct LocalService *service = value;
419 510
511 GNUNET_free_non_null (service->name);
420 GNUNET_free (service); 512 GNUNET_free (service);
421 return GNUNET_OK; 513 return GNUNET_OK;
422} 514}
@@ -429,19 +521,19 @@ free_service_record (void *cls,
429 * @param service_map map of services (TCP or UDP) 521 * @param service_map map of services (TCP or UDP)
430 * @param name name of the service 522 * @param name name of the service
431 * @param dpt destination port 523 * @param dpt destination port
432 * @param service service information record to store (service->desc will be set). 524 * @param service service information record to store (service->name will be set).
433 */ 525 */
434static void 526static void
435store_service (struct GNUNET_CONTAINER_MultiHashMap *service_map, 527store_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
436 const char *name, 528 const char *name,
437 uint16_t dpt, 529 uint16_t dpt,
438 struct redirect_service *service) 530 struct LocalService *service)
439{ 531{
440 char key[sizeof (GNUNET_HashCode) + sizeof (uint16_t)]; 532 char key[sizeof (GNUNET_HashCode) + sizeof (uint16_t)];
441 GNUNET_HashCode desc; 533 GNUNET_HashCode desc;
442 534
443 GNUNET_CRYPTO_hash (name, strlen (name) + 1, &desc); 535 GNUNET_CRYPTO_hash (name, strlen (name) + 1, &desc);
444 service->desc = desc; 536 service->name = GNUNET_strdup (name);
445 memcpy (&key[0], &dpt, sizeof (uint16_t)); 537 memcpy (&key[0], &dpt, sizeof (uint16_t));
446 memcpy (&key[sizeof(uint16_t)], &desc, sizeof (GNUNET_HashCode)); 538 memcpy (&key[sizeof(uint16_t)], &desc, sizeof (GNUNET_HashCode));
447 if (GNUNET_OK != 539 if (GNUNET_OK !=
@@ -462,7 +554,7 @@ store_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
462/** 554/**
463 * MESH is ready to receive a message for the tunnel. Transmit it. 555 * MESH is ready to receive a message for the tunnel. Transmit it.
464 * 556 *
465 * @param cls the 'struct tunnel_state'. 557 * @param cls the 'struct TunnelState'.
466 * @param size number of bytes available in buf 558 * @param size number of bytes available in buf
467 * @param buf where to copy the message 559 * @param buf where to copy the message
468 * @return number of bytes copied to buf 560 * @return number of bytes copied to buf
@@ -470,9 +562,9 @@ store_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
470static size_t 562static size_t
471send_to_peer_notify_callback (void *cls, size_t size, void *buf) 563send_to_peer_notify_callback (void *cls, size_t size, void *buf)
472{ 564{
473 struct tunnel_state *s = cls; 565 struct TunnelState *s = cls;
474 struct GNUNET_MESH_Tunnel *tunnel = s->tunnel; 566 struct GNUNET_MESH_Tunnel *tunnel = s->tunnel;
475 struct tunnel_notify_queue *tnq; 567 struct TunnelMessageQueue *tnq;
476 568
477 s->th = NULL; 569 s->th = NULL;
478 tnq = s->head; 570 tnq = s->head;
@@ -502,7 +594,7 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
502 * @param mesh_tunnel destination 594 * @param mesh_tunnel destination
503 * @param payload message to transmit 595 * @param payload message to transmit
504 * @param payload_length number of bytes in payload 596 * @param payload_length number of bytes in payload
505 * @param desc descriptor to add 597 * @param desc descriptor to add before payload (optional)
506 * @param mtype message type to use 598 * @param mtype message type to use
507 */ 599 */
508static void 600static void
@@ -512,8 +604,8 @@ send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
512 const GNUNET_HashCode *desc, 604 const GNUNET_HashCode *desc,
513 uint16_t mtype) 605 uint16_t mtype)
514{ 606{
515 struct tunnel_state *s; 607 struct TunnelState *s;
516 struct tunnel_notify_queue *tnq; 608 struct TunnelMessageQueue *tnq;
517 struct GNUNET_MessageHeader *msg; 609 struct GNUNET_MessageHeader *msg;
518 size_t len; 610 size_t len;
519 GNUNET_HashCode *dp; 611 GNUNET_HashCode *dp;
@@ -524,15 +616,22 @@ send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
524 GNUNET_break (0); 616 GNUNET_break (0);
525 return; 617 return;
526 } 618 }
527 tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + len); 619 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + len);
528 tnq->payload = &tnq[1]; 620 tnq->payload = &tnq[1];
529 tnq->len = len; 621 tnq->len = len;
530 msg = (struct GNUNET_MessageHeader *) &tnq[1]; 622 msg = (struct GNUNET_MessageHeader *) &tnq[1];
531 msg->size = htons ((uint16_t) len); 623 msg->size = htons ((uint16_t) len);
532 msg->type = htons (mtype); 624 msg->type = htons (mtype);
533 dp = (GNUNET_HashCode *) &msg[1]; 625 if (NULL != desc)
534 *dp = *desc; 626 {
535 memcpy (&dp[1], payload, payload_length); 627 dp = (GNUNET_HashCode *) &msg[1];
628 *dp = *desc;
629 memcpy (&dp[1], payload, payload_length);
630 }
631 else
632 {
633 memcpy (&msg[1], payload, payload_length);
634 }
536 s = GNUNET_MESH_tunnel_get_data (mesh_tunnel); 635 s = GNUNET_MESH_tunnel_get_data (mesh_tunnel);
537 GNUNET_assert (NULL != s); 636 GNUNET_assert (NULL != s);
538 GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq); 637 GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq);
@@ -546,68 +645,24 @@ send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
546 645
547 646
548/** 647/**
549 * Get our connection tracking state. Warns if it does not exists,
550 * refreshes the timestamp if it does exist.
551 *
552 * @param af address family
553 * @param protocol IPPROTO_UDP or IPPROTO_TCP
554 * @param destination_ip target IP
555 * @param destination_port target port
556 * @param source_port source port
557 * @return NULL if we have no tracking information for this tuple
558 */
559static struct redirect_state *
560get_redirect_state (int af,
561 int protocol,
562 const void *destination_ip,
563 uint16_t destination_port,
564 uint16_t source_port)
565{
566 struct redirect_info ri;
567 GNUNET_HashCode state_key;
568 struct redirect_state *state;
569
570 ri.remote_address.af = af;
571 if (af == AF_INET)
572 ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
573 else
574 ri.remote_address.address.ipv6 = * ((struct in6_addr*) destination_ip);
575 ri.remote_address.port = destination_port;
576 ri.remote_address.proto = IPPROTO_UDP;
577 ri.source_port = source_port;
578
579 hash_redirect_info (&state_key, &ri);
580 state = GNUNET_CONTAINER_multihashmap_get (connections_map, &state_key);
581 if (NULL == state)
582 {
583 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
584 _("Packet dropped, have no matching connection information\n"));
585 return NULL;
586 }
587 /* Mark this connection as freshly used */
588 GNUNET_CONTAINER_heap_update_cost (connections_heap,
589 state->heap_node,
590 GNUNET_TIME_absolute_get ().abs_value);
591 return state;
592}
593
594
595/**
596 * @brief Handles an UDP packet received from the helper. 648 * @brief Handles an UDP packet received from the helper.
597 * 649 *
598 * @param udp A pointer to the Packet 650 * @param udp A pointer to the Packet
599 * @param pktlen number of bytes in 'udp' 651 * @param pktlen number of bytes in 'udp'
600 * @param destination_ip destination IP-address
601 * @param af address family (AFINET or AF_INET6) 652 * @param af address family (AFINET or AF_INET6)
653 * @param destination_ip destination IP-address of the IP packet (should
654 * be our local address)
655 * @param source_ip original source IP-address of the IP packet (should
656 * be the original destination address)
602 */ 657 */
603static void 658static void
604udp_from_helper (const struct udp_packet *udp, 659udp_from_helper (const struct udp_packet *udp,
605 size_t pktlen, 660 size_t pktlen,
606 const void *destination_ip, int af) 661 int af,
662 const void *destination_ip,
663 const void *source_ip)
607{ 664{
608 struct redirect_state *state; 665 struct TunnelState *state;
609 struct GNUNET_MESH_Tunnel *tunnel;
610 GNUNET_HashCode desc;
611 666
612 if (pktlen < sizeof (struct udp_packet)) 667 if (pktlen < sizeof (struct udp_packet))
613 { 668 {
@@ -622,60 +677,20 @@ udp_from_helper (const struct udp_packet *udp,
622 return; 677 return;
623 } 678 }
624 state = get_redirect_state (af, IPPROTO_UDP, 679 state = get_redirect_state (af, IPPROTO_UDP,
680 source_ip,
681 ntohs (udp->spt),
625 destination_ip, 682 destination_ip,
626 ntohs (udp->dpt), 683 ntohs (udp->dpt),
627 ntohs (udp->spt)); 684 NULL);
628 if (NULL == state) 685 if (NULL == state)
629 return;
630 tunnel = state->tunnel;
631
632 // FIXME...
633#if 0
634 if (state->type == SERVICE)
635 { 686 {
636 /* check if spt == serv.remote if yes: set spt = serv.myport ("nat") */ 687 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
637 if (ntohs (udp->spt) == state->serv->remote_port) 688 _("Packet dropped, have no matching connection information\n"));
638 { 689 return;
639 udp->spt = htons (state->serv->my_port);
640 }
641 else
642 {
643 /* otherwise the answer came from a different port (tftp does this)
644 * add this new port to the list of all services, so that the packets
645 * coming back from the client to this new port will be routed correctly
646 */
647 struct redirect_service *serv =
648 GNUNET_malloc (sizeof (struct redirect_service));
649 memcpy (serv, state->serv, sizeof (struct redirect_service));
650 serv->my_port = ntohs (udp->spt);
651 serv->remote_port = ntohs (udp->spt);
652 uint16_t *desc = alloca (sizeof (GNUNET_HashCode) + 2);
653
654 memcpy ((GNUNET_HashCode *) (desc + 1), &state->desc,
655 sizeof (GNUNET_HashCode));
656 *desc = ntohs (udp->spt);
657 GNUNET_assert (GNUNET_OK ==
658 GNUNET_CONTAINER_multihashmap_put (udp_services,
659 (GNUNET_HashCode *)
660 desc, serv,
661 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
662
663 state->serv = serv;
664 }
665 } 690 }
666 691 send_packet_to_mesh_tunnel (state->tunnel,
667 if (state->type == SERVICE) 692 &udp[1], pktlen - sizeof (struct udp_packet),
668 memcpy (&desc, &state->desc, sizeof (GNUNET_HashCode)); 693 NULL,
669 else
670 memcpy (&desc, &state->remote, sizeof (struct remote_addr));
671#else
672 memset (&desc, 0, sizeof (desc));
673#endif
674
675 /* send udp-packet back */
676 send_packet_to_mesh_tunnel (tunnel,
677 udp, pktlen,
678 &desc,
679 state->serv != NULL 694 state->serv != NULL
680 ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK 695 ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK
681 : GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK); 696 : GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK);
@@ -687,17 +702,22 @@ udp_from_helper (const struct udp_packet *udp,
687 * 702 *
688 * @param tcp A pointer to the Packet 703 * @param tcp A pointer to the Packet
689 * @param pktlen the length of the packet, including its header 704 * @param pktlen the length of the packet, including its header
690 * @param destination_ip destination IP-address
691 * @param af address family (AFINET or AF_INET6) 705 * @param af address family (AFINET or AF_INET6)
706 * @param destination_ip destination IP-address of the IP packet (should
707 * be our local address)
708 * @param source_ip original source IP-address of the IP packet (should
709 * be the original destination address)
692 */ 710 */
693static void 711static void
694tcp_from_helper (const struct tcp_packet *tcp, 712tcp_from_helper (const struct tcp_packet *tcp,
695 size_t pktlen, 713 size_t pktlen,
696 const void *destination_ip, int af) 714 int af,
715 const void *destination_ip,
716 const void *source_ip)
697{ 717{
698 struct redirect_state *state; 718 struct TunnelState *state;
699 struct GNUNET_MESH_Tunnel *tunnel; 719 char buf[pktlen];
700 GNUNET_HashCode desc; 720 struct tcp_packet *mtcp;
701 721
702 if (pktlen < sizeof (struct tcp_packet)) 722 if (pktlen < sizeof (struct tcp_packet))
703 { 723 {
@@ -706,42 +726,28 @@ tcp_from_helper (const struct tcp_packet *tcp,
706 return; 726 return;
707 } 727 }
708 state = get_redirect_state (af, IPPROTO_TCP, 728 state = get_redirect_state (af, IPPROTO_TCP,
709 destination_ip, 729 source_ip,
730 ntohs (tcp->spt),
731 destination_ip,
710 ntohs (tcp->dpt), 732 ntohs (tcp->dpt),
711 ntohs (tcp->spt)); 733 NULL);
712 if (NULL == state) 734 if (NULL == state)
713 return;
714 tunnel = state->tunnel;
715
716 // FIXME...
717#if 0
718 if (state->type == SERVICE)
719 { 735 {
720 /* check if spt == serv.remote if yes: set spt = serv.myport ("nat") */ 736 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
721 if (ntohs (tcp->spt) == state->serv->remote_port) 737 _("Packet dropped, have no matching connection information\n"));
722 { 738
723 tcp->spt = htons (state->serv->my_port); 739 return;
724 }
725 else
726 {
727 // This is an illegal packet.
728 return;
729 }
730 } 740 }
731 741 /* mug port numbers and crc to avoid information leakage;
732 /* send tcp-packet back */ 742 sender will need to lookup the correct values anyway */
733 if (state->type == SERVICE) 743 memcpy (buf, tcp, pktlen);
734 memcpy (&desc, &state->desc, sizeof (GNUNET_HashCode)); 744 mtcp = (struct tcp_packet *) buf;
735 else 745 mtcp->spt = 0;
736 memcpy (&desc, &state->remote, sizeof (struct remote_addr)); 746 mtcp->dpt = 0;
737#else 747 mtcp->crc = 0;
738 memset (&desc, 0, sizeof (desc)); 748 send_packet_to_mesh_tunnel (state->tunnel,
739#endif 749 mtcp, pktlen,
740 750 NULL,
741
742 send_packet_to_mesh_tunnel (tunnel,
743 tcp, pktlen,
744 &desc,
745 state->serv != NULL 751 state->serv != NULL
746 ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK 752 ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK
747 : GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK); 753 : GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK);
@@ -798,14 +804,16 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
798 switch (pkt6->next_header) 804 switch (pkt6->next_header)
799 { 805 {
800 case IPPROTO_UDP: 806 case IPPROTO_UDP:
801 udp_from_helper ( (const struct udp_packet *) &pkt6[1], size, 807 udp_from_helper ((const struct udp_packet *) &pkt6[1], size,
802 &pkt6->destination_address, 808 AF_INET6,
803 AF_INET6); 809 &pkt6->destination_address,
810 &pkt6->source_address);
804 break; 811 break;
805 case IPPROTO_TCP: 812 case IPPROTO_TCP:
806 tcp_from_helper ((const struct tcp_packet *) &pkt6[1], size, 813 tcp_from_helper ((const struct tcp_packet *) &pkt6[1], size,
814 AF_INET6,
807 &pkt6->destination_address, 815 &pkt6->destination_address,
808 AF_INET6); 816 &pkt6->source_address);
809 break; 817 break;
810 default: 818 default:
811 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 819 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -842,11 +850,14 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
842 { 850 {
843 case IPPROTO_UDP: 851 case IPPROTO_UDP:
844 udp_from_helper ((const struct udp_packet *) &pkt4[1], size, 852 udp_from_helper ((const struct udp_packet *) &pkt4[1], size,
845 &pkt4->destination_address, AF_INET); 853 AF_INET,
846 break; 854 &pkt4->destination_address,
855 &pkt4->source_address);
847 case IPPROTO_TCP: 856 case IPPROTO_TCP:
848 tcp_from_helper ((const struct tcp_packet *) &pkt4[1], size, 857 tcp_from_helper ((const struct tcp_packet *) &pkt4[1], size,
849 &pkt4->destination_address, AF_INET); 858 AF_INET,
859 &pkt4->destination_address,
860 &pkt4->source_address);
850 break; 861 break;
851 default: 862 default:
852 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 863 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -866,10 +877,15 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
866 877
867 878
868 879
880
881
869void 882void
870prepare_ipv4_packet (size_t len, uint16_t pktlen, void *payload, 883prepare_ipv4_packet (size_t len,
871 uint8_t protocol, void *ipaddress, void *tunnel, 884 uint16_t pktlen, void *payload,
872 struct redirect_info *state, struct ip4_header *pkt4) 885 uint8_t protocol,
886 void *ipaddress, void *tunnel,
887 struct RedirectInformation *
888 state, struct ip4_header *pkt4)
873{ 889{
874 const char *ipv4addr = exit_argv[4]; 890 const char *ipv4addr = exit_argv[4];
875 const char *ipv4mask = exit_argv[5]; 891 const char *ipv4mask = exit_argv[5];
@@ -938,7 +954,7 @@ prepare_ipv4_packet (size_t len, uint16_t pktlen, void *payload,
938void 954void
939prepare_ipv6_packet (size_t len, uint16_t pktlen, void *payload, 955prepare_ipv6_packet (size_t len, uint16_t pktlen, void *payload,
940 uint16_t protocol, void *ipaddress, void *tunnel, 956 uint16_t protocol, void *ipaddress, void *tunnel,
941 struct redirect_info *state, struct ip6_header *pkt6) 957 struct RedirectInformation *state, struct ip6_header *pkt6)
942{ 958{
943 const char *ipv6addr = exit_argv[2]; 959 const char *ipv6addr = exit_argv[2];
944 uint32_t tmp; 960 uint32_t tmp;
@@ -1032,12 +1048,12 @@ prepare_ipv6_packet (size_t len, uint16_t pktlen, void *payload,
1032 * @param serv service information 1048 * @param serv service information
1033 */ 1049 */
1034void 1050void
1035update_state_map (const struct redirect_info *ri, 1051update_state_map (const struct RedirectInformation *ri,
1036 struct GNUNET_MESH_Tunnel *tunnel, 1052 struct GNUNET_MESH_Tunnel *tunnel,
1037 const GNUNET_HashCode *desc, 1053 const GNUNET_HashCode *desc,
1038 struct redirect_service *serv) 1054 struct LocalService *serv)
1039{ 1055{
1040 struct redirect_state *state; 1056 struct TunnelState *state;
1041 GNUNET_HashCode state_key; 1057 GNUNET_HashCode state_key;
1042 1058
1043 hash_redirect_info (&state_key, 1059 hash_redirect_info (&state_key,
@@ -1045,7 +1061,7 @@ update_state_map (const struct redirect_info *ri,
1045 state = GNUNET_CONTAINER_multihashmap_get (connections_map, &state_key); 1061 state = GNUNET_CONTAINER_multihashmap_get (connections_map, &state_key);
1046 if (NULL == state) 1062 if (NULL == state)
1047 { 1063 {
1048 state = GNUNET_malloc (sizeof (struct redirect_state)); 1064 state = GNUNET_malloc (sizeof (struct TunnelState));
1049 state->tunnel = tunnel; 1065 state->tunnel = tunnel;
1050 state->state_key = state_key; 1066 state->state_key = state_key;
1051 state->serv = serv; 1067 state->serv = serv;
@@ -1102,8 +1118,8 @@ receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunn
1102 const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1]; 1118 const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1103 const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1]; 1119 const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1];
1104 uint16_t pkt_len = ntohs (message->size); 1120 uint16_t pkt_len = ntohs (message->size);
1105 struct redirect_service *serv; 1121 struct LocalService *serv;
1106 struct redirect_info u_i; 1122 struct RedirectInformation u_i;
1107 GNUNET_HashCode state_key; 1123 GNUNET_HashCode state_key;
1108 1124
1109 /* check that we got at least a valid header */ 1125 /* check that we got at least a valid header */
@@ -1209,7 +1225,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1209 ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - 1225 ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1210 sizeof (GNUNET_HashCode); 1226 sizeof (GNUNET_HashCode);
1211 1227
1212 struct redirect_state *state = GNUNET_malloc (sizeof (struct redirect_state)); 1228 struct TunnelState *state = GNUNET_malloc (sizeof (struct TunnelState));
1213 1229
1214 state->tunnel = tunnel; 1230 state->tunnel = tunnel;
1215 state->type = REMOTE; 1231 state->type = REMOTE;
@@ -1292,7 +1308,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1292 * This will be saved in the hashmap, so that the receiving procedure knows 1308 * This will be saved in the hashmap, so that the receiving procedure knows
1293 * through which tunnel this connection has to be routed. 1309 * through which tunnel this connection has to be routed.
1294 */ 1310 */
1295 struct redirect_state *state = GNUNET_malloc (sizeof (struct redirect_state)); 1311 struct TunnelState *state = GNUNET_malloc (sizeof (struct TunnelState));
1296 1312
1297 state->tunnel = tunnel; 1313 state->tunnel = tunnel;
1298 state->hashmap = udp_connections; 1314 state->hashmap = udp_connections;
@@ -1349,6 +1365,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1349 return GNUNET_YES; 1365 return GNUNET_YES;
1350} 1366}
1351 1367
1368
1352/** 1369/**
1353 * The messages are one GNUNET_HashCode for the service, followed by a struct udp_packet 1370 * The messages are one GNUNET_HashCode for the service, followed by a struct udp_packet
1354 */ 1371 */
@@ -1361,10 +1378,14 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1361{ 1378{
1362 // FIXME 1379 // FIXME
1363#if 0 1380#if 0
1364 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); 1381 const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1365 struct udp_packet *pkt = (struct udp_packet *) (desc + 1); 1382 const struct udp_packet *pkt = (const struct udp_packet *) &desc[1];
1366 uint16_t pkt_len = ntohs (message->size); 1383 uint16_t pkt_len = ntohs (message->size);
1367 struct redirect_service *serv; 1384 struct LocalService *serv;
1385 struct TunnelState *state;
1386 struct tunnel_state *s;
1387 char *buf;
1388 size_t len;
1368 1389
1369 /* check that we got at least a valid header */ 1390 /* check that we got at least a valid header */
1370 if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet)) 1391 if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet))
@@ -1388,18 +1409,17 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1388 } 1409 }
1389 pkt->dpt = htons (serv->remote_port); 1410 pkt->dpt = htons (serv->remote_port);
1390 1411
1391 /* 1412 /* At this point it would be possible to check against some kind of ACL. */
1392 * At this point it would be possible to check against some kind of ACL. 1413
1393 */ 1414 s = GNUNET_MESH_tunnel_get_data (tunnel);
1394 1415
1395 char *buf;
1396 size_t len;
1397 1416
1398 /* Prepare the state. 1417 /* Prepare the state.
1399 * This will be saved in the hashmap, so that the receiving procedure knows 1418 * This will be saved in the hashmap, so that the receiving procedure knows
1400 * through which tunnel this connection has to be routed. 1419 * through which tunnel this connection has to be routed.
1401 */ 1420 */
1402 struct redirect_state *state = GNUNET_malloc (sizeof (struct redirect_state)); 1421
1422 state = GNUNET_malloc (sizeof (struct TunnelState));
1403 1423
1404 state->tunnel = tunnel; 1424 state->tunnel = tunnel;
1405 state->serv = serv; 1425 state->serv = serv;
@@ -1480,7 +1500,7 @@ new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1480 const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED, 1500 const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED,
1481 const struct GNUNET_ATS_Information *ats GNUNET_UNUSED) 1501 const struct GNUNET_ATS_Information *ats GNUNET_UNUSED)
1482{ 1502{
1483 struct tunnel_state *s = GNUNET_malloc (sizeof (struct tunnel_state)); 1503 struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState));
1484 1504
1485 s->tunnel = tunnel; 1505 s->tunnel = tunnel;
1486 return s; 1506 return s;
@@ -1500,8 +1520,8 @@ static void
1500clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel, 1520clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
1501 void *tunnel_ctx) 1521 void *tunnel_ctx)
1502{ 1522{
1503 struct tunnel_state *s = tunnel_ctx; 1523 struct TunnelState *s = tunnel_ctx;
1504 struct tunnel_notify_queue *tnq; 1524 struct TunnelMessageQueue *tnq;
1505 1525
1506 while (NULL != (tnq = s->head)) 1526 while (NULL != (tnq = s->head))
1507 { 1527 {
@@ -1510,6 +1530,15 @@ clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
1510 tnq); 1530 tnq);
1511 GNUNET_free (tnq); 1531 GNUNET_free (tnq);
1512 } 1532 }
1533 if (s->heap_node != NULL)
1534 {
1535 GNUNET_assert (GNUNET_YES ==
1536 GNUNET_CONTAINER_multihashmap_remove (connections_map,
1537 &s->state_key,
1538 s));
1539 GNUNET_CONTAINER_heap_remove_node (s->heap_node);
1540 s->heap_node = NULL;
1541 }
1513 if (NULL != s->th) 1542 if (NULL != s->th)
1514 { 1543 {
1515 GNUNET_MESH_notify_transmit_ready_cancel (s->th); 1544 GNUNET_MESH_notify_transmit_ready_cancel (s->th);
@@ -1597,7 +1626,7 @@ add_services (int proto,
1597 char *redirect; 1626 char *redirect;
1598 char *hostname; 1627 char *hostname;
1599 char *hostport; 1628 char *hostport;
1600 struct redirect_service *serv; 1629 struct LocalService *serv;
1601 1630
1602 for (redirect = strtok (cpy, " "); redirect != NULL; 1631 for (redirect = strtok (cpy, " "); redirect != NULL;
1603 redirect = strtok (NULL, " ")) 1632 redirect = strtok (NULL, " "))
@@ -1641,7 +1670,7 @@ add_services (int proto,
1641 continue; 1670 continue;
1642 } 1671 }
1643 1672
1644 serv = GNUNET_malloc (sizeof (struct redirect_service)); 1673 serv = GNUNET_malloc (sizeof (struct LocalService));
1645 serv->my_port = (uint16_t) local_port; 1674 serv->my_port = (uint16_t) local_port;
1646 serv->address.port = remote_port; 1675 serv->address.port = remote_port;
1647 if (0 == strcmp ("localhost4", hostname)) 1676 if (0 == strcmp ("localhost4", hostname))
@@ -1905,7 +1934,7 @@ main (int argc, char *const *argv)
1905 GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit", 1934 GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
1906 gettext_noop 1935 gettext_noop
1907 ("Daemon to run to provide an IP exit node for the VPN"), 1936 ("Daemon to run to provide an IP exit node for the VPN"),
1908 options, &run, NULL)) ? ret : 1; 1937 options, &run, NULL)) ? 0 : 1;
1909} 1938}
1910 1939
1911 1940