/* $Id$ */
/* 
 * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include "turn.h"
#include "auth.h"


#define THIS_FILE   "allocation.c"


enum {
    TIMER_ID_NONE,
    TIMER_ID_TIMEOUT,
    TIMER_ID_DESTROY
};

#define DESTROY_DELAY	    {0, 500}
#define PEER_TABLE_SIZE	    32

#define MAX_CLIENT_BANDWIDTH	128  /* In Kbps */
#define DEFA_CLIENT_BANDWIDTH	64

#define MIN_LIFETIME		30
#define MAX_LIFETIME		600
#define DEF_LIFETIME		300


/* Parsed Allocation request. */
typedef struct alloc_request
{
    unsigned		tp_type;		    /* Requested transport  */
    char		addr[PJ_INET6_ADDRSTRLEN];  /* Requested IP	    */
    unsigned		bandwidth;		    /* Requested bandwidth  */
    unsigned		lifetime;		    /* Lifetime.	    */
    unsigned		rpp_bits;		    /* A bits		    */
    unsigned		rpp_port;		    /* Requested port	    */
} alloc_request;



/* Prototypes */
static void destroy_allocation(pj_turn_allocation *alloc);
static pj_status_t create_relay(pj_turn_srv *srv,
				pj_turn_allocation *alloc,
				const pj_stun_msg *msg,
				const alloc_request *req,
				pj_turn_relay_res *relay);
static void destroy_relay(pj_turn_relay_res *relay);
static void on_rx_from_peer(pj_ioqueue_key_t *key, 
                            pj_ioqueue_op_key_t *op_key, 
                            pj_ssize_t bytes_read);
static pj_status_t stun_on_send_msg(pj_stun_session *sess,
				    void *token,
				    const void *pkt,
				    pj_size_t pkt_size,
				    const pj_sockaddr_t *dst_addr,
				    unsigned addr_len);
static pj_status_t stun_on_rx_request(pj_stun_session *sess,
				      const pj_uint8_t *pkt,
				      unsigned pkt_len,
				      const pj_stun_rx_data *rdata,
				      void *token,
				      const pj_sockaddr_t *src_addr,
				      unsigned src_addr_len);
static pj_status_t stun_on_rx_indication(pj_stun_session *sess,
					 const pj_uint8_t *pkt,
					 unsigned pkt_len,
					 const pj_stun_msg *msg,
					 void *token,
					 const pj_sockaddr_t *src_addr,
					 unsigned src_addr_len);

/* Log allocation error */
static void alloc_err(pj_turn_allocation *alloc, const char *title,
		      pj_status_t status)
{
    char errmsg[PJ_ERR_MSG_SIZE];

    pj_strerror(status, errmsg, sizeof(errmsg));
    PJ_LOG(4,(alloc->obj_name, "%s for client %s: %s",
	      title, alloc->info, errmsg));
}


/* Parse ALLOCATE request */
static pj_status_t parse_allocate_req(alloc_request *cfg,
				      pj_stun_session *sess,
				      const pj_stun_rx_data *rdata,
				      const pj_sockaddr_t *src_addr,
				      unsigned src_addr_len)
{
    const pj_stun_msg *req = rdata->msg;
    pj_stun_bandwidth_attr *attr_bw;
    pj_stun_req_transport_attr *attr_req_tp;
    pj_stun_res_token_attr *attr_res_token;
    pj_stun_req_props_attr *attr_rpp;
    pj_stun_lifetime_attr *attr_lifetime;

    pj_bzero(cfg, sizeof(*cfg));

    /* Get BANDWIDTH attribute, if any. */
    attr_bw = (pj_stun_uint_attr*)
	      pj_stun_msg_find_attr(req, PJ_STUN_ATTR_BANDWIDTH, 0);
    if (attr_bw) {
	cfg->bandwidth = attr_bw->value;
    } else {
	cfg->bandwidth = DEFA_CLIENT_BANDWIDTH;
    }

    /* Check if we can satisfy the bandwidth */
    if (cfg->bandwidth > MAX_CLIENT_BANDWIDTH) {
	pj_stun_session_respond(sess, rdata, 
				PJ_STUN_SC_ALLOCATION_QUOTA_REACHED,
			        "Invalid bandwidth", NULL, PJ_TRUE,
				src_addr, src_addr_len);
	return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_ALLOCATION_QUOTA_REACHED);
    }

    /* MUST have REQUESTED-TRANSPORT attribute */
    attr_req_tp = (pj_stun_uint_attr*)
	          pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REQ_TRANSPORT, 0);
    if (attr_req_tp == NULL) {
	pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST,
			        "Missing REQUESTED-TRANSPORT attribute", 
				NULL, PJ_TRUE, src_addr, src_addr_len);
	return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);
    }

    cfg->tp_type = PJ_STUN_GET_RT_PROTO(attr_req_tp->value);

    /* Can only support UDP for now */
    if (cfg->tp_type != PJ_TURN_TP_UDP) {
	pj_stun_session_respond(sess, rdata, PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO,
				NULL, NULL, PJ_TRUE, src_addr, src_addr_len);
	return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO);
    }

    /* Get RESERVATION-TOKEN attribute, if any */
    attr_res_token = (pj_stun_res_token_attr*)
	             pj_stun_msg_find_attr(req, PJ_STUN_ATTR_RESERVATION_TOKEN,
					   0);
    if (attr_res_token) {
	/* We don't support RESERVATION-TOKEN for now */
	pj_stun_session_respond(sess, rdata, 
				PJ_STUN_SC_BAD_REQUEST,
				"RESERVATION-TOKEN is not supported", NULL, 
				PJ_TRUE, src_addr, src_addr_len);
	return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);
    }

    /* Get REQUESTED-PROPS attribute, if any */
    attr_rpp = (pj_stun_req_props_attr*)
	       pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REQ_PROPS, 0);
    if (attr_rpp) {
	/* We don't support REQUESTED-PROPS for now */
	pj_stun_session_respond(sess, rdata, 
				PJ_STUN_SC_BAD_REQUEST,
				"REQUESTED-PROPS is not supported", 
				NULL, PJ_TRUE, src_addr, src_addr_len);
	return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);
    }

    /* Get LIFETIME attribute */
    attr_lifetime = (pj_stun_uint_attr*)
	            pj_stun_msg_find_attr(req, PJ_STUN_ATTR_LIFETIME, 0);
    if (attr_lifetime) {
	cfg->lifetime = attr_lifetime->value;
	if (cfg->lifetime < MIN_LIFETIME) {
	    pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST,
				    "LIFETIME too short", NULL, 
				    PJ_TRUE, src_addr, src_addr_len);
	    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);
	}
	if (cfg->lifetime > MAX_LIFETIME)
	    cfg->lifetime = MAX_LIFETIME;
    } else {
	cfg->lifetime = DEF_LIFETIME;
    }

    return PJ_SUCCESS;
}


/* Respond to ALLOCATE request */
static pj_status_t send_allocate_response(pj_turn_allocation *alloc,
					  pj_stun_session *srv_sess,
					  pj_turn_transport *transport,
					  const pj_stun_rx_data *rdata)
{
    pj_stun_tx_data *tdata;
    pj_status_t status;

    /* Respond the original ALLOCATE request */
    status = pj_stun_session_create_res(srv_sess, rdata, 0, NULL, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* Add RELAYED-ADDRESS attribute */
    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
				  PJ_STUN_ATTR_RELAYED_ADDR, PJ_TRUE,
				  &alloc->relay.hkey.addr,
				  pj_sockaddr_get_len(&alloc->relay.hkey.addr));

    /* Add LIFETIME. */
    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
			      PJ_STUN_ATTR_LIFETIME, 
			      (unsigned)alloc->relay.lifetime);

    /* Add BANDWIDTH */
    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
			      PJ_STUN_ATTR_BANDWIDTH,
			      alloc->bandwidth);

    /* Add RESERVATION-TOKEN */
    PJ_TODO(ADD_RESERVATION_TOKEN);

    /* Add XOR-MAPPED-ADDRESS */
    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
				  PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE,
				  &alloc->hkey.clt_addr,
				  pj_sockaddr_get_len(&alloc->hkey.clt_addr));
    
    /* Send the response */
    return pj_stun_session_send_msg(srv_sess, transport, PJ_TRUE,
				    PJ_FALSE, &alloc->hkey.clt_addr, 
				    pj_sockaddr_get_len(&alloc->hkey.clt_addr),
				    tdata);
}


/*
 * Init credential for the allocation. We use static credential, meaning that
 * the user's password must not change during allocation.
 */
static pj_status_t init_cred(pj_turn_allocation *alloc, const pj_stun_msg *req)
{
    const pj_stun_username_attr *user;
    const pj_stun_realm_attr *realm;
    const pj_stun_nonce_attr *nonce;
    pj_status_t status;

    realm = (const pj_stun_realm_attr*)
	    pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REALM, 0);
    PJ_ASSERT_RETURN(realm != NULL, PJ_EBUG);

    user = (const pj_stun_username_attr*)
	   pj_stun_msg_find_attr(req, PJ_STUN_ATTR_USERNAME, 0);
    PJ_ASSERT_RETURN(user != NULL, PJ_EBUG);

    nonce = (const pj_stun_nonce_attr*)
	    pj_stun_msg_find_attr(req, PJ_STUN_ATTR_NONCE, 0);
    PJ_ASSERT_RETURN(nonce != NULL, PJ_EBUG);

    /* Lookup the password */
    status = pj_turn_get_password(NULL, NULL, &realm->value, 
				  &user->value, alloc->pool, 
				  &alloc->cred.data.static_cred.data_type, 
				  &alloc->cred.data.static_cred.data);
    if (status != PJ_SUCCESS)
	return status;

    /* Save credential */
    alloc->cred.type = PJ_STUN_AUTH_CRED_STATIC;
    pj_strdup(alloc->pool, &alloc->cred.data.static_cred.realm, &realm->value);
    pj_strdup(alloc->pool, &alloc->cred.data.static_cred.username, &user->value);
    pj_strdup(alloc->pool, &alloc->cred.data.static_cred.nonce, &nonce->value);

    return PJ_SUCCESS;
}


/*
 * Create new allocation.
 */
PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,
					      const pj_sockaddr_t *src_addr,
					      unsigned src_addr_len,
					      const pj_stun_rx_data *rdata,
					      pj_stun_session *srv_sess,
					      pj_turn_allocation **p_alloc)
{
    pj_turn_srv *srv = transport->listener->server;
    const pj_stun_msg *msg = rdata->msg;
    pj_pool_t *pool;
    alloc_request req;
    pj_turn_allocation *alloc;
    pj_stun_session_cb sess_cb;
    char str_tmp[80];
    pj_status_t status;

    /* Parse ALLOCATE request */
    status = parse_allocate_req(&req, srv_sess, rdata, src_addr, src_addr_len);
    if (status != PJ_SUCCESS)
	return status;

    pool = pj_pool_create(srv->core.pf, "alloc%p", 1000, 1000, NULL);

    /* Init allocation structure */
    alloc = PJ_POOL_ZALLOC_T(pool, pj_turn_allocation);
    alloc->pool = pool;
    alloc->obj_name = pool->obj_name;
    alloc->relay.tp.sock = PJ_INVALID_SOCKET;
    alloc->server = transport->listener->server;

    alloc->bandwidth = req.bandwidth;

    /* Set transport */
    alloc->transport = transport;
    pj_turn_transport_add_ref(transport, alloc);

    alloc->hkey.tp_type = transport->listener->tp_type;
    pj_memcpy(&alloc->hkey.clt_addr, src_addr, src_addr_len);

    status = pj_lock_create_recursive_mutex(pool, alloc->obj_name, 
					    &alloc->lock);
    if (status != PJ_SUCCESS) {
	goto on_error;
    }

    /* Create peer hash table */
    alloc->peer_table = pj_hash_create(pool, PEER_TABLE_SIZE);

    /* Create channel hash table */
    alloc->ch_table = pj_hash_create(pool, PEER_TABLE_SIZE);

    /* Print info */
    pj_ansi_strcpy(alloc->info, 
		   pj_turn_tp_type_name(transport->listener->tp_type));
    alloc->info[3] = ':';
    pj_sockaddr_print(src_addr, alloc->info+4, sizeof(alloc->info)-4, 3);

    /* Create STUN session to handle STUN communication with client */
    pj_bzero(&sess_cb, sizeof(sess_cb));
    sess_cb.on_send_msg = &stun_on_send_msg;
    sess_cb.on_rx_request = &stun_on_rx_request;
    sess_cb.on_rx_indication = &stun_on_rx_indication;
    status = pj_stun_session_create(&srv->core.stun_cfg, alloc->obj_name,
				    &sess_cb, PJ_FALSE, &alloc->sess);
    if (status != PJ_SUCCESS) {
	goto on_error;
    }

    /* Attach to STUN session */
    pj_stun_session_set_user_data(alloc->sess, alloc);

    /* Init authentication credential */
    status = init_cred(alloc, msg);
    if (status != PJ_SUCCESS) {
	goto on_error;
    }

    /* Attach authentication credential to STUN session */
    pj_stun_session_set_credential(alloc->sess, PJ_STUN_AUTH_LONG_TERM,
				   &alloc->cred);

    /* Create the relay resource */
    status = create_relay(srv, alloc, msg, &req, &alloc->relay);
    if (status != PJ_SUCCESS) {
	goto on_error;
    }

    /* Register this allocation */
    pj_turn_srv_register_allocation(srv, alloc);

    /* Respond to ALLOCATE request */
    status = send_allocate_response(alloc, srv_sess, transport, rdata);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Done */
    pj_sockaddr_print(&alloc->relay.hkey.addr, str_tmp, 
		      sizeof(str_tmp), 3);
    PJ_LOG(4,(alloc->obj_name, "Client %s created, relay addr=%s:%s", 
	      alloc->info, pj_turn_tp_type_name(req.tp_type), str_tmp));

    /* Success */
    *p_alloc = alloc;
    return PJ_SUCCESS;

on_error:
    /* Send reply to the ALLOCATE request */
    pj_strerror(status, str_tmp, sizeof(str_tmp));
    pj_stun_session_respond(srv_sess, rdata, PJ_STUN_SC_BAD_REQUEST, str_tmp, 
			    transport, PJ_TRUE, src_addr, src_addr_len);

    /* Cleanup */
    destroy_allocation(alloc);
    return status;
}


/* Destroy relay resource */
static void destroy_relay(pj_turn_relay_res *relay)
{
    if (relay->timer.id) {
	pj_timer_heap_cancel(relay->allocation->server->core.timer_heap, 
			     &relay->timer);
	relay->timer.id = PJ_FALSE;
    }

    if (relay->tp.key) {
	pj_ioqueue_unregister(relay->tp.key);
	relay->tp.key = NULL;
	relay->tp.sock = PJ_INVALID_SOCKET;
    } else if (relay->tp.sock != PJ_INVALID_SOCKET) {
	pj_sock_close(relay->tp.sock);
	relay->tp.sock = PJ_INVALID_SOCKET;
    }

    /* Mark as shutdown */
    relay->lifetime = 0;
}


/*
 * Really destroy allocation.
 */
static void destroy_allocation(pj_turn_allocation *alloc)
{
    pj_pool_t *pool;

    /* Unregister this allocation */
    pj_turn_srv_unregister_allocation(alloc->server, alloc);

    /* Destroy relay */
    destroy_relay(&alloc->relay);

    /* Must lock only after destroying relay otherwise deadlock */
    if (alloc->lock) {
	pj_lock_acquire(alloc->lock);
    }

    /* Unreference transport */
    if (alloc->transport) {
	pj_turn_transport_dec_ref(alloc->transport, alloc);
	alloc->transport = NULL;
    }

    /* Destroy STUN session */
    if (alloc->sess) {
	pj_stun_session_destroy(alloc->sess);
	alloc->sess = NULL;
    }

    /* Destroy lock */
    if (alloc->lock) {
	pj_lock_release(alloc->lock);
	pj_lock_destroy(alloc->lock);
	alloc->lock = NULL;
    }

    /* Destroy pool */
    pool = alloc->pool;
    if (pool) {
	alloc->pool = NULL;
	pj_pool_release(pool);
    }
}


PJ_DECL(void) pj_turn_allocation_destroy(pj_turn_allocation *alloc)
{
    destroy_allocation(alloc);
}


/*
 * Handle transport closure.
 */
PJ_DEF(void) pj_turn_allocation_on_transport_closed( pj_turn_allocation *alloc,
						     pj_turn_transport *tp)
{
    PJ_LOG(5,(alloc->obj_name, "Transport %s unexpectedly closed, destroying "
	      "allocation %s", tp->info, alloc->info));
    pj_turn_transport_dec_ref(tp, alloc);
    alloc->transport = NULL;
    destroy_allocation(alloc);
}


/* Initiate shutdown sequence for this allocation and start destroy timer.
 * Once allocation is marked as shutting down, any packets will be 
 * rejected/discarded 
 */
static void alloc_shutdown(pj_turn_allocation *alloc)
{
    pj_time_val destroy_delay = DESTROY_DELAY;

    /* Work with existing schedule */
    if (alloc->relay.timer.id == TIMER_ID_TIMEOUT) {
	/* Cancel existing shutdown timer */
	pj_timer_heap_cancel(alloc->server->core.timer_heap,
			     &alloc->relay.timer);
	alloc->relay.timer.id = TIMER_ID_NONE;

    } else if (alloc->relay.timer.id == TIMER_ID_DESTROY) {
	/* We've been scheduled to be destroyed, ignore this
	 * shutdown request.
	 */
	return;
    } 

    pj_assert(alloc->relay.timer.id == TIMER_ID_NONE);

    /* Shutdown relay socket */
    destroy_relay(&alloc->relay);

    /* Don't unregister from hash table because we still need to
     * handle REFRESH retransmission.
     */

    /* Schedule destroy timer */
    alloc->relay.timer.id = TIMER_ID_DESTROY;
    pj_timer_heap_schedule(alloc->server->core.timer_heap,
			   &alloc->relay.timer, &destroy_delay);
}


/* Reschedule timeout using current lifetime setting */
static pj_status_t resched_timeout(pj_turn_allocation *alloc)
{
    pj_time_val delay;
    pj_status_t status;

    pj_gettimeofday(&alloc->relay.expiry);
    alloc->relay.expiry.sec += alloc->relay.lifetime;

    pj_assert(alloc->relay.timer.id != TIMER_ID_DESTROY);
    if (alloc->relay.timer.id != 0) {
	pj_timer_heap_cancel(alloc->server->core.timer_heap, 
			     &alloc->relay.timer);
	alloc->relay.timer.id = TIMER_ID_NONE;
    }

    delay.sec = alloc->relay.lifetime;
    delay.msec = 0;

    alloc->relay.timer.id = TIMER_ID_TIMEOUT;
    status = pj_timer_heap_schedule(alloc->server->core.timer_heap, 
				    &alloc->relay.timer, &delay);
    if (status != PJ_SUCCESS) {
	alloc->relay.timer.id = TIMER_ID_NONE;
	return status;
    }

    return PJ_SUCCESS;
}


/* Timer timeout callback */
static void relay_timeout_cb(pj_timer_heap_t *heap, pj_timer_entry *e)
{
    pj_turn_relay_res *rel;
    pj_turn_allocation *alloc;

    PJ_UNUSED_ARG(heap);

    rel = (pj_turn_relay_res*) e->user_data;
    alloc = rel->allocation;

    if (e->id == TIMER_ID_TIMEOUT) {

	e->id = TIMER_ID_NONE;

	PJ_LOG(4,(alloc->obj_name, 
		  "Client %s refresh timed-out, shutting down..", 
		  alloc->info));

	alloc_shutdown(alloc);

    } else if (e->id == TIMER_ID_DESTROY) {
	e->id = TIMER_ID_NONE;

	PJ_LOG(4,(alloc->obj_name, "Client %s destroying..", 
		  alloc->info));

	destroy_allocation(alloc);
    }
}


/*
 * Create relay.
 */
static pj_status_t create_relay(pj_turn_srv *srv,
				pj_turn_allocation *alloc,
				const pj_stun_msg *msg,
				const alloc_request *req,
				pj_turn_relay_res *relay)
{
    enum { RETRY = 40 };
    pj_pool_t *pool = alloc->pool;
    int retry, retry_max, sock_type;
    pj_ioqueue_callback icb;
    int af, namelen;
    pj_stun_string_attr *sa;
    pj_status_t status;

    pj_bzero(relay, sizeof(*relay));
    
    relay->allocation = alloc;
    relay->tp.sock = PJ_INVALID_SOCKET;
    
    /* TODO: get the requested address family from somewhere */
    af = alloc->transport->listener->addr.addr.sa_family;

    /* Save realm */
    sa = (pj_stun_string_attr*)
	 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_REALM, 0);
    PJ_ASSERT_RETURN(sa, PJ_EINVALIDOP);
    pj_strdup(pool, &relay->realm, &sa->value);

    /* Save username */
    sa = (pj_stun_string_attr*)
	 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USERNAME, 0);
    PJ_ASSERT_RETURN(sa, PJ_EINVALIDOP);
    pj_strdup(pool, &relay->user, &sa->value);

    /* Lifetime and timeout */
    relay->lifetime = req->lifetime;
    pj_timer_entry_init(&relay->timer, TIMER_ID_NONE, relay, 
			&relay_timeout_cb);
    resched_timeout(alloc);
    
    /* Transport type */
    relay->hkey.tp_type = req->tp_type;

    /* Create the socket */
    if (req->tp_type == PJ_TURN_TP_UDP) {
	sock_type = pj_SOCK_DGRAM();
    } else if (req->tp_type == PJ_TURN_TP_TCP) {
	sock_type = pj_SOCK_STREAM();
    } else {
	pj_assert(!"Unknown transport");
	return PJ_EINVALIDOP;
    }

    status = pj_sock_socket(af, sock_type, 0, &relay->tp.sock);
    if (status != PJ_SUCCESS) {
	pj_bzero(relay, sizeof(*relay));
	return status;
    }

    /* Find suitable port for this allocation */
    if (req->rpp_port) {
	retry_max = 1;
    } else {
	retry_max = RETRY;
    }

    for (retry=0; retry<retry_max; ++retry) {
	pj_uint16_t port;
	pj_sockaddr bound_addr;

	pj_lock_acquire(srv->core.lock);

	if (req->rpp_port) {
	    port = (pj_uint16_t) req->rpp_port;
	} else if (req->tp_type == PJ_TURN_TP_UDP) {
	    port = (pj_uint16_t) srv->ports.next_udp++;
	    if (srv->ports.next_udp > srv->ports.max_udp)
		srv->ports.next_udp = srv->ports.min_udp;
	} else if (req->tp_type == PJ_TURN_TP_TCP) {
	    port = (pj_uint16_t) srv->ports.next_tcp++;
	    if (srv->ports.next_tcp > srv->ports.max_tcp)
		srv->ports.next_tcp = srv->ports.min_tcp;
	} else {
	    pj_assert(!"Invalid transport");
	    port = 0;
	}

	pj_lock_release(srv->core.lock);

	pj_sockaddr_init(af, &bound_addr, NULL, port);

	status = pj_sock_bind(relay->tp.sock, &bound_addr, 
			      pj_sockaddr_get_len(&bound_addr));
	if (status == PJ_SUCCESS)
	    break;
    }

    if (status != PJ_SUCCESS) {
	/* Unable to allocate port */
	PJ_LOG(4,(THIS_FILE, "Unable to allocate relay, giving up: err %d", 
		  status));
	pj_sock_close(relay->tp.sock);
	relay->tp.sock = PJ_INVALID_SOCKET;
	return status;
    }

    /* Init relay key */
    namelen = sizeof(relay->hkey.addr);
    status = pj_sock_getsockname(relay->tp.sock, &relay->hkey.addr, &namelen);
    if (status != PJ_SUCCESS) {
	PJ_LOG(4,(THIS_FILE, "pj_sock_getsockname() failed: err %d", 
		  status));
	pj_sock_close(relay->tp.sock);
	relay->tp.sock = PJ_INVALID_SOCKET;
	return status;
    }
    if (!pj_sockaddr_has_addr(&relay->hkey.addr)) {
	pj_sockaddr_copy_addr(&relay->hkey.addr, 
			      &alloc->transport->listener->addr);
    }
    if (!pj_sockaddr_has_addr(&relay->hkey.addr)) {
	pj_sockaddr tmp_addr;
	pj_gethostip(af, &tmp_addr);
	pj_sockaddr_copy_addr(&relay->hkey.addr, &tmp_addr);
    }

    /* Init ioqueue */
    pj_bzero(&icb, sizeof(icb));
    icb.on_read_complete = &on_rx_from_peer;

    status = pj_ioqueue_register_sock(pool, srv->core.ioqueue, relay->tp.sock,
				      relay, &icb, &relay->tp.key);
    if (status != PJ_SUCCESS) {
	PJ_LOG(4,(THIS_FILE, "pj_ioqueue_register_sock() failed: err %d", 
		  status));
	pj_sock_close(relay->tp.sock);
	relay->tp.sock = PJ_INVALID_SOCKET;
	return status;
    }

    /* Kick off pending read operation */
    pj_ioqueue_op_key_init(&relay->tp.read_key, sizeof(relay->tp.read_key));
    on_rx_from_peer(relay->tp.key, &relay->tp.read_key, 0);

    /* Done */
    return PJ_SUCCESS;
}

/* Create and send error response */
static void send_reply_err(pj_turn_allocation *alloc,
			   const pj_stun_rx_data *rdata,
			   pj_bool_t cache, 
			   int code, const char *errmsg)
{
    pj_status_t status;

    status = pj_stun_session_respond(alloc->sess, rdata, code, errmsg, NULL, 
				     cache, &alloc->hkey.clt_addr,
				     pj_sockaddr_get_len(&alloc->hkey.clt_addr.addr));
    if (status != PJ_SUCCESS) {
	alloc_err(alloc, "Error sending STUN error response", status);
	return;
    }
}

/* Create and send successful response */
static void send_reply_ok(pj_turn_allocation *alloc,
		          const pj_stun_rx_data *rdata)
{
    pj_status_t status;
    unsigned interval;
    pj_stun_tx_data *tdata;

    status = pj_stun_session_create_res(alloc->sess, rdata, 0, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	alloc_err(alloc, "Error creating STUN success response", status);
	return;
    }

    /* Calculate time to expiration */
    if (alloc->relay.lifetime != 0) {
	pj_time_val now;
	pj_gettimeofday(&now);
	interval = alloc->relay.expiry.sec - now.sec;
    } else {
	interval = 0;
    }

    /* Add LIFETIME if this is not ChannelBind. */
    if (PJ_STUN_GET_METHOD(tdata->msg->hdr.type)!=PJ_STUN_CHANNEL_BIND_METHOD){
	pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
				  PJ_STUN_ATTR_LIFETIME, interval);

	/* Add BANDWIDTH if lifetime is not zero */
	if (interval != 0) {
	    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
				      PJ_STUN_ATTR_BANDWIDTH,
				      alloc->bandwidth);
	}
    }

    status = pj_stun_session_send_msg(alloc->sess, NULL, PJ_TRUE, 
				      PJ_FALSE, &alloc->hkey.clt_addr,  
				      pj_sockaddr_get_len(&alloc->hkey.clt_addr), 
				      tdata);
    if (status != PJ_SUCCESS) {
	alloc_err(alloc, "Error sending STUN success response", status);
	return;
    }
}


/* Create new permission */
static pj_turn_permission *create_permission(pj_turn_allocation *alloc,
					     const pj_sockaddr_t *peer_addr,
					     unsigned addr_len)
{
    pj_turn_permission *perm;

    perm = PJ_POOL_ZALLOC_T(alloc->pool, pj_turn_permission);
    pj_memcpy(&perm->hkey.peer_addr, peer_addr, addr_len);
    
    perm->allocation = alloc;
    perm->channel = PJ_TURN_INVALID_CHANNEL;

    pj_gettimeofday(&perm->expiry);
    perm->expiry.sec += PJ_TURN_PERM_TIMEOUT;

    /* Register to hash table (only the address part!) */
    pj_hash_set(alloc->pool, alloc->peer_table, 
		pj_sockaddr_get_addr(&perm->hkey.peer_addr), 
	        pj_sockaddr_get_addr_len(&perm->hkey.peer_addr), 0, perm);

    return perm;
}

/* Check if a permission isn't expired. Return NULL if expired. */
static pj_turn_permission *check_permission_expiry(pj_turn_permission *perm)
{
    pj_turn_allocation *alloc = perm->allocation;
    pj_time_val now;

    pj_gettimeofday(&now);
    if (PJ_TIME_VAL_GT(perm->expiry, now)) {
	/* Permission has not expired */
	return perm;
    }

    /* Remove from permission hash table */
    pj_hash_set(NULL, alloc->peer_table, 
		pj_sockaddr_get_addr(&perm->hkey.peer_addr), 
	        pj_sockaddr_get_addr_len(&perm->hkey.peer_addr), 0, NULL);

    /* Remove from channel hash table, if assigned a channel number */
    if (perm->channel != PJ_TURN_INVALID_CHANNEL) {
	pj_hash_set(NULL, alloc->ch_table, &perm->channel, 
		    sizeof(perm->channel), 0, NULL);
    }

    return NULL;
}

/* Lookup permission in hash table by the peer address */
static pj_turn_permission*
lookup_permission_by_addr(pj_turn_allocation *alloc,
			  const pj_sockaddr_t *peer_addr,
			  unsigned addr_len)
{
    pj_turn_permission *perm;

    PJ_UNUSED_ARG(addr_len);

    /* Lookup in peer hash table */
    perm = (pj_turn_permission*) 
	   pj_hash_get(alloc->peer_table, 
		       pj_sockaddr_get_addr(peer_addr),
		       pj_sockaddr_get_addr_len(peer_addr), 
		       NULL);
    return perm ? check_permission_expiry(perm) : NULL;
}

/* Lookup permission in hash table by the channel number */
static pj_turn_permission*
lookup_permission_by_chnum(pj_turn_allocation *alloc,
			   unsigned chnum)
{
    pj_uint16_t chnum16 = (pj_uint16_t)chnum;
    pj_turn_permission *perm;

    /* Lookup in peer hash table */
    perm = (pj_turn_permission*) pj_hash_get(alloc->ch_table, &chnum16,
					    sizeof(chnum16), NULL);
    return perm ? check_permission_expiry(perm) : NULL;
}

/* Update permission because of data from client to peer. 
 * Return PJ_TRUE is permission is found.
 */
static pj_bool_t refresh_permission(pj_turn_permission *perm)
{
    pj_gettimeofday(&perm->expiry);
    if (perm->channel == PJ_TURN_INVALID_CHANNEL)
	perm->expiry.sec += PJ_TURN_PERM_TIMEOUT;
    else
	perm->expiry.sec += PJ_TURN_CHANNEL_TIMEOUT;
    return PJ_TRUE;
}

/*
 * Handle incoming packet from client. This would have been called by
 * server upon receiving packet from a listener.
 */
PJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,
						 pj_turn_pkt *pkt)
{
    pj_bool_t is_stun;
    pj_status_t status;

    /* Lock this allocation */
    pj_lock_acquire(alloc->lock);

    /* Quickly check if this is STUN message */
    is_stun = ((*((pj_uint8_t*)pkt->pkt) & 0xC0) == 0);

    if (is_stun) {
	/*
	 * This could be an incoming STUN requests or indications.
	 * Pass this through to the STUN session, which will call
	 * our stun_on_rx_request() or stun_on_rx_indication()
	 * callbacks.
	 *
	 * Note: currently it is necessary to specify the 
	 * PJ_STUN_NO_FINGERPRINT_CHECK otherwise the FINGERPRINT
	 * attribute inside STUN Send Indication message will mess up
	 * with fingerprint checking.
	 */
	unsigned options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK;
	unsigned parsed_len = 0;

	if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP)
	    options |= PJ_STUN_IS_DATAGRAM;

	status = pj_stun_session_on_rx_pkt(alloc->sess, pkt->pkt, pkt->len,
					   options, NULL, &parsed_len,
					   &pkt->src.clt_addr, 
					   pkt->src_addr_len);

	if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) {
	    pkt->len = 0;
	} else if (parsed_len > 0) {
	    if (parsed_len == pkt->len) {
		pkt->len = 0;
	    } else {
		pj_memmove(pkt->pkt, pkt->pkt+parsed_len,
			   pkt->len - parsed_len);
		pkt->len -= parsed_len;
	    }
	}

	if (status != PJ_SUCCESS) {
	    alloc_err(alloc, "Error handling STUN packet", status);
	    goto on_return;
	}

    } else {
	/*
	 * This is not a STUN packet, must be ChannelData packet.
	 */
	pj_turn_channel_data *cd = (pj_turn_channel_data*)pkt->pkt;
	pj_turn_permission *perm;
	pj_ssize_t len;

	pj_assert(sizeof(*cd)==4);

	/* For UDP check the packet length */
	if (alloc->transport->listener->tp_type == PJ_TURN_TP_UDP) {
	    if (pkt->len < pj_ntohs(cd->length)+sizeof(*cd)) {
		PJ_LOG(4,(alloc->obj_name, 
			  "ChannelData from %s discarded: UDP size error",
			  alloc->info));
		goto on_return;
	    }
	} else {
	    pj_assert(!"Unsupported transport");
	    goto on_return;
	}

	perm = lookup_permission_by_chnum(alloc, pj_ntohs(cd->ch_number));
	if (!perm) {
	    /* Discard */
	    PJ_LOG(4,(alloc->obj_name, 
		      "ChannelData from %s discarded: ch#0x%x not found",
		      alloc->info, pj_ntohs(cd->ch_number)));
	    goto on_return;
	}

	/* Relay the data */
	len = pj_ntohs(cd->length);
	pj_sock_sendto(alloc->relay.tp.sock, cd+1, &len, 0,
		       &perm->hkey.peer_addr,
		       pj_sockaddr_get_len(&perm->hkey.peer_addr));

	/* Refresh permission */
	refresh_permission(perm);
    }

on_return:
    /* Release lock */
    pj_lock_release(alloc->lock);
}


/*
 * Handle incoming packet from peer. This function is called by 
 * on_rx_from_peer().
 */
static void handle_peer_pkt(pj_turn_allocation *alloc,
			    pj_turn_relay_res *rel,
			    char *pkt, pj_size_t len,
			    const pj_sockaddr *src_addr)
{
    pj_turn_permission *perm;

    /* Lookup permission */
    perm = lookup_permission_by_addr(alloc, src_addr, 
				     pj_sockaddr_get_len(src_addr));
    if (perm == NULL) {
	/* No permission, discard data */
	return;
    }

    /* Send Data Indication or ChannelData, depends on whether
     * this permission is attached to a channel number.
     */
    if (perm->channel != PJ_TURN_INVALID_CHANNEL) {
	/* Send ChannelData */
	pj_turn_channel_data *cd = (pj_turn_channel_data*)rel->tp.tx_pkt;

	if (len > PJ_TURN_MAX_PKT_LEN) {
	    char peer_addr[80];
	    pj_sockaddr_print(src_addr, peer_addr, sizeof(peer_addr), 3);
	    PJ_LOG(4,(alloc->obj_name, "Client %s: discarded data from %s "
		      "because it's too long (%d bytes)",
		      alloc->info, peer_addr, len));
	    return;
	}

	/* Init header */
	cd->ch_number = pj_htons(perm->channel);
	cd->length = pj_htons((pj_uint16_t)len);

	/* Copy data */
	pj_memcpy(rel->tp.tx_pkt+sizeof(pj_turn_channel_data), pkt, len);

	/* Send to client */
	alloc->transport->sendto(alloc->transport, rel->tp.tx_pkt,
			         len+sizeof(pj_turn_channel_data), 0,
			         &alloc->hkey.clt_addr,
			         pj_sockaddr_get_len(&alloc->hkey.clt_addr));
    } else {
	/* Send Data Indication */
	pj_stun_tx_data *tdata;
	pj_status_t status;

	status = pj_stun_session_create_ind(alloc->sess, 
					    PJ_STUN_DATA_INDICATION, &tdata);
	if (status != PJ_SUCCESS) {
	    alloc_err(alloc, "Error creating Data indication", status);
	    return;
	}

	pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 
				      PJ_STUN_ATTR_PEER_ADDR, PJ_TRUE,
				      src_addr, pj_sockaddr_get_len(src_addr));
	pj_stun_msg_add_binary_attr(tdata->pool, tdata->msg,
				    PJ_STUN_ATTR_DATA, 
				    (const pj_uint8_t*)pkt, len);

	pj_stun_session_send_msg(alloc->sess, NULL, PJ_FALSE, 
				 PJ_FALSE, &alloc->hkey.clt_addr, 
				 pj_sockaddr_get_len(&alloc->hkey.clt_addr), 
				 tdata);
    }
}

/*
 * ioqueue notification on RX packets from the relay socket.
 */
static void on_rx_from_peer(pj_ioqueue_key_t *key, 
                            pj_ioqueue_op_key_t *op_key, 
                            pj_ssize_t bytes_read)
{
    pj_turn_relay_res *rel;
    pj_status_t status;

    rel = (pj_turn_relay_res*) pj_ioqueue_get_user_data(key);

    /* Lock the allocation */
    pj_lock_acquire(rel->allocation->lock);

    do {
	if (bytes_read > 0) {
	    handle_peer_pkt(rel->allocation, rel, rel->tp.rx_pkt,
			    bytes_read, &rel->tp.src_addr);
	}

	/* Read next packet */
	bytes_read = sizeof(rel->tp.rx_pkt);
	rel->tp.src_addr_len = sizeof(rel->tp.src_addr);
	status = pj_ioqueue_recvfrom(key, op_key,
				     rel->tp.rx_pkt, &bytes_read, 0,
				     &rel->tp.src_addr, 
				     &rel->tp.src_addr_len);

	if (status != PJ_EPENDING && status != PJ_SUCCESS)
	    bytes_read = -status;

    } while (status != PJ_EPENDING && status != PJ_ECANCELLED);

    /* Release allocation lock */
    pj_lock_release(rel->allocation->lock);
}

/*
 * Callback notification from STUN session when it wants to send
 * a STUN message towards the client.
 */
static pj_status_t stun_on_send_msg(pj_stun_session *sess,
				    void *token,
				    const void *pkt,
				    pj_size_t pkt_size,
				    const pj_sockaddr_t *dst_addr,
				    unsigned addr_len)
{
    pj_turn_allocation *alloc;

    PJ_UNUSED_ARG(token);

    alloc = (pj_turn_allocation*) pj_stun_session_get_user_data(sess);

    return alloc->transport->sendto(alloc->transport, pkt, pkt_size, 0,
				    dst_addr, addr_len);
}

/*
 * Callback notification from STUN session when it receives STUN
 * requests. This callback was trigger by STUN incoming message
 * processing in pj_turn_allocation_on_rx_client_pkt().
 */
static pj_status_t stun_on_rx_request(pj_stun_session *sess,
				      const pj_uint8_t *pkt,
				      unsigned pkt_len,
				      const pj_stun_rx_data *rdata,
				      void *token,
				      const pj_sockaddr_t *src_addr,
				      unsigned src_addr_len)
{
    const pj_stun_msg *msg = rdata->msg;
    pj_turn_allocation *alloc;

    PJ_UNUSED_ARG(pkt);
    PJ_UNUSED_ARG(pkt_len);
    PJ_UNUSED_ARG(token);
    PJ_UNUSED_ARG(src_addr);
    PJ_UNUSED_ARG(src_addr_len);

    alloc = (pj_turn_allocation*) pj_stun_session_get_user_data(sess);

    /* Refuse to serve any request if we've been shutdown */
    if (alloc->relay.lifetime == 0) {
	/* Reject with 437 if we're shutting down */
	send_reply_err(alloc, rdata, PJ_TRUE, 
		       PJ_STUN_SC_ALLOCATION_MISMATCH, NULL);
	return PJ_SUCCESS;
    }

    if (msg->hdr.type == PJ_STUN_REFRESH_REQUEST) {
	/* 
	 * Handle REFRESH request 
	 */
	pj_stun_lifetime_attr *lifetime;
	pj_stun_bandwidth_attr *bandwidth;

	/* Get LIFETIME attribute */
	lifetime = (pj_stun_lifetime_attr*)
		   pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_LIFETIME, 0);

	/* Get BANDWIDTH attribute */
	bandwidth = (pj_stun_bandwidth_attr*)
	            pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_BANDWIDTH, 0);

	if (lifetime && lifetime->value==0) {
	    /*
	     * This is deallocation request.
	     */
	    alloc->relay.lifetime = 0;

	    /* Respond first */
	    send_reply_ok(alloc, rdata);

	    /* Shutdown allocation */
	    PJ_LOG(4,(alloc->obj_name, 
		      "Client %s request to dealloc, shutting down",
		      alloc->info));

	    alloc_shutdown(alloc);

	} else {
	    /*
	     * This is a refresh request.
	     */
	    
	    /* Update lifetime */
	    if (lifetime) {
		alloc->relay.lifetime = lifetime->value;
	    }

	    /* Update bandwidth */
	    // TODO:

	    /* Update expiration timer */
	    resched_timeout(alloc);

	    /* Send reply */
	    send_reply_ok(alloc, rdata);
	}

    } else if (msg->hdr.type == PJ_STUN_CHANNEL_BIND_REQUEST) {
	/*
	 * ChannelBind request.
	 */
	pj_stun_channel_number_attr *ch_attr;
	pj_stun_peer_addr_attr *peer_attr;
	pj_turn_permission *p1, *p2;

	ch_attr = (pj_stun_channel_number_attr*)
		  pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_CHANNEL_NUMBER, 0);
	peer_attr = (pj_stun_peer_addr_attr*)
		    pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_PEER_ADDR, 0);

	if (!ch_attr || !peer_attr) {
	    send_reply_err(alloc, rdata, PJ_TRUE, 
			   PJ_STUN_SC_BAD_REQUEST, NULL);
	    return PJ_SUCCESS;
	}

	/* Find permission with the channel number */
	p1 = lookup_permission_by_chnum(alloc, PJ_STUN_GET_CH_NB(ch_attr->value));

	/* If permission is found, this is supposed to be a channel bind 
	 * refresh. Make sure it's for the same peer.
	 */
	if (p1) {
	    if (pj_sockaddr_cmp(&p1->hkey.peer_addr, &peer_attr->sockaddr)) {
		/* Address mismatch. Send 400 */
		send_reply_err(alloc, rdata, PJ_TRUE, 
			       PJ_STUN_SC_BAD_REQUEST, 
			       "Peer address mismatch");
		return PJ_SUCCESS;
	    }

	    /* Refresh permission */
	    refresh_permission(p1);

	    /* Send response */
	    send_reply_ok(alloc, rdata);

	    /* Done */
	    return PJ_SUCCESS;
	}

	/* If permission is not found, create a new one. Make sure the peer
	 * has not alreadyy assigned with a channel number.
	 */
	p2 = lookup_permission_by_addr(alloc, &peer_attr->sockaddr,
				       pj_sockaddr_get_len(&peer_attr->sockaddr));
	if (p2 && p2->channel != PJ_TURN_INVALID_CHANNEL) {
	    send_reply_err(alloc, rdata, PJ_TRUE, PJ_STUN_SC_BAD_REQUEST, 
			   "Peer address already assigned a channel number");
	    return PJ_SUCCESS;
	}

	/* Create permission if it doesn't exist */
	if (!p2) {
	    p2 = create_permission(alloc, &peer_attr->sockaddr,
				   pj_sockaddr_get_len(&peer_attr->sockaddr));
	    if (!p2)
		return PJ_SUCCESS;
	}

	/* Assign channel number to permission */
	p2->channel = PJ_STUN_GET_CH_NB(ch_attr->value);

	/* Register to hash table */
	pj_assert(sizeof(p2->channel==2));
	pj_hash_set(alloc->pool, alloc->ch_table, &p2->channel, 
		    sizeof(p2->channel), 0, p2);

	/* Update */
	refresh_permission(p2);

	/* Reply */
	send_reply_ok(alloc, rdata);

	return PJ_SUCCESS;

    } else if (msg->hdr.type == PJ_STUN_ALLOCATE_REQUEST) {

	/* Respond with 437 (section 6.3 turn-07) */
	send_reply_err(alloc, rdata, PJ_TRUE, PJ_STUN_SC_ALLOCATION_MISMATCH,
		       NULL);

    } else {

	/* Respond with Bad Request? */
	send_reply_err(alloc, rdata, PJ_TRUE, PJ_STUN_SC_BAD_REQUEST, NULL);

    }

    return PJ_SUCCESS;
}

/*
 * Callback notification from STUN session when it receives STUN
 * indications. This callback was trigger by STUN incoming message
 * processing in pj_turn_allocation_on_rx_client_pkt().
 */
static pj_status_t stun_on_rx_indication(pj_stun_session *sess,
					 const pj_uint8_t *pkt,
					 unsigned pkt_len,
					 const pj_stun_msg *msg,
					 void *token,
					 const pj_sockaddr_t *src_addr,
					 unsigned src_addr_len)
{
    pj_stun_peer_addr_attr *peer_attr;
    pj_stun_data_attr *data_attr;
    pj_turn_allocation *alloc;
    pj_turn_permission *perm;
    pj_ssize_t len;

    PJ_UNUSED_ARG(pkt);
    PJ_UNUSED_ARG(pkt_len);
    PJ_UNUSED_ARG(token);
    PJ_UNUSED_ARG(src_addr);
    PJ_UNUSED_ARG(src_addr_len);

    alloc = (pj_turn_allocation*) pj_stun_session_get_user_data(sess);

    /* Only expect Send Indication */
    if (msg->hdr.type != PJ_STUN_SEND_INDICATION) {
	/* Ignore */
	return PJ_SUCCESS;
    }

    /* Get PEER-ADDRESS attribute */
    peer_attr = (pj_stun_peer_addr_attr*)
		pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_PEER_ADDR, 0);

    /* MUST have PEER-ADDRESS attribute */
    if (!peer_attr)
	return PJ_SUCCESS;

    /* Get DATA attribute */
    data_attr = (pj_stun_data_attr*)
		pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_DATA, 0);

    /* Create/update/refresh the permission */
    perm = lookup_permission_by_addr(alloc, &peer_attr->sockaddr,
				     pj_sockaddr_get_len(&peer_attr->sockaddr));
    if (perm == NULL) {
	perm = create_permission(alloc, &peer_attr->sockaddr,
				 pj_sockaddr_get_len(&peer_attr->sockaddr));
    }
    refresh_permission(perm);

    /* Return if we don't have data */
    if (data_attr == NULL)
	return PJ_SUCCESS;

    /* Relay the data to peer */
    len = data_attr->length;
    pj_sock_sendto(alloc->relay.tp.sock, data_attr->data, 
		   &len, 0, &peer_attr->sockaddr,
		   pj_sockaddr_get_len(&peer_attr->sockaddr));

    return PJ_SUCCESS;
}


