diff options
Diffstat (limited to 'cpp/src/Ice/Endpoint.cpp')
-rw-r--r-- | cpp/src/Ice/Endpoint.cpp | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/cpp/src/Ice/Endpoint.cpp b/cpp/src/Ice/Endpoint.cpp index 399d7fcfd01..699311c72c3 100644 --- a/cpp/src/Ice/Endpoint.cpp +++ b/cpp/src/Ice/Endpoint.cpp @@ -17,6 +17,7 @@ #include <Ice/SslConnector.h> #include <Ice/SslTransceiver.h> #include <Ice/UdpTransceiver.h> +#include <Ice/SUdpTransceiver.h> #include <Ice/BasicStream.h> #include <Ice/Exception.h> #include <Ice/Instance.h> @@ -67,6 +68,11 @@ IceInternal::Endpoint::endpointFromString(const InstancePtr& instance, const str return new UdpEndpoint(instance, str.substr(end)); } + if (protocol == "sudp") + { + return new SUdpEndpoint(instance, str.substr(end)); + } + throw EndpointParseException(__FILE__, __LINE__); } @@ -96,6 +102,12 @@ IceInternal::Endpoint::streamRead(BasicStream* s, EndpointPtr& v) break; } + case SUdpEndpointType: + { + v = new SUdpEndpoint(s); + break; + } + default: { v = new UnknownEndpoint(s); @@ -514,6 +526,11 @@ IceInternal::TcpEndpoint::operator<(const Endpoint& r) const return false; // tcp is not "less than" udp } + if (dynamic_cast<const SUdpEndpoint*>(&r)) + { + return false; // tcp is not "less than" sudp + } + if (dynamic_cast<const UnknownEndpoint*>(&r)) { return false; // tcp is not "less than" unknown @@ -816,6 +833,11 @@ IceInternal::SslEndpoint::operator<(const Endpoint& r) const return false; // ssl is not "less than" udp } + if (dynamic_cast<const SUdpEndpoint*>(&r)) + { + return false; // ssl is not "less than" sudp + } + if (dynamic_cast<const UnknownEndpoint*>(&r)) { return false; // ssl is not "less than" unknown @@ -1095,6 +1117,11 @@ IceInternal::UdpEndpoint::operator<(const Endpoint& r) const return true; // udp is "less than" tcp } + if (dynamic_cast<const SUdpEndpoint*>(&r)) + { + return false; // udp is not "less than" sudp + } + if (dynamic_cast<const UnknownEndpoint*>(&r)) { return false; // udp is not "less than" unknown @@ -1132,3 +1159,280 @@ IceInternal::UdpEndpoint::operator<(const Endpoint& r) const return false; } + +/////////////////////////////////////// + +IceInternal::SUdpEndpoint::SUdpEndpoint(const InstancePtr& instance, const string& ho, Int po) : + _instance(instance), + _host(ho), + _port(po) +{ +} + +IceInternal::SUdpEndpoint::SUdpEndpoint(const InstancePtr& instance, const string& str) : + _instance(instance), + _port(0) +{ + const string delim = " \t\n\r"; + + string::size_type beg; + string::size_type end = 0; + + while (true) + { + beg = str.find_first_not_of(delim, end); + if (beg == string::npos) + { + break; + } + + end = str.find_first_of(delim, beg); + if (end == string::npos) + { + end = str.length(); + } + + string option = str.substr(beg, end - beg); + if (option.length() != 2 || option[0] != '-') + { + throw EndpointParseException(__FILE__, __LINE__); + } + + beg = str.find_first_not_of(delim, end); + if (beg == string::npos) + { + throw EndpointParseException(__FILE__, __LINE__); + } + + end = str.find_first_of(delim, beg); + if (end == string::npos) + { + end = str.length(); + } + + string argument = str.substr(beg, end - beg); + + switch (option[1]) + { + case 'h': + { + const_cast<string&>(_host) = argument; + break; + } + + case 'p': + { + const_cast<Int&>(_port) = atoi(argument.c_str()); + break; + } + + default: + { + throw EndpointParseException(__FILE__, __LINE__); + } + } + } + + if (_host.empty()) + { + const_cast<string&>(_host) = _instance->defaultHost(); + } +} + +IceInternal::SUdpEndpoint::SUdpEndpoint(BasicStream* s) : + _instance(s->instance()), + _port(0) +{ + s->startReadEncaps(); + s->read(const_cast<string&>(_host)); + s->read(const_cast<Int&>(_port)); + s->endReadEncaps(); +} + +void +IceInternal::SUdpEndpoint::streamWrite(BasicStream* s) const +{ + s->write(SUdpEndpointType); + s->startWriteEncaps(); + s->write(_host); + s->write(_port); + s->endWriteEncaps(); +} + +string +IceInternal::SUdpEndpoint::toString() const +{ + ostringstream s; + s << "sudp -h " << _host << " -p " << _port; + return s.str(); +} + +Short +IceInternal::SUdpEndpoint::type() const +{ + return SUdpEndpointType; +} + +Int +IceInternal::SUdpEndpoint::timeout() const +{ + return -1; +} + +EndpointPtr +IceInternal::SUdpEndpoint::timeout(Int) const +{ + return const_cast<SUdpEndpoint*>(this); +} + +bool +IceInternal::SUdpEndpoint::datagram() const +{ + return true; +} + +bool +IceInternal::SUdpEndpoint::secure() const +{ + return true; +} + +TransceiverPtr +IceInternal::SUdpEndpoint::clientTransceiver() const +{ + return new SUdpTransceiver(_instance, _host, _port); +} + +TransceiverPtr +IceInternal::SUdpEndpoint::serverTransceiver(EndpointPtr& endp) const +{ + SUdpTransceiver* p = new SUdpTransceiver(_instance, _port); + endp = new SUdpEndpoint(_instance, _host, p->effectivePort()); + return p; +} + +ConnectorPtr +IceInternal::SUdpEndpoint::connector() const +{ + return 0; +} + +AcceptorPtr +IceInternal::SUdpEndpoint::acceptor(EndpointPtr& endp) const +{ + endp = const_cast<SUdpEndpoint*>(this); + return 0; +} + +bool +IceInternal::SUdpEndpoint::equivalent(const TransceiverPtr& transceiver) const +{ + const SUdpTransceiver* sudpTransceiver = dynamic_cast<const SUdpTransceiver*>(transceiver.get()); + if (!sudpTransceiver) + { + return false; + } + return sudpTransceiver->equivalent(_host, _port); +} + +bool +IceInternal::SUdpEndpoint::equivalent(const AcceptorPtr&) const +{ + return false; +} + +bool +IceInternal::SUdpEndpoint::operator==(const Endpoint& r) const +{ + const SUdpEndpoint* p = dynamic_cast<const SUdpEndpoint*>(&r); + if (!p) + { + return false; + } + + if (this == p) + { + return true; + } + + if (_port != p->_port) + { + return false; + } + + struct sockaddr_in laddr; + struct sockaddr_in raddr; + getAddress(_host.c_str(), _port, laddr); + getAddress(p->_host.c_str(), p->_port, raddr); + if (memcmp(&laddr, &raddr, sizeof(struct sockaddr_in)) != 0) + { + return false; + } + + return true; +} + +bool +IceInternal::SUdpEndpoint::operator!=(const Endpoint& r) const +{ + return !operator==(r); +} + +bool +IceInternal::SUdpEndpoint::operator<(const Endpoint& r) const +{ + const SUdpEndpoint* p = dynamic_cast<const SUdpEndpoint*>(&r); + if (!p) + { + if (dynamic_cast<const SslEndpoint*>(&r)) + { + return true; // sudp is "less than" ssl + } + + if (dynamic_cast<const TcpEndpoint*>(&r)) + { + return true; // sudp is "less than" tcp + } + + if (dynamic_cast<const UdpEndpoint*>(&r)) + { + return true; // sudp is "less than" udp + } + + if (dynamic_cast<const UnknownEndpoint*>(&r)) + { + return false; // sudp is not "less than" unknown + } + + assert(false); + } + + if (this == p) + { + return false; + } + + struct sockaddr_in laddr; + struct sockaddr_in raddr; + getAddress(_host.c_str(), _port, laddr); + getAddress(p->_host.c_str(), p->_port, raddr); + if (laddr.sin_addr.s_addr < raddr.sin_addr.s_addr) + { + return true; + } + else if (raddr.sin_addr.s_addr < laddr.sin_addr.s_addr) + { + return false; + } + + if (_port < p->_port) + { + return true; + } + else if (p->_port < _port) + { + return false; + } + + return false; +} |