diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-10 15:13:41 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-10 15:13:41 +0000 |
commit | 4cd9ad92ad6131400e52dc1f25516b4134150aef (patch) | |
tree | 3288a2d18903a2b17b1b5b2c067e52985d5d9577 | |
parent | d2c214f97316f90f0242a0921fb4f060313c6c18 (diff) | |
download | gnunet-4cd9ad92ad6131400e52dc1f25516b4134150aef.tar.gz gnunet-4cd9ad92ad6131400e52dc1f25516b4134150aef.zip |
-dealing with new TCP message formats
-rw-r--r-- | src/exit/exit.h | 2 | ||||
-rw-r--r-- | src/exit/gnunet-daemon-exit.c | 168 |
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) | |||
971 | static void | 971 | static void |
972 | prepare_ipv4_packet (const void *payload, size_t payload_length, | 972 | prepare_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, | |||
1073 | static void | 1071 | static void |
1074 | prepare_ipv6_packet (const void *payload, size_t payload_length, | 1072 | prepare_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 | */ |
1172 | static void | 1172 | static void |
1173 | send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | 1173 | send_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); |