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