📄 vpn.c
字号:
if (identity->isBlacklisted(&((store1+i)->peer)), GNUNET_YES) { GNUNET_GE_LOG(ectx, GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER, _("RFC4193 --- whitelist of peer %x\n"), (store1+i)->peer.hashPubKey.bits[0]); identity->whitelistHost(&((store1+i)->peer)); } } } }*/ } GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, _("RFC4193 Thread exiting\n")); GNUNET_mutex_unlock (lock); return NULL;}/** * here we copy the prototype route table we are collecting from peers to the actual * "realised" route table we distribute to peers, and to the kernel's table. */static voidrealise (void *unused){ int i, j, found; GNUNET_PeerIdentity id; int reqcapacity; route_info *reqstore; struct in6_rtmsg rt; GNUNET_mutex_lock (lock); /* make sure realised table can take the new routes - if it wont, abort now! */ GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, _("realise alloc ram\n")); if (route_entries > realised_entries) { reqcapacity = sizeof (route_info) * route_entries; if (reqcapacity > realised_capacity) { reqstore = GNUNET_realloc (realised_store, reqcapacity); if (reqstore == NULL) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_BULK, "I cannot up the ram for realised routes.\n"); GNUNET_mutex_unlock (lock); return; } realised_store = reqstore; realised_capacity = reqcapacity; } } /* add routes that are in the new table but not the old */ GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, _("realise add routes\n")); for (i = 0; i < route_entries; i++) { found = 0; for (j = 0; j < realised_entries; j++) { /* compare public key */ if (isEqualP (&(route_store + i)->owner, &(realised_store + j)->owner) && ((route_store + i)->hops == (realised_store + j)->hops) && ((route_store + i)->tunnel == (realised_store + j)->tunnel)) { found = 1; } } /* we are hops == 0 * hops == 1 auto added by tunneler * hops >= 2 added here! */ if (!(found) && ((route_store + i)->hops > 1)) { /* lets add a route to this long remote node */ memset ((char *) &rt, 0, sizeof (struct in6_rtmsg)); /* rtmsg_ifindex would be zero for routes not specifying a device, such as by gateway */ rt.rtmsg_ifindex = (store1 + ((route_store + i)->tunnel))->ifindex; identity->getPeerIdentity (&(route_store + i)->owner, &id); id2net (&rt.rtmsg_dst, &id); rt.rtmsg_flags = RTF_UP; rt.rtmsg_metric = (route_store + i)->hops; /* how many hops to owner of public key */ rt.rtmsg_dst_len = 48; /* always 48 as per RFC4193 */ GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, "Add route gnu%d hops %d dst %x:%x:%x:%x:%x:%x:%x:%x/%d\n", id, rt.rtmsg_metric, ntohs (rt.rtmsg_dst.s6_addr16[0]), ntohs (rt.rtmsg_dst.s6_addr16[1]), ntohs (rt.rtmsg_dst.s6_addr16[2]), ntohs (rt.rtmsg_dst.s6_addr16[3]), ntohs (rt.rtmsg_dst.s6_addr16[4]), ntohs (rt.rtmsg_dst.s6_addr16[5]), ntohs (rt.rtmsg_dst.s6_addr16[6]), ntohs (rt.rtmsg_dst.s6_addr16[7]), rt.rtmsg_dst_len); if (ioctl (admin_fd, SIOCADDRT, &rt) < 0) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_BULK, "Cannot add route IPv6 address for gnu%s because %s\n", id, strerror (errno)); } } } GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, "Removing routes\n"); /* pull routes that are in the old table but not the new */ for (i = 0; i < realised_entries; i++) { found = 0; for (j = 0; j < route_entries; j++) { /* compare public key */ if (isEqualP (&(realised_store + i)->owner, &(route_store + j)->owner) && ((realised_store + i)->hops == (route_store + j)->hops) && ((realised_store + i)->tunnel == (route_store + j)->tunnel)) { found = 1; } } /* we are hops == 0 * hops == 1 auto added by tunneler * hops >= 2 added here! */ if (!(found) && ((realised_store + i)->hops > 1)) { /* remove the route to this long remote node */ memset ((char *) &rt, 0, sizeof (struct in6_rtmsg)); /* rtmsg_ifindex would be zero for routes not specifying a device, such as by gateway */ rt.rtmsg_ifindex = (store1 + ((realised_store + i)->tunnel))->ifindex; identity->getPeerIdentity (&(realised_store + i)->owner, &id); id2net (&rt.rtmsg_dst, &id); rt.rtmsg_flags = RTF_UP; rt.rtmsg_metric = (realised_store + i)->hops; /* how many hops to owner of public key */ rt.rtmsg_dst_len = 48; /* always 48 as per RFC4193 */ GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, "Delete route gnu%d hops %d dst %x:%x:%x:%x:%x:%x:%x:%x/%d\n", id, rt.rtmsg_metric, ntohs (rt.rtmsg_dst.s6_addr16[0]), ntohs (rt.rtmsg_dst.s6_addr16[1]), ntohs (rt.rtmsg_dst.s6_addr16[2]), ntohs (rt.rtmsg_dst.s6_addr16[3]), ntohs (rt.rtmsg_dst.s6_addr16[4]), ntohs (rt.rtmsg_dst.s6_addr16[5]), ntohs (rt.rtmsg_dst.s6_addr16[6]), ntohs (rt.rtmsg_dst.s6_addr16[7]), rt.rtmsg_dst_len); if (ioctl (admin_fd, SIOCDELRT, &rt) < 0) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_BULK, "Cannot del route IPv6 address for gnu%s because %s\n", id, strerror (errno)); } } } GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, _("realise copy table\n")); realised_entries = route_entries; memcpy (realised_store, route_store, sizeof (route_info) * route_entries); GNUNET_mutex_unlock (lock);}/** * Module inserted... create thread to listen to TUNTAP and pass * these messages on to GNUnet. * * Also enumerate all current peers and create taps for them. * */intinitialize_module_vpn (GNUNET_CoreAPIForPlugins * capi){ int pfd; char *str = GNUNET_strdup ("OK\r\n"); ectx = capi->ectx; lock = GNUNET_mutex_create (GNUNET_NO); coreAPI = capi; /* Signal to the root init script we want cap_net_admin */ pfd = open ("/var/lib/gnunet/gnunet.vpn", O_WRONLY); if (pfd > -1) { WRITE (pfd, str, strlen (str)); CLOSE (pfd); } pfd = open ("/var/lib/gnunet/gnunet.vpn", O_RDONLY); if (pfd > -1) { READ (pfd, str, strlen (str)); CLOSE (pfd); } UNLINK ("/var/lib/gnunet/gnunet.vpn"); GNUNET_free (str); /* system("sudo setpcaps cap_net_admin+eip `pidof gnunetd`"); */ admin_fd = socket (AF_INET6, SOCK_DGRAM, 0); GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, _("`%s' initialising RFC4913 module %d and %d\n"), "template", GNUNET_CS_PROTO_MAX_USED, GNUNET_P2P_PROTO_MAX_USED); GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, _("RFC4193 my First 4 hex digits of host id are %x\n"), capi->my_identity->hashPubKey.bits[0]); /* core calls us to receive messages */ /* get a PONG = peer is online */ /* get a HANGUP = peer is offline */ GNUNET_VPN_p2p_handler_init (capi); GNUNET_VPN_cs_handler_init (capi); identity = coreAPI->service_request ("identity"); GNUNET_GE_ASSERT (ectx, identity != NULL); session = coreAPI->service_request ("session"); GNUNET_GE_ASSERT (ectx, session != NULL); init_router (); /* requires identity */ init_realised (); /* requires identity */ PIPE (signalingPipe); /* important: make signalingPipe non-blocking to avoid stalling on signaling! */ GNUNET_pipe_make_nonblocking (ectx, signalingPipe[1]); /* Yes we have to make our own thread, cause the GUNnet API is * missing some callbacks (Namely CanReadThisFd - SELECT()) that I would like ;-( * They may go in the thread that usually monitors the GUI port. */ tunThreadInfo = GNUNET_thread_create (&tunThread, NULL, 128 * 1024); GNUNET_cron_add_job (capi->cron, &realise, 5 * GNUNET_CRON_MINUTES, 5 * GNUNET_CRON_MINUTES, NULL); /* use capi->ciphertext_send to send messages to connected peers */ GNUNET_GE_ASSERT (capi->ectx, 0 == GNUNET_GC_set_configuration_value_string (capi->cfg, capi->ectx, "ABOUT", "vpn", _ ("enables IPv6 over GNUnet (incomplete)"))); return GNUNET_OK;}/** * Module uninserted. */voiddone_module_vpn (){ int i; int ret; void *returnval; GNUNET_cron_del_job (coreAPI->cron, &realise, 5 * GNUNET_CRON_MINUTES, NULL); GNUNET_VPN_p2p_handler_done (); GNUNET_VPN_cs_handler_done (); GNUNET_GE_LOG (ectx, GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER, _("RFC4193 Waiting for tun thread to end\n")); running = 0; /* thread should wake up and exit */ ret = write (signalingPipe[1], &running, sizeof (char)); if (ret != sizeof (char)) if (errno != EAGAIN) GNUNET_GE_LOG_STRERROR (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, "RFC4193 can not tell thread to exit"); /* wait for it to exit */ GNUNET_thread_join (tunThreadInfo, &returnval); GNUNET_GE_LOG (ectx, GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER, _("RFC4193 The tun thread has ended\n")); coreAPI->service_release (identity); identity = NULL; coreAPI->service_release (session); session = NULL; CLOSE (signalingPipe[0]); CLOSE (signalingPipe[1]); /* bye bye TUNTAP ... */ for (i = 0; i < entries1; i++) { if (((store1 + i)->fd) != 0) { GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST, _("RFC4193 Closing tunnel %d fd %d\n"), i, (store1 + i)->fd); CLOSE ((store1 + i)->fd); (store1 + i)->fd = 0; } } if (store1 != NULL) { entries1 = 0; capacity1 = 0; GNUNET_free (store1); } CLOSE (admin_fd); GNUNET_mutex_destroy (lock); coreAPI = NULL;}/* end of vpn.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -