diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-07 23:28:50 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-07 23:28:50 +0000 |
commit | 6429f7e56bcbe50863e05e284c0174f252ca1d5b (patch) | |
tree | cbbda488c9f59e9202fa32814f19c4049bd10a0c /src | |
parent | c2df6481757fd97c9580d8a12d2ffa9489c3be91 (diff) | |
download | gnunet-6429f7e56bcbe50863e05e284c0174f252ca1d5b.tar.gz gnunet-6429f7e56bcbe50863e05e284c0174f252ca1d5b.zip |
-also handle client service redirection requests
Diffstat (limited to 'src')
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 165 |
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 | |||
1391 | service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client, | 1406 | service_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 | ||