[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r19062 - gnunet/src/vpn
From: |
gnunet |
Subject: |
[GNUnet-SVN] r19062 - gnunet/src/vpn |
Date: |
Sun, 8 Jan 2012 00:28:50 +0100 |
Author: grothoff
Date: 2012-01-08 00:28:50 +0100 (Sun, 08 Jan 2012)
New Revision: 19062
Modified:
gnunet/src/vpn/gnunet-service-vpn.c
Log:
-also handle client service redirection requests
Modified: gnunet/src/vpn/gnunet-service-vpn.c
===================================================================
--- gnunet/src/vpn/gnunet-service-vpn.c 2012-01-07 23:20:11 UTC (rev 19061)
+++ gnunet/src/vpn/gnunet-service-vpn.c 2012-01-07 23:28:50 UTC (rev 19062)
@@ -71,38 +71,53 @@
* GNUNET_YES if this tunnel is to a service.
*/
int is_service;
-
- /**
- * Address family used (AF_INET or AF_INET6).
- */
- int af;
/**
* Details about the connection (depending on is_service).
*/
union
{
- /**
- * The description of the service (only used for service tunnels).
- */
- GNUNET_HashCode desc;
- /**
- * IP address of the ultimate destination (only used for exit tunnels).
- */
- union
+ struct
{
/**
- * Address if af is AF_INET.
+ * The description of the service (only used for service tunnels).
*/
- struct in_addr v4;
+ GNUNET_HashCode service_descriptor;
/**
- * Address if af is AF_INET6.
+ * Peer offering the service.
*/
- struct in6_addr v6;
- } ip;
+ struct GNUNET_PeerIdentity target;
+ } service_destination;
+
+ struct
+ {
+
+ /**
+ * Address family used (AF_INET or AF_INET6).
+ */
+ int af;
+
+ /**
+ * IP address of the ultimate destination (only used for exit tunnels).
+ */
+ union
+ {
+ /**
+ * Address if af is AF_INET.
+ */
+ struct in_addr v4;
+
+ /**
+ * Address if af is AF_INET6.
+ */
+ struct in6_addr v6;
+ } ip;
+
+ } exit_destination;
+
} details;
};
@@ -1335,8 +1350,8 @@
/* setup destination record */
de = GNUNET_malloc (sizeof (struct DestinationEntry));
de->is_service = GNUNET_NO;
- de->af = addr_af;
- memcpy (&de->details.ip,
+ de->details.exit_destination.af = addr_af;
+ memcpy (&de->details.exit_destination.ip,
&msg[1],
alen);
get_destination_key_from_ip (result_af,
@@ -1391,8 +1406,114 @@
service_redirect_to_service (void *cls GNUNET_UNUSED, struct
GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- // FIXME!
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ const struct RedirectToServiceRequestMessage *msg;
+ int result_af;
+ struct in_addr v4;
+ struct in6_addr v6;
+ void *addr;
+ struct DestinationEntry *de;
+ GNUNET_HashCode key;
+ struct TunnelState *ts;
+
+ /* parse request */
+ msg = (const struct RedirectToServiceRequestMessage *) message;
+
+ /* allocate response IP */
+ addr = NULL;
+ result_af = (int) htonl (msg->result_af);
+ switch (result_af)
+ {
+ case AF_INET:
+ if (GNUNET_OK !=
+ allocate_v4_address (&v4))
+ result_af = AF_UNSPEC;
+ else
+ addr = &v4;
+ break;
+ case AF_INET6:
+ if (GNUNET_OK !=
+ allocate_v6_address (&v6))
+ result_af = AF_UNSPEC;
+ else
+ addr = &v6;
+ break;
+ case AF_UNSPEC:
+ if (GNUNET_OK ==
+ allocate_v4_address (&v4))
+ {
+ addr = &v4;
+ result_af = AF_INET;
+ }
+ else if (GNUNET_OK ==
+ allocate_v6_address (&v6))
+ {
+ addr = &v6;
+ result_af = AF_INET6;
+ }
+ break;
+ default:
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ if ( (result_af == AF_UNSPEC) ||
+ (GNUNET_NO == ntohl (msg->nac)) )
+ {
+ /* send reply "instantly" */
+ send_client_reply (client,
+ msg->request_id,
+ result_af,
+ addr);
+ }
+ if (result_af == AF_UNSPEC)
+ {
+ /* failure, we're done */
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ /* setup destination record */
+ de = GNUNET_malloc (sizeof (struct DestinationEntry));
+ de->is_service = GNUNET_YES;
+ de->details.service_destination.service_descriptor = msg->service_descriptor;
+ de->details.service_destination.target = msg->target;
+ get_destination_key_from_ip (result_af,
+ addr,
+ &key);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap_put (destination_map,
+ &key,
+ de,
+
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
+ de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
+ de,
+ GNUNET_TIME_absolute_ntoh
(msg->expiration_time).abs_value);
+
+ /* setup tunnel to destination */
+ ts = GNUNET_malloc (sizeof (struct TunnelState));
+ if (GNUNET_NO != ntohl (msg->nac))
+ {
+ ts->request_id = msg->request_id;
+ ts->client = client;
+ GNUNET_SERVER_client_keep (client);
+ }
+ ts->destination = *de;
+ ts->destination.heap_node = NULL;
+ ts->is_service = GNUNET_YES;
+ ts->af = result_af;
+ if (result_af == AF_INET)
+ ts->destination_ip.v4 = v4;
+ else
+ ts->destination_ip.v6 = v6;
+ de->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
+ ts,
+ &tunnel_peer_connect_handler,
+ &tunnel_peer_disconnect_handler,
+ ts);
+ GNUNET_MESH_peer_request_connect_add (de->tunnel,
+ &msg->target);
+ /* we're done */
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r19062 - gnunet/src/vpn,
gnunet <=