-
Notifications
You must be signed in to change notification settings - Fork 17
An easy to use DNS library with C and Lua bindings
License
spc476/SPCDNS
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
SPCDNS: The sane DNS encoding/decoding library SPCDNS implements a simple yet sane API to encode DNS queries and to decode DNS replies. The library (v2.0.0) currently supports the encoding and decoding of 30 DNS resource records, which is more than just about all other DNS resolving libraries I've seen (c-ares, udns, adns, libdns and djbdns [1]). SPCDNS is *NOT* a general purpose DNS resolving library (although code is provided to make DNS queries, it is simple and fairly stupid). This code exists to provide a simple method of encoding and decoding the DNS protocol and thus the network side of things is a bit lacking I'll admit. But that is beyond what I wanted for this project anyway. In the "src/" directory you'll find the following: dns.h Defines the various DNS RR types, a structure for an in-memory representation of each RR type (which is what you'll get back when you call the decoding routine), and the definitions for two functions, dns_encode() and dns_decode() which pretty much do what they say. codec.c The actual implementations of dns_encode() and dns_decode(). This is the only file that's needed to encode and decode the raw DNS protocol. The routines are thread safe, do *not* allocate memory (see below for more details) and do not use signals. It also does not use code from any other file in this package. mappings.h mappings.c These files provide definitions and implementation of a few helpful routines that return string representations of the DNS RR types, classes, opcodes and errors. Again, thread safe and no memory allocations made. netsimple.h netsimple.c These files provide definitions and implementations for making simple DNS queries to a given server. This code is *simple* and *dumb*, it may be good for light usage but was written to get actual DNS packets from a DNS server for testing. This uses UDP and is thus limited to a query of 512 bytes or less. output.h output.c These files provide definitions and implementations for utility functions to print query results using C stdio. It was factored out of the unit tests for debugging client applications making using of libspcdns.a and libspcdns.so. They are found in the libspcdnsmisc.a and libspcdnsmisc.so libraries. luadns.c Lua [2] bindings for this library. It exports the routines found in codec.c, mappings.c and netsimple.c. dotest.c An example program showing how to use the API to construct and send a query, and to decode the response. You'll probably want to check the Makefile to make sure the right compiler and locations are set. Or not. You don't *HAVE* to use the included Makefile. It's really just a set of suggestions anyway. A NOTE ABOUT MEMORY ALLOCATIONS The dns_encode() and dns_decode() functions do no memory allocation; they use what you give them. In the case of dns_decode(), the block of memory passed in must be big enough to handle not only the dns_query_t structure, but multiple dns_answer_t structures and text strings representing domain names and the occasional string or two (say, for TXT or NAPTR records). In testing, I've found that 4K for decoding appears to be enough memory to handle DNS requests made via UDP (although the test.c program uses an 8K buffer). This block of memory should be properly aligned and to help make that easier I've defined two data types that should allow proper alignment, along with some useful constants to declare buffers of proper alignment and size. dns_packet_t reply [DNS_BUFFER_UDP]; dns_decoded_t decoded[DNS_DECODEBUF_4K]; dns_query_t *result; dns_rcode rc; size_t replysize; size_t decodesize; /* assume reply contains a DNS packet, and replysize is set */ decodesize = sizeof(decoded); rc = dns_decode(decoded,&decodesize,reply,replysize); if (rc != RCODE_OKAY) { /* handle error */ } result = (dns_query_t *)decoded; /* go with processing the result */ Do *NOT* assume that DNS_DECODEBUF_4K is equal to 4096---it's not. It *DOES*, however, result in at least a 4K block of memory made up of DNS_DECODEBUF_4K worth of dns_decoded_t types. By the same token, do *NOT* assume that DNS_BUFFER_UDP is 512, but it too, does result in a buffer of at least 512 bytes made up of DNS_BUFFER_UDP dns_packet_t types. And while passing in a char * declared buffer to dns_decode() may appear to work, it only works on *YOUR* system; it may not work on other systems. A NOTE ABOUT DOMAIN NAMES The dns_encode() function assumes the domain passed is a fully qualified domain name. If you see an RCODE_NAME_ERROR when calling this function, you are probably not passing in a FQDN (if you are and are still getting that error, it's most likely a domain name segment exceeding the 63 character DNS limit). SOME NOTES ABOUT THE LUA BINDINGS The Lua bindings (for Lua 5.1-5.4) are loaded into a Lua script with the following: local dns = require "org.conman.dns" Doing a "make install-lua" will install this file under: /usr/local/lib/lua/<Lua version>/org/conman/ (assuming you didn't change the LUA setting in the Makefile) and thus place it under the appropriate namespace so Lua can find it. The file "lua/test.lua" shows the best use of the Lua bindings (and is close enough to what "src/test.c" does). Better network handling could be done using LuaSocket, but for that, you are on your own. UNIT TESTING The dotest program allows unit-testing SPCDNS when making changes or integrating it with client applications. Note: the unit test program, dotest, requires a fully-qualified canonical DNS name. This means "www.example.com." NOT "www.example.com". If this is not present, the dns_encode_domain function returns RCODE_NAME_ERROR and the test will fail with a mysterious error message. Sample Output: This is an example of a working run, querying for Google's web server, using a Google Public DNS Server [4]. $ ./dotest -d -s 8.8.8.8 www.google.com. OUTGOING: ... MEMORY DUMP... INCOMING: ... MEMORY DUMP... Bytes used: 680 ; Questions = 1 ; Answers = 5 ; Name Servers = 0 ; Additional Records = 0 ; Authoritative Result = false ; Truncated Result = false ; Recursion Desired = true ; Recursion Available = true ; Result = No error ;;; QUESTIONS ;www.google.com. IN A ;;; ANSWERS www.google.com. 185 IN A 74.125.239.49 www.google.com. 185 IN A 74.125.239.52 www.google.com. 185 IN A 74.125.239.50 www.google.com. 185 IN A 74.125.239.51 www.google.com. 185 IN A 74.125.239.48 ;;; NAMESERVERS ;;; ADDITIONAL A FINAL NOTE If you have any problems, questions or enhancements, please send them my way, to sean@conman.org. Thank you. Other contributors include, but are not limited to: Matthew Hall <mhall@mhcomputing.net> [1] http://c-ares.haxx.se/ http://www.corpit.ru/mjt/udns.html http://www.chiark.greenend.org.uk/~ian/adns/ http://www.25thandclement.com/~william/projects/dns.c.html http://cr.yp.to/djbdns.html [2] http://www.lua.org/ [3] http://w3.impa.br/~diego/software/luasocket/ [4] https://developers.google.com/speed/public-dns/
About
An easy to use DNS library with C and Lua bindings
Resources
License
Stars
Watchers
Forks
Packages 0
No packages published