From rick at openfortress.nl Thu May 26 20:31:54 2016 From: rick at openfortress.nl (Rick van Rein) Date: Thu, 26 May 2016 22:31:54 +0200 Subject: [getdns-users] GetDNS use case: Kerberos Realm Crossover Message-ID: <57475D3A.10005@openfortress.nl> Hello, This is to let you know that a student of mine finished his MSc thesis work using GetDNS. I thought it might be an interesting case study. What he's done is prototype a mechanism for automatic / in-situ realm crossover with Kerberos, based on mutual authentication between KDCs with DNSSEC / DANE. More details, in increasing level of detail, is on http://realm-xover.arpa2.net/kerberos.html http://k5wiki.kerberos.org/wiki/Projects/Realm_Crossover_between_KDCs http://research.arpa2.org/library/bellatriu-2016-kerberos-realm-crossover.pdf What may be interesting for GetDNS is to learn about our timing concerns, and how GetDNS' asynchronous handling may help here. To establish a remote site's identity, we need to go through a sequential DNS lookup: 1. based on a DNS name, we need to lookup the Kerberos realm name in DNS using a _kerberos TXT record; 2. based on the realm, mapped to a DNS name, we locate the SRV record for the KDC; 3. based on the KDC location, we can (a) contact it and (b) formulate its TLSA record location We then continue to compare TLSA to the KDC certificate, and so on. The thing is, this sequence takes quite a bit of time and Kerberos clients, which usually prod their KDC over UDP, tend to wait only for a small timeout. In Heimdal, a default of 1 second is compiled-in. Compare that to the complex DNSSEC-based procedure above, and realise that this should be done on both sides, and we're clearly in trouble. One way out of this predicament would be if we would first ask for DNS data and then add the authenticity information later. So, we'd take a stab at the data that we may reasonably assume to be correct, and while still checking, we already progress to the next stage. That would result in the DNSSEC validation of phases 1, 2 and 3 all taking place in parallel. The sequence of 1, 2, 3 is only as slow as three plain DNS lookups and we can withhold the final conclusion (and relaying it back to the client) until the three DNSSEC phases have cleared as well. Only when DNSSEC returns Bogus or Insecure would we scratch behind our ears, and perhaps restart. This is only one application, but at least the sequence 2,3 is going to be commonplace, I'd expect. And the agony of delays, though not always as obstructive as with timeout-based UDP protocols, is going to devastate things like TLS performance as well. So... I'd say that an eager DNS resolver may want to take these concerns into account, judging whether it is to be expected to be a common user requirement. Willem, note that this might mingle nicely with the suggestions I've done about having a "current state" object for DNS data. One would simple first ask_data() and later await_dnssec(SECURE). I hope this is useful; it is written in the assumption that GetDNS is still looking for ways to be useful. Cheers, -Rick From pusateri at bangj.com Sun May 1 17:29:40 2016 From: pusateri at bangj.com (Tom Pusateri) Date: Sun, 1 May 2016 13:29:40 -0400 Subject: [getdns-api] libevent and multiple contexts Message-ID: <1622E040-8F57-4CD0-A06C-5BF9B184C5B0@bangj.com> I?ve been looking at the example code in the spec and there is a function getdns_extension_set_libevent_base(context, event_base). I am using libevent to handle multiple DNS queries and responses but some are UDP only, some are TLS and have different context parameters. So my question is, can I create several contexts and have them all point to the same libevent base? Thanks, Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From pusateri at bangj.com Sun May 1 20:14:44 2016 From: pusateri at bangj.com (Tom Pusateri) Date: Sun, 1 May 2016 16:14:44 -0400 Subject: [getdns-api] string from dict bindata Message-ID: In the spec, there is a function to return API information: getdns_dict *api_info = getdns_context_get_api_information(getdns_context *context); It contains version_string and implementation_string both as bindata. There is a function to get the bindata from the dict but I don?t see an API to convert the bindata to a generic string: getdns_bindata *version_bindata = NULL; getdns_dict_get_bindata(api_info, "version_string", &version_bindata); Are we supposed to peek inside of bindata and assume the bytes and length are string data? Thanks, Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From melinda.shore at nomountain.net Mon May 2 00:40:58 2016 From: melinda.shore at nomountain.net (Melinda Shore) Date: Sun, 1 May 2016 16:40:58 -0800 Subject: [getdns-api] string from dict bindata In-Reply-To: References: Message-ID: <5726A21A.40101@nomountain.net> On 5/1/16 12:14 PM, Tom Pusateri wrote: > Are we supposed to peek inside of bindata and assume the bytes and length are string data? Yes, unfortunately you need to know what type of data are being returned in each dictionary element, but if you do it's extremely reliable. bindata->size holds the string length. I've found that bindata strings do not always have a terminal \0, so in the Python bindings I'm doing string conversions using PyString_FromStringAndSize() rather than just PyString_FromString(). Melinda From pusateri at bangj.com Mon May 2 03:39:27 2016 From: pusateri at bangj.com (Tom Pusateri) Date: Sun, 1 May 2016 23:39:27 -0400 Subject: [getdns-api] string from dict bindata In-Reply-To: <5726A21A.40101@nomountain.net> References: <5726A21A.40101@nomountain.net> Message-ID: <851FE58D-620F-476F-8723-5956F29A5F44@bangj.com> > On May 1, 2016, at 8:40 PM, Melinda Shore wrote: > > On 5/1/16 12:14 PM, Tom Pusateri wrote: >> Are we supposed to peek inside of bindata and assume the bytes and length are string data? > > Yes, unfortunately you need to know what type of data > are being returned in each dictionary element, but if you > do it's extremely reliable. bindata->size holds the > string length. I've found that bindata strings do not > always have a terminal \0, so in the Python bindings I'm > doing string conversions using PyString_FromStringAndSize() > rather than just PyString_FromString(). > > Melinda Ok, good to confirm. I am using a special printf construct to avoid the need for ?\0' terminated strings: printf("getdns version: %.*s implementation: %.*s\n", (int)version_bindata->size, version_bindata->data, (int)impl_bindata->size, impl_bindata->data); This seems a little dirty to be accessing the data/size which should be opaque. It?s not a big deal but I guess I was hoping for something like: char * getdns_characters_from_bindata(getdns_bindata *bindata, int *lenp) { if (lenp) { *lenp = (int)bindata->size; } return bindata->data; } Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From willem at nlnetlabs.nl Mon May 2 08:53:49 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Mon, 2 May 2016 10:53:49 +0200 Subject: [getdns-api] libevent and multiple contexts In-Reply-To: <1622E040-8F57-4CD0-A06C-5BF9B184C5B0@bangj.com> References: <1622E040-8F57-4CD0-A06C-5BF9B184C5B0@bangj.com> Message-ID: <5727159D.30106@nlnetlabs.nl> Op 01-05-16 om 19:29 schreef Tom Pusateri: > I?ve been looking at the example code in the spec and there is a function > getdns_extension_set_libevent_base(context, event_base). > > I am using libevent to handle multiple DNS queries and responses but some are UDP only, some are TLS and have different context parameters. > > So my question is, can I create several contexts and have them all point to the same libevent base? Hi Tom, this is perfectly possible. One event base can be shared between your application and multiple getdns contexts (*). Cheers, -- Willem (*) though within the same process and thread. > > Thanks, > Tom > > > > _______________________________________________ > spec mailing list > spec at getdnsapi.net > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From willem at nlnetlabs.nl Mon May 2 09:06:39 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Mon, 2 May 2016 11:06:39 +0200 Subject: [getdns-api] string from dict bindata In-Reply-To: <5726A21A.40101@nomountain.net> References: <5726A21A.40101@nomountain.net> Message-ID: <5727189F.2080207@nlnetlabs.nl> Op 02-05-16 om 02:40 schreef Melinda Shore: > On 5/1/16 12:14 PM, Tom Pusateri wrote: >> Are we supposed to peek inside of bindata and assume the bytes and >> length are string data? > > Yes, unfortunately you need to know what type of data > are being returned in each dictionary element, but if you > do it's extremely reliable. bindata->size holds the > string length. I've found that bindata strings do not > always have a terminal \0, so in the Python bindings I'm > doing string conversions using PyString_FromStringAndSize() > rather than just PyString_FromString(). That is correct, the internally used getdns_dict_util_set_string() does not copy the terminating \0 character, because the string length is already provided in bindata.size. Note that in our implementation of the API we provide some non-standard, but more C-friendly functions to access the version information in getdns_extra.h, that do return \0 terminated strings: const char *getdns_get_version(void); uint32_t getdns_get_version_number(void); const char *getdns_get_api_version(void); uint32_t getdns_get_api_version_number(void); It also contains some macros providing the version information of the library used at compile time: #define GETDNS_VERSION "1.0.0b1" #define GETDNS_NUMERIC_VERSION 0x00100100 #define GETDNS_API_VERSION "December 2015" #define GETDNS_API_NUMERIC_VERSION 0x07df0c00 -- Willem > > Melinda > > _______________________________________________ > spec mailing list > spec at getdnsapi.net From pusateri at bangj.com Mon May 2 20:55:58 2016 From: pusateri at bangj.com (Tom Pusateri) Date: Mon, 2 May 2016 16:55:58 -0400 Subject: [getdns-api] string from dict bindata In-Reply-To: <5727189F.2080207@nlnetlabs.nl> References: <5726A21A.40101@nomountain.net> <5727189F.2080207@nlnetlabs.nl> Message-ID: > On May 2, 2016, at 5:06 AM, Willem Toorop wrote: > > Op 02-05-16 om 02:40 schreef Melinda Shore: >> On 5/1/16 12:14 PM, Tom Pusateri wrote: >>> Are we supposed to peek inside of bindata and assume the bytes and >>> length are string data? >> >> Yes, unfortunately you need to know what type of data >> are being returned in each dictionary element, but if you >> do it's extremely reliable. bindata->size holds the >> string length. I've found that bindata strings do not >> always have a terminal \0, so in the Python bindings I'm >> doing string conversions using PyString_FromStringAndSize() >> rather than just PyString_FromString(). > > That is correct, the internally used getdns_dict_util_set_string() does > not copy the terminating \0 character, because the string length is > already provided in bindata.size. > > Note that in our implementation of the API we provide some non-standard, > but more C-friendly functions to access the version information in > getdns_extra.h, that do return \0 terminated strings: > > const char *getdns_get_version(void); > uint32_t getdns_get_version_number(void); > const char *getdns_get_api_version(void); > uint32_t getdns_get_api_version_number(void); > > It also contains some macros providing the version information of the > library used at compile time: > > #define GETDNS_VERSION "1.0.0b1" > #define GETDNS_NUMERIC_VERSION 0x00100100 > #define GETDNS_API_VERSION "December 2015" > #define GETDNS_API_NUMERIC_VERSION 0x07df0c00 > > -- Willem Thanks Willem. For the version info, this is helpful. I was just using the api info as an example. I will also have to get strings from TXT records which are more generic. Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From pusateri at bangj.com Mon May 2 20:56:26 2016 From: pusateri at bangj.com (Tom Pusateri) Date: Mon, 2 May 2016 16:56:26 -0400 Subject: [getdns-api] libevent and multiple contexts In-Reply-To: <5727159D.30106@nlnetlabs.nl> References: <1622E040-8F57-4CD0-A06C-5BF9B184C5B0@bangj.com> <5727159D.30106@nlnetlabs.nl> Message-ID: <1EDBE5B9-38A0-4052-A533-DDDFA7AFD415@bangj.com> > On May 2, 2016, at 4:53 AM, Willem Toorop wrote: > > Op 01-05-16 om 19:29 schreef Tom Pusateri: >> I?ve been looking at the example code in the spec and there is a function >> getdns_extension_set_libevent_base(context, event_base). >> >> I am using libevent to handle multiple DNS queries and responses but some are UDP only, some are TLS and have different context parameters. >> >> So my question is, can I create several contexts and have them all point to the same libevent base? > > Hi Tom, this is perfectly possible. One event base can be shared > between your application and multiple getdns contexts (*). > > Cheers, > -- Willem > > (*) though within the same process and thread. Cool. I?ll try this out. Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From pusateri at bangj.com Mon May 9 22:56:03 2016 From: pusateri at bangj.com (Tom Pusateri) Date: Mon, 9 May 2016 18:56:03 -0400 Subject: [getdns-api] getdns_context_set_upstream_recursive_servers Message-ID: <325CC105-8ACB-4F00-8048-6EB7858E828A@bangj.com> If I want to send a query to the target of the result of an SRV query, do I use this function to set the target as the DNS server to query? getdns_return_t getdns_context_set_upstream_recursive_servers( getdns_context *context, getdns_list *upstream_list ); The name is a little misleading since I don?t want to do a recursive resolve, just a direct query with no rd bit set but I don?t see any other way to set the DNS server to query. If this is the right function, then maybe ?recursive? should be removed? Thanks, Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From willem at nlnetlabs.nl Tue May 10 07:52:13 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Tue, 10 May 2016 09:52:13 +0200 Subject: [getdns-api] getdns_context_set_upstream_recursive_servers In-Reply-To: <325CC105-8ACB-4F00-8048-6EB7858E828A@bangj.com> References: <325CC105-8ACB-4F00-8048-6EB7858E828A@bangj.com> Message-ID: <5731932D.2070607@nlnetlabs.nl> Hi Tom, That is indeed the function you need to use to target servers directly. Don't forget to put the context in GETDNS_RESOLUTION_STUB mode with getdns_context_set_resolution_type() too. To not send the RD bit set with your queries, you have to pass along an (unofficial) header extension with the "rd" bit set to zero, ie: { "header": { "rd": 0 } }. But yes, function (and constant) names in getdns can be rather verbose. getdns_context_set_upstreams() would have worked just as well. We could add unofficial more concise aliases, but I don't want to bloat the API. Regards, -- Willem Op 10-05-16 om 00:56 schreef Tom Pusateri: > If I want to send a query to the target of the result of an SRV query, do I use this function to set the target as the DNS server to query? > > getdns_return_t > getdns_context_set_upstream_recursive_servers( getdns_context *context, getdns_list *upstream_list ); > > The name is a little misleading since I don?t want to do a recursive resolve, just a direct query with no rd bit set but I don?t see any other way to set the DNS server to query. > > If this is the right function, then maybe ?recursive? should be removed? > > Thanks, > Tom > > > > > _______________________________________________ > spec mailing list > spec at getdnsapi.net > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From robert.groenenberg at broadforward.com Thu May 12 17:18:09 2016 From: robert.groenenberg at broadforward.com (Robert Groenenberg) Date: Thu, 12 May 2016 19:18:09 +0200 Subject: [getdns-api] Actual upstream server Message-ID: <968bf020-c6cc-2560-3eac-5bd8d754c126@broadforward.com> Hi, I'm using getdns in stub mode with one or more upstream servers configured in the context. For statistics and logging I'd like to figure out which upstream server was actually used for a particular query. Am I correct that that information is currently not available, at least not (yet) via the API? When the user callback is invoked, does context->upstreams->current indicate the upstream server that responded, or could it have already been changed for another query that has been send out between sending the 'current' query and receiving its response? Thanks, Robert From willem at nlnetlabs.nl Thu May 12 17:39:16 2016 From: willem at nlnetlabs.nl (Willem Toorop) Date: Thu, 12 May 2016 19:39:16 +0200 Subject: [getdns-api] Actual upstream server In-Reply-To: <968bf020-c6cc-2560-3eac-5bd8d754c126@broadforward.com> References: <968bf020-c6cc-2560-3eac-5bd8d754c126@broadforward.com> Message-ID: <5734BFC4.6090001@nlnetlabs.nl> Hi Robert, You'll get that information when you use the call reporting extension. willem at bonobo:~$ getdns_query -s +return_call_reporting -A nlnetlabs.nl SYNC response: { "answer_type": GETDNS_NAMETYPE_DNS, "call_reporting": [ { "query_name": , "query_to": { "address_data": , "address_type": }, "query_type": GETDNS_RRTYPE_AAAA, "run_time/ms": 14, "transport": GETDNS_TRANSPORT_UDP }, { "query_name": , "query_to": { "address_data": , "address_type": }, "query_type": GETDNS_RRTYPE_A, "run_time/ms": 18, "transport": GETDNS_TRANSPORT_UDP } ], "canonical_name": , "just_address_answers": [ { "address_data": , "address_type": }, { "address_data": , "address_type": } ], "replies_full": [ , ], "replies_tree": [ { "additional": [], "answer": [ { "class": GETDNS_RRCLASS_IN, "name": , "rdata": { "ipv6_address": , "rdata_raw": }, "ttl": 10200, "type": GETDNS_RRTYPE_AAAA } ], "answer_type": GETDNS_NAMETYPE_DNS, "authority": [], "canonical_name": , "header": { "aa": 0, "ad": 0, "ancount": 1, "arcount": 0, "cd": 0, "id": 48885, "nscount": 0, "opcode": GETDNS_OPCODE_QUERY, "qdcount": 1, "qr": 1, "ra": 1, "rcode": GETDNS_RCODE_NOERROR, "rd": 1, "tc": 0, "z": 0 }, "question": { "qclass": GETDNS_RRCLASS_IN, "qname": , "qtype": GETDNS_RRTYPE_AAAA } }, { "additional": [], "answer": [ { "class": GETDNS_RRCLASS_IN, "name": , "rdata": { "ipv4_address": , "rdata_raw": }, "ttl": 10200, "type": GETDNS_RRTYPE_A } ], "answer_type": GETDNS_NAMETYPE_DNS, "authority": [], "canonical_name": , "header": { "aa": 0, "ad": 0, "ancount": 1, "arcount": 0, "cd": 0, "id": 36458, "nscount": 0, "opcode": GETDNS_OPCODE_QUERY, "qdcount": 1, "qr": 1, "ra": 1, "rcode": GETDNS_RCODE_NOERROR, "rd": 1, "tc": 0, "z": 0 }, "question": { "qclass": GETDNS_RRCLASS_IN, "qname": , "qtype": GETDNS_RRTYPE_A } } ], "status": GETDNS_RESPSTATUS_GOOD } Response code was: GOOD. Status was: At least one response was returned All done. Op 12-05-16 om 19:18 schreef Robert Groenenberg: > Hi, > > I'm using getdns in stub mode with one or more upstream servers > configured in the context. > For statistics and logging I'd like to figure out which upstream server > was actually used for a particular query. Am I correct that that > information is currently not available, at least not (yet) via the API? > > When the user callback is invoked, does context->upstreams->current > indicate the upstream server that responded, or could it have already > been changed for another query that has been send out between sending > the 'current' query and receiving its response? > > Thanks, > Robert > _______________________________________________ > spec mailing list > spec at getdnsapi.net From robert.groenenberg at broadforward.com Thu May 12 20:43:10 2016 From: robert.groenenberg at broadforward.com (Robert Groenenberg) Date: Thu, 12 May 2016 22:43:10 +0200 Subject: [getdns-api] Actual upstream server In-Reply-To: <5734BFC4.6090001@nlnetlabs.nl> References: <968bf020-c6cc-2560-3eac-5bd8d754c126@broadforward.com> <5734BFC4.6090001@nlnetlabs.nl> Message-ID: Hi Willem, Oops, I missed that in the documentation... Looks like this extension provides just what I need. Thanks! Robert On 12-05-16 19:39, Willem Toorop wrote: > Hi Robert, > > You'll get that information when you use the call reporting extension. > > > willem at bonobo:~$ getdns_query -s +return_call_reporting -A nlnetlabs.nl > SYNC response: > { > "answer_type": GETDNS_NAMETYPE_DNS, > "call_reporting": > [ > { > "query_name": , > "query_to": > { > "address_data": , > "address_type": > }, > "query_type": GETDNS_RRTYPE_AAAA, > "run_time/ms": 14, > "transport": GETDNS_TRANSPORT_UDP > }, > { > "query_name": , > "query_to": > { > "address_data": , > "address_type": > }, > "query_type": GETDNS_RRTYPE_A, > "run_time/ms": 18, > "transport": GETDNS_TRANSPORT_UDP > } > ], > "canonical_name": , > "just_address_answers": > [ > { > "address_data": , > "address_type": > }, > { > "address_data": , > "address_type": > } > ], > "replies_full": > [ > , > > ], > "replies_tree": > [ > { > "additional": [], > "answer": > [ > { > "class": GETDNS_RRCLASS_IN, > "name": , > "rdata": > { > "ipv6_address": , > "rdata_raw": > }, > "ttl": 10200, > "type": GETDNS_RRTYPE_AAAA > } > ], > "answer_type": GETDNS_NAMETYPE_DNS, > "authority": [], > "canonical_name": , > "header": > { > "aa": 0, > "ad": 0, > "ancount": 1, > "arcount": 0, > "cd": 0, > "id": 48885, > "nscount": 0, > "opcode": GETDNS_OPCODE_QUERY, > "qdcount": 1, > "qr": 1, > "ra": 1, > "rcode": GETDNS_RCODE_NOERROR, > "rd": 1, > "tc": 0, > "z": 0 > }, > "question": > { > "qclass": GETDNS_RRCLASS_IN, > "qname": , > "qtype": GETDNS_RRTYPE_AAAA > } > }, > { > "additional": [], > "answer": > [ > { > "class": GETDNS_RRCLASS_IN, > "name": , > "rdata": > { > "ipv4_address": , > "rdata_raw": > }, > "ttl": 10200, > "type": GETDNS_RRTYPE_A > } > ], > "answer_type": GETDNS_NAMETYPE_DNS, > "authority": [], > "canonical_name": , > "header": > { > "aa": 0, > "ad": 0, > "ancount": 1, > "arcount": 0, > "cd": 0, > "id": 36458, > "nscount": 0, > "opcode": GETDNS_OPCODE_QUERY, > "qdcount": 1, > "qr": 1, > "ra": 1, > "rcode": GETDNS_RCODE_NOERROR, > "rd": 1, > "tc": 0, > "z": 0 > }, > "question": > { > "qclass": GETDNS_RRCLASS_IN, > "qname": , > "qtype": GETDNS_RRTYPE_A > } > } > ], > "status": GETDNS_RESPSTATUS_GOOD > } > Response code was: GOOD. Status was: At least one response was returned > > All done. > > > Op 12-05-16 om 19:18 schreef Robert Groenenberg: >> Hi, >> >> I'm using getdns in stub mode with one or more upstream servers >> configured in the context. >> For statistics and logging I'd like to figure out which upstream server >> was actually used for a particular query. Am I correct that that >> information is currently not available, at least not (yet) via the API? >> >> When the user callback is invoked, does context->upstreams->current >> indicate the upstream server that responded, or could it have already >> been changed for another query that has been send out between sending >> the 'current' query and receiving its response? >> >> Thanks, >> Robert >> _______________________________________________ >> spec mailing list >> spec at getdnsapi.net > _______________________________________________ > spec mailing list > spec at getdnsapi.net