[getdns-api] 0.268 srv_addresses not useful

Phillip Hallam-Baker hallam at gmail.com
Thu Jan 31 14:31:45 MST 2013


Sorting the SRV records into order seems wasteful to me. I would prefer to
have a function 'GetNext' that would give me the next service to attempt a
connection to.

I am also somewhat worried about the caching implications since I only want
to cache the record, I do NOT want my client to choose the same service
each time.


The algorithm I have implemented in the past is as follows:

typedef struct _SRVContext {
    int tries = 0;
    int priority = 0 ;
    bool tried [MAX_RECORDS] = FALSE;
    }

int GetSRV (DNSRecord[] records, int number_records, SRVContext context) {
    int     priority = 0xffff;
    int     total = 0;
    for (i=0; i<number_records; i++)  {
        if (! tried [i] ) {
        if (records[i].priority < priority) {
            priority = records[i].priority;
            total = records[i].weight;
            }
        else if if (records[i].priority == priority) {
            total += records[i].weight;
            }
        }
        }
    int choice = RANDOM (total);
    total = 0;
    for (i=0; i<number_records; i++)  {
        if (! tried [i] ) {
        if (records[i].priority == priority) {
           if (records[i].weight; > choice) {
              tried [i] = true;
              return i;
              }
           else {
              choice -= records[i].weight;
              }
        }
        }
    }

The way it would be used is you initialize the context (there would be a
convenience function of course) and then you call GetNext as many times as
you need till you succeed.

If you know a-priori that the number of records is less than 32 or 64 then
you could even use a bitfield to record the tries.


On Thu, Jan 31, 2013 at 2:56 PM, Phil Pennock
<getdns-api-phil at spodhuis.org>wrote:

> On 2013-01-31 at 13:38 -0500, Phillip Hallam-Baker wrote:
> > That is my understanding of the SRV specification.
> >
> > I don't think it makes sense but it isn't the job of this group to change
> > it.
>
> Notably, the fix Paul will make will support what I suspect you think
> makes sense too.
>
> Each application protocol is free to override the default specification
> of how SRV records should be used.
>

Where is that stated?

I think that would be a terrible idea. The discovery process should be
consistent across all protocols so that the infrastructure can know how to
optimize delivery of records etc.

Having different protocols use SRV records in different ways is a layering
violation.

Where I am skeptical about the SRV scheme is that the weight and priority
are both 16 bit integers. So in theory a site could have 65,000 different
priority levels.

I think that is more than a little silly.

In practice there is only really a need for two different priority levels
and the reason that they would be used is that you want to know when all
your production servers have been hosed.


If the getdns-api provides something that provides a fully presorted
> list, then an app which needs to just use one SRV record at each
> priority can easily walk the list, skipping while current-priority is
> the same as previous-priority.  There's a little extra logic in doing a
> full sorting for results which are then discarded, but it's small enough
> that avoiding writing full DNS parsing from scratch as a benefit
> outweighs the cost.
>

The API is not going to provide parsing for each record type? I can't see
the point in the API if it can't do that.

'Parsing' DNS record wireline format is easy enough in C. It is going to be
my next project after I get the object oriented .NET version done.

In most cases the parsing is achieved by simply overlaying a C structure
onto the wireline data. But it needs to be a bit more than that of course
as C uses null terminated strings.

So lets take Paul's favorite record, the definition in the compiler file
for TLSA is:

RR TLSA 52 "TLSA" "RFC6698"
Byte CertificateUsage
Byte Selector
Byte MatchingType
Binary Certificate

This is represented in C# as:

public class DNSRecord_TLSA : DNSRecord {

public byte   CertificateUsage  ;
public byte   Selector  ;
public byte   MatchingType  ;
public byte[]   Certificate  ;
        // accessors and methods go here
        }

The C equivalent structure might look something like this

typedef struct _DNSRecord {
     // stuff
     union {
         byte [] RawData;
         ....
         DNSRecord_TLSA    TLSA;
          } ParsedData;
    }

typedef struct _DNSRecordTLSA {
    byte    CertificateUsage;
    byte    CertificateUsage;
    byte    Selector;
    byte    MatchingType;
    DNSBinary Certificate;
    }

To read the data in the record we call a routine that looks at the record
type and fills out the appropriate structure in the union:

DNSParseRecord (DNSRecord *record)


The C# library has the full whack of methods to encode, decode both the
wireline and presentation formats. But the C library will only be intended
to support application clients and proxy servers so it should not need the
methods to encode record types.



So fixing this supports the spec use-case and the other most obviously
> sane usage, which sounds like an API win to me.
>
> -Phil
> _______________________________________________
> getdns-api mailing list
> getdns-api at vpnc.org
>



-- 
Website: http://hallambaker.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vpnc.org/pipermail/getdns-api/attachments/20130131/a05bd746/attachment-0001.html>


More information about the getdns-api mailing list