Module: sip-router Branch: master Commit: 63ef5f0edcfebe86cffe7489f3524186ed3400d4 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=63ef5f0e...
Author: Mihály Mészáros misi@niif.hu Committer: Mihály Mészáros misi@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 73715e3..251d680 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);
CC (gcc) [kamailio] dns_cache.o dns_cache.c: In function âdns_naptr_sip_resolvehostâ: dns_cache.c:2893: warning: implicit declaration of function âno_naptr_srv_sip_resolvehostâ dns_cache.c:2893: warning: return makes pointer from integer without a cast
gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)
On Thu, Dec 20, 2012 at 7:43 AM, Mihaly Meszaros misi@niif.hu wrote:
Module: sip-router Branch: master Commit: 63ef5f0edcfebe86cffe7489f3524186ed3400d4 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=63ef5f0e...
Author: Mihály Mészáros misi@niif.hu Committer: Mihály Mészáros misi@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 73715e3..251d680 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);