pdnsd maintenance version 1.1.11-par by Paul Rombouts ======================================================= This file describes the version of pdnsd that I maintain personally and am making available so other people can enjoy the latest features and fixes. Thomas Moestl no longer maintains pdnsd himself, so I am effectively the new maintainer. The current version is 1.1.11-par, which has a rather large number of small changes. Among the bugs fixed are a race condition in the cache lookup code, a flaw in the code that caused a busy spin when a remote server answered with "Not Implemented", and problems with the -4 and -6 command-line options. Among the improvements are an alternative sorting algorithm which should allow pdnsd to start up faster when reading a large cache file from disk, automatic mapping of IPv4 to IPv6 addresses when running in IPv6 mode, somewhat more efficient memory use, and better compression of the replies. Some of the new features are described in the second half of this file (look for "new in version 1.1.11"). For the rest of the changes I will have to refer you to the ChangeLog. For a short history about recent releases have a look at doc/html/index.html. Since version 1.1.9 I've added some missing pieces to the documentation (the manual doc/html/doc.html,doc/txt/manual.txt and the man page doc/pdnsd-ctl.8). Version 1.1.11 finally has a man page doc/pdnsd.8, thanks to a contribution by Mahesh T. Pai. The first part of this file describes how to patch, compile, install and run pdnsd. The second part describes some of the changes I've made to Thomas Moestl's code. Unless you're using the pre-patched source archive pdnsd-1.1.11-par.tar.gz you must first apply my patch file pdnsd-1.1.11-par.diff.gz before compiling and installing pdnsd according to Thomas Moestl's instructions described in the the documentation. Use a freshly untarred copy of Thomas Moestl's original version 1.1.7a source, cd into the source directory pdnsd-1.1.7a and apply the command: gzip -cd /pdnsd-1.1.11-par.diff.gz | patch -p2 -N -Z Note: I have used GNU extensions so there may be some portability issues. I have supplied alternatives for some of the less portable functions. There should be no problem with most Linux distributions. That's it! You should now be able to compile, install and run pdnsd. See the documentation in doc/html/doc.html or doc/txt/manual.txt for more detailed instructions. Some people may want change the compiler optimization flag. I use the -O2 flag, but it might be safer to use a lower level of optimization or no optimization at all. In that case prefix the configure command with the desired compiler flags like this (assuming you're using a bash shell): CFLAGS="-O1 -g -Wall" ./configure ... I have added a new configuration option "--with-thread-lib=", which you should use if you experience problems with signal handling under Linux. The usual symptom is failure by pdnsd to save the cache to disk, and /var/cache/pdnsd/pdnsd.cache remaining empty. If you experience this kind of trouble, try reconfiguring with different values for the --with-thread-lib option. The allowable values are "linuxthreads" (the default), "linuxthreads2" (or "lt2" for short), and "nptl". I recommend that you first configure and compile without the --with-thread-lib option, then if you experience trouble try again with --with-thread-lib=lt2 and recompile. If your Linux system has an implementation of the Native POSIX Thread Library, which is the case with Red Hat 9 for instance, you should use --with-thread-lib=nptl . Ideally, I would like to write a configure script which automatically detects which kind of thread library is being used on a Linux system, but I don't have a clue yet how to do this. If you can help me with this please write to me at the email address listed at the end of this file. The rest of this file describes some of the modifications I've made, but you don't have to read it if you simply want to run pdnsd as you're used to. - The main new feature I've added enables you to change the server addresses that pdnsd uses at run-time using pdnsd-ctl. I've done this because the ISPs I use do not specify fixed DNS server addresses, but expect their clients to use dynamic DNS configuration (DHCP in the case of the cable connection, RFC1877 in case of isdn). I've extended the options that can be given with the "server" command to pdnsd-ctl, to allow IP addresses to be specified as an additional argument after "up|down|retest". This allows me to put something like this in my ifup-local script: pdnsd-ctl server isp-label up "$DNS1 $DNS2" For more details how to use pdnsd-ctl read the updated documentation in the doc/html directory. There is also a manpage for pdnsd-ctl. This was quite tricky to implement because there might be pending queries while the addresses are being changed. It certainly was an interesting exercise in writing multi-threaded code for me. - I've implemented a feature which allowed me to specify multiple IP addresses per server section in the configuration file. This allowed for a much more compact configuration file (3 server sections instead of 7 in my case), because most configuration options are identical for servers belonging to the same ISP. It also made the output of "pdnsd-ctl status" more compact. And it was necessary to enable a satisfactory implementation of the previous feature. Example of the new syntax: ip = 123.456.789.001, 123.456.789.002, 123.456.789.003; At the suggestion of Greg Norris server sections no longer have to specify IP addresses. A server section without IP addresses will remain inactive until it is assigned one more addresses at run-time with pdnsd-ctl. - I've changed the implementation of dynamic arrays to make it slightly more efficient, and improve type safety. I also got rid of several arrays of fixed size in favor of dynamically allocated arrays. In particular, I got rid of all occurrences of MAXPATH. I also made several static variables "automatic". - The output of the "status" command of pdnsd-ctl now gives more meaningful constant names "ping|none|if|exec" instead of numbers for the "uptest" option. I've also added some information that was previously missing. - I've fixed I a problem that caused pdnsd to use up a lot of CPU time and slow down my system considerably when it received a query that took a long time to resolve. It turned out that pdnsd can get into a "busy spin" when one of the DNS servers pdnsd is querying refuses the connection. Apart from fixing this bug, to speed things up additionally, I thought it would be a good idea to mark a server down (without retesting it) after detecting errno==ECONNREFUSED. This gives me very satisfactory performance, with the problematic server being tried only once during every testing interval. New in version 1.1.11: An additional busy spin condition, triggered when a remote server answers with "Not Implemented", has been discovered and fixed. In case there are remaining bugs in the multiplexing code, I've added a test that checks if the number of events reported by poll/select matches the number of events handled by pdnsd. If not, pdnsd will log an error message and give up. Although the bugs still need to be reported and fixed, at least this should prevent pdnsd from wasting CPU cycles. - Due to a bug in Thomas' code, pdnsd tries, but fails, to remove the control socket "pdnsd.status" before exiting. This has also been fixed. In version 1.1.8b1-par6 I have cleaned this up some more so that pdnsd will handle situations where it can't open or bind the control socket more gracefully. - I've rewritten some of the code that saves the contents of the cache to the file "pdnsd.cache" just before pdnsd exits. This is because I noticed in my logfiles that pdnsd occasionally had problems reading this file back at startup. I eliminated the use of fseek() in Thomas' code. I could not find anything that was demonstrably incorrect about his use of fseek(), but it seemed better to me to do without it and write the file in a strictly sequential order. Anyway, it turned out my hunch paid off: no more error messages about "pdnsd.cache" in my logfile. New in version 1.1.11: I've added some new code for sorting the queue used for purging stale cache entries. This should allow pdnsd to start up faster when reading large cache files from disk. - I've extended the configuration options for policies of inclusion/exclusion lists in server sections. The new policies options are "simple_only" and "fqdn_only". Setting policy=simple_only will cause the server to used only for simple hostnames if no other rule matches. On the other hand, setting policy=fqdn_only will cause the server to be used only for fully qualified domain names (i.e. the name has at least one dot in-between). I find these options useful for controlling which name servers (if any) will be used by pdnsd for simple host names. - I've added a new "delegation_only" option that can be used to undo the unwanted effects of DNS "wildcards". It works roughly as the feature by the same name in BIND. It is turned off by default. To block Verisign's Sitefinder, add the following line to the global section of the configuration file: delegation_only= com, net; If you find that this feature blocks some legitimate domain names, you will probably need to add the address of a nameserver that provides good authority information. More information can be found at http://www.phys.uu.nl/~rombouts/pdnsd/delegationonly.html - It is no longer mandatory that domain names in the configuration file end in a dot. - The parser for configuration files has been rewritten purely in C, so (f)lex and yacc/bison are no longer needed to build pdnsd. It is no longer necessary to place strings between quotes in the configuration file, unless a string contains a special character such as whitespace, a token that normally starts a comment, or one of the characters ",;{}". Note that these special characters are illegal in domain names anyway. - New in version 1.1.11: Negating whole domains with a neg section in the config file will result in all the subdomains being negated as well. For example, adding the lines neg {name=doubleclick.com; types=domain;} neg {name=doubleclick.net; types=domain;} will also negate ad.doubleclick.com, ad.fr.doubleclick.net, etc. - New in version 1.1.11: When running in IPv6 mode, pdnsd will now automatically map any IPv4 addresses it reads in the config file to IPv6 addresses. When pdnsd has been compiled with IPv6 support and runs in IPv4 mode, it will skip IPv6 addresses with a warning message. This may result in certain server sections becoming inactive, though. The -4 and -6 options should now work as advertised. I've added two new command-line options, "-a" and "-i ". With the -a flag pdnsd will try to detect automatically if IPv6 support is available on a system, and fall back to IPv4 if not. The -a flag can be used instead of -4 or -6. The -i option can be used to specify a prefix for mapping IPv4 to IPv6 address. The default is ::ffff.0.0.0.0. There is also a corresponding ipv4_6_prefix= option for the config file. - New in version 1.1.11: I've slightly changed the way pdnsd does parallel queries. Active queries or not canceled until we have received a useful response from a remote name server, or all the queries have failed or timed out. Thus the par_queries parameter is no longer the maximum number of parallel queries, but rather the increment with which the number of parallel queries is increased when the previous set has timed out. In the worst case there will be pending queries to all the servers in the list of available servers simultaneously. We may be wasting more system resources this way, but the advantage is that we have a greater chance of catching a reply. After all, if we wait longer anyway, why not for more servers. I've also introduced a global timeout parameter. This is the minimum period of time pdnsd will wait after sending the first query to a remote server before giving up without having received a reply. The timeout options in the configuration file are now only minimum timeout intervals. Setting the global timeout option makes it possible to specify quite short timeout intervals in the server sections. This will have the effect that pdnsd will start querying additional servers fairly quickly if the first servers are slow to respond (but will still continue to listen for responses from the first ones). This may allow pdnsd to get an answer more quickly in certain situations. After receiving a reply from a remote server the server is marked up and its time stamp is updated. This will have the effect that pdnsd doesn't bother testing this server for availability for a period of time, and thus the overhead caused by testing is reduced. After server timeouts, uptests are performed by the separate server status thread, not by threads that have to answer queries. Unresponsive servers with uptest=ping will not be marked down immediately any more, but only after the ping test has definitely failed. I've also included a number of bug-fixes contained in a patch file supplied to me by Thomas Moestl. In addition to the things I had already fixed, the following issues are addressed: some memory leaks, dropping of root privileges before calling uptest scripts in case pdnsd was started setuid root (which is a bad idea anyway), passing on open fd's to uptests, integer overruns in the status reporting code, fixing string passing from the lexer, more consistent treatment of underscores in domain names. In addition to the things I've listed above, I've made various little changes to fix minor bugs, improve efficiency or elegance, or simply to suit my my own coding style. These changes are too numerous to list here, but some of them are listed in the ChangeLog. Of course if you are really interested in the nitty-gritty you can always compare the source of my version with Thomas' original code. If you have any questions about the modifications I've made, you can send these to . Questions about the original pdnsd version should be sent to or .