diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-11 22:20:12 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-11 22:20:12 +0000 |
commit | baaef78cd06674caac97c96cf3061a7a376b5422 (patch) | |
tree | 1a8dce03fdaf7e9e05fa0568fa7f0ecbadfd03c7 /src/vpn/gnunet-service-vpn.c | |
parent | 2f31bf62ac7c57984f9e674fca3fc9eb68b1b656 (diff) | |
download | gnunet-baaef78cd06674caac97c96cf3061a7a376b5422.tar.gz gnunet-baaef78cd06674caac97c96cf3061a7a376b5422.zip |
-building IPv4 TCP reply messages for TUN
Diffstat (limited to 'src/vpn/gnunet-service-vpn.c')
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 119 |
1 files changed, 98 insertions, 21 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 9739e24d0..ad00d4c99 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -1158,6 +1158,90 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1158 | const struct GNUNET_MessageHeader *message, | 1158 | const struct GNUNET_MessageHeader *message, |
1159 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | 1159 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) |
1160 | { | 1160 | { |
1161 | struct TunnelState *ts = *tunnel_ctx; | ||
1162 | const struct GNUNET_EXIT_TcpDataMessage *data; | ||
1163 | size_t mlen; | ||
1164 | |||
1165 | mlen = ntohs (message->size); | ||
1166 | if (mlen < sizeof (struct GNUNET_EXIT_TcpDataMessage)) | ||
1167 | { | ||
1168 | GNUNET_break_op (0); | ||
1169 | return GNUNET_SYSERR; | ||
1170 | } | ||
1171 | if (NULL == ts->heap_node) | ||
1172 | { | ||
1173 | GNUNET_break_op (0); | ||
1174 | return GNUNET_SYSERR; | ||
1175 | } | ||
1176 | data = (const struct GNUNET_EXIT_TcpDataMessage *) message; | ||
1177 | mlen -= sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
1178 | switch (ts->af) | ||
1179 | { | ||
1180 | case AF_INET: | ||
1181 | { | ||
1182 | size_t size = sizeof (struct ip4_header) | ||
1183 | + sizeof (struct tcp_packet) | ||
1184 | + sizeof (struct GNUNET_MessageHeader) + | ||
1185 | sizeof (struct tun_header) + | ||
1186 | mlen; | ||
1187 | { | ||
1188 | char buf[size]; | ||
1189 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1190 | struct tun_header *tun = (struct tun_header*) &msg[1]; | ||
1191 | struct ip4_header *ipv4 = (struct ip4_header *) &tun[1]; | ||
1192 | struct tcp_packet *tcp = (struct tcp_packet *) &ipv4[1]; | ||
1193 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1194 | msg->size = htons (size); | ||
1195 | tun->flags = htons (0); | ||
1196 | tun->proto = htons (ETH_P_IPV4); | ||
1197 | ipv4->version = 4; | ||
1198 | ipv4->header_length = sizeof (struct ip4_header) / 4; | ||
1199 | ipv4->diff_serv = 0; | ||
1200 | ipv4->total_length = htons (sizeof (struct ip4_header) + | ||
1201 | sizeof (struct tcp_packet) + | ||
1202 | mlen); | ||
1203 | ipv4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1204 | UINT16_MAX + 1); | ||
1205 | ipv4->flags = 0; | ||
1206 | ipv4->fragmentation_offset = 0; | ||
1207 | ipv4->ttl = 255; | ||
1208 | ipv4->protocol = IPPROTO_TCP; | ||
1209 | ipv4->checksum = 0; | ||
1210 | ipv4->source_address = ts->destination_ip.v4; | ||
1211 | ipv4->destination_address = ts->source_ip.v4; | ||
1212 | ipv4->checksum = | ||
1213 | GNUNET_CRYPTO_crc16_n (ipv4, sizeof (struct ip4_header)); | ||
1214 | *tcp = data->tcp_header; | ||
1215 | tcp->spt = htons (ts->destination_port); | ||
1216 | tcp->dpt = htons (ts->source_port); | ||
1217 | tcp->crc = 0; | ||
1218 | memcpy (&tcp[1], | ||
1219 | &data[1], | ||
1220 | mlen); | ||
1221 | { | ||
1222 | uint32_t sum = 0; | ||
1223 | uint32_t tmp; | ||
1224 | |||
1225 | sum = GNUNET_CRYPTO_crc16_step (sum, | ||
1226 | &ipv4->source_address, | ||
1227 | 2 * sizeof (struct in_addr)); | ||
1228 | tmp = htonl ((IPPROTO_TCP << 16) | (mlen + sizeof (struct tcp_packet))); | ||
1229 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); | ||
1230 | sum = GNUNET_CRYPTO_crc16_step (sum, tcp, mlen + sizeof (struct tcp_packet)); | ||
1231 | tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1232 | } | ||
1233 | (void) GNUNET_HELPER_send (helper_handle, | ||
1234 | msg, | ||
1235 | GNUNET_YES, | ||
1236 | NULL, NULL); | ||
1237 | } | ||
1238 | } | ||
1239 | break; | ||
1240 | case AF_INET6: | ||
1241 | break; | ||
1242 | default: | ||
1243 | GNUNET_assert (0); | ||
1244 | } | ||
1161 | // FIXME: parse message, build IP packet, give to TUN! | 1245 | // FIXME: parse message, build IP packet, give to TUN! |
1162 | #if 0 | 1246 | #if 0 |
1163 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | 1247 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); |
@@ -1229,11 +1313,11 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1229 | GNUNET_assert (me != NULL); | 1313 | GNUNET_assert (me != NULL); |
1230 | 1314 | ||
1231 | pkt6->tcp_hdr.crc = 0; | 1315 | pkt6->tcp_hdr.crc = 0; |
1232 | uint32_t sum = 0; | ||
1233 | uint32_t tmp; | ||
1234 | 1316 | ||
1235 | sum = | 1317 | uint32_t sum = 0; |
1236 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16); | 1318 | uint32_t tmp; |
1319 | |||
1320 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16); | ||
1237 | sum = | 1321 | sum = |
1238 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16); | 1322 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16); |
1239 | tmp = htonl (pktlen); | 1323 | tmp = htonl (pktlen); |
@@ -1246,6 +1330,7 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1246 | ntohs (pkt6->ip6_hdr.paylgth)); | 1330 | ntohs (pkt6->ip6_hdr.paylgth)); |
1247 | pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | 1331 | pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); |
1248 | 1332 | ||
1333 | |||
1249 | (void) GNUNET_HELPER_send (helper_handle, | 1334 | (void) GNUNET_HELPER_send (helper_handle, |
1250 | &pkt6->shdr, | 1335 | &pkt6->shdr, |
1251 | GNUNET_YES, | 1336 | GNUNET_YES, |
@@ -1312,23 +1397,6 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1312 | 1397 | ||
1313 | GNUNET_assert (me != NULL); | 1398 | GNUNET_assert (me != NULL); |
1314 | pkt4->tcp_hdr.crc = 0; | 1399 | pkt4->tcp_hdr.crc = 0; |
1315 | uint32_t sum = 0; | ||
1316 | uint32_t tmp; | ||
1317 | |||
1318 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.sadr, 4); | ||
1319 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.dadr, 4); | ||
1320 | |||
1321 | tmp = (0x06 << 16) | (0xffff & pktlen); // 0x06 for TCP? | ||
1322 | |||
1323 | tmp = htonl (tmp); | ||
1324 | |||
1325 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | ||
1326 | |||
1327 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt4->tcp_hdr, pktlen); | ||
1328 | pkt4->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | ||
1329 | |||
1330 | pkt4->ip_hdr.chks = | ||
1331 | GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4); | ||
1332 | 1400 | ||
1333 | (void) GNUNET_HELPER_send (helper_handle, | 1401 | (void) GNUNET_HELPER_send (helper_handle, |
1334 | &pkt4->shdr, | 1402 | &pkt4->shdr, |
@@ -1337,6 +1405,15 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1337 | 1405 | ||
1338 | } | 1406 | } |
1339 | #endif | 1407 | #endif |
1408 | |||
1409 | #if 0 | ||
1410 | // FIXME: refresh entry to avoid expiration... | ||
1411 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
1412 | |||
1413 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, | ||
1414 | GNUNET_TIME_absolute_get ().abs_value); | ||
1415 | |||
1416 | #endif | ||
1340 | return GNUNET_OK; | 1417 | return GNUNET_OK; |
1341 | } | 1418 | } |
1342 | 1419 | ||