aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-07 23:28:50 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-07 23:28:50 +0000
commit6429f7e56bcbe50863e05e284c0174f252ca1d5b (patch)
treecbbda488c9f59e9202fa32814f19c4049bd10a0c /src
parentc2df6481757fd97c9580d8a12d2ffa9489c3be91 (diff)
downloadgnunet-6429f7e56bcbe50863e05e284c0174f252ca1d5b.tar.gz
gnunet-6429f7e56bcbe50863e05e284c0174f252ca1d5b.zip
-also handle client service redirection requests
Diffstat (limited to 'src')
-rw-r--r--src/vpn/gnunet-service-vpn.c165
1 files changed, 143 insertions, 22 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index a1848728b..5ad5ff1db 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -71,37 +71,52 @@ struct DestinationEntry
71 * GNUNET_YES if this tunnel is to a service. 71 * GNUNET_YES if this tunnel is to a service.
72 */ 72 */
73 int is_service; 73 int is_service;
74
75 /**
76 * Address family used (AF_INET or AF_INET6).
77 */
78 int af;
79 74
80 /** 75 /**
81 * Details about the connection (depending on is_service). 76 * Details about the connection (depending on is_service).
82 */ 77 */
83 union 78 union
84 { 79 {
85 /**
86 * The description of the service (only used for service tunnels).
87 */
88 GNUNET_HashCode desc;
89 80
90 /** 81 struct
91 * IP address of the ultimate destination (only used for exit tunnels).
92 */
93 union
94 { 82 {
95 /** 83 /**
96 * Address if af is AF_INET. 84 * The description of the service (only used for service tunnels).
97 */ 85 */
98 struct in_addr v4; 86 GNUNET_HashCode service_descriptor;
99 87
100 /** 88 /**
101 * Address if af is AF_INET6. 89 * Peer offering the service.
90 */
91 struct GNUNET_PeerIdentity target;
92
93 } service_destination;
94
95 struct
96 {
97
98 /**
99 * Address family used (AF_INET or AF_INET6).
100 */
101 int af;
102
103 /**
104 * IP address of the ultimate destination (only used for exit tunnels).
102 */ 105 */
103 struct in6_addr v6; 106 union
104 } ip; 107 {
108 /**
109 * Address if af is AF_INET.
110 */
111 struct in_addr v4;
112
113 /**
114 * Address if af is AF_INET6.
115 */
116 struct in6_addr v6;
117 } ip;
118
119 } exit_destination;
105 120
106 } details; 121 } details;
107 122
@@ -1335,8 +1350,8 @@ service_redirect_to_ip (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *cl
1335 /* setup destination record */ 1350 /* setup destination record */
1336 de = GNUNET_malloc (sizeof (struct DestinationEntry)); 1351 de = GNUNET_malloc (sizeof (struct DestinationEntry));
1337 de->is_service = GNUNET_NO; 1352 de->is_service = GNUNET_NO;
1338 de->af = addr_af; 1353 de->details.exit_destination.af = addr_af;
1339 memcpy (&de->details.ip, 1354 memcpy (&de->details.exit_destination.ip,
1340 &msg[1], 1355 &msg[1],
1341 alen); 1356 alen);
1342 get_destination_key_from_ip (result_af, 1357 get_destination_key_from_ip (result_af,
@@ -1391,8 +1406,114 @@ static void
1391service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client, 1406service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client,
1392 const struct GNUNET_MessageHeader *message) 1407 const struct GNUNET_MessageHeader *message)
1393{ 1408{
1394 // FIXME! 1409 const struct RedirectToServiceRequestMessage *msg;
1395 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1410 int result_af;
1411 struct in_addr v4;
1412 struct in6_addr v6;
1413 void *addr;
1414 struct DestinationEntry *de;
1415 GNUNET_HashCode key;
1416 struct TunnelState *ts;
1417
1418 /* parse request */
1419 msg = (const struct RedirectToServiceRequestMessage *) message;
1420
1421 /* allocate response IP */
1422 addr = NULL;
1423 result_af = (int) htonl (msg->result_af);
1424 switch (result_af)
1425 {
1426 case AF_INET:
1427 if (GNUNET_OK !=
1428 allocate_v4_address (&v4))
1429 result_af = AF_UNSPEC;
1430 else
1431 addr = &v4;
1432 break;
1433 case AF_INET6:
1434 if (GNUNET_OK !=
1435 allocate_v6_address (&v6))
1436 result_af = AF_UNSPEC;
1437 else
1438 addr = &v6;
1439 break;
1440 case AF_UNSPEC:
1441 if (GNUNET_OK ==
1442 allocate_v4_address (&v4))
1443 {
1444 addr = &v4;
1445 result_af = AF_INET;
1446 }
1447 else if (GNUNET_OK ==
1448 allocate_v6_address (&v6))
1449 {
1450 addr = &v6;
1451 result_af = AF_INET6;
1452 }
1453 break;
1454 default:
1455 GNUNET_break (0);
1456 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1457 return;
1458 }
1459 if ( (result_af == AF_UNSPEC) ||
1460 (GNUNET_NO == ntohl (msg->nac)) )
1461 {
1462 /* send reply "instantly" */
1463 send_client_reply (client,
1464 msg->request_id,
1465 result_af,
1466 addr);
1467 }
1468 if (result_af == AF_UNSPEC)
1469 {
1470 /* failure, we're done */
1471 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1472 return;
1473 }
1474
1475 /* setup destination record */
1476 de = GNUNET_malloc (sizeof (struct DestinationEntry));
1477 de->is_service = GNUNET_YES;
1478 de->details.service_destination.service_descriptor = msg->service_descriptor;
1479 de->details.service_destination.target = msg->target;
1480 get_destination_key_from_ip (result_af,
1481 addr,
1482 &key);
1483 GNUNET_assert (GNUNET_OK ==
1484 GNUNET_CONTAINER_multihashmap_put (destination_map,
1485 &key,
1486 de,
1487 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1488 de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
1489 de,
1490 GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value);
1491
1492 /* setup tunnel to destination */
1493 ts = GNUNET_malloc (sizeof (struct TunnelState));
1494 if (GNUNET_NO != ntohl (msg->nac))
1495 {
1496 ts->request_id = msg->request_id;
1497 ts->client = client;
1498 GNUNET_SERVER_client_keep (client);
1499 }
1500 ts->destination = *de;
1501 ts->destination.heap_node = NULL;
1502 ts->is_service = GNUNET_YES;
1503 ts->af = result_af;
1504 if (result_af == AF_INET)
1505 ts->destination_ip.v4 = v4;
1506 else
1507 ts->destination_ip.v6 = v6;
1508 de->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
1509 ts,
1510 &tunnel_peer_connect_handler,
1511 &tunnel_peer_disconnect_handler,
1512 ts);
1513 GNUNET_MESH_peer_request_connect_add (de->tunnel,
1514 &msg->target);
1515 /* we're done */
1516 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1396} 1517}
1397 1518
1398 1519