aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-10 15:13:41 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-10 15:13:41 +0000
commit4cd9ad92ad6131400e52dc1f25516b4134150aef (patch)
tree3288a2d18903a2b17b1b5b2c067e52985d5d9577
parentd2c214f97316f90f0242a0921fb4f060313c6c18 (diff)
downloadgnunet-4cd9ad92ad6131400e52dc1f25516b4134150aef.tar.gz
gnunet-4cd9ad92ad6131400e52dc1f25516b4134150aef.zip
-dealing with new TCP message formats
-rw-r--r--src/exit/exit.h2
-rw-r--r--src/exit/gnunet-daemon-exit.c168
2 files changed, 107 insertions, 63 deletions
diff --git a/src/exit/exit.h b/src/exit/exit.h
index 1e92cc501..37ae7e8a4 100644
--- a/src/exit/exit.h
+++ b/src/exit/exit.h
@@ -108,7 +108,7 @@ struct GNUNET_EXIT_TcpDataMessage
108 108
109 /** 109 /**
110 * Skeleton of the TCP header to send. Port numbers are to 110 * Skeleton of the TCP header to send. Port numbers are to
111 * be replaced and the checksum may be updated as necessary. 111 * be replaced and the checksum may be updated as necessary. (The destination port number should not be changed, as it contains the desired destination port.)
112 */ 112 */
113 struct tcp_packet tcp_header; 113 struct tcp_packet tcp_header;
114 114
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index eecc26aeb..e5d471b2f 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -971,6 +971,7 @@ setup_state_record (struct TunnelState *state)
971static void 971static void
972prepare_ipv4_packet (const void *payload, size_t payload_length, 972prepare_ipv4_packet (const void *payload, size_t payload_length,
973 int protocol, 973 int protocol,
974 const struct tcp_packet *tcp_header,
974 const struct SocketAddress *src_address, 975 const struct SocketAddress *src_address,
975 const struct SocketAddress *dst_address, 976 const struct SocketAddress *dst_address,
976 struct ip4_header *pkt4) 977 struct ip4_header *pkt4)
@@ -984,12 +985,8 @@ prepare_ipv4_packet (const void *payload, size_t payload_length,
984 len += sizeof (struct udp_packet); 985 len += sizeof (struct udp_packet);
985 break; 986 break;
986 case IPPROTO_TCP: 987 case IPPROTO_TCP:
987 /* tcp_header (with port/crc not set) must be part of payload! */ 988 len += sizeof (struct tcp_packet);
988 if (len < sizeof (struct tcp_packet)) 989 GNUNET_assert (NULL != tcp_header);
989 {
990 GNUNET_break (0);
991 return;
992 }
993 break; 990 break;
994 default: 991 default:
995 GNUNET_break (0); 992 GNUNET_break (0);
@@ -1033,7 +1030,8 @@ prepare_ipv4_packet (const void *payload, size_t payload_length,
1033 { 1030 {
1034 struct tcp_packet *pkt4_tcp = (struct tcp_packet *) &pkt4[1]; 1031 struct tcp_packet *pkt4_tcp = (struct tcp_packet *) &pkt4[1];
1035 1032
1036 memcpy (pkt4_tcp, payload, payload_length); 1033 memcpy (pkt4_tcp, tcp_header, sizeof (struct tcp_packet));
1034 memcpy (&pkt4_tcp[1], payload, payload_length);
1037 pkt4_tcp->spt = htons (src_address->port); 1035 pkt4_tcp->spt = htons (src_address->port);
1038 pkt4_tcp->dpt = htons (dst_address->port); 1036 pkt4_tcp->dpt = htons (dst_address->port);
1039 pkt4_tcp->crc = 0; 1037 pkt4_tcp->crc = 0;
@@ -1073,6 +1071,7 @@ prepare_ipv4_packet (const void *payload, size_t payload_length,
1073static void 1071static void
1074prepare_ipv6_packet (const void *payload, size_t payload_length, 1072prepare_ipv6_packet (const void *payload, size_t payload_length,
1075 int protocol, 1073 int protocol,
1074 const struct tcp_packet *tcp_header,
1076 const struct SocketAddress *src_address, 1075 const struct SocketAddress *src_address,
1077 const struct SocketAddress *dst_address, 1076 const struct SocketAddress *dst_address,
1078 struct ip6_header *pkt6) 1077 struct ip6_header *pkt6)
@@ -1166,12 +1165,14 @@ prepare_ipv6_packet (const void *payload, size_t payload_length,
1166 * 1165 *
1167 * @param destination_address IP and port to use for the TCP packet's destination 1166 * @param destination_address IP and port to use for the TCP packet's destination
1168 * @param source_address IP and port to use for the TCP packet's source 1167 * @param source_address IP and port to use for the TCP packet's source
1169 * @param payload payload of the IP header (includes TCP header) 1168 * @param tcp header template to use
1169 * @param payload payload of the TCP packet
1170 * @param payload_length number of bytes in 'payload' 1170 * @param payload_length number of bytes in 'payload'
1171 */ 1171 */
1172static void 1172static void
1173send_tcp_packet_via_tun (const struct SocketAddress *destination_address, 1173send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1174 const struct SocketAddress *source_address, 1174 const struct SocketAddress *source_address,
1175 const struct tcp_packet *tcp_header,
1175 const void *payload, size_t payload_length) 1176 const void *payload, size_t payload_length)
1176{ 1177{
1177 size_t len; 1178 size_t len;
@@ -1212,7 +1213,9 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1212 struct ip4_header * ipv4 = (struct ip4_header*) &tun[1]; 1213 struct ip4_header * ipv4 = (struct ip4_header*) &tun[1];
1213 1214
1214 tun->proto = htons (ETH_P_IPV4); 1215 tun->proto = htons (ETH_P_IPV4);
1215 prepare_ipv4_packet (payload, payload_length, IPPROTO_TCP, 1216 prepare_ipv4_packet (payload, payload_length,
1217 IPPROTO_TCP,
1218 tcp_header,
1216 source_address, 1219 source_address,
1217 destination_address, 1220 destination_address,
1218 ipv4); 1221 ipv4);
@@ -1223,7 +1226,9 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1223 struct ip6_header * ipv6 = (struct ip6_header*) &tun[1]; 1226 struct ip6_header * ipv6 = (struct ip6_header*) &tun[1];
1224 1227
1225 tun->proto = htons (ETH_P_IPV6); 1228 tun->proto = htons (ETH_P_IPV6);
1226 prepare_ipv6_packet (payload, payload_length, IPPROTO_TCP, 1229 prepare_ipv6_packet (payload, payload_length,
1230 IPPROTO_TCP,
1231 tcp_header,
1227 source_address, 1232 source_address,
1228 destination_address, 1233 destination_address,
1229 ipv6); 1234 ipv6);
@@ -1242,12 +1247,9 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1242 1247
1243 1248
1244/** 1249/**
1245 * Process a request via mesh to send a request to a UDP service 1250 * Process a request via mesh to send a request to a TCP service
1246 * offered by this system. 1251 * offered by this system.
1247 * 1252 *
1248 * The messages are one GNUNET_HashCode for the service followed by a struct tcp_packet
1249 * (FIXME: this is not great).
1250 *
1251 * @param cls closure, NULL 1253 * @param cls closure, NULL
1252 * @param tunnel connection to the other end 1254 * @param tunnel connection to the other end
1253 * @param tunnel_ctx pointer to our 'struct TunnelState *' 1255 * @param tunnel_ctx pointer to our 'struct TunnelState *'
@@ -1265,38 +1267,41 @@ receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunn
1265 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) 1267 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1266{ 1268{
1267 struct TunnelState *state = *tunnel_ctx; 1269 struct TunnelState *state = *tunnel_ctx;
1268 // FIXME: write proper request struct (we don't need the descriptor EACH time here!) 1270 const struct GNUNET_EXIT_TcpServiceStartMessage *start;
1269 const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1270 const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1];
1271 uint16_t pkt_len = ntohs (message->size); 1271 uint16_t pkt_len = ntohs (message->size);
1272 1272
1273
1274 /* check that we got at least a valid header */ 1273 /* check that we got at least a valid header */
1275 if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet)) 1274 if (pkt_len < sizeof (struct GNUNET_EXIT_TcpServiceStartMessage))
1276 { 1275 {
1277 GNUNET_break_op (0); 1276 GNUNET_break_op (0);
1278 return GNUNET_SYSERR; 1277 return GNUNET_SYSERR;
1279 } 1278 }
1280 pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode)); 1279 start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message;
1281 1280 pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage);
1282 if (NULL == state->serv) 1281 if ( (NULL == state) ||
1282 (NULL != state->serv) ||
1283 (NULL != state->heap_node) )
1283 { 1284 {
1284 /* setup fresh connection */ 1285 GNUNET_break_op (0);
1285 GNUNET_assert (NULL == state->heap_node); 1286 return GNUNET_SYSERR;
1286 if (NULL == (state->serv = find_service (tcp_services, desc, ntohs (pkt->dpt))))
1287 {
1288 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1289 _("No service found for %s on port %d!\n"),
1290 "TCP",
1291 ntohs (pkt->dpt));
1292 return GNUNET_SYSERR;
1293 }
1294 state->ri.remote_address = state->serv->address;
1295 setup_state_record (state);
1296 } 1287 }
1288 GNUNET_break_op (ntohl (start->reserved) == 0);
1289 /* setup fresh connection */
1290 if (NULL == (state->serv = find_service (tcp_services, &start->service_descriptor,
1291 ntohs (start->tcp_header.dpt))))
1292 {
1293 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1294 _("No service found for %s on port %d!\n"),
1295 "TCP",
1296 ntohs (start->tcp_header.dpt));
1297 return GNUNET_SYSERR;
1298 }
1299 state->ri.remote_address = state->serv->address;
1300 setup_state_record (state);
1297 send_tcp_packet_via_tun (&state->ri.remote_address, 1301 send_tcp_packet_via_tun (&state->ri.remote_address,
1298 &state->ri.local_address, 1302 &state->ri.local_address,
1299 pkt, pkt_len); 1303 &start->tcp_header,
1304 &start[1], pkt_len);
1300 return GNUNET_YES; 1305 return GNUNET_YES;
1301} 1306}
1302 1307
@@ -1321,29 +1326,64 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1321 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) 1326 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1322{ 1327{
1323 struct TunnelState *state = *tunnel_ctx; 1328 struct TunnelState *state = *tunnel_ctx;
1324 // FIXME: write proper request struct (!) 1329 const struct GNUNET_EXIT_TcpInternetStartMessage *start;
1325 const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1326 const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1];
1327 const struct SocketAddress *s = (const struct SocketAddress *) desc;
1328 uint16_t pkt_len = ntohs (message->size); 1330 uint16_t pkt_len = ntohs (message->size);
1331 const struct in_addr *v4;
1332 const struct in6_addr *v6;
1333 const void *payload;
1334 int af;
1329 1335
1330 if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet)) 1336 if (pkt_len < sizeof (struct GNUNET_EXIT_TcpInternetStartMessage))
1331 { 1337 {
1332 GNUNET_break_op (0); 1338 GNUNET_break_op (0);
1333 return GNUNET_SYSERR; 1339 return GNUNET_SYSERR;
1334 } 1340 }
1335 pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode)); 1341 start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message;
1336 1342 pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage);
1337 if (NULL == state->heap_node) 1343 if ( (NULL == state) ||
1344 (NULL != state->serv) ||
1345 (NULL != state->heap_node) )
1338 { 1346 {
1339 /* first packet, setup record */ 1347 GNUNET_break_op (0);
1340 state->ri.remote_address = *s; 1348 return GNUNET_SYSERR;
1341 setup_state_record (state);
1342 } 1349 }
1343 1350 af = (int) ntohl (start->af);
1351 state->ri.remote_address.af = af;
1352 switch (af)
1353 {
1354 case AF_INET:
1355 if (pkt_len < sizeof (struct in_addr))
1356 {
1357 GNUNET_break_op (0);
1358 return GNUNET_SYSERR;
1359 }
1360 v4 = (const struct in_addr*) &start[1];
1361 payload = &v4[1];
1362 pkt_len -= sizeof (struct in_addr);
1363 state->ri.remote_address.address.ipv4 = *v4;
1364 break;
1365 case AF_INET6:
1366 if (pkt_len < sizeof (struct in6_addr))
1367 {
1368 GNUNET_break_op (0);
1369 return GNUNET_SYSERR;
1370 }
1371 v6 = (const struct in6_addr*) &start[1];
1372 payload = &v6[1];
1373 pkt_len -= sizeof (struct in_addr);
1374 state->ri.remote_address.address.ipv6 = *v6;
1375 break;
1376 default:
1377 GNUNET_break_op (0);
1378 return GNUNET_SYSERR;
1379 }
1380 state->ri.remote_address.proto = IPPROTO_TCP;
1381 state->ri.remote_address.port = ntohs (start->tcp_header.dpt);
1382 setup_state_record (state);
1344 send_tcp_packet_via_tun (&state->ri.remote_address, 1383 send_tcp_packet_via_tun (&state->ri.remote_address,
1345 &state->ri.local_address, 1384 &state->ri.local_address,
1346 pkt, pkt_len); 1385 &start->tcp_header,
1386 payload, pkt_len);
1347 return GNUNET_YES; 1387 return GNUNET_YES;
1348} 1388}
1349 1389
@@ -1369,29 +1409,29 @@ receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1369 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) 1409 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1370{ 1410{
1371 struct TunnelState *state = *tunnel_ctx; 1411 struct TunnelState *state = *tunnel_ctx;
1372 // FIXME: write proper request struct (!) 1412 const struct GNUNET_EXIT_TcpDataMessage *data;
1373 const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1374 const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1];
1375 uint16_t pkt_len = ntohs (message->size); 1413 uint16_t pkt_len = ntohs (message->size);
1376 1414
1377 if (NULL == state) 1415 if (pkt_len < sizeof (struct GNUNET_EXIT_TcpDataMessage))
1378 { 1416 {
1379 /* connection should have been up! */ 1417 GNUNET_break_op (0);
1380 /* FIXME: call statistics */
1381 return GNUNET_SYSERR; 1418 return GNUNET_SYSERR;
1382 } 1419 }
1383 1420 data = (const struct GNUNET_EXIT_TcpDataMessage*) message;
1384 if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet)) 1421 pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
1422 if ( (NULL == state) ||
1423 (NULL == state->heap_node) )
1385 { 1424 {
1425 /* connection should have been up! */
1386 GNUNET_break_op (0); 1426 GNUNET_break_op (0);
1427 /* FIXME: call statistics */
1387 return GNUNET_SYSERR; 1428 return GNUNET_SYSERR;
1388 } 1429 }
1389 pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode)); 1430 GNUNET_break_op (ntohl (data->reserved) == 0);
1390
1391
1392 send_tcp_packet_via_tun (&state->ri.remote_address, 1431 send_tcp_packet_via_tun (&state->ri.remote_address,
1393 &state->ri.local_address, 1432 &state->ri.local_address,
1394 pkt, pkt_len); 1433 &data->tcp_header,
1434 &data[1], pkt_len);
1395 return GNUNET_YES; 1435 return GNUNET_YES;
1396} 1436}
1397 1437
@@ -1448,7 +1488,9 @@ send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1448 struct ip4_header * ipv4 = (struct ip4_header*) &tun[1]; 1488 struct ip4_header * ipv4 = (struct ip4_header*) &tun[1];
1449 1489
1450 tun->proto = htons (ETH_P_IPV4); 1490 tun->proto = htons (ETH_P_IPV4);
1451 prepare_ipv4_packet (payload, payload_length, IPPROTO_UDP, 1491 prepare_ipv4_packet (payload, payload_length,
1492 IPPROTO_UDP,
1493 NULL,
1452 source_address, 1494 source_address,
1453 destination_address, 1495 destination_address,
1454 ipv4); 1496 ipv4);
@@ -1459,7 +1501,9 @@ send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1459 struct ip6_header * ipv6 = (struct ip6_header*) &tun[1]; 1501 struct ip6_header * ipv6 = (struct ip6_header*) &tun[1];
1460 1502
1461 tun->proto = htons (ETH_P_IPV6); 1503 tun->proto = htons (ETH_P_IPV6);
1462 prepare_ipv6_packet (payload, payload_length, IPPROTO_UDP, 1504 prepare_ipv6_packet (payload, payload_length,
1505 IPPROTO_UDP,
1506 NULL,
1463 source_address, 1507 source_address,
1464 destination_address, 1508 destination_address,
1465 ipv6); 1509 ipv6);