Skip to content

Commit

Permalink
In process of pushing much of the DNS client functionaity into the Op…
Browse files Browse the repository at this point in the history
…enNICDnsQuery class such that that query is able to operate independent of the initiator.
  • Loading branch information
8bitgeek committed Mar 3, 2012
1 parent 82d50dc commit 597f126
Show file tree
Hide file tree
Showing 11 changed files with 338 additions and 156 deletions.
88 changes: 44 additions & 44 deletions server/opennicdnsclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ OpenNICDnsClient::~OpenNICDnsClient()
close();
for(int n=0; n < mQueries.count(); n++)
{
dns_query* q = mQueries.takeAt(0);
OpenNICDnsQuery* q = mQueries.takeAt(0);
delete q;
}
mQueries.clear();
Expand All @@ -41,9 +41,9 @@ OpenNICDnsClient::~OpenNICDnsClient()
/**
* @brief assemble a reply packet and emit it through the reply() sinal
*/
void OpenNICDnsClient::doReply(dns_query* q, dns_error error)
void OpenNICDnsClient::doReply(OpenNICDnsQuery* q, OpenNICDnsQuery::DNSError error)
{
q->error = error;
q->setError(error);
reply(*q);
}

Expand Down Expand Up @@ -104,11 +104,11 @@ void OpenNICDnsClient::purge()
QDateTime now = QDateTime::currentDateTime();
for(int n=0; n < mQueries.count(); n++ )
{
dns_query* q = mQueries.at(n);
if ( q->expire < now )
OpenNICDnsQuery* q = mQueries.at(n);
if ( q->expireTime() < now )
{
q->addr.clear();
doReply(q,DNS_TIMEOUT);
q->addr().clear();
doReply(q,OpenNICDnsQuery::DNS_TIMEOUT);
disposeQuery(q);
}
}
Expand All @@ -117,15 +117,15 @@ void OpenNICDnsClient::purge()
/**
* @brief Append an active query to the list of active queries.
*/
void OpenNICDnsClient::appendActiveQuery(dns_query* q)
void OpenNICDnsClient::appendActiveQuery(OpenNICDnsQuery* q)
{
mQueries.append(q);
}

/**
* @brief Dispose a query.
*/
void OpenNICDnsClient::disposeQuery(dns_query *q)
void OpenNICDnsClient::disposeQuery(OpenNICDnsQuery *q)
{
int n = mQueries.indexOf(q);
if ( n >= 0 )
Expand All @@ -138,12 +138,12 @@ void OpenNICDnsClient::disposeQuery(dns_query *q)
* @brief Match a tid to a pending query.
* @return the query or NULL.
*/
dns_query* OpenNICDnsClient::findActiveQuery(quint16 tid)
OpenNICDnsQuery* OpenNICDnsClient::findActiveQuery(quint16 tid)
{
for(int n=0; n < mQueries.count(); n++)
{
dns_query* q = mQueries.at(n);
if (tid == q->tid)
OpenNICDnsQuery* q = mQueries.at(n);
if (tid == q->tid())
{
return q;
}
Expand Down Expand Up @@ -188,14 +188,14 @@ void OpenNICDnsClient::fetch(const quint8 *pkt, const quint8 *s, int pktsiz, cha
*/
void OpenNICDnsClient::processDatagram(QByteArray& datagram)
{
quint8* pkt = (quint8*)datagram.data();
int len = datagram.length();
header* pkt_hdr;
const quint8 *p, *e, *s;
dns_query* q;
quint16 type;
char name[1025];
int found, stop, dlen, nlen;
quint8* pkt = (quint8*)datagram.data();
int len = datagram.length();
header* pkt_hdr;
const quint8 *p, *e, *s;
OpenNICDnsQuery* q;
quint16 type;
char name[1025];
int found, stop, dlen, nlen;

/* We sent 1 query. We want to see more that 1 answer. */
pkt_hdr = (header *) pkt;
Expand All @@ -208,8 +208,8 @@ void OpenNICDnsClient::processDatagram(QByteArray& datagram)

/* Received 0 answers */
if (pkt_hdr->nanswers == 0) {
q->addr.clear();
doReply(q, DNS_DOES_NOT_EXIST);
q->addr().clear();
doReply(q, OpenNICDnsQuery::DNS_DOES_NOT_EXIST);
return;
}

Expand All @@ -220,7 +220,7 @@ void OpenNICDnsClient::processDatagram(QByteArray& datagram)
#define NTOHS(p) (((p)[0] << 8) | (p)[1])

/* We sent query class 1, query type 1 */
if (&p[5] > e || NTOHS(p + 1) != q->query_type)
if (&p[5] > e || NTOHS(p + 1) != q->queryType())
return;

/* Go to the first answer section */
Expand All @@ -242,7 +242,7 @@ void OpenNICDnsClient::processDatagram(QByteArray& datagram)
/* CNAME answer. shift to the next section */
dlen = htons(((uint16_t *) p)[5]);
p += 12 + dlen;
} else if (type == q->query_type) {
} else if (type == q->queryType()) {
found = stop = 1;
} else {
stop = 1;
Expand All @@ -256,17 +256,17 @@ void OpenNICDnsClient::processDatagram(QByteArray& datagram)
if (p + dlen <= e) {

/* Call user */
if (q->query_type == DNS_MX_RECORD)
if (q->queryType() == OpenNICDnsQuery::DNS_MX_RECORD)
{
fetch((quint8*)pkt_hdr, p + 2, len, name, sizeof(name) - 1);
p = (const unsigned char *)name;
dlen = strlen(name);
QByteArray mx((const char*)p,dlen);
q->mxName.append(mx);
doReply(q, DNS_OK);
q->mxName().append(mx);
doReply(q, OpenNICDnsQuery::DNS_OK);
disposeQuery(q);
}
else if (q->query_type == DNS_A_RECORD)
else if (q->queryType() == OpenNICDnsQuery::DNS_A_RECORD)
{
QByteArray addr((const char*)p,dlen);
if (dlen >= 4)
Expand All @@ -276,19 +276,19 @@ void OpenNICDnsClient::processDatagram(QByteArray& datagram)
QString::number((quint8)addr[1])+"."+
QString::number((quint8)addr[2])+"."+
QString::number((quint8)addr[3]);
q->addr.setAddress(sAddr);
doReply(q, DNS_OK);
q->addr().setAddress(sAddr);
doReply(q, OpenNICDnsQuery::DNS_OK);
disposeQuery(q);
}
else
{
doReply(q,DNS_ERROR);
doReply(q,OpenNICDnsQuery::DNS_ERROR);
disposeQuery(q);
}
}
else
{
doReply(q,DNS_ERROR);
doReply(q,OpenNICDnsQuery::DNS_ERROR);
disposeQuery(q);
}
}
Expand All @@ -303,7 +303,7 @@ void OpenNICDnsClient::processDatagram(QByteArray& datagram)
* @param port the port address at the resolver
* @return Resultes are emitted by the reply() signal.
*/
void OpenNICDnsClient::lookup(QHostAddress resolverAddress, OpenNICDomainName name, dns_query_type type, quint16 port)
void OpenNICDnsClient::lookup(QHostAddress resolverAddress, OpenNICDomainName name, OpenNICDnsQuery::DNSQueryType type, quint16 port)
{
setResolver(resolverAddress);
lookup(name,type,port);
Expand All @@ -316,15 +316,15 @@ void OpenNICDnsClient::lookup(QHostAddress resolverAddress, OpenNICDomainName na
* @param port the port address at the resolver
* @return Results are emitted by the reply() signal.
*/
void OpenNICDnsClient::lookup(OpenNICDomainName name, dns_query_type qtype, quint16 port)
void OpenNICDnsClient::lookup(OpenNICDomainName name, OpenNICDnsQuery::DNSQueryType qtype, quint16 port)
{
dns_query* q;
OpenNICDnsQuery* q;

if ( !isOpen() )
{
open();
}
if ( isOpen() && (q = new dns_query) != NULL )
if ( isOpen() && (q = new OpenNICDnsQuery()) != NULL )
{
QDateTime now = QDateTime::currentDateTime();

Expand All @@ -334,14 +334,14 @@ void OpenNICDnsClient::lookup(OpenNICDomainName name, dns_query_type qtype, quin
const char* s;

/* Init query structure */
q->query_type = qtype;
q->tid = ++m_tid;
q->expire = now.addSecs(DNS_QUERY_TIMEOUT);
q->name = name;
q->setQueryType(qtype);
q->setTid(++m_tid);
q->setExpireTime(now.addSecs(DNS_QUERY_TIMEOUT));
q->setName(name);

/* Prepare DNS packet header */
pkt_hdr = (header*)pkt;
pkt_hdr->tid = q->tid;
pkt_hdr->tid = q->tid();
pkt_hdr->flags = htons(0x100); /* Haha. guess what it is */
pkt_hdr->nqueries = htons(1); /* Just one query */
pkt_hdr->nanswers = 0;
Expand Down Expand Up @@ -382,22 +382,22 @@ void OpenNICDnsClient::lookup(OpenNICDomainName name, dns_query_type qtype, quin

if ( !(p < pkt + sizeof(pkt)) )
{
doReply(q,DNS_ERROR);
doReply(q,OpenNICDnsQuery::DNS_ERROR);
return;
}
n = p - pkt; /* Total packet length */

QByteArray datagram(pkt,n);
if ( mClientSocket->writeDatagram(datagram,resolverAddress(),port) < 0 )
{
doReply(q,DNS_ERROR);
doReply(q,OpenNICDnsQuery::DNS_ERROR);
delete q;
}
appendActiveQuery(q);
}
else
{
doReply(q,DNS_ERROR);
doReply(q,OpenNICDnsQuery::DNS_ERROR);
delete q;
return;
}
Expand Down
67 changes: 10 additions & 57 deletions server/opennicdnsclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <QTimerEvent>

#include "opennicdomainname.h"
#include "opennicdnsquery.h"

#define DNS_QUERY_TIMEOUT 30 /* Query timeout, seconds */
#define DNS_MAX 1025 /* Maximum host name */
Expand All @@ -46,28 +47,16 @@ class OpenNICDnsClient : public QObject
quint8 data[1]; /* Data, variable length */
} header;

typedef enum {
DNS_A_RECORD = 0x01, /* Lookup IP adress for host */
DNS_MX_RECORD = 0x0f /* Lookup MX for domain */
} dns_query_type;

/*
* User defined function that will be called when DNS reply arrives for
* requested hostname. "struct dns_cb_data" is passed to the user callback,
* which has an error indicator, resolved address, etc.
*/

typedef enum {
DNS_OK, /* No error */
DNS_DOES_NOT_EXIST, /* Error: adress does not exist */
DNS_TIMEOUT, /* Lookup time expired */
DNS_ERROR /* No memory or other error */
} dns_error;

OpenNICDnsClient(bool active=true, QObject *parent = 0);
virtual ~OpenNICDnsClient();
bool isActive() {return mActive;}
dns_query* find(void* context);
OpenNICDnsQuery* find(void* context);
public slots:
virtual void setActive(bool active) {mActive=active;}

Expand All @@ -78,63 +67,27 @@ class OpenNICDnsClient : public QObject
bool isOpen() {return mClientSocket != NULL; }
bool open();
void close();
virtual void lookup(QHostAddress resolverAddress, OpenNICDomainName name, dns_query_type qtype, quint16 port=DEFAULT_DNS_PORT);
virtual void lookup(OpenNICDomainName name, dns_query_type qtype, quint16 port=DEFAULT_DNS_PORT);
virtual void reply(dns_query& data) {}
virtual void lookup(QHostAddress resolverAddress, OpenNICDomainName name, OpenNICDnsQuery::DNSQueryType qtype, quint16 port=DEFAULT_DNS_PORT);
virtual void lookup(OpenNICDomainName name, OpenNICDnsQuery::DNSQueryType qtype, quint16 port=DEFAULT_DNS_PORT);
virtual void reply(OpenNICDnsQuery& data) {}

private slots:
void readPendingDatagrams();

private:
void appendActiveQuery(dns_query* q);
dns_query* findActiveQuery(quint16 tid);
void disposeQuery(dns_query* q);
void appendActiveQuery(OpenNICDnsQuery* q);
OpenNICDnsQuery* findActiveQuery(quint16 tid);
void disposeQuery(OpenNICDnsQuery* q);
void fetch(const quint8 *pkt, const quint8 *s, int pktsiz, char *dst, int dstlen);
void doReply(dns_query* q, dns_error error);
void doReply(OpenNICDnsQuery* q, OpenNICDnsQuery::DNSError error);
void processDatagram(QByteArray& datagram);
bool mActive;
quint16 m_tid; /* Latest tid used */
QHostAddress mResolverAddress; /* The resolver address */
QUdpSocket* mClientSocket; /* UDP socket used for queries */
QList<dns_query*> mQueries; /* In-flight queries */
QList<OpenNICDnsQuery*> mQueries; /* In-flight queries */
};

/*
* User query. Holds mapping from application-level ID to DNS transaction id,
* and user defined callback function.
*/
class dns_query {
public:
dns_query()
: latency(NULL)
, error(OpenNICDnsClient::DNS_OK)
, query_type(OpenNICDnsClient::DNS_A_RECORD)
, tid(0)
{}
dns_query(const dns_query& other)
{
latency = other.latency;
error = other.error;
query_type = other.query_type;
tid = other.tid;
start = other.start;
expire = other.expire;
name = other.name;
addr = other.addr;
mxName = other.mxName;
}
~dns_query() {}
QDateTime end() {return start.addMSecs(latency);}
quint64 latency; /* latency in milliseconds */
OpenNICDnsClient::dns_error error; /* Result code */
OpenNICDnsClient::dns_query_type query_type; /* Query type */
quint16 tid; /* UDP DNS transaction ID */
QDateTime start; /* The start of the query */
QDateTime expire; /* Time when this query expire */
OpenNICDomainName name; /* Host name */
QHostAddress addr; /* Host address */
QString mxName; /* MX record host name. */
};


#endif // OPENNICDNSCLIENT_H
Loading

0 comments on commit 597f126

Please sign in to comment.