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

📄 forward.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
📖 第 1 页 / 共 2 页
字号:
	      /* reset packet received timer if TLS packet */	      if (c->options.ping_rec_timeout)		event_timeout_reset (&c->c2.ping_rec_interval);	    }	}#endif /* USE_SSL */      /* authenticate and decrypt the incoming packet */      decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, &c->c2.crypto_options, &c->c2.frame);#ifdef USE_SSL      if (c->c2.tls_multi)	{	  //tls_mutex_unlock (c->c2.tls_multi);	}#endif            if (!decrypt_status && link_socket_connection_oriented (c->c2.link_socket))	{	  /* decryption errors are fatal in TCP mode */	  c->sig->signal_received = SIGUSR1;	  msg (D_STREAM_ERRORS, "Fatal decryption error, restarting");	  c->sig->signal_text = "decryption-error";	  goto done;	}#endif /* USE_CRYPTO */      if (c->c2.fragment)	fragment_incoming (c->c2.fragment, &c->c2.buf, &c->c2.frame_fragment);#ifdef USE_LZO      /* decompress the incoming packet */      if (c->options.comp_lzo)	lzo_decompress (&c->c2.buf, c->c2.buffers->lzo_decompress_buf, &c->c2.lzo_compwork, &c->c2.frame);#endif      /*       * Set our "official" outgoing address, since       * if buf.len is non-zero, we know the packet       * authenticated.  In TLS mode we do nothing       * because TLS mode takes care of source address       * authentication.       *       * Also, update the persisted version of our packet-id.       */      if (!TLS_MODE)	link_socket_set_outgoing_addr (&c->c2.buf, lsi, &c->c2.from, NULL);      /* reset packet received timer */      if (c->options.ping_rec_timeout && c->c2.buf.len > 0)	event_timeout_reset (&c->c2.ping_rec_interval);      /* increment authenticated receive byte count */      if (c->c2.buf.len > 0)	{	  c->c2.link_read_bytes_auth += c->c2.buf.len;	  c->c2.max_recv_size_local = max_int (c->c2.original_recv_size, c->c2.max_recv_size_local);	}      /* Did we just receive an openvpn ping packet? */      if (is_ping_msg (&c->c2.buf))	{	  msg (D_PACKET_CONTENT, "RECEIVED PING PACKET");	  c->c2.buf.len = 0; /* drop packet */	}      /* Did we just receive an OCC packet? */      if (is_occ_msg (&c->c2.buf))	process_received_occ_msg (c);            c->c2.to_tun = c->c2.buf;      /* to_tun defined + unopened tuntap can cause deadlock */      if (!tuntap_defined (c->c1.tuntap))	c->c2.to_tun.len = 0;    }  else    {      buf_reset (&c->c2.to_tun);    } done:  gc_free (&gc);}voidread_incoming_tun (struct context *c){  /*   * Setup for read() call on TUN/TAP device.   */  ASSERT (!c->c2.to_link.len);  c->c2.buf = c->c2.buffers->read_tun_buf;#ifdef TUN_PASS_BUFFER  read_tun_buffered (c->c1.tuntap, &c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame));#else  ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM (&c->c2.frame)));  ASSERT (buf_safe (&c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame)));  c->c2.buf.len = read_tun (c->c1.tuntap, BPTR (&c->c2.buf), MAX_RW_SIZE_TUN (&c->c2.frame));#endif  /* Was TUN/TAP interface stopped? */  if (tuntap_stop (c->c2.buf.len))    {      c->sig->signal_received = SIGTERM;      c->sig->signal_text = "tun-stop";      msg (M_INFO, "TUN/TAP interface has been stopped, exiting");      return;		      }  /* Check the status return from read() */  check_status (c->c2.buf.len, "read from TUN/TAP", NULL, c->c1.tuntap);}voidprocess_incoming_tun (struct context *c){  struct gc_arena gc = gc_new ();  if (c->c2.buf.len > 0)    c->c2.tun_read_bytes += c->c2.buf.len;#ifdef LOG_RW  if (c->c2.log_rw)    fprintf (stderr, "r");#endif  /* Show packet content */  msg (D_TUN_RW, "TUN READ [%d]: %s md5=%s",       BLEN (&c->c2.buf),       format_hex (BPTR (&c->c2.buf), BLEN (&c->c2.buf), 80, &gc),       MD5SUM (BPTR (&c->c2.buf), BLEN (&c->c2.buf), &gc));  if (c->c2.buf.len > 0)    {      /*       * The --passtos and --mssfix options require       * us to examine the IPv4 header.       */      if (c->options.mssfix#if PASSTOS_CAPABILITY	  || c->options.passtos#endif	  )	{	  struct buffer ipbuf = c->c2.buf;	  if (is_ipv4 (TUNNEL_TYPE (c->c1.tuntap), &ipbuf))	    {#if PASSTOS_CAPABILITY	      /* extract TOS from IP header */	      if (c->options.passtos)		{		  struct openvpn_iphdr *iph = 		    (struct openvpn_iphdr *) BPTR (&ipbuf);		  c->c2.ptos = iph->tos;		  c->c2.ptos_defined = true;		}#endif			  	      /* possibly alter the TCP MSS */	      if (c->options.mssfix)		mss_fixup (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame)));	    }	}      encrypt_sign (c, true);    }  else    {      buf_reset (&c->c2.to_link);    }  gc_free (&gc);}voidprocess_outgoing_link (struct context *c){  struct gc_arena gc = gc_new ();  if (c->c2.to_link.len > 0 && c->c2.to_link.len <= EXPANDED_SIZE (&c->c2.frame))    {      /*       * Setup for call to send/sendto which will send       * packet to remote over the TCP/UDP port.       */      int size;      ASSERT (addr_defined (&c->c2.to_link_addr));      /* In gremlin-test mode, we may choose to drop this packet */      if (!c->options.gremlin || ask_gremlin())	{	  /*	   * Let the traffic shaper know how many bytes	   * we wrote.	   */#ifdef HAVE_GETTIMEOFDAY	  if (c->options.shaper)	    shaper_wrote_bytes (&c->c2.shaper, BLEN (&c->c2.to_link)				+ datagram_overhead (c->options.proto));#endif	  /*	   * Let the pinger know that we sent a packet.	   */	  if (c->options.ping_send_timeout)	    event_timeout_reset (&c->c2.ping_send_interval);#if PASSTOS_CAPABILITY	  /* Set TOS */	  if (c->c2.ptos_defined)	    setsockopt (c->c2.link_socket->sd, IPPROTO_IP, IP_TOS, &c->c2.ptos, sizeof (c->c2.ptos));#endif	  /* Log packet send */#ifdef LOG_RW	  if (c->c2.log_rw)	    fprintf (stderr, "W");#endif	  msg (D_LINK_RW, "%s WRITE [%d] to %s: %s",	       proto2ascii (c->c2.link_socket->info.proto, true),	       BLEN (&c->c2.to_link),	       print_sockaddr (&c->c2.to_link_addr, &gc),	       PROTO_DUMP (&c->c2.to_link, &gc));	  /* Packet send complexified by possible Socks5 usage */	  {	    struct sockaddr_in *to_addr = &c->c2.to_link_addr;	    int size_delta = 0;	    /* If Socks5 over UDP, prepend header */	    socks_preprocess_outgoing_link (c, &to_addr, &size_delta);	    /* Send packet */	    size = link_socket_write (c->c2.link_socket, &c->c2.to_link, to_addr);	    /* Undo effect of prepend */	    link_socket_write_post_size_adjust (&size, size_delta, &c->c2.to_link);	  }	  if (size > 0)	    {	      c->c2.max_send_size_local = max_int (size, c->c2.max_send_size_local);	      c->c2.link_write_bytes += size;	    }	}      else	size = 0;      /* Check return status */      check_status (size, "write", c->c2.link_socket, NULL);      if (size > 0)	{	  /* Did we write a different size packet than we intended? */	  if (size != BLEN (&c->c2.to_link))	    msg (D_LINK_ERRORS,		 "TCP/UDP packet was truncated/expanded on write to %s (tried=%d,actual=%d)",		 print_sockaddr (&c->c2.to_link_addr, &gc),		 BLEN (&c->c2.to_link),		 size);	}    }  else    {      if (c->c2.to_link.len > 0)	msg (D_LINK_ERRORS, "TCP/UDP packet too large on write to %s (tried=%d,max=%d)",	     print_sockaddr (&c->c2.to_link_addr, &gc),	     c->c2.to_link.len,	     EXPANDED_SIZE (&c->c2.frame));    }  buf_reset (&c->c2.to_link);  gc_free (&gc);}voidprocess_outgoing_tun (struct context *c){  struct gc_arena gc = gc_new ();  /*   * Set up for write() call to TUN/TAP   * device.   */  ASSERT (c->c2.to_tun.len > 0);  /*   * The --mssfix option requires   * us to examine the IPv4 header.   */  if (c->options.mssfix)    {      struct buffer ipbuf = c->c2.to_tun;      if (is_ipv4 (c->c1.tuntap->type, &ipbuf))	{	  /* possibly alter the TCP MSS */	  if (c->options.mssfix)	    mss_fixup (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame)));	}    }	        if (c->c2.to_tun.len <= MAX_RW_SIZE_TUN (&c->c2.frame))    {      /*       * Write to TUN/TAP device.       */      int size;#ifdef LOG_RW      if (c->c2.log_rw)	fprintf (stderr, "w");#endif      msg (D_TUN_RW, "TUN WRITE [%d]: %s md5=%s",	   BLEN (&c->c2.to_tun),	   format_hex (BPTR (&c->c2.to_tun), BLEN (&c->c2.to_tun), 80, &gc),	   MD5SUM (BPTR (&c->c2.to_tun), BLEN (&c->c2.to_tun), &gc));#ifdef TUN_PASS_BUFFER      size = write_tun_buffered (c->c1.tuntap, &c->c2.to_tun);#else      size = write_tun (c->c1.tuntap, BPTR (&c->c2.to_tun), BLEN (&c->c2.to_tun));#endif      if (size > 0)	c->c2.tun_write_bytes += size;      check_status (size, "write to TUN/TAP", NULL, c->c1.tuntap);      /* check written packet size */      if (size > 0)	{	  /* Did we write a different size packet than we intended? */	  if (size != BLEN (&c->c2.to_tun))	    msg (D_LINK_ERRORS,		 "TUN/TAP packet was destructively fragmented on write to %s (tried=%d,actual=%d)",		 c->c1.tuntap->actual_name,		 BLEN (&c->c2.to_tun),		 size);	}    }  else    {      /*       * This should never happen, probably indicates some kind       * of MTU mismatch.       */      msg (D_LINK_ERRORS, "tun packet too large on write (tried=%d,max=%d)",	   c->c2.to_tun.len,	   MAX_RW_SIZE_TUN (&c->c2.frame));    }  /*   * Putting the --inactive timeout reset here, ensures that we will timeout   * if the remote goes away, even if we are trying to send data to the   * remote and failing.   */  register_activity (c);  buf_reset (&c->c2.to_tun);  gc_free (&gc);}voidpre_select (struct context *c){  /* make sure current time (now) is updated on function entry */  /*   * Start with an effectively infinite timeout, then let it   * reduce to a timeout that reflects the component which   * needs the earliest service.   */  c->c2.timeval.tv_sec = BIG_TIMEOUT;  c->c2.timeval.tv_usec = 0;#if defined(WIN32) && defined(TAP_WIN32_DEBUG)  c->c2.timeval.tv_sec = 1;  if (tuntap_defined (c->c1.tuntap) && check_debug_level (D_TAP_WIN32_DEBUG))    tun_show_debug (c->c1.tuntap);#endif  /* check coarse timers? */  check_coarse_timers (c);  if (c->sig->signal_received)    return;  /* Does TLS need service? */  check_tls (c);  /* In certain cases, TLS errors will require a restart */  check_tls_errors (c);  if (c->sig->signal_received)    return;  /* check for incoming configuration info on the control channel */  check_incoming_control_channel (c);  /* Should we send an OCC message? */  check_send_occ_msg (c);  /* Should we deliver a datagram fragment to remote? */  check_fragment (c);  /* Update random component of timeout */  check_timeout_random_component (c);}/* * Wait for I/O events.  Used for both TCP & UDP sockets * in point-to-point mode and for UDP sockets in * point-to-multipoint mode. */voidio_wait (struct context *c,	 unsigned int flags){  unsigned int socket = 0;  unsigned int tuntap = 0;  struct event_set_return esr[3];  /* These shifts all depend on EVENT_READ and EVENT_WRITE */  static const int socket_shift = 0; /* depends on SOCKET_READ and SOCKET_WRITE */  static const int tun_shift = 2;    /* depends on TUN_READ and TUN_WRITE */  static const int err_shift = 4;    /* depends on ES_ERROR */  /*   * Decide what kind of events we want to wait for.   */  event_reset (c->c2.event_set);  /*   * On win32 we use the keyboard or an event object as a source   * of asynchronous signals.   */  wait_signal (c->c2.event_set, (void*)&err_shift);  /*   * If outgoing data (for TCP/UDP port) pending, wait for ready-to-send   * status from TCP/UDP port. Otherwise, wait for incoming data on   * TUN/TAP device.   */  if (flags & IOW_TO_LINK)    {      if (flags & IOW_SHAPER)	{	  /*	   * If sending this packet would put us over our traffic shaping	   * quota, don't send -- instead compute the delay we must wait	   * until it will be OK to send the packet.	   */#ifdef HAVE_GETTIMEOFDAY	  int delay = 0;	  /* set traffic shaping delay in microseconds */	  if (c->options.shaper)	    delay = max_int (delay, shaper_delay (&c->c2.shaper));	  	  if (delay < 1000)	    {	      socket |= EVENT_WRITE;	    }	  else	    {	      shaper_soonest_event (&c->c2.timeval, delay);	    }#else /* HAVE_GETTIMEOFDAY */	  socket |= EVENT_WRITE;#endif /* HAVE_GETTIMEOFDAY */	}      else	{	  socket |= EVENT_WRITE;	}    }  else if (!((flags & IOW_FRAG) && TO_LINK_FRAG (c)))    {      if (flags & IOW_READ)	tuntap |= EVENT_READ;    }  /*   * outgoing bcast buffer waiting to be sent?   */  if (flags & IOW_MBUF)    socket |= EVENT_WRITE;  /*   * If outgoing data (for TUN/TAP device) pending, wait for ready-to-send status   * from device.  Otherwise, wait for incoming data on TCP/UDP port.   */  if (flags & IOW_TO_TUN)    {      tuntap |= EVENT_WRITE;    }  else    {      if (flags & IOW_READ)	socket |= EVENT_READ;    }  /*   * Configure event wait based on socket, tuntap flags.   */  socket_set (c->c2.link_socket, c->c2.event_set, socket, (void*)&socket_shift);  tun_set (c->c1.tuntap, c->c2.event_set, tuntap, (void*)&tun_shift);  /*   * Possible scenarios:   *  (1) tcp/udp port has data available to read   *  (2) tcp/udp port is ready to accept more data to write   *  (3) tun dev has data available to read   *  (4) tun dev is ready to accept more data to write   *  (5) we received a signal (handler sets signal_received)   *  (6) timeout (tv) expired   */  c->c2.event_set_status = ES_ERROR;  if (!c->sig->signal_received)    {      if (!(flags & IOW_CHECK_RESIDUAL) || !socket_read_residual (c->c2.link_socket))	{	  int status;	  if (check_debug_level (D_EVENT_WAIT))	    show_wait_status (c);	  /*	   * Wait for something to happen.	   */	  status = event_wait (c->c2.event_set, &c->c2.timeval, esr, SIZE(esr));	  check_status (status, "event_wait", NULL, NULL);	  if (status > 0)	    {	      int i;	      c->c2.event_set_status = 0;	      for (i = 0; i < status; ++i)		{		  const struct event_set_return *e = &esr[i];		  c->c2.event_set_status |= ((e->rwflags & 3) << *((int*)e->arg));		}	    }	  else if (status == 0)	    {	      c->c2.event_set_status = ES_TIMEOUT;	    }	}      else	{	  c->c2.event_set_status = SOCKET_READ;	}    }  /* 'now' should always be a reasonably up-to-date timestamp */  update_time ();  /* set signal_received if a signal was received */  if (c->c2.event_set_status & ES_ERROR)    get_signal (&c->sig->signal_received);  msg (D_EVENT_WAIT, "I/O WAIT status=0x%04x", c->c2.event_set_status);}voidprocess_io (struct context *c){  const unsigned int status = c->c2.event_set_status;  /* TCP/UDP port ready to accept write */  if (status & SOCKET_WRITE)    {      process_outgoing_link (c);    }  /* TUN device ready to accept write */  else if (status & TUN_WRITE)    {      process_outgoing_tun (c);    }  /* Incoming data on TCP/UDP port */  else if (status & SOCKET_READ)    {      read_incoming_link (c);      if (!IS_SIG (c))	process_incoming_link (c);    }  /* Incoming data on TUN device */  else if (status & TUN_READ)    {      read_incoming_tun (c);      if (!IS_SIG (c))	process_incoming_tun (c);    }}

⌨️ 快捷键说明

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