Exemplo n.º 1
0
bool
hash_add(struct hash *hash, const void *key, void *value, bool replace)
{
    uint32_t hv;
    struct hash_bucket *bucket;
    struct hash_element *he;
    bool ret = false;

    hv = hash_value(hash, key);
    bucket = &hash->buckets[hv & hash->mask];

    if ((he = hash_lookup_fast(hash, bucket, key, hv))) /* already exists? */
    {
        if (replace)
        {
            he->value = value;
            ret = true;
        }
    }
    else
    {
        hash_add_fast(hash, bucket, key, hv, value);
        ret = true;
    }

    return ret;
}
Exemplo n.º 2
0
static inline struct pf_cn *
lookup_cn_rule (struct hash *h, const char *cn, const uint32_t cn_hash)
{
  struct hash_element *he = hash_lookup_fast (h, hash_bucket (h, cn_hash), cn, cn_hash);
  if (he)
    return (struct pf_cn *) he->value;
  else
    return NULL;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
		  session_forged = !(crypto_test_hmac(&m->top.c2.buf, &mi->context.c2.crypto_options));
		  if (session_forged)
		    {
		      mi = NULL;
		      msg (D_MULTI_MEDIUM, "hmac verification failed, session forge detected!");
		    }
		  else
		    {
		      update_floated(m, mi, real, hv);
		    }
		}
	    }
	}
      else
	{
	  he = hash_lookup_fast (hash, bucket, &real, hv);
	  if (he)
	    {
	      mi = (struct multi_instance *) he->value;
	    }
	}
      if (!mi && !session_forged)
	{
	  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)
		    {