![]() |
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 & | ) |
Definition at line 60 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
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 }
ResolvSocket::ResolvSocket | ( | ISocketHandler & | , | |
Socket * | parent, | |||
const std::string & | host, | |||
port_t | port, | |||
bool | ipv6 = false | |||
) |
Definition at line 73 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
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 }
ResolvSocket::ResolvSocket | ( | ISocketHandler & | , | |
Socket * | parent, | |||
ipaddr_t | ||||
) |
Definition at line 88 of file ResolvSocket.cpp.
References TcpSocket::SetLineProtocol().
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 }
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 123 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(), TcpSocket::Send(), Socket::SetCloseAndDelete(), and Utility::u2ip().
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 // %! check cache 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) // ttl 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()) /* failed */ 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()) // detach failed? 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 // update cache 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 // update cache 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); // ip2ipaddr_t 00228 if (Handler().Valid(m_parent)) 00229 { 00230 m_parent -> OnResolved(m_resolv_id, l, m_resolv_port); 00231 } 00232 // update cache 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; // always use first ip in case there are several 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 // update cache 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 }
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 268 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().
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 }
void ResolvSocket::OnDelete | ( | ) | [virtual] |
Called before a socket class is deleted by the ISocketHandler.
Reimplemented from Socket.
Definition at line 405 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().
00406 { 00407 if (m_parent) 00408 { 00409 if (Handler().Valid(m_parent)) 00410 { 00411 m_parent -> OnResolveFailed(m_resolv_id); 00412 } 00413 // update cache 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 }
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 370 of file ResolvSocket.cpp.
References Utility::l2ip(), m_data, m_query, m_resolv_address, m_resolv_host, and TcpSocket::Send().
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 }
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] |