Proposal: SocketBackend #529

Closed
Habbie opened this Issue Apr 26, 2013 · 5 comments

Projects

None yet

1 participant

@Habbie
Member
Habbie commented Apr 26, 2013

(As thrown around on IRC #powerdns on 2012-07-11)

PowerDNS supports a large number of back-ends, one of which, the PIPE back-end
pipeabi is frequently used for prototyping or by people not willing or able to
invest in creating a native C++ back-end. The PIPE back-end is a forking model,
by which a process or processes receive queries and return replies to queries
via stdin/stdout in currently up to three different "protocols" (see ABI in
pipeabi).

We herewith propose a new native SOCKET back-end for PowerDNS which speaks to an
existing process over TCP. One idea is to use HTTP as ubiquitous communication
protocol to speak with the back-end, in which case PowerDNS would present an
incoming query via a POST request and obtain a response (or list of responses)
which it returns to the DNS client.

(An advantage of using HTTP is possible use or re-use of existing server-side
infrastructure for creating SOCKET co-routines: HTTP CGI, node.js, etc. are
examples.)

SocketBackend configuration:

socket-url
    URL to which PowerDNS POSTs a request
socket-timeout
    Number of milliseconds to wait for an answer from the back-end
socket-regex
    If set, acts like pipe-regex
socket-backend-version
    The version of the question format

SocketBackend protocol:

Queries:
Questions come in to `socket-url' via a POST request. The request's
payload is a JSON json string representing the DNS query:

    {
        "qname"  : "www.ds9a.nl",
        "qclass" : "IN",
        "qtype"  : "A"
    }
The HTTP request's headers contain additional information:

Y-Remote-IP: 
    IP address of the nameserver asking the question
Y-Local-IP:
    IP address on which the question was received.
Y-EDNS-Subnet: 
    actual client subnet as provided via edns-subnet support

Responses:
The `socket-url' returns a (possibly zero-length) JSON array containing
the replies it wants PowerDNS to return to the DNS client. An empty
array signifies the SOCKET back-end has no data. (c.f. "END" in the
PIPE back-end.)

HTTP STATUS codes indicate success or failure (e.g.):

        200 OK / i.e. NOERROR
        404 NOTFOUND / i.e. NXDOMAIN
        ...

Examples: No data / no error

        {
            "data" : [ 
                ]
        }

Examples: An SOA record:

        {
            "data" : [
                    { "qname" : "ds9a.nl",
                      "qclass" : "IN",
                      "qtype"  : "SOA",
                      "rdata"  : "123 ......."
                    }
                ]
        }

Examples: One AAAA and one MX RR:


        {
            "data" : [
                    { "qname" : "www.ds9a.nl",
                      "qclass" : "IN",
                      "qtype"  : "MX",
                      "rdata"  : "10 gmail.com."
                    },
                    { "qname" : "www.ds9a.nl",
                      "qclass" : "IN",
                      "qtype"  : "AAAA",
                      "rdata"  : ":::1"
                    }
                ]
        }

Tired. Somebody pick up here please! ;-)

Regards,

-JP
@Habbie Habbie was assigned Apr 26, 2013
@Habbie Habbie closed this Apr 26, 2013
@Habbie
Member
Habbie commented Apr 26, 2013

Author: anon
Some ideas:

  • Make it able to connect to either UNIX Socket or TCP socket.
  • Make HTTP optional, so it can either send full HTTP POST or just plain json.
  • Do HTTP over Unix socket
  • Must support (re)connection without blocking the entire process.
  • Timeout for request is 2 seconds. Always.

Also, we could have DNSSEC support on it by being able to ask DNS keying material and stuff? Also I think we should put all data into JSON, not in headers...

Some proposal for protocol

Query formats

 {
    "type": "query" 
    "qname": "label"
    "qclass": "IN"
    "qtype": "A"
 }

 {
    "type": "meta"
    "name": "domain"
    "kind": "meta-key"
 }

 {
    "type": "key"
    "name": "domain"
 }

Response formats:

 {
    "type": "answer" 
    "rname": "label"
    "rclass": "IN"
    "rtype": "A"
    "rdata": "1.2.3.4"
 }

 {
    "type": "meta"
    "name": "domain"
    "kind": "meta-key"
    "value": "meta-value"
 }

 {
    "type": "key"
    "name": "domain"
    "keys" [
       "keydata",
       "keydata",
       ...
    ]
 }
@Habbie
Member
Habbie commented Apr 26, 2013

Author: anon
For HTTP support, maybe REST-like URLs (configurable instead of HTTP POST) would ease back-end development for the myriad of WSGI/FASTCGI/etc. platforms out there?

socket-url "http://host:port/$qname/$qclass/$qtype"
@Habbie
Member
Habbie commented Apr 26, 2013

Author: anon
A small fix for the syntax proposal

Response formats:

 {
    "type": "answer"
    [
     { 
      "rname": "label"
      "rclass": "IN"
      "rtype": "A"
      "rdata": "1.2.3.4"
     }, 
     ...
    ]
 }

 {
    "type": "meta"
    "name": "domain"
    "kind": "meta-key"
    "value": ["meta-value", "meta-value", ...]
 }
@Habbie
Member
Habbie commented Apr 26, 2013

Author: anon
See also: exact ''qtype'' in ticket:531

@Habbie
Member
Habbie commented Apr 26, 2013

Author: peter
Aki Tuomi's socketbackend was merged!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment