mirror of
https://github.com/privacore/open-source-search-engine.git
synced 2025-01-22 02:18:42 -05:00
173 lines
5.1 KiB
C++
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
|