llares.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:14k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llares.h
  3.  * @author Bryan O'Sullivan
  4.  * @date 2007-08-15
  5.  * @brief Wrapper for asynchronous DNS lookups.
  6.  *
  7.  * $LicenseInfo:firstyear=2007&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2007-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #ifndef LL_LLARES_H
  35. #define LL_LLARES_H
  36. #ifdef LL_WINDOWS
  37. // ares.h is broken on windows in that it depends on types defined in ws2tcpip.h
  38. // we need to include them first to work around it, but the headers issue warnings
  39. # pragma warning(push)
  40. # pragma warning(disable:4996)
  41. # include <winsock2.h>
  42. # include <ws2tcpip.h>
  43. # pragma warning(pop)
  44. #endif
  45. #ifdef LL_STANDALONE
  46. # include <ares.h>
  47. #else
  48. # include <ares/ares.h>
  49. #endif
  50. #include "llpointer.h"
  51. #include "llrefcount.h"
  52. #include "lluri.h"
  53. #include <boost/shared_ptr.hpp>
  54. class LLQueryResponder;
  55. class LLAresListener;
  56. /**
  57.  * @brief Supported DNS RR types.
  58.  */
  59. enum LLResType
  60. {
  61. RES_INVALID = 0, /**< Cookie. */
  62. RES_A = 1, /**< "A" record. IPv4 address. */
  63. RES_NS = 2, /**< "NS" record. Authoritative server. */
  64. RES_CNAME = 5, /**< "CNAME" record. Canonical name. */
  65. RES_PTR = 12, /**< "PTR" record. Domain name pointer. */
  66. RES_AAAA = 28, /**< "AAAA" record. IPv6 Address. */
  67. RES_SRV = 33, /**< "SRV" record. Server Selection. */
  68. RES_MAX = 65536 /**< Sentinel; RR types are 16 bits wide. */
  69. };
  70. /**
  71.  * @class LLDnsRecord
  72.  * @brief Base class for all DNS RR types.
  73.  */
  74. class LLDnsRecord : public LLRefCount
  75. {
  76. protected:
  77. friend class LLQueryResponder;
  78. LLResType mType;
  79. std::string mName;
  80. unsigned mTTL;
  81. virtual int parse(const char *buf, size_t len, const char *pos,
  82.   size_t rrlen) = 0;
  83. LLDnsRecord(LLResType type, const std::string &name, unsigned ttl);
  84. public:
  85. /**
  86.  * @brief Record name.
  87.  */
  88. const std::string &name() const { return mName; }
  89. /**
  90.  * @brief Time-to-live value, in seconds.
  91.  */
  92. unsigned ttl() const { return mTTL; }
  93. /**
  94.  * @brief RR type.
  95.  */
  96. LLResType type() const { return mType; }
  97. };
  98. /**
  99.  * @class LLAddrRecord
  100.  * @brief Base class for address-related RRs.
  101.  */
  102. class LLAddrRecord : public LLDnsRecord
  103. {
  104. protected:
  105. friend class LLQueryResponder;
  106. LLAddrRecord(LLResType type, const std::string &name, unsigned ttl);
  107. union 
  108. {
  109. sockaddr sa;
  110. sockaddr_in sin;
  111. sockaddr_in6 sin6;
  112. } mSA;
  113. socklen_t mSize;
  114. public:
  115. /**
  116.  * @brief Generic socket address.
  117.  */
  118. const sockaddr &addr() const { return mSA.sa; }
  119. /**
  120.  * @brief Size of the socket structure.
  121.  */
  122. socklen_t size() const { return mSize; }
  123. };
  124. /**
  125.  * @class LLARecord
  126.  * @brief A RR, for IPv4 addresses.
  127.  */
  128. class LLARecord : public LLAddrRecord
  129. {
  130. protected:
  131. friend class LLQueryResponder;
  132. LLARecord(const std::string &name, unsigned ttl);
  133. int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
  134. public:
  135. /**
  136.  * @brief Socket address.
  137.  */
  138. const sockaddr_in &addr_in() const { return mSA.sin; }
  139. };
  140. /**
  141.  * @class LLAaaaRecord
  142.  * @brief AAAA RR, for IPv6 addresses.
  143.  */
  144. class LLAaaaRecord : public LLAddrRecord
  145. {
  146. protected:
  147. friend class LLQueryResponder;
  148. LLAaaaRecord(const std::string &name, unsigned ttl);
  149. int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
  150. public:
  151. /**
  152.  * @brief Socket address.
  153.  */
  154. const sockaddr_in6 &addr_in6() const { return mSA.sin6; }
  155. };
  156. /**
  157.  * @class LLHostRecord
  158.  * @brief Base class for host-related RRs.
  159.  */
  160. class LLHostRecord : public LLDnsRecord
  161. {
  162. protected:
  163. LLHostRecord(LLResType type, const std::string &name, unsigned ttl);
  164. int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
  165. std::string mHost;
  166. public:
  167. /**
  168.  * @brief Host name.
  169.  */
  170. const std::string &host() const { return mHost; }
  171. };
  172. /**
  173.  * @class LLCnameRecord
  174.  * @brief CNAME RR.
  175.  */
  176. class LLCnameRecord : public LLHostRecord
  177. {
  178. protected:
  179. friend class LLQueryResponder;
  180. LLCnameRecord(const std::string &name, unsigned ttl);
  181. };
  182. /**
  183.  * @class LLPtrRecord
  184.  * @brief PTR RR.
  185.  */
  186. class LLPtrRecord : public LLHostRecord
  187. {
  188. protected:
  189. friend class LLQueryResponder;
  190. LLPtrRecord(const std::string &name, unsigned ttl);
  191. };
  192. /**
  193.  * @class LLSrvRecord
  194.  * @brief SRV RR.
  195.  */
  196. class LLSrvRecord : public LLHostRecord
  197. {
  198. protected:
  199. U16 mPriority;
  200. U16 mWeight;
  201. U16 mPort;
  202. int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
  203. public:
  204. LLSrvRecord(const std::string &name, unsigned ttl);
  205. /**
  206.  * @brief Service priority.
  207.  */
  208. U16 priority() const { return mPriority; }
  209. /**
  210.  * @brief Service weight.
  211.  */
  212. U16 weight() const { return mWeight; }
  213. /**
  214.  * @brief Port number of service.
  215.  */
  216. U16 port() const { return mPort; }
  217. /**
  218.  * @brief Functor for sorting SRV records by priority.
  219.  */
  220. struct ComparePriorityLowest
  221. {
  222. bool operator()(const LLSrvRecord& lhs, const LLSrvRecord& rhs)
  223. {
  224. return lhs.mPriority < rhs.mPriority;
  225. }
  226. };
  227. };
  228. /**
  229.  * @class LLNsRecord
  230.  * @brief NS RR.
  231.  */
  232. class LLNsRecord : public LLHostRecord
  233. {
  234. public:
  235. LLNsRecord(const std::string &name, unsigned ttl);
  236. };
  237. class LLQueryResponder;
  238. /**
  239.  * @class LLAres
  240.  * @brief Asynchronous address resolver.
  241.  */
  242. class LLAres
  243. {
  244. public:
  245.     /**
  246.  * @class HostResponder
  247.  * @brief Base class for responding to hostname lookups.
  248.  * @see LLAres::getHostByName
  249.  */
  250. class HostResponder : public LLRefCount
  251. {
  252. public:
  253. virtual ~HostResponder();
  254. virtual void hostResult(const hostent *ent);
  255. virtual void hostError(int code);
  256. };
  257.     /**
  258.  * @class NameInfoResponder
  259.  * @brief Base class for responding to address lookups.
  260.  * @see LLAres::getNameInfo
  261.  */
  262. class NameInfoResponder : public LLRefCount
  263. {
  264. public:
  265. virtual ~NameInfoResponder();
  266. virtual void nameInfoResult(const char *node, const char *service);
  267. virtual void nameInfoError(int code);
  268. };
  269.     /**
  270.  * @class QueryResponder
  271.  * @brief Base class for responding to custom searches.
  272.  * @see LLAres::search
  273.  */
  274. class QueryResponder : public LLRefCount
  275. {
  276. public:
  277. virtual ~QueryResponder();
  278. virtual void queryResult(const char *buf, size_t len);
  279. virtual void queryError(int code);
  280. };
  281. class SrvResponder;
  282. class UriRewriteResponder;
  283. LLAres();
  284. ~LLAres();
  285. /**
  286.  * Cancel all outstanding requests.  The error methods of the
  287.  * corresponding responders will be called, with ARES_ETIMEOUT.
  288.  */
  289. void cancel();
  290. /**
  291.  * Look up the address of a host.
  292.  *
  293.  * @param name name of host to look up
  294.  * @param resp responder to call with result
  295.  * @param family AF_INET for IPv4 addresses, AF_INET6 for IPv6
  296.  */
  297. void getHostByName(const std::string &name, HostResponder *resp,
  298.    int family = AF_INET) {
  299. getHostByName(name.c_str(), resp, family);
  300. }
  301. /**
  302.  * Look up the address of a host.
  303.  *
  304.  * @param name name of host to look up
  305.  * @param resp responder to call with result
  306.  * @param family AF_INET for IPv4 addresses, AF_INET6 for IPv6
  307.  */
  308. void getHostByName(const char *name, HostResponder *resp,
  309.    int family = PF_INET);
  310. /**
  311.  * Look up the name associated with a socket address.
  312.  *
  313.  * @param sa socket address to look up
  314.  * @param salen size of socket address
  315.  * @param flags flags to use
  316.  * @param resp responder to call with result
  317.  */
  318. void getNameInfo(const struct sockaddr &sa, socklen_t salen, int flags,
  319.  NameInfoResponder *resp);
  320. /**
  321.  * Look up SRV (service location) records for a service name.
  322.  *
  323.  * @param name service name (e.g. "_https._tcp.login.agni.lindenlab.com")
  324.  * @param resp responder to call with result
  325.  */
  326. void getSrvRecords(const std::string &name, SrvResponder *resp);
  327. /**
  328.  * Rewrite a URI, using SRV (service location) records for its
  329.  * protocol if available.  If no SRV records are published, the
  330.  * existing URI is handed to the responder.
  331.  *
  332.  * @param uri URI to rewrite
  333.  * @param resp responder to call with result
  334.  */
  335. void rewriteURI(const std::string &uri,
  336. UriRewriteResponder *resp);
  337. /**
  338.  * Start a custom search.
  339.  *
  340.  * @param query query to make
  341.  * @param type type of query to perform
  342.  * @param resp responder to call with result
  343.  */
  344. void search(const std::string &query, LLResType type,
  345. QueryResponder *resp);
  346. /**
  347.  * Process any outstanding queries.  This method takes an optional
  348.  * timeout parameter (specified in microseconds).  If provided, it
  349.  * will block the calling thread for that length of time to await
  350.  * possible responses. A timeout of zero will return immediately
  351.  * if there are no responses or timeouts to process.
  352.  *
  353.  * @param timeoutUsecs number of microseconds to block before timing out
  354.  * @return whether any responses were processed
  355.  */
  356. bool process(U64 timeoutUsecs = 0);
  357. /**
  358.  * Process all outstanding queries, blocking the calling thread
  359.  * until all have either been responded to or timed out.
  360.  *
  361.  * @return whether any responses were processed
  362.  */
  363. bool processAll();
  364. /**
  365.  * Expand a DNS-encoded compressed string into a normal string.
  366.  *
  367.  * @param encoded the encoded name (null-terminated)
  368.  * @param abuf the response buffer in which the string is embedded
  369.  * @param alen the length of the response buffer
  370.  * @param s the string into which to place the result
  371.  * @return ARES_SUCCESS on success, otherwise an error indicator
  372.  */
  373. static int expandName(const char *encoded, const char *abuf, size_t alen,
  374.   std::string &s) {
  375. size_t ignore;
  376. return expandName(encoded, abuf, alen, s, ignore);
  377. }
  378. static int expandName(const char *encoded, const char *abuf, size_t alen,
  379.   std::string &s, size_t &enclen);
  380. /**
  381.  * Return a string describing an error code.
  382.  */
  383. static const char *strerror(int code);
  384. bool isInitialized(void) { return mInitSuccess; }
  385. protected:
  386. ares_channel chan_;
  387. bool mInitSuccess;
  388.     // boost::scoped_ptr would actually fit the requirement better, but it
  389.     // can't handle incomplete types as boost::shared_ptr can.
  390.     boost::shared_ptr<LLAresListener> mListener;
  391. };
  392. /**
  393.  * An ordered collection of DNS resource records.
  394.  */
  395. typedef std::vector<LLPointer<LLDnsRecord> > dns_rrs_t;
  396. /**
  397.  * @class LLQueryResponder
  398.  * @brief Base class for friendly handling of DNS query responses.
  399.  *
  400.  * This class parses a DNS response and represents it in a friendly
  401.  * manner.
  402.  *
  403.  * @see LLDnsRecord
  404.  * @see LLARecord
  405.  * @see LLNsRecord
  406.  * @see LLCnameRecord
  407.  * @see LLPtrRecord
  408.  * @see LLAaaaRecord
  409.  * @see LLSrvRecord
  410.  */
  411. class LLQueryResponder : public LLAres::QueryResponder
  412. {
  413. protected:
  414. int mResult;
  415. std::string mQuery;
  416. LLResType mType;
  417. dns_rrs_t mAnswers;
  418. dns_rrs_t mAuthorities;
  419. dns_rrs_t mAdditional;
  420. /**
  421.  * Parse a single RR.
  422.  */
  423. int parseRR(const char *buf, size_t len, const char *&pos,
  424. LLPointer<LLDnsRecord> &r);
  425. /**
  426.  * Parse one section of a response.
  427.  */
  428. int parseSection(const char *buf, size_t len,
  429.  size_t count, const char *& pos, dns_rrs_t &rrs);
  430. void queryResult(const char *buf, size_t len);
  431. virtual void querySuccess();
  432. public:
  433. LLQueryResponder();
  434. /**
  435.  * Indicate whether the response could be parsed successfully.
  436.  */
  437. bool valid() const { return mResult == ARES_SUCCESS; }
  438. /**
  439.  * The more detailed result of parsing the response.
  440.  */
  441. int result() const { return mResult; }
  442. /**
  443.  * Return the query embedded in the response.
  444.  */
  445. const std::string &query() const { return mQuery; }
  446. /**
  447.  * Return the contents of the "answers" section of the response.
  448.  */
  449. const dns_rrs_t &answers() const { return mAnswers; }
  450. /**
  451.  * Return the contents of the "authorities" section of the
  452.  * response.
  453.  */
  454. const dns_rrs_t &authorities() const { return mAuthorities; }
  455. /**
  456.  * Return the contents of the "additional records" section of the
  457.  * response.
  458.  */
  459. const dns_rrs_t &additional() const { return mAdditional; }
  460. };
  461. /**
  462.  * @class LLAres::SrvResponder
  463.  * @brief Class for handling SRV query responses.
  464.  */
  465. class LLAres::SrvResponder : public LLQueryResponder
  466. {
  467. public:
  468. friend void LLAres::getSrvRecords(const std::string &name,
  469.   SrvResponder *resp);
  470. void querySuccess();
  471. void queryError(int code);
  472. virtual void srvResult(const dns_rrs_t &ents);
  473. virtual void srvError(int code);
  474. };
  475. /**
  476.  * @class LLAres::UriRewriteResponder
  477.  * @brief Class for handling URI rewrites based on SRV records.
  478.  */
  479. class LLAres::UriRewriteResponder : public LLQueryResponder
  480. {
  481. protected:
  482. LLURI mUri;
  483. public:
  484. friend void LLAres::rewriteURI(const std::string &uri,
  485.    UriRewriteResponder *resp);
  486. void querySuccess();
  487. void queryError(int code);
  488. virtual void rewriteResult(const std::vector<std::string> &uris);
  489. };
  490. /**
  491.  * Singleton responder.
  492.  */
  493. extern LLAres *gAres;
  494. /**
  495.  * Set up the singleton responder.  It's safe to call this more than
  496.  * once from within a single thread, but this function is not
  497.  * thread safe.
  498.  */
  499. extern LLAres *ll_init_ares();
  500. #endif // LL_LLARES_H