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 #pragma warning(disable:4503)
00033 #else
00034 #include <netdb.h>
00035 #endif
00036 #include "ResolvSocket.h"
00037 #ifdef ENABLE_RESOLVER
00038 #include "Utility.h"
00039 #include "Parse.h"
00040 #include "ISocketHandler.h"
00041 #include "Lock.h"
00042
00043 #ifdef SOCKETS_NAMESPACE
00044 namespace SOCKETS_NAMESPACE {
00045 #endif
00046
00047 #ifdef _DEBUG
00048 #define DEB(x) x
00049 #else
00050 #define DEB(x)
00051 #endif
00052
00053
00054
00055 ResolvSocket::cache_t ResolvSocket::m_cache;
00056 ResolvSocket::timeout_t ResolvSocket::m_cache_to;
00057 Mutex ResolvSocket::m_cache_mutex;
00058
00059
00060 ResolvSocket::ResolvSocket(ISocketHandler& h)
00061 :TcpSocket(h)
00062 ,m_bServer(false)
00063 ,m_parent(NULL)
00064 #ifdef ENABLE_IPV6
00065 ,m_resolve_ipv6(false)
00066 #endif
00067 ,m_cached(false)
00068 {
00069 SetLineProtocol();
00070 }
00071
00072
00073 ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, const std::string& host, port_t port, bool ipv6)
00074 :TcpSocket(h)
00075 ,m_bServer(false)
00076 ,m_parent(parent)
00077 ,m_resolv_host(host)
00078 ,m_resolv_port(port)
00079 #ifdef ENABLE_IPV6
00080 ,m_resolve_ipv6(ipv6)
00081 #endif
00082 ,m_cached(false)
00083 {
00084 SetLineProtocol();
00085 }
00086
00087
00088 ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, ipaddr_t a)
00089 :TcpSocket(h)
00090 ,m_bServer(false)
00091 ,m_parent(parent)
00092 ,m_resolv_port(0)
00093 ,m_resolv_address(a)
00094 #ifdef ENABLE_IPV6
00095 ,m_resolve_ipv6(false)
00096 #endif
00097 ,m_cached(false)
00098 {
00099 SetLineProtocol();
00100 }
00101
00102
00103 #ifdef ENABLE_IPV6
00104 ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, in6_addr& a)
00105 :TcpSocket(h)
00106 ,m_bServer(false)
00107 ,m_parent(parent)
00108 ,m_resolv_port(0)
00109 ,m_resolve_ipv6(true)
00110 ,m_resolv_address6(a)
00111 ,m_cached(false)
00112 {
00113 SetLineProtocol();
00114 }
00115 #endif
00116
00117
00118 ResolvSocket::~ResolvSocket()
00119 {
00120 }
00121
00122
00123 void ResolvSocket::OnLine(const std::string& line)
00124 {
00125 Parse pa(line, ":");
00126 if (m_bServer)
00127 {
00128 m_query = pa.getword();
00129 m_data = pa.getrest();
00130 DEB( fprintf(stderr, "ResolvSocket server; query=%s, data=%s\n", m_query.c_str(), m_data.c_str());)
00131
00132 {
00133 Lock lock(m_cache_mutex);
00134 if (m_cache[m_query].find(m_data) != m_cache[m_query].end())
00135 {
00136 if (time(NULL) - m_cache_to[m_query][m_data] < 3600)
00137 {
00138 std::string result = m_cache[m_query][m_data];
00139 DEB(printf("Returning cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), result.c_str());)
00140 Send("Cached\n");
00141 if (!result.size())
00142 {
00143 Send("Failed\n\n");
00144 SetCloseAndDelete();
00145 return;
00146 }
00147 else
00148 if (m_query == "gethostbyname")
00149 {
00150 Send("A: " + result + "\n\n");
00151 SetCloseAndDelete();
00152 return;
00153 }
00154 else
00155 #ifdef ENABLE_IPV6
00156 #ifdef IPPROTO_IPV6
00157 if (m_query == "gethostbyname2")
00158 {
00159 Send("AAAA: " + result + "\n\n");
00160 SetCloseAndDelete();
00161 return;
00162 }
00163 else
00164 #endif
00165 #endif
00166 if (m_query == "gethostbyaddr")
00167 {
00168 Send("Name: " + result + "\n\n");
00169 SetCloseAndDelete();
00170 return;
00171 }
00172 }
00173 }
00174 }
00175 if (!Detach())
00176 {
00177 SetCloseAndDelete();
00178 }
00179 return;
00180 }
00181 std::string key = pa.getword();
00182 std::string value = pa.getrest();
00183
00184 if (key == "Cached")
00185 {
00186 m_cached = true;
00187 }
00188 else
00189 if (key == "Failed" && m_parent)
00190 {
00191 DEB( fprintf(stderr, "************ Resolve failed\n");)
00192 if (Handler().Valid(m_parent))
00193 {
00194 m_parent -> OnResolveFailed(m_resolv_id);
00195 }
00196
00197 if (!m_cached)
00198 {
00199 Lock lock(m_cache_mutex);
00200 DEB(printf("Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
00201 m_cache[m_query][m_data] = value;
00202 m_cache_to[m_query][m_data] = time(NULL);
00203 }
00204 m_parent = NULL;
00205 }
00206 else
00207 if (key == "Name" && !m_resolv_host.size() && m_parent)
00208 {
00209 if (Handler().Valid(m_parent))
00210 {
00211 m_parent -> OnReverseResolved(m_resolv_id, value);
00212 }
00213
00214 if (!m_cached)
00215 {
00216 Lock lock(m_cache_mutex);
00217 DEB(printf("Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
00218 m_cache[m_query][m_data] = value;
00219 m_cache_to[m_query][m_data] = time(NULL);
00220 }
00221 m_parent = NULL;
00222 }
00223 else
00224 if (key == "A" && m_parent)
00225 {
00226 ipaddr_t l;
00227 Utility::u2ip(value, l);
00228 if (Handler().Valid(m_parent))
00229 {
00230 m_parent -> OnResolved(m_resolv_id, l, m_resolv_port);
00231 }
00232
00233 if (!m_cached)
00234 {
00235 Lock lock(m_cache_mutex);
00236 DEB(printf("Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
00237 m_cache[m_query][m_data] = value;
00238 m_cache_to[m_query][m_data] = time(NULL);
00239 }
00240 m_parent = NULL;
00241 }
00242 #ifdef ENABLE_IPV6
00243 #ifdef IPPROTO_IPV6
00244 else
00245 if (key == "AAAA" && m_parent)
00246 {
00247 in6_addr a;
00248 Utility::u2ip(value, a);
00249 if (Handler().Valid(m_parent))
00250 {
00251 m_parent -> OnResolved(m_resolv_id, a, m_resolv_port);
00252 }
00253
00254 if (!m_cached)
00255 {
00256 Lock lock(m_cache_mutex);
00257 DEB(printf("Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
00258 m_cache[m_query][m_data] = value;
00259 m_cache_to[m_query][m_data] = time(NULL);
00260 }
00261 m_parent = NULL;
00262 }
00263 #endif
00264 #endif
00265 }
00266
00267
00268 void ResolvSocket::OnDetached()
00269 {
00270 DEB( fprintf(stderr, "ResolvSocket::OnDetached(); query=%s, data=%s\n", m_query.c_str(), m_data.c_str());)
00271 if (m_query == "gethostbyname")
00272 {
00273 struct sockaddr_in sa;
00274 if (Utility::u2ip(m_data, sa))
00275 {
00276 std::string ip;
00277 Utility::l2ip(sa.sin_addr, ip);
00278 Send("A: " + ip + "\n");
00279 }
00280 else
00281 {
00282 Send("Failed\n");
00283 }
00284 Send("\n");
00285 }
00286 else
00287 #ifdef ENABLE_IPV6
00288 #ifdef IPPROTO_IPV6
00289 if (m_query == "gethostbyname2")
00290 {
00291 struct sockaddr_in6 sa;
00292 if (Utility::u2ip(m_data, sa))
00293 {
00294 std::string ip;
00295 Utility::l2ip(sa.sin6_addr, ip);
00296 Send("AAAA: " + ip + "\n");
00297 }
00298 else
00299 {
00300 Send("Failed\n");
00301 }
00302 Send("\n");
00303 }
00304 else
00305 #endif
00306 #endif
00307 if (m_query == "gethostbyaddr")
00308 {
00309 if (Utility::isipv4( m_data ))
00310 {
00311 struct sockaddr_in sa;
00312 if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST))
00313 {
00314 Send("Failed: convert to sockaddr_in failed\n");
00315 }
00316 else
00317 {
00318 std::string name;
00319 if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name))
00320 {
00321 Send("Failed: ipv4 reverse lookup of " + m_data + "\n");
00322 }
00323 else
00324 {
00325 Send("Name: " + name + "\n");
00326 }
00327 }
00328 }
00329 else
00330 #ifdef ENABLE_IPV6
00331 #ifdef IPPROTO_IPV6
00332 if (Utility::isipv6( m_data ))
00333 {
00334 struct sockaddr_in6 sa;
00335 if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST))
00336 {
00337 Send("Failed: convert to sockaddr_in6 failed\n");
00338 }
00339 else
00340 {
00341 std::string name;
00342 if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name))
00343 {
00344 Send("Failed: ipv6 reverse lookup of " + m_data + "\n");
00345 }
00346 else
00347 {
00348 Send("Name: " + name + "\n");
00349 }
00350 }
00351 }
00352 else
00353 #endif
00354 #endif
00355 {
00356 Send("Failed: malformed address\n");
00357 }
00358 Send("\n");
00359 }
00360 else
00361 {
00362 std::string msg = "Unknown query type: " + m_query;
00363 Handler().LogError(this, "OnDetached", 0, msg);
00364 Send("Unknown\n\n");
00365 }
00366 SetCloseAndDelete();
00367 }
00368
00369
00370 void ResolvSocket::OnConnect()
00371 {
00372 if (m_resolv_host.size())
00373 {
00374 #ifdef ENABLE_IPV6
00375 std::string msg = (m_resolve_ipv6 ? "gethostbyname2 " : "gethostbyname ") + m_resolv_host + "\n";
00376 m_query = m_resolve_ipv6 ? "gethostbyname2" : "gethostbyname";
00377 #else
00378 std::string msg = "gethostbyname " + m_resolv_host + "\n";
00379 m_query = "gethostbyname";
00380 #endif
00381 m_data = m_resolv_host;
00382 Send( msg );
00383 return;
00384 }
00385 #ifdef ENABLE_IPV6
00386 if (m_resolve_ipv6)
00387 {
00388 std::string tmp;
00389 Utility::l2ip(m_resolv_address6, tmp);
00390 m_query = "gethostbyaddr";
00391 m_data = tmp;
00392 std::string msg = "gethostbyaddr " + tmp + "\n";
00393 Send( msg );
00394 }
00395 #endif
00396 std::string tmp;
00397 Utility::l2ip(m_resolv_address, tmp);
00398 m_query = "gethostbyaddr";
00399 m_data = tmp;
00400 std::string msg = "gethostbyaddr " + tmp + "\n";
00401 Send( msg );
00402 }
00403
00404
00405 void ResolvSocket::OnDelete()
00406 {
00407 if (m_parent)
00408 {
00409 if (Handler().Valid(m_parent))
00410 {
00411 m_parent -> OnResolveFailed(m_resolv_id);
00412 }
00413
00414 if (!m_cached)
00415 {
00416 Lock lock(m_cache_mutex);
00417 std::string value;
00418 DEB(printf("Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
00419 m_cache[m_query][m_data] = value;
00420 m_cache_to[m_query][m_data] = time(NULL);
00421 }
00422 m_parent = NULL;
00423 }
00424 }
00425
00426
00427 #ifdef SOCKETS_NAMESPACE
00428 }
00429 #endif
00430
00431 #endif // ENABLE_RESOLVER