| 1 |
/* |
|---|
| 2 |
* Copyright (C) 2005-2006 Alo Sarv <madcat_@users.sourceforge.net> |
|---|
| 3 |
* |
|---|
| 4 |
* This program is free software; you can redistribute it and/or modify |
|---|
| 5 |
* it under the terms of the GNU General Public License as published by |
|---|
| 6 |
* the Free Software Foundation; either version 2 of the License, or |
|---|
| 7 |
* (at your option) any later version. |
|---|
| 8 |
* |
|---|
| 9 |
* This program is distributed in the hope that it will be useful, |
|---|
| 10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 |
* GNU General Public License for more details. |
|---|
| 13 |
* |
|---|
| 14 |
* You should have received a copy of the GNU General Public License |
|---|
| 15 |
* along with this program; if not, write to the Free Software |
|---|
| 16 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 17 |
*/ |
|---|
| 18 |
|
|---|
| 19 |
#ifndef __HOSTINFO_H__ |
|---|
| 20 |
#define __HOSTINFO_H__ |
|---|
| 21 |
|
|---|
| 22 |
/** |
|---|
| 23 |
* \file hostinfo.h Interface for Hydranode Resolver API |
|---|
| 24 |
*/ |
|---|
| 25 |
|
|---|
| 26 |
#include <hnbase/osdep.h> |
|---|
| 27 |
#include <hnbase/event.h> |
|---|
| 28 |
#include <hnbase/ipv4addr.h> |
|---|
| 29 |
#include <hnbase/workthread.h> |
|---|
| 30 |
#include <hnbase/timed_callback.h> |
|---|
| 31 |
#include <string> |
|---|
| 32 |
|
|---|
| 33 |
#ifdef WIN32 |
|---|
| 34 |
#include <winsock2.h> |
|---|
| 35 |
#else |
|---|
| 36 |
#include <netdb.h> |
|---|
| 37 |
#include <netinet/in.h> |
|---|
| 38 |
#include <arpa/inet.h> |
|---|
| 39 |
#endif |
|---|
| 40 |
|
|---|
| 41 |
/** |
|---|
| 42 |
* Contains information about hosts, which is filled by process() [blocking] |
|---|
| 43 |
* method. Generally, process() will be called in a secondary thread. |
|---|
| 44 |
*/ |
|---|
| 45 |
class HNBASE_EXPORT HostInfo : public ThreadWork { |
|---|
| 46 |
public: |
|---|
| 47 |
enum ErrorState { |
|---|
| 48 |
HI_NOERROR = 0, |
|---|
| 49 |
HI_NOTFOUND = HOST_NOT_FOUND, |
|---|
| 50 |
HI_NODATA = NO_ADDRESS, |
|---|
| 51 |
HI_NORECOVERY = NO_DATA, |
|---|
| 52 |
HI_TRYAGAIN = TRY_AGAIN |
|---|
| 53 |
}; |
|---|
| 54 |
typedef std::vector<IPV4Address>::const_iterator Iter; |
|---|
| 55 |
typedef boost::function<void (HostInfo)> HandlerType; |
|---|
| 56 |
|
|---|
| 57 |
HostInfo(const std::string &name, HandlerType); |
|---|
| 58 |
HostInfo(const HostInfo &h); |
|---|
| 59 |
HostInfo& operator=(const HostInfo &h); |
|---|
| 60 |
|
|---|
| 61 |
bool process(); |
|---|
| 62 |
|
|---|
| 63 |
Iter begin() const { return m_addrList.begin(); } |
|---|
| 64 |
Iter end() const { return m_addrList.end(); } |
|---|
| 65 |
size_t size() const { return m_addrList.size(); } |
|---|
| 66 |
std::string getName() const { return m_name; } |
|---|
| 67 |
std::vector<std::string> getAliases() const { return m_aliasList; } |
|---|
| 68 |
std::vector<IPV4Address> getAddresses() const { return m_addrList; } |
|---|
| 69 |
ErrorState error() const { return m_error; } |
|---|
| 70 |
std::string errorMsg() const { return m_errorMsg; } |
|---|
| 71 |
|
|---|
| 72 |
private: |
|---|
| 73 |
std::vector<IPV4Address> m_addrList; |
|---|
| 74 |
std::vector<std::string> m_aliasList; |
|---|
| 75 |
std::string m_name; |
|---|
| 76 |
ErrorState m_error; |
|---|
| 77 |
std::string m_errorMsg; |
|---|
| 78 |
HandlerType m_handler; |
|---|
| 79 |
}; |
|---|
| 80 |
|
|---|
| 81 |
namespace DNS { |
|---|
| 82 |
/** |
|---|
| 83 |
* Worker thread that performs DNS lookups using blocking API calls. |
|---|
| 84 |
*/ |
|---|
| 85 |
class HNBASE_EXPORT ResolverThread : public WorkThread { |
|---|
| 86 |
public: |
|---|
| 87 |
ResolverThread(); |
|---|
| 88 |
static ResolverThread& instance(); |
|---|
| 89 |
std::string error(HostInfo::ErrorState err) { |
|---|
| 90 |
return m_errors[err]; |
|---|
| 91 |
} |
|---|
| 92 |
private: |
|---|
| 93 |
std::map<HostInfo::ErrorState, std::string> m_errors; |
|---|
| 94 |
}; |
|---|
| 95 |
|
|---|
| 96 |
/** |
|---|
| 97 |
* Perform a DNS name-to-address lookup. |
|---|
| 98 |
* |
|---|
| 99 |
* @param name Name to be looked up, e.g. "www.google.com" |
|---|
| 100 |
* @param handler Function that takes HostInfo argument |
|---|
| 101 |
* |
|---|
| 102 |
* \note handler function is called even when DNS lookup fails. Make |
|---|
| 103 |
* sure to test HostInfo::error() for error conditions. |
|---|
| 104 |
*/ |
|---|
| 105 |
inline void lookup( |
|---|
| 106 |
const std::string &name, HostInfo::HandlerType handler |
|---|
| 107 |
) { |
|---|
| 108 |
CHECK_RET(name.size()); |
|---|
| 109 |
CHECK_RET(handler); |
|---|
| 110 |
ThreadWorkPtr job(new HostInfo(name, handler)); |
|---|
| 111 |
ResolverThread::instance().postWork(job); |
|---|
| 112 |
} |
|---|
| 113 |
|
|---|
| 114 |
/** |
|---|
| 115 |
* Overloaded version of the above, provided for convenience. |
|---|
| 116 |
*/ |
|---|
| 117 |
template<typename T> |
|---|
| 118 |
inline void lookup( |
|---|
| 119 |
const std::string &name, T *obj, void (T::*handler)(HostInfo) |
|---|
| 120 |
) { |
|---|
| 121 |
CHECK_RET(obj); |
|---|
| 122 |
CHECK_RET(handler); |
|---|
| 123 |
lookup(name, boost::bind(handler, obj, _1)); |
|---|
| 124 |
} |
|---|
| 125 |
} |
|---|
| 126 |
|
|---|
| 127 |
#endif |
|---|