diff options
-rw-r--r-- | src/vpn/gnunet-daemon-exit.c | 220 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-vpn-helper.c | 3 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-vpn.c | 75 |
3 files changed, 232 insertions, 66 deletions
diff --git a/src/vpn/gnunet-daemon-exit.c b/src/vpn/gnunet-daemon-exit.c index b6b86cfc8..c30a74e85 100644 --- a/src/vpn/gnunet-daemon-exit.c +++ b/src/vpn/gnunet-daemon-exit.c | |||
@@ -174,100 +174,188 @@ send_udp_to_peer_notify_callback (void *cls, size_t size, void *buf) | |||
174 | } | 174 | } |
175 | 175 | ||
176 | /** | 176 | /** |
177 | * Receive packets from the helper-process | 177 | * @brief Handles an UDP-Packet received from the helper. |
178 | * | ||
179 | * @param udp A pointer to the Packet | ||
180 | * @param dadr The IP-Destination-address | ||
181 | * @param addrlen The length of the address | ||
182 | * @param version 4 or 6 | ||
178 | */ | 183 | */ |
179 | static void | 184 | static void |
180 | message_token (void *cls, | 185 | udp_from_helper (struct udp_pkt *udp, unsigned char *dadr, size_t addrlen, |
181 | void *client, const struct GNUNET_MessageHeader *message) | 186 | unsigned int version) |
182 | { | 187 | { |
183 | GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER); | 188 | struct redirect_info u_i; |
184 | |||
185 | struct tun_pkt *pkt_tun = (struct tun_pkt *) message; | ||
186 | |||
187 | struct GNUNET_MessageHeader *msg; | ||
188 | struct GNUNET_MESH_Tunnel *tunnel; | 189 | struct GNUNET_MESH_Tunnel *tunnel; |
189 | uint32_t len; | 190 | uint32_t len; |
191 | struct GNUNET_MessageHeader *msg; | ||
190 | 192 | ||
191 | struct udp_pkt *udp; | 193 | memset (&u_i, 0, sizeof (struct redirect_info)); |
192 | struct redirect_info u_i; | ||
193 | memset(&u_i, 0, sizeof(struct redirect_info)); | ||
194 | 194 | ||
195 | unsigned int version; | 195 | memcpy (&u_i.addr, dadr, addrlen); |
196 | |||
197 | /* ethertype is ipv6 */ | ||
198 | if (ntohs (pkt_tun->tun.type) == 0x86dd) | ||
199 | { | ||
200 | struct ip6_udp *pkt6 = (struct ip6_udp*)pkt_tun; | ||
201 | if (pkt6->ip6_hdr.nxthdr != 0x11) return; | ||
202 | /* lookup in udp_connections for dpt/dadr*/ | ||
203 | memcpy(&u_i.addr, pkt6->ip6_hdr.dadr, 16); | ||
204 | udp = &pkt6->udp_hdr; | ||
205 | version = 6; | ||
206 | } | ||
207 | else if (ntohs(pkt_tun->tun.type) == 0x0800) | ||
208 | { | ||
209 | struct ip_udp *pkt4 = (struct ip_udp*)pkt_tun; | ||
210 | if (pkt4->ip_hdr.proto != 0x11) return; | ||
211 | uint32_t tmp = pkt4->ip_hdr.dadr; | ||
212 | memcpy(&u_i.addr, &tmp, 4); | ||
213 | udp = &pkt4->udp_hdr; | ||
214 | version = 4; | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | return; | ||
219 | } | ||
220 | 196 | ||
221 | u_i.pt = udp->dpt; | 197 | u_i.pt = udp->dpt; |
222 | 198 | ||
223 | /* get tunnel and service-descriptor from this*/ | 199 | /* get tunnel and service-descriptor from this */ |
224 | GNUNET_HashCode hash; | 200 | GNUNET_HashCode hash; |
225 | GNUNET_CRYPTO_hash(&u_i, sizeof(struct redirect_info), &hash); | 201 | GNUNET_CRYPTO_hash (&u_i, sizeof (struct redirect_info), &hash); |
226 | struct redirect_state *state = GNUNET_CONTAINER_multihashmap_get(udp_connections, &hash); | 202 | struct redirect_state *state = |
203 | GNUNET_CONTAINER_multihashmap_get (udp_connections, &hash); | ||
227 | 204 | ||
228 | tunnel = state->tunnel; | 205 | tunnel = state->tunnel; |
229 | 206 | ||
230 | /* check if spt == serv.remote if yes: set spt = serv.myport*/ | 207 | /* check if spt == serv.remote if yes: set spt = serv.myport ("nat") */ |
231 | if (ntohs(udp->spt) == state->serv->remote_port) | 208 | if (ntohs (udp->spt) == state->serv->remote_port) |
232 | { | 209 | { |
233 | udp->spt = htons(state->serv->my_port); | 210 | udp->spt = htons (state->serv->my_port); |
234 | } | 211 | } |
235 | else | 212 | else |
236 | { | 213 | { |
237 | struct redirect_service *serv = GNUNET_malloc(sizeof(struct redirect_service)); | 214 | struct redirect_service *serv = |
238 | memcpy(serv, state->serv, sizeof(struct redirect_service)); | 215 | GNUNET_malloc (sizeof (struct redirect_service)); |
239 | serv->my_port = ntohs(udp->spt); | 216 | memcpy (serv, state->serv, sizeof (struct redirect_service)); |
240 | serv->remote_port = ntohs(udp->spt); | 217 | serv->my_port = ntohs (udp->spt); |
218 | serv->remote_port = ntohs (udp->spt); | ||
241 | uint16_t *desc = alloca (sizeof (GNUNET_HashCode) + 2); | 219 | uint16_t *desc = alloca (sizeof (GNUNET_HashCode) + 2); |
242 | memcpy((GNUNET_HashCode *) (desc + 1), &state->desc, sizeof(GNUNET_HashCode)); | 220 | memcpy ((GNUNET_HashCode *) (desc + 1), &state->desc, |
243 | *desc = ntohs(udp->spt); | 221 | sizeof (GNUNET_HashCode)); |
222 | *desc = ntohs (udp->spt); | ||
244 | GNUNET_HashCode hash; | 223 | GNUNET_HashCode hash; |
245 | GNUNET_CRYPTO_hash (desc, sizeof (GNUNET_HashCode) + 2, &hash); | 224 | GNUNET_CRYPTO_hash (desc, sizeof (GNUNET_HashCode) + 2, &hash); |
246 | GNUNET_assert (GNUNET_OK == | 225 | GNUNET_assert (GNUNET_OK == |
247 | GNUNET_CONTAINER_multihashmap_put (udp_services, | 226 | GNUNET_CONTAINER_multihashmap_put (udp_services, |
248 | &hash, serv, | 227 | &hash, serv, |
249 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 228 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
250 | state->serv = serv; | 229 | state->serv = serv; |
251 | } | 230 | } |
252 | /* send udp-packet back */ | 231 | /* send udp-packet back */ |
253 | len = sizeof(struct GNUNET_MessageHeader) + sizeof(GNUNET_HashCode) + ntohs(udp->len); | 232 | len = |
254 | msg = GNUNET_malloc(len); | 233 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + |
255 | msg->size = htons(len); | 234 | ntohs (udp->len); |
256 | msg->type = htons(GNUNET_MESSAGE_TYPE_SERVICE_UDP_BACK); | 235 | msg = GNUNET_malloc (len); |
257 | GNUNET_HashCode *desc = (GNUNET_HashCode*)(msg+1); | 236 | msg->size = htons (len); |
258 | memcpy(desc, &state->desc, sizeof(GNUNET_HashCode)); | 237 | msg->type = htons (GNUNET_MESSAGE_TYPE_SERVICE_UDP_BACK); |
259 | void* _udp = desc+1; | 238 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (msg + 1); |
260 | memcpy(_udp, udp, ntohs(udp->len)); | 239 | memcpy (desc, &state->desc, sizeof (GNUNET_HashCode)); |
240 | void *_udp = desc + 1; | ||
241 | memcpy (_udp, udp, ntohs (udp->len)); | ||
261 | 242 | ||
262 | GNUNET_MESH_notify_transmit_ready (tunnel, | 243 | GNUNET_MESH_notify_transmit_ready (tunnel, |
263 | GNUNET_NO, | 244 | GNUNET_NO, |
264 | 42, | 245 | 42, |
265 | GNUNET_TIME_relative_divide(GNUNET_CONSTANTS_MAX_CORK_DELAY, 2), | 246 | GNUNET_TIME_relative_divide |
266 | len, | 247 | (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2), |
267 | send_udp_to_peer_notify_callback, | 248 | len, send_udp_to_peer_notify_callback, |
268 | msg); | 249 | msg); |
269 | } | 250 | } |
270 | 251 | ||
252 | /** | ||
253 | * @brief Handles a TCP-Packet received from the helper. | ||
254 | * | ||
255 | * @param tcp A pointer to the Packet | ||
256 | * @param dadr The IP-Destination-address | ||
257 | * @param addrlen The length of the address | ||
258 | * @param version 4 or 6 | ||
259 | */ | ||
260 | static void | ||
261 | tcp_from_helper (struct tcp_pkt *tcp, unsigned char *dadr, size_t addrlen, | ||
262 | unsigned int version, size_t pktlen) | ||
263 | { | ||
264 | struct redirect_info u_i; | ||
265 | struct GNUNET_MESH_Tunnel *tunnel; | ||
266 | uint32_t len; | ||
267 | struct GNUNET_MessageHeader *msg; | ||
268 | |||
269 | memset (&u_i, 0, sizeof (struct redirect_info)); | ||
270 | |||
271 | memcpy (&u_i.addr, dadr, addrlen); | ||
272 | u_i.pt = tcp->dpt; | ||
273 | |||
274 | /* get tunnel and service-descriptor from this */ | ||
275 | GNUNET_HashCode hash; | ||
276 | GNUNET_CRYPTO_hash (&u_i, sizeof (struct redirect_info), &hash); | ||
277 | struct redirect_state *state = | ||
278 | GNUNET_CONTAINER_multihashmap_get (tcp_connections, &hash); | ||
279 | |||
280 | tunnel = state->tunnel; | ||
281 | |||
282 | /* check if spt == serv.remote if yes: set spt = serv.myport ("nat") */ | ||
283 | if (ntohs (tcp->spt) == state->serv->remote_port) | ||
284 | { | ||
285 | tcp->spt = htons (state->serv->my_port); | ||
286 | } | ||
287 | else | ||
288 | { | ||
289 | // This is an illegal packet. | ||
290 | GNUNET_assert (0); | ||
291 | } | ||
292 | /* send udp-packet back */ | ||
293 | len = | ||
294 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + pktlen; | ||
295 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "len: %d\n", pktlen); | ||
296 | msg = GNUNET_malloc (len); | ||
297 | msg->size = htons (len); | ||
298 | msg->type = htons (GNUNET_MESSAGE_TYPE_SERVICE_TCP_BACK); | ||
299 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (msg + 1); | ||
300 | memcpy (desc, &state->desc, sizeof (GNUNET_HashCode)); | ||
301 | void *_tcp = desc + 1; | ||
302 | memcpy (_tcp, tcp, pktlen); | ||
303 | |||
304 | GNUNET_MESH_notify_transmit_ready (tunnel, | ||
305 | GNUNET_NO, | ||
306 | 42, | ||
307 | GNUNET_TIME_relative_divide | ||
308 | (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2), | ||
309 | len, send_udp_to_peer_notify_callback, | ||
310 | msg); | ||
311 | } | ||
312 | |||
313 | |||
314 | /** | ||
315 | * Receive packets from the helper-process | ||
316 | */ | ||
317 | static void | ||
318 | message_token (void *cls, | ||
319 | void *client, const struct GNUNET_MessageHeader *message) | ||
320 | { | ||
321 | GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
322 | |||
323 | struct tun_pkt *pkt_tun = (struct tun_pkt *) message; | ||
324 | |||
325 | /* ethertype is ipv6 */ | ||
326 | if (ntohs (pkt_tun->tun.type) == 0x86dd) | ||
327 | { | ||
328 | struct ip6_pkt *pkt6 = (struct ip6_pkt *) pkt_tun; | ||
329 | if (0x11 == pkt6->ip6_hdr.nxthdr) | ||
330 | udp_from_helper (&((struct ip6_udp *) pkt6)->udp_hdr, | ||
331 | (unsigned char *) &pkt6->ip6_hdr.dadr, 16, 6); | ||
332 | else if (0x06 == pkt6->ip6_hdr.nxthdr) | ||
333 | tcp_from_helper (&((struct ip6_tcp *) pkt6)->tcp_hdr, | ||
334 | (unsigned char *) &pkt6->ip6_hdr.dadr, 16, 6, | ||
335 | ntohs (pkt6->ip6_hdr.paylgth)); | ||
336 | } | ||
337 | else if (ntohs (pkt_tun->tun.type) == 0x0800) | ||
338 | { | ||
339 | struct ip_pkt *pkt4 = (struct ip_pkt *) pkt_tun; | ||
340 | uint32_t tmp = pkt4->ip_hdr.dadr; | ||
341 | if (0x11 == pkt4->ip_hdr.proto) | ||
342 | udp_from_helper (&((struct ip_udp *) pkt4)->udp_hdr, | ||
343 | (unsigned char *) &tmp, 4, 4); | ||
344 | else if (0x06 == pkt4->ip_hdr.proto) | ||
345 | { | ||
346 | size_t pktlen = ntohs(pkt4->ip_hdr.tot_lngth); | ||
347 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tot: %d\n", pktlen); | ||
348 | pktlen -= 4*pkt4->ip_hdr.hdr_lngth; | ||
349 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "-hdr: %d\n", pktlen); | ||
350 | tcp_from_helper (&((struct ip_tcp *) pkt4)->tcp_hdr, | ||
351 | (unsigned char *) &tmp, 4, 4, pktlen); | ||
352 | } | ||
353 | } | ||
354 | else | ||
355 | { | ||
356 | return; | ||
357 | } | ||
358 | } | ||
271 | 359 | ||
272 | /** | 360 | /** |
273 | * Reads the configuration servicecfg and populates udp_services | 361 | * Reads the configuration servicecfg and populates udp_services |
diff --git a/src/vpn/gnunet-daemon-vpn-helper.c b/src/vpn/gnunet-daemon-vpn-helper.c index 40cf96826..b5f83f9db 100644 --- a/src/vpn/gnunet-daemon-vpn-helper.c +++ b/src/vpn/gnunet-daemon-vpn-helper.c | |||
@@ -274,6 +274,9 @@ message_token (void *cls, | |||
274 | } | 274 | } |
275 | else | 275 | else |
276 | { | 276 | { |
277 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Dropping packet. nxthdr=%d, type=%d, dpt=%x, flg=%d, ports=%x\n", | ||
278 | pkt6->ip6_hdr.nxthdr, ntohl(me->desc.service_type), | ||
279 | ntohs(pkt6_tcp->tcp_hdr.dpt), pkt6_tcp->tcp_hdr.flg, me->desc.ports); | ||
277 | GNUNET_free (cls); | 280 | GNUNET_free (cls); |
278 | cls = NULL; | 281 | cls = NULL; |
279 | } | 282 | } |
diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 86a616109..e57a5bf23 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c | |||
@@ -479,6 +479,80 @@ receive_udp_back (void *cls, struct GNUNET_MESH_Tunnel* tunnel, | |||
479 | return GNUNET_OK; | 479 | return GNUNET_OK; |
480 | } | 480 | } |
481 | 481 | ||
482 | static int | ||
483 | receive_tcp_back (void *cls, struct GNUNET_MESH_Tunnel* tunnel, | ||
484 | void **tunnel_ctx, | ||
485 | const struct GNUNET_PeerIdentity *sender, | ||
486 | const struct GNUNET_MessageHeader *message, | ||
487 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) | ||
488 | { | ||
489 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
490 | struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1); | ||
491 | const struct GNUNET_PeerIdentity* other = GNUNET_MESH_get_peer(tunnel); | ||
492 | |||
493 | size_t pktlen = ntohs(message->size) - sizeof(struct GNUNET_MessageHeader) - sizeof(GNUNET_HashCode); | ||
494 | size_t size = pktlen + sizeof(struct ip6_tcp) - 1; | ||
495 | |||
496 | struct ip6_tcp* pkt6 = alloca(size); | ||
497 | |||
498 | GNUNET_assert(pkt6 != NULL); | ||
499 | |||
500 | new_ip6addr(pkt6->ip6_hdr.sadr, &other->hashPubKey, desc); | ||
501 | |||
502 | pkt6->shdr.type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
503 | pkt6->shdr.size = htons(size); | ||
504 | |||
505 | pkt6->tun.flags = 0; | ||
506 | pkt6->tun.type = htons(0x86dd); | ||
507 | |||
508 | pkt6->ip6_hdr.version = 6; | ||
509 | pkt6->ip6_hdr.tclass_h = 0; | ||
510 | pkt6->ip6_hdr.tclass_l = 0; | ||
511 | pkt6->ip6_hdr.flowlbl = 0; | ||
512 | pkt6->ip6_hdr.paylgth = htons(pktlen); | ||
513 | pkt6->ip6_hdr.nxthdr = 0x06; | ||
514 | pkt6->ip6_hdr.hoplmt = 0xff; | ||
515 | |||
516 | { | ||
517 | char* ipv6addr; | ||
518 | GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr)); | ||
519 | inet_pton (AF_INET6, ipv6addr, pkt6->ip6_hdr.dadr); | ||
520 | GNUNET_free(ipv6addr); | ||
521 | } | ||
522 | memcpy(&pkt6->tcp_hdr, pkt, pktlen); | ||
523 | |||
524 | GNUNET_HashCode* key = address_mapping_exists(pkt6->ip6_hdr.sadr); | ||
525 | GNUNET_assert (key != NULL); | ||
526 | |||
527 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get(hashmap, key); | ||
528 | |||
529 | GNUNET_free(key); | ||
530 | |||
531 | GNUNET_assert (me != NULL); | ||
532 | GNUNET_assert (me->desc.service_type & htonl(GNUNET_DNS_SERVICE_TYPE_TCP)); | ||
533 | |||
534 | pkt6->tcp_hdr.crc = 0; | ||
535 | uint32_t sum = 0; | ||
536 | uint32_t tmp; | ||
537 | sum = | ||
538 | calculate_checksum_update (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16); | ||
539 | sum = | ||
540 | calculate_checksum_update (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16); | ||
541 | tmp = htonl(pktlen); | ||
542 | sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4); | ||
543 | tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff))); | ||
544 | sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4); | ||
545 | |||
546 | sum = | ||
547 | calculate_checksum_update (sum, (uint16_t *) & pkt6->tcp_hdr, | ||
548 | ntohs (pkt6->ip6_hdr.paylgth)); | ||
549 | pkt6->tcp_hdr.crc = calculate_checksum_end (sum); | ||
550 | |||
551 | write_to_helper(pkt6, size); | ||
552 | |||
553 | return GNUNET_OK; | ||
554 | } | ||
555 | |||
482 | void init_mesh (void* cls, struct GNUNET_MESH_Handle* server, const struct GNUNET_PeerIdentity* my_identity, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey) { | 556 | void init_mesh (void* cls, struct GNUNET_MESH_Handle* server, const struct GNUNET_PeerIdentity* my_identity, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey) { |
483 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected to MESH, I am %x\n", *((unsigned long*)my_identity)); | 557 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected to MESH, I am %x\n", *((unsigned long*)my_identity)); |
484 | } | 558 | } |
@@ -503,6 +577,7 @@ run (void *cls, | |||
503 | { | 577 | { |
504 | const static struct GNUNET_MESH_MessageHandler handlers[] = { | 578 | const static struct GNUNET_MESH_MessageHandler handlers[] = { |
505 | {receive_udp_back, GNUNET_MESSAGE_TYPE_SERVICE_UDP_BACK, 0}, | 579 | {receive_udp_back, GNUNET_MESSAGE_TYPE_SERVICE_UDP_BACK, 0}, |
580 | {receive_tcp_back, GNUNET_MESSAGE_TYPE_SERVICE_TCP_BACK, 0}, | ||
506 | {NULL, 0, 0} | 581 | {NULL, 0, 0} |
507 | }; | 582 | }; |
508 | mesh_handle = GNUNET_MESH_connect(cfg_, | 583 | mesh_handle = GNUNET_MESH_connect(cfg_, |