Logo
~Sockets~
~Examples~
~Contact~


ResolvSocket Class Reference
[Asynchronous DNS]

Async DNS resolver socket. More...

#include <ResolvSocket.h>

Inheritance diagram for ResolvSocket:

Inheritance graph
[legend]
Collaboration diagram for ResolvSocket:

Collaboration graph
[legend]
List of all members.

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)
ResolvSocketoperator= (const ResolvSocket &)

Private Attributes

std::string m_query
std::string m_data
bool m_bServer
Socketm_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

Detailed Description

Async DNS resolver socket.

Definition at line 45 of file ResolvSocket.h.


Member Typedef Documentation

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.


Constructor & Destructor Documentation

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 (  ) 

Definition at line 118 of file ResolvSocket.cpp.

00119 {
00120 }

ResolvSocket::ResolvSocket ( const ResolvSocket s  )  [inline, private]

Definition at line 76 of file ResolvSocket.h.

00076 : TcpSocket(s) {} // copy constructor


Member Function Documentation

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.

Parameters:
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.

See also:
ResolvSocket

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]

Definition at line 66 of file ResolvSocket.h.

00066 { m_resolv_id = x; }

int ResolvSocket::GetId (  )  [inline]

Definition at line 67 of file ResolvSocket.h.

00067 { return m_resolv_id; }

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]

Definition at line 77 of file ResolvSocket.h.

00077 { return *this; } // assignment operator


Member Data Documentation

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]

Definition at line 81 of file ResolvSocket.h.

Referenced by OnLine().

Pointer to ListenSocket class, valid for incoming sockets.

Reimplemented from Socket.

Definition at line 82 of file ResolvSocket.h.

Referenced by OnDelete(), and OnLine().

Definition at line 83 of file ResolvSocket.h.

Referenced by OnDelete(), and OnLine().

std::string ResolvSocket::m_resolv_host [private]

Definition at line 84 of file ResolvSocket.h.

Referenced by OnConnect(), and OnLine().

Definition at line 85 of file ResolvSocket.h.

Referenced by OnLine().

Definition at line 86 of file ResolvSocket.h.

Referenced by OnConnect().

Definition at line 91 of file ResolvSocket.h.

Referenced by OnDelete(), and OnLine().

Definition at line 92 of file ResolvSocket.h.

Referenced by OnDelete(), and OnLine().

Definition at line 93 of file ResolvSocket.h.

Referenced by OnDelete(), and OnLine().

bool ResolvSocket::m_cached [private]

Definition at line 94 of file ResolvSocket.h.

Referenced by OnDelete(), and OnLine().


The documentation for this class was generated from the following files:
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4