Module: sip-router Branch: master Commit: 9ac9b5c35858efd7c71163c604d18a1fa35e3a02 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9ac9b5c3...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Fri Jul 12 18:09:09 2013 +0200
ipops: added dsn_int_match_ip(hostname, ipaddr)
- function that uses the internal resolver to match a hostname with an ip (similar operation like 'scr_ip=="hostname"') - rename dns_nc_match_ip() to dns_sys_match_ip() to be more suggestive about what kind of resolver is used
---
modules/ipops/README | 51 +++++++++++++++++++++++------ modules/ipops/doc/ipops_admin.xml | 64 +++++++++++++++++++++++++++++++++--- modules/ipops/ipops_mod.c | 60 ++++++++++++++++++++++++++++++++-- 3 files changed, 155 insertions(+), 20 deletions(-)
diff --git a/modules/ipops/README b/modules/ipops/README index 901535a..cd6118e 100644 --- a/modules/ipops/README +++ b/modules/ipops/README @@ -36,7 +36,8 @@ I 4.8. compare_pure_ips (ip1, ip2) 4.9. is_ip_rfc1918 (ip) 4.10. is_in_subnet (ip, subnet) - 4.11. dns_nc_match_ip(hostname, ipaddr) + 4.11. dns_sys_match_ip(hostname, ipaddr) + 4.12. dns_int_match_ip(hostname, ipaddr)
List of Examples
@@ -50,7 +51,8 @@ I 1.8. compare_pure_ips usage 1.9. is_ip_rfc1918 usage 1.10. is_in_subnet usage - 1.11. dns_nc_match_ip usage + 1.11. dns_sys_match_ip usage + 1.12. dns_int_match_ip usage
Chapter 1. Admin Guide
@@ -75,7 +77,8 @@ Chapter 1. Admin Guide 4.8. compare_pure_ips (ip1, ip2) 4.9. is_ip_rfc1918 (ip) 4.10. is_in_subnet (ip, subnet) - 4.11. dns_nc_match_ip(hostname, ipaddr) + 4.11. dns_sys_match_ip(hostname, ipaddr) + 4.12. dns_int_match_ip(hostname, ipaddr)
1. Overview
@@ -127,7 +130,8 @@ Chapter 1. Admin Guide 4.8. compare_pure_ips (ip1, ip2) 4.9. is_ip_rfc1918 (ip) 4.10. is_in_subnet (ip, subnet) - 4.11. dns_nc_match_ip(hostname, ipaddr) + 4.11. dns_sys_match_ip(hostname, ipaddr) + 4.12. dns_int_match_ip(hostname, ipaddr)
4.1. is_ip (ip)
@@ -334,22 +338,49 @@ if (is_in_subnet("10.0.123.123", "10.0.123.1/24")) { } ...
-4.11. dns_nc_match_ip(hostname, ipaddr) +4.11. dns_sys_match_ip(hostname, ipaddr)
Returns TRUE if ipaddr is associated by DNS to hostname. FALSE - otherwise. It does not use the internal DNS cache, but directly - getaddrinfo(...). + otherwise. It does not use the internal DNS resolver, but directly + getaddrinfo(...). All addresses returned for the hostname are checked. + Note that some hosts may return different lists of IP addresses for + each query, if the DNS server is configured in that way (e.g., for + providing load balancing through DNS).
Parameters: * ipaddr - string or pseudo-variable containing the ip address. * hostname - string or pseudo-variable containing the hostname. The - resulting IP addresses from DNS query are compared with ipaddress. + resulting IP addresses from DNS query are compared with ipaddr.
This function can be used from ANY_ROUTE.
- Example 1.11. dns_nc_match_ip usage + Example 1.11. dns_sys_match_ip usage ... -if (!dns_nc_match_ip("myhost.com", "1.2.3.4")) { +if (!dns_sys_match_ip("myhost.com", "1.2.3.4")) { + xdbg("ip address not associated with hostname\n"); +} +... + +4.12. dns_int_match_ip(hostname, ipaddr) + + Returns TRUE if ipaddr is associated by DNS to hostname. FALSE + otherwise. It uses internal DNS resolver. At this moment, the function + might not check all the IP addresses as returned by dns_sys_match_ip(), + because the internal resolver targets to discover the first address to + be used for relaying SIP traffic. Thus is better to use + dns_sys_match_ip() if the host you want to check has many IP addresses, + in different address famililies (IPv4/6). + + Parameters: + * ipaddr - string or pseudo-variable containing the ip address. + * hostname - string or pseudo-variable containing the hostname. The + resulting IP addresses from DNS query are compared with ipaddr. + + This function can be used from ANY_ROUTE. + + Example 1.12. dns_int_match_ip usage +... +if (!dns_int_match_ip("myhost.com", "1.2.3.4")) { xdbg("ip address not associated with hostname\n"); } ... diff --git a/modules/ipops/doc/ipops_admin.xml b/modules/ipops/doc/ipops_admin.xml index afb03d8..9f3528d 100644 --- a/modules/ipops/doc/ipops_admin.xml +++ b/modules/ipops/doc/ipops_admin.xml @@ -529,14 +529,17 @@ if (is_in_subnet("10.0.123.123", "10.0.123.1/24")) {
</section>
- <section id="ipops.f.dns_nc_match_ip"> + <section id="ipops.f.dns_sys_match_ip"> <title> - <function moreinfo="none">dns_nc_match_ip(hostname, ipaddr)</function> + <function moreinfo="none">dns_sys_match_ip(hostname, ipaddr)</function> </title>
<para> Returns TRUE if ipaddr is associated by DNS to hostname. FALSE otherwise. It - does not use the internal DNS cache, but directly getaddrinfo(...). + does not use the internal DNS resolver, but directly getaddrinfo(...). All + addresses returned for the hostname are checked. Note that some hosts may + return different lists of IP addresses for each query, if the DNS server + is configured in that way (e.g., for providing load balancing through DNS). </para>
<para>Parameters:</para> @@ -550,7 +553,7 @@ if (is_in_subnet("10.0.123.123", "10.0.123.1/24")) { <listitem> <para> <emphasis>hostname</emphasis> - string or pseudo-variable containing the hostname. - The resulting IP addresses from DNS query are compared with ipaddress. + The resulting IP addresses from DNS query are compared with ipaddr. </para> </listitem> </itemizedlist> @@ -561,11 +564,60 @@ if (is_in_subnet("10.0.123.123", "10.0.123.1/24")) {
<example> <title> - <function>dns_nc_match_ip</function> usage + <function>dns_sys_match_ip</function> usage </title> <programlisting format="linespecific"> ... -if (!dns_nc_match_ip("myhost.com", "1.2.3.4")) { +if (!dns_sys_match_ip("myhost.com", "1.2.3.4")) { + xdbg("ip address not associated with hostname\n"); +} +... + </programlisting> + </example> + + </section> + + <section id="ipops.f.dns_int_match_ip"> + <title> + <function moreinfo="none">dns_int_match_ip(hostname, ipaddr)</function> + </title> + + <para> + Returns TRUE if ipaddr is associated by DNS to hostname. FALSE otherwise. It + uses internal DNS resolver. At this moment, the function might not check all + the IP addresses as returned by dns_sys_match_ip(), because the internal + resolver targets to discover the first address to be used for relaying + SIP traffic. Thus is better to use dns_sys_match_ip() if the host you want + to check has many IP addresses, in different address famililies (IPv4/6). + </para> + + <para>Parameters:</para> + + <itemizedlist> + <listitem> + <para> + <emphasis>ipaddr</emphasis> - string or pseudo-variable containing the ip address. + </para> + </listitem> + <listitem> + <para> + <emphasis>hostname</emphasis> - string or pseudo-variable containing the hostname. + The resulting IP addresses from DNS query are compared with ipaddr. + </para> + </listitem> + </itemizedlist> + + <para> + This function can be used from ANY_ROUTE. + </para> + + <example> + <title> + <function>dns_int_match_ip</function> usage + </title> + <programlisting format="linespecific"> +... +if (!dns_int_match_ip("myhost.com", "1.2.3.4")) { xdbg("ip address not associated with hostname\n"); } ... diff --git a/modules/ipops/ipops_mod.c b/modules/ipops/ipops_mod.c index d21546c..dc58fc8 100644 --- a/modules/ipops/ipops_mod.c +++ b/modules/ipops/ipops_mod.c @@ -87,7 +87,8 @@ static int w_compare_ips(struct sip_msg*, char*, char*); static int w_compare_pure_ips(struct sip_msg*, char*, char*); static int w_is_ip_rfc1918(struct sip_msg*, char*); static int w_ip_is_in_subnet(struct sip_msg*, char*, char*); -static int w_dns_nc_match_ip(sip_msg_t*, char*, char*); +static int w_dns_sys_match_ip(sip_msg_t*, char*, char*); +static int w_dns_int_match_ip(sip_msg_t*, char*, char*);
/* @@ -115,7 +116,9 @@ static cmd_export_t cmds[] = REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE }, { "is_in_subnet", (cmd_function)w_ip_is_in_subnet, 2, fixup_spve_spve, 0, REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE }, - { "dns_nc_match_ip", (cmd_function)w_dns_nc_match_ip, 2, fixup_spve_spve, 0, + { "dns_sys_match_ip", (cmd_function)w_dns_sys_match_ip, 2, fixup_spve_spve, 0, + ANY_ROUTE }, + { "dns_int_match_ip", (cmd_function)w_dns_int_match_ip, 2, fixup_spve_spve, 0, ANY_ROUTE }, { "bind_ipops", (cmd_function)bind_ipops, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0 } @@ -617,7 +620,7 @@ static inline ip_addr_t *strtoipX(str *ips) } }
-static int w_dns_nc_match_ip(sip_msg_t *msg, char *hnp, char *ipp) +static int w_dns_sys_match_ip(sip_msg_t *msg, char *hnp, char *ipp) { struct addrinfo hints, *res, *p; int status; @@ -653,7 +656,7 @@ static int w_dns_nc_match_ip(sip_msg_t *msg, char *hnp, char *ipp) if ((status = getaddrinfo(hns.s, NULL, &hints, &res)) != 0) { LM_ERR("getaddrinfo: %s\n", gai_strerror(status)); - return -2; + return -4; }
for(p = res;p != NULL; p = p->ai_next) @@ -680,3 +683,52 @@ static int w_dns_nc_match_ip(sip_msg_t *msg, char *hnp, char *ipp)
return -1; } + +static int w_dns_int_match_ip(sip_msg_t *msg, char *hnp, char *ipp) +{ + ip_addr_t *ipa; + str hns; + str ips; + struct hostent* he; + char ** h; + int ret; + + if (fixup_get_svalue(msg, (gparam_p)hnp, &hns)) + { + LM_ERR("cannot evaluate hostname parameter\n"); + return -2; + } + + if (fixup_get_svalue(msg, (gparam_p)ipp, &ips)) + { + LM_ERR("cannot evaluate ip address parameter\n"); + return -2; + } + + ipa = strtoipX(&ips); + if(ipa==NULL) + { + LM_ERR("invalid ip address: %.*s\n", ips.len, ips.s); + return -3; + } + + he=resolvehost(hns.s); + if (he==0) { + DBG("could not resolve %s\n", hns.s); + return -4; + } + ret = 0; + if (he->h_addrtype==ipa->af) + { + for(h=he->h_addr_list; (*h); h++) + { + if(memcmp(ipa->u.addr, *h, ipa->len)==0) + { + /* match */ + return 1; + } + } + } + /* no match */ + return -1; +}