Exemplo n.º 1
0
int agent_alloc(struct agent **agp, struct reicec *cli,
		const struct trice_conf *conf)
{
	struct agent *ag;
	int err = 0;

	ag = mem_zalloc(sizeof(*ag), destructor);
	if (!ag)
		return ENOMEM;

	ag->cli = cli;
	ag->client = cli->client;
	rand_str(ag->lufrag, sizeof(ag->lufrag));
	rand_str(ag->lpwd, sizeof(ag->lpwd));

	err = trice_alloc(&ag->icem, conf, cli->client, ag->lufrag, ag->lpwd);
	if (err)
		goto out;

	err = stun_alloc(&ag->stun, NULL, NULL, NULL);
	if (err)
		goto out;

 out:
	if (err)
		mem_deref(ag);
	else
		*agp = ag;

	return err;
}
Exemplo n.º 2
0
/**
 * Add a new ICE Media object to the ICE Session
 *
 * @param icemp  Pointer to allocated ICE Media object
 * @param ice    ICE Session
 * @param proto  Transport protocol
 * @param layer  Protocol stack layer
 * @param gh     Gather handler
 * @param chkh   Connectivity check handler
 * @param arg    Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int icem_alloc(struct icem **icemp, struct ice *ice, int proto, int layer,
	       ice_gather_h *gh, ice_connchk_h *chkh, void *arg)
{
	struct icem *icem;
	int err = 0;

	if (!ice)
		return EINVAL;

	if (proto != IPPROTO_UDP)
		return EPROTONOSUPPORT;

	icem = mem_zalloc(sizeof(*icem), icem_destructor);
	if (!icem)
		return ENOMEM;

	tmr_init(&icem->tmr_pace);
	list_init(&icem->lcandl);
	list_init(&icem->rcandl);
	list_init(&icem->checkl);
	list_init(&icem->validl);

	icem->ice   = ice;
	icem->layer = layer;
	icem->proto = proto;
	icem->state = CHECKLIST_NULL;
	icem->nstun = 0;
	icem->gh    = gh;
	icem->chkh  = chkh;
	icem->arg   = arg;

	if (ICE_MODE_FULL == ice->lmode) {

		err = stun_alloc(&icem->stun, NULL, NULL, NULL);
		if (err)
			goto out;

		/* Update STUN Transport */
		stun_conf(icem->stun)->rto = ice->conf.rto;
		stun_conf(icem->stun)->rc = ice->conf.rc;
	}

	if (err)
		goto out;

	list_append(&ice->ml, &icem->le, icem);

 out:
	if (err)
		mem_deref(icem);
	else if (icemp)
		*icemp = icem;

	return err;
}
Exemplo n.º 3
0
/**
 * Allocate a SIP stack instance
 *
 * @param sipp     Pointer to allocated SIP stack
 * @param dnsc     DNS Client (optional)
 * @param ctsz     Size of client transactions hashtable (power of 2)
 * @param stsz     Size of server transactions hashtable (power of 2)
 * @param tcsz     Size of SIP transport hashtable (power of 2)
 * @param software Software identifier
 * @param exith    SIP-stack exit handler
 * @param arg      Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_alloc(struct sip **sipp, struct dnsc *dnsc, uint32_t ctsz,
	      uint32_t stsz, uint32_t tcsz, const char *software,
	      sip_exit_h *exith, void *arg)
{
	struct sip *sip;
	int err;

	if (!sipp)
		return EINVAL;

	sip = mem_zalloc(sizeof(*sip), destructor);
	if (!sip)
		return ENOMEM;

	err = sip_transp_init(sip, tcsz);
	if (err)
		goto out;

	err = sip_ctrans_init(sip, ctsz);
	if (err)
		goto out;

	err = sip_strans_init(sip, stsz);
	if (err)
		goto out;

	err = hash_alloc(&sip->ht_udpconn, tcsz);
	if (err)
		goto out;

	err = stun_alloc(&sip->stun, NULL, NULL, NULL);
	if (err)
		goto out;

	if (software) {
		err = str_dup(&sip->software, software);
		if (err)
			goto out;
	}

	sip->dnsc  = mem_ref(dnsc);
	sip->exith = exith;
	sip->arg   = arg;

 out:
	if (err)
		mem_deref(sip);
	else
		*sipp = sip;

	return err;
}
Exemplo n.º 4
0
Arquivo: ice.c Projeto: Issic47/libre
/**
 * Allocate a new ICE Session
 *
 * @param icep    Pointer to allocated ICE Session object
 * @param mode    ICE Mode; Full-mode or Lite-mode
 * @param offerer True if we are SDP offerer, otherwise false
 *
 * @return 0 if success, otherwise errorcode
 */
int ice_alloc(struct ice **icep, enum ice_mode mode, bool offerer)
{
	struct ice *ice;
	int err = 0;

	if (!icep)
		return EINVAL;

	ice = mem_zalloc(sizeof(*ice), ice_destructor);
	if (!ice)
		return ENOMEM;

	list_init(&ice->ml);

	ice->conf = conf_default;
	ice->lmode = mode;
	ice->tiebrk = rand_u64();

	rand_str(ice->lufrag, sizeof(ice->lufrag));
	rand_str(ice->lpwd, sizeof(ice->lpwd));

	ice_determine_role(ice, offerer);

	if (ICE_MODE_FULL == ice->lmode) {

		err = stun_alloc(&ice->stun, NULL, NULL, NULL);
		if (err)
			goto out;

		/* Update STUN Transport */
		stun_conf(ice->stun)->rto = ice->conf.rto;
		stun_conf(ice->stun)->rc = ice->conf.rc;
	}

 out:
	if (err)
		mem_deref(ice);
	else
		*icep = ice;

	return err;
}
Exemplo n.º 5
0
/**
 * Allocate a new NAT Hairpinning discovery session
 *
 * @param nhp      Pointer to allocated NAT Hairpinning object
 * @param proto    Transport protocol
 * @param srv      STUN Server IP address and port number
 * @param proto    Transport protocol
 * @param conf     STUN configuration (Optional)
 * @param hph      Hairpinning result handler
 * @param arg      Handler argument
 *
 * @return 0 if success, errorcode if failure
 */
int nat_hairpinning_alloc(struct nat_hairpinning **nhp,
			  const struct sa *srv, int proto,
			  const struct stun_conf *conf,
			  nat_hairpinning_h *hph, void *arg)
{
	struct nat_hairpinning *nh;
	struct sa local;
	int err;

	if (!srv || !hph)
		return EINVAL;

	nh = mem_zalloc(sizeof(*nh), hairpinning_destructor);
	if (!nh)
		return ENOMEM;

	err = stun_alloc(&nh->stun, conf, NULL, NULL);
	if (err)
		goto out;

	sa_cpy(&nh->srv, srv);
	nh->proto = proto;
	nh->hph   = hph;
	nh->arg   = arg;

	switch (proto) {

	case IPPROTO_UDP:
		err = udp_listen(&nh->us, NULL, udp_recv_handler, nh);
		break;

	case IPPROTO_TCP:
		sa_set_in(&local, 0, 0);

		/*
		 * Part I - Allocate and bind all sockets
		 */
		err = tcp_sock_alloc(&nh->ts, &local, tcp_conn_handler, nh);
		if (err)
			break;

		err = tcp_conn_alloc(&nh->tc, &nh->srv,
				     tcp_estab_handler, tcp_recv_handler,
				     tcp_close_handler, nh);
		if (err)
			break;

		err = tcp_sock_bind(nh->ts, &local);
		if (err)
			break;

		err = tcp_sock_local_get(nh->ts, &local);
		if (err)
			break;

		err = tcp_conn_bind(nh->tc, &local);
		if (err)
			break;

		/*
		 * Part II - Listen and connect all sockets
		 */
		err = tcp_sock_listen(nh->ts, 5);
		break;

	default:
		err = EPROTONOSUPPORT;
		break;
	}

 out:
	if (err)
		mem_deref(nh);
	else
		*nhp = nh;

	return err;
}
Exemplo n.º 6
0
/**
 * Allocate a TURN Client
 *
 * @param turncp    Pointer to allocated TURN Client
 * @param conf      Optional STUN Configuration
 * @param proto     Transport Protocol
 * @param sock      Transport socket
 * @param layer     Transport layer
 * @param srv       TURN Server IP-address
 * @param username  Authentication username
 * @param password  Authentication password
 * @param lifetime  Allocate lifetime in [seconds]
 * @param th        TURN handler
 * @param arg       Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int turnc_alloc(struct turnc **turncp, const struct stun_conf *conf, int proto,
		void *sock, int layer, const struct sa *srv,
		const char *username, const char *password,
		uint32_t lifetime, turnc_h *th, void *arg)
{
	struct turnc *turnc;
	int err;

	if (!turncp || !sock || !srv || !username || !password || !th)
		return EINVAL;

	turnc = mem_zalloc(sizeof(*turnc), destructor);
	if (!turnc)
		return ENOMEM;

	err = stun_alloc(&turnc->stun, conf, NULL, NULL);
	if (err)
		goto out;

	err = str_dup(&turnc->username, username);
	if (err)
		goto out;

	err = str_dup(&turnc->password, password);
	if (err)
		goto out;

	err = turnc_perm_hash_alloc(&turnc->perms, PERM_HASH_SIZE);
	if (err)
		goto out;

	err =  turnc_chan_hash_alloc(&turnc->chans, CHAN_HASH_SIZE);
	if (err)
		goto out;

	tmr_init(&turnc->tmr);
	turnc->proto = proto;
	turnc->sock = mem_ref(sock);
	turnc->psrv = *srv;
	turnc->srv = *srv;
	turnc->lifetime = lifetime;
	turnc->th = th;
	turnc->arg = arg;

	switch (proto) {

	case IPPROTO_UDP:
		err = udp_register_helper(&turnc->uh, sock, layer,
					  udp_send_handler, udp_recv_handler,
					  turnc);
		break;

	default:
		err = 0;
		break;
	}

	if (err)
		goto out;

	err = allocate_request(turnc);
	if (err)
		goto out;

 out:
	if (err)
		mem_deref(turnc);
	else
		*turncp = turnc;

	return err;
}
Exemplo n.º 7
0
/**
 * Add a new ICE Media object to the ICE Session
 *
 * @param icemp   Pointer to allocated ICE Media object
 * @param mode    ICE mode
 * @param role    Local ICE role
 * @param proto   Transport protocol
 * @param layer   Protocol stack layer
 * @param tiebrk  Tie-breaker value, must be same for all media streams
 * @param lufrag  Local username fragment
 * @param lpwd    Local password
 * @param chkh    Connectivity check handler
 * @param arg     Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int  icem_alloc(struct icem **icemp,
		enum ice_mode mode, enum ice_role role,
		int proto, int layer,
		uint64_t tiebrk, const char *lufrag, const char *lpwd,
		ice_connchk_h *chkh, void *arg)
{
	struct icem *icem;
	int err = 0;

	if (!icemp || !tiebrk || !lufrag || !lpwd)
		return EINVAL;

	if (str_len(lufrag) < 4 || str_len(lpwd) < 22) {
		DEBUG_WARNING("alloc: lufrag/lpwd is too short\n");
		return EINVAL;
	}

	if (proto != IPPROTO_UDP)
		return EPROTONOSUPPORT;

	icem = mem_zalloc(sizeof(*icem), icem_destructor);
	if (!icem)
		return ENOMEM;

	icem->conf = conf_default;

	tmr_init(&icem->tmr_pace);
	list_init(&icem->lcandl);
	list_init(&icem->rcandl);
	list_init(&icem->checkl);
	list_init(&icem->validl);

	icem->layer = layer;
	icem->proto = proto;
	icem->state = ICE_CHECKLIST_NULL;
	icem->chkh  = chkh;
	icem->arg   = arg;

	if (err)
		goto out;

	icem->lmode = mode;
	icem->tiebrk = tiebrk;

	err |= str_dup(&icem->lufrag, lufrag);
	err |= str_dup(&icem->lpwd, lpwd);
	if (err)
		goto out;

	ice_determine_role(icem, role);

	if (ICE_MODE_FULL == icem->lmode) {

		err = stun_alloc(&icem->stun, NULL, NULL, NULL);
		if (err)
			goto out;

		/* Update STUN Transport */
		stun_conf(icem->stun)->rto = icem->conf.rto;
		stun_conf(icem->stun)->rc = icem->conf.rc;
	}

 out:
	if (err)
		mem_deref(icem);
	else if (icemp)
		*icemp = icem;

	return err;
}
Exemplo n.º 8
0
/**
 * Allocate a new NAT Mapping Behaviour Discovery session
 *
 * @param nmp       Pointer to allocated NAT Mapping object
 * @param laddr     Local IP address
 * @param srv       STUN Server IP address and port
 * @param proto     Transport protocol
 * @param conf      STUN configuration (Optional)
 * @param mh        Mapping handler
 * @param arg       Handler argument
 *
 * @return 0 if success, errorcode if failure
 */
int nat_mapping_alloc(struct nat_mapping **nmp, const struct sa *laddr,
		      const struct sa *srv, int proto,
		      const struct stun_conf *conf,
		      nat_mapping_h *mh, void *arg)
{
	struct nat_mapping *nm;
	int i, err;

	if (!nmp || !laddr || !srv || !mh)
		return EINVAL;

	nm = mem_zalloc(sizeof(*nm), mapping_destructor);
	if (!nm)
		return ENOMEM;

	err = stun_alloc(&nm->stun, conf, NULL, NULL);
	if (err)
		goto out;

	nm->proto = proto;
	sa_cpy(&nm->laddr, laddr);

	switch (proto) {

	case IPPROTO_UDP:
		err = udp_listen(&nm->us, &nm->laddr, udp_recv_handler, nm);
		if (err)
			goto out;
		err = udp_local_get(nm->us, &nm->laddr);
		if (err)
			goto out;
		break;

	case IPPROTO_TCP:

		/* Allocate and bind 3 TCP Sockets */
		for (i=0; i<3; i++) {
			err = tcp_conn_alloc(&nm->tcv[i], srv,
					     tcp_estab_handler,
					     tcp_recv_handler,
					     tcp_close_handler, nm);
			if (err)
				goto out;

			err = tcp_conn_bind(nm->tcv[i], &nm->laddr);
			if (err)
				goto out;

			err = tcp_conn_local_get(nm->tcv[i], &nm->laddr);
			if (err)
				goto out;
		}
		break;

	default:
		err = EPROTONOSUPPORT;
		goto out;
	}

	sa_cpy(&nm->srv, srv);
	nm->mh  = mh;
	nm->arg = arg;

	*nmp = nm;

 out:
	if (err)
		mem_deref(nm);
	return err;
}
Exemplo n.º 9
0
static int test_stun_request(int proto, bool natted)
{
	struct stunserver *srv = NULL;
	struct stun_ctrans *ct = NULL;
	struct nat *nat = NULL;
	struct test test;
	struct sa laddr, public_addr;
	int err;

	memset(&test, 0, sizeof(test));

	err = stunserver_alloc(&srv);
	if (err)
		goto out;

	err = stun_alloc(&test.stun, NULL, NULL, NULL);
	if (err)
		goto out;

	if (proto == IPPROTO_UDP) {
		err = sa_set_str(&laddr, "127.0.0.1", 0);
		TEST_ERR(err);

		err = udp_listen(&test.us, &laddr, udp_recv_handler, &test);
		if (err)
			goto out;
		err = udp_local_get(test.us, &laddr);
		TEST_ERR(err);
	}

	if (natted) {
		err = sa_set_str(&public_addr, "4.5.6.7", 0);
		TEST_ERR(err);

		err = nat_alloc(&nat, srv->us, &public_addr);
		if (err)
			goto out;

		sa_set_port(&public_addr, sa_port(&laddr));
	}
	else {
		public_addr = laddr;
	}

	err = stun_request(&ct, test.stun, proto, test.us,
			   stunserver_addr(srv, proto), 0,
			   STUN_METHOD_BINDING, NULL, 0, true,
			   stun_resp_handler, &test, 0);
	if (err)
		goto out;

	TEST_ASSERT(ct != NULL);

	err = re_main_timeout(100);
	if (err)
		goto out;

	if (srv->err) {
		err = srv->err;
		goto out;
	}
	if (test.err) {
		err = test.err;
		goto out;
	}

	/* verify results */
	TEST_ASSERT(srv->nrecv >= 1);
	TEST_EQUALS(1, test.n_resp);

	if (proto == IPPROTO_UDP) {
		TEST_SACMP(&public_addr, &test.mapped_addr, SA_ALL);
	}

 out:
	mem_deref(test.stun);
	mem_deref(test.us);
	mem_deref(nat);
	mem_deref(srv);

	return err;
}