- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gresolver_unix.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gresolver_unix.cpp
19 //
20
21 #include "gdef.h"
22 #include "gresolver.h"
23 #include "glinebuffer.h"
24 #include "gsimpleclient.h"
25 #include "gsocketprotocol.h"
26 #include "gresolverinfo.h"
27 #include "gexception.h"
28 #include "gsocket.h"
29 #include "gevent.h"
30 #include "gmemory.h"
31 #include "gstr.h"
32 #include "gdebug.h"
33 #include "glog.h"
34
35 namespace
36 {
37 const unsigned int c_port = 208U ;
38 }
39
49 class GNet::ResolverImp : public GNet::SimpleClient
50 {
51 public:
52 ResolverImp( EventHandler & event_handler , Resolver & resolver , unsigned int port ) ;
53 // Constructor.
54
55 virtual ~ResolverImp() ;
56 // Destructor.
57
58 bool resolveReq( std::string host_part, std::string service_part , bool udp ) ;
59 // Issues a resolve request for the given host and service names.
60
61 bool busy() const ;
62 // Returns true if resolving is currently in progress.
63
64 protected:
65 virtual void onConnect() ;
66 virtual void onSendComplete() ;
67 virtual void onData( const char * , std::string::size_type ) ;
68 virtual void onSecure( const std::string & ) ;
69 virtual void onException( std::exception & ) ;
70
71 private:
72 void operator=( const ResolverImp & ) ; // not implemented
73 ResolverImp( const ResolverImp & ) ; // not implemented
74 static ResolverInfo resolverInfo( unsigned int ) ;
75
76 private:
77 EventHandler & m_event_handler ;
78 Resolver & m_outer ;
79 LineBuffer m_line_buffer ;
80 std::string m_request ;
81 } ;
82
83 // ===
84
85 GNet::ResolverImp::ResolverImp( EventHandler & event_handler , Resolver & resolver , unsigned int port ) :
86 SimpleClient(resolverInfo(port)) ,
87 m_event_handler(event_handler) ,
88 m_outer(resolver)
89 {
90 }
91
92 GNet::ResolverImp::~ResolverImp()
93 {
94 }
95
96 GNet::ResolverInfo GNet::ResolverImp::resolverInfo( unsigned int port )
97 {
98 ResolverInfo info( "localhost" , "0" ) ;
99 info.update( Address::localhost(port) , "localhost" ) ;
100 return info ;
101 }
102
103 bool GNet::ResolverImp::resolveReq( std::string host_part, std::string service_part , bool udp )
104 {
105 if( ! m_request.empty() )
106 return false ; // still busy
107 m_request = host_part + ":" + service_part + ":" + ( udp ? "udp" : "tcp" ) + "\n" ;
108
109 if( connected() )
110 send( m_request ) ;
111 else
112 connect() ;
113
114 return true ;
115 }
116
117 void GNet::ResolverImp::onConnect()
118 {
119 if( ! m_request.empty() )
120 send( m_request ) ;
121 }
122
123 void GNet::ResolverImp::onSendComplete()
124 {
125 }
126
127 void GNet::ResolverImp::onSecure( const std::string & )
128 {
129 }
130
131 void GNet::ResolverImp::onData( const char * p , std::string::size_type n )
132 {
133 m_line_buffer.add( p , n ) ;
134 while( m_line_buffer.more() )
135 {
136 m_request.erase() ;
137
138 std::string result = m_line_buffer.line() ;
139 G_DEBUG( "GNet::ResolverImp::readEvent: \"" << result << "\"" ) ;
140 G::Str::trim( result , " \n\r" ) ;
141 std::string::size_type pos = result.find( ' ' ) ;
142 std::string head = pos == std::string::npos ? result : result.substr(0U,pos) ;
143 std::string tail = pos == std::string::npos ? std::string() : result.substr(pos+1U) ;
144 if( Address::validString(head) )
145 {
146 G::Str::trim( tail , " \n" ) ;
147 m_outer.resolveCon( true , Address(head) , tail ) ;
148 }
149 else
150 {
151 std::string reason = result ;
152 reason = G::Str::isPrintableAscii( reason ) ? reason : std::string("dns error") ;
153 m_outer.resolveCon( false , Address::invalidAddress() , reason ) ;
154 }
155 }
156 }
157
158 void GNet::ResolverImp::onException( std::exception & e )
159 {
160 if( busy() )
161 {
162 m_request.erase() ;
163 m_outer.resolveCon( false , Address::invalidAddress() , e.what() ) ;
164 }
165 else
166 {
167 m_event_handler.onException( e ) ;
168 }
169 }
170
171 bool GNet::ResolverImp::busy() const
172 {
173 return ! m_request.empty() ;
174 }
175
176 // ===
177
178 GNet::Resolver::Resolver( EventHandler & event_handler ) :
179 m_imp(new ResolverImp(event_handler,*this,c_port))
180 {
181 }
182
183 GNet::Resolver::~Resolver()
184 {
185 delete m_imp ;
186 }
187
188 bool GNet::Resolver::resolveReq( std::string name , bool udp )
189 {
190 std::string host_part ;
191 std::string service_part ;
192 if( ! parse(name,host_part,service_part) )
193 return false ;
194
195 return m_imp->resolveReq( host_part , service_part , udp ) ;
196 }
197
198 bool GNet::Resolver::resolveReq( std::string host_part, std::string service_part , bool udp )
199 {
200 if( m_imp == NULL )
201 return false ;
202
203 if( host_part.length() == 0 )
204 host_part = "0.0.0.0" ;
205
206 if( service_part.length() == 0 )
207 service_part = "0" ;
208
209 return m_imp->resolveReq( host_part , service_part , udp ) ;
210 }
211
212 void GNet::Resolver::resolveCon( bool , const Address & , std::string )
213 {
214 // no-op
215 }
216
217 bool GNet::Resolver::busy() const
218 {
219 return m_imp->busy() ;
220 }
221
GNet::Resolver::~Resolver
virtual ~Resolver()
Virtual destructor.
Definition: gresolver_unix.cpp:183
GNet::ResolverImp::onSecure
virtual void onSecure(const std::string &)
Called once the secure socket protocol has been successfully negotiated.
Definition: gresolver_unix.cpp:127
GNet::Address::localhost
static Address localhost(unsigned int port=0U)
Returns a localhost ("loopback") address.
Definition: gaddress_ipv4.cpp:463
GNet::SimpleClient
A class for making an outgoing connection to a remote server, with support for socket-level protocols...
Definition: gsimpleclient.h:81
glog.h
GNet::ResolverImp::onConnect
virtual void onConnect()
Called once connected.
Definition: gresolver_unix.cpp:117
gresolverinfo.h
gsocketprotocol.h
GNet::Resolver
A class for asynchronous TCP name-to-address resolution.
Definition: gresolver.h:45
GNet::Address
The Address class encapsulates an IP transport address.
Definition: gaddress.h:48
GNet::ResolverImp::resolveReq
bool resolveReq(std::string host_part, std::string service_part, bool udp)
Definition: gresolver_unix.cpp:103
GNet::ResolverInfo
A class that holds a host/service name pair and optionally the results of a name-to-address lookup...
Definition: gresolverinfo.h:48
md5::size_type
std::string::size_type size_type
A std::size_t type.
Definition: md5.h:43
GNet::Address::invalidAddress
static Address invalidAddress()
Returns an invalid address.
Definition: gaddress_ipv4.cpp:458
GNet::Resolver::resolveCon
virtual void resolveCon(bool success, const Address &address, std::string fqdn_or_failure_reason)
Called when the resolution process is complete.
Definition: gresolver_unix.cpp:212
G::Str::trim
static void trim(std::string &s, const std::string &ws)
Trims both ends of s, taking off any of the 'ws' characters.
Definition: gstr.cpp:133
gsimpleclient.h
glinebuffer.h
GNet::ResolverImp::onSendComplete
virtual void onSendComplete()
Called when all residual data from send() has been sent.
Definition: gresolver_unix.cpp:123
gstr.h
gevent.h
GNet::EventHandler
A base class for classes that handle asynchronous socket events.
Definition: geventhandler.h:54
GNet::ResolverImp::onData
virtual void onData(const char *, std::string::size_type)
Called when data is read from the socket.
Definition: gresolver_unix.cpp:131
G_DEBUG
#define G_DEBUG(expr)
Definition: glog.h:95
gsocket.h
gexception.h
GNet::ResolverImp::busy
bool busy() const
Definition: gresolver_unix.cpp:171
G::Str::isPrintableAscii
static bool isPrintableAscii(const std::string &s)
Returns true if every character is a 7-bit, non-control character (ie.
Definition: gstr.cpp:167
GNet::Address::validString
static bool validString(const std::string &display_string, std::string *reason=NULL)
Returns true if the display string is valid.
Definition: gaddress_ipv4.cpp:591
GNet::LineBuffer
A class which does line buffering.
Definition: glinebuffer.h:52
GNet::Resolver::busy
bool busy() const
Returns true if there is a pending resolve request.
Definition: gresolver_unix.cpp:217
GNet::SimpleClient::resolverInfo
ResolverInfo resolverInfo() const
Returns a ResolverInfo structure containing the result of host() and service() name lookup if availab...
Definition: gsimpleclient.cpp:75
GNet::ResolverImp::~ResolverImp
virtual ~ResolverImp()
Definition: gresolver_unix.cpp:92
GNet::ResolverImp::ResolverImp
ResolverImp(EventHandler &event_handler, Resolver &resolver, unsigned int port)
Definition: gresolver_unix.cpp:85
GNet::ResolverImp::onException
virtual void onException(std::exception &)
Called when an exception is thrown out of readEvent(), writeEvent() or exceptionEvent().
Definition: gresolver_unix.cpp:158
GNet::Resolver::resolveReq
bool resolveReq(std::string name, bool udp=false)
Initiates a name-to-address resolution.
Definition: gresolver_unix.cpp:188
GNet::Resolver::Resolver
Resolver(EventHandler &)
Constructor taking an event handler reference.
Definition: gresolver_unix.cpp:178
gmemory.h
GNet::ResolverImp
A pimple-pattern implementation class for GNet::Resolver.
Definition: gresolver_unix.cpp:49
gdebug.h
gresolver.h