/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 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 <pjsip/sip_resolve.h>
#include <pjsip/sip_transport.h>
#include <pjsip/sip_errno.h>
#include <pjlib-util/errno.h>
#include <pjlib-util/srv_resolver.h>
#include <pj/addr_resolv.h>
#include <pj/array.h>
#include <pj/assert.h>
#include <pj/ctype.h>
#include <pj/log.h>
#include <pj/pool.h>
#include <pj/rand.h>
#include <pj/string.h>


#define THIS_FILE   "sip_resolve.c"

#define ADDR_MAX_COUNT	    8

struct naptr_target
{
    pj_str_t		    res_type;	    /**< e.g. "_sip._udp"   */
    pj_str_t		    name;	    /**< Domain name.	    */
    pjsip_transport_type_e  type;	    /**< Transport type.    */
    unsigned		    order;	    /**< Order		    */
    unsigned		    pref;	    /**< Preference.	    */
};

struct query
{
    char		    *objname;

    pj_dns_type		     query_type;
    void		    *token;
    pjsip_resolver_callback *cb;
    pj_dns_async_query	    *object;
    pj_status_t		     last_error;

    /* Original request: */
    struct {
	pjsip_host_info	     target;
	unsigned	     def_port;
    } req;

    /* NAPTR records: */
    unsigned		     naptr_cnt;
    struct naptr_target	     naptr[8];
};


struct pjsip_resolver_t
{
    pj_dns_resolver *res;
};


static void srv_resolver_cb(void *user_data,
			    pj_status_t status,
			    const pj_dns_srv_record *rec);
static void dns_a_callback(void *user_data,
			   pj_status_t status,
			   pj_dns_parsed_packet *response);


/*
 * Public API to create the resolver.
 */
PJ_DEF(pj_status_t) pjsip_resolver_create( pj_pool_t *pool,
					   pjsip_resolver_t **p_res)
{
    pjsip_resolver_t *resolver;

    PJ_ASSERT_RETURN(pool && p_res, PJ_EINVAL);
    resolver = PJ_POOL_ZALLOC_T(pool, pjsip_resolver_t);
    *p_res = resolver;

    return PJ_SUCCESS;
}


/*
 * Public API to set the DNS resolver instance for the SIP resolver.
 */
PJ_DEF(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res,
						pj_dns_resolver *dns_res)
{
#if PJSIP_HAS_RESOLVER
    res->res = dns_res;
    return PJ_SUCCESS;
#else
    PJ_UNUSED_ARG(res);
    PJ_UNUSED_ARG(dns_res);
    pj_assert(!"Resolver is disabled (PJSIP_HAS_RESOLVER==0)");
    return PJ_EINVALIDOP;
#endif
}


/*
 * Public API to get the internal DNS resolver.
 */
PJ_DEF(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res)
{
    return res->res;
}


/*
 * Public API to create destroy the resolver
 */
PJ_DEF(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver)
{
    if (resolver->res) {
#if PJSIP_HAS_RESOLVER
	pj_dns_resolver_destroy(resolver->res, PJ_FALSE);
#endif
	resolver->res = NULL;
    }
}

/*
 * Internal:
 *  determine if an address is a valid IP address, and if it is,
 *  return the IP version (4 or 6).
 */
static int get_ip_addr_ver(const pj_str_t *host)
{
    pj_in_addr dummy;
    pj_in6_addr dummy6;

    /* First check with inet_aton() */
    if (pj_inet_aton(host, &dummy) > 0)
	return 4;

    /* Then check if this is an IPv6 address */
    if (pj_inet_pton(pj_AF_INET6(), host, &dummy6) == PJ_SUCCESS)
	return 6;

    /* Not an IP address */
    return 0;
}


/*
 * This is the main function for performing server resolution.
 */
PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
			    pj_pool_t *pool,
			    const pjsip_host_info *target,
			    void *token,
			    pjsip_resolver_callback *cb)
{
    pjsip_server_addresses svr_addr;
    pj_status_t status = PJ_SUCCESS;
    int ip_addr_ver;
    struct query *query;
    pjsip_transport_type_e type = target->type;

    /* Is it IP address or hostname? And if it's an IP, which version? */
    ip_addr_ver = get_ip_addr_ver(&target->addr.host);

    /* Set the transport type if not explicitly specified. 
     * RFC 3263 section 4.1 specify rules to set up this.
     */
    if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
	if (ip_addr_ver || (target->addr.port != 0)) {
#if PJ_HAS_TCP
	    if (target->flag & PJSIP_TRANSPORT_SECURE) 
	    {
		type = PJSIP_TRANSPORT_TLS;
	    } else if (target->flag & PJSIP_TRANSPORT_RELIABLE) 
	    {
		type = PJSIP_TRANSPORT_TCP;
	    } else 
#endif
	    {
		type = PJSIP_TRANSPORT_UDP;
	    }
	} else {
	    /* No type or explicit port is specified, and the address is
	     * not IP address.
	     * In this case, full NAPTR resolution must be performed.
	     * But we don't support it (yet).
	     */
#if PJ_HAS_TCP
	    if (target->flag & PJSIP_TRANSPORT_SECURE) 
	    {
		type = PJSIP_TRANSPORT_TLS;
	    } else if (target->flag & PJSIP_TRANSPORT_RELIABLE) 
	    {
		type = PJSIP_TRANSPORT_TCP;
	    } else 
#endif
	    {
		type = PJSIP_TRANSPORT_UDP;
	    }
	}

	/* Add IPv6 flag for IPv6 address */
	if (ip_addr_ver == 6)
	    type = (pjsip_transport_type_e)((int)type + PJSIP_TRANSPORT_IPV6);
    }


    /* If target is an IP address, or if resolver is not configured, 
     * we can just finish the resolution now using pj_gethostbyname()
     */
    if (ip_addr_ver || resolver->res == NULL) {
	char addr_str[PJ_INET6_ADDRSTRLEN+10];
	pj_uint16_t srv_port;

	if (ip_addr_ver != 0) {
	    /* Target is an IP address, no need to resolve */
	    if (ip_addr_ver == 4) {
		pj_sockaddr_init(pj_AF_INET(), &svr_addr.entry[0].addr, 
				 NULL, 0);
		pj_inet_aton(&target->addr.host,
			     &svr_addr.entry[0].addr.ipv4.sin_addr);
	    } else {
		pj_sockaddr_init(pj_AF_INET6(), &svr_addr.entry[0].addr, 
				 NULL, 0);
		pj_inet_pton(pj_AF_INET6(), &target->addr.host,
			     &svr_addr.entry[0].addr.ipv6.sin6_addr);
	    }
	} else {
	    pj_addrinfo ai;
	    unsigned count;
	    int af;

	    PJ_LOG(5,(THIS_FILE,
		      "DNS resolver not available, target '%.*s:%d' type=%s "
		      "will be resolved with getaddrinfo()",
		      target->addr.host.slen,
		      target->addr.host.ptr,
		      target->addr.port,
		      pjsip_transport_get_type_name(target->type)));

	    if (type & PJSIP_TRANSPORT_IPV6) {
		af = pj_AF_INET6();
	    } else {
		af = pj_AF_INET();
	    }

	    /* Resolve */
	    count = 1;
	    status = pj_getaddrinfo(af, &target->addr.host, &count, &ai);
	    if (status != PJ_SUCCESS) {
		/* "Normalize" error to PJ_ERESOLVE. This is a special error
		 * because it will be translated to SIP status 502 by
		 * sip_transaction.c
		 */
		status = PJ_ERESOLVE;
		goto on_error;
	    }

	    svr_addr.entry[0].addr.addr.sa_family = (pj_uint16_t)af;
	    pj_memcpy(&svr_addr.entry[0].addr, &ai.ai_addr,
		      sizeof(pj_sockaddr));
	}

	/* Set the port number */
	if (target->addr.port == 0) {
	   srv_port = (pj_uint16_t)
		      pjsip_transport_get_default_port_for_type(type);
	} else {
	   srv_port = (pj_uint16_t)target->addr.port;
	}
	pj_sockaddr_set_port(&svr_addr.entry[0].addr, srv_port);

	/* Call the callback. */
	PJ_LOG(5,(THIS_FILE, 
		  "Target '%.*s:%d' type=%s resolved to "
		  "'%s' type=%s (%s)",
		  (int)target->addr.host.slen,
		  target->addr.host.ptr,
		  target->addr.port,
		  pjsip_transport_get_type_name(target->type),
		  pj_sockaddr_print(&svr_addr.entry[0].addr, addr_str,
				    sizeof(addr_str), 3),
		  pjsip_transport_get_type_name(type),
		  pjsip_transport_get_type_desc(type)));
	svr_addr.count = 1;
	svr_addr.entry[0].priority = 0;
	svr_addr.entry[0].weight = 0;
	svr_addr.entry[0].type = type;
	svr_addr.entry[0].addr_len = pj_sockaddr_get_len(&svr_addr.entry[0].addr);
	(*cb)(status, token, &svr_addr);

	/* Done. */
	return;
    }

    /* Target is not an IP address so we need to resolve it. */
#if PJSIP_HAS_RESOLVER

    /* Build the query state */
    query = PJ_POOL_ZALLOC_T(pool, struct query);
    query->objname = THIS_FILE;
    query->token = token;
    query->cb = cb;
    query->req.target = *target;
    pj_strdup(pool, &query->req.target.addr.host, &target->addr.host);

    /* If port is not specified, start with SRV resolution
     * (should be with NAPTR, but we'll do that later)
     */
    PJ_TODO(SUPPORT_DNS_NAPTR);

    /* Build dummy NAPTR entry */
    query->naptr_cnt = 1;
    pj_bzero(&query->naptr[0], sizeof(query->naptr[0]));
    query->naptr[0].order = 0;
    query->naptr[0].pref = 0;
    query->naptr[0].type = type;
    pj_strdup(pool, &query->naptr[0].name, &target->addr.host);


    /* Start DNS SRV or A resolution, depending on whether port is specified */
    if (target->addr.port == 0) {
	query->query_type = PJ_DNS_TYPE_SRV;

	query->req.def_port = 5060;

	if (type == PJSIP_TRANSPORT_TLS) {
	    query->naptr[0].res_type = pj_str("_sips._tcp.");
	    query->req.def_port = 5061;
	} else if (type == PJSIP_TRANSPORT_TCP)
	    query->naptr[0].res_type = pj_str("_sip._tcp.");
	else if (type == PJSIP_TRANSPORT_UDP)
	    query->naptr[0].res_type = pj_str("_sip._udp.");
	else {
	    pj_assert(!"Unknown transport type");
	    query->naptr[0].res_type = pj_str("_sip._udp.");
	    
	}

    } else {
	/* Otherwise if port is specified, start with A (or AAAA) host 
	 * resolution 
	 */
	query->query_type = PJ_DNS_TYPE_A;
	query->naptr[0].res_type.slen = 0;
	query->req.def_port = target->addr.port;
    }

    /* Start the asynchronous query */
    PJ_LOG(5, (query->objname, 
	       "Starting async DNS %s query: target=%.*s%.*s, transport=%s, "
	       "port=%d",
	       pj_dns_get_type_name(query->query_type),
	       (int)query->naptr[0].res_type.slen,
	       query->naptr[0].res_type.ptr,
	       (int)query->naptr[0].name.slen, query->naptr[0].name.ptr,
	       pjsip_transport_get_type_name(target->type),
	       target->addr.port));

    if (query->query_type == PJ_DNS_TYPE_SRV) {

	status = pj_dns_srv_resolve(&query->naptr[0].name,
				    &query->naptr[0].res_type,
				    query->req.def_port, pool, resolver->res,
				    PJ_TRUE, query, &srv_resolver_cb, NULL);

    } else if (query->query_type == PJ_DNS_TYPE_A) {

	status = pj_dns_resolver_start_query(resolver->res, 
					     &query->naptr[0].name,
					     PJ_DNS_TYPE_A, 0, 
					     &dns_a_callback,
    					     query, &query->object);

    } else {
	pj_assert(!"Unexpected");
	status = PJ_EBUG;
    }

    if (status != PJ_SUCCESS)
	goto on_error;

    return;

#else /* PJSIP_HAS_RESOLVER */
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(query);
    PJ_UNUSED_ARG(srv_name);
#endif /* PJSIP_HAS_RESOLVER */

on_error:
    if (status != PJ_SUCCESS) {
	char errmsg[PJ_ERR_MSG_SIZE];
	PJ_LOG(4,(THIS_FILE, "Failed to resolve '%.*s'. Err=%d (%s)",
			     (int)target->addr.host.slen,
			     target->addr.host.ptr,
			     status,
			     pj_strerror(status,errmsg,sizeof(errmsg)).ptr));
	(*cb)(status, token, NULL);
	return;
    }
}

#if PJSIP_HAS_RESOLVER

/* 
 * This callback is called when target is resolved with DNS A query.
 */
static void dns_a_callback(void *user_data,
			   pj_status_t status,
			   pj_dns_parsed_packet *pkt)
{
    struct query *query = (struct query*) user_data;
    pjsip_server_addresses srv;
    pj_dns_a_record rec;
    unsigned i;

    rec.addr_count = 0;

    /* Parse the response */
    if (status == PJ_SUCCESS) {
	status = pj_dns_parse_a_response(pkt, &rec);
    }

    if (status != PJ_SUCCESS) {
	char errmsg[PJ_ERR_MSG_SIZE];

	/* Log error */
	pj_strerror(status, errmsg, sizeof(errmsg));
	PJ_LOG(4,(query->objname, "DNS A record resolution failed: %s", 
		  errmsg));

	/* Call the callback */
	(*query->cb)(status, query->token, NULL);
	return;
    }

    /* Build server addresses and call callback */
    srv.count = 0;
    for (i=0; i<rec.addr_count; ++i) {
	srv.entry[srv.count].type = query->naptr[0].type;
	srv.entry[srv.count].priority = 0;
	srv.entry[srv.count].weight = 0;
	srv.entry[srv.count].addr_len = sizeof(pj_sockaddr_in);
	pj_sockaddr_in_init(&srv.entry[srv.count].addr.ipv4,
			    0, (pj_uint16_t)query->req.def_port);
	srv.entry[srv.count].addr.ipv4.sin_addr.s_addr =
	    rec.addr[i].s_addr;

	++srv.count;
    }

    /* Call the callback */
    (*query->cb)(PJ_SUCCESS, query->token, &srv);
}


/* Callback to be called by DNS SRV resolution */
static void srv_resolver_cb(void *user_data,
			    pj_status_t status,
			    const pj_dns_srv_record *rec)
{
    struct query *query = (struct query*) user_data;
    pjsip_server_addresses srv;
    unsigned i;

    if (status != PJ_SUCCESS) {
	char errmsg[PJ_ERR_MSG_SIZE];

	/* Log error */
	pj_strerror(status, errmsg, sizeof(errmsg));
	PJ_LOG(4,(query->objname, "DNS A record resolution failed: %s", 
		  errmsg));

	/* Call the callback */
	(*query->cb)(status, query->token, NULL);
	return;
    }

    /* Build server addresses and call callback */
    srv.count = 0;
    for (i=0; i<rec->count; ++i) {
	unsigned j;

	for (j=0; j<rec->entry[i].server.addr_count; ++j) {
	    srv.entry[srv.count].type = query->naptr[0].type;
	    srv.entry[srv.count].priority = rec->entry[i].priority;
	    srv.entry[srv.count].weight = rec->entry[i].weight;
	    srv.entry[srv.count].addr_len = sizeof(pj_sockaddr_in);
	    pj_sockaddr_in_init(&srv.entry[srv.count].addr.ipv4,
				0, (pj_uint16_t)rec->entry[i].port);
	    srv.entry[srv.count].addr.ipv4.sin_addr.s_addr =
		rec->entry[i].server.addr[j].s_addr;

	    ++srv.count;
	}
    }

    /* Call the callback */
    (*query->cb)(PJ_SUCCESS, query->token, &srv);
}

#endif	/* PJSIP_HAS_RESOLVER */

