Module: sip-router
Branch: master
Commit: 9ac9b5c35858efd7c71163c604d18a1fa35e3a02
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9ac9b5c…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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;
+}