ResolvSocket Class ReferenceAsync DNS resolver socket.
More...
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Public Member Functions | |
| ResolvSocket (ISocketHandler &) | |
| ResolvSocket (ISocketHandler &, Socket *parent, const std::string &host, port_t port, bool ipv6=false) | |
| ResolvSocket (ISocketHandler &, Socket *parent, ipaddr_t) | |
| ~ResolvSocket () | |
| void | OnAccept () |
| Called when an incoming connection has been completed. | |
| void | OnLine (const std::string &line) |
| Callback fires when a socket in line protocol has read one full line. | |
| void | OnDetached () |
| Callback fires when a new socket thread has started and this socket is ready for operation again. | |
| void | OnDelete () |
| Called before a socket class is deleted by the ISocketHandler. | |
| void | SetId (int x) |
| int | GetId () |
| void | OnConnect () |
| Called when a connection has completed. | |
Private Types | |
| typedef std::map< std::string, std::map< std::string, std::string > > | cache_t |
| typedef std::map< std::string, std::map< std::string, time_t > > | timeout_t |
Private Member Functions | |
| ResolvSocket (const ResolvSocket &s) | |
| ResolvSocket & | operator= (const ResolvSocket &) |
Private Attributes | |
| std::string | m_query |
| std::string | m_data |
| bool | m_bServer |
| Socket * | m_parent |
| Pointer to ListenSocket class, valid for incoming sockets. | |
| int | m_resolv_id |
| std::string | m_resolv_host |
| port_t | m_resolv_port |
| ipaddr_t | m_resolv_address |
| bool | m_cached |
Static Private Attributes | |
| static cache_t | m_cache |
| static timeout_t | m_cache_to |
| static Mutex | m_cache_mutex |
Definition at line 45 of file ResolvSocket.h.
typedef std::map<std::string, std::map<std::string, std::string> > ResolvSocket::cache_t [private] |
Definition at line 48 of file ResolvSocket.h.
typedef std::map<std::string, std::map<std::string, time_t> > ResolvSocket::timeout_t [private] |
Definition at line 50 of file ResolvSocket.h.
| ResolvSocket::ResolvSocket | ( | ISocketHandler & | h | ) |
Definition at line 63 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
00064 :TcpSocket(h) 00065 ,m_bServer(false) 00066 ,m_parent(NULL) 00067 #ifdef ENABLE_IPV6 00068 ,m_resolve_ipv6(false) 00069 #endif 00070 ,m_cached(false) 00071 { 00072 SetLineProtocol(); 00073 }
| ResolvSocket::ResolvSocket | ( | ISocketHandler & | h, | |
| Socket * | parent, | |||
| const std::string & | host, | |||
| port_t | port, | |||
| bool | ipv6 = false | |||
| ) |
Definition at line 76 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
00077 :TcpSocket(h) 00078 ,m_bServer(false) 00079 ,m_parent(parent) 00080 ,m_resolv_host(host) 00081 ,m_resolv_port(port) 00082 #ifdef ENABLE_IPV6 00083 ,m_resolve_ipv6(ipv6) 00084 #endif 00085 ,m_cached(false) 00086 { 00087 SetLineProtocol(); 00088 }
| ResolvSocket::ResolvSocket | ( | ISocketHandler & | h, | |
| Socket * | parent, | |||
| ipaddr_t | a | |||
| ) |
Definition at line 91 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
00092 :TcpSocket(h) 00093 ,m_bServer(false) 00094 ,m_parent(parent) 00095 ,m_resolv_port(0) 00096 ,m_resolv_address(a) 00097 #ifdef ENABLE_IPV6 00098 ,m_resolve_ipv6(false) 00099 #endif 00100 ,m_cached(false) 00101 { 00102 SetLineProtocol(); 00103 }
| ResolvSocket::~ResolvSocket | ( | ) |
| ResolvSocket::ResolvSocket | ( | const ResolvSocket & | s | ) | [inline, private] |
| void ResolvSocket::OnAccept | ( | ) | [inline, virtual] |
Called when an incoming connection has been completed.
Reimplemented from Socket.
Definition at line 61 of file ResolvSocket.h.
00061 { m_bServer = true; }
| void ResolvSocket::OnLine | ( | const std::string & | line | ) | [virtual] |
Callback fires when a socket in line protocol has read one full line.
| line | Line read |
Reimplemented from TcpSocket.
Definition at line 126 of file ResolvSocket.cpp.
References DEB, Socket::Detach(), Parse::getrest(), Parse::getword(), Socket::Handler(), m_bServer, m_cache, m_cache_mutex, m_cache_to, m_cached, m_data, m_parent, m_query, m_resolv_host, m_resolv_id, m_resolv_port, TcpSocket::OnResolved(), Socket::OnResolveFailed(), Socket::OnReverseResolved(), ISocketHandler::Resolving(), TcpSocket::Send(), Socket::SetCloseAndDelete(), Utility::u2ip(), and ISocketHandler::Valid().
00127 { 00128 Parse pa(line, ":"); 00129 if (m_bServer) 00130 { 00131 m_query = pa.getword(); 00132 m_data = pa.getrest(); 00133 DEB( fprintf(stderr, " *** ResolvSocket server; query=%s, data=%s\n", m_query.c_str(), m_data.c_str());) 00134 // %! check cache 00135 { 00136 Lock lock(m_cache_mutex); 00137 if (m_cache[m_query].find(m_data) != m_cache[m_query].end()) 00138 { 00139 if (time(NULL) - m_cache_to[m_query][m_data] < 3600) // ttl 00140 { 00141 std::string result = m_cache[m_query][m_data]; 00142 DEB(fprintf(stderr, " *** Returning cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), result.c_str());) 00143 Send("Cached\n"); 00144 if (!result.size()) /* failed */ 00145 { 00146 Send("Failed\n\n"); 00147 SetCloseAndDelete(); 00148 return; 00149 } 00150 else 00151 if (m_query == "gethostbyname") 00152 { 00153 Send("A: " + result + "\n\n"); 00154 SetCloseAndDelete(); 00155 return; 00156 } 00157 else 00158 #ifdef ENABLE_IPV6 00159 #ifdef IPPROTO_IPV6 00160 if (m_query == "gethostbyname2") 00161 { 00162 Send("AAAA: " + result + "\n\n"); 00163 SetCloseAndDelete(); 00164 return; 00165 } 00166 else 00167 #endif 00168 #endif 00169 if (m_query == "gethostbyaddr") 00170 { 00171 Send("Name: " + result + "\n\n"); 00172 SetCloseAndDelete(); 00173 return; 00174 } 00175 } 00176 } 00177 } 00178 if (!Detach()) // detach failed? 00179 { 00180 SetCloseAndDelete(); 00181 } 00182 return; 00183 } 00184 std::string key = pa.getword(); 00185 std::string value = pa.getrest(); 00186 DEB( fprintf(stderr, " *** ResolvSocket response; %s: %s\n", key.c_str(), value.c_str());) 00187 00188 if (key == "Cached") 00189 { 00190 m_cached = true; 00191 } 00192 else 00193 if (key == "Failed" && m_parent) 00194 { 00195 DEB( fprintf(stderr, " ************ Resolve failed\n");) 00196 if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) 00197 { 00198 m_parent -> OnResolveFailed(m_resolv_id); 00199 } 00200 // update cache 00201 if (!m_cached) 00202 { 00203 Lock lock(m_cache_mutex); 00204 DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) 00205 m_cache[m_query][m_data] = value; 00206 m_cache_to[m_query][m_data] = time(NULL); 00207 } 00208 m_parent = NULL; 00209 } 00210 else 00211 if (key == "Name" && !m_resolv_host.size() && m_parent) 00212 { 00213 if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) 00214 { 00215 m_parent -> OnReverseResolved(m_resolv_id, value); 00216 } 00217 // update cache 00218 if (!m_cached) 00219 { 00220 Lock lock(m_cache_mutex); 00221 DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) 00222 m_cache[m_query][m_data] = value; 00223 m_cache_to[m_query][m_data] = time(NULL); 00224 } 00225 m_parent = NULL; 00226 } 00227 else 00228 if (key == "A" && m_parent) 00229 { 00230 if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) 00231 { 00232 ipaddr_t l; 00233 Utility::u2ip(value, l); // ip2ipaddr_t 00234 m_parent -> OnResolved(m_resolv_id, l, m_resolv_port); 00235 } 00236 // update cache 00237 if (!m_cached) 00238 { 00239 Lock lock(m_cache_mutex); 00240 DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) 00241 m_cache[m_query][m_data] = value; 00242 m_cache_to[m_query][m_data] = time(NULL); 00243 } 00244 m_parent = NULL; // always use first ip in case there are several 00245 } 00246 #ifdef ENABLE_IPV6 00247 #ifdef IPPROTO_IPV6 00248 else 00249 if (key == "AAAA" && m_parent) 00250 { 00251 if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) 00252 { 00253 in6_addr a; 00254 Utility::u2ip(value, a); 00255 m_parent -> OnResolved(m_resolv_id, a, m_resolv_port); 00256 } 00257 // update cache 00258 if (!m_cached) 00259 { 00260 Lock lock(m_cache_mutex); 00261 DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) 00262 m_cache[m_query][m_data] = value; 00263 m_cache_to[m_query][m_data] = time(NULL); 00264 } 00265 m_parent = NULL; 00266 } 00267 #endif 00268 #endif 00269 }
| void ResolvSocket::OnDetached | ( | ) | [virtual] |
Callback fires when a new socket thread has started and this socket is ready for operation again.
Reimplemented from Socket.
Definition at line 272 of file ResolvSocket.cpp.
References AI_NUMERICHOST, DEB, Socket::Handler(), Utility::isipv4(), Utility::isipv6(), Utility::l2ip(), ISocketHandler::LogError(), m_data, m_query, Utility::reverse(), TcpSocket::Send(), Socket::SetCloseAndDelete(), and Utility::u2ip().
00273 { 00274 DEB( fprintf(stderr, " *** ResolvSocket::OnDetached(); query=%s, data=%s\n", m_query.c_str(), m_data.c_str());) 00275 if (m_query == "gethostbyname") 00276 { 00277 struct sockaddr_in sa; 00278 if (Utility::u2ip(m_data, sa)) 00279 { 00280 std::string ip; 00281 Utility::l2ip(sa.sin_addr, ip); 00282 Send("A: " + ip + "\n"); 00283 } 00284 else 00285 { 00286 Send("Failed\n"); 00287 } 00288 Send("\n"); 00289 } 00290 else 00291 #ifdef ENABLE_IPV6 00292 #ifdef IPPROTO_IPV6 00293 if (m_query == "gethostbyname2") 00294 { 00295 struct sockaddr_in6 sa; 00296 if (Utility::u2ip(m_data, sa)) 00297 { 00298 std::string ip; 00299 Utility::l2ip(sa.sin6_addr, ip); 00300 Send("AAAA: " + ip + "\n"); 00301 } 00302 else 00303 { 00304 Send("Failed\n"); 00305 } 00306 Send("\n"); 00307 } 00308 else 00309 #endif 00310 #endif 00311 if (m_query == "gethostbyaddr") 00312 { 00313 if (Utility::isipv4( m_data )) 00314 { 00315 struct sockaddr_in sa; 00316 if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST)) 00317 { 00318 Send("Failed: convert to sockaddr_in failed\n"); 00319 } 00320 else 00321 { 00322 std::string name; 00323 if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name)) 00324 { 00325 Send("Failed: ipv4 reverse lookup of " + m_data + "\n"); 00326 } 00327 else 00328 { 00329 Send("Name: " + name + "\n"); 00330 } 00331 } 00332 } 00333 else 00334 #ifdef ENABLE_IPV6 00335 #ifdef IPPROTO_IPV6 00336 if (Utility::isipv6( m_data )) 00337 { 00338 struct sockaddr_in6 sa; 00339 if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST)) 00340 { 00341 Send("Failed: convert to sockaddr_in6 failed\n"); 00342 } 00343 else 00344 { 00345 std::string name; 00346 if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name)) 00347 { 00348 Send("Failed: ipv6 reverse lookup of " + m_data + "\n"); 00349 } 00350 else 00351 { 00352 Send("Name: " + name + "\n"); 00353 } 00354 } 00355 } 00356 else 00357 #endif 00358 #endif 00359 { 00360 Send("Failed: malformed address\n"); 00361 } 00362 Send("\n"); 00363 } 00364 else 00365 { 00366 std::string msg = "Unknown query type: " + m_query; 00367 Handler().LogError(this, "OnDetached", 0, msg); 00368 Send("Unknown\n\n"); 00369 } 00370 SetCloseAndDelete(); 00371 }
| void ResolvSocket::OnDelete | ( | ) | [virtual] |
Called before a socket class is deleted by the ISocketHandler.
Reimplemented from Socket.
Definition at line 409 of file ResolvSocket.cpp.
References DEB, Socket::Handler(), m_cache, m_cache_mutex, m_cache_to, m_cached, m_data, m_parent, m_query, m_resolv_id, and Socket::OnResolveFailed().
00410 { 00411 if (m_parent) 00412 { 00413 if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) 00414 { 00415 m_parent -> OnResolveFailed(m_resolv_id); 00416 } 00417 // update cache 00418 if (!m_cached) 00419 { 00420 Lock lock(m_cache_mutex); 00421 std::string value; 00422 DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) 00423 m_cache[m_query][m_data] = value; 00424 m_cache_to[m_query][m_data] = time(NULL); 00425 } 00426 m_parent = NULL; 00427 } 00428 }
| void ResolvSocket::SetId | ( | int | x | ) | [inline] |
| int ResolvSocket::GetId | ( | ) | [inline] |
| void ResolvSocket::OnConnect | ( | ) | [virtual] |
Called when a connection has completed.
Reimplemented from Socket.
Definition at line 374 of file ResolvSocket.cpp.
References Utility::l2ip(), m_data, m_query, m_resolv_address, m_resolv_host, and TcpSocket::Send().
00375 { 00376 if (m_resolv_host.size()) 00377 { 00378 #ifdef ENABLE_IPV6 00379 std::string msg = (m_resolve_ipv6 ? "gethostbyname2 " : "gethostbyname ") + m_resolv_host + "\n"; 00380 m_query = m_resolve_ipv6 ? "gethostbyname2" : "gethostbyname"; 00381 #else 00382 std::string msg = "gethostbyname " + m_resolv_host + "\n"; 00383 m_query = "gethostbyname"; 00384 #endif 00385 m_data = m_resolv_host; 00386 Send( msg ); 00387 return; 00388 } 00389 #ifdef ENABLE_IPV6 00390 if (m_resolve_ipv6) 00391 { 00392 std::string tmp; 00393 Utility::l2ip(m_resolv_address6, tmp); 00394 m_query = "gethostbyaddr"; 00395 m_data = tmp; 00396 std::string msg = "gethostbyaddr " + tmp + "\n"; 00397 Send( msg ); 00398 } 00399 #endif 00400 std::string tmp; 00401 Utility::l2ip(m_resolv_address, tmp); 00402 m_query = "gethostbyaddr"; 00403 m_data = tmp; 00404 std::string msg = "gethostbyaddr " + tmp + "\n"; 00405 Send( msg ); 00406 }
| ResolvSocket& ResolvSocket::operator= | ( | const ResolvSocket & | ) | [inline, private] |
std::string ResolvSocket::m_query [private] |
Definition at line 79 of file ResolvSocket.h.
Referenced by OnConnect(), OnDelete(), OnDetached(), and OnLine().
std::string ResolvSocket::m_data [private] |
Definition at line 80 of file ResolvSocket.h.
Referenced by OnConnect(), OnDelete(), OnDetached(), and OnLine().
bool ResolvSocket::m_bServer [private] |
Socket* ResolvSocket::m_parent [private] |
Pointer to ListenSocket class, valid for incoming sockets.
Reimplemented from Socket.
Definition at line 82 of file ResolvSocket.h.
Referenced by OnDelete(), and OnLine().
int ResolvSocket::m_resolv_id [private] |
std::string ResolvSocket::m_resolv_host [private] |
port_t ResolvSocket::m_resolv_port [private] |
ipaddr_t ResolvSocket::m_resolv_address [private] |
ResolvSocket::cache_t ResolvSocket::m_cache [static, private] |
ResolvSocket::timeout_t ResolvSocket::m_cache_to [static, private] |
Mutex ResolvSocket::m_cache_mutex [static, private] |
bool ResolvSocket::m_cached [private] |
1.4.4