along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-// $Id: dnspacket.cc,v 1.14 2003/01/21 10:42:34 ahu Exp $
+// $Id: dnspacket.cc,v 1.15 2003/01/21 15:04:02 ahu Exp $
#include "utility.hh"
#include <cstdio>
d.ancount++;
}
+
+void DNSPacket::addSRVRecord(const DNSResourceRecord &rr)
+{
+ addSRVRecord(rr.qname, rr.content, rr.priority, rr.ttl);
+}
+
+void DNSPacket::addSRVRecord(const string &domain, const string &srv, int priority, u_int32_t ttl)
+{
+ string piece1;
+ toqname(domain,&piece1);
+
+ string target;
+ int weight=0;
+ int port=0;
+
+ vector<string>parts;
+ stringtok(parts,srv);
+ int pleft=parts.size();
+
+ // We need to have exactly 3 parts, so we have to check it!
+ if (pleft<2) {
+ throw AhuException("Missing data for type SRV "+domain);
+ }
+
+ if(pleft)
+ weight = atoi(parts[0].c_str());
+
+ if(pleft>1)
+ port = atoi(parts[1].c_str());
+
+ if(pleft>2)
+ toqname(parts[2],&target);
+
+
+
+ char p[16];
+ makeHeader(p,QType::SRV,ttl);
+
+ p[8]=0;
+ p[9]=0; // need to fill this in
+
+ // start of payload for which we need to specify the length in 8 & 9
+
+ // priority aka preference
+ p[10]=(priority>>8)&0xff;
+ p[11]=priority&0xff;
+
+ // weight
+ p[12]=(weight>>8)&0xff;
+ p[13]=weight&0xff;
+
+ // port
+ p[14]=(port>>8)&0xff;
+ p[15]=port&0xff;
+
+ // target
+ // end of payload
+
+ p[9]=target.length()+6; // fill in length
+
+ stringbuffer+=piece1;
+ stringbuffer.append(p,16);
+ stringbuffer+=target;
+
+ d.ancount++;
+}
+
string &DNSPacket::attodot(string &str)
{
if(str.find_first_of("@")==string::npos)
addAAAARecord(rr);
break;
+ case QType::SRV:
+ addSRVRecord(rr);
+ break;
+
case QType::LOC:
addLOCRecord(rr);
break;
ostringstream o;
int ip;
+ int weight;
+ int port;
switch(rr.qtype.getCode()) {
break;
+ case QType::SRV: // rfc 2025
+ // priority goes into mx-priority
+ rr.priority=(datapos[0] << 8) + datapos[1];
+ // rest glue together
+ weight = (datapos[2] << 8) + datapos[3];
+ port = (datapos[4] << 8) + datapos[5];
+ expand(datapos+offset+6,end,part);
+ rr.content.assign(itoa(weight));
+ rr.content+=" "+itoa(port)+" "+part;
+ break;
+
+
case QType::RP:
offset+=expand(datapos+offset,end,rr.content);
expand(datapos+offset,end,part);
break;
}
else {
- if (strcmp(p, label.data()) == 0)
+ if (strncmp(p, label.data(), label.size()) == 0)
return (p - data);
p += (*p + 1);
}
}
else
{
- if (strcmp(p, label.data()) == 0)
+ if (strncmp(p, label.data(), label.size()) == 0)
{
return (p - data);
}
}
else {
- if (strcmp(p, label.data()) == 0) {
+ if (strncmp(p, label.data(), label.size()) == 0) {
return (p - data);
}
// org
int i = 0;
+ bool containsptr=false;
- while (qname[i] != 0x00) {
+ while (qname[i] != 0x00 && /* qname[i] == 0x00 => i == qname.length */
+ (qname[i] & 0xC0) != 0xC0) { // no use to try to compress offsets
// Get a portion of the name
- string s = qname.substr(i);
+ // qname must include an extra trailing '\0' if it's prefix
+ // is not an offset ptr
+ string s = qname.substr(i); /* s == qname[i..N) */
+ if (!containsptr) s = s + '\0';
+
// Did we see this before?
int offset = findlabel(s);
qname[i + 0] = (char) (((offset | 0xC000) & 0x0000FF00) >> 8);
qname[i + 1] = (char) ((offset | 0xC000) & 0x000000FF);
qname = qname.substr(0, i + 2); // XX setlength() ?
+ containsptr=true;
// qname now consists of unique prefix+known suffix (on location 'offset')
- break;
+ // we managed to make qname shorter, maybe we can do that again
+ i = 0;
+
+ }
+ else { /* offset == -1 */
+ // Move to the next label
+ i += (qname[i] + 1); // doesn't quite handle very long labels
}
- // Move to the next label
- i += (qname[i] + 1);
}
}
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-// $Id: dnspacket.hh,v 1.13 2003/01/13 23:05:15 ahu Exp $
+// $Id: dnspacket.hh,v 1.14 2003/01/21 15:04:02 ahu Exp $
#ifndef DNSPACKET_HH
#define DNSPACKET_HH
void addMXRecord(const string &domain, const string &mx, int priority, u_int32_t ttl); //!< add an MX record to the packet
void addMXRecord(const DNSResourceRecord &); //!< add an MX record to the packet
+ void addSRVRecord(const string &domain, const string &srv, int priority, u_int32_t ttl); //!< add an SRVMX record to the packet
+ void addSRVRecord(const DNSResourceRecord &); //!< add an SRV record to the packet
+
void addCNAMERecord(const string &domain, const string &alias, u_int32_t ttl); //!< add a CNAME record to the packet
void addCNAMERecord(const DNSResourceRecord &); //!< add a CNAME record to the packet
</affiliation>
</author>
- <PubDate>v2.1 $Date: 2003/01/21 10:42:34 $</PubDate>
+ <PubDate>v2.1 $Date: 2003/01/21 15:04:02 $</PubDate>
<Abstract>
<para>
</para>
<para>
The 'Contributor of the Month' award goes to Mark Bergsma who has responded to our plea for help with the label compressor and contributed
- a wonderfully simple and right fix that allows PDNS to compress just as well as Other namerervers out there.
+ a wonderfully simple and right fix that allows PDNS to compress just as well as Other namerervers out there. An honorary mention goes to
+ Ueli Heuer who, despite having no C++ experience, submitted an excellent SRV record implementation.
</para>
<para>
Other changes:
Yet more UltraSPARC alignment issues fixed (Chris Andrews).
</para>
</listitem>
+ <listitem>
+ <para>
+ Label compression was improved so we can now fit all . records in 436 bytes, this used to be 460! (Code & formal
+ proof of correctness by Mark Bergsma).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SRV support (incoming and outgoing), submitted by Ueli Heuer.
+ </para>
+ </listitem>
</itemizedlist>
</para>
</sect2>
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>SRV</term>
+ <listitem>
+ <para>
+ SRV records can be used to encode the location and port of services on a domain name. When encoding, the priority field
+ is used to encode the priority. For example, '_ldap._tcp.dc._msdcs.conaxis.ch SRV 0 100 389 mars.conaxis.ch' would be
+ encoded with 0 in the priorit field and '100 389 mars.conaxis.ch' in the tontent field.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>TXT</term>
<listitem>
#ifndef QTYPE_HH
#define QTYPE_HH
/* (C) 2002 POWERDNS.COM BV */
-// $Id: qtype.hh,v 1.3 2003/01/21 10:42:34 ahu Exp $
+// $Id: qtype.hh,v 1.4 2003/01/21 15:04:02 ahu Exp $
#include <string>
#include <vector>
#include <utility>
static int chartocode(const char *p); //!< convert a character string to a code
- enum {A=1,NS=2,CNAME=5,SOA=6,PTR=12,HINFO=13,MX=15,TXT=16,RP=17,AAAA=28,LOC=29,NAPTR=35,AXFR=252, ANY=255} types;
+ enum {A=1,NS=2,CNAME=5,SOA=6,PTR=12,HINFO=13,MX=15,TXT=16,RP=17,AAAA=28,LOC=29,SRV=33,NAPTR=35,AXFR=252, ANY=255} types;
private:
short int code;
typedef pair<string,int> namenum;