Exemplo n.º 1
0
static uint32_t calc_prio(enum ice_cand_type type, int proto,
			  enum ice_tcptype tcptype, int af, int turn_proto)
{
	uint16_t lpref = 0;

	switch (proto) {

	case IPPROTO_UDP:
		if (af==AF_INET6)
			lpref = turn_proto==IPPROTO_UDP ? 65535 : 65533;
		else
			lpref = turn_proto==IPPROTO_UDP ? 65534 : 65532;
		break;

	case IPPROTO_TCP:
		lpref = local_tcp_preference(tcptype, af==AF_INET6);
		break;
	}

	return ice_cand_calc_prio(type, lpref, COMPID);
}
Exemplo n.º 2
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;
}