Simon Kelley schrieb:
> Dnsmasq 2.52 is now available for download from
>
[snip]
For those interrested, my regex patch rediffed against 2.52.
Now new and improved, with the powerful conditional compilation formula!
So don't forget to set HAVE_REGEX to you COPTS like:
make COPTS=-DHAVE_REGEX
or unkomment it in config.h
>
> Cheers,
>
> Simon.
>
Greetings
Jan
[snip]
--
"...by all means, do not use a hammer."
(from an IBM dokumentation, ca. 1920)
=== modified file 'Makefile'
--- old/Makefile 2010-01-23 19:48:37 +0000
+++ new/Makefile 2010-01-23 19:49:07 +0000
@@ -32,8 +32,9 @@
PO = po
MAN = man
-DNSMASQ_CFLAGS=`echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --cflags dbus-1`
-DNSMASQ_LIBS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1`
+DNSMASQ_CFLAGS=`echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --cflags dbus-1`
+DNSMASQ_LIBS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1`
+DNSMASQ_LIBS +=`echo $(COPTS) | ../bld/pkg-wrapper HAVE_REGEX $(PKG_CONFIG) --libs libpcre`
SUNOS_LIBS= `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket -lnsl -lposix4; fi`
OBJS = cache.o rfc1035.o util.o option.o forward.o network.o \
=== modified file 'src/config.h'
--- old/src/config.h 2010-01-23 19:48:37 +0000
+++ new/src/config.h 2010-01-23 19:49:07 +0000
@@ -147,6 +147,10 @@
define some methods to allow (re)configuration of the upstream DNS
servers via DBus.
+HAVE_REGEX
+ Define this if you want to link against lib pcre to get regex
+ support in "address=" matches
+
NOTES:
For Linux you should define
HAVE_LINUX_NETWORK
@@ -171,6 +175,7 @@
#define HAVE_SCRIPT
/* #define HAVE_BROKEN_RTC */
/* #define HAVE_DBUS */
+/* #define HAVE_REGEX */
/* Allow TFTP to be disabled with COPTS=-DNO_TFTP */
#ifdef NO_TFTP
=== modified file 'src/dnsmasq.c'
--- old/src/dnsmasq.c 2010-01-23 19:48:37 +0000
+++ new/src/dnsmasq.c 2010-01-23 19:49:08 +0000
@@ -37,6 +37,10 @@
"no-"
#endif
"DBus "
+#ifndef HAVE_REGEX
+"no-"
+#endif
+"regex "
#ifndef LOCALEDIR
"no-"
#endif
=== modified file 'src/dnsmasq.h'
--- old/src/dnsmasq.h 2010-01-23 19:48:37 +0000
+++ new/src/dnsmasq.h 2010-01-23 19:49:08 +0000
@@ -120,6 +120,10 @@
#include <priv.h>
#endif
+#ifdef HAVE_REGEX
+# include <pcre.h>
+#endif
+
/* daemon is function in the C library.... */
#define daemon dnsmasq_daemon
@@ -319,6 +323,7 @@
#define SERV_MARK 256 /* for mark-and-delete */
#define SERV_TYPE (SERV_HAS_DOMAIN | SERV_FOR_NODOTS)
#define SERV_COUNTED 512 /* workspace for log code */
+#define SERV_IS_REGEX 1024 /* server entry is a regex */
struct serverfd {
int fd;
@@ -337,6 +342,10 @@
char interface[IF_NAMESIZE+1];
struct serverfd *sfd;
char *domain; /* set if this server only handles a domain. */
+#ifdef HAVE_REGEX
+ pcre *regex;
+ pcre_extra *pextra;
+#endif
int flags, tcpfd;
unsigned int queries, failed_queries;
struct server *next;
=== modified file 'src/forward.c'
--- old/src/forward.c 2010-01-23 19:48:37 +0000
+++ new/src/forward.c 2010-01-23 19:49:08 +0000
@@ -149,12 +149,38 @@
}
else if (serv->flags & SERV_HAS_DOMAIN)
{
- unsigned int domainlen = strlen(serv->domain);
- char *matchstart = qdomain + namelen - domainlen;
- if (namelen >= domainlen &&
- hostname_isequal(matchstart, serv->domain) &&
- domainlen >= matchlen &&
- (domainlen == 0 || namelen == domainlen || *(serv->domain) == '.' || *(matchstart-1) == '.' ))
+ unsigned int domainlen = matchlen;
+ int serverhit = 0;
+
+#ifdef HAVE_REGEX
+ if (serv->flags & SERV_IS_REGEX)
+ {
+ int captcount = 0;
+ if (pcre_fullinfo(serv->regex, serv->pextra, PCRE_INFO_CAPTURECOUNT, &captcount) == 0)
+ {
+ /* C99 dyn-array, or alloca must be used */
+ int ovect[(captcount + 1) * 3];
+ if (pcre_exec(serv->regex, serv->pextra, qdomain, namelen, 0, 0, ovect, (captcount + 1) * 3) > 0)
+ {
+ domainlen = (unsigned int) (ovect[1] - ovect[0]);
+ if (domainlen >= matchlen)
+ serverhit = 1;
+ }
+ }
+ }
+ else
+#endif
+ {
+ domainlen = strlen(serv->domain);
+ char *matchstart = qdomain + namelen - domainlen;
+ if (namelen >= domainlen &&
+ hostname_isequal(matchstart, serv->domain) &&
+ domainlen >= matchlen &&
+ (domainlen == 0 || namelen == domainlen || *(serv->domain) == '.' || *(matchstart-1) == '.' ))
+ serverhit = 1;
+ }
+
+ if (serverhit)
{
unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
*type = SERV_HAS_DOMAIN;
=== modified file 'src/network.c'
--- old/src/network.c 2010-01-23 19:48:37 +0000
+++ new/src/network.c 2010-01-23 19:49:08 +0000
@@ -741,7 +741,7 @@
char *s1, *s2;
if (!(new->flags & SERV_HAS_DOMAIN))
s1 = _("unqualified"), s2 = _("names");
- else if (strlen(new->domain) == 0)
+ else if (new->domain && strlen(new->domain) == 0)
s1 = _("default"), s2 = "";
else
s1 = _("domain"), s2 = new->domain;
=== modified file 'src/option.c'
--- old/src/option.c 2010-01-23 19:48:37 +0000
+++ new/src/option.c 2010-01-23 19:49:08 +0000
@@ -1405,10 +1405,16 @@
arg++;
while ((end = split_chr(arg, '/')))
{
- char *domain = NULL;
+ char *domain = NULL, *regex = NULL;
+ char *real_end = arg + strlen(arg);
/* # matches everything and becomes a zero length domain string */
if (strcmp(arg, "#") == 0)
domain = "";
+ else if (*arg == ':' && *(real_end - 1) == ':')
+ {
+ *(real_end - 1) = '\0';
+ regex = arg + 1;
+ }
else if (strlen (arg) != 0 && !(domain = canonicalise_opt(arg)))
option = '?';
serv = opt_malloc(sizeof(struct server));
@@ -1416,7 +1422,28 @@
serv->next = newlist;
newlist = serv;
serv->domain = domain;
- serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
+ serv->flags = domain || regex ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
+ if (regex)
+ {
+#ifdef HAVE_REGEX
+ const char *error;
+ int erroff;
+ serv->regex = pcre_compile(regex, 0, &error, &erroff, NULL);
+
+ if (!serv->regex)
+ {
+ option = '?';
+ problem = (char *) error;
+ break;
+ }
+ serv->flags |= SERV_IS_REGEX;
+ serv->pextra = pcre_study(serv->regex, 0, &error);
+#else
+ option = '?';
+ problem = "Using a regex while server was configured without regex support!";
+ break;
+#endif
+ }
arg = end;
}
if (!newlist)