[sr-dev] git:misi/dns_srv: core/dns: dns SRV lookup, if no NAPTR available

Mihaly Meszaros misi at niif.hu
Mon Nov 12 16:21:36 CET 2012


Module: sip-router
Branch: misi/dns_srv
Commit: fd1a5bf99af922eccf33756f6421f00998ccaed9
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fd1a5bf99af922eccf33756f6421f00998ccaed9

Author: Mihály Mészáros <misi at niif.hu>
Committer: Mihály Mészáros <misi at niif.hu>
Date:   Mon Nov 12 16:02:48 2012 +0100

core/dns: dns SRV lookup, if no NAPTR available

- Resolving the first most preferred and available SRV record if no NAPTR found.
  It reuse the dns protocol preference scores. Sort protocols based on this preference.

---

 dns_cache.c |    2 +-
 resolve.c   |  138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 137 insertions(+), 3 deletions(-)

diff --git a/dns_cache.c b/dns_cache.c
index 1a7f1c5..1f4ae82 100644
--- a/dns_cache.c
+++ b/dns_cache.c
@@ -2890,7 +2890,7 @@ struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port,
 		dns_hash_put(e);
 	}
 naptr_not_found:
-	return dns_srv_sip_resolvehost(name, port, proto);
+	return no_naptr_srv_sip_resolvehost(name,port,proto);
 }
 #endif /* USE_NAPTR */
 
diff --git a/resolve.c b/resolve.c
index faabb96..9b094ec 100644
--- a/resolve.c
+++ b/resolve.c
@@ -1448,8 +1448,142 @@ end:
 	return 0;
 }
 
+/* Resolves SRV if no naptr found. 
+ * It reuse dns_pref values and according that resolves supported protocols. 
+ * If dns_pref are equal then it use udp,tcp,tls,sctp order.
+ * returns: hostent struct & *port filled with the port from the SRV record;
+ *  0 on error
+ */
+
+struct hostent* no_naptr_srv_sip_resolvehost(str* name, unsigned short* port, char* proto)
+{
+	struct dns_srv_proto_t {
+		char proto;
+		int proto_pref;
+	} srv_proto_list[PROTO_LAST], tmp_srv_element;
+	struct hostent* he;
+	str srv_name;
+	static char tmp_srv[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
+	int len;
+	unsigned char i,j,max,default_order=0,list_len=0;
+	/* init variables */
+	he=0;
+	len=0;
+
+	if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
+		LOG(L_WARN, "WARNING: no_naptr_srv_sip_resolvehost: domain name too long"
+						" (%d), unable to perform SRV lookup\n", name->len);
+	} else {
+		/* if proto available, then add only the forced protocol to the list */
+		if (proto && *proto==0){
+			srv_proto_list[0].proto=*proto;
+			list_len=1;
+		} else {
+	
+			/*get protocols and preference scores, and add availble protocol(s) and score(s) to the list*/
+			for (i=PROTO_UDP; i<PROTO_LAST;i++) {
+				tmp_srv_element.proto_pref = proto_pref_score(i);
+				/* if -1 so disabled continue with next protocol*/
+				if (naptr_proto_supported(i) == 0 ) {
+					continue;
+				} else {
+					srv_proto_list[i-1].proto_pref=tmp_srv_element.proto_pref;
+					srv_proto_list[i-1].proto=i;
+					list_len++;
+				}
+			};
+
+			/* if all protocol prefence scores equal, then set the perference to default values: udp,tcp,tls,sctp */
+			for (i=1; i<list_len;i++) {
+				if(srv_proto_list[0].proto_pref!=srv_proto_list[i].proto_pref){
+					default_order=0;
+				}
+			}
+			if (default_order){
+				for (i=0; i<list_len;i++) {
+					switch ( srv_proto_list[i].proto) {
+						case PROTO_UDP:
+							srv_proto_list[i].proto_pref=4;
+							break;
+						case PROTO_TCP:
+							srv_proto_list[i].proto_pref=3;
+							break;
+						case PROTO_TLS:
+							srv_proto_list[i].proto_pref=2;
+							break;
+						case PROTO_SCTP:
+							srv_proto_list[i].proto_pref=1;
+							break;
+					}
+				}
+			}
+
+			/* sorting the list */
+			for (i=0;i<list_len-1;i++) {
+				max=i;
+				for (j=i+1;j<list_len;j++) {
+					if (srv_proto_list[j].proto_pref>srv_proto_list[max].proto_pref) { 
+						max=j; 
+					}
+				}
+				if (i!=max) {
+					tmp_srv_element=srv_proto_list[i];
+					srv_proto_list[i]=srv_proto_list[max];
+					srv_proto_list[max]=tmp_srv_element;
+				}
+			}
 
+		}
+		/* looping on the ordered list until we found a protocol what has srv record */
+		for (i=0; i<list_len;i++) {	
+			switch (srv_proto_list[i].proto) {
+				case PROTO_NONE: /* no proto specified, use udp */
+					if (proto)
+						*proto=PROTO_UDP;
+					/* no break */
+				case PROTO_UDP:
+					memcpy(tmp_srv, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
+					memcpy(tmp_srv+SRV_UDP_PREFIX_LEN, name->s, name->len);
+					tmp_srv[SRV_UDP_PREFIX_LEN + name->len] = '\0';
+					len=SRV_UDP_PREFIX_LEN + name->len;
+					break;
+				case PROTO_TCP:
+					memcpy(tmp_srv, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
+					memcpy(tmp_srv+SRV_TCP_PREFIX_LEN, name->s, name->len);
+					tmp_srv[SRV_TCP_PREFIX_LEN + name->len] = '\0';
+					len=SRV_TCP_PREFIX_LEN + name->len;
+					break;
+				case PROTO_TLS:
+					memcpy(tmp_srv, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
+					memcpy(tmp_srv+SRV_TLS_PREFIX_LEN, name->s, name->len);
+					tmp_srv[SRV_TLS_PREFIX_LEN + name->len] = '\0';
+					len=SRV_TLS_PREFIX_LEN + name->len;
+					break;
+				case PROTO_SCTP:
+					memcpy(tmp_srv, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
+					memcpy(tmp_srv+SRV_SCTP_PREFIX_LEN, name->s, name->len);
+					tmp_srv[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
+					len=SRV_SCTP_PREFIX_LEN + name->len;
+					break;
+				default:
+					LOG(L_CRIT, "BUG: sip_resolvehost: unknown proto %d\n",
+							(int)srv_proto_list[i].proto);
+					return 0;
+			}
+			/* set default port */
+			if ((port)&&(*port==0)){
+				*port=(srv_proto_list[i].proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we don't find another */
+			}
+			srv_name.s=tmp_srv;
+			srv_name.len=len;
+			if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0) {
+				return he;
+			}
+		}
+	}
+	return 0;
 
+} 
 
 /* internal sip naptr resolver function: resolves a host name trying:
  * - NAPTR lookup if the address is not an ip and *proto==0 and *port==0.
@@ -1515,8 +1649,8 @@ struct hostent* naptr_sip_resolvehost(str* name,  unsigned short* port,
 				" trying SRV lookup...\n", name->len, name->s);
 #endif
 	}
-	/* fallback to normal srv lookup */
-	he=srv_sip_resolvehost(name, 0, port, proto, 0, 0);
+	/* fallback to srv lookup */
+	no_naptr_srv_sip_resolvehost(name,port,proto);
 end:
 	if (naptr_head)
 		free_rdata_list(naptr_head);




More information about the sr-dev mailing list