![]() |
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. | |
socketuid_t | m_parent_uid |
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 47 of file ResolvSocket.h.
typedef std::map<std::string, std::map<std::string, std::string> > ResolvSocket::cache_t [private] |
Definition at line 50 of file ResolvSocket.h.
typedef std::map<std::string, std::map<std::string, time_t> > ResolvSocket::timeout_t [private] |
Definition at line 52 of file ResolvSocket.h.
ResolvSocket::ResolvSocket | ( | ISocketHandler & | h | ) |
Definition at line 65 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
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 }
ResolvSocket::ResolvSocket | ( | ISocketHandler & | h, | |
Socket * | parent, | |||
const std::string & | host, | |||
port_t | port, | |||
bool | ipv6 = false | |||
) |
Definition at line 79 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
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 }
ResolvSocket::ResolvSocket | ( | ISocketHandler & | h, | |
Socket * | parent, | |||
ipaddr_t | a | |||
) |
Definition at line 95 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
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 }
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 63 of file ResolvSocket.h.
00063 { 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 132 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_parent_uid, 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().
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 // %! check cache 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) // ttl 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()) /* failed */ 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()) // detach failed? 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 // update cache 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 // update cache 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); // ip2ipaddr_t 00240 m_parent -> OnResolved(m_resolv_id, l, m_resolv_port); 00241 } 00242 // update cache 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; // always use first ip in case there are several 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 // update cache 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 }
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 278 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().
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 }
void ResolvSocket::OnDelete | ( | ) | [virtual] |
Called before a socket class is deleted by the ISocketHandler.
Reimplemented from Socket.
Definition at line 415 of file ResolvSocket.cpp.
References DEB, Socket::Handler(), m_cache, m_cache_mutex, m_cache_to, m_cached, m_data, m_parent, m_parent_uid, m_query, m_resolv_id, and Socket::OnResolveFailed().
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 // update cache 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 }
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 380 of file ResolvSocket.cpp.
References Utility::l2ip(), m_data, m_query, m_resolv_address, m_resolv_host, and TcpSocket::Send().
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 }
ResolvSocket& ResolvSocket::operator= | ( | const ResolvSocket & | ) | [inline, private] |
std::string ResolvSocket::m_query [private] |
Definition at line 81 of file ResolvSocket.h.
Referenced by OnConnect(), OnDelete(), OnDetached(), and OnLine().
std::string ResolvSocket::m_data [private] |
Definition at line 82 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 84 of file ResolvSocket.h.
Referenced by OnDelete(), and OnLine().
socketuid_t ResolvSocket::m_parent_uid [private] |
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] |