privacore-open-source-searc.../DnsProtocol.h
2016-09-26 15:37:13 +02:00

173 lines
5.1 KiB
C++

// Matt Wells, copyright Mar 2001
#ifndef GB_DNSPROTOCOL_H
#define GB_DNSPROTOCOL_H
#include "UdpProtocol.h"
#include "UdpSlot.h"
// DNS request datagram (in network/bigEndian order):
//
// unsigned id: 16;
//
// // fields in third byte
//
// unsigned qr: 1; /* response flag */
// unsigned opcode: 4; /* purpose of message */
// unsigned aa: 1; /* authoritative answer */
// unsigned tc: 1; /* truncated message */
// unsigned rd: 1; /* recursion desired */
//
// // fields in fourth byte
//
// unsigned ra: 1; /* recursion available */
// unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
// unsigned ad: 1; /* authentic data from named */
// unsigned cd: 1; /* checking disabled by resolver */
// unsigned rcode :4; /* response code */
// unsigned qdcount :16; /* number of question entries */
// unsigned ancount :16; /* number of answer entries */
// unsigned nscount :16; /* number of authority entries */
// unsigned arcount :16; /* number of resource entries */
//
// // query record/entry
//
// CCLLLLLL L = length of label, C = compressed?
// ssssssss ........ s = label (or next 8 bits of offset if C is true)
// ........
// CCLLLLLL L = length of label, C = compressed?
// ssssssss ........ s = label (or next 8 bits of offset if C is true)
// 00000000 0 = zero, no more labels
// tttttttt tttttttt t = queryType
// cccccccc cccccccc c = queryClass
//
// // other records/entries
//
// CCLLLLLL L = length of label, C = compressed?
// ssssssss ........ s = label (or next 8 bits of offset if C is true)
// ........
// CCLLLLLL L = length of label, C = compressed?
// ssssssss ........ s = label (or next 8 bits of offset if C is true)
// 00000000 0 = zero, no more labels
// tttttttt tttttttt t = queryType
// cccccccc cccccccc c = queryClass
// TTTTTTTT TTTTTTTT T = time to live (TTL)
// TTTTTTTT TTTTTTTT
// rrrrrrrr rrrrrrrr r = resource data len
// dddddddd ........ d = resource data
class DnsProtocol : public UdpProtocol {
public:
DnsProtocol() {
}
virtual ~DnsProtocol() {
}
// override some protocol-depenent datagram parsing funcs
// override these 4 functions to suit your own protocol
virtual int32_t getTransId( const char *peek, int32_t /*peekSize*/ ) {
return ntohs( *(int16_t *)( peek ) );
}
// we never use acks in dns land
virtual bool useAcks() {
return false;
}
// this is the reply/response bit in dns-land
virtual bool isReply( const char *peek, int32_t peekSize ) {
if ( peekSize < 4 )
return true;
return peek[2] & 0x80;
}
virtual bool didWeInitiate( const char * peek, int32_t peekSize ) {
return !isReply( peek, peekSize );
}
virtual bool hadError( const char * /*peek*/, int32_t /*peekSize*/ ) {
return false;
}
// should we remove headers from the UdpSlot::m_readBuf ?
virtual bool stripHeaders() {
return false;
}
// first 4 bytes should have the info we need for DNS reply processing
virtual int32_t getMaxPeekSize() {
return 4;
}
// . do we have errnos in a dns reply?
// . TODO: investigate this
// . returns 0 if hadError bit is NOT set
// . otherwise, returns first 4 bytes of msg CONTENT as an errno
virtual int32_t getErrno( const char * /*peek*/, int32_t /*peekSize*/ ) {
return 0;
}
// we don't use acks
virtual bool isAck( const char * /*peek*/, int32_t /*peekSize*/ ) {
return false;
}
// we don't cancel signals
virtual bool isCancelTrans( const char * /*peek*/, int32_t /*peekSize*/ ) {
return false;
}
virtual bool isNice( const char * /*peek*/, int32_t /*peekSize*/ ) {
return true;
}
// we never use more than 1 udp dgram for dns
virtual int32_t getDgramNum( const char * /*peek*/, int32_t /*peekSize*/ ) {
return 0;
}
// . even though it may be less than this, we can assume it's full
// . returns -1 if msg size is the length of the whole dgram
virtual int32_t getMsgSize( const char * /*peek*/, int32_t /*peekSize*/ ) {
return -1;
}
// how many dgram in the msg?
virtual int32_t getNumDgrams( int32_t /*msgSize*/, int32_t /*maxDgramSize*/ ) {
return 1;
}
// TODO: i guess all msg types are 0 for now
virtual unsigned char getMsgType( const char * /*peek*/, int32_t /*peekSize*/ ) {
return 0;
}
// consider for our purposes to be 0
virtual int32_t getHeaderSize( const char * /*peek*/, int32_t /*peekSize*/ ) {
return 0;
}
// given a msg to send, how big is the header?
virtual int32_t getHeaderSize( int32_t /*msgSize*/ ) {
return 0;
}
virtual int32_t getMaxMsgSize() {
return DGRAM_SIZE_DNS;
}
// we don't make Acks so return a dgramSize of 0
virtual int32_t makeAck( char * /*dgram*/, int32_t /*dgramNum*/, int32_t /*transId*/, bool /*weInitiated*/,
bool /*cancelTrans*/ ) {
return 0;
}
// we store the 1 dgram in it's ready to send form
virtual void setHeader( char * /*buf*/, int32_t /*msgSize*/, unsigned char /*msgType*/, int32_t /*dgramNum*/,
int32_t /*transId*/, bool /*weInitiated*/, bool /*hadError*/, int32_t /*niceness*/ ) {
return;
}
};
#endif // GB_DNSPROTOCOL_H