Logo
~Sockets~
~Examples~
~Contact~


ResolvSocket.cpp

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2004-2007  Anders Hedstrom
00007 
00008 This library is made available under the terms of the GNU GPL.
00009 
00010 If you would like to use this library in a closed-source application,
00011 a separate license agreement is available. For information about
00012 the closed-source license agreement for the C++ sockets library,
00013 please visit http://www.alhem.net/Sockets/license.html and/or
00014 email license@alhem.net.
00015 
00016 This program is free software; you can redistribute it and/or
00017 modify it under the terms of the GNU General Public License
00018 as published by the Free Software Foundation; either version 2
00019 of the License, or (at your option) any later version.
00020 
00021 This program is distributed in the hope that it will be useful,
00022 but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 GNU General Public License for more details.
00025 
00026 You should have received a copy of the GNU General Public License
00027 along with this program; if not, write to the Free Software
00028 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00029 */
00030 #ifdef _WIN32
00031 #pragma warning(disable:4786)
00032 #else
00033 #include <netdb.h>
00034 #endif
00035 #include "ResolvSocket.h"
00036 #ifdef ENABLE_RESOLVER
00037 #include "Utility.h"
00038 #include "Parse.h"
00039 #include "ISocketHandler.h"
00040 
00041 #ifdef SOCKETS_NAMESPACE
00042 namespace SOCKETS_NAMESPACE {
00043 #endif
00044 
00045 #ifdef _DEBUG
00046 #define DEB(x) x
00047 #else
00048 #define DEB(x)
00049 #endif
00050 
00051 
00052 ResolvSocket::ResolvSocket(ISocketHandler& h,Socket *parent)
00053 :TcpSocket(h)
00054 ,m_bServer(false)
00055 ,m_parent(parent)
00056 #ifdef ENABLE_IPV6
00057 ,m_resolve_ipv6(false)
00058 #endif
00059 {
00060         SetLineProtocol();
00061 }
00062 
00063 
00064 ResolvSocket::~ResolvSocket()
00065 {
00066 }
00067 
00068 
00069 void ResolvSocket::OnLine(const std::string& line)
00070 {
00071         Parse pa(line, ":");
00072         if (m_bServer)
00073         {
00074                 m_query = pa.getword();
00075                 m_data = pa.getrest();
00076 DEB(            fprintf(stderr, "ResolvSocket server; query=%s, data=%s\n", m_query.c_str(), m_data.c_str());)
00077                 if (!Detach()) // detach failed?
00078                 {
00079                         SetCloseAndDelete();
00080                 }
00081                 return;
00082         }
00083         std::string key = pa.getword();
00084         std::string value = pa.getrest();
00085 
00086         if (key == "Failed" && m_parent)
00087         {
00088 DEB(            fprintf(stderr, "************ Resolve failed\n");)
00089                 if (Handler().Valid(m_parent))
00090                         m_parent -> OnResolveFailed(m_resolv_id);
00091                 m_parent = NULL;
00092         }
00093         else
00094         if (key == "Name" && !m_resolv_host.size() && m_parent)
00095         {
00096                 if (Handler().Valid(m_parent))
00097                         m_parent -> OnReverseResolved(m_resolv_id, value);
00098                 m_parent = NULL;
00099         }
00100         else
00101         if (key == "A" && m_parent)
00102         {
00103                 ipaddr_t l;
00104                 Utility::u2ip(value, l); // ip2ipaddr_t
00105                 if (Handler().Valid(m_parent))
00106                         m_parent -> OnResolved(m_resolv_id, l, m_resolv_port);
00107                 m_parent = NULL; // always use first ip in case there are several
00108         }
00109 #ifdef ENABLE_IPV6
00110 #ifdef IPPROTO_IPV6
00111         else
00112         if (key == "AAAA" && m_parent)
00113         {
00114                 in6_addr a;
00115                 Utility::u2ip(value, a);
00116                 if (Handler().Valid(m_parent))
00117                         m_parent -> OnResolved(m_resolv_id, a, m_resolv_port);
00118                 m_parent = NULL;
00119         }
00120 #endif
00121 #endif
00122 }
00123 
00124 
00125 void ResolvSocket::OnDetached()
00126 {
00127 DEB(    fprintf(stderr, "ResolvSocket::OnDetached(); query=%s, data=%s\n", m_query.c_str(), m_data.c_str());)
00128         if (m_query == "gethostbyname")
00129         {
00130                 struct sockaddr_in sa;
00131                 if (Utility::u2ip(m_data, sa))
00132                 {
00133                         std::string ip;
00134                         Utility::l2ip(sa.sin_addr, ip);
00135                         Send("A: " + ip + "\n");
00136                 }
00137                 else
00138                 {
00139                         Send("Failed\n");
00140                 }
00141                 Send("\n");
00142         }
00143         else
00144 #ifdef ENABLE_IPV6
00145 #ifdef IPPROTO_IPV6
00146         if (m_query == "gethostbyname2")
00147         {
00148                 struct sockaddr_in6 sa;
00149                 if (Utility::u2ip(m_data, sa))
00150                 {
00151                         std::string ip;
00152                         Utility::l2ip(sa.sin6_addr, ip);
00153                         Send("AAAA: " + ip + "\n");
00154                 }
00155                 else
00156                 {
00157                         Send("Failed\n");
00158                 }
00159                 Send("\n");
00160         }
00161         else
00162 #endif
00163 #endif
00164         if (m_query == "gethostbyaddr")
00165         {
00166                 if (Utility::isipv4( m_data ))
00167                 {
00168                         struct sockaddr_in sa;
00169                         if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST))
00170                         {
00171                                 Send("Failed: convert to sockaddr_in failed\n");
00172                         }
00173                         else
00174                         {
00175                                 std::string name;
00176                                 if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name))
00177                                 {
00178                                         Send("Failed: ipv4 reverse lookup of " + m_data + "\n");
00179                                 }
00180                                 else
00181                                 {
00182                                         Send("Name: " + name + "\n");
00183                                 }
00184                         }
00185                 }
00186                 else
00187 #ifdef ENABLE_IPV6
00188 #ifdef IPPROTO_IPV6
00189                 if (Utility::isipv6( m_data ))
00190                 {
00191                         struct sockaddr_in6 sa;
00192                         if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST))
00193                         {
00194                                 Send("Failed: convert to sockaddr_in6 failed\n");
00195                         }
00196                         else
00197                         {
00198                                 std::string name;
00199                                 if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name))
00200                                 {
00201                                         Send("Failed: ipv6 reverse lookup of " + m_data + "\n");
00202                                 }
00203                                 else
00204                                 {
00205                                         Send("Name: " + name + "\n");
00206                                 }
00207                         }
00208                 }
00209                 else
00210 #endif
00211 #endif
00212                 {
00213                         Send("Failed: malformed address\n");
00214                 }
00215                 Send("\n");
00216         }
00217         else
00218         {
00219                 std::string msg = "Unknown query type: " + m_query;
00220                 Handler().LogError(this, "OnDetached", 0, msg);
00221                 Send("Unknown\n\n");
00222         }
00223         SetCloseAndDelete();
00224 }
00225 
00226 
00227 void ResolvSocket::OnConnect()
00228 {
00229         if (m_resolv_host.size())
00230         {
00231 #ifdef ENABLE_IPV6
00232                 std::string msg = (m_resolve_ipv6 ? "gethostbyname2 " : "gethostbyname ") + m_resolv_host + "\n";
00233 #else
00234                 std::string msg = "gethostbyname " + m_resolv_host + "\n";
00235 #endif
00236                 Send( msg );
00237                 return;
00238         }
00239 #ifdef ENABLE_IPV6
00240         if (m_resolve_ipv6)
00241         {
00242                 std::string tmp;
00243                 Utility::l2ip(m_resolv_address6, tmp);
00244                 std::string msg = "gethostbyaddr " + tmp + "\n";
00245                 Send( msg );
00246         }
00247 #endif
00248         std::string tmp;
00249         Utility::l2ip(m_resolv_address, tmp);
00250         std::string msg = "gethostbyaddr " + tmp + "\n";
00251         Send( msg );
00252 }
00253 
00254 
00255 void ResolvSocket::OnDelete()
00256 {
00257         if (m_parent)
00258         {
00259                 if (Handler().Valid(m_parent))
00260                         m_parent -> OnResolveFailed(m_resolv_id);
00261                 m_parent = NULL;
00262         }
00263 }
00264 
00265 
00266 #ifdef SOCKETS_NAMESPACE
00267 }
00268 #endif
00269 
00270 #endif // ENABLE_RESOLVER
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4