Ignore:
Timestamp:
Oct 8, 2006 12:39:34 PM (18 years ago)
Author:
bennylp
Message:

Major addition to support DNS SRV resolution in PJSIP:

  • added DNS asynchronous/caching resolver engine in PJLIB-UTIL (resolver.[hc])
  • modified SIP resolver (sip_resolve.c) to properly perform DNS SRV/A resolution when DNS resolution is enabled.
  • added dns_test.c in PJSIP-TEST for testing the SIP resolver.
  • added nameserver configuration in PJSUA-LIB
  • added "--nameserver" option in PJSUA.
  • updated project/Makefiles and doxygen documentation.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsip/sip_resolve.h

    r515 r753  
    2828 
    2929#include <pjsip/sip_types.h> 
     30#include <pjlib-util/resolver.h> 
    3031#include <pj/sock.h> 
    3132 
     
    3334 
    3435/** 
    35  * @defgroup PJSIP_RESOLVE Server Resolution 
     36 * @defgroup PJSIP_RESOLVE SIP SRV Server Resolution (RFC 3263 - Locating SIP Servers) 
    3637 * @ingroup PJSIP_TRANSPORT 
    3738 * @brief Framework to resolve SIP servers based on RFC 3263. 
    3839 * @{ 
    39  * This is the server resolution framework, which is modelled after  
    40  * RFC 3263 - Locating SIP Servers document. The server resolution 
     40 * \section PJSIP_RESOLVE_FEATURES Features 
     41 * 
     42 * This is the SIP server resolution framework, which is modelled after  
     43 * RFC 3263 - Locating SIP Servers document. The SIP server resolution 
    4144 * framework is asynchronous; callback will be called once the server  
    4245 * address has been resolved (successfully or with errors). 
    43  */ 
    44  
    45 /**  
    46  * Maximum number of addresses returned by the resolver.  
    47  */ 
    48 #define PJSIP_MAX_RESOLVED_ADDRESSES    8 
     46 * 
     47 * \subsection PJSIP_RESOLVE_CONFORMANT Conformance to RFC 3263 
     48 * 
     49 * The SIP server resolution framework is modelled after RFC 3263 (Locating  
     50 * SIP Servers) document, and it provides a single function (#pjsip_resolve()) 
     51 * to resolve a domain into actual IP addresses of the servers, by querying  
     52 * DNS SRV record and DNS A record where necessary. 
     53 * 
     54 * The #pjsip_resolve() function performs the server resolution according 
     55 * to RFC 3263 with some additional fallback mechanisms, as follows: 
     56 *  - if the target name is an IP address, the callback will be called 
     57 *    immediately with the IP address. If port number was specified, this 
     58 *    port number will be used, otherwise the default port number for the 
     59 *    transport will be used (5060 for TCP/UDP, 5061 for TLS) if the transport 
     60 *    is specified. If the transport is not specified, UDP with port number 
     61 *    5060 will be used. 
     62 *  - if target name is not an IP address but it contains port number, 
     63 *    then the target name is resolved with DNS A (or AAAA, when IPv6 is 
     64 *    supported in the future) query, and the port is taken from the 
     65 *    port number argument. The callback will be called once the DNS A 
     66 *    resolution completes. If the DNS A resolution returns multiple IP 
     67 *    addresses, these IP addresses will be returned to the caller. 
     68 *  - if target name is not an IP address and port number is not specified, 
     69 *    DNS SRV resolution will be performed for the specified name and 
     70 *    transport type (or UDP when transport is not specified),  
     71 *    then followed by DNS A (or AAAA, when IPv6 is supported) 
     72 *    resolution for each target in the SRV record. If DNS SRV 
     73 *    resolution returns error, DNS A (or AAAA) resolution will be 
     74 *    performed for the original target (it is assumed that the target domain 
     75 *    does not support SRV records). Upon successful completion,  
     76 *    application callback will be called with each IP address of the 
     77 *    target selected based on the load-balancing and fail-over criteria 
     78 *    below. 
     79 * 
     80 * The above server resolution procedure differs from RFC 3263 in these 
     81 * regards: 
     82 *  - currently #pjsip_resolve() doesn't support DNS NAPTR record. 
     83 *  - if transport is not specified, it is assumed to be UDP (the proper 
     84 *    behavior is to query the NAPTR record, but we don't support this 
     85 *    yet). 
     86 * 
     87 * 
     88 * \subsection PJSIP_SIP_RESOLVE_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over 
     89 * 
     90 * When multiple targets are returned in the DNS SRV response, server entries 
     91 * are selected based on the following rule (which is described in RFC 2782): 
     92 *  - targets will be sorted based on the priority first. 
     93 *  - for targets with the same priority, #pjsip_resolve() will select 
     94 *    only one target according to its weight. To select this one target, 
     95 *    the function associates running-sum for all targets, and generates  
     96 *    a random number between zero and the total running-sum (inclusive). 
     97 *    The target selected is the first target with running-sum greater than 
     98 *    or equal to this random number. 
     99 * 
     100 * The above procedure will select one target for each priority, allowing 
     101 * application to fail-over to the next target when the previous target fails. 
     102 * These targets are returned in the #pjsip_server_addresses structure  
     103 * argument of the callback.  
     104 * 
     105 * \subsection PJSIP_SIP_RESOLVE_SIP_FEATURES SIP SRV Resolver Features 
     106 * 
     107 * Some features of the SIP resolver: 
     108 *  - DNS SRV entries are returned on sorted order based on priority  
     109 *    to allow failover to the next appropriate server. 
     110 *  - The procedure in RFC 2782 is used to select server with the same 
     111 *    priority to load-balance the servers load. 
     112 *  - A single function (#pjsip_resolve()) performs all server resolution 
     113 *    works, from resolving the SRV records to getting the actual IP addresses 
     114 *    of the servers with DNS A (or AAAA) resolution. 
     115 *  - When multiple DNS SRV records are returned, parallel DNS A (or AAAA) 
     116 *    queries will be issued simultaneously. 
     117 *  - The PJLIB-UTIL DNS resolver provides additional functionality such as 
     118 *    response caching, query aggregation, parallel nameservers, fallback 
     119 *    nameserver, etc., which will be described below. 
     120 *  
     121 * 
     122 * \subsection PJSIP_RESOLVE_DNS_FEATURES DNS Resolver Features 
     123 * 
     124 * The PJSIP server resolution framework uses PJLIB-UTIL DNS resolver engine 
     125 * for performing the asynchronous DNS request. The PJLIB-UTIL DNS resolver 
     126 * has some useful features, such as: 
     127 *  - queries are asynchronous with configurable timeout, 
     128 *  - query aggregation to combine multiple pending queries to the same 
     129 *    DNS target into a single DNS request (to save message round-trip and 
     130 *    processing), 
     131 *  - response caching with TTL negotiated between the minimum TTL found in 
     132 *    the response and the maximum TTL allowed in the configuration, 
     133 *  - multiple nameservers, with active nameserver is selected from nameserver 
     134 *    which provides the best response time, 
     135 *  - fallback nameserver, with periodic detection of which name servers are 
     136 *    active or down. 
     137 *  - etc. 
     138 * 
     139 * Please consult PJLIB-UTIL DNS resolver documentation for more details. 
     140 * 
     141 * 
     142 * \section PJSIP_RESOLVE_USING Using the Resolver 
     143 * 
     144 * To maintain backward compatibility, the resolver MUST be enabled manually. 
     145 * With the default settings, the resolver WILL NOT perform DNS SRV resolution, 
     146 * as it will just resolve the name with standard pj_gethostbyname() function. 
     147 * 
     148 * Application can enable the SRV resolver by creating the PJLIB-UTIL DNS  
     149 * resolver with #pjsip_endpt_create_resolver(), configure the 
     150 * nameservers of the PJLIB-UTIL DNS resolver object by calling 
     151 * pj_dns_resolver_set_ns() function, and pass the DNS resolver object to  
     152 * #pjsip_resolver_set_resolver() function. 
     153 * 
     154 * Once the resolver is set, it will be used automatically by PJSIP everytime 
     155 * PJSIP needs to send SIP request/response messages. 
     156 * 
     157 * 
     158 * \section PJSIP_RESOLVE_REFERENCE Reference 
     159 * 
     160 * Reference: 
     161 *  - RFC 2782: A DNS RR for specifying the location of services (DNS SRV) 
     162 *  - RFC 3263: Locating SIP Servers 
     163 */ 
    49164 
    50165/** 
     
    62177        pjsip_transport_type_e  type; 
    63178 
     179        /** Server priority (the lower the higher the priority). */ 
     180        unsigned                priority; 
     181 
     182        /** Server weight (the higher the more load it can handle). */ 
     183        unsigned                weight; 
     184 
    64185        /** The server's address. */ 
    65186        pj_sockaddr             addr; 
     
    86207 
    87208/** 
    88  * Create resolver engine. 
    89  * 
    90  * @param pool  The Pool. 
    91  * @return      The resolver engine. 
    92  */ 
    93 PJ_DECL(pjsip_resolver_t*) pjsip_resolver_create(pj_pool_t *pool); 
    94  
    95 /** 
    96  * Destroy resolver engine. 
     209 * Create SIP resolver engine. Note that this function is normally called 
     210 * internally by pjsip_endpoint instance. 
     211 * 
     212 * @param pf        The Pool Factory. 
     213 * @param p_res     Pointer to receive SIP resolver instance. 
     214 * 
     215 * @return          PJ_SUCCESS when resolver can be successfully created. 
     216 */ 
     217PJ_DECL(pj_status_t) pjsip_resolver_create(pj_pool_t *pool, 
     218                                           pjsip_resolver_t **p_res); 
     219 
     220/** 
     221 * Set the DNS resolver instance of the SIP resolver engine. Before the 
     222 * DNS resolver is set, the SIP resolver will use standard pj_gethostbyname() 
     223 * to resolve addresses. 
     224 * 
     225 * Note that application normally will use #pjsip_endpt_set_resolver() instead 
     226 * since it does not normally have access to the SIP resolver instance. 
     227 * 
     228 * @param res       The SIP resolver engine. 
     229 * @param dns_res   The DNS resolver instance to be used by the SIP resolver. 
     230 *                  This argument can be NULL to reset the internal DNS 
     231 *                  instance. 
     232 * 
     233 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     234 */ 
     235PJ_DECL(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res, 
     236                                                 pj_dns_resolver *dns_res); 
     237 
     238 
     239/** 
     240 * Get the DNS resolver instance of the SIP resolver engine.  
     241 * 
     242 * Note that application normally will use #pjsip_endpt_get_resolver() instead 
     243 * since it does not normally have access to the SIP resolver instance. 
     244 * 
     245 * @param res       The SIP resolver engine. 
     246 * 
     247 * @return          The DNS resolver instance (may be NULL) 
     248 */ 
     249PJ_DECL(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res); 
     250 
     251/** 
     252 * Destroy resolver engine. Note that this will also destroy the internal 
     253 * DNS resolver inside the engine. If application doesn't want the internal 
     254 * DNS resolver to be destroyed, it should set the internal DNS resolver 
     255 * to NULL before calling this function. 
     256 * 
     257 * Note that this function will normally called by the SIP endpoint instance 
     258 * when the SIP endpoint instance is destroyed. 
    97259 * 
    98260 * @param resolver The resolver. 
     
    105267 * has completed, the callback will be called. 
    106268 * 
    107  * Note: at the moment we don't have implementation of RFC 3263 yet! 
     269 * Note that application normally will use #pjsip_endpt_resolve() instead 
     270 * since it does not normally have access to the SIP resolver instance. 
    108271 * 
    109272 * @param resolver      The resolver engine. 
     
    115278PJ_DECL(void) pjsip_resolve( pjsip_resolver_t *resolver, 
    116279                             pj_pool_t *pool, 
    117                              pjsip_host_info *target, 
     280                             const pjsip_host_info *target, 
    118281                             void *token, 
    119282                             pjsip_resolver_callback *cb); 
Note: See TracChangeset for help on using the changeset viewer.