00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef _WIN32
00031 #pragma warning(disable:4786)
00032 #else
00033 #include <netdb.h>
00034 #endif
00035 #include "ResolvSocket.h"
00036 #ifdef ENABLE_RESOLVER
00037 #include "Utility.h"
00038 #include "Parse.h"
00039 #include "ISocketHandler.h"
00040
00041 #ifdef SOCKETS_NAMESPACE
00042 namespace SOCKETS_NAMESPACE {
00043 #endif
00044
00045 #ifdef _DEBUG
00046 #define DEB(x) x
00047 #else
00048 #define DEB(x)
00049 #endif
00050
00051
00052 ResolvSocket::ResolvSocket(ISocketHandler& h,Socket *parent)
00053 :TcpSocket(h)
00054 ,m_bServer(false)
00055 ,m_parent(parent)
00056 #ifdef ENABLE_IPV6
00057 ,m_resolve_ipv6(false)
00058 #endif
00059 {
00060 SetLineProtocol();
00061 }
00062
00063
00064 ResolvSocket::~ResolvSocket()
00065 {
00066 }
00067
00068
00069 void ResolvSocket::OnLine(const std::string& line)
00070 {
00071 Parse pa(line, ":");
00072 if (m_bServer)
00073 {
00074 m_query = pa.getword();
00075 m_data = pa.getrest();
00076 DEB( fprintf(stderr, "ResolvSocket server; query=%s, data=%s\n", m_query.c_str(), m_data.c_str());)
00077 if (!Detach())
00078 {
00079 SetCloseAndDelete();
00080 }
00081 return;
00082 }
00083 std::string key = pa.getword();
00084 std::string value = pa.getrest();
00085
00086 if (key == "Failed" && m_parent)
00087 {
00088 DEB( fprintf(stderr, "************ Resolve failed\n");)
00089 if (Handler().Valid(m_parent))
00090 m_parent -> OnResolveFailed(m_resolv_id);
00091 m_parent = NULL;
00092 }
00093 else
00094 if (key == "Name" && !m_resolv_host.size() && m_parent)
00095 {
00096 if (Handler().Valid(m_parent))
00097 m_parent -> OnReverseResolved(m_resolv_id, value);
00098 m_parent = NULL;
00099 }
00100 else
00101 if (key == "A" && m_parent)
00102 {
00103 ipaddr_t l;
00104 Utility::u2ip(value, l);
00105 if (Handler().Valid(m_parent))
00106 m_parent -> OnResolved(m_resolv_id, l, m_resolv_port);
00107 m_parent = NULL;
00108 }
00109 #ifdef ENABLE_IPV6
00110 #ifdef IPPROTO_IPV6
00111 else
00112 if (key == "AAAA" && m_parent)
00113 {
00114 in6_addr a;
00115 Utility::u2ip(value, a);
00116 if (Handler().Valid(m_parent))
00117 m_parent -> OnResolved(m_resolv_id, a, m_resolv_port);
00118 m_parent = NULL;
00119 }
00120 #endif
00121 #endif
00122 }
00123
00124
00125 void ResolvSocket::OnDetached()
00126 {
00127 DEB( fprintf(stderr, "ResolvSocket::OnDetached(); query=%s, data=%s\n", m_query.c_str(), m_data.c_str());)
00128 if (m_query == "gethostbyname")
00129 {
00130 struct sockaddr_in sa;
00131 if (Utility::u2ip(m_data, sa))
00132 {
00133 std::string ip;
00134 Utility::l2ip(sa.sin_addr, ip);
00135 Send("A: " + ip + "\n");
00136 }
00137 else
00138 {
00139 Send("Failed\n");
00140 }
00141 Send("\n");
00142 }
00143 else
00144 #ifdef ENABLE_IPV6
00145 #ifdef IPPROTO_IPV6
00146 if (m_query == "gethostbyname2")
00147 {
00148 struct sockaddr_in6 sa;
00149 if (Utility::u2ip(m_data, sa))
00150 {
00151 std::string ip;
00152 Utility::l2ip(sa.sin6_addr, ip);
00153 Send("AAAA: " + ip + "\n");
00154 }
00155 else
00156 {
00157 Send("Failed\n");
00158 }
00159 Send("\n");
00160 }
00161 else
00162 #endif
00163 #endif
00164 if (m_query == "gethostbyaddr")
00165 {
00166 if (Utility::isipv4( m_data ))
00167 {
00168 struct sockaddr_in sa;
00169 if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST))
00170 {
00171 Send("Failed: convert to sockaddr_in failed\n");
00172 }
00173 else
00174 {
00175 std::string name;
00176 if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name))
00177 {
00178 Send("Failed: ipv4 reverse lookup of " + m_data + "\n");
00179 }
00180 else
00181 {
00182 Send("Name: " + name + "\n");
00183 }
00184 }
00185 }
00186 else
00187 #ifdef ENABLE_IPV6
00188 #ifdef IPPROTO_IPV6
00189 if (Utility::isipv6( m_data ))
00190 {
00191 struct sockaddr_in6 sa;
00192 if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST))
00193 {
00194 Send("Failed: convert to sockaddr_in6 failed\n");
00195 }
00196 else
00197 {
00198 std::string name;
00199 if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name))
00200 {
00201 Send("Failed: ipv6 reverse lookup of " + m_data + "\n");
00202 }
00203 else
00204 {
00205 Send("Name: " + name + "\n");
00206 }
00207 }
00208 }
00209 else
00210 #endif
00211 #endif
00212 {
00213 Send("Failed: malformed address\n");
00214 }
00215 Send("\n");
00216 }
00217 else
00218 {
00219 std::string msg = "Unknown query type: " + m_query;
00220 Handler().LogError(this, "OnDetached", 0, msg);
00221 Send("Unknown\n\n");
00222 }
00223 SetCloseAndDelete();
00224 }
00225
00226
00227 void ResolvSocket::OnConnect()
00228 {
00229 if (m_resolv_host.size())
00230 {
00231 #ifdef ENABLE_IPV6
00232 std::string msg = (m_resolve_ipv6 ? "gethostbyname2 " : "gethostbyname ") + m_resolv_host + "\n";
00233 #else
00234 std::string msg = "gethostbyname " + m_resolv_host + "\n";
00235 #endif
00236 Send( msg );
00237 return;
00238 }
00239 #ifdef ENABLE_IPV6
00240 if (m_resolve_ipv6)
00241 {
00242 std::string tmp;
00243 Utility::l2ip(m_resolv_address6, tmp);
00244 std::string msg = "gethostbyaddr " + tmp + "\n";
00245 Send( msg );
00246 }
00247 #endif
00248 std::string tmp;
00249 Utility::l2ip(m_resolv_address, tmp);
00250 std::string msg = "gethostbyaddr " + tmp + "\n";
00251 Send( msg );
00252 }
00253
00254
00255 void ResolvSocket::OnDelete()
00256 {
00257 if (m_parent)
00258 {
00259 if (Handler().Valid(m_parent))
00260 m_parent -> OnResolveFailed(m_resolv_id);
00261 m_parent = NULL;
00262 }
00263 }
00264
00265
00266 #ifdef SOCKETS_NAMESPACE
00267 }
00268 #endif
00269
00270 #endif // ENABLE_RESOLVER