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