示例#1
0
文件: mtu.c 项目: angelol/iOpenVPN
/*
 * Set the tun MTU dynamically.
 */
void
frame_set_mtu_dynamic (struct frame *frame, int mtu, unsigned int flags)
{

#ifdef ENABLE_DEBUG
  const int orig_mtu = mtu;
  const int orig_link_mtu_dynamic = frame->link_mtu_dynamic;
#endif

  ASSERT (mtu >= 0);

  if (flags & SET_MTU_TUN)
    mtu += TUN_LINK_DELTA (frame);

  if (!(flags & SET_MTU_UPPER_BOUND) || mtu < frame->link_mtu_dynamic)
    {
      frame->link_mtu_dynamic = constrain_int (
	mtu,
	EXPANDED_SIZE_MIN (frame),
	EXPANDED_SIZE (frame));
    }

  dmsg (D_MTU_DEBUG, "MTU DYNAMIC mtu=%d, flags=%u, %d -> %d",
       orig_mtu,
       flags,
       orig_link_mtu_dynamic,
       frame->link_mtu_dynamic);
}
示例#2
0
文件: comp.c 项目: Distrotech/openvpn
void
comp_add_to_extra_buffer(struct frame *frame)
{
  /* Leave room for compression buffer to expand in worst case scenario
     where data is totally uncompressible */
  frame_add_to_extra_buffer (frame, COMP_EXTRA_BUFFER (EXPANDED_SIZE(frame)));
}
示例#3
0
文件: occ.c 项目: liuxfiu/primogeni
void
check_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 " PACKAGE_NAME " 1.5 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;
	}
    }
}
示例#4
0
文件: lzo.c 项目: OpenVPN/openvpn
static void
lzo_decompress(struct buffer *buf, struct buffer work,
               struct compress_context *compctx,
               const struct frame *frame)
{
    lzo_uint zlen = EXPANDED_SIZE(frame);
    int err;
    uint8_t c;          /* flag indicating whether or not our peer compressed */

    if (buf->len <= 0)
    {
        return;
    }

    ASSERT(buf_init(&work, FRAME_HEADROOM(frame)));

    c = *BPTR(buf);
    ASSERT(buf_advance(buf, 1));

    if (c == LZO_COMPRESS_BYTE) /* packet was compressed */
    {
        ASSERT(buf_safe(&work, zlen));
        err = LZO_DECOMPRESS(BPTR(buf), BLEN(buf), BPTR(&work), &zlen,
                             compctx->wu.lzo.wmem);
        if (err != LZO_E_OK)
        {
            dmsg(D_COMP_ERRORS, "LZO decompression error: %d", err);
            buf->len = 0;
            return;
        }

        ASSERT(buf_safe(&work, zlen));
        work.len = zlen;

        dmsg(D_COMP, "LZO decompress %d -> %d", buf->len, work.len);
        compctx->pre_decompress += buf->len;
        compctx->post_decompress += work.len;

        *buf = work;
    }
    else if (c == NO_COMPRESS_BYTE)     /* packet was not compressed */
    {
    }
    else
    {
        dmsg(D_COMP_ERRORS, "Bad LZO decompression header byte: %d", c);
        buf->len = 0;
    }
}
示例#5
0
static void
lz4v2_decompress(struct buffer *buf, struct buffer work,
                 struct compress_context *compctx,
                 const struct frame *frame)
{
    size_t zlen_max = EXPANDED_SIZE(frame);
    uint8_t c;          /* flag indicating whether or not our peer compressed */

    if (buf->len <= 0)
    {
        return;
    }

    ASSERT(buf_init(&work, FRAME_HEADROOM(frame)));

    /* do unframing/swap (assumes buf->len > 0) */
    uint8_t *head = BPTR(buf);
    c = *head;

    /* Not compressed */
    if (c != COMP_ALGV2_INDICATOR_BYTE)
    {
        return;
    }

    /* Packet to short to make sense */
    if (buf->len <= 1)
    {
        buf->len = 0;
        return;
    }

    c = head[1];
    if (c == COMP_ALGV2_LZ4_BYTE) /* packet was compressed */
    {
        buf_advance(buf,2);
        do_lz4_decompress(zlen_max, &work, buf, compctx);
    }
    else if (c == COMP_ALGV2_UNCOMPRESSED_BYTE)
    {
        buf_advance(buf,2);
    }
    else
    {
        dmsg(D_COMP_ERRORS, "Bad LZ4v2 decompression header byte: %d", c);
        buf->len = 0;
    }
}
示例#6
0
static void
lz4_decompress(struct buffer *buf, struct buffer work,
               struct compress_context *compctx,
               const struct frame *frame)
{
    size_t zlen_max = EXPANDED_SIZE(frame);
    uint8_t c;          /* flag indicating whether or not our peer compressed */

    if (buf->len <= 0)
    {
        return;
    }

    ASSERT(buf_init(&work, FRAME_HEADROOM(frame)));

    /* do unframing/swap (assumes buf->len > 0) */
    {
        uint8_t *head = BPTR(buf);
        c = *head;
        --buf->len;
        *head = *BEND(buf);
    }

    if (c == LZ4_COMPRESS_BYTE) /* packet was compressed */
    {
        do_lz4_decompress(zlen_max, &work, buf, compctx);
    }
    else if (c == NO_COMPRESS_BYTE_SWAP) /* packet was not compressed */
    {
    }
    else
    {
        dmsg(D_COMP_ERRORS, "Bad LZ4 decompression header byte: %d", c);
        buf->len = 0;
    }
}
示例#7
0
void
process_outgoing_link (struct context *c)
{
  struct gc_arena gc = gc_new ();

  perf_push (PERF_PROC_OUT_LINK);

  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 = 0;
      ASSERT (link_socket_actual_defined (c->c2.to_link_addr));

#ifdef ENABLE_DEBUG
      /* In gremlin-test mode, we may choose to drop this packet */
      if (!c->options.gremlin || ask_gremlin (c->options.gremlin))
#endif
	{
	  /*
	   * Let the traffic shaper know how many bytes
	   * we wrote.
	   */
#ifdef ENABLE_FEATURE_SHAPER
	  if (c->options.shaper)
	    shaper_wrote_bytes (&c->c2.shaper, BLEN (&c->c2.to_link)
				+ datagram_overhead (c->options.ce.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 */
	  link_socket_set_tos (c->c2.link_socket);
#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_link_socket_actual (c->c2.to_link_addr, &gc),
	       PROTO_DUMP (&c->c2.to_link, &gc));

	  /* Packet send complexified by possible Socks5 usage */
	  {
	    struct link_socket_actual *to_addr = c->c2.to_link_addr;
#ifdef ENABLE_SOCKS
	    int size_delta = 0;
#endif

#ifdef ENABLE_SOCKS
	    /* If Socks5 over UDP, prepend header */
	    socks_preprocess_outgoing_link (c, &to_addr, &size_delta);
#endif
	    /* Send packet */
	    size = link_socket_write (c->c2.link_socket,
				      &c->c2.to_link,
				      to_addr);

#ifdef ENABLE_SOCKS
	    /* Undo effect of prepend */
	    link_socket_write_post_size_adjust (&size, size_delta, &c->c2.to_link);
#endif
	  }

	  if (size > 0)
	    {
	      c->c2.max_send_size_local = max_int (size, c->c2.max_send_size_local);
	      c->c2.link_write_bytes += size;
	      link_write_bytes_global += size;
#ifdef ENABLE_MEMSTATS
	      if (mmap_stats)
		mmap_stats->link_write_bytes = link_write_bytes_global;
#endif
#ifdef ENABLE_MANAGEMENT
	      if (management)
		{
		  management_bytes_out (management, size);
#ifdef MANAGEMENT_DEF_AUTH
		  management_bytes_server (management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context);
#endif
		}
#endif
	    }
	}

      /* 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_link_socket_actual (c->c2.to_link_addr, &gc),
		 BLEN (&c->c2.to_link),
		 size);
	}

      /* if not a ping/control message, indicate activity regarding --inactive parameter */
      if (c->c2.buf.len > 0 )
        register_activity (c, 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_link_socket_actual (c->c2.to_link_addr, &gc),
	     c->c2.to_link.len,
	     EXPANDED_SIZE (&c->c2.frame));
    }

  buf_reset (&c->c2.to_link);

  perf_pop ();
  gc_free (&gc);
}
示例#8
0
文件: occ.c 项目: liuxfiu/primogeni
void
check_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;
      dmsg (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;
      dmsg (D_PACKET_CONTENT, "SENT OCC_REPLY");
      doit = true;
      break;

    case OCC_MTU_REQUEST:
      if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REQUEST))
	break;
      dmsg (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;
      dmsg (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;
      dmsg (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, EXPANDED_SIZE (&c->c2.frame))
			       - OCC_STRING_SIZE
			       - sizeof (uint8_t)
	                       - EXTRA_FRAME (&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;
	  }
	dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD min_int(%d-%d-%d-%d,%d) size=%d",
	     c->c2.occ_mtu_load_size,
	     OCC_STRING_SIZE,
	      (int) sizeof (uint8_t),
	     EXTRA_FRAME (&c->c2.frame),
	     MAX_RW_SIZE_TUN (&c->c2.frame),
	     BLEN (&c->c2.buf));
	doit = true;
      }
      break;

    case OCC_EXIT:
      if (!buf_write_u8 (&c->c2.buf, OCC_EXIT))
	break;
      dmsg (D_PACKET_CONTENT, "SENT OCC_EXIT");
      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;
}