cgs1999 / jain-sip

Automatically exported from code.google.com/p/jain-sip
0 stars 0 forks source link

Resolving a domain with multiple A records only resolves ONE IP instead of all the IPs #16

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
using the locateHops(URI uri) method of 
org.mobicents.ext.javax.sip.dns.DefaultDNSServerLocator
Here is the DNS information i'm using in my test:
jag.com.               IN SOA  ns.jag.com.         hostmaster.jag.com. (
                                                2012082801
                                                10800
                                                3600
                                                604800
                                                86400 )

jag.com.               IN NS     ns.jag.com.

ns.jag.com.         IN A       142.120.93.49

server1.jag.com.              IN A       142.120.93.49
server1.jag.com.              IN A       127.0.0.1
server2.jag.com.              IN A       127.0.0.1

_sip._udp.jag.com. 86400 IN SRV 1 100 5060 server1.jag.com.
_sip._udp.jag.com. 86400 IN SRV 0 100 5070 server2.jag.com.
_sip._tcp.jag.com. 86400 IN SRV 0 100 5060 server1.jag.com.
_sip._tcp.jag.com. 86400 IN SRV 0 100 5070 server2.jag.com.

jag.com. IN NAPTR 100 10 "S" "SIP+D2U" "" _sip._udp.jag.com.
jag.com. IN NAPTR 101 10 "S" "SIP+D2T" "" _sip._tcp.jag.com.

When I resolve jag.com, jain-sip-ext gives me 2 different results which each 
contain two hops :

Uri: sip:jean@jag.com resulted in hops: [127.0.0.1:5070/udp, 127.0.0.1:5060/udp]
or
Uri: sip:jean@jag.com resulted in hops: [127.0.0.1:5070/udp, 
142.120.93.49:5060/udp]

As a comparison, I also tested with the "jain-sip-rfc3263-router" and I get the 
expected three hops :

Uri: sip:jean@jag.com resulted in hops: [127.0.0.1:5070/UDP, 
142.120.93.49:5060/UDP, 127.0.0.1:5060/UDP]

This difference/bug is that the code only resolves one A record:

String hostAddress= InetAddress.getByName(resolvedName).getHostAddress();

versus looping through all A/AAAA records(like in the jain-sip-rfc3263-router).

final Set<ARecord> aRecords = resolver.lookupARecords(hop.getHost());

for (ARecord aRecord : aRecords) {
  final String ipAddress = aRecord.getAddress().getHostAddress();
  final Hop resolvedHop = new HopImpl(ipAddress, hop.getPort(), hop.getTransport());
  if (resolvedHops.contains(resolvedHop) == false) {
    resolvedHops.add(resolvedHop);
  }
}

final Set<AAAARecord> aaaaRecords = resolver.lookupAAAARecords(hop.getHost());

for (AAAARecord aaaaRecord : aaaaRecords) {
                           }
  final String ipAddress = aaaaRecord.getAddress().getHostAddress();
  final Hop resolvedHop = new HopImpl(ipAddress, hop.getPort(), hop.getTransport());
  if (resolvedHops.contains(resolvedHop) == false) {
    resolvedHops.add(resolvedHop);
  }
}

For reference, here are the revelant sections in the rfcs 3263 and 2782:

RCF 3263 :
   If the TARGET was not a numeric IP address, and no port was present
   in the URI, the client performs an SRV query on the record returned
   from the NAPTR processing of Section 4.1, if such processing was
   performed. [...] Irregardless
   of how the SRV records were determined, the procedures of RFC 2782,
   as described in the section titled "Usage rules" are followed,
   augmented by the additional procedures of Section 4.3 of this
   document.

RFC 2782 :
Usage rules

   A SRV-cognizant client SHOULD use this procedure to locate a list of
   servers and connect to the preferred one:

        Do a lookup for QNAME=_service._protocol.target, QCLASS=IN,
        QTYPE=SRV.

        If the reply is NOERROR, ANCOUNT>0 and there is at least one
        SRV RR which specifies the requested Service and Protocol in
        the reply:

            If there is precisely one SRV RR, and its Target is "."
            (the root domain), abort.

            Else, for all such RR's, build a list of (Priority, Weight,
            Target) tuples

            Sort the list by priority (lowest number first)

            Create a new empty list

            For each distinct priority level
                While there are still elements left at this priority
                level

                    Select an element as specified above, in the
                    description of Weight in "The format of the SRV
                    RR" Section, and move it to the tail of the new
                    list

            For each element in the new list

                query the DNS for address records for the Target or
                use any such records found in the Additional Data
                section of the earlier SRV response.

                for each address record found, try to connect to the
               (protocol, address, service).

        else

            Do a lookup for QNAME=target, QCLASS=IN, QTYPE=A

            for each address record found, try to connect to the
           (protocol, address, service)

Original issue reported on code.google.com by Jonathan...@gmail.com on 10 Sep 2012 at 5:40

GoogleCodeExporter commented 9 years ago

Original comment by gvage...@gmail.com on 10 Sep 2012 at 8:56