Ignore:
Timestamp:
Dec 1, 2007 8:59:25 AM (16 years ago)
Author:
bennylp
Message:

Ticket #421: initial IPv6 support: UDP transport

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_resolve.c

    r1484 r1602  
    2222#include <pjlib-util/errno.h> 
    2323#include <pjlib-util/srv_resolver.h> 
     24#include <pj/addr_resolv.h> 
    2425#include <pj/array.h> 
    2526#include <pj/assert.h> 
     
    138139/* 
    139140 * Internal: 
    140  *  determine if an address is a valid IP address. 
    141  */ 
    142 static int is_str_ip(const pj_str_t *host) 
    143 { 
    144     const char *p = host->ptr; 
    145     const char *end = ((const char*)host->ptr) + host->slen; 
    146  
    147     while (p != end) { 
    148         if (pj_isdigit(*p) || *p=='.') { 
    149             ++p; 
    150         } else { 
    151             return 0; 
    152         } 
    153     } 
    154     return 1; 
     141 *  determine if an address is a valid IP address, and if it is, 
     142 *  return the IP version (4 or 6). 
     143 */ 
     144static int get_ip_addr_ver(const pj_str_t *host) 
     145{ 
     146    pj_in_addr dummy; 
     147    pj_in6_addr dummy6; 
     148 
     149    /* First check with inet_aton() */ 
     150    if (pj_inet_aton(host, &dummy) > 0) 
     151        return 4; 
     152 
     153    /* Then check if this is an IPv6 address */ 
     154    if (pj_inet_pton(pj_AF_INET6(), host, &dummy6) == PJ_SUCCESS) 
     155        return 6; 
     156 
     157    /* Not an IP address */ 
     158    return 0; 
    155159} 
    156160 
     
    167171    pjsip_server_addresses svr_addr; 
    168172    pj_status_t status = PJ_SUCCESS; 
    169     int is_ip_addr; 
     173    int ip_addr_ver; 
    170174    struct query *query; 
    171175    pjsip_transport_type_e type = target->type; 
    172176 
    173     /* Is it IP address or hostname?. */ 
    174     is_ip_addr = is_str_ip(&target->addr.host); 
     177    /* Is it IP address or hostname? And if it's an IP, which version? */ 
     178    ip_addr_ver = get_ip_addr_ver(&target->addr.host); 
    175179 
    176180    /* Set the transport type if not explicitly specified.  
     
    178182     */ 
    179183    if (type == PJSIP_TRANSPORT_UNSPECIFIED) { 
    180         if (is_ip_addr || (target->addr.port != 0)) { 
     184        if (ip_addr_ver || (target->addr.port != 0)) { 
    181185#if PJ_HAS_TCP 
    182186            if (target->flag & PJSIP_TRANSPORT_SECURE)  
     
    210214            } 
    211215        } 
     216 
     217        /* Add IPv6 flag for IPv6 address */ 
     218        if (ip_addr_ver == 6) 
     219            type = (pjsip_transport_type_e)((int)type + PJSIP_TRANSPORT_IPV6); 
    212220    } 
    213221 
     
    216224     * we can just finish the resolution now using pj_gethostbyname() 
    217225     */ 
    218     if (is_ip_addr || resolver->res == NULL) { 
     226    if (ip_addr_ver || resolver->res == NULL) { 
    219227 
    220228        pj_in_addr ip_addr; 
     229        int af; 
     230        pj_addrinfo ai; 
     231        unsigned count; 
    221232        pj_uint16_t srv_port; 
    222233 
    223         if (!is_ip_addr) { 
     234        if (!ip_addr_ver) { 
    224235            PJ_LOG(5,(THIS_FILE,  
    225236                      "DNS resolver not available, target '%.*s:%d' type=%s " 
     
    239250        } 
    240251 
    241         /* This will eventually call pj_gethostbyname() if the host 
    242          * is not an IP address. 
    243          */ 
    244         status = pj_sockaddr_in_init((pj_sockaddr_in*)&svr_addr.entry[0].addr, 
    245                                       &target->addr.host, srv_port); 
     252        if (type & PJSIP_TRANSPORT_IPV6) { 
     253            af = pj_AF_INET6(); 
     254        } else { 
     255            af = pj_AF_INET(); 
     256        } 
     257 
     258        /* Resolve */ 
     259        count = 1; 
     260        status = pj_getaddrinfo(af, &target->addr.host, &count, &ai); 
    246261        if (status != PJ_SUCCESS) 
    247262            goto on_error; 
     263 
     264        svr_addr.entry[0].addr.addr.sa_family = (pj_uint16_t)af; 
     265        pj_memcpy(&svr_addr.entry[0].addr, &ai.ai_addr, sizeof(pj_sockaddr)); 
     266 
     267        if (af == pj_AF_INET6()) { 
     268            svr_addr.entry[0].addr.ipv6.sin6_port = pj_htons(srv_port); 
     269        } else { 
     270            svr_addr.entry[0].addr.ipv4.sin_port = pj_htons(srv_port); 
     271        } 
    248272 
    249273        /* Call the callback. */ 
Note: See TracChangeset for help on using the changeset viewer.