示例#1
0
static int update(struct mnat_sess *sess)
{
	struct le *le;
	int err = 0;

	if (!sess)
		return EINVAL;

	for (le=sess->medial.head; le; le=le->next) {

		struct mnat_media *m = le->data;
		struct sa raddr1, raddr2;

		raddr1 = *sdp_media_raddr(m->sdpm);
		sdp_media_raddr_rtcp(m->sdpm, &raddr2);

		if (m->turnc1 && sa_isset(&raddr1, SA_ALL))
			err |= turnc_add_chan(m->turnc1, &raddr1, NULL, NULL);

		if (m->turnc2 && sa_isset(&raddr2, SA_ALL))
			err |= turnc_add_chan(m->turnc2, &raddr2, NULL, NULL);
	}

	return err;
}
示例#2
0
文件: turn.c 项目: alfredh/restunc
static void turnc_handler(int err, uint16_t scode, const char *reason,
			  const struct sa *relay,
			  const struct sa *mapped,
			  const struct stun_msg *msg, void *arg)
{
	(void)msg;
	(void)arg;

	/* Transaction errors */
	if (err) {
		DEBUG_WARNING("TURN Client error: %m\n", err);
		turn_done();
		return;
	}

	/* STUN errors */
	if (scode) {
		DEBUG_WARNING("TURN Client error: %u %s\n", scode, reason);
		turn_done();
		return;
	}

	(void)re_fprintf(stderr, "Allocate Request: relay_addr=%J"
			 ", mapped_addr=%J\n", relay, mapped);

	if (sa_isset(turnc.peer, SA_ALL)) {
		(void)re_fprintf(stderr, "ChannelBind: %J\n", turnc.peer);

		err = turnc_add_chan(turnc.tc, turnc.peer, NULL, NULL);
		if (err) {
			DEBUG_WARNING("TURN add channel: %m\n", err);
		}
	}
}
示例#3
0
/* Incoming data from TURN-server */
static void data_handler(struct allocation *alloc, const struct sa *src,
			 struct mbuf *mb)
{
	int err;

	if (!alloc->ok) {
		re_fprintf(stderr, "allocation not ready"
			   " -- ignore %zu bytes from %J\n",
			   mbuf_get_left(mb), src);
		return;
	}

	if (!sa_cmp(src, &alloc->peer, SA_ALL)) {

		re_printf("updating peer address:  %J  -->  %J\n",
			  &alloc->peer, src);

		alloc->peer = *src;

		if (!alloc->turn_ind)
			turnc_add_chan(alloc->turnc, src, NULL, NULL);

		tmr_start(&alloc->tmr_ping, PING_INTERVAL,
			  tmr_ping_handler, alloc);
	}

	err = receiver_recv(&alloc->recv, src, mb);
	if (err) {
		re_fprintf(stderr, "corrupt packet coming from %J (%m)\n",
			   src, err);
	}
}
示例#4
0
static int set_peer(struct allocation *alloc, const struct sa *peer)
{
	alloc->peer = *peer;

	tmr_start(&alloc->tmr_ping, PING_INTERVAL, tmr_ping_handler, alloc);

	if (alloc->turn_ind)
		return turnc_add_perm(alloc->turnc, peer, perm_handler, alloc);
	else
		return turnc_add_chan(alloc->turnc, peer, perm_handler, alloc);
}
示例#5
0
文件: comp.c 项目: soramimi/qSIP
void icem_comp_set_default_rcand(struct icem_comp *comp, struct cand *rcand)
{
	if (!comp)
		return;

	icecomp_printf(comp, "Set default remote candidate: %s:%J\n",
		       ice_cand_type2name(rcand->type), &rcand->addr);

	mem_deref(comp->def_rcand);
	comp->def_rcand = mem_ref(rcand);

	if (comp->turnc) {
		DEBUG_NOTICE("{%s.%u} Default: Add TURN Channel to peer %J\n",
			     comp->icem->name, comp->id, &rcand->addr);

		(void)turnc_add_chan(comp->turnc, &rcand->addr, NULL, NULL);
	}
}
示例#6
0
/**
 * Add a TURN Channel for the selected remote address
 *
 * @param icem   ICE Media object
 * @param compid Component ID
 * @param raddr  Remote network address
 *
 * @return 0 if success, otherwise errorcode
 */
int icem_add_chan(struct icem *icem, unsigned compid, const struct sa *raddr)
{
	struct icem_comp *comp;

	if (!icem)
		return EINVAL;

	comp = icem_comp_find(icem, compid);
	if (!comp)
		return ENOENT;

	if (comp->turnc) {
		DEBUG_NOTICE("{%s.%u} Add TURN Channel to peer %J\n",
			     comp->icem->name, comp->id, raddr);

		return turnc_add_chan(comp->turnc, raddr, NULL, NULL);
	}

	return 0;
}
int icem_conncheck_send(struct ice_candpair *cp, bool use_cand, bool trigged)
{
	struct ice_cand *lcand = cp->lcand;
	struct icem *icem = cp->icem;
	char username_buf[64];
	size_t presz = 0;
	uint32_t prio_prflx;
	uint16_t ctrl_attr;
	int err = 0;

	icem_candpair_set_state(cp, ICE_CANDPAIR_INPROGRESS);

	(void)re_snprintf(username_buf, sizeof(username_buf),
			  "%s:%s", icem->rufrag, icem->lufrag);

	/* PRIORITY and USE-CANDIDATE */
	prio_prflx = ice_cand_calc_prio(ICE_CAND_TYPE_PRFLX, 0, lcand->compid);

	switch (icem->lrole) {

	case ICE_ROLE_CONTROLLING:
		ctrl_attr = STUN_ATTR_CONTROLLING;

		if (icem->conf.nom == ICE_NOMINATION_AGGRESSIVE)
			use_cand = true;
		break;

	case ICE_ROLE_CONTROLLED:
		ctrl_attr = STUN_ATTR_CONTROLLED;
		break;

	default:
		return EINVAL;
	}

#if ICE_TRACE
	icecomp_printf(cp->comp, "Tx %H ---> %H (%s) %s %s\n",
		       icem_cand_print, cp->lcand, icem_cand_print, cp->rcand,
		       ice_candpair_state2name(cp->state),
		       use_cand ? "[USE]" : "",
		       trigged ? "[Trigged]" : "");
#else
	(void)trigged;
#endif

	/* A connectivity check MUST utilize the STUN short term credential
	   mechanism. */

	/* The password is equal to the password provided by the peer */
	if (!icem->rpwd) {
		DEBUG_WARNING("no remote password!\n");
	}

	if (cp->ct_conn) {
		DEBUG_WARNING("send_req: CONNCHECK already Pending!\n");
		return EBUSY;
	}

	switch (lcand->type) {

	case ICE_CAND_TYPE_RELAY:
		/* Creating Permissions for Relayed Candidates */
		err = turnc_add_chan(cp->comp->turnc, &cp->rcand->addr,
				     NULL, NULL);
		if (err) {
			DEBUG_WARNING("add channel: %m\n", err);
			break;
		}
		presz = 4;
		/*@fallthrough@*/

	case ICE_CAND_TYPE_HOST:
	case ICE_CAND_TYPE_SRFLX:
	case ICE_CAND_TYPE_PRFLX:
		cp->ct_conn = mem_deref(cp->ct_conn);
		err = stun_request(&cp->ct_conn, icem->stun, icem->proto,
				   cp->comp->sock, &cp->rcand->addr, presz,
				   STUN_METHOD_BINDING,
				   (uint8_t *)icem->rpwd, str_len(icem->rpwd),
				   true, stunc_resp_handler, cp,
				   4,
				   STUN_ATTR_USERNAME, username_buf,
				   STUN_ATTR_PRIORITY, &prio_prflx,
				   ctrl_attr, &icem->tiebrk,
				   STUN_ATTR_USE_CAND,
				   use_cand ? &use_cand : 0);
		break;

	default:
		DEBUG_WARNING("unknown candidate type %d\n", lcand->type);
		err = EINVAL;
		break;
	}

	return err;
}