/**
 * @file turnc.c  TURN Client implementation
 *
 * Copyright (C) 2010 Creytiv.com
 */
#include <re_types.h>
#include <re_fmt.h>
#include <re_mem.h>
#include <re_mbuf.h>
#include <re_md5.h>
#include <re_list.h>
#include <re_hash.h>
#include <re_tmr.h>
#include <re_sa.h>
#include <re_udp.h>
#include <re_tcp.h>
#include <re_srtp.h>
#include <re_tls.h>
#include <re_stun.h>
#include <re_turn.h>
#include "turnc.h"


#define DEBUG_MODULE "turnc"
#define DEBUG_LEVEL 5
#include <re_dbg.h>


/** TURN Client protocol values */
enum {
	PERM_HASH_SIZE = 16,
	CHAN_HASH_SIZE = 16,
	FAILC_MAX = 16, /**< Maximum number of request errors for loopcheck. */
	STUN_ATTR_ADDR4_SIZE = 8,
	STUN_ATTR_ADDR6_SIZE = 20,
};


static const uint8_t sendind_tid[STUN_TID_SIZE];

static int allocate_request(struct turnc *t);
static int refresh_request(struct turnc *t, uint32_t lifetime, bool reset_ls,
			   stun_resp_h *resph, void *arg);
static void refresh_resp_handler(int err, uint16_t scode, const char *reason,
				 const struct stun_msg *msg, void *arg);


static void destructor(void *arg)
{
	struct turnc *turnc = arg;

	if (turnc->allocated)
		(void)refresh_request(turnc, 0, true, NULL, NULL);

	tmr_cancel(&turnc->tmr);
	mem_deref(turnc->ct);

	hash_flush(turnc->perms);
	mem_deref(turnc->perms);
	mem_deref(turnc->chans);
	mem_deref(turnc->username);
	mem_deref(turnc->password);
	mem_deref(turnc->nonce);
	mem_deref(turnc->realm);
	mem_deref(turnc->stun);
	mem_deref(turnc->uh);
	mem_deref(turnc->sock);
}


static void timeout(void *arg)
{
	struct turnc *turnc = arg;
	int err;

	err = refresh_request(turnc, turnc->lifetime, true,
			      refresh_resp_handler, turnc);
	if (err)
		turnc->th(err, 0, NULL, NULL, NULL, NULL, turnc->arg);
}


static void refresh_timer(struct turnc *turnc)
{
	const uint32_t t = turnc->lifetime*1000*3/4;

	DEBUG_INFO("Start refresh timer.. %u seconds\n", t/1000);

	tmr_start(&turnc->tmr, t, timeout, turnc);
}


static void allocate_resp_handler(int err, uint16_t scode, const char *reason,
				  const struct stun_msg *msg, void *arg)
{
	struct stun_attr *map = NULL, *rel = NULL, *ltm, *alt;
	struct turnc *turnc = arg;

	if (err || turnc_request_loops(&turnc->ls, scode))
		goto out;

	switch (scode) {

	case 0:
		map = stun_msg_attr(msg, STUN_ATTR_XOR_MAPPED_ADDR);
		rel = stun_msg_attr(msg, STUN_ATTR_XOR_RELAY_ADDR);
		ltm = stun_msg_attr(msg, STUN_ATTR_LIFETIME);
		if (!rel || !map) {
			DEBUG_WARNING("xor_mapped/relay addr attr missing\n");
			err = EPROTO;
			break;
		}

		if (ltm)
			turnc->lifetime = ltm->v.lifetime;

		turnc->allocated = true;
		refresh_timer(turnc);
		break;

	case 300:
		if (turnc->proto == IPPROTO_TCP ||
		    turnc->proto == STUN_TRANSP_DTLS)
			break;

		alt = stun_msg_attr(msg, STUN_ATTR_ALT_SERVER);
		if (!alt)
			break;

		turnc->psrv = turnc->srv;
		turnc->srv = alt->v.alt_server;

		err = allocate_request(turnc);
		if (err)
			break;

		return;

	case 401:
	case 438:
		err = turnc_keygen(turnc, msg);
		if (err)
			break;

		err = allocate_request(turnc);
		if (err)
			break;

		return;

	default:
		break;
	}

 out:
	turnc->th(err, scode, reason,
		  rel ? &rel->v.xor_relay_addr : NULL,
		  map ? &map->v.xor_mapped_addr : NULL,
		  msg,
		  turnc->arg);
}


static int allocate_request(struct turnc *t)
{
	const uint8_t proto = IPPROTO_UDP;

	return stun_request(&t->ct, t->stun, t->proto, t->sock, &t->srv, 0,
			    STUN_METHOD_ALLOCATE,
			    t->realm ? t->md5_hash : NULL, sizeof(t->md5_hash),
			    false, allocate_resp_handler, t, 6,
			    STUN_ATTR_LIFETIME, &t->lifetime,
			    STUN_ATTR_REQ_TRANSPORT, &proto,
			    STUN_ATTR_USERNAME, t->realm ? t->username : NULL,
			    STUN_ATTR_REALM, t->realm,
			    STUN_ATTR_NONCE, t->nonce,
			    STUN_ATTR_SOFTWARE, stun_software);
}


static void refresh_resp_handler(int err, uint16_t scode, const char *reason,
				 const struct stun_msg *msg, void *arg)
{
	struct turnc *turnc = arg;
	struct stun_attr *ltm;

	if (err || turnc_request_loops(&turnc->ls, scode))
		goto out;

	switch (scode) {

	case 0:
		ltm = stun_msg_attr(msg, STUN_ATTR_LIFETIME);
		if (ltm)
			turnc->lifetime = ltm->v.lifetime;
		refresh_timer(turnc);
		return;

	case 401:
	case 438:
		err = turnc_keygen(turnc, msg);
		if (err)
			break;

		err = refresh_request(turnc, turnc->lifetime, false,
				      refresh_resp_handler, turnc);
		if (err)
			break;

		return;

	default:
		break;
	}

 out:
	turnc->th(err, scode, reason, NULL, NULL, msg, turnc->arg);
}


static int refresh_request(struct turnc *t, uint32_t lifetime, bool reset_ls,
			   stun_resp_h *resph, void *arg)
{
	if (!t)
		return EINVAL;

	if (reset_ls)
		turnc_loopstate_reset(&t->ls);

	if (t->ct)
		t->ct = mem_deref(t->ct);

	return stun_request(&t->ct, t->stun, t->proto, t->sock, &t->srv, 0,
			    STUN_METHOD_REFRESH,
			    t->realm ? t->md5_hash : NULL, sizeof(t->md5_hash),
			    false, resph, arg, 5,
			    STUN_ATTR_LIFETIME, &lifetime,
			    STUN_ATTR_USERNAME, t->realm ? t->username : NULL,
			    STUN_ATTR_REALM, t->realm,
			    STUN_ATTR_NONCE, t->nonce,
			    STUN_ATTR_SOFTWARE, stun_software);
}


static inline size_t stun_indlen(const struct sa *sa)
{
	size_t len = STUN_HEADER_SIZE + STUN_ATTR_HEADER_SIZE * 2;

	switch (sa_af(sa)) {

	case AF_INET:
		len += STUN_ATTR_ADDR4_SIZE;
		break;

#ifdef HAVE_INET6
	case AF_INET6:
		len += STUN_ATTR_ADDR6_SIZE;
		break;
#endif
	}

	return len;
}


static bool udp_send_handler(int *err, struct sa *dst, struct mbuf *mb,
			     void *arg)
{
	struct turnc *turnc = arg;
	size_t pos, indlen;
	struct chan *chan;

	if (mb->pos < CHAN_HDR_SIZE)
		return false;

	chan = turnc_chan_find_peer(turnc, dst);
	if (chan) {
		struct chan_hdr hdr;

		hdr.nr  = turnc_chan_numb(chan);
		hdr.len = mbuf_get_left(mb);

		mb->pos -= CHAN_HDR_SIZE;
		*err = turnc_chan_hdr_encode(&hdr, mb);
		mb->pos -= CHAN_HDR_SIZE;

		*dst = turnc->srv;

		return false;
	}

	indlen = stun_indlen(dst);

	if (mb->pos < indlen)
		return false;

	mb->pos -= indlen;
	pos = mb->pos;
	*err = stun_msg_encode(mb, STUN_METHOD_SEND, STUN_CLASS_INDICATION,
			       sendind_tid, NULL, NULL, 0, false, 0x00, 2,
			       STUN_ATTR_XOR_PEER_ADDR, dst,
			       STUN_ATTR_DATA, mb);
	mb->pos = pos;

	*dst = turnc->srv;

	return false;
}


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;
}


/**
 * 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;
}


int turnc_send(struct turnc *turnc, const struct sa *dst, struct mbuf *mb)
{
	size_t pos, indlen;
	struct chan *chan;
	int err;

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

	chan = turnc_chan_find_peer(turnc, dst);
	if (chan) {
		struct chan_hdr hdr;

		if (mb->pos < CHAN_HDR_SIZE)
			return EINVAL;

		hdr.nr  = turnc_chan_numb(chan);
		hdr.len = mbuf_get_left(mb);

		mb->pos -= CHAN_HDR_SIZE;
		pos = mb->pos;

		err = turnc_chan_hdr_encode(&hdr, mb);
		if (err)
			return err;

		if (turnc->proto == IPPROTO_TCP) {

			mb->pos = mb->end;

			/* padding */
			while (hdr.len++ & 0x03) {
				err = mbuf_write_u8(mb, 0x00);
				if (err)
					return err;
			}
		}

		mb->pos = pos;
	}
	else {
		indlen = stun_indlen(dst);

		if (mb->pos < indlen)
			return EINVAL;

		mb->pos -= indlen;
		pos = mb->pos;

		err = stun_msg_encode(mb, STUN_METHOD_SEND,
				      STUN_CLASS_INDICATION, sendind_tid,
				      NULL, NULL, 0, false, 0x00, 2,
				      STUN_ATTR_XOR_PEER_ADDR, dst,
				      STUN_ATTR_DATA, mb);
		if (err)
			return err;

		mb->pos = pos;
	}

	switch (turnc->proto) {

	case IPPROTO_UDP:
		err = udp_send(turnc->sock, &turnc->srv, mb);
		break;

	case IPPROTO_TCP:
		err = tcp_send(turnc->sock, mb);
		break;

#ifdef USE_DTLS
	case STUN_TRANSP_DTLS:
		err = dtls_send(turnc->sock, mb);
		break;
#endif

	default:
		err = EPROTONOSUPPORT;
		break;
	}

	return err;
}


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;
}


bool turnc_request_loops(struct loop_state *ls, uint16_t scode)
{
	bool loop = false;

	switch (scode) {

	case 0:
		ls->failc = 0;
		break;

	default:
		if (ls->last_scode == scode)
			loop = true;
		/*@fallthrough@*/
	case 300:
		if (++ls->failc >= FAILC_MAX)
			loop = true;

		break;
	}

	ls->last_scode = scode;

	return loop;
}


void turnc_loopstate_reset(struct loop_state *ls)
{
	if (!ls)
		return;

	ls->last_scode = 0;
	ls->failc = 0;
}


int turnc_keygen(struct turnc *turnc, const struct stun_msg *msg)
{
	struct stun_attr *realm, *nonce;

	realm = stun_msg_attr(msg, STUN_ATTR_REALM);
	nonce = stun_msg_attr(msg, STUN_ATTR_NONCE);
	if (!realm || !nonce)
		return EPROTO;

	mem_deref(turnc->realm);
	mem_deref(turnc->nonce);
	turnc->realm = mem_ref(realm->v.realm);
	turnc->nonce = mem_ref(nonce->v.nonce);

	return md5_printf(turnc->md5_hash, "%s:%s:%s",
			  turnc->username, turnc->realm, turnc->password);
}
