コード例 #1
0
ファイル: mroute.c プロジェクト: OpenVPN/openvpn
/*
 * Don't learn certain addresses.
 */
bool
mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc)
{
    int i;
    bool all_zeros = true;
    bool all_ones = true;

    for (i = 0; i < addr->len; ++i)
    {
        int b = addr->raw_addr[i];
        if (b != 0x00)
        {
            all_zeros = false;
        }
        if (b != 0xFF)
        {
            all_ones = false;
        }
    }

    /* only networkss shorter than 8 bits are allowed to be all 0s. */
    if (all_zeros
        && !((addr->type & MR_WITH_NETBITS) && (addr->netbits < 8)))
    {
        msg(D_MULTI_LOW, "Can't learn %s: network is all 0s, but netbits >= 8",
            mroute_addr_print(addr, gc));
        return false;
    }

    if (all_ones)
    {
        msg(D_MULTI_LOW, "Can't learn %s: network is all 1s",
            mroute_addr_print(addr, gc));
        return false;
    }

    if (is_mac_mcast_maddr(addr))
    {
        msg(D_MULTI_LOW, "Can't learn %s: network is a multicast address",
            mroute_addr_print(addr, gc));
        return false;
    }

    return true;
}
コード例 #2
0
ファイル: mtcp.c プロジェクト: ikelos/openvpn
static struct multi_instance *
multi_create_instance_tcp(struct multi_context *m)
{
    struct gc_arena gc = gc_new();
    struct multi_instance *mi = NULL;
    struct hash *hash = m->hash;

    mi = multi_create_instance(m, NULL);
    if (mi)
    {
        struct hash_element *he;
        const uint32_t hv = hash_value(hash, &mi->real);
        struct hash_bucket *bucket = hash_bucket(hash, hv);

        he = hash_lookup_fast(hash, bucket, &mi->real, hv);

        if (he)
        {
            struct multi_instance *oldmi = (struct multi_instance *) he->value;
            msg(D_MULTI_LOW, "MULTI TCP: new incoming client address matches existing client address -- new client takes precedence");
            oldmi->did_real_hash = false;
            multi_close_instance(m, oldmi, false);
            he->key = &mi->real;
            he->value = mi;
        }
        else
        {
            hash_add_fast(hash, bucket, &mi->real, hv, mi);
        }

        mi->did_real_hash = true;
    }

#ifdef ENABLE_DEBUG
    if (mi)
    {
        dmsg(D_MULTI_DEBUG, "MULTI TCP: instance added: %s", mroute_addr_print(&mi->real, &gc));
    }
    else
    {
        dmsg(D_MULTI_DEBUG, "MULTI TCP: new client instance failed");
    }
#endif

    gc_free(&gc);
    ASSERT(!(mi && mi->halt));
    return mi;
}
コード例 #3
0
ファイル: mudp.c プロジェクト: 51isoft/openvpn-ipv6
struct multi_instance *
multi_get_create_instance_udp (struct multi_context *m)
{
  struct gc_arena gc = gc_new ();
  struct mroute_addr real;
  struct multi_instance *mi = NULL;
  struct hash *hash = m->hash;

  if (mroute_extract_openvpn_sockaddr (&real, &m->top.c2.from.dest, true))
    {
      struct hash_element *he;
      const uint32_t hv = hash_value (hash, &real);
      struct hash_bucket *bucket = hash_bucket (hash, hv);
  
      he = hash_lookup_fast (hash, bucket, &real, hv);

      if (he)
	{
	  mi = (struct multi_instance *) he->value;
	}
      else
	{
	  if (!m->top.c2.tls_auth_standalone
	      || tls_pre_decrypt_lite (m->top.c2.tls_auth_standalone, &m->top.c2.from, &m->top.c2.buf))
	    {
	      if (frequency_limit_event_allowed (m->new_connection_limiter))
		{
		  mi = multi_create_instance (m, &real);
		  if (mi)
		    {
		      hash_add_fast (hash, bucket, &mi->real, hv, mi);
		      mi->did_real_hash = true;
		    }
		}
	      else
		{
		  msg (D_MULTI_ERRORS,
		       "MULTI: Connection from %s would exceed new connection frequency limit as controlled by --connect-freq",
		       mroute_addr_print (&real, &gc));
		}
	    }
	}

#ifdef ENABLE_DEBUG
      if (check_debug_level (D_MULTI_DEBUG))
	{
	  const char *status;

	  if (he && mi)
	    status = "[succeeded]";
	  else if (!he && mi)
	    status = "[created]";
	  else
	    status = "[failed]";
	
	  dmsg (D_MULTI_DEBUG, "GET INST BY REAL: %s %s",
	       mroute_addr_print (&real, &gc),
	       status);
	}
#endif
    }

  gc_free (&gc);
  ASSERT (!(mi && mi->halt));
  return mi;
}
コード例 #4
0
ファイル: mudp.c プロジェクト: DenisMishin/openvpn
struct multi_instance *
multi_get_create_instance_udp (struct multi_context *m, bool *floated)
{
  struct gc_arena gc = gc_new ();
  struct mroute_addr real;
  struct multi_instance *mi = NULL;
  struct hash *hash = m->hash;

  if (mroute_extract_openvpn_sockaddr (&real, &m->top.c2.from.dest, true) &&
      m->top.c2.buf.len > 0)
    {
      struct hash_element *he;
      const uint32_t hv = hash_value (hash, &real);
      struct hash_bucket *bucket = hash_bucket (hash, hv);
      uint8_t* ptr = BPTR(&m->top.c2.buf);
      uint8_t op = ptr[0] >> P_OPCODE_SHIFT;

      /* make sure buffer has enough length to read opcode (1 byte) and peer-id (3 bytes) */
      if (op == P_DATA_V2 && m->top.c2.buf.len >= (1 + 3))
	{
	  uint32_t peer_id = ntohl(*(uint32_t*)ptr) & 0xFFFFFF;
	  if ((peer_id < m->max_clients) && (m->instances[peer_id]))
	    {
	      mi = m->instances[peer_id];

	      *floated = !link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from);

	      if (*floated)
	      {
		/* reset prefix, since here we are not sure peer is the one it claims to be */
		ungenerate_prefix(mi);
		msg (D_MULTI_ERRORS, "Untrusted peer %" PRIu32 " wants to float to %s", peer_id,
			mroute_addr_print (&real, &gc));
	      }
	    }
	}
      else
	{
	  he = hash_lookup_fast (hash, bucket, &real, hv);
	  if (he)
	    {
	      mi = (struct multi_instance *) he->value;
	    }
	}
      if (!mi)
	{
	  if (!m->top.c2.tls_auth_standalone
	      || tls_pre_decrypt_lite (m->top.c2.tls_auth_standalone, &m->top.c2.from, &m->top.c2.buf))
	    {
	      if (frequency_limit_event_allowed (m->new_connection_limiter))
		{
		  mi = multi_create_instance (m, &real);
		  if (mi)
		    {
		      int i;

		      hash_add_fast (hash, bucket, &mi->real, hv, mi);
		      mi->did_real_hash = true;

		      for (i = 0; i < m->max_clients; ++i)
			{
			  if (!m->instances[i])
			    {
			      mi->context.c2.tls_multi->peer_id = i;
			      m->instances[i] = mi;
			      break;
			    }
			}

		      /* should not really end up here, since multi_create_instance returns null
		       * if amount of clients exceeds max_clients */
		      ASSERT(i < m->max_clients);
		    }
		}
	      else
		{
		  msg (D_MULTI_ERRORS,
		       "MULTI: Connection from %s would exceed new connection frequency limit as controlled by --connect-freq",
		       mroute_addr_print (&real, &gc));
		}
	    }
	}

#ifdef ENABLE_DEBUG
      if (check_debug_level (D_MULTI_DEBUG))
	{
	  const char *status = mi ? "[ok]" : "[failed]";

	  dmsg (D_MULTI_DEBUG, "GET INST BY REAL: %s %s",
	       mroute_addr_print (&real, &gc),
	       status);
	}
#endif
    }

  gc_free (&gc);
  ASSERT (!(mi && mi->halt));
  return mi;
}