Пример #1
0
static void msg_recv(struct nat_hairpinning *nh, int proto, void *sock,
		     const struct sa *src, struct mbuf *mb)
{
	struct stun_unknown_attr ua;
	struct stun_msg *msg;

	if (0 != stun_msg_decode(&msg, mb, &ua))
		return;

	switch (stun_msg_class(msg)) {

	case STUN_CLASS_REQUEST:
		(void)stun_reply(proto, sock, src, 0, msg, NULL, 0, false, 3,
				 STUN_ATTR_XOR_MAPPED_ADDR, src,
				 STUN_ATTR_MAPPED_ADDR, src,
				 STUN_ATTR_SOFTWARE, stun_software);
		break;

	case STUN_CLASS_ERROR_RESP:
	case STUN_CLASS_SUCCESS_RESP:
		(void)stun_ctrans_recv(nh->stun, msg, &ua);
		break;

	default:
		DEBUG_WARNING("unknown class 0x%04x\n", stun_msg_class(msg));
		break;
	}

	mem_deref(msg);
}
Пример #2
0
static bool helper_recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
	struct icem_comp *comp = arg;
	struct icem *icem = comp->icem;
	struct stun_msg *msg = NULL;
	struct stun_unknown_attr ua;
	const size_t start = mb->pos;

#if 0
	re_printf("{%d} UDP recv_helper: %u bytes from %J\n",
		  comp->id, mbuf_get_left(mb), src);
#endif

	if (stun_msg_decode(&msg, mb, &ua))
		return false;

	if (STUN_METHOD_BINDING == stun_msg_method(msg)) {

		switch (stun_msg_class(msg)) {

		case STUN_CLASS_REQUEST:
			(void)icem_stund_recv(comp, src, msg, start);
			break;

		default:
			(void)stun_ctrans_recv(icem->ice->stun, msg, &ua);
			break;
		}
	}

	mem_deref(msg);

	return true;  /* handled */
}
Пример #3
0
/* only used for STUN gathering */
static void process_stun(struct candidate *cand, struct mbuf *mb)
{
	struct stun_unknown_attr ua;
	struct stun_msg *msg;
	int err;

	err = stun_msg_decode(&msg, mb, &ua);
	if (err) {
		re_fprintf(stderr, "could not decode STUN message\n");
		return;
	}

	switch (stun_msg_class(msg)) {

	case STUN_CLASS_ERROR_RESP:
	case STUN_CLASS_SUCCESS_RESP:
		(void)stun_ctrans_recv(cand->ag->stun, msg, &ua);
		break;

	default:
		break;
	}

	mem_deref(msg);
}
Пример #4
0
static void udp_recv_handler(const struct sa *src, struct mbuf *mb, void *arg)
{
	struct sip_transport *transp = arg;
	struct stun_unknown_attr ua;
	struct stun_msg *stun_msg;
	struct sip_msg *msg;
	int err;

	if (mb->end <= 4)
		return;

	if (!stun_msg_decode(&stun_msg, mb, &ua)) {

		if (stun_msg_method(stun_msg) == STUN_METHOD_BINDING) {

			switch (stun_msg_class(stun_msg)) {

			case STUN_CLASS_REQUEST:
				(void)stun_reply(IPPROTO_UDP, transp->sock,
						 src, 0, stun_msg,
						 NULL, 0, false, 2,
						 STUN_ATTR_XOR_MAPPED_ADDR,
						 src,
						 STUN_ATTR_SOFTWARE,
						 transp->sip->software);
				break;

			default:
				(void)stun_ctrans_recv(transp->sip->stun,
						       stun_msg, &ua);
				break;
			}
		}

		mem_deref(stun_msg);

		return;
	}

	err = sip_msg_decode(&msg, mb);
	if (err) {
		(void)re_fprintf(stderr, "sip: msg decode err: %m\n", err);
		return;
	}

	msg->sock = mem_ref(transp->sock);
	msg->src = *src;
	msg->dst = transp->laddr;
	msg->tp = SIP_TRANSP_UDP;

	sip_recv(transp->sip, msg);

	mem_deref(msg);
}
Пример #5
0
/* sock = [ struct udp_sock | struct tcp_conn ] */
bool trice_stun_process(struct trice *icem, struct ice_lcand *lcand,
		       int proto, void *sock, const struct sa *src,
		       struct mbuf *mb)
{
	struct stun_msg *msg = NULL;
	struct stun_unknown_attr ua;
	size_t start = mb->pos;
	(void)proto;

	if (stun_msg_decode(&msg, mb, &ua)) {
		return false;  /* continue recv-processing */
	}

	if (STUN_METHOD_BINDING == stun_msg_method(msg)) {

		switch (stun_msg_class(msg)) {

		case STUN_CLASS_REQUEST:
			(void)trice_stund_recv(icem, lcand, sock,
					      src, msg, start);
			break;

		default:
			if (icem->checklist) {
				(void)stun_ctrans_recv(icem->checklist->stun,
						       msg, &ua);
			}
			else {
				DEBUG_NOTICE("STUN resp from %J dropped"
					     " (no checklist)\n",
					     src);
			}
			break;
		}
	}

	mem_deref(msg);

	return true;
}
Пример #6
0
int turnc_recv(struct turnc *turnc, struct sa *src, struct mbuf *mb)
{
	struct stun_attr *peer, *data;
	struct stun_unknown_attr ua;
	struct stun_msg *msg;
	int err = 0;

	if (!turnc || !src || !mb)
		return EINVAL;

	if (stun_msg_decode(&msg, mb, &ua)) {

		struct chan_hdr hdr;
		struct chan *chan;

		if (turnc_chan_hdr_decode(&hdr, mb))
			return EBADMSG;

		if (mbuf_get_left(mb) < hdr.len)
			return EBADMSG;

		chan = turnc_chan_find_numb(turnc, hdr.nr);
		if (!chan)
			return EBADMSG;

		*src = *turnc_chan_peer(chan);

		return 0;
	}

	switch (stun_msg_class(msg)) {

	case STUN_CLASS_INDICATION:
		if (ua.typec > 0) {
			err = ENOSYS;
			break;
		}

		if (stun_msg_method(msg) != STUN_METHOD_DATA) {
			err = ENOSYS;
			break;
		}

		peer = stun_msg_attr(msg, STUN_ATTR_XOR_PEER_ADDR);
		data = stun_msg_attr(msg, STUN_ATTR_DATA);
		if (!peer || !data) {
			err = EPROTO;
			break;
		}

		*src = peer->v.xor_peer_addr;

		mb->pos = data->v.data.pos;
		mb->end = data->v.data.end;
		break;

	case STUN_CLASS_ERROR_RESP:
	case STUN_CLASS_SUCCESS_RESP:
		(void)stun_ctrans_recv(turnc->stun, msg, &ua);
		mb->pos = mb->end;
		break;

	default:
		err = ENOSYS;
		break;
	}

	mem_deref(msg);

	return err;
}
Пример #7
0
static bool udp_recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
	struct stun_attr *peer, *data;
	struct stun_unknown_attr ua;
	struct turnc *turnc = arg;
	struct stun_msg *msg;
	bool hdld = true;

	if (!sa_cmp(&turnc->srv, src, SA_ALL) &&
	    !sa_cmp(&turnc->psrv, src, SA_ALL))
		return false;

	if (stun_msg_decode(&msg, mb, &ua)) {

		struct chan_hdr hdr;
		struct chan *chan;

		if (turnc_chan_hdr_decode(&hdr, mb))
			return true;

		if (mbuf_get_left(mb) < hdr.len)
			return true;

		chan = turnc_chan_find_numb(turnc, hdr.nr);
		if (!chan)
			return true;

		*src = *turnc_chan_peer(chan);

		return false;
	}

	switch (stun_msg_class(msg)) {

	case STUN_CLASS_INDICATION:
		if (ua.typec > 0)
			break;

		if (stun_msg_method(msg) != STUN_METHOD_DATA)
			break;

		peer = stun_msg_attr(msg, STUN_ATTR_XOR_PEER_ADDR);
		data = stun_msg_attr(msg, STUN_ATTR_DATA);
		if (!peer || !data)
			break;

		*src = peer->v.xor_peer_addr;

		mb->pos = data->v.data.pos;
		mb->end = data->v.data.end;

		hdld = false;
		break;

	case STUN_CLASS_ERROR_RESP:
	case STUN_CLASS_SUCCESS_RESP:
		(void)stun_ctrans_recv(turnc->stun, msg, &ua);
		break;

	default:
		break;
	}

	mem_deref(msg);

	return hdld;
}