1 // **********************************************************************
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
8 // **********************************************************************
10 #include <IceSSL/EndpointI.h>
11 #include <IceSSL/AcceptorI.h>
12 #include <IceSSL/ConnectorI.h>
13 #include <IceSSL/TransceiverI.h>
14 #include <IceSSL/Instance.h>
15 #include <Ice/Network.h>
16 #include <Ice/BasicStream.h>
17 #include <Ice/LocalException.h>
18 #include <Ice/DefaultsAndOverrides.h>
19 #include <Ice/HashUtil.h>
23 using namespace IceSSL
;
25 IceSSL::EndpointI::EndpointI(const InstancePtr
& instance
, const string
& ho
, Int po
, Int ti
, const string
& conId
,
36 IceSSL::EndpointI::EndpointI(const InstancePtr
& instance
, const string
& str
, bool oaEndpoint
) :
42 const string delim
= " \t\n\r";
44 string::size_type beg
;
45 string::size_type end
= 0;
49 beg
= str
.find_first_not_of(delim
, end
);
50 if(beg
== string::npos
)
55 end
= str
.find_first_of(delim
, beg
);
56 if(end
== string::npos
)
61 string option
= str
.substr(beg
, end
- beg
);
62 if(option
.length() != 2 || option
[0] != '-')
64 EndpointParseException
ex(__FILE__
, __LINE__
);
65 ex
.str
= "expected an endpoint option but found `" + option
+ "' in endpoint `ssl " + str
+ "'";
70 string::size_type argumentBeg
= str
.find_first_not_of(delim
, end
);
71 if(argumentBeg
!= string::npos
&& str
[argumentBeg
] != '-')
74 end
= str
.find_first_of(delim
, beg
);
75 if(end
== string::npos
)
79 argument
= str
.substr(beg
, end
- beg
);
80 if(argument
[0] == '\"' && argument
[argument
.size() - 1] == '\"')
82 argument
= argument
.substr(1, argument
.size() - 2);
92 EndpointParseException
ex(__FILE__
, __LINE__
);
93 ex
.str
= "no argument provided for -h option in endpoint `ssl " + str
+ "'";
96 const_cast<string
&>(_host
) = argument
;
104 EndpointParseException
ex(__FILE__
, __LINE__
);
105 ex
.str
= "no argument provided for -p option in endpoint `ssl " + str
+ "'";
108 istringstream
p(argument
);
109 if(!(p
>> const_cast<Int
&>(_port
)) || !p
.eof())
111 EndpointParseException
ex(__FILE__
, __LINE__
);
112 ex
.str
= "invalid port value `" + argument
+ "' in endpoint `ssl " + str
+ "'";
115 else if(_port
< 0 || _port
> 65535)
117 EndpointParseException
ex(__FILE__
, __LINE__
);
118 ex
.str
= "port value `" + argument
+ "' out of range in endpoint `ssl " + str
+ "'";
128 EndpointParseException
ex(__FILE__
, __LINE__
);
129 ex
.str
= "no argument provided for -t option in endpoint `ssl " + str
+ "'";
132 istringstream
t(argument
);
133 if(!(t
>> const_cast<Int
&>(_timeout
)) || !t
.eof())
135 EndpointParseException
ex(__FILE__
, __LINE__
);
136 ex
.str
= "invalid timeout value `" + argument
+ "' in endpoint `ssl " + str
+ "'";
144 if(!argument
.empty())
146 EndpointParseException
ex(__FILE__
, __LINE__
);
147 ex
.str
= "unexpected argument `" + argument
+ "' provided for -z option in `ssl " + str
+ "'";
150 const_cast<bool&>(_compress
) = true;
156 EndpointParseException
ex(__FILE__
, __LINE__
);
157 ex
.str
= "unknown option `" + option
+ "' in `ssl " + str
+ "'";
165 const_cast<string
&>(_host
) = _instance
->defaultHost();
167 else if(_host
== "*")
171 const_cast<string
&>(_host
) = string();
175 EndpointParseException
ex(__FILE__
, __LINE__
);
176 ex
.str
= "`-h *' not valid for proxy endpoint `ssl " + str
+ "'";
182 IceSSL::EndpointI::EndpointI(const InstancePtr
& instance
, IceInternal::BasicStream
* s
) :
188 s
->startReadEncaps();
189 s
->read(const_cast<string
&>(_host
), false);
190 s
->read(const_cast<Int
&>(_port
));
191 s
->read(const_cast<Int
&>(_timeout
));
192 s
->read(const_cast<bool&>(_compress
));
197 IceSSL::EndpointI::streamWrite(IceInternal::BasicStream
* s
) const
199 s
->write(EndpointType
);
200 s
->startWriteEncaps();
201 s
->write(_host
, false);
209 IceSSL::EndpointI::toString() const
212 // WARNING: Certain features, such as proxy validation in Glacier2,
213 // depend on the format of proxy strings. Changes to toString() and
214 // methods called to generate parts of the reference string could break
215 // these features. Please review for all features that depend on the
216 // format of proxyToString() before changing this and related code.
224 bool addQuote
= _host
.find(':') != string::npos
;
236 s
<< " -p " << _port
;
239 s
<< " -t " << _timeout
;
249 // COMPILERFIX: VC6 complains about an ambiguous "EndpointInfo" symbol when this class is defined inside
250 // getInfo(). Moving the definition into an anonymous namespace works around it.
254 class InfoI
: public IceSSL::EndpointInfo
258 InfoI(Int to
, bool comp
, const string
& host
, Int port
) :
259 IceSSL::EndpointInfo(to
, comp
, host
, port
)
284 IceSSL::EndpointI::getInfo() const
286 return new InfoI(_timeout
, _compress
, _host
, _port
);
290 IceSSL::EndpointI::type() const
296 IceSSL::EndpointI::timeout() const
301 IceInternal::EndpointIPtr
302 IceSSL::EndpointI::timeout(Int timeout
) const
304 if(timeout
== _timeout
)
306 return const_cast<EndpointI
*>(this);
310 return new EndpointI(_instance
, _host
, _port
, timeout
, _connectionId
, _compress
);
314 IceInternal::EndpointIPtr
315 IceSSL::EndpointI::connectionId(const string
& connectionId
) const
317 if(connectionId
== _connectionId
)
319 return const_cast<EndpointI
*>(this);
323 return new EndpointI(_instance
, _host
, _port
, _timeout
, connectionId
, _compress
);
328 IceSSL::EndpointI::compress() const
333 IceInternal::EndpointIPtr
334 IceSSL::EndpointI::compress(bool compress
) const
336 if(compress
== _compress
)
338 return const_cast<EndpointI
*>(this);
342 return new EndpointI(_instance
, _host
, _port
, _timeout
, _connectionId
, compress
);
347 IceSSL::EndpointI::datagram() const
353 IceSSL::EndpointI::secure() const
358 IceInternal::TransceiverPtr
359 IceSSL::EndpointI::transceiver(IceInternal::EndpointIPtr
& endp
) const
361 endp
= const_cast<EndpointI
*>(this);
365 vector
<IceInternal::ConnectorPtr
>
366 IceSSL::EndpointI::connectors() const
368 return connectors(IceInternal::getAddresses(_host
, _port
, _instance
->protocolSupport(), true));
372 IceSSL::EndpointI::connectors_async(const IceInternal::EndpointI_connectorsPtr
& callback
) const
374 _instance
->endpointHostResolver()->resolve(_host
, _port
, const_cast<EndpointI
*>(this), callback
);
377 IceInternal::AcceptorPtr
378 IceSSL::EndpointI::acceptor(IceInternal::EndpointIPtr
& endp
, const string
& adapterName
) const
380 AcceptorI
* p
= new AcceptorI(_instance
, adapterName
, _host
, _port
);
381 endp
= new EndpointI(_instance
, _host
, p
->effectivePort(), _timeout
, _connectionId
, _compress
);
385 vector
<IceInternal::EndpointIPtr
>
386 IceSSL::EndpointI::expand() const
388 vector
<IceInternal::EndpointIPtr
> endps
;
389 vector
<string
> hosts
= IceInternal::getHostsForEndpointExpand(_host
, _instance
->protocolSupport(), false);
392 endps
.push_back(const_cast<EndpointI
*>(this));
396 for(vector
<string
>::const_iterator p
= hosts
.begin(); p
!= hosts
.end(); ++p
)
398 endps
.push_back(new EndpointI(_instance
, *p
, _port
, _timeout
, _connectionId
, _compress
));
405 IceSSL::EndpointI::equivalent(const IceInternal::EndpointIPtr
& endpoint
) const
407 const EndpointI
* sslEndpointI
= dynamic_cast<const EndpointI
*>(endpoint
.get());
412 return sslEndpointI
->_host
== _host
&& sslEndpointI
->_port
== _port
;
416 IceSSL::EndpointI::operator==(const Ice::LocalObject
& r
) const
418 const EndpointI
* p
= dynamic_cast<const EndpointI
*>(&r
);
429 if(_host
!= p
->_host
)
434 if(_port
!= p
->_port
)
439 if(_timeout
!= p
->_timeout
)
444 if(_connectionId
!= p
->_connectionId
)
449 if(_compress
!= p
->_compress
)
458 IceSSL::EndpointI::operator<(const Ice::LocalObject
& r
) const
460 const EndpointI
* p
= dynamic_cast<const EndpointI
*>(&r
);
463 const IceInternal::EndpointI
* e
= dynamic_cast<const IceInternal::EndpointI
*>(&r
);
468 return type() < e
->type();
480 else if (p
->_host
< _host
)
489 else if(p
->_port
< _port
)
494 if(_timeout
< p
->_timeout
)
498 else if(p
->_timeout
< _timeout
)
503 if(_connectionId
< p
->_connectionId
)
507 else if(p
->_connectionId
< _connectionId
)
512 if(!_compress
&& p
->_compress
)
516 else if(p
->_compress
< _compress
)
525 IceSSL::EndpointI::hashInit() const
528 IceInternal::hashAdd(h
, _host
);
529 IceInternal::hashAdd(h
, _port
);
530 IceInternal::hashAdd(h
, _timeout
);
531 IceInternal::hashAdd(h
, _connectionId
);
532 IceInternal::hashAdd(h
, _compress
);
536 vector
<IceInternal::ConnectorPtr
>
537 IceSSL::EndpointI::connectors(const vector
<struct sockaddr_storage
>& addresses
) const
539 vector
<IceInternal::ConnectorPtr
> connectors
;
540 for(unsigned int i
= 0; i
< addresses
.size(); ++i
)
542 connectors
.push_back(new ConnectorI(_instance
, _host
, addresses
[i
], _timeout
, _connectionId
));
547 IceSSL::EndpointFactoryI::EndpointFactoryI(const InstancePtr
& instance
)
548 : _instance(instance
)
552 IceSSL::EndpointFactoryI::~EndpointFactoryI()
557 IceSSL::EndpointFactoryI::type() const
563 IceSSL::EndpointFactoryI::protocol() const
568 IceInternal::EndpointIPtr
569 IceSSL::EndpointFactoryI::create(const string
& str
, bool oaEndpoint
) const
571 return new EndpointI(_instance
, str
, oaEndpoint
);
574 IceInternal::EndpointIPtr
575 IceSSL::EndpointFactoryI::read(IceInternal::BasicStream
* s
) const
577 return new EndpointI(_instance
, s
);
581 IceSSL::EndpointFactoryI::destroy()