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

📄 occ.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
字号:
/* *  OpenVPN -- An application to securely tunnel IP networks *             over a single TCP/UDP port, with support for SSL/TLS-based *             session authentication and key exchange, *             packet encryption, packet authentication, and *             packet compression. * *  Copyright (C) 2002-2004 James Yonan <jim@yonan.net> * *  This program 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 of the License, or *  (at your option) any later version. * *  This program 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 this program (see the file COPYING included with this *  distribution); if not, write to the Free Software Foundation, Inc., *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#ifdef WIN32#include "config-win32.h"#else#include "config.h"#endif#include "syshead.h"#include "occ.h"#include "memdbg.h"#include "forward-inline.h"#include "occ-inline.h"/* * This random string identifies an OpenVPN * options consistency check packet. * It should be of sufficient length and randomness * so as not to collide with other tunnel data. * * The OCC protocol is as follows: * * occ_magic -- (16 octets) * * type [OCC_REQUEST | OCC_REPLY] (1 octet) * null terminated options string if OCC_REPLY (variable) * * When encryption is used, the OCC packet * is encapsulated within the encrypted * envelope. * * OCC_STRING_SIZE must be set to sizeof (occ_magic) */const uint8_t occ_magic[] = {  0x28, 0x7f, 0x34, 0x6b, 0xd4, 0xef, 0x7a, 0x81,  0x2d, 0x56, 0xb8, 0xd3, 0xaf, 0xc5, 0x45, 0x9c};static const struct mtu_load_test mtu_load_test_sequence[] = {  {OCC_MTU_LOAD_REQUEST, -1000},  {OCC_MTU_LOAD, -1000},  {OCC_MTU_LOAD_REQUEST, -1000},  {OCC_MTU_LOAD, -1000},  {OCC_MTU_LOAD_REQUEST, -1000},  {OCC_MTU_LOAD, -1000},  {OCC_MTU_LOAD_REQUEST, -500},  {OCC_MTU_LOAD, -500},  {OCC_MTU_LOAD_REQUEST, -500},  {OCC_MTU_LOAD, -500},  {OCC_MTU_LOAD_REQUEST, -500},  {OCC_MTU_LOAD, -500},  {OCC_MTU_LOAD_REQUEST, -750},  {OCC_MTU_LOAD, -750},  {OCC_MTU_LOAD_REQUEST, -750},  {OCC_MTU_LOAD, -750},  {OCC_MTU_LOAD_REQUEST, -750},  {OCC_MTU_LOAD, -750},  {OCC_MTU_LOAD_REQUEST, -400},  {OCC_MTU_LOAD, -400},  {OCC_MTU_LOAD_REQUEST, -400},  {OCC_MTU_LOAD, -400},  {OCC_MTU_LOAD_REQUEST, -400},  {OCC_MTU_LOAD, -400},  {OCC_MTU_LOAD_REQUEST, -300},  {OCC_MTU_LOAD, -300},  {OCC_MTU_LOAD_REQUEST, -300},  {OCC_MTU_LOAD, -300},  {OCC_MTU_LOAD_REQUEST, -300},  {OCC_MTU_LOAD, -300},  {OCC_MTU_LOAD_REQUEST, -200},  {OCC_MTU_LOAD, -200},  {OCC_MTU_LOAD_REQUEST, -200},  {OCC_MTU_LOAD, -200},  {OCC_MTU_LOAD_REQUEST, -200},  {OCC_MTU_LOAD, -200},  {OCC_MTU_LOAD_REQUEST, -150},  {OCC_MTU_LOAD, -150},  {OCC_MTU_LOAD_REQUEST, -150},  {OCC_MTU_LOAD, -150},  {OCC_MTU_LOAD_REQUEST, -150},  {OCC_MTU_LOAD, -150},  {OCC_MTU_LOAD_REQUEST, -100},  {OCC_MTU_LOAD, -100},  {OCC_MTU_LOAD_REQUEST, -100},  {OCC_MTU_LOAD, -100},  {OCC_MTU_LOAD_REQUEST, -100},  {OCC_MTU_LOAD, -100},  {OCC_MTU_LOAD_REQUEST, -50},  {OCC_MTU_LOAD, -50},  {OCC_MTU_LOAD_REQUEST, -50},  {OCC_MTU_LOAD, -50},  {OCC_MTU_LOAD_REQUEST, -50},  {OCC_MTU_LOAD, -50},  {OCC_MTU_LOAD_REQUEST, 0},  {OCC_MTU_LOAD, 0},  {OCC_MTU_LOAD_REQUEST, 0},  {OCC_MTU_LOAD, 0},  {OCC_MTU_LOAD_REQUEST, 0},  {OCC_MTU_LOAD, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {OCC_MTU_REQUEST, 0},  {-1, 0}};voidcheck_send_occ_req_dowork (struct context *c){  if (++c->c2.occ_n_tries >= OCC_N_TRIES)    {      if (c->options.remote_list)	/*	 * No OCC_REPLY from peer after repeated attempts.	 * Give up.	 */	msg (D_SHOW_OCC,	     "NOTE: failed to obtain options consistency info from peer -- this could occur if the remote peer is running a version of "	     PACKAGE_NAME	     " before 1.5-beta8 or if there is a network connectivity problem, and will not necessarily prevent "	     PACKAGE_NAME	     " from running (%u bytes received from peer, %u bytes authenticated data channel traffic) -- you can disable the options consistency check with --disable-occ.",	     (unsigned int) c->c2.link_read_bytes,	     (unsigned int) c->c2.link_read_bytes_auth);      event_timeout_clear (&c->c2.occ_interval);    }  else    {      c->c2.occ_op = OCC_REQUEST;      /*       * If we don't hear back from peer, send another       * OCC_REQUEST in OCC_INTERVAL_SECONDS.       */      event_timeout_reset (&c->c2.occ_interval);    }}voidcheck_send_occ_load_test_dowork (struct context *c){  if (CONNECTION_ESTABLISHED (c))    {      const struct mtu_load_test *entry;      if (!c->c2.occ_mtu_load_n_tries)	msg (M_INFO,	     "NOTE: Beginning empirical MTU test -- results should be available in 3 to 4 minutes.");      entry = &mtu_load_test_sequence[c->c2.occ_mtu_load_n_tries++];      if (entry->op >= 0)	{	  c->c2.occ_op = entry->op;	  c->c2.occ_mtu_load_size =	    EXPANDED_SIZE (&c->c2.frame) + entry->delta;	}      else	{	  msg (M_INFO,	       "NOTE: failed to empirically measure MTU (requires 1.5-beta8 or higher at other end of connection).");	  event_timeout_clear (&c->c2.occ_mtu_load_test_interval);	  c->c2.occ_mtu_load_n_tries = 0;	}    }}voidcheck_send_occ_msg_dowork (struct context *c){  bool doit = false;  c->c2.buf = c->c2.buffers->aux_buf;  ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM (&c->c2.frame)));  ASSERT (buf_safe (&c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame)));  ASSERT (buf_write (&c->c2.buf, occ_magic, OCC_STRING_SIZE));  switch (c->c2.occ_op)    {    case OCC_REQUEST:      if (!buf_write_u8 (&c->c2.buf, OCC_REQUEST))	break;      msg (D_PACKET_CONTENT, "SENT OCC_REQUEST");      doit = true;      break;    case OCC_REPLY:      if (!c->c2.options_string_local)	break;      if (!buf_write_u8 (&c->c2.buf, OCC_REPLY))	break;      if (!buf_write (&c->c2.buf, c->c2.options_string_local,		      strlen (c->c2.options_string_local) + 1))	break;      msg (D_PACKET_CONTENT, "SENT OCC_REPLY");      doit = true;      break;    case OCC_MTU_REQUEST:      if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REQUEST))	break;      msg (D_PACKET_CONTENT, "SENT OCC_MTU_REQUEST");      doit = true;      break;    case OCC_MTU_REPLY:      if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REPLY))	break;      if (!buf_write_u16 (&c->c2.buf, c->c2.max_recv_size_local))	break;      if (!buf_write_u16 (&c->c2.buf, c->c2.max_send_size_local))	break;      msg (D_PACKET_CONTENT, "SENT OCC_MTU_REPLY");      doit = true;      break;    case OCC_MTU_LOAD_REQUEST:      if (!buf_write_u8 (&c->c2.buf, OCC_MTU_LOAD_REQUEST))	break;      if (!buf_write_u16 (&c->c2.buf, c->c2.occ_mtu_load_size))	break;      msg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD_REQUEST");      doit = true;      break;    case OCC_MTU_LOAD:      {	int need_to_add;	if (!buf_write_u8 (&c->c2.buf, OCC_MTU_LOAD))	  break;	need_to_add = min_int (c->c2.occ_mtu_load_size			       - OCC_STRING_SIZE			       - sizeof (uint8_t)			       - EXTRA_FRAME (&c->c2.frame), 			       EXPANDED_SIZE (&c->c2.frame));	while (need_to_add > 0)	  {	    /*	     * Fill the load test packet with pseudo-random bytes.	     */	    if (!buf_write_u8 (&c->c2.buf, get_random () & 0xFF))	      break;	    --need_to_add;	  }	msg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD %d",	     c->c2.occ_mtu_load_size);	doit = true;      }      break;    }  if (doit)    {      /*       * We will treat the packet like any other outgoing packet,       * compress, encrypt, sign, etc.       */      encrypt_sign (c, true);    }  c->c2.occ_op = -1;}voidprocess_received_occ_msg (struct context *c){  ASSERT (buf_advance (&c->c2.buf, OCC_STRING_SIZE));  switch (buf_read_u8 (&c->c2.buf))    {    case OCC_REQUEST:      msg (D_PACKET_CONTENT, "RECEIVED OCC_REQUEST");      c->c2.occ_op = OCC_REPLY;      break;    case OCC_MTU_REQUEST:      msg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_REQUEST");      c->c2.occ_op = OCC_MTU_REPLY;      break;    case OCC_MTU_LOAD_REQUEST:      msg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_LOAD_REQUEST");      c->c2.occ_mtu_load_size = buf_read_u16 (&c->c2.buf);      if (c->c2.occ_mtu_load_size >= 0)	c->c2.occ_op = OCC_MTU_LOAD;      break;    case OCC_REPLY:      msg (D_PACKET_CONTENT, "RECEIVED OCC_REPLY");      if (c->options.occ && !TLS_MODE && c->c2.options_string_remote)	{	  if (!options_cmp_equal (BPTR (&c->c2.buf),				  c->c2.options_string_remote,				  c->c2.buf.len))	    {	      options_warning (BPTR (&c->c2.buf),			       c->c2.options_string_remote,			       c->c2.buf.len);	    }	}      event_timeout_clear (&c->c2.occ_interval);      break;    case OCC_MTU_REPLY:      msg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_REPLY");      c->c2.max_recv_size_remote = buf_read_u16 (&c->c2.buf);      c->c2.max_send_size_remote = buf_read_u16 (&c->c2.buf);      if (c->options.mtu_test	  && c->c2.max_recv_size_remote > 0	  && c->c2.max_send_size_remote > 0)	{	  msg (M_INFO, "NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[%d,%d] remote->local=[%d,%d]",	       c->c2.max_send_size_local,	       c->c2.max_recv_size_remote,	       c->c2.max_send_size_remote,	       c->c2.max_recv_size_local);	  if (!c->options.fragment	      && c->options.proto == PROTO_UDPv4	      && c->c2.max_send_size_local > TUN_MTU_MIN	      && (c->c2.max_recv_size_remote < c->c2.max_send_size_local		  || c->c2.max_recv_size_local < c->c2.max_send_size_remote))	    msg (M_INFO, "NOTE: This connection is unable to accomodate a UDP packet size of %d. Consider using --fragment or --mssfix options as a workaround.",		 c->c2.max_send_size_local);	}      event_timeout_clear (&c->c2.occ_mtu_load_test_interval);      break;    }  c->c2.buf.len = 0; /* don't pass packet on */}

⌨️ 快捷键说明

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