aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/vpn/gnunet-daemon-exit.c220
-rw-r--r--src/vpn/gnunet-daemon-vpn-helper.c3
-rw-r--r--src/vpn/gnunet-daemon-vpn.c75
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 */
179static void 184static void
180message_token (void *cls, 185udp_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 */
260static void
261tcp_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 */
317static void
318message_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
482static int
483receive_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
482void init_mesh (void* cls, struct GNUNET_MESH_Handle* server, const struct GNUNET_PeerIdentity* my_identity, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey) { 556void 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_,