00001
00034 #ifndef LL_LLARES_H
00035 #define LL_LLARES_H
00036
00037 #ifdef LL_WINDOWS
00038 # include <ws2tcpip.h>
00039 #endif
00040
00041 #ifdef LL_STANDALONE
00042 # include <ares.h>
00043 #else
00044 # include <ares/ares.h>
00045 #endif
00046
00047 #include "llmemory.h"
00048 #include "lluri.h"
00049
00050 class LLQueryResponder;
00051
00055 enum LLResType
00056 {
00057 RES_INVALID = 0,
00058 RES_A = 1,
00059 RES_NS = 2,
00060 RES_CNAME = 5,
00061 RES_PTR = 12,
00062 RES_AAAA = 28,
00063 RES_SRV = 33,
00064 RES_MAX = 65536
00065 };
00066
00071 class LLDnsRecord : public LLRefCount
00072 {
00073 protected:
00074 friend class LLQueryResponder;
00075
00076 LLResType mType;
00077 std::string mName;
00078 unsigned mTTL;
00079
00080 virtual int parse(const char *buf, size_t len, const char *pos,
00081 size_t rrlen) = 0;
00082
00083 LLDnsRecord(LLResType type, const std::string &name, unsigned ttl);
00084
00085 public:
00089 const std::string &name() const { return mName; }
00090
00094 unsigned ttl() const { return mTTL; }
00095
00099 LLResType type() const { return mType; }
00100 };
00101
00106 class LLAddrRecord : public LLDnsRecord
00107 {
00108 protected:
00109 friend class LLQueryResponder;
00110
00111 LLAddrRecord(LLResType type, const std::string &name, unsigned ttl);
00112
00113 union
00114 {
00115 sockaddr sa;
00116 sockaddr_in sin;
00117 sockaddr_in6 sin6;
00118 } mSA;
00119
00120 socklen_t mSize;
00121
00122 public:
00126 const sockaddr &addr() const { return mSA.sa; }
00127
00131 socklen_t size() const { return mSize; }
00132 };
00133
00138 class LLARecord : public LLAddrRecord
00139 {
00140 protected:
00141 friend class LLQueryResponder;
00142
00143 LLARecord(const std::string &name, unsigned ttl);
00144
00145 int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
00146
00147 public:
00151 const sockaddr_in &addr_in() const { return mSA.sin; }
00152 };
00153
00158 class LLAaaaRecord : public LLAddrRecord
00159 {
00160 protected:
00161 friend class LLQueryResponder;
00162
00163 LLAaaaRecord(const std::string &name, unsigned ttl);
00164
00165 int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
00166
00167 public:
00171 const sockaddr_in6 &addr_in6() const { return mSA.sin6; }
00172 };
00173
00178 class LLHostRecord : public LLDnsRecord
00179 {
00180 protected:
00181 LLHostRecord(LLResType type, const std::string &name, unsigned ttl);
00182
00183 int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
00184
00185 std::string mHost;
00186
00187 public:
00191 const std::string &host() const { return mHost; }
00192 };
00193
00198 class LLCnameRecord : public LLHostRecord
00199 {
00200 protected:
00201 friend class LLQueryResponder;
00202
00203 LLCnameRecord(const std::string &name, unsigned ttl);
00204 };
00205
00210 class LLPtrRecord : public LLHostRecord
00211 {
00212 protected:
00213 friend class LLQueryResponder;
00214
00215 LLPtrRecord(const std::string &name, unsigned ttl);
00216 };
00217
00222 class LLSrvRecord : public LLHostRecord
00223 {
00224 protected:
00225 U16 mPriority;
00226 U16 mWeight;
00227 U16 mPort;
00228
00229 int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
00230
00231 public:
00232 LLSrvRecord(const std::string &name, unsigned ttl);
00233
00237 U16 priority() const { return mPriority; }
00238
00242 U16 weight() const { return mWeight; }
00243
00247 U16 port() const { return mPort; }
00248
00252 struct ComparePriorityLowest
00253 {
00254 bool operator()(const LLSrvRecord& lhs, const LLSrvRecord& rhs)
00255 {
00256 return lhs.mPriority < rhs.mPriority;
00257 }
00258 };
00259 };
00260
00265 class LLNsRecord : public LLHostRecord
00266 {
00267 public:
00268 LLNsRecord(const std::string &name, unsigned ttl);
00269 };
00270
00271 class LLQueryResponder;
00272
00277 class LLAres
00278 {
00279 public:
00285 class HostResponder : public LLRefCount
00286 {
00287 public:
00288 virtual ~HostResponder();
00289
00290 virtual void hostResult(const hostent *ent);
00291 virtual void hostError(int code);
00292 };
00293
00299 class NameInfoResponder : public LLRefCount
00300 {
00301 public:
00302 virtual ~NameInfoResponder();
00303
00304 virtual void nameInfoResult(const char *node, const char *service);
00305 virtual void nameInfoError(int code);
00306 };
00307
00313 class QueryResponder : public LLRefCount
00314 {
00315 public:
00316 virtual ~QueryResponder();
00317
00318 virtual void queryResult(const char *buf, size_t len);
00319 virtual void queryError(int code);
00320 };
00321
00322 class SrvResponder;
00323 class UriRewriteResponder;
00324
00325 LLAres();
00326
00327 ~LLAres();
00328
00333 void cancel();
00334
00342 void getHostByName(const std::string &name, HostResponder *resp,
00343 int family = AF_INET) {
00344 getHostByName(name.c_str(), resp, family);
00345 }
00346
00354 void getHostByName(const char *name, HostResponder *resp,
00355 int family = PF_INET);
00356
00365 void getNameInfo(const struct sockaddr &sa, socklen_t salen, int flags,
00366 NameInfoResponder *resp);
00367
00374 void getSrvRecords(const std::string &name, SrvResponder *resp);
00375
00384 void rewriteURI(const std::string &uri,
00385 UriRewriteResponder *resp);
00386
00394 void search(const std::string &query, LLResType type,
00395 QueryResponder *resp);
00396
00407 bool process(U64 timeoutUsecs = 0);
00408
00415 bool processAll();
00416
00426 static int expandName(const char *encoded, const char *abuf, size_t alen,
00427 std::string &s) {
00428 size_t ignore;
00429 return expandName(encoded, abuf, alen, s, ignore);
00430 }
00431
00432 static int expandName(const char *encoded, const char *abuf, size_t alen,
00433 std::string &s, size_t &enclen);
00434
00438 static const char *strerror(int code);
00439
00440 protected:
00441 ares_channel chan_;
00442
00443 };
00444
00448 typedef std::vector<LLPointer<LLDnsRecord> > dns_rrs_t;
00449
00465 class LLQueryResponder : public LLAres::QueryResponder
00466 {
00467 protected:
00468 int mResult;
00469 std::string mQuery;
00470 LLResType mType;
00471
00472 dns_rrs_t mAnswers;
00473 dns_rrs_t mAuthorities;
00474 dns_rrs_t mAdditional;
00475
00479 int parseRR(const char *buf, size_t len, const char *&pos,
00480 LLPointer<LLDnsRecord> &r);
00484 int parseSection(const char *buf, size_t len,
00485 size_t count, const char *& pos, dns_rrs_t &rrs);
00486
00487 void queryResult(const char *buf, size_t len);
00488 virtual void queryResult();
00489
00490 public:
00491 LLQueryResponder();
00492
00496 bool valid() const { return mResult == ARES_SUCCESS; }
00497
00501 int result() const { return mResult; }
00502
00506 const std::string &query() const { return mQuery; }
00507
00511 const dns_rrs_t &answers() const { return mAnswers; }
00512
00517 const dns_rrs_t &authorities() const { return mAuthorities; }
00518
00523 const dns_rrs_t &additional() const { return mAdditional; }
00524 };
00525
00530 class LLAres::SrvResponder : public LLQueryResponder
00531 {
00532 public:
00533 friend void LLAres::getSrvRecords(const std::string &name,
00534 SrvResponder *resp);
00535 void queryResult();
00536 void queryError(int code);
00537
00538 virtual void srvResult(const dns_rrs_t &ents);
00539 virtual void srvError(int code);
00540 };
00541
00546 class LLAres::UriRewriteResponder : public LLQueryResponder
00547 {
00548 protected:
00549 LLURI mUri;
00550
00551 public:
00552 friend void LLAres::rewriteURI(const std::string &uri,
00553 UriRewriteResponder *resp);
00554 void queryResult();
00555 void queryError(int code);
00556
00557 virtual void rewriteResult(const std::vector<std::string> &uris);
00558 };
00559
00563 extern LLAres *gAres;
00564
00570 extern LLAres *ll_init_ares();
00571
00572 #endif // LL_LLARES_H