blob: b89b7c01bf3f2db42071db79381ad3302b12f95b [file] [log] [blame]
/* $Id$ */
/*
* Copyright (C) 2003-2006 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 <pj/pool.h>
#include <pj/ctype.h>
#include <pj/assert.h>
struct pjsip_resolver_t
{
void *dummy;
};
PJ_DEF(pjsip_resolver_t*) pjsip_resolver_create(pj_pool_t *pool)
{
pjsip_resolver_t *resolver;
resolver = (pjsip_resolver_t*) pj_pool_calloc(pool, 1, sizeof(*resolver));
return resolver;
}
PJ_DEF(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver)
{
PJ_UNUSED_ARG(resolver);
}
static int is_str_ip(const pj_str_t *host)
{
const char *p = host->ptr;
const char *end = ((const char*)host->ptr) + host->slen;
while (p != end) {
if (pj_isdigit(*p) || *p=='.') {
++p;
} else {
return 0;
}
}
return 1;
}
PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
pj_pool_t *pool,
pjsip_host_port *target,
void *token,
pjsip_resolver_callback *cb)
{
struct pjsip_server_addresses svr_addr;
pj_status_t status;
int is_ip_addr;
pjsip_transport_type_e type = target->type;
PJ_UNUSED_ARG(resolver);
PJ_UNUSED_ARG(pool);
/* We only do synchronous resolving at this moment. */
PJ_TODO(SUPPORT_RFC3263_SERVER_RESOLUTION)
/* Is it IP address or hostname?. */
is_ip_addr = is_str_ip(&target->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 (is_ip_addr || (target->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 resolution must be performed.
* But we don't support it (yet).
*/
type = PJSIP_TRANSPORT_UDP;
}
}
/* Set the port number if not specified. */
if (target->port == 0) {
target->port = pjsip_transport_get_default_port_for_type(type);
}
/* Resolve hostname. */
if (!is_ip_addr) {
status = pj_sockaddr_in_init(&svr_addr.entry[0].addr, &target->host,
(pj_uint16_t)target->port);
} else {
status = pj_sockaddr_in_init(&svr_addr.entry[0].addr, &target->host,
(pj_uint16_t)target->port);
pj_assert(status == PJ_SUCCESS);
}
/* Call the callback. */
svr_addr.count = (status == PJ_SUCCESS) ? 1 : 0;
svr_addr.entry[0].type = type;
(*cb)(status, token, &svr_addr);
}