⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vpn.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/*     This file is part of GNUnet.     (C) 2001, 2002, 2004, 2005, 2006, 2008 Christian Grothoff (and other contributing authors)     GNUnet is free software; you can redistribute it and/or modify     it under the terms of the GNU General Public License as published     by the Free Software Foundation; either version 2, or (at your     option) any later version.     GNUnet is distributed in the hope that it will be useful, but     WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     General Public License for more details.     You should have received a copy of the GNU General Public License     along with GNUnet; see the file COPYING.  If not, write to the     Free Software Foundation, Inc., 59 Temple Place - Suite 330,     Boston, MA 02111-1307, USA.*//** * @file applications/vpn/vpn.c * @author Michael John Wensley * @author Christian Grothoff (code cleanup, breaking things) * @brief tunnel RFC 4193 in GNUnet * * * http://gnunet.wensley.org.uk/ * * Yes this will thoroughly break most of the coding guidelines :-/ at least the first release. * * We use IPv6 addresses because they provide a larger space, and are * not as likely to be in use by other applications such as NAT. * * We also follow the guidance in RFC4193 and use only the 40 bits * specified for the randomly generated publickey. This allows nodes * to connect subnets to the network. * * It also allows interoperation with other users of this space such * as anonymous internets. We use GNUnet to benefit from its key * infrastructure, though other users may well rip fdxx:: bits * directly from public keys, using the private key to GNUNET_RSA_sign * route announcements. * * CHANGELOG: * 20060110 Change ifconfig/route to ioctl's * 20060111 P2P packet includes length of the header. * 20060802 Logging for multiple clients * * TODO: * - consider using linked list for routing tables instead of arrays * - find a better solution for /var/lib/gnunet/gnunet.vpn, *   at least do not hardwire the path * - can we split off TUN code into *   individual files without keeping globals? * - use PeerIdentities instead of PublicKeys where *   possible */#include "vpn.h"#include "cs.h"#include "p2p.h"#include "helper.h"/** * Identity service, to reset the core. */GNUNET_Identity_ServiceAPI *identity;GNUNET_Session_ServiceAPI *session;GNUNET_CoreAPIForPlugins *coreAPI;struct GNUNET_Mutex *lock;/* from bluetooth agent */tunnel_info *store1;int entries1;route_info *route_store;int route_entries;route_info *realised_store;int realised_entries;static int interval = 60;static struct GNUNET_ThreadHandle *tunThreadInfo;static struct GNUNET_GE_Context *ectx;static int capacity1; /** * Pipe to communicate with select thread * Used to tell it there is something to do... */static int signalingPipe[2];/** is thread to stop? */static int running;static int admin_fd;static int route_capacity;static int realised_capacity;/** * clear out the prototype routes table * called at start or when we know a peer changes its route table. */voidinit_router (){  int reqcapacity;  route_info *reqstore;  reqcapacity = sizeof (route_info);  if (reqcapacity > route_capacity)    {      reqstore = GNUNET_realloc (route_store, reqcapacity);      if (reqstore == NULL)        return;                 /* not enough ram, cannot init! */      route_store = reqstore;      route_capacity = reqcapacity;    }  route_entries = 1;  route_store->hops = 0;        /* us! */  route_store->tunnel = -1;     /* n/a! */  route_store->owner = *(identity->getPublicPrivateKey ());     /* us! */}/** * clear out the actual route at startup only */static voidinit_realised (){  int reqcapacity;  route_info *reqstore;  reqcapacity = sizeof (route_info);  if (reqcapacity > realised_capacity)    {      reqstore = GNUNET_realloc (realised_store, reqcapacity);      if (reqstore == NULL)        return;                 /* not enough ram, cannot init! */      realised_store = reqstore;      realised_capacity = reqcapacity;    }  realised_entries = 1;  realised_store->hops = 0;     /* us! */  realised_store->tunnel = -1;  /* n/a! */  realised_store->owner = *(identity->getPublicPrivateKey ());  /* us! */}/* adds a route to prototype route table, unless it has same GNUNET_RSA_PublicKey and tunnel as another entry */voidadd_route (GNUNET_RSA_PublicKey * them, int hops, int tunnel){  int i;  route_info *rstore;  int rcapacity;  for (i = 0; i < route_entries; i++)    {      if (isEqualP (them, &(route_store + i)->owner))        {          if ((route_store + i)->hops == 0)            {              /* we don't store alternative routes to ourselves,               * as we already know how to route to ourself               */              GNUNET_GE_LOG (ectx,                             GNUNET_GE_DEBUG | GNUNET_GE_BULK |                             GNUNET_GE_ADMIN,                             _("Not storing route to myself from peer %d\n"),                             tunnel);              return;            }          if ((route_store + i)->tunnel == tunnel)            {              /* also, we only keep one route to a node per peer,               * but store the lowest hop count that the peer is advertising for that node.               */              (route_store + i)->hops = mini ((route_store + i)->hops, hops);              GNUNET_GE_LOG (ectx,                             GNUNET_GE_DEBUG | GNUNET_GE_BULK |                             GNUNET_GE_ADMIN,                             _                             ("Duplicate route to node from peer %d, choosing minimum hops"),                             tunnel);              return;            }        }    }  route_entries++;  rcapacity = route_entries * sizeof (route_info);  if (rcapacity > route_capacity)    {      rstore = GNUNET_realloc (route_store, rcapacity);      if (rstore == NULL)        {          route_entries--;          return;               /* not enough ram, we will have to drop this route. */        }      route_capacity = rcapacity;      route_store = rstore;    }  /*   * we really should keep the route table in ascending hop count order...   */  if (route_entries > 0)    {      i = route_entries - 1;    /* i = insert location */      while ((i > 0) && ((route_store + (i - 1))->hops > hops))        {          (route_store + i)->hops = (route_store + (i - 1))->hops;          (route_store + i)->tunnel = (route_store + (i - 1))->hops;          (route_store + i)->owner = (route_store + (i - 1))->owner;          i--;        }      GNUNET_GE_LOG (ectx,                     GNUNET_GE_DEBUG | GNUNET_GE_BULK | GNUNET_GE_ADMIN,                     _                     ("Inserting route from peer %d in route table at location %d\n"),                     tunnel, i);      (route_store + i)->hops = hops;      (route_store + i)->tunnel = tunnel;      (route_store + i)->owner = *them;    }}/** check that ethertype matches ip version for incoming packets from linux specific code */static intvalid_incoming (int len, struct tun_pi *tp, struct ip6_hdr *fp){  char info[100];  if (len > (65535 - sizeof (struct tun_pi)))    {      GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,                     _("RFC4193 Frame length %d is too big for GNUnet!\n"),                     len);      return GNUNET_NO;    }  if (len < sizeof (struct tun_pi))    {      GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,                     _("RFC4193 Frame length %d too small\n"), len);      return GNUNET_NO;    }  if ((ntohs (tp->proto) == ETH_P_IP)      && (((struct iphdr *) fp)->version == 4))    {      return GNUNET_YES;    }  else if ((ntohs (tp->proto) == ETH_P_IPV6)           && (((struct iphdr *) fp)->version == 6))    {      ipinfo (info, fp);      GNUNET_GE_LOG (ectx,                     GNUNET_GE_DEBUG | GNUNET_GE_BULK | GNUNET_GE_ADMIN,                     "-> GNUnet(%d) : %s\n", len - sizeof (struct tun_pi),                     info);      return GNUNET_YES;    }  GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,                 _("RFC4193 Ethertype %x and IP version %x do not match!\n"),                 ntohs (tp->proto), ((struct iphdr *) fp)->version);  return GNUNET_NO;}static voidsetup_tunnel (int n, const GNUNET_PeerIdentity * them){  struct ifreq ifr;  struct in6_ifreq ifr6;  struct in6_rtmsg rt;  int i, used, fd, id = 0;  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER | GNUNET_GE_REQUEST,                 _("RFC4193 Going to try and make a tunnel in slot %d\n"), n);  fd = open ("/dev/net/tun", O_RDWR);  if (fd < 0)    {      GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,                     _("Cannot open tunnel device because of %s"),                     strerror (fd));      GNUNET_GE_DIE_STRERROR (ectx,                              GNUNET_GE_FATAL | GNUNET_GE_ADMIN |                              GNUNET_GE_BULK, "open");    }  memset (&ifr, 0, sizeof (ifr));  /* IFF_TUN = IP Packets   * IFF_TAP = Ethernet packets   *   * IFF_NO_PI = Do not provide packet information   */  /* we know its going to be ipv6 cause the version tells us.   * except that linux *assumes* it will be sent IPv4 frames   * unless we configure IFF_PI.... hmmmm.... :-/   * lets see the tun linux module source   *   * this needs PI as type = htons(0x86DD)   * ifr.ifr_flags = IFF_TUN | IFF_NO_PI;   * We do need PI otherwise TUNTAP assumes it is receiving IPv4...   */  ifr.ifr_flags = IFF_TUN;  /* try various names until we find a free one */  do    {      used = 0;      for (i = 0; i < entries1; i++)        {          if ((store1 + i)->id == id)            {              GNUNET_GE_LOG (ectx,                             GNUNET_GE_DEBUG | GNUNET_GE_DEVELOPER |                             GNUNET_GE_REQUEST,                             _                             ("RFC4193 Create skips gnu%d as we are already using it\n"),                             id);              id++;              used = 1;            }        }      if (used == 0)        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -