GithubHelp home page GithubHelp logo

wahern / dns Goto Github PK

View Code? Open in Web Editor NEW
255.0 27.0 65.0 595 KB

dns.c: Single file non-blocking DNS C library without callbacks or external dependencies.

Home Page: http://25thandclement.com/~william/projects/dns.c.html

License: MIT License

C 75.65% Ragel in Ruby Host 22.29% Shell 1.35% Makefile 0.71%

dns's Introduction

Home Page

This project's home page and main repository is located at http://25thandClement.com/~william/projects/dns.c.html.

But feel free to rely on Github for tracking the source tree.

Description

A non-blocking DNS resolver library in a single .c file.

  • No dependencies!

  • Supports both stub and recursive modes.

  • No event callbacks! Callbacks are usually inevitable when writing non-blocking network software, but when too many libraries introduce too many callback interfaces code quickly becomes incomprehensible beyond necessity. dns.c requires no particular callback scheme, nor enforces callbacks at all. That makes it easy to use and embed within other components.

  • Works with any event loop. All resolver objects support three common methods: pollfd, events, and timeout.

  • Core DNS API built around actual DNS packet; as generic as DNS itself. This makes querying and manipulating records other than A, AAAA, and PTR much easier, yet with similar simplicity as API's which make annoying assumptions.

  • Type-specific interfaces for A, AAAA, CNAME, NS, SOA, PTR, MX, TXT, SRV, SSHFP, and SPF records.

  • Restartable record iterators with user-specified sorting. Iterate over MX or SRV records in semantic order (i.e. preference and priority) using a single dns_rr_foreach loop. Interruptible loops supported with dns_rr_grep.

  • Thoughtful /etc/resolv.conf, /etc/nsswitch.conf, and /etc/hosts integration. Easy to change system defaults, or to skip entirely.

  • getaddrinfo-like auxiliary interface.

  • Pluggable cache interface. Application can specify a synchronous or asynchronous local cache for use by the core resolver.

  • "Smart" queries which automatically dereference NS, MX, SRV, PTR, etc. to A or AAAA records. Recursing, caching nameservers don't usually do this explicitly, but merely rely on the authoritative server to include glue, which won't exist for out-of-bailiwick references (very common these days). This means software must do two separate logical DNS operations; a headache when patching software which only supported A lookups. Smart queries are available with a flag to the core resolver-—in both stub and recursive modes—-and more efficiently with the built-in getaddrinfo-like auxiliary interface.

  • Randomized source ports and encrypted QIDs using a 16-bit Feistel block cipher. User specifiable entropy source. Defaults to arc4random where available; knows how to use OpenSSL RAND_bytes if specified during the build (-DDNS_RANDOM=RAND_bytes).

  • Statistics interface. Retrieve count of packets and bytes, sent and received; and number of queries processed.

  • Used successfully by many projects for many years, including several Silicon Valley giants.

  • Regularly testing on Linux, OS X, OpenBSD, FreeBSD, NetBSD, and Solaris. Occassionally tested in MinGW environment. Builds with GCC, Clang, and SunPro.

spf.c

Asynchronous SPF resolver--no threading, no forking, no callbacks, no library dependencies.

  • A single source file. Requires Ragel precompiler, but no run-time dependencies other than dns.c. The Ragel translation can be done once and the result stored if you don't plan on hacking spf.c.
  • Passes over 90% of OpenSPF test suite. 100% test suite compliance is not the goal, as some tests are fairly debatable. (The SPF specification has some bugs.)
  • Used successfully in countless MTA installations and for billions (trillions?) of queries.

Build

dns.c is intended to be dropped into existing project builds. The included Makefile is mostly for development and testing.

Usage

Until the API is properly documented you must rely on the source code. The header, dns.h, and the API is fairly straight-forward, with each object implementating a simple, consistent, and hopefully self-explanatory pattern.

The last 1/6 of dns.c implements a command-line utility and a full regression testing suite permitting each component to be tested individually. This is excellent usage documentation as well.

License

Copyright (c) 2008-2015 William Ahern [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

dns's People

Contributors

wahern avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dns's Issues

localhost not preloaded

I was suprised to see dns.c reach out to my dns server to ask about 'localhost'.

rfc6761:

6.3. Domain Name Reservation Considerations for "localhost."

...

  1. Name resolution APIs and libraries SHOULD recognize localhost
    names as special and SHOULD always return the IP loopback address
    for address queries and negative responses for all other query
    types. Name resolution APIs SHOULD NOT send queries for
    localhost names to their configured caching DNS server(s).

I tracked this down to be due to /etc/hosts not containing a 'localhost' entry: dns.c needs to treat localhost specially.

SPF Without Ragel

Reimplement Ragel-based policy parser in basic C. The Ragel requirement turns some people off. In this case it should be easy to reimplement. The new implementation should taking into account the remainder of the SPF test suite. We fail some tests because the SPF grammar is ambiguous and the test suite assumes reliance on using naive regular expressions to parse the policy.

Memory leak

Test program:

#include "dns/dns.c"

int main() {
    int rc;
    struct dns_resolv_conf *dns_conf = dns_resconf_local(&rc);
    assert(dns_conf);
    struct dns_hosts *dns_hosts = dns_hosts_local(&rc);
    assert(dns_hosts);
    struct dns_hints *dns_hints = dns_hints_local(dns_conf, &rc);
    assert(dns_hints);
    struct dns_resolver *resolver = dns_res_open(dns_conf, dns_hosts, dns_hints, NULL, dns_opts(), &rc);
    assert(resolver);
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_INET;
    struct dns_addrinfo *ai = dns_ai_open("example.org", "80", DNS_T_A, &hints, resolver, &rc);
    assert(ai);
    struct addrinfo *it = NULL;
    while(1) {
        rc = dns_ai_nextent(&it, ai);
        if(rc == EAGAIN) {
            rc = dns_res_poll(resolver, -1);
            assert(rc == 0);
            continue;
        }
        if(rc == ENOENT)
            break;
    }
    dns_ai_close(ai);
    dns_res_close(resolver);
    dns_hints_close(dns_hints);
    dns_hosts_close(dns_hosts);
    dns_resconf_close(dns_conf);
    return 0;
}

Valgrind output:

$ valgrind --leak-check=full ./test
==18871== Memcheck, a memory error detector
==18871== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==18871== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==18871== Command: ./test
==18871== 
==18871== 
==18871== HEAP SUMMARY:
==18871==     in use at exit: 64 bytes in 1 blocks
==18871==   total heap usage: 28 allocs, 27 frees, 16,838 bytes allocated
==18871== 
==18871== 64 bytes in 1 blocks are definitely lost in loss record 1 of 1
==18871==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18871==    by 0x4130DC: dns_ai_setent (in /home/sustrik/dsock/test)
==18871==    by 0x4137A2: dns_ai_nextent (in /home/sustrik/dsock/test)
==18871==    by 0x414D6B: main (in /home/sustrik/dsock/test)
==18871== 
==18871== LEAK SUMMARY:
==18871==    definitely lost: 64 bytes in 1 blocks
==18871==    indirectly lost: 0 bytes in 0 blocks
==18871==      possibly lost: 0 bytes in 0 blocks
==18871==    still reachable: 0 bytes in 0 blocks
==18871==         suppressed: 0 bytes in 0 blocks
==18871== 
==18871== For counts of detected and suppressed errors, rerun with: -v
==18871== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

How to use Cache implementation in dns.c

1.) Do we need to include zone.c, cache.c for cache implementation?
2.) Is there any example, which explains the usage of command line arguments like "-z" (path to zone cache) etc. when using dns.c with cache implementation?

Support DNSSEC

Hopefully we can implement a simple, user-definable crypto interface provider (e.g. dns_random()) for signing and verification. But first version might just require OpenSSL to get a feel for the contours of the required cryptographic APIs.

Raspberry PI

Hey all! I have been having trouble getting this to work on the raspberry PI. Can anyone help?

Implement Parallel A/AAAA Queries

Support parallel A/AAAA queries. Likely implementation includes

  • Send & receive queue as either
    • simple, 2-packet queue integrated into struct dns_socket
    • complex queuing data structure supporting a shared socket among multiple resolvers
      • BUT complicates event polling contract--assumes event loop will wake up all pollers, or requires unique epoll/kqueue/socketpair descriptor per resolver
    • multiple sockets per resolver object
      • BUT complicates event polling contract--requires using epoll/kqueue descriptor to proxy multiple socket descriptors
  • 2 execution stacks per resolver object, instead of 1.

dns_ai_nextaf NULL pointer dereference

Previously dns_ai_nextent worked for numeric addresses even if no resolver object was provided. Now the first thing that dns_ai_nextent calls is dns_ai_nextaf, which immediately tries to dereference a ai->res to reach ai->res->resconf.

-Werror=array-bounds

Encountering 6 errors while attempting to compile.

til/dns.c:6528:17: error: array subscript -2 is below array bounds of 'unsigned char[1]' [-Werror=array-bounds]
so->query->data[-2] = 0xff & (so->query->end >> 8);

util/dns.c:6529:17: error: array subscript -1 is below array bounds of 'unsigned char[1]' [-Werror=array-bounds]
so->query->data[-1] = 0xff & (so->query->end >> 0);
~~~~~~~~~~~~~~~^~~~
util/dns.c:6531:9: error: array subscript -2 is below array bounds of 'unsigned char[1]' [-Werror=array-bounds]
qsrc = &so->query->data[-2] + so->qout;
       ^~~~~~~~~~~~~~~~~~~~
util/dns.c:6557:10: error: array subscript -2 is below array bounds of 'unsigned char[1]' [-Werror=array-bounds]
 asrc = &so->answer->data[-2];
        ^~~~~~~~~~~~~~~~~~~~~
util/dns.c:6568:18: error: array subscript -2 is below array bounds of 'unsigned char[1]' [-Werror=array-bounds]
  alen = ((0xff & so->answer->data[-2]) << 8)
          ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
util/dns.c:6569:42: error: array subscript -1 is below array bounds of 'unsigned char[1]' [-Werror=array-bounds]
       | ((0xff & so->answer->data[-1]) << 0);
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~

Win32/MinGW doesn't work

The code is filled with traces of Win32 + MinGW. But it's been some time, since the last MinGW compile, I think.

  • It doesn't compile, out of the box. (Easy fix.)
  • Functions like dns_resconf_local, dns_hosts_local doesn't work on Windows. "/etc/resolv.conf" anyone? And there're no hints on what to do instead. (I copied the files from my Linux. It seemed easier that figuring out how to hack the functions.)
  • dns_poll has a faulty assert, that breaks the program. You could argue that this is an issue in MinGW. But it's not a useful assert anyway, so.

Default to 127.0.0.1 when /etc/resolv.conf missing

The current code initializes struct dns_resolv_conf with a default name server of 0.0.0.0. However, that's only half of the original BIND semantics. 0.0.0.0 should be translated to 127.0.0.1 when finalizing the list, which in our case means when copying the name servers into the hints database. The translation should happen in either dns_hints_insert_resconf, or dns_hints_insert. The former is probably safer; the latter has its own appeal, but might be a tad too magical.

This should resolve issues received by the Enlightenment team where broken systems fail to write-out /etc/resolv.conf, yet applications using gethostbyname(3) or getaddrinfo(3) still work when a local DNS proxy is running.

Here's the relevant bits from glibc 2.23:

/*
 * Resolver state default settings.
 */

/*
 * Set up default settings.  If the configuration file exist, the values
 * there will have precedence.  Otherwise, the server address is set to
 * INADDR_ANY and the default domain name comes from the gethostname().
 *
 * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
 * rather than INADDR_ANY ("0.0.0.0") as the default name server address
 * since it was noted that INADDR_ANY actually meant ``the first interface
 * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
 * it had to be "up" in order for you to reach your own name server.  It
 * was later decided that since the recommended practice is to always
 * install local static routes through 127.0.0.1 for all your network
 * interfaces, that we could solve this problem without a code change.
 *
 * The configuration file should always be used, since it is the only way
 * to specify a default domain.  If you are running a server on your local
 * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
 * in the configuration file.
 *
 * Return 0 if completes successfully, -1 on error
 */

and

        if (__builtin_expect(statp->nscount == 0, 0)) {
            statp->nsaddr.sin_addr = __inet_makeaddr(IN_LOOPBACKNET, 1);
            statp->nsaddr.sin_family = AF_INET;
            statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
            statp->nscount = 1;
        }

Segmentation fault in dns_res_frame_init when dns_so_init fails

When dns_so_init in dns_res_open fails, it performs a cleanup.
However, dns_resolver is not fully configured by that point yet.
It calls dns_res_close(), which results in those calls: dns_res_reset(), dns_res_frame_init().

dns_res_frame_init() sets some options on the frame, based on the resconf configuration.
But at that point resconf is not set, and the program crashes.
There should be a check in dns_res_frame_init to make sure that R->resconf even valid.

The code that fails:

static void dns_res_frame_init(struct dns_resolver *R, struct dns_res_frame *frame) {
    memset(frame, '\0', sizeof *frame);

    if (!R->resconf->options.recurse)
        frame->qflags |= DNS_Q_RD;
    if (R->resconf->options.edns0)
        frame->qflags |= DNS_Q_EDNS0;
} /* dns_res_frame_init() */

I'm not sure why the first flag is SET when the option is NOT set,
but if resconf is not set it probably doesn't really matter...

Remove OpenBSD GCC Bug Workaround

Remove the workaround for the buggy compound-literal code emitted by OpenBSD GCC. Rather than figure out if the bug has been fixed (which ideally requires tracking down the culprit code in GCC), just use dynamic memory or a per-resolver static buffer.

SPF API Linkage and Visibility

Copy linkage and visibility improvements from dns.c to spf.c. Specifically, qualify API functions with SPF_PUBLIC in spf.h, and move extern objects behind a function interface so visibility can be easily controlled using the simple SPF_PUBLIC macro.

Use "e" (O_CLOEXEC) fopen mode flag

Currently dns_hosts_loadpath, dns_resconf_loadpath, and dns_nssconf_loadpath are not thread-safe. The "e" mode flag to fopen is now widely supported and scheduled for inclusion in the next POSIX standard. Add support conditioned on a compile-time feature macro.

gcc 9.1.0 compile error

gcc -c dns.c -o dns.o -D_DEFAULT_SOURCE

  dns.h:527:16: error: lvalue required as unary ‘&’ operand
  527 |  dns_rr_i_init(&dns_quietinit((struct dns_rr_i){ 0, __VA_ARGS__ }), (P))

How to use dns.c do dns redirecting ?

Hi,
I want to use dns.c as my raspberry pi dns server, when the raspberry pi is offline , all of dns request will be redirected a IP which I pointed.
now I use dnsmasq to do this function, I set "address=/#/172.1.8.1" on dnsmasq.conf. But I dont like dnsmasq. so how can I use dns.c do same job ?

Cache is being ignored

This is probably caused by the fact that I am not using the APIs properly,
but I cannot get the cache to work... at all.

I use the resolver generated using dns_res_open(), passing a cache object to it.
Then I use dns_ai_open() and dns_ai_nextent().
Everything works fine, except the cache is getting ignored...

Nothing new is added to it, when I dump it to a file it's empty.
When I manually create a cache, using data generated by 'cache' tool,
it is loaded, but then it is getting ignored and still does the DNS query.

Is there an example how to add cache support to the resolver?
Thanks!

#defining defined() in macros is undefined

Clang-5.0.1 on OpenBSD complains when compiling dns.c:

cc -std=gnu99 -Wall -Wextra -O2 -g -fstack-protector -O2 -pipe  -DDNS_DEBUG -DDNS_MAIN  -o dns dns.c 
dns.c:383:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
#if HAVE___ATOMIC_FETCH_ADD && __GCC_ATOMIC_LONG_LOCK_FREE == 2
    ^
dns.c:375:34: note: expanded from macro 'HAVE___ATOMIC_FETCH_ADD'
#define HAVE___ATOMIC_FETCH_ADD (defined __ATOMIC_RELAXED)
                                 ^
dns.c:392:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
#if HAVE___ATOMIC_FETCH_SUB && __GCC_ATOMIC_LONG_LOCK_FREE == 2
    ^
dns.c:379:33: note: expanded from macro 'HAVE___ATOMIC_FETCH_SUB'
#define HAVE___ATOMIC_FETCH_SUB HAVE___ATOMIC_FETCH_ADD
                                ^
dns.c:375:34: note: expanded from macro 'HAVE___ATOMIC_FETCH_ADD'
#define HAVE___ATOMIC_FETCH_ADD (defined __ATOMIC_RELAXED)
                                 ^
dns.c:788:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
#if DNS_HAVE_SOCKADDR_UN
    ^
dns.c:782:31: note: expanded from macro 'DNS_HAVE_SOCKADDR_UN'
#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
                              ^
dns.c:788:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
dns.c:782:51: note: expanded from macro 'DNS_HAVE_SOCKADDR_UN'
#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
                                                  ^
dns.c:843:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
#if DNS_HAVE_SOCKADDR_UN
    ^
dns.c:782:31: note: expanded from macro 'DNS_HAVE_SOCKADDR_UN'
#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
                              ^
dns.c:843:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
dns.c:782:51: note: expanded from macro 'DNS_HAVE_SOCKADDR_UN'
#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
                                                  ^
dns.c:849:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
#if DNS_HAVE_SOCKADDR_UN
    ^
dns.c:782:31: note: expanded from macro 'DNS_HAVE_SOCKADDR_UN'
#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
                              ^
dns.c:849:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
dns.c:782:51: note: expanded from macro 'DNS_HAVE_SOCKADDR_UN'
#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
                                                  ^
dns.c:909:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
#if DNS_HAVE_SOCKADDR_UN
    ^
dns.c:782:31: note: expanded from macro 'DNS_HAVE_SOCKADDR_UN'
#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
                              ^
dns.c:909:5: warning: macro expansion producing 'defined' has undefined behavior
      [-Wexpansion-to-defined]
dns.c:782:51: note: expanded from macro 'DNS_HAVE_SOCKADDR_UN'
#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
                                                  ^
dns.c:6134:5: warning: macro expansion producing 'defined' has undefined
      behavior [-Wexpansion-to-defined]
#if HAVE_SOCK_CLOEXEC
    ^
dns.c:6118:28: note: expanded from macro 'HAVE_SOCK_CLOEXEC'
#define HAVE_SOCK_CLOEXEC (defined SOCK_CLOEXEC)
                           ^
dns.c:6137:5: warning: macro expansion producing 'defined' has undefined
      behavior [-Wexpansion-to-defined]
#if HAVE_SOCK_NONBLOCK
    ^
dns.c:6122:29: note: expanded from macro 'HAVE_SOCK_NONBLOCK'
#define HAVE_SOCK_NONBLOCK (defined SOCK_NONBLOCK)
                            ^
dns.c:6143:25: warning: macro expansion producing 'defined' has undefined
      behavior [-Wexpansion-to-defined]
#if defined F_SETFD && !HAVE_SOCK_CLOEXEC
                        ^
dns.c:6118:28: note: expanded from macro 'HAVE_SOCK_CLOEXEC'
#define HAVE_SOCK_CLOEXEC (defined SOCK_CLOEXEC)
                           ^
dns.c:6148:28: warning: macro expansion producing 'defined' has undefined
      behavior [-Wexpansion-to-defined]
#if defined O_NONBLOCK && !HAVE_SOCK_NONBLOCK
                           ^
dns.c:6122:29: note: expanded from macro 'HAVE_SOCK_NONBLOCK'
#define HAVE_SOCK_NONBLOCK (defined SOCK_NONBLOCK)
                            ^
dns.c:6206:26: warning: macro expansion producing 'defined' has undefined
      behavior [-Wexpansion-to-defined]
#if (defined F_SETFD && !HAVE_SOCK_CLOEXEC) || (defined O_NONBLOCK && !H...
                         ^
dns.c:6118:28: note: expanded from macro 'HAVE_SOCK_CLOEXEC'
#define HAVE_SOCK_CLOEXEC (defined SOCK_CLOEXEC)
                           ^
dns.c:6206:72: warning: macro expansion producing 'defined' has undefined
      behavior [-Wexpansion-to-defined]
  ...F_SETFD && !HAVE_SOCK_CLOEXEC) || (defined O_NONBLOCK && !HAVE_SOCK_NONB...
                                                               ^
dns.c:6122:29: note: expanded from macro 'HAVE_SOCK_NONBLOCK'
#define HAVE_SOCK_NONBLOCK (defined SOCK_NONBLOCK)
                            ^
16 warnings generated.

C++ compatibility

Why on God's green earth would you guys declare a variable "class" in your C source file. It makes it impossible to include in a C++ source file without a hack like this:

extern "C" {
#define class klass
#include "dns.h"
#undef class
}

Can this be fixed?

It doesn't work with IPv6 DNS servers

Hi.

I cannot get it to work with IPv6 DNS servers.
Is this supported? I am using current master.

When I set only v6 DNS servers in my resolv.conf, the demo app refused to work:

$ ./dns show-hints
ZONE "."
        (1) [2001:4860:4860::8888]:53
$ ./dns send-query -q google.ca
querying 2001:4860:4860::8888 for google.ca IN AAAA
dns: (send_query:9433) dns_so_query: Address family not supported by protocol (97)

It works just fine with IPv4 DNS:

$ ./dns show-hints
ZONE "."
        (1) [8.8.8.8]:53
$ ./dns send-query -q google.ca
querying 8.8.8.8 for google.ca IN AAAA
;; [HEADER]
;;    qid : 53039
;;     qr : RESPONSE(1)
;; opcode : QUERY(0)
;;     aa : NON-AUTHORITATIVE(0)
;;     tc : NOT-TRUNCATED(0)
;;     rd : RECURSION-DESIRED(1)
;;     ra : RECURSION-ALLOWED(1)
;;  rcode : NOERROR(0)

;; [QUESTION:1]
;google.ca. IN AAAA

;; [ANSWER:1]
google.ca. 294 IN AAAA 2607:f8b0:400b:80e::2003

I also got it working in my application, by adding the DNS server name to hints with dns_hints_insert(),
and using dns_res_submit() and dns_res_check(). It works if I provide IPv4 DNS address,
but always returns 0 addresses when IPv6 DNS server is used.

I can also see that it creates an AF_INET socket in both cases, but only tries to call 'connect' when IPv4 DNS server is used.

Am I missing something?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.