summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/FreezeScript/Scanner.l2
-rw-r--r--cpp/src/Glacier2/SessionRouterI.cpp10
-rw-r--r--cpp/src/Ice/Application.cpp2
-rw-r--r--cpp/src/Ice/Base64.cpp271
-rw-r--r--cpp/src/Ice/Base64.h36
-rw-r--r--cpp/src/Ice/ConnectionFactory.cpp18
-rw-r--r--cpp/src/Ice/EndpointFactoryManager.cpp2
-rw-r--r--cpp/src/Ice/EndpointFactoryManager.h1
-rw-r--r--cpp/src/Ice/EndpointI.cpp10
-rw-r--r--cpp/src/Ice/EndpointI.h5
-rw-r--r--cpp/src/Ice/Instance.cpp34
-rw-r--r--cpp/src/Ice/Instance.h2
-rw-r--r--cpp/src/Ice/Makefile.mak1
-rw-r--r--cpp/src/Ice/Network.cpp933
-rw-r--r--cpp/src/Ice/Network.h33
-rw-r--r--cpp/src/Ice/ObjectAdapterI.cpp71
-rw-r--r--cpp/src/Ice/ObjectAdapterI.h2
-rw-r--r--cpp/src/Ice/PropertyNames.cpp2
-rw-r--r--cpp/src/Ice/ProtocolPluginFacade.cpp6
-rw-r--r--cpp/src/Ice/ReferenceFactory.cpp43
-rw-r--r--cpp/src/Ice/TcpAcceptor.cpp10
-rw-r--r--cpp/src/Ice/TcpAcceptor.h6
-rw-r--r--cpp/src/Ice/TcpConnector.cpp7
-rw-r--r--cpp/src/Ice/TcpConnector.h6
-rw-r--r--cpp/src/Ice/TcpEndpointI.cpp74
-rw-r--r--cpp/src/Ice/TcpEndpointI.h2
-rw-r--r--cpp/src/Ice/ThreadPool.cpp1
-rw-r--r--cpp/src/Ice/UdpConnector.cpp3
-rw-r--r--cpp/src/Ice/UdpConnector.h7
-rw-r--r--cpp/src/Ice/UdpEndpointI.cpp74
-rw-r--r--cpp/src/Ice/UdpEndpointI.h2
-rw-r--r--cpp/src/Ice/UdpTransceiver.cpp78
-rw-r--r--cpp/src/Ice/UdpTransceiver.h6
-rw-r--r--cpp/src/Ice/UnknownEndpointI.cpp1
-rw-r--r--cpp/src/IceGrid/RegistryI.cpp22
-rw-r--r--cpp/src/IceSSL/AcceptorI.cpp17
-rw-r--r--cpp/src/IceSSL/AcceptorI.h7
-rw-r--r--cpp/src/IceSSL/ConnectorI.cpp5
-rw-r--r--cpp/src/IceSSL/ConnectorI.h7
-rw-r--r--cpp/src/IceSSL/EndpointI.cpp72
-rw-r--r--cpp/src/IceSSL/EndpointI.h2
-rw-r--r--cpp/src/IceSSL/Instance.cpp6
-rw-r--r--cpp/src/IceSSL/Instance.h1
-rw-r--r--cpp/src/IceSSL/TransceiverI.cpp2
-rw-r--r--cpp/src/Slice/Grammar.y71
-rw-r--r--cpp/src/Slice/GrammarUtil.h15
-rw-r--r--cpp/src/Slice/MD5.cpp56
-rw-r--r--cpp/src/Slice/MD5.h44
-rw-r--r--cpp/src/Slice/MD5I.cpp381
-rw-r--r--cpp/src/Slice/MD5I.h91
-rw-r--r--cpp/src/Slice/Makefile1
-rw-r--r--cpp/src/Slice/Makefile.mak5
-rw-r--r--cpp/src/Slice/Parser.cpp31
-rw-r--r--cpp/src/Slice/Scanner.l7
-rwxr-xr-xcpp/src/Slice/VbUtil.cpp1294
-rw-r--r--cpp/src/slice2html/Gen.cpp63
56 files changed, 2083 insertions, 1878 deletions
diff --git a/cpp/src/FreezeScript/Scanner.l b/cpp/src/FreezeScript/Scanner.l
index 8fa7a97c01f..b480edac7ae 100644
--- a/cpp/src/FreezeScript/Scanner.l
+++ b/cpp/src/FreezeScript/Scanner.l
@@ -124,7 +124,7 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e
{integer_constant} {
IntegerTokPtr itp = new IntegerTok;
*yylvalp = itp;
- if(!IceUtil::stringToInt64(string(yytext), itp->v))
+ if(!IceUtilInternal::stringToInt64(string(yytext), itp->v))
{
assert(itp->v != 0);
string msg = "integer constant `";
diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp
index 9e05665ce3c..830bb978243 100644
--- a/cpp/src/Glacier2/SessionRouterI.cpp
+++ b/cpp/src/Glacier2/SessionRouterI.cpp
@@ -778,10 +778,10 @@ Glacier2::SessionRouterI::createSessionFromSecureConnection_async(
try
{
IceSSL::ConnectionInfo info = IceSSL::getConnectionInfo(current.con);
- sslinfo.remotePort = ntohs(info.remoteAddr.sin_port);
- sslinfo.remoteHost = IceInternal::inetAddrToString(info.remoteAddr.sin_addr);
- sslinfo.localPort = ntohs(info.localAddr.sin_port);
- sslinfo.localHost = IceInternal::inetAddrToString(info.localAddr.sin_addr);
+ sslinfo.remotePort = IceInternal::getPort(info.remoteAddr);
+ sslinfo.remoteHost = IceInternal::inetAddrToString(info.remoteAddr);
+ sslinfo.localPort = IceInternal::getPort(info.localAddr);
+ sslinfo.localHost = IceInternal::inetAddrToString(info.localAddr);
sslinfo.cipher = info.cipher;
@@ -804,7 +804,7 @@ Glacier2::SessionRouterI::createSessionFromSecureConnection_async(
sslCtx["SSL.Remote.Port"] = os.str();
sslCtx["SSL.Remote.Host"] = sslinfo.remoteHost;
os.str("");
- os << ntohs(info.localAddr.sin_port);
+ os << sslinfo.localPort;
sslCtx["SSL.Local.Port"] = os.str();
sslCtx["SSL.Local.Host"] = sslinfo.localHost;
if(info.certs.size() > 0)
diff --git a/cpp/src/Ice/Application.cpp b/cpp/src/Ice/Application.cpp
index c28bfac02f1..1e84d1f4957 100644
--- a/cpp/src/Ice/Application.cpp
+++ b/cpp/src/Ice/Application.cpp
@@ -652,7 +652,7 @@ Ice::Application::mainInternal(int argc, char* argv[], const InitializationData&
}
catch(const std::exception& ex)
{
- cerr << _appName << ex.what() << endl;
+ cerr << _appName << ": " << ex.what() << endl;
status = EXIT_FAILURE;
}
catch(...)
diff --git a/cpp/src/Ice/Base64.cpp b/cpp/src/Ice/Base64.cpp
new file mode 100644
index 00000000000..9f241146534
--- /dev/null
+++ b/cpp/src/Ice/Base64.cpp
@@ -0,0 +1,271 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Base64.h>
+#ifdef __BCPLUSPLUS__
+# include <iterator>
+#endif
+
+using namespace std;
+
+string
+IceInternal::Base64::encode(const vector<unsigned char>& plainSeq)
+{
+ string retval;
+
+ if(plainSeq.size() == 0)
+ {
+ return retval;
+ }
+
+ // Reserve enough space for the returned base64 string
+ size_t base64Bytes = (((plainSeq.size() * 4) / 3) + 1);
+ size_t newlineBytes = (((base64Bytes * 2) / 76) + 1);
+ size_t totalBytes = base64Bytes + newlineBytes;
+
+ retval.reserve(totalBytes);
+
+ unsigned char by1 = 0;
+ unsigned char by2 = 0;
+ unsigned char by3 = 0;
+ unsigned char by4 = 0;
+ unsigned char by5 = 0;
+ unsigned char by6 = 0;
+ unsigned char by7 = 0;
+
+ for(size_t i = 0; i < plainSeq.size(); i += 3)
+ {
+ by1 = plainSeq[i];
+ by2 = 0;
+ by3 = 0;
+
+ if((i + 1) < plainSeq.size())
+ {
+ by2 = plainSeq[i+1];
+ }
+
+ if((i + 2) < plainSeq.size())
+ {
+ by3 = plainSeq[i+2];
+ }
+
+ by4 = by1 >> 2;
+ by5 = ((by1 & 0x3) << 4) | (by2 >> 4);
+ by6 = ((by2 & 0xf) << 2) | (by3 >> 6);
+ by7 = by3 & 0x3f;
+
+ retval += encode(by4);
+ retval += encode(by5);
+
+ if((i + 1) < plainSeq.size())
+ {
+ retval += encode(by6);
+ }
+ else
+ {
+ retval += "=";
+ }
+
+ if((i + 2) < plainSeq.size())
+ {
+ retval += encode(by7);
+ }
+ else
+ {
+ retval += "=";
+ }
+ }
+
+ string outString;
+ outString.reserve(totalBytes);
+ string::iterator iter = retval.begin();
+
+ while((retval.end() - iter) > 76)
+ {
+ copy(iter, iter+76, back_inserter(outString));
+ outString += "\r\n";
+ iter += 76;
+ }
+
+ copy(iter, retval.end(), back_inserter(outString));
+
+ return outString;
+}
+
+vector<unsigned char>
+IceInternal::Base64::decode(const string& str)
+{
+ string newStr;
+
+ newStr.reserve(str.length());
+
+ for(size_t j = 0; j < str.length(); j++)
+ {
+ if(isBase64(str[j]))
+ {
+ newStr += str[j];
+ }
+ }
+
+ vector<unsigned char> retval;
+
+ if(newStr.length() == 0)
+ {
+ return retval;
+ }
+
+ // Note: This is how we were previously computing the size of the return
+ // sequence. The method below is more efficient (and correct).
+ // size_t lines = str.size() / 78;
+ // size_t totalBytes = (lines * 76) + (((str.size() - (lines * 78)) * 3) / 4);
+
+ // Figure out how long the final sequence is going to be.
+ size_t totalBytes = (newStr.size() * 3 / 4) + 1;
+
+ retval.reserve(totalBytes);
+
+ unsigned char by1 = 0;
+ unsigned char by2 = 0;
+ unsigned char by3 = 0;
+ unsigned char by4 = 0;
+
+ char c1, c2, c3, c4;
+
+ for(size_t i = 0; i < newStr.length(); i += 4)
+ {
+ c1 = 'A';
+ c2 = 'A';
+ c3 = 'A';
+ c4 = 'A';
+
+ c1 = newStr[i];
+
+ if((i + 1) < newStr.length())
+ {
+ c2 = newStr[i + 1];
+ }
+
+ if((i + 2) < newStr.length())
+ {
+ c3 = newStr[i + 2];
+ }
+
+ if((i + 3) < newStr.length())
+ {
+ c4 = newStr[i + 3];
+ }
+
+ by1 = decode(c1);
+ by2 = decode(c2);
+ by3 = decode(c3);
+ by4 = decode(c4);
+
+ retval.push_back((by1 << 2) | (by2 >> 4));
+
+ if(c3 != '=')
+ {
+ retval.push_back(((by2 & 0xf) << 4) | (by3 >> 2));
+ }
+
+ if(c4 != '=')
+ {
+ retval.push_back(((by3 & 0x3) << 6) | by4);
+ }
+ }
+
+ return retval;
+}
+
+bool
+IceInternal::Base64::isBase64(char c)
+{
+ if(c >= 'A' && c <= 'Z')
+ {
+ return true;
+ }
+
+ if(c >= 'a' && c <= 'z')
+ {
+ return true;
+ }
+
+ if(c >= '0' && c <= '9')
+ {
+ return true;
+ }
+
+ if(c == '+')
+ {
+ return true;
+ }
+
+ if(c == '/')
+ {
+ return true;
+ }
+
+ if(c == '=')
+ {
+ return true;
+ }
+
+ return false;
+}
+
+char
+IceInternal::Base64::encode(unsigned char uc)
+{
+ if(uc < 26)
+ {
+ return 'A' + uc;
+ }
+
+ if(uc < 52)
+ {
+ return 'a' + (uc - 26);
+ }
+
+ if(uc < 62)
+ {
+ return '0' + (uc - 52);
+ }
+
+ if(uc == 62)
+ {
+ return '+';
+ }
+
+ return '/';
+}
+
+unsigned char
+IceInternal::Base64::decode(char c)
+{
+ if(c >= 'A' && c <= 'Z')
+ {
+ return c - 'A';
+ }
+
+ if(c >= 'a' && c <= 'z')
+ {
+ return c - 'a' + 26;
+ }
+
+ if(c >= '0' && c <= '9')
+ {
+ return c - '0' + 52;
+ }
+
+ if(c == '+')
+ {
+ return 62;
+ }
+
+ return 63;
+}
diff --git a/cpp/src/Ice/Base64.h b/cpp/src/Ice/Base64.h
new file mode 100644
index 00000000000..fece85491bb
--- /dev/null
+++ b/cpp/src/Ice/Base64.h
@@ -0,0 +1,36 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_BASE_64_H
+#define ICE_BASE_64_H
+
+#include <Ice/Config.h>
+#include <string>
+#include <vector>
+
+namespace IceInternal
+{
+
+class Base64
+{
+public:
+
+ static std::string encode(const std::vector<unsigned char>&);
+ static std::vector<unsigned char> decode(const std::string&);
+ static bool isBase64(char);
+
+private:
+
+ static char encode(unsigned char);
+ static unsigned char decode(char);
+};
+
+}
+
+#endif
diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp
index 94079e88077..39e5a178dd0 100644
--- a/cpp/src/Ice/ConnectionFactory.cpp
+++ b/cpp/src/Ice/ConnectionFactory.cpp
@@ -679,7 +679,7 @@ IceInternal::OutgoingConnectionFactory::getConnection(const vector<ConnectorInfo
}
}
}
-
+
if(_destroyed)
{
throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__);
@@ -688,12 +688,14 @@ IceInternal::OutgoingConnectionFactory::getConnection(const vector<ConnectorInfo
//
// No connection to any of our endpoints exists yet; we add the given connectors to
// the _pending set to indicate that we're attempting connection establishment to
- // these connectors.
+ // these connectors. We might attempt to connect to the same connector multiple times.
//
for(vector<ConnectorInfo>::const_iterator r = connectors.begin(); r != connectors.end(); ++r)
{
- assert(_pending.find(*r) == _pending.end());
- _pending.insert(pair<ConnectorInfo, set<ConnectCallbackPtr> >(*r, set<ConnectCallbackPtr>()));
+ if(_pending.find(*r) == _pending.end())
+ {
+ _pending.insert(pair<ConnectorInfo, set<ConnectCallbackPtr> >(*r, set<ConnectCallbackPtr>()));
+ }
}
}
@@ -769,9 +771,11 @@ IceInternal::OutgoingConnectionFactory::finishGetConnection(const vector<Connect
for(vector<ConnectorInfo>::const_iterator p = connectors.begin(); p != connectors.end(); ++p)
{
map<ConnectorInfo, set<ConnectCallbackPtr> >::iterator q = _pending.find(*p);
- assert(q != _pending.end());
- callbacks.insert(q->second.begin(), q->second.end());
- _pending.erase(q);
+ if(q != _pending.end())
+ {
+ callbacks.insert(q->second.begin(), q->second.end());
+ _pending.erase(q);
+ }
}
notifyAll();
diff --git a/cpp/src/Ice/EndpointFactoryManager.cpp b/cpp/src/Ice/EndpointFactoryManager.cpp
index 9b1a126a1d6..b47686f19b7 100644
--- a/cpp/src/Ice/EndpointFactoryManager.cpp
+++ b/cpp/src/Ice/EndpointFactoryManager.cpp
@@ -111,7 +111,7 @@ IceInternal::EndpointFactoryManager::create(const string& str, bool oaEndpoint)
return factory->create(str.substr(end), oaEndpoint);
#else
// Code below left in place for debugging.
-
+
EndpointIPtr e = factory->create(str.substr(end), oaEndpoint);
BasicStream bs(_instance.get());
e->streamWrite(&bs);
diff --git a/cpp/src/Ice/EndpointFactoryManager.h b/cpp/src/Ice/EndpointFactoryManager.h
index c2e5671020a..9dd5611a4f1 100644
--- a/cpp/src/Ice/EndpointFactoryManager.h
+++ b/cpp/src/Ice/EndpointFactoryManager.h
@@ -16,6 +16,7 @@
#include <Ice/EndpointIF.h>
#include <Ice/EndpointFactoryF.h>
#include <Ice/EndpointFactoryManagerF.h>
+#include <Ice/Protocol.h>
namespace IceInternal
{
diff --git a/cpp/src/Ice/EndpointI.cpp b/cpp/src/Ice/EndpointI.cpp
index 2ae93da7362..8edb81f99a1 100644
--- a/cpp/src/Ice/EndpointI.cpp
+++ b/cpp/src/Ice/EndpointI.cpp
@@ -19,7 +19,7 @@ Ice::LocalObject* IceInternal::upCast(EndpointI* p) { return p; }
IceUtil::Shared* IceInternal::upCast(EndpointHostResolver* p) { return p; }
vector<ConnectorPtr>
-IceInternal::EndpointI::connectors(const vector<struct sockaddr_in>& addrs) const
+IceInternal::EndpointI::connectors(const vector<struct sockaddr_storage>& addrs) const
{
//
// This method must be extended by endpoints which use the EndpointHostResolver to create
@@ -37,7 +37,7 @@ IceInternal::EndpointHostResolver::EndpointHostResolver(const InstancePtr& insta
}
void
-IceInternal::EndpointHostResolver::resolve(const string& host, int port, const EndpointIPtr& endpoint,
+IceInternal::EndpointHostResolver::resolve(const string& host, int port, const EndpointIPtr& endpoint,
const EndpointI_connectorsPtr& callback)
{
//
@@ -46,7 +46,7 @@ IceInternal::EndpointHostResolver::resolve(const string& host, int port, const E
//
try
{
- vector<struct sockaddr_in> addrs = getAddresses(host, port, false);
+ vector<struct sockaddr_storage> addrs = getAddresses(host, port, _instance->protocolSupport(), false);
if(!addrs.empty())
{
callback->connectors(endpoint->connectors(addrs));
@@ -109,7 +109,9 @@ IceInternal::EndpointHostResolver::run()
_queue.pop_front();
}
- resolve.callback->connectors(resolve.endpoint->connectors(getAddresses(resolve.host, resolve.port)));
+ resolve.callback->connectors(
+ resolve.endpoint->connectors(
+ getAddresses(resolve.host, resolve.port, _instance->protocolSupport(), true)));
}
for(deque<ResolveEntry>::const_iterator p = _queue.begin(); p != _queue.end(); ++p)
diff --git a/cpp/src/Ice/EndpointI.h b/cpp/src/Ice/EndpointI.h
index 1d5eff2df76..63f8c18abf3 100644
--- a/cpp/src/Ice/EndpointI.h
+++ b/cpp/src/Ice/EndpointI.h
@@ -19,6 +19,7 @@
#include <Ice/TransceiverF.h>
#include <Ice/ConnectorF.h>
#include <Ice/AcceptorF.h>
+#include <Ice/Protocol.h>
#ifdef _WIN32
# include <winsock2.h>
@@ -131,7 +132,7 @@ public:
//
// Expand endpoint out in to separate endpoints for each local
- // host if listening on INADDR_ANY.
+ // host if listening on INADDR_ANY on server side.
//
virtual std::vector<EndpointIPtr> expand() const = 0;
@@ -149,7 +150,7 @@ public:
private:
- virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_in>&) const;
+ virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_storage>&) const;
friend class EndpointHostResolver;
#if defined(__SUNPRO_CC) || defined(__HP_aCC)
diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp
index 38984229732..5fedbabce4c 100644
--- a/cpp/src/Ice/Instance.cpp
+++ b/cpp/src/Ice/Instance.cpp
@@ -199,6 +199,19 @@ IceInternal::Instance::objectAdapterFactory() const
return _objectAdapterFactory;
}
+ProtocolSupport
+IceInternal::Instance::protocolSupport() const
+{
+ IceUtil::RecMutex::Lock sync(*this);
+
+ if(_state == StateDestroyed)
+ {
+ throw CommunicatorDestroyedException(__FILE__, __LINE__);
+ }
+
+ return _protocolSupport;
+}
+
ThreadPoolPtr
IceInternal::Instance::clientThreadPool()
{
@@ -623,7 +636,8 @@ IceInternal::Instance::getAdmin()
}
catch(const ServerNotFoundException&)
{
- throw InitializationException(__FILE__, __LINE__, "Locator knows nothing about server '" + serverId + "'");
+ throw InitializationException(__FILE__, __LINE__, "Locator knows nothing about server '" +
+ serverId + "'");
}
}
@@ -890,6 +904,24 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi
_proxyFactory = new ProxyFactory(this);
+ bool ipv4 = _initData.properties->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0;
+ bool ipv6 = _initData.properties->getPropertyAsIntWithDefault("Ice.IPv6", 0) > 0;
+ if(!ipv4 && !ipv6)
+ {
+ throw InitializationException(__FILE__, __LINE__, "Both IPV4 and IPv6 support cannot be disabled.");
+ }
+ else if(ipv4 && ipv6)
+ {
+ _protocolSupport = EnableBoth;
+ }
+ else if(ipv4)
+ {
+ _protocolSupport = EnableIPv4;
+ }
+ else
+ {
+ _protocolSupport = EnableIPv6;
+ }
_endpointFactoryManager = new EndpointFactoryManager(this);
EndpointFactoryPtr tcpEndpointFactory = new TcpEndpointFactory(this);
_endpointFactoryManager->add(tcpEndpointFactory);
diff --git a/cpp/src/Ice/Instance.h b/cpp/src/Ice/Instance.h
index cbf6ad36ecf..2c840985fe6 100644
--- a/cpp/src/Ice/Instance.h
+++ b/cpp/src/Ice/Instance.h
@@ -66,6 +66,7 @@ public:
ConnectionMonitorPtr connectionMonitor() const;
ObjectFactoryManagerPtr servantFactoryManager() const;
ObjectAdapterFactoryPtr objectAdapterFactory() const;
+ ProtocolSupport protocolSupport() const;
ThreadPoolPtr clientThreadPool();
ThreadPoolPtr serverThreadPool();
SelectorThreadPtr selectorThread();
@@ -123,6 +124,7 @@ private:
ConnectionMonitorPtr _connectionMonitor;
ObjectFactoryManagerPtr _servantFactoryManager;
ObjectAdapterFactoryPtr _objectAdapterFactory;
+ ProtocolSupport _protocolSupport;
ThreadPoolPtr _clientThreadPool;
ThreadPoolPtr _serverThreadPool;
SelectorThreadPtr _selectorThread;
diff --git a/cpp/src/Ice/Makefile.mak b/cpp/src/Ice/Makefile.mak
index 6b4d6ee0318..5beb39cb0a3 100644
--- a/cpp/src/Ice/Makefile.mak
+++ b/cpp/src/Ice/Makefile.mak
@@ -16,6 +16,7 @@ TARGETS = $(LIBNAME) $(DLLNAME)
OBJS = Acceptor.obj \
Application.obj \
+ Base64.obj \
Buffer.obj \
BasicStream.obj \
BuiltinSequences.obj \
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp
index 0bd0fa8bd4a..db66ebc4441 100644
--- a/cpp/src/Ice/Network.cpp
+++ b/cpp/src/Ice/Network.cpp
@@ -28,6 +28,7 @@
# include <ws2tcpip.h>
#elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__)
# include <ifaddrs.h>
+# include <net/if.h>
#else
# include <sys/ioctl.h>
# include <net/if.h>
@@ -44,17 +45,350 @@ using namespace IceInternal;
# define INADDR_NONE (in_addr_t)0xffffffff
#endif
-static IceUtil::StaticMutex inetMutex = ICE_STATIC_MUTEX_INITIALIZER;
+namespace
+{
-string
-IceInternal::inetAddrToString(const struct in_addr& in)
+vector<struct sockaddr_storage>
+getLocalAddresses(ProtocolSupport protocol)
+{
+ vector<struct sockaddr_storage> result;
+
+#if defined(_WIN32)
+ try
+ {
+ for(int i = 0; i < 2; i++)
+ {
+ if((i == 0 && protocol == EnableIPv6) || (i == 1 && protocol == EnableIPv4))
+ {
+ continue;
+ }
+
+ SOCKET fd = createSocket(false, i == 0 ? AF_INET : AF_INET6);
+
+ vector<unsigned char> buffer;
+ buffer.resize(1024);
+ unsigned long len = 0;
+ DWORD rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0,
+ &buffer[0], static_cast<DWORD>(buffer.size()),
+ &len, 0, 0);
+ if(rs == SOCKET_ERROR)
+ {
+ //
+ // If the buffer wasn't big enough, resize it to the
+ // required length and try again.
+ //
+ if(getSocketErrno() == WSAEFAULT)
+ {
+ buffer.resize(len);
+ rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0,
+ &buffer[0], static_cast<DWORD>(buffer.size()),
+ &len, 0, 0);
+ }
+
+ if(rs == SOCKET_ERROR)
+ {
+ closeSocketNoThrow(fd);
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+
+ //
+ // Add the local interface addresses.
+ //
+ SOCKET_ADDRESS_LIST* addrs = reinterpret_cast<SOCKET_ADDRESS_LIST*>(&buffer[0]);
+ for (int i = 0; i < addrs->iAddressCount; ++i)
+ {
+ sockaddr_storage addr;
+ memcpy(&addr, addrs->Address[i].lpSockaddr, addrs->Address[i].iSockaddrLength);
+ if(addr.ss_family == AF_INET && protocol != EnableIPv6)
+ {
+ if(reinterpret_cast<struct sockaddr_in*>(&addr)->sin_addr.s_addr != 0)
+ {
+ result.push_back(addr);
+ }
+ }
+ else if(addr.ss_family == AF_INET6 && protocol != EnableIPv4)
+ {
+ struct in6_addr* inaddr6 = &reinterpret_cast<struct sockaddr_in6*>(&addr)->sin6_addr;
+ if(!IN6_IS_ADDR_UNSPECIFIED(inaddr6) && !IN6_IS_ADDR_LOOPBACK(inaddr6))
+ {
+ result.push_back(addr);
+ }
+ }
+ }
+
+ closeSocket(fd);
+ }
+ }
+ catch(const Ice::LocalException&)
+ {
+ //
+ // TODO: Warning?
+ //
+ }
+#elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__)
+ struct ifaddrs* ifap;
+ if(::getifaddrs(&ifap) == SOCKET_ERROR)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+
+ struct ifaddrs* curr = ifap;
+ while(curr != 0)
+ {
+ if(curr->ifa_addr && !(curr->ifa_flags & IFF_LOOPBACK)) // Don't include loopback interface addresses
+ {
+ if(curr->ifa_addr->sa_family == AF_INET && protocol != EnableIPv6)
+ {
+ sockaddr_storage addr;
+ memcpy(&addr, curr->ifa_addr, sizeof(sockaddr_in));
+ if(reinterpret_cast<struct sockaddr_in*>(&addr)->sin_addr.s_addr != 0)
+ {
+ result.push_back(addr);
+ }
+ }
+ else if(curr->ifa_addr->sa_family == AF_INET6 && protocol != EnableIPv4)
+ {
+ sockaddr_storage addr;
+ memcpy(&addr, curr->ifa_addr, sizeof(sockaddr_in6));
+ if(!IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast<struct sockaddr_in6*>(&addr)->sin6_addr))
+ {
+ result.push_back(*reinterpret_cast<struct sockaddr_storage*>(curr->ifa_addr));
+ }
+ }
+ }
+
+ curr = curr->ifa_next;
+ }
+
+ ::freeifaddrs(ifap);
+#else
+ for(int i = 0; i < 2; i++)
+ {
+ if((i == 0 && protocol == EnableIPv6) || (i == 1 && protocol == EnableIPv4))
+ {
+ continue;
+ }
+ SOCKET fd = createSocket(false, i == 0 ? AF_INET : AF_INET6);
+
+#ifdef _AIX
+ int cmd = CSIOCGIFCONF;
+#else
+ int cmd = SIOCGIFCONF;
+#endif
+ struct ifconf ifc;
+ int numaddrs = 10;
+ int old_ifc_len = 0;
+
+ //
+ // Need to call ioctl multiple times since we do not know up front
+ // how many addresses there will be, and thus how large a buffer we need.
+ // We keep increasing the buffer size until subsequent calls return
+ // the same length, meaning we have all the addresses.
+ //
+ while(true)
+ {
+ int bufsize = numaddrs * static_cast<int>(sizeof(struct ifreq));
+ ifc.ifc_len = bufsize;
+ ifc.ifc_buf = (char*)malloc(bufsize);
+
+ int rs = ioctl(fd, cmd, &ifc);
+ if(rs == SOCKET_ERROR)
+ {
+ free(ifc.ifc_buf);
+ closeSocketNoThrow(fd);
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else if(ifc.ifc_len == old_ifc_len)
+ {
+ //
+ // Returned same length twice in a row, finished.
+ //
+ break;
+ }
+ else
+ {
+ old_ifc_len = ifc.ifc_len;
+ }
+
+ numaddrs += 10;
+ free(ifc.ifc_buf);
+ }
+ closeSocket(fd);
+
+ numaddrs = ifc.ifc_len / static_cast<int>(sizeof(struct ifreq));
+ struct ifreq* ifr = ifc.ifc_req;
+ for(int i = 0; i < numaddrs; ++i)
+ {
+ if(!(ifr[i].ifr_flags & IFF_LOOPBACK)) // Don't include loopback interface addresses
+ {
+ if(ifr[i].ifr_addr.sa_family == AF_INET && protocol != EnableIPv6)
+ {
+ sockaddr_storage addr;
+ memcpy(&addr, &ifr[i].ifr_addr, sizeof(sockaddr_in));
+ if(reinterpret_cast<struct sockaddr_in*>(&addr)->sin_addr.s_addr != 0)
+ {
+ result.push_back(addr);
+ }
+ }
+ else if(ifr[i].ifr_addr.sa_family == AF_INET6 && protocol != EnableIPv4)
+ {
+ sockaddr_storage addr;
+ memcpy(&addr, &ifr[i].ifr_addr, sizeof(sockaddr_in6));
+ if(!IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast<struct sockaddr_in6*>(&addr)->sin6_addr))
+ {
+ result.push_back(*reinterpret_cast<struct sockaddr_storage*>(curr->ifa_addr));
+ }
+ }
+ }
+ }
+ free(ifc.ifc_buf);
+ }
+#endif
+
+ return result;
+}
+
+void
+getAddressImpl(const string& host, int port, struct sockaddr_storage& addr, ProtocolSupport protocol, bool server)
{
//
- // inet_ntoa uses static memory on some platforms so we protect
- // access and make a copy.
+ // We now use getaddrinfo() on Windows.
//
- IceUtil::StaticMutex::Lock lock(inetMutex);
- return string(inet_ntoa(in));
+// #ifdef _WIN32
+
+// //
+// // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice.
+// //
+
+// //
+// // gethostbyname() is thread safe on Windows, with a separate hostent per thread
+// //
+// struct hostent* entry;
+// int retry = 5;
+// do
+// {
+// entry = gethostbyname(host.c_str());
+// }
+// while(entry == 0 && WSAGetLastError() == WSATRY_AGAIN && --retry >= 0);
+
+// if(entry == 0)
+// {
+// DNSException ex(__FILE__, __LINE__);
+
+// ex.error = WSAGetLastError();
+// ex.host = host;
+// throw ex;
+// }
+// memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
+
+// #else
+
+ memset(&addr, 0, sizeof(struct sockaddr_storage));
+ struct addrinfo* info = 0;
+ int retry = 5;
+
+ struct addrinfo hints = { 0 };
+
+ if(server)
+ {
+ //
+ // If host is empty, getaddrinfo will return the wildcard
+ // address instead of the loopack address.
+ //
+ hints.ai_flags |= AI_PASSIVE;
+ }
+
+ if(protocol == EnableIPv4)
+ {
+ hints.ai_family = PF_INET;
+ }
+ else if(protocol == EnableIPv6)
+ {
+ hints.ai_family = PF_INET6;
+ }
+ else
+ {
+ hints.ai_family = PF_UNSPEC;
+ }
+
+ int rs = 0;
+ do
+ {
+ if(host.empty())
+ {
+ rs = getaddrinfo(0, "0", &hints, &info);
+ }
+ else
+ {
+ rs = getaddrinfo(host.c_str(), 0, &hints, &info);
+ }
+ }
+ while(info == 0 && rs == EAI_AGAIN && --retry >= 0);
+
+ if(rs != 0)
+ {
+ DNSException ex(__FILE__, __LINE__);
+ ex.error = rs;
+ ex.host = host;
+ throw ex;
+ }
+
+ memcpy(&addr, info->ai_addr, info->ai_addrlen);
+ if(info->ai_family != PF_INET)
+ {
+ reinterpret_cast<sockaddr_in*>(&addr)->sin_port = htons(port);
+ }
+ else if(info->ai_family != AF_INET6)
+ {
+ reinterpret_cast<sockaddr_in6*>(&addr)->sin6_port = htons(port);
+ }
+ else // Unknown address family.
+ {
+ freeaddrinfo(info);
+ DNSException ex(__FILE__, __LINE__);
+ ex.host = host;
+ throw ex;
+ }
+ freeaddrinfo(info);
+}
+
+bool
+isWildcard(const string& host, ProtocolSupport protocol)
+{
+ try
+ {
+ sockaddr_storage addr;
+ getAddressImpl(host, 0, addr, protocol, false);
+ if(addr.ss_family == AF_INET)
+ {
+ struct sockaddr_in* addrin = reinterpret_cast<sockaddr_in*>(&addr);
+ if(addrin->sin_addr.s_addr == INADDR_ANY)
+ {
+ return true;
+ }
+ }
+ else if(addr.ss_family)
+ {
+ struct sockaddr_in6* addrin6 = reinterpret_cast<sockaddr_in6*>(&addr);
+ if(IN6_IS_ADDR_UNSPECIFIED(&addrin6->sin6_addr))
+ {
+ return true;
+ }
+ }
+ }
+ catch(const DNSException&)
+ {
+ }
+ return false;
+}
+
}
int
@@ -209,17 +543,17 @@ IceInternal::recvTruncated()
}
SOCKET
-IceInternal::createSocket(bool udp)
+IceInternal::createSocket(bool udp, int family)
{
SOCKET fd;
if(udp)
{
- fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
}
else
{
- fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
}
if(fd == INVALID_SOCKET)
@@ -533,9 +867,19 @@ IceInternal::setReuseAddress(SOCKET fd, bool reuse)
}
void
-IceInternal::doBind(SOCKET fd, struct sockaddr_in& addr)
+IceInternal::doBind(SOCKET fd, struct sockaddr_storage& addr)
{
- if(bind(fd, reinterpret_cast<struct sockaddr*>(&addr), int(sizeof(addr))) == SOCKET_ERROR)
+ int size;
+ if(addr.ss_family == AF_INET)
+ {
+ size = sizeof(sockaddr_in);
+ }
+ else if(addr.ss_family == AF_INET6)
+ {
+ size = sizeof(sockaddr_in6);
+ }
+
+ if(bind(fd, reinterpret_cast<struct sockaddr*>(&addr), size) == SOCKET_ERROR)
{
closeSocketNoThrow(fd);
SocketException ex(__FILE__, __LINE__);
@@ -571,10 +915,20 @@ repeatListen:
}
bool
-IceInternal::doConnect(SOCKET fd, struct sockaddr_in& addr, int timeout)
+IceInternal::doConnect(SOCKET fd, struct sockaddr_storage& addr, int timeout)
{
repeatConnect:
- if(::connect(fd, reinterpret_cast<struct sockaddr*>(&addr), int(sizeof(addr))) == SOCKET_ERROR)
+ int size;
+ if(addr.ss_family == AF_INET)
+ {
+ size = sizeof(sockaddr_in);
+ }
+ else if(addr.ss_family == AF_INET6)
+ {
+ size = sizeof(sockaddr_in6);
+ }
+
+ if(::connect(fd, reinterpret_cast<struct sockaddr*>(&addr), size) == SOCKET_ERROR)
{
if(interrupted())
{
@@ -627,7 +981,7 @@ repeatConnect:
// a server which was just deactivated if the client socket re-uses the same ephemeral
// port as the server).
//
- struct sockaddr_in localAddr;
+ struct sockaddr_storage localAddr;
fdToLocalAddress(fd, localAddr);
if(compareAddress(addr, localAddr) == 0)
{
@@ -744,9 +1098,9 @@ IceInternal::doFinishConnect(SOCKET fd, int timeout)
// a server which was just deactivated if the client socket re-uses the same ephemeral
// port as the server).
//
- struct sockaddr_in localAddr;
+ struct sockaddr_storage localAddr;
fdToLocalAddress(fd, localAddr);
- struct sockaddr_in remoteAddr;
+ struct sockaddr_storage remoteAddr;
if(fdToRemoteAddress(fd, remoteAddr) && compareAddress(remoteAddr, localAddr) == 0)
{
ConnectionRefusedException ex(__FILE__, __LINE__);
@@ -830,20 +1184,24 @@ repeatAccept:
}
void
-IceInternal::getAddress(const string& host, int port, struct sockaddr_in& addr)
+IceInternal::getAddressForServer(const string& host, int port, struct sockaddr_storage& addr, ProtocolSupport protocol)
{
- memset(&addr, 0, sizeof(struct sockaddr_in));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = inet_addr(host.c_str());
+ getAddressImpl(host, port, addr, protocol, true);
+}
- if(addr.sin_addr.s_addr == INADDR_NONE)
- {
- //
- // We now use getaddrinfo() on Windows.
- //
-// #ifdef _WIN32
+void
+IceInternal::getAddress(const string& host, int port, struct sockaddr_storage& addr, ProtocolSupport protocol)
+{
+ getAddressImpl(host, port, addr, protocol, false);
+}
+vector<struct sockaddr_storage>
+IceInternal::getAddresses(const string& host, int port, ProtocolSupport protocol, bool blocking)
+{
+ //
+ // We now use getaddrinfo() on Windows.
+ //
+// #ifdef _WIN32
// //
// // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice.
// //
@@ -851,83 +1209,185 @@ IceInternal::getAddress(const string& host, int port, struct sockaddr_in& addr)
// //
// // gethostbyname() is thread safe on Windows, with a separate hostent per thread
// //
-// struct hostent* entry;
+// struct hostent* entry = 0;
// int retry = 5;
+
// do
// {
// entry = gethostbyname(host.c_str());
// }
-// while(entry == 0 && WSAGetLastError() == WSATRY_AGAIN && --retry >= 0);
-
+// while(entry == 0 && h_errno == TRY_AGAIN && --retry >= 0);
+
// if(entry == 0)
// {
// DNSException ex(__FILE__, __LINE__);
-
-// ex.error = WSAGetLastError();
+// ex.error = h_errno;
// ex.host = host;
// throw ex;
// }
-// memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
+
+// char** p = entry->h_addr_list;
+// while(*p)
+// {
+// memcpy(&addr.sin_addr, *p, entry->h_length);
+// result.push_back(addr);
+// p++;
+// }
// #else
- struct addrinfo* info = 0;
- int retry = 5;
+ vector<struct sockaddr_storage> result;
+ struct sockaddr_storage addr;
+ memset(&addr, 0, sizeof(struct sockaddr_storage));
+
+ struct addrinfo* info = 0;
+ int retry = 5;
- struct addrinfo hints = { 0 };
+ struct addrinfo hints = { 0 };
+ if(protocol == EnableIPv4)
+ {
hints.ai_family = PF_INET;
+ }
+ else if(protocol == EnableIPv6)
+ {
+ hints.ai_family = PF_INET6;
+ }
+ else
+ {
+ hints.ai_family = PF_UNSPEC;
+ }
- int rs = 0;
- do
+ if(!blocking)
+ {
+ hints.ai_flags = AI_NUMERICHOST;
+ }
+
+ int rs = 0;
+ do
+ {
+ if(host.empty())
{
- rs = getaddrinfo(host.c_str(), 0, &hints, &info);
+ rs = getaddrinfo(0, "0", &hints, &info); // Get the address of the loopback interface
}
- while(info == 0 && rs == EAI_AGAIN && --retry >= 0);
-
- if(rs != 0)
+ else
{
- DNSException ex(__FILE__, __LINE__);
- ex.error = rs;
- ex.host = host;
- throw ex;
+ rs = getaddrinfo(host.c_str(), 0, &hints, &info);
}
+ }
+ while(info == 0 && rs == EAI_AGAIN && --retry >= 0);
- assert(info->ai_family == PF_INET);
- struct sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(info->ai_addr);
+ if(!blocking && rs == EAI_NONAME)
+ {
+ return result; // Empty result indicates that a blocking lookup is necessary.
+ }
+ else if(rs != 0)
+ {
+ DNSException ex(__FILE__, __LINE__);
+ ex.error = rs;
+ ex.host = host;
+ throw ex;
+ }
- addr.sin_addr.s_addr = sin->sin_addr.s_addr;
- freeaddrinfo(info);
+ struct addrinfo* p;
+ for(p = info; p != NULL; p = p->ai_next)
+ {
+ memcpy(&addr, p->ai_addr, p->ai_addrlen);
+ if(p->ai_family == PF_INET)
+ {
+ struct sockaddr_in* addrin = reinterpret_cast<sockaddr_in*>(&addr);
+ addrin->sin_port = htons(port);
+ if(addrin->sin_addr.s_addr == 0)
+ {
+ continue;
+ }
+ }
+ else if(p->ai_family == PF_INET6)
+ {
+ struct sockaddr_in6* addrin6 = reinterpret_cast<sockaddr_in6*>(&addr);
+ addrin6->sin6_port = htons(port);
+ if(IN6_IS_ADDR_UNSPECIFIED(&addrin6->sin6_addr))
+ {
+ continue;
+ }
+ }
+
+ bool found = false;
+ for(unsigned int i = 0; i < result.size(); ++i)
+ {
+ if(compareAddress(result[i], addr) == 0)
+ {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ result.push_back(addr);
+ }
}
+
+ freeaddrinfo(info);
+ return result;
}
int
-IceInternal::compareAddress(const struct sockaddr_in& addr1, const struct sockaddr_in& addr2)
+IceInternal::compareAddress(const struct sockaddr_storage& addr1, const struct sockaddr_storage& addr2)
{
- if(addr1.sin_family < addr2.sin_family)
+ if(addr1.ss_family < addr2.ss_family)
{
return -1;
}
- else if(addr2.sin_family < addr1.sin_family)
+ else if(addr2.ss_family < addr1.ss_family)
{
return 1;
}
- if(addr1.sin_port < addr2.sin_port)
+ if(addr1.ss_family == AF_INET)
{
- return -1;
- }
- else if(addr2.sin_port < addr1.sin_port)
- {
- return 1;
- }
+ const struct sockaddr_in* addr1in = reinterpret_cast<const sockaddr_in*>(&addr1);
+ const struct sockaddr_in* addr2in = reinterpret_cast<const sockaddr_in*>(&addr2);
- if(addr1.sin_addr.s_addr < addr2.sin_addr.s_addr)
- {
- return -1;
+ if(addr1in->sin_port < addr2in->sin_port)
+ {
+ return -1;
+ }
+ else if(addr2in->sin_port < addr1in->sin_port)
+ {
+ return 1;
+ }
+
+ if(addr1in->sin_addr.s_addr < addr2in->sin_addr.s_addr)
+ {
+ return -1;
+ }
+ else if(addr2in->sin_addr.s_addr < addr1in->sin_addr.s_addr)
+ {
+ return 1;
+ }
}
- else if(addr2.sin_addr.s_addr < addr1.sin_addr.s_addr)
+ else
{
- return 1;
+ const struct sockaddr_in6* addr1in = reinterpret_cast<const sockaddr_in6*>(&addr1);
+ const struct sockaddr_in6* addr2in = reinterpret_cast<const sockaddr_in6*>(&addr2);
+
+ if(addr1in->sin6_port < addr2in->sin6_port)
+ {
+ return -1;
+ }
+ else if(addr2in->sin6_port < addr1in->sin6_port)
+ {
+ return 1;
+ }
+
+ int res = memcmp(&addr1in->sin6_addr, &addr2in->sin6_addr, sizeof(struct in6_addr));
+ if(res < 0)
+ {
+ return -1;
+ }
+ else if(res > 0)
+ {
+ return 1;
+ }
}
return 0;
@@ -938,21 +1398,23 @@ IceInternal::createPipe(SOCKET fds[2])
{
#ifdef _WIN32
- SOCKET fd = createSocket(false);
+ SOCKET fd = createSocket(false, AF_INET);
setBlock(fd, true);
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(0);
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ struct sockaddr_in* addrin = reinterpret_cast<struct sockaddr_in*>(&addr);
+ addrin->sin_family = AF_INET;
+ addrin->sin_port = htons(0);
+ addrin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
doBind(fd, addr);
doListen(fd, 1);
try
{
- fds[0] = createSocket(false);
+ fds[0] = createSocket(false, AF_INET);
}
catch(...)
{
@@ -1268,17 +1730,17 @@ IceInternal::fdToString(SOCKET fd)
return "<closed>";
}
- struct sockaddr_in localAddr;
+ struct sockaddr_storage localAddr;
fdToLocalAddress(fd, localAddr);
- struct sockaddr_in remoteAddr;
+ struct sockaddr_storage remoteAddr;
bool peerConnected = fdToRemoteAddress(fd, remoteAddr);
return addressesToString(localAddr, remoteAddr, peerConnected);
};
std::string
-IceInternal::addressesToString(const struct sockaddr_in& localAddr, const struct sockaddr_in& remoteAddr,
+IceInternal::addressesToString(const struct sockaddr_storage& localAddr, const struct sockaddr_storage& remoteAddr,
bool peerConnected)
{
ostringstream s;
@@ -1295,9 +1757,9 @@ IceInternal::addressesToString(const struct sockaddr_in& localAddr, const struct
}
void
-IceInternal::fdToLocalAddress(SOCKET fd, struct sockaddr_in& addr)
+IceInternal::fdToLocalAddress(SOCKET fd, struct sockaddr_storage& addr)
{
- socklen_t len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
+ socklen_t len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
if(getsockname(fd, reinterpret_cast<struct sockaddr*>(&addr), &len) == SOCKET_ERROR)
{
closeSocketNoThrow(fd);
@@ -1308,9 +1770,9 @@ IceInternal::fdToLocalAddress(SOCKET fd, struct sockaddr_in& addr)
}
bool
-IceInternal::fdToRemoteAddress(SOCKET fd, struct sockaddr_in& addr)
+IceInternal::fdToRemoteAddress(SOCKET fd, struct sockaddr_storage& addr)
{
- socklen_t len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
+ socklen_t len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
if(getpeername(fd, reinterpret_cast<struct sockaddr*>(&addr), &len) == SOCKET_ERROR)
{
if(notConnected())
@@ -1330,296 +1792,89 @@ IceInternal::fdToRemoteAddress(SOCKET fd, struct sockaddr_in& addr)
}
string
-IceInternal::addrToString(const struct sockaddr_in& addr)
+IceInternal::inetAddrToString(const struct sockaddr_storage& ss)
+{
+ int size;
+ if(ss.ss_family == AF_INET)
+ {
+ size = sizeof(sockaddr_in);
+ }
+ else if(ss.ss_family == AF_INET6)
+ {
+ size = sizeof(sockaddr_in6);
+ }
+
+ char namebuf[1024];
+ namebuf[0] = '\0';
+ getnameinfo(reinterpret_cast<const struct sockaddr *>(&ss), size, namebuf, sizeof(namebuf), 0, 0, NI_NUMERICHOST);
+ return string(namebuf);
+}
+
+string
+IceInternal::addrToString(const struct sockaddr_storage& addr)
{
ostringstream s;
- s << inetAddrToString(addr.sin_addr) << ':' << ntohs(addr.sin_port);
+ string port;
+ s << inetAddrToString(addr) << ':';
+ if(addr.ss_family == AF_INET)
+ {
+ const struct sockaddr_in* addrin = reinterpret_cast<const sockaddr_in*>(&addr);
+ s << ntohs(addrin->sin_port);
+ }
+ else
+ {
+ const struct sockaddr_in6* addrin = reinterpret_cast<const sockaddr_in6*>(&addr);
+ s << ntohs(addrin->sin6_port);
+ }
return s.str();
}
-vector<struct sockaddr_in>
-IceInternal::getAddresses(const string& host, int port, bool blocking)
+int
+IceInternal::getPort(const struct sockaddr_storage& addr)
{
- vector<struct sockaddr_in> result;
-
- if(host == "0.0.0.0")
+ if(addr.ss_family == AF_INET)
{
- vector<string> hosts = getLocalHosts();
- for(unsigned int i = 0; i < hosts.size(); ++i)
- {
- struct sockaddr_in addr;
- getAddress(hosts[i], port, addr);
- result.push_back(addr);
- }
+ return ntohs(reinterpret_cast<const sockaddr_in*>(&addr)->sin_port);
}
else
{
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(struct sockaddr_in));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
-
- //
- // We now use getaddrinfo() on Windows.
- //
-// #ifdef _WIN32
-
-// //
-// // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice.
-// //
-
-// //
-// // gethostbyname() is thread safe on Windows, with a separate hostent per thread
-// //
-// struct hostent* entry = 0;
-// int retry = 5;
-
-// do
-// {
-// entry = gethostbyname(host.c_str());
-// }
-// while(entry == 0 && h_errno == TRY_AGAIN && --retry >= 0);
-
-// if(entry == 0)
-// {
-// DNSException ex(__FILE__, __LINE__);
-// ex.error = h_errno;
-// ex.host = host;
-// throw ex;
-// }
-
-// char** p = entry->h_addr_list;
-// while(*p)
-// {
-// memcpy(&addr.sin_addr, *p, entry->h_length);
-// result.push_back(addr);
-// p++;
-// }
-
-// #else
-
- struct addrinfo* info = 0;
- int retry = 5;
-
- struct addrinfo hints = { 0 };
- hints.ai_family = PF_INET;
- if(!blocking)
- {
- hints.ai_flags = AI_NUMERICHOST;
- }
-
- int rs = 0;
- do
- {
- rs = getaddrinfo(host.c_str(), 0, &hints, &info);
- }
- while(info == 0 && rs == EAI_AGAIN && --retry >= 0);
-
- if(!blocking && rs == EAI_NONAME)
- {
- return result; // Empty result indicates that a blocking lookup is necessary.
- }
- else if(rs != 0)
- {
- DNSException ex(__FILE__, __LINE__);
- ex.error = rs;
- ex.host = host;
- throw ex;
- }
-
- struct addrinfo* p;
- for(p = info; p != NULL; p = p->ai_next)
- {
- assert(p->ai_family == PF_INET);
- struct sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(p->ai_addr);
- if(sin->sin_addr.s_addr != 0)
- {
- addr.sin_addr.s_addr = sin->sin_addr.s_addr;
-
- bool found = false;
- for(unsigned int i = 0; i < result.size(); ++i)
- {
- if(compareAddress(result[i], addr) == 0)
- {
- found = true;
- break;
- }
- }
- if(!found)
- {
- result.push_back(addr);
- }
- }
- }
-
- freeaddrinfo(info);
-
-//#endif
+ return ntohs(reinterpret_cast<const sockaddr_in6*>(&addr)->sin6_port);
}
-
- return result;
}
vector<string>
-IceInternal::getLocalHosts()
+IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport protocolSupport)
{
- vector<string> result;
-
-#if defined(_WIN32)
- try
+ vector<string> hosts;
+ if(host.empty() || isWildcard(host, protocolSupport))
{
- SOCKET fd = createSocket(false);
-
- vector<unsigned char> buffer;
- buffer.resize(1024);
- unsigned long len = 0;
- DWORD rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0,
- &buffer[0], static_cast<DWORD>(buffer.size()),
- &len, 0, 0);
- if(rs == SOCKET_ERROR)
+ vector<struct sockaddr_storage> addrs = getLocalAddresses(protocolSupport);
+ for(vector<struct sockaddr_storage>::const_iterator p = addrs.begin(); p != addrs.end(); ++p)
{
//
- // If the buffer wasn't big enough, resize it to the
- // required length and try again.
+ // NOTE: We don't publish link-local IPv6 addresses as these addresses can only
+ // be accessed in general with a scope-id.
//
- if(getSocketErrno() == WSAEFAULT)
+ if(p->ss_family != AF_INET6 ||
+ !IN6_IS_ADDR_LINKLOCAL(&reinterpret_cast<const struct sockaddr_in6*>(&(*p))->sin6_addr))
{
- buffer.resize(len);
- rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0,
- &buffer[0], static_cast<DWORD>(buffer.size()),
- &len, 0, 0);
+ hosts.push_back(inetAddrToString(*p));
}
-
- if(rs == SOCKET_ERROR)
- {
- closeSocketNoThrow(fd);
- SocketException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
- }
-
- //
- // Add the local interface addresses.
- //
- SOCKET_ADDRESS_LIST* addrs = reinterpret_cast<SOCKET_ADDRESS_LIST*>(&buffer[0]);
- for (int i = 0; i < addrs->iAddressCount; ++i)
- {
- result.push_back(
- inetAddrToString(reinterpret_cast<struct sockaddr_in*>(addrs->Address[i].lpSockaddr)->sin_addr));
}
- //
- // Add the loopback interface address.
- //
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(0);
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- result.push_back(inetAddrToString(addr.sin_addr));
-
- closeSocket(fd);
- }
- catch(const Ice::LocalException&)
- {
- //
- // TODO: Warning?
- //
- }
-#elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__)
- struct ifaddrs* ifap;
- if(::getifaddrs(&ifap) == SOCKET_ERROR)
- {
- SocketException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
-
- struct ifaddrs* curr = ifap;
- while(curr != 0)
- {
- if(curr->ifa_addr && curr->ifa_addr->sa_family == AF_INET)
+ if(hosts.empty())
{
- struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(curr->ifa_addr);
- if(addr->sin_addr.s_addr != 0)
+ if(protocolSupport != EnableIPv6)
{
- result.push_back(inetAddrToString((*addr).sin_addr));
+ hosts.push_back("127.0.0.1");
}
- }
-
- curr = curr->ifa_next;
- }
-
- ::freeifaddrs(ifap);
-#else
- SOCKET fd = createSocket(false);
-
-#ifdef _AIX
- int cmd = CSIOCGIFCONF;
-#else
- int cmd = SIOCGIFCONF;
-#endif
- struct ifconf ifc;
- int numaddrs = 10;
- int old_ifc_len = 0;
-
- //
- // Need to call ioctl multiple times since we do not know up front
- // how many addresses there will be, and thus how large a buffer we need.
- // We keep increasing the buffer size until subsequent calls return
- // the same length, meaning we have all the addresses.
- //
- while(true)
- {
- int bufsize = numaddrs * static_cast<int>(sizeof(struct ifreq));
- ifc.ifc_len = bufsize;
- ifc.ifc_buf = (char*)malloc(bufsize);
-
- int rs = ioctl(fd, cmd, &ifc);
- if(rs == SOCKET_ERROR)
- {
- free(ifc.ifc_buf);
- closeSocketNoThrow(fd);
- SocketException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
- else if(ifc.ifc_len == old_ifc_len)
- {
- //
- // Returned same length twice in a row, finished.
- //
- break;
- }
- else
- {
- old_ifc_len = ifc.ifc_len;
- }
-
- numaddrs += 10;
- free(ifc.ifc_buf);
- }
-
- numaddrs = ifc.ifc_len / static_cast<int>(sizeof(struct ifreq));
- struct ifreq* ifr = ifc.ifc_req;
- for(int i = 0; i < numaddrs; ++i)
- {
- if(ifr[i].ifr_addr.sa_family == AF_INET)
- {
- struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(&ifr[i].ifr_addr);
- if(addr->sin_addr.s_addr != 0)
+ if(protocolSupport != EnableIPv4)
{
- result.push_back(inetAddrToString((*addr).sin_addr));
+ hosts.push_back("0:0:0:0:0:0:0:1");
}
}
}
-
- free(ifc.ifc_buf);
- closeSocket(fd);
-#endif
-
- return result;
+ return hosts; // An empty host list indicates to just use the given host.
}
void
diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h
index 5936a2cd2c0..d5ba13de419 100644
--- a/cpp/src/Ice/Network.h
+++ b/cpp/src/Ice/Network.h
@@ -17,9 +17,11 @@
#include <Ice/Config.h>
#include <Ice/PropertiesF.h> // For setTcpBufSize
#include <Ice/LoggerF.h> // For setTcpBufSize
+#include <Ice/Protocol.h>
#ifdef _WIN32
# include <winsock2.h>
+# include <ws2tcpip.h>
typedef int ssize_t;
#else
# include <unistd.h>
@@ -76,7 +78,7 @@ ICE_API bool connectionLost();
ICE_API bool notConnected();
ICE_API bool recvTruncated();
-ICE_API SOCKET createSocket(bool);
+ICE_API SOCKET createSocket(bool, int);
ICE_API void closeSocket(SOCKET);
ICE_API void closeSocketNoThrow(SOCKET);
ICE_API void shutdownSocketWrite(SOCKET);
@@ -94,14 +96,18 @@ ICE_API void setMcastInterface(SOCKET, const struct in_addr&);
ICE_API void setMcastTtl(SOCKET, int);
ICE_API void setReuseAddress(SOCKET, bool);
-ICE_API void doBind(SOCKET, struct sockaddr_in&);
+ICE_API void doBind(SOCKET, struct sockaddr_storage&);
ICE_API void doListen(SOCKET, int);
-ICE_API bool doConnect(SOCKET, struct sockaddr_in&, int);
+ICE_API bool doConnect(SOCKET, struct sockaddr_storage&, int);
ICE_API void doFinishConnect(SOCKET, int);
ICE_API SOCKET doAccept(SOCKET, int);
-ICE_API void getAddress(const std::string&, int, struct sockaddr_in&);
-ICE_API int compareAddress(const struct sockaddr_in&, const struct sockaddr_in&);
+ICE_API void getAddressForServer(const std::string&, int, struct sockaddr_storage&, ProtocolSupport);
+ICE_API void getAddress(const std::string&, int, struct sockaddr_storage&, ProtocolSupport);
+ICE_API std::vector<struct sockaddr_storage> getAddresses(const std::string&, int, ProtocolSupport, bool);
+
+
+ICE_API int compareAddress(const struct sockaddr_storage&, const struct sockaddr_storage&);
ICE_API void createPipe(SOCKET fds[2]);
@@ -110,16 +116,17 @@ ICE_API std::string errorToStringDNS(int);
ICE_API std::string lastErrorToString();
ICE_API std::string fdToString(SOCKET);
-ICE_API std::string addressesToString(const struct sockaddr_in&, const struct sockaddr_in&, bool);
-ICE_API void fdToLocalAddress(SOCKET, struct sockaddr_in&);
-ICE_API bool fdToRemoteAddress(SOCKET, struct sockaddr_in&);
-ICE_API std::string addrToString(const struct sockaddr_in&);
-
-ICE_API std::vector<struct sockaddr_in> getAddresses(const std::string&, int, bool = true);
-ICE_API std::vector<std::string> getLocalHosts();
+ICE_API std::string addressesToString(const struct sockaddr_storage&, const struct sockaddr_storage&, bool);
+ICE_API void fdToLocalAddress(SOCKET, struct sockaddr_storage&);
+ICE_API bool fdToRemoteAddress(SOCKET, struct sockaddr_storage&);
+ICE_API std::string inetAddrToString(const struct sockaddr_storage&);
+ICE_API std::string addrToString(const struct sockaddr_storage&);
+ICE_API int getPort(const struct sockaddr_storage&);
+
+ICE_API std::vector<std::string> getHostsForEndpointExpand(const std::string&, ProtocolSupport);
ICE_API void setTcpBufSize(SOCKET, const Ice::PropertiesPtr&, const Ice::LoggerPtr&);
+
ICE_API int getSocketErrno();
-ICE_API std::string inetAddrToString(const struct in_addr&);
}
diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp
index ccd571147ec..b89200fa601 100644
--- a/cpp/src/Ice/ObjectAdapterI.cpp
+++ b/cpp/src/Ice/ObjectAdapterI.cpp
@@ -932,17 +932,19 @@ Ice::ObjectAdapterI::ObjectAdapterI(const InstancePtr& instance, const Communica
vector<EndpointIPtr> endpoints;
if(endpointInfo.empty())
{
- endpoints = parseEndpoints(properties->getProperty(_name + ".Endpoints"));
+ endpoints = parseEndpoints(properties->getProperty(_name + ".Endpoints"), true);
}
else
{
- endpoints = parseEndpoints(endpointInfo);
+ endpoints = parseEndpoints(endpointInfo, true);
}
+
for(vector<EndpointIPtr>::iterator p = endpoints.begin(); p != endpoints.end(); ++p)
{
IncomingConnectionFactoryPtr factory = new IncomingConnectionFactory(instance, *p, this, _name);
_incomingConnectionFactories.push_back(factory);
}
+
if(endpoints.empty())
{
TraceLevelsPtr tl = _instance->traceLevels();
@@ -1083,7 +1085,7 @@ Ice::ObjectAdapterI::checkIdentity(const Identity& ident)
}
vector<EndpointIPtr>
-Ice::ObjectAdapterI::parseEndpoints(const string& endpts) const
+Ice::ObjectAdapterI::parseEndpoints(const string& endpts, bool oaEndpoints) const
{
string::size_type beg;
string::size_type end = 0;
@@ -1099,10 +1101,47 @@ Ice::ObjectAdapterI::parseEndpoints(const string& endpts) const
break;
}
- end = endpts.find(':', beg);
- if(end == string::npos)
+ end = beg;
+ while(true)
{
- end = endpts.length();
+ end = endpts.find(':', end);
+ if(end == string::npos)
+ {
+ end = endpts.length();
+ break;
+ }
+ else
+ {
+ bool quoted = false;
+ string::size_type quote = beg;
+ while(true)
+ {
+ quote = endpts.find('\"', quote);
+ if(quote == string::npos || end < quote)
+ {
+ break;
+ }
+ else
+ {
+ quote = endpts.find('\"', ++quote);
+ if(quote == string::npos)
+ {
+ break;
+ }
+ else if(end < quote)
+ {
+ quoted = true;
+ break;
+ }
+ ++quote;
+ }
+ }
+ if(!quoted)
+ {
+ break;
+ }
+ ++end;
+ }
}
if(end == beg)
@@ -1112,7 +1151,7 @@ Ice::ObjectAdapterI::parseEndpoints(const string& endpts) const
}
string s = endpts.substr(beg, end - beg);
- EndpointIPtr endp = _instance->endpointFactoryManager()->create(s, true);
+ EndpointIPtr endp = _instance->endpointFactoryManager()->create(s, oaEndpoints);
if(endp == 0)
{
EndpointParseException ex(__FILE__, __LINE__);
@@ -1135,16 +1174,22 @@ ObjectAdapterI::parsePublishedEndpoints()
// instead of the connection factory endpoints.
//
string endpts = _communicator->getProperties()->getProperty(_name + ".PublishedEndpoints");
- vector<EndpointIPtr> endpoints = parseEndpoints(endpts);
- if(endpoints.empty())
+ vector<EndpointIPtr> endpoints = parseEndpoints(endpts, false);
+ if(!endpoints.empty())
{
- transform(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(),
- back_inserter(endpoints), Ice::constMemFun(&IncomingConnectionFactory::endpoint));
+ return endpoints;
}
//
- // Expand any endpoints that may be listening on INADDR_ANY to
- // include actual addresses in the published endpoints.
+ // If the PublishedEndpoints property isn't set, we compute the published enpdoints
+ // from the OA endpoints.
+ //
+ transform(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(),
+ back_inserter(endpoints), Ice::constMemFun(&IncomingConnectionFactory::endpoint));
+
+ //
+ // Expand any endpoints that may be listening on INADDR_ANY to include actual
+ // addresses in the published endpoints.
//
vector<EndpointIPtr> expandedEndpoints;
for(unsigned int i = 0; i < endpoints.size(); ++i)
diff --git a/cpp/src/Ice/ObjectAdapterI.h b/cpp/src/Ice/ObjectAdapterI.h
index 84322f3a495..973e01ebc8e 100644
--- a/cpp/src/Ice/ObjectAdapterI.h
+++ b/cpp/src/Ice/ObjectAdapterI.h
@@ -100,7 +100,7 @@ private:
ObjectPrx newIndirectProxy(const Identity&, const std::string&, const std::string&) const;
void checkForDeactivation() const;
static void checkIdentity(const Identity&);
- std::vector<IceInternal::EndpointIPtr> parseEndpoints(const std::string&) const;
+ std::vector<IceInternal::EndpointIPtr> parseEndpoints(const std::string&, bool) const;
std::vector<IceInternal::EndpointIPtr> parsePublishedEndpoints();
void updateLocatorRegistry(const IceInternal::LocatorInfoPtr&, const Ice::ObjectPrx&, bool);
bool filterProperties(Ice::StringSeq&);
diff --git a/cpp/src/Ice/PropertyNames.cpp b/cpp/src/Ice/PropertyNames.cpp
index 4cd655a1d55..00636a8f1e3 100644
--- a/cpp/src/Ice/PropertyNames.cpp
+++ b/cpp/src/Ice/PropertyNames.cpp
@@ -66,6 +66,8 @@ const IceInternal::Property IcePropsData[] =
IceInternal::Property("Ice.Default.Router.CollocationOptimized", false, 0),
IceInternal::Property("Ice.Default.Router.ThreadPerConnection", false, 0),
IceInternal::Property("Ice.Default.Router", false, 0),
+ IceInternal::Property("Ice.IPv4", false, 0),
+ IceInternal::Property("Ice.IPv6", false, 0),
IceInternal::Property("Ice.EventLog.Source", false, 0),
IceInternal::Property("Ice.GC.Interval", false, 0),
IceInternal::Property("Ice.ImplicitContext", false, 0),
diff --git a/cpp/src/Ice/ProtocolPluginFacade.cpp b/cpp/src/Ice/ProtocolPluginFacade.cpp
index 2134bdd6ec1..25e9b157d68 100644
--- a/cpp/src/Ice/ProtocolPluginFacade.cpp
+++ b/cpp/src/Ice/ProtocolPluginFacade.cpp
@@ -56,6 +56,12 @@ IceInternal::ProtocolPluginFacade::getEndpointHostResolver() const
return _instance->endpointHostResolver();
}
+ProtocolSupport
+IceInternal::ProtocolPluginFacade::getProtocolSupport() const
+{
+ return _instance->protocolSupport();
+}
+
void
IceInternal::ProtocolPluginFacade::addEndpointFactory(const EndpointFactoryPtr& factory) const
{
diff --git a/cpp/src/Ice/ReferenceFactory.cpp b/cpp/src/Ice/ReferenceFactory.cpp
index 1ec79aa047e..0220d90d54c 100644
--- a/cpp/src/Ice/ReferenceFactory.cpp
+++ b/cpp/src/Ice/ReferenceFactory.cpp
@@ -450,10 +450,47 @@ IceInternal::ReferenceFactory::create(const string& str)
{
beg = end + 1;
- end = s.find(':', beg);
- if(end == string::npos)
+ end = beg;
+ while(true)
{
- end = s.length();
+ end = s.find(':', end);
+ if(end == string::npos)
+ {
+ end = s.length();
+ break;
+ }
+ else
+ {
+ bool quoted = false;
+ string::size_type quote = beg;
+ while(true)
+ {
+ quote = s.find('\"', quote);
+ if(quote == string::npos || end < quote)
+ {
+ break;
+ }
+ else
+ {
+ quote = s.find('\"', ++quote);
+ if(quote == string::npos)
+ {
+ break;
+ }
+ else if(end < quote)
+ {
+ quoted = true;
+ break;
+ }
+ ++quote;
+ }
+ }
+ if(!quoted)
+ {
+ break;
+ }
+ ++end;
+ }
}
string es = s.substr(beg, end - beg);
diff --git a/cpp/src/Ice/TcpAcceptor.cpp b/cpp/src/Ice/TcpAcceptor.cpp
index baa93aa594a..23378e54139 100644
--- a/cpp/src/Ice/TcpAcceptor.cpp
+++ b/cpp/src/Ice/TcpAcceptor.cpp
@@ -78,7 +78,7 @@ IceInternal::TcpAcceptor::accept(int timeout)
void
IceInternal::TcpAcceptor::connectToSelf()
{
- SOCKET fd = createSocket(false);
+ SOCKET fd = createSocket(false, _addr.ss_family);
setBlock(fd, false);
doConnect(fd, _addr, -1);
closeSocket(fd);
@@ -91,9 +91,9 @@ IceInternal::TcpAcceptor::toString() const
}
int
-IceInternal::TcpAcceptor::effectivePort()
+IceInternal::TcpAcceptor::effectivePort() const
{
- return ntohs(_addr.sin_port);
+ return getPort(_addr);
}
IceInternal::TcpAcceptor::TcpAcceptor(const InstancePtr& instance, const string& host, int port) :
@@ -109,9 +109,9 @@ IceInternal::TcpAcceptor::TcpAcceptor(const InstancePtr& instance, const string&
try
{
- _fd = createSocket(false);
+ getAddressForServer(host, port, _addr, _instance->protocolSupport());
+ _fd = createSocket(false, _addr.ss_family);
setBlock(_fd, false);
- getAddress(host, port, _addr);
setTcpBufSize(_fd, _instance->initializationData().properties, _logger);
#ifndef _WIN32
//
diff --git a/cpp/src/Ice/TcpAcceptor.h b/cpp/src/Ice/TcpAcceptor.h
index ed2634a74ef..9d2526914f4 100644
--- a/cpp/src/Ice/TcpAcceptor.h
+++ b/cpp/src/Ice/TcpAcceptor.h
@@ -17,7 +17,7 @@
#include <Ice/Acceptor.h>
#ifndef _WIN32
-# include <netinet/in.h> // For struct sockaddr_in
+# include <netinet/in.h> // For struct sockaddr_storage
#endif
namespace IceInternal
@@ -36,7 +36,7 @@ public:
virtual void connectToSelf();
virtual std::string toString() const;
- int effectivePort();
+ int effectivePort() const;
private:
@@ -49,7 +49,7 @@ private:
::Ice::LoggerPtr _logger;
SOCKET _fd;
int _backlog;
- struct sockaddr_in _addr;
+ struct sockaddr_storage _addr;
};
}
diff --git a/cpp/src/Ice/TcpConnector.cpp b/cpp/src/Ice/TcpConnector.cpp
index a4394598ba9..eadb705f8e8 100644
--- a/cpp/src/Ice/TcpConnector.cpp
+++ b/cpp/src/Ice/TcpConnector.cpp
@@ -29,7 +29,7 @@ IceInternal::TcpConnector::connect(int timeout)
out << "trying to establish tcp connection to " << toString();
}
- SOCKET fd = createSocket(false);
+ SOCKET fd = createSocket(false, _addr.ss_family);
setBlock(fd, false);
setTcpBufSize(fd, _instance->initializationData().properties, _logger);
bool connected = doConnect(fd, _addr, timeout);
@@ -115,12 +115,11 @@ IceInternal::TcpConnector::operator<(const Connector& r) const
{
return false;
}
-
return compareAddress(_addr, p->_addr) == -1;
}
-IceInternal::TcpConnector::TcpConnector(const InstancePtr& instance, const struct sockaddr_in& addr, Ice::Int timeout,
- const string& connectionId) :
+IceInternal::TcpConnector::TcpConnector(const InstancePtr& instance, const struct sockaddr_storage& addr,
+ Ice::Int timeout, const string& connectionId) :
_instance(instance),
_traceLevels(instance->traceLevels()),
_logger(instance->initializationData().logger),
diff --git a/cpp/src/Ice/TcpConnector.h b/cpp/src/Ice/TcpConnector.h
index 2147f30cccc..28c42c064b8 100644
--- a/cpp/src/Ice/TcpConnector.h
+++ b/cpp/src/Ice/TcpConnector.h
@@ -19,7 +19,7 @@
#ifdef _WIN32
# include <winsock2.h>
#else
-# include <netinet/in.h> // For struct sockaddr_in
+# include <netinet/in.h> // For struct sockaddr_storage
#endif
namespace IceInternal
@@ -40,14 +40,14 @@ public:
private:
- TcpConnector(const InstancePtr&, const struct sockaddr_in&, Ice::Int, const std::string&);
+ TcpConnector(const InstancePtr&, const struct sockaddr_storage&, Ice::Int, const std::string&);
virtual ~TcpConnector();
friend class TcpEndpointI;
const InstancePtr _instance;
const TraceLevelsPtr _traceLevels;
const ::Ice::LoggerPtr _logger;
- struct sockaddr_in _addr;
+ struct sockaddr_storage _addr;
const Ice::Int _timeout;
const std::string _connectionId;
};
diff --git a/cpp/src/Ice/TcpEndpointI.cpp b/cpp/src/Ice/TcpEndpointI.cpp
index 0cab29774ad..2568b5aeb2f 100644
--- a/cpp/src/Ice/TcpEndpointI.cpp
+++ b/cpp/src/Ice/TcpEndpointI.cpp
@@ -32,7 +32,7 @@ IceInternal::TcpEndpointI::TcpEndpointI(const InstancePtr& instance, const strin
{
}
-IceInternal::TcpEndpointI::TcpEndpointI(const InstancePtr& instance, const string& str, bool server) :
+IceInternal::TcpEndpointI::TcpEndpointI(const InstancePtr& instance, const string& str, bool oaEndpoint) :
_instance(instance),
_port(0),
_timeout(-1),
@@ -76,6 +76,10 @@ IceInternal::TcpEndpointI::TcpEndpointI(const InstancePtr& instance, const strin
end = str.length();
}
argument = str.substr(beg, end - beg);
+ if(argument[0] == '\"' && argument[argument.size() - 1] == '\"')
+ {
+ argument = argument.substr(1, argument.size() - 2);
+ }
}
switch(option[1])
@@ -140,21 +144,19 @@ IceInternal::TcpEndpointI::TcpEndpointI(const InstancePtr& instance, const strin
if(_host.empty())
{
const_cast<string&>(_host) = _instance->defaultsAndOverrides()->defaultHost;
- if(_host.empty())
- {
- if(server)
- {
- const_cast<string&>(_host) = "0.0.0.0";
- }
- else
- {
- const_cast<string&>(_host) = "127.0.0.1";
- }
- }
}
else if(_host == "*")
{
- const_cast<string&>(_host) = "0.0.0.0";
+ if(oaEndpoint)
+ {
+ const_cast<string&>(_host) = string();
+ }
+ else
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "tcp " + str;
+ throw ex;
+ }
}
}
@@ -195,7 +197,24 @@ IceInternal::TcpEndpointI::toString() const
// format of proxyToString() before changing this and related code.
//
ostringstream s;
- s << "tcp -h " << _host << " -p " << _port;
+ s << "tcp";
+
+ if(!_host.empty())
+ {
+ s << " -h ";
+ bool addQuote = _host.find(':') != string::npos;
+ if(addQuote)
+ {
+ s << "\"";
+ }
+ s << _host;
+ if(addQuote)
+ {
+ s << "\"";
+ }
+ }
+
+ s << " -p " << _port;
if(_timeout != -1)
{
s << " -t " << _timeout;
@@ -292,7 +311,7 @@ IceInternal::TcpEndpointI::transceiver(EndpointIPtr& endp) const
vector<ConnectorPtr>
IceInternal::TcpEndpointI::connectors() const
{
- return connectors(getAddresses(_host, _port));
+ return connectors(getAddresses(_host, _port, _instance->protocolSupport(), true));
}
void
@@ -314,21 +333,18 @@ vector<EndpointIPtr>
IceInternal::TcpEndpointI::expand() const
{
vector<EndpointIPtr> endps;
- if(_host == "0.0.0.0")
+ vector<string> hosts = getHostsForEndpointExpand(_host, _instance->protocolSupport());
+ if(hosts.empty())
{
- vector<string> hosts = getLocalHosts();
- for(unsigned int i = 0; i < hosts.size(); ++i)
- {
- if(hosts.size() == 1 || hosts[i] != "127.0.0.1")
- {
- endps.push_back(new TcpEndpointI(_instance, hosts[i], _port, _timeout, _connectionId, _compress));
- }
- }
+ endps.push_back(const_cast<TcpEndpointI*>(this));
}
else
{
- endps.push_back(const_cast<TcpEndpointI*>(this));
- }
+ for(vector<string>::const_iterator p = hosts.begin(); p != hosts.end(); ++p)
+ {
+ endps.push_back(new TcpEndpointI(_instance, *p, _port, _timeout, _connectionId, _compress));
+ }
+ }
return endps;
}
@@ -454,7 +470,7 @@ IceInternal::TcpEndpointI::operator<(const EndpointI& r) const
}
vector<ConnectorPtr>
-IceInternal::TcpEndpointI::connectors(const vector<struct sockaddr_in>& addresses) const
+IceInternal::TcpEndpointI::connectors(const vector<struct sockaddr_storage>& addresses) const
{
vector<ConnectorPtr> connectors;
for(unsigned int i = 0; i < addresses.size(); ++i)
@@ -486,9 +502,9 @@ IceInternal::TcpEndpointFactory::protocol() const
}
EndpointIPtr
-IceInternal::TcpEndpointFactory::create(const std::string& str, bool server) const
+IceInternal::TcpEndpointFactory::create(const std::string& str, bool oaEndpoint) const
{
- return new TcpEndpointI(_instance, str, server);
+ return new TcpEndpointI(_instance, str, oaEndpoint);
}
EndpointIPtr
diff --git a/cpp/src/Ice/TcpEndpointI.h b/cpp/src/Ice/TcpEndpointI.h
index 361d7150de8..a2df26f15dc 100644
--- a/cpp/src/Ice/TcpEndpointI.h
+++ b/cpp/src/Ice/TcpEndpointI.h
@@ -50,7 +50,7 @@ public:
private:
- virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_in>&) const;
+ virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_storage>&) const;
#if defined(__SUNPRO_CC)
//
diff --git a/cpp/src/Ice/ThreadPool.cpp b/cpp/src/Ice/ThreadPool.cpp
index f18134ca2a5..61b01e42c48 100644
--- a/cpp/src/Ice/ThreadPool.cpp
+++ b/cpp/src/Ice/ThreadPool.cpp
@@ -126,7 +126,6 @@ IceInternal::ThreadPool::destroy()
IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
assert(!_destroyed);
assert(_handlerMap.empty());
- assert(_workItems.empty());
_destroyed = true;
_selector.setInterrupt();
}
diff --git a/cpp/src/Ice/UdpConnector.cpp b/cpp/src/Ice/UdpConnector.cpp
index 05c202a8310..96019514ca1 100644
--- a/cpp/src/Ice/UdpConnector.cpp
+++ b/cpp/src/Ice/UdpConnector.cpp
@@ -168,7 +168,8 @@ IceInternal::UdpConnector::operator<(const Connector& r) const
return compareAddress(_addr, p->_addr) == -1;
}
-IceInternal::UdpConnector::UdpConnector(const InstancePtr& instance, const struct sockaddr_in& addr,
+
+IceInternal::UdpConnector::UdpConnector(const InstancePtr& instance, const struct sockaddr_storage& addr,
const string& mcastInterface, int mcastTtl, Ice::Byte protocolMajor,
Ice::Byte protocolMinor, Ice::Byte encodingMajor, Ice::Byte encodingMinor,
const std::string& connectionId) :
diff --git a/cpp/src/Ice/UdpConnector.h b/cpp/src/Ice/UdpConnector.h
index 77d73bba277..b6ca621cfb9 100644
--- a/cpp/src/Ice/UdpConnector.h
+++ b/cpp/src/Ice/UdpConnector.h
@@ -13,11 +13,12 @@
#include <Ice/TransceiverF.h>
#include <Ice/InstanceF.h>
#include <Ice/Connector.h>
+#include <Ice/Protocol.h>
#ifdef _WIN32
# include <winsock2.h>
#else
-# include <netinet/in.h> // For struct sockaddr_in
+# include <netinet/in.h> // For struct sockaddr_storage
#endif
namespace IceInternal
@@ -38,13 +39,13 @@ public:
private:
- UdpConnector(const InstancePtr&, const struct sockaddr_in&, const std::string&, int, Ice::Byte, Ice::Byte,
+ UdpConnector(const InstancePtr&, const struct sockaddr_storage&, const std::string&, int, Ice::Byte, Ice::Byte,
Ice::Byte, Ice::Byte, const std::string&);
virtual ~UdpConnector();
friend class UdpEndpointI;
const InstancePtr _instance;
- struct sockaddr_in _addr;
+ struct sockaddr_storage _addr;
const std::string _mcastInterface;
const int _mcastTtl;
const Ice::Byte _protocolMajor;
diff --git a/cpp/src/Ice/UdpEndpointI.cpp b/cpp/src/Ice/UdpEndpointI.cpp
index b5f4588714c..217f9625528 100644
--- a/cpp/src/Ice/UdpEndpointI.cpp
+++ b/cpp/src/Ice/UdpEndpointI.cpp
@@ -39,7 +39,7 @@ IceInternal::UdpEndpointI::UdpEndpointI(const InstancePtr& instance, const strin
{
}
-IceInternal::UdpEndpointI::UdpEndpointI(const InstancePtr& instance, const string& str, bool server) :
+IceInternal::UdpEndpointI::UdpEndpointI(const InstancePtr& instance, const string& str, bool oaEndpoint) :
_instance(instance),
_port(0),
_mcastTtl(-1),
@@ -88,6 +88,10 @@ IceInternal::UdpEndpointI::UdpEndpointI(const InstancePtr& instance, const strin
end = str.length();
}
argument = str.substr(beg, end - beg);
+ if(argument[0] == '\"' && argument[argument.size() - 1] == '\"')
+ {
+ argument = argument.substr(1, argument.size() - 2);
+ }
}
if(option == "-v")
@@ -267,21 +271,19 @@ IceInternal::UdpEndpointI::UdpEndpointI(const InstancePtr& instance, const strin
if(_host.empty())
{
const_cast<string&>(_host) = _instance->defaultsAndOverrides()->defaultHost;
- if(_host.empty())
- {
- if(server)
- {
- const_cast<string&>(_host) = "0.0.0.0";
- }
- else
- {
- const_cast<string&>(_host) = "127.0.0.1";
- }
- }
}
else if(_host == "*")
{
- const_cast<string&>(_host) = "0.0.0.0";
+ if(oaEndpoint)
+ {
+ const_cast<string&>(_host) = string();
+ }
+ else
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "udp " + str;
+ throw ex;
+ }
}
}
@@ -372,7 +374,22 @@ IceInternal::UdpEndpointI::toString() const
<< static_cast<unsigned>(static_cast<unsigned char>(_encodingMinor));
}
- s << " -h " << _host << " -p " << _port;
+ if(!_host.empty())
+ {
+ s << " -h ";
+ bool addQuote = _host.find(':') != string::npos;
+ if(addQuote)
+ {
+ s << "\"";
+ }
+ s << _host;
+ if(addQuote)
+ {
+ s << "\"";
+ }
+ }
+
+ s << " -p " << _port;
if(_mcastInterface.length() > 0)
{
@@ -480,7 +497,7 @@ IceInternal::UdpEndpointI::transceiver(EndpointIPtr& endp) const
vector<ConnectorPtr>
IceInternal::UdpEndpointI::connectors() const
{
- return connectors(getAddresses(_host, _port));
+ return connectors(getAddresses(_host, _port, _instance->protocolSupport(), true));
}
void
@@ -500,22 +517,19 @@ vector<EndpointIPtr>
IceInternal::UdpEndpointI::expand() const
{
vector<EndpointIPtr> endps;
- if(_host == "0.0.0.0")
+ vector<string> hosts = getHostsForEndpointExpand(_host, _instance->protocolSupport());
+ if(hosts.empty())
{
- vector<string> hosts = getLocalHosts();
- for(unsigned int i = 0; i < hosts.size(); ++i)
- {
- if(hosts.size() == 1 || hosts[i] != "127.0.0.1")
- {
- endps.push_back(new UdpEndpointI(_instance, hosts[i], _port, _mcastInterface, _mcastTtl, _protocolMajor,
- _protocolMinor, _encodingMajor, _encodingMinor, _connect,
- _connectionId, _compress));
- }
- }
+ endps.push_back(const_cast<UdpEndpointI*>(this));
}
else
{
- endps.push_back(const_cast<UdpEndpointI*>(this));
+ for(vector<string>::const_iterator p = hosts.begin(); p != hosts.end(); ++p)
+ {
+ endps.push_back(new UdpEndpointI(_instance, *p, _port, _mcastInterface, _mcastTtl, _protocolMajor,
+ _protocolMinor, _encodingMajor, _encodingMinor, _connect,
+ _connectionId, _compress));
+ }
}
return endps;
}
@@ -726,7 +740,7 @@ IceInternal::UdpEndpointI::operator<(const EndpointI& r) const
}
vector<ConnectorPtr>
-IceInternal::UdpEndpointI::connectors(const vector<struct sockaddr_in>& addresses) const
+IceInternal::UdpEndpointI::connectors(const vector<struct sockaddr_storage>& addresses) const
{
vector<ConnectorPtr> connectors;
for(unsigned int i = 0; i < addresses.size(); ++i)
@@ -759,9 +773,9 @@ IceInternal::UdpEndpointFactory::protocol() const
}
EndpointIPtr
-IceInternal::UdpEndpointFactory::create(const std::string& str, bool server) const
+IceInternal::UdpEndpointFactory::create(const std::string& str, bool oaEndpoint) const
{
- return new UdpEndpointI(_instance, str, server);
+ return new UdpEndpointI(_instance, str, oaEndpoint);
}
EndpointIPtr
diff --git a/cpp/src/Ice/UdpEndpointI.h b/cpp/src/Ice/UdpEndpointI.h
index 07fb3daaf2d..051efd646b4 100644
--- a/cpp/src/Ice/UdpEndpointI.h
+++ b/cpp/src/Ice/UdpEndpointI.h
@@ -51,7 +51,7 @@ public:
private:
- virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_in>&) const;
+ virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_storage>&) const;
#if defined(__SUNPRO_CC)
//
diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp
index 2736587f7a8..1d889d686de 100644
--- a/cpp/src/Ice/UdpTransceiver.cpp
+++ b/cpp/src/Ice/UdpTransceiver.cpp
@@ -72,7 +72,7 @@ IceInternal::UdpTransceiver::shutdownReadWrite()
//
// Save the local address before shutting down or disconnecting.
//
- struct sockaddr_in localAddr;
+ struct sockaddr_storage localAddr;
fdToLocalAddress(_fd, localAddr);
assert(_fd != INVALID_SOCKET);
@@ -84,9 +84,9 @@ IceInternal::UdpTransceiver::shutdownReadWrite()
//
if(!_connect)
{
- struct sockaddr_in unspec;
+ struct sockaddr_storage unspec;
memset(&unspec, 0, sizeof(unspec));
- unspec.sin_family = AF_UNSPEC;
+ unspec.ss_family = AF_UNSPEC;
::connect(_fd, reinterpret_cast<struct sockaddr*>(&unspec), int(sizeof(unspec)));
}
@@ -94,7 +94,7 @@ IceInternal::UdpTransceiver::shutdownReadWrite()
// Send a dummy packet to the socket. This packet is ignored because we have
// already set _shutdownReadWrite.
//
- SOCKET fd = createSocket(true);
+ SOCKET fd = createSocket(true, localAddr.ss_family);
setBlock(fd, false);
doConnect(fd, localAddr, -1);
::send(fd, "", 1, 0);
@@ -259,8 +259,8 @@ repeat:
// If we must connect, then we connect to the first peer that
// sends us a packet.
//
- struct sockaddr_in peerAddr;
- memset(&peerAddr, 0, sizeof(struct sockaddr_in));
+ struct sockaddr_storage peerAddr;
+ memset(&peerAddr, 0, sizeof(struct sockaddr_storage));
socklen_t len = static_cast<socklen_t>(sizeof(peerAddr));
assert(_fd != INVALID_SOCKET);
ret = recvfrom(_fd, reinterpret_cast<char*>(&buf.b[0]), packetSize,
@@ -374,7 +374,7 @@ IceInternal::UdpTransceiver::toString() const
{
if(_mcastServer && _fd != INVALID_SOCKET)
{
- struct sockaddr_in remoteAddr;
+ struct sockaddr_storage remoteAddr;
bool peerConnected = fdToRemoteAddress(_fd, remoteAddr);
return addressesToString(_addr, remoteAddr, peerConnected);
}
@@ -407,10 +407,10 @@ IceInternal::UdpTransceiver::checkSendSize(const Buffer& buf, size_t messageSize
int
IceInternal::UdpTransceiver::effectivePort() const
{
- return ntohs(_addr.sin_port);
+ return getPort(_addr);
}
-IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const struct sockaddr_in& addr,
+IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const struct sockaddr_storage& addr,
const string& mcastInterface, int mcastTtl) :
_traceLevels(instance->traceLevels()),
_logger(instance->initializationData().logger),
@@ -423,18 +423,35 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s
{
try
{
- _fd = createSocket(true);
+ _fd = createSocket(true, _addr.ss_family);
setBufSize(instance);
setBlock(_fd, false);
doConnect(_fd, _addr, -1);
_connect = false; // We're connected now
- if(IN_MULTICAST(ntohl(_addr.sin_addr.s_addr)))
+
+ bool multicast = false;
+ int port;
+ if(_addr.ss_family == AF_INET)
+ {
+ struct sockaddr_in* addrin = reinterpret_cast<struct sockaddr_in*>(&_addr);
+ multicast = IN_MULTICAST(ntohl(addrin->sin_addr.s_addr));
+ port = ntohs(addrin->sin_port);
+ }
+ /*
+ else
+ {
+ struct sockaddr_in6* addrin = reinterpret_cast<struct sockaddr_in6*>(&_addr);
+ multicast = IN6_IS_ADDR_MULTICAST(&addrin->sin6_addr);
+ port = ntohs(addrin->sin6_port);
+ }
+ */
+ if(multicast)
{
if(mcastInterface.length() > 0)
{
- struct sockaddr_in addr;
- getAddress(mcastInterface, ntohs(_addr.sin_port), addr);
- setMcastInterface(_fd, addr.sin_addr);
+ struct sockaddr_storage addr;
+ getAddress(mcastInterface, port, addr, instance->protocolSupport());
+ setMcastInterface(_fd, reinterpret_cast<struct sockaddr_in*>(&addr)->sin_addr);
}
if(mcastTtl != -1)
{
@@ -472,39 +489,56 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s
{
try
{
- _fd = createSocket(true);
+ getAddressForServer(host, port, _addr, instance->protocolSupport());
+ _fd = createSocket(true, _addr.ss_family);
setBufSize(instance);
setBlock(_fd, false);
- getAddress(host, port, _addr);
if(_traceLevels->network >= 2)
{
Trace out(_logger, _traceLevels->networkCat);
out << "attempting to bind to udp socket " << addrToString(_addr);
}
- if(IN_MULTICAST(ntohl(_addr.sin_addr.s_addr)))
+ bool multicast = false;
+ int port;
+ if(_addr.ss_family == AF_INET)
+ {
+ struct sockaddr_in* addrin = reinterpret_cast<struct sockaddr_in*>(&_addr);
+ multicast = IN_MULTICAST(ntohl(addrin->sin_addr.s_addr));
+ port = ntohs(addrin->sin_port);
+ }
+ /*
+ else
+ {
+ struct sockaddr_in6* addrin = reinterpret_cast<struct sockaddr_in6*>(&_addr);
+ multicast = IN6_IS_ADDR_MULTICAST(&addrin->sin6_addr);
+ port = ntohs(addrin->sin6_port);
+ }
+ */
+ if(multicast)
{
setReuseAddress(_fd, true);
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
//
// Windows does not allow binding to the mcast address itself
// so we bind to INADDR_ANY (0.0.0.0) instead.
//
#ifdef _WIN32
- getAddress("0.0.0.0", port, addr);
+ getAddressForServer("", port, addr, instance->protocolSupport());
doBind(_fd, addr);
#else
doBind(_fd, _addr);
#endif
+ struct sockaddr_in* maddr = reinterpret_cast<sockaddr_in*>(&addr);
if(mcastInterface.length() > 0)
{
- getAddress(mcastInterface, port, addr);
+ getAddress(mcastInterface, port, addr, instance->protocolSupport());
}
else
{
- addr.sin_addr.s_addr = INADDR_ANY;
+ maddr->sin_addr.s_addr = INADDR_ANY;
}
- setMcastGroup(_fd, _addr.sin_addr, addr.sin_addr);
+ setMcastGroup(_fd, reinterpret_cast<struct sockaddr_in*>(&_addr)->sin_addr, maddr->sin_addr);
_mcastServer = true;
}
else
diff --git a/cpp/src/Ice/UdpTransceiver.h b/cpp/src/Ice/UdpTransceiver.h
index 6fe77182793..ebe9a2f4669 100644
--- a/cpp/src/Ice/UdpTransceiver.h
+++ b/cpp/src/Ice/UdpTransceiver.h
@@ -18,7 +18,7 @@
#include <IceUtil/Mutex.h>
#ifndef _WIN32
-# include <netinet/in.h> // For struct sockaddr_in
+# include <netinet/in.h> // For struct sockaddr_storage
#endif
namespace IceInternal
@@ -47,7 +47,7 @@ public:
private:
- UdpTransceiver(const InstancePtr&, const struct sockaddr_in&, const std::string&, int);
+ UdpTransceiver(const InstancePtr&, const struct sockaddr_storage&, const std::string&, int);
UdpTransceiver(const InstancePtr&, const std::string&, int, const std::string&, bool);
virtual ~UdpTransceiver();
@@ -62,7 +62,7 @@ private:
const bool _incoming;
SOCKET _fd;
- struct sockaddr_in _addr;
+ struct sockaddr_storage _addr;
bool _mcastServer;
#ifdef _WIN32
fd_set _rFdSet;
diff --git a/cpp/src/Ice/UnknownEndpointI.cpp b/cpp/src/Ice/UnknownEndpointI.cpp
index 9262a39e672..8a9682b27e1 100644
--- a/cpp/src/Ice/UnknownEndpointI.cpp
+++ b/cpp/src/Ice/UnknownEndpointI.cpp
@@ -138,7 +138,6 @@ IceInternal::UnknownEndpointI::streamWrite(BasicStream* s) const
string
IceInternal::UnknownEndpointI::toString() const
{
-
ostringstream s;
string val = Base64::encode(_rawBytes);
s << "opaque -t " << _type << " -v " << val;
diff --git a/cpp/src/IceGrid/RegistryI.cpp b/cpp/src/IceGrid/RegistryI.cpp
index 64272b1d16f..663a3173691 100644
--- a/cpp/src/IceGrid/RegistryI.cpp
+++ b/cpp/src/IceGrid/RegistryI.cpp
@@ -1215,10 +1215,24 @@ RegistryI::getSSLInfo(const ConnectionPtr& connection, string& userDN)
try
{
IceSSL::ConnectionInfo info = IceSSL::getConnectionInfo(connection);
- sslinfo.remotePort = ntohs(info.remoteAddr.sin_port);
- sslinfo.remoteHost = IceInternal::inetAddrToString(info.remoteAddr.sin_addr);
- sslinfo.localPort = ntohs(info.localAddr.sin_port);
- sslinfo.localHost = IceInternal::inetAddrToString(info.localAddr.sin_addr);
+ if(info.remoteAddr.ss_family == AF_INET)
+ {
+ sslinfo.remotePort = ntohs(reinterpret_cast<sockaddr_in*>(&info.remoteAddr)->sin_port);
+ }
+ else
+ {
+ sslinfo.remotePort = ntohs(reinterpret_cast<sockaddr_in6*>(&info.remoteAddr)->sin6_port);
+ }
+ sslinfo.remoteHost = IceInternal::inetAddrToString(info.remoteAddr);
+ if(info.remoteAddr.ss_family == AF_INET)
+ {
+ sslinfo.localPort = ntohs(reinterpret_cast<sockaddr_in*>(&info.localAddr)->sin_port);
+ }
+ else
+ {
+ sslinfo.localPort = ntohs(reinterpret_cast<sockaddr_in6*>(&info.localAddr)->sin6_port);
+ }
+ sslinfo.localHost = IceInternal::inetAddrToString(info.localAddr);
sslinfo.cipher = info.cipher;
diff --git a/cpp/src/IceSSL/AcceptorI.cpp b/cpp/src/IceSSL/AcceptorI.cpp
index 7f467fee5c0..70fa17a3759 100644
--- a/cpp/src/IceSSL/AcceptorI.cpp
+++ b/cpp/src/IceSSL/AcceptorI.cpp
@@ -114,7 +114,7 @@ IceSSL::AcceptorI::accept(int timeout)
void
IceSSL::AcceptorI::connectToSelf()
{
- SOCKET fd = IceInternal::createSocket(false);
+ SOCKET fd = IceInternal::createSocket(false, _addr.ss_family);
IceInternal::setBlock(fd, false);
IceInternal::doConnect(fd, _addr, -1);
IceInternal::closeSocket(fd);
@@ -127,9 +127,16 @@ IceSSL::AcceptorI::toString() const
}
int
-IceSSL::AcceptorI::effectivePort()
+IceSSL::AcceptorI::effectivePort() const
{
- return ntohs(_addr.sin_port);
+ if(_addr.ss_family == AF_INET)
+ {
+ return ntohs(reinterpret_cast<const sockaddr_in*>(&_addr)->sin_port);
+ }
+ else
+ {
+ return ntohs(reinterpret_cast<const sockaddr_in6*>(&_addr)->sin6_port);
+ }
}
IceSSL::AcceptorI::AcceptorI(const InstancePtr& instance, const string& adapterName, const string& host, int port) :
@@ -145,9 +152,9 @@ IceSSL::AcceptorI::AcceptorI(const InstancePtr& instance, const string& adapterN
try
{
- _fd = IceInternal::createSocket(false);
+ IceInternal::getAddressForServer(host, port, _addr, _instance->protocolSupport());
+ _fd = IceInternal::createSocket(false, _addr.ss_family);
IceInternal::setBlock(_fd, false);
- IceInternal::getAddress(host, port, _addr);
IceInternal::setTcpBufSize(_fd, _instance->communicator()->getProperties(), _logger);
#ifndef _WIN32
//
diff --git a/cpp/src/IceSSL/AcceptorI.h b/cpp/src/IceSSL/AcceptorI.h
index 183ff0abf24..38d1fcf864e 100644
--- a/cpp/src/IceSSL/AcceptorI.h
+++ b/cpp/src/IceSSL/AcceptorI.h
@@ -13,10 +13,11 @@
#include <Ice/LoggerF.h>
#include <Ice/TransceiverF.h>
#include <Ice/Acceptor.h>
+#include <Ice/Protocol.h>
#include <IceSSL/InstanceF.h>
#ifndef _WIN32
-# include <netinet/in.h> // For struct sockaddr_in
+# include <netinet/in.h> // For struct sockaddr_storage
#endif
namespace IceSSL
@@ -35,7 +36,7 @@ public:
virtual void connectToSelf();
virtual std::string toString() const;
- int effectivePort();
+ int effectivePort() const;
private:
@@ -48,7 +49,7 @@ private:
Ice::LoggerPtr _logger;
SOCKET _fd;
int _backlog;
- struct sockaddr_in _addr;
+ struct sockaddr_storage _addr;
};
}
diff --git a/cpp/src/IceSSL/ConnectorI.cpp b/cpp/src/IceSSL/ConnectorI.cpp
index feb4c4b4e89..31f2c176e15 100644
--- a/cpp/src/IceSSL/ConnectorI.cpp
+++ b/cpp/src/IceSSL/ConnectorI.cpp
@@ -40,7 +40,7 @@ IceSSL::ConnectorI::connect(int timeout)
out << "trying to establish ssl connection to " << toString();
}
- SOCKET fd = IceInternal::createSocket(false);
+ SOCKET fd = IceInternal::createSocket(false, _addr.ss_family);
IceInternal::setBlock(fd, false);
IceInternal::setTcpBufSize(fd, _instance->communicator()->getProperties(), _logger);
bool connected = IceInternal::doConnect(fd, _addr, timeout);
@@ -147,10 +147,9 @@ IceSSL::ConnectorI::operator<(const IceInternal::Connector& r) const
return IceInternal::compareAddress(_addr, p->_addr) == -1;
}
-IceSSL::ConnectorI::ConnectorI(const InstancePtr& instance, const struct sockaddr_in& addr, Ice::Int timeout,
+IceSSL::ConnectorI::ConnectorI(const InstancePtr& instance, const struct sockaddr_storage& addr, Ice::Int timeout,
const string& connectionId) :
_instance(instance),
- _host(IceInternal::inetAddrToString(addr.sin_addr)),
_logger(instance->communicator()->getLogger()),
_addr(addr),
_timeout(timeout),
diff --git a/cpp/src/IceSSL/ConnectorI.h b/cpp/src/IceSSL/ConnectorI.h
index 72f7a61fb32..4102a478c48 100644
--- a/cpp/src/IceSSL/ConnectorI.h
+++ b/cpp/src/IceSSL/ConnectorI.h
@@ -18,7 +18,7 @@
#ifdef _WIN32
# include <winsock2.h>
#else
-# include <netinet/in.h> // For struct sockaddr_in
+# include <netinet/in.h> // For struct sockaddr_storage
#endif
namespace IceSSL
@@ -41,14 +41,13 @@ public:
private:
- ConnectorI(const InstancePtr&, const struct sockaddr_in&, Ice::Int, const std::string&);
+ ConnectorI(const InstancePtr&, const struct sockaddr_storage&, Ice::Int, const std::string&);
virtual ~ConnectorI();
friend class EndpointI;
const InstancePtr _instance;
- const std::string _host;
const Ice::LoggerPtr _logger;
- struct sockaddr_in _addr;
+ struct sockaddr_storage _addr;
const Ice::Int _timeout;
const std::string _connectionId;
SOCKET _fd;
diff --git a/cpp/src/IceSSL/EndpointI.cpp b/cpp/src/IceSSL/EndpointI.cpp
index fd9edd4f42d..31edfbe0995 100644
--- a/cpp/src/IceSSL/EndpointI.cpp
+++ b/cpp/src/IceSSL/EndpointI.cpp
@@ -32,7 +32,7 @@ IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const string& ho, Int
{
}
-IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const string& str, bool server) :
+IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const string& str, bool oaEndpoint) :
_instance(instance),
_port(0),
_timeout(-1),
@@ -76,6 +76,10 @@ IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const string& str, boo
end = str.length();
}
argument = str.substr(beg, end - beg);
+ if(argument[0] == '\"' && argument[argument.size() - 1] == '\"')
+ {
+ argument = argument.substr(1, argument.size() - 2);
+ }
}
switch(option[1])
@@ -140,21 +144,19 @@ IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const string& str, boo
if(_host.empty())
{
const_cast<string&>(_host) = _instance->defaultHost();
- if(_host.empty())
- {
- if(server)
- {
- const_cast<string&>(_host) = "0.0.0.0";
- }
- else
- {
- const_cast<string&>(_host) = "127.0.0.1";
- }
- }
}
else if(_host == "*")
{
- const_cast<string&>(_host) = "0.0.0.0";
+ if(oaEndpoint)
+ {
+ const_cast<string&>(_host) = string();
+ }
+ else
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "ssl " + str;
+ throw ex;
+ }
}
}
@@ -195,7 +197,24 @@ IceSSL::EndpointI::toString() const
// format of proxyToString() before changing this and related code.
//
ostringstream s;
- s << "ssl -h " << _host << " -p " << _port;
+ s << "ssl";
+
+ if(!_host.empty())
+ {
+ s << " -h ";
+ bool addQuote = _host.find(':') != string::npos;
+ if(addQuote)
+ {
+ s << "\"";
+ }
+ s << _host;
+ if(addQuote)
+ {
+ s << "\"";
+ }
+ }
+
+ s << " -p " << _port;
if(_timeout != -1)
{
s << " -t " << _timeout;
@@ -292,7 +311,7 @@ IceSSL::EndpointI::transceiver(IceInternal::EndpointIPtr& endp) const
vector<IceInternal::ConnectorPtr>
IceSSL::EndpointI::connectors() const
{
- return connectors(IceInternal::getAddresses(_host, _port));
+ return connectors(IceInternal::getAddresses(_host, _port, _instance->protocolSupport(), true));
}
void
@@ -313,20 +332,17 @@ vector<IceInternal::EndpointIPtr>
IceSSL::EndpointI::expand() const
{
vector<IceInternal::EndpointIPtr> endps;
- if(_host == "0.0.0.0")
+ vector<string> hosts = IceInternal::getHostsForEndpointExpand(_host, _instance->protocolSupport());
+ if(hosts.empty())
{
- vector<string> hosts = IceInternal::getLocalHosts();
- for(unsigned int i = 0; i < hosts.size(); ++i)
- {
- if(hosts.size() == 1 || hosts[i] != "127.0.0.1")
- {
- endps.push_back(new EndpointI(_instance, hosts[i], _port, _timeout, _connectionId, _compress));
- }
- }
+ endps.push_back(const_cast<EndpointI*>(this));
}
else
{
- endps.push_back(const_cast<EndpointI*>(this));
+ for(vector<string>::const_iterator p = hosts.begin(); p != hosts.end(); ++p)
+ {
+ endps.push_back(new EndpointI(_instance, *p, _port, _timeout, _connectionId, _compress));
+ }
}
return endps;
}
@@ -453,7 +469,7 @@ IceSSL::EndpointI::operator<(const IceInternal::EndpointI& r) const
}
vector<IceInternal::ConnectorPtr>
-IceSSL::EndpointI::connectors(const vector<struct sockaddr_in>& addresses) const
+IceSSL::EndpointI::connectors(const vector<struct sockaddr_storage>& addresses) const
{
vector<IceInternal::ConnectorPtr> connectors;
for(unsigned int i = 0; i < addresses.size(); ++i)
@@ -485,9 +501,9 @@ IceSSL::EndpointFactoryI::protocol() const
}
IceInternal::EndpointIPtr
-IceSSL::EndpointFactoryI::create(const string& str, bool server) const
+IceSSL::EndpointFactoryI::create(const string& str, bool oaEndpoint) const
{
- return new EndpointI(_instance, str, server);
+ return new EndpointI(_instance, str, oaEndpoint);
}
IceInternal::EndpointIPtr
diff --git a/cpp/src/IceSSL/EndpointI.h b/cpp/src/IceSSL/EndpointI.h
index 99e748e7782..1fbf9d6ace2 100644
--- a/cpp/src/IceSSL/EndpointI.h
+++ b/cpp/src/IceSSL/EndpointI.h
@@ -51,7 +51,7 @@ public:
private:
- virtual std::vector<IceInternal::ConnectorPtr> connectors(const std::vector<struct sockaddr_in>&) const;
+ virtual std::vector<IceInternal::ConnectorPtr> connectors(const std::vector<struct sockaddr_storage>&) const;
#if defined(__SUNPRO_CC)
//
diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp
index a0933c5420d..15176f9131d 100644
--- a/cpp/src/IceSSL/Instance.cpp
+++ b/cpp/src/IceSSL/Instance.cpp
@@ -538,6 +538,12 @@ IceSSL::Instance::endpointHostResolver() const
return _facade->getEndpointHostResolver();
}
+IceInternal::ProtocolSupport
+IceSSL::Instance::protocolSupport() const
+{
+ return _facade->getProtocolSupport();
+}
+
string
IceSSL::Instance::defaultHost() const
{
diff --git a/cpp/src/IceSSL/Instance.h b/cpp/src/IceSSL/Instance.h
index 9f3d69284ff..fcfb6fcef14 100644
--- a/cpp/src/IceSSL/Instance.h
+++ b/cpp/src/IceSSL/Instance.h
@@ -36,6 +36,7 @@ public:
Ice::CommunicatorPtr communicator() const;
IceInternal::EndpointHostResolverPtr endpointHostResolver() const;
+ IceInternal::ProtocolSupport protocolSupport() const;
std::string defaultHost() const;
int networkTraceLevel() const;
std::string networkTraceCategory() const;
diff --git a/cpp/src/IceSSL/TransceiverI.cpp b/cpp/src/IceSSL/TransceiverI.cpp
index d930c3d8cff..9b4fdb7f726 100644
--- a/cpp/src/IceSSL/TransceiverI.cpp
+++ b/cpp/src/IceSSL/TransceiverI.cpp
@@ -532,7 +532,7 @@ IceSSL::TransceiverI::initialize(int timeout)
}
case SSL_ERROR_SSL:
{
- struct sockaddr_in remoteAddr;
+ struct sockaddr_storage remoteAddr;
string desc;
if(IceInternal::fdToRemoteAddress(_fd, remoteAddr))
{
diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y
index 0e8b7274525..3b38486d84c 100644
--- a/cpp/src/Slice/Grammar.y
+++ b/cpp/src/Slice/Grammar.y
@@ -1588,9 +1588,12 @@ const_initializer
IntegerTokPtr intVal = IntegerTokPtr::dynamicCast($1);
ostringstream sstr;
sstr << intVal->v;
- SyntaxTreeBaseStringTokPtr basestring = new SyntaxTreeBaseStringTok;
- basestring->v = pair<SyntaxTreeBasePtr,string>(type, sstr.str());
- $$ = basestring;
+ ConstDefTokPtr def = new ConstDefTok;
+ def->v.type = type;
+ def->v.value = type;
+ def->v.valueAsString = sstr.str();
+ def->v.valueAsLiteral = intVal->literal;
+ $$ = def;
}
| ICE_FLOATING_POINT_LITERAL
{
@@ -1598,18 +1601,24 @@ const_initializer
FloatingTokPtr floatVal = FloatingTokPtr::dynamicCast($1);
ostringstream sstr;
sstr << floatVal->v;
- SyntaxTreeBaseStringTokPtr basestring = new SyntaxTreeBaseStringTok;
- basestring->v = pair<SyntaxTreeBasePtr,string>(type, sstr.str());
- $$ = basestring;
+ ConstDefTokPtr def = new ConstDefTok;
+ def->v.type = type;
+ def->v.value = type;
+ def->v.valueAsString = sstr.str();
+ def->v.valueAsLiteral = floatVal->literal;
+ $$ = def;
}
| scoped_name
{
StringTokPtr scoped = StringTokPtr::dynamicCast($1);
- SyntaxTreeBaseStringTokPtr basestring = new SyntaxTreeBaseStringTok;
+ ConstDefTokPtr def = new ConstDefTok;
ContainedList cl = unit->currentContainer()->lookupContained(scoped->v);
if(cl.empty())
{
- basestring->v = pair<SyntaxTreeBasePtr,string>(TypePtr(0), scoped->v);
+ def->v.type = TypePtr(0);
+ def->v.value = TypePtr(0);
+ def->v.valueAsString = scoped->v;
+ def->v.valueAsLiteral = scoped->v;
}
else
{
@@ -1627,33 +1636,45 @@ const_initializer
unit->error(msg); // $$ is dummy
}
unit->currentContainer()->checkIntroduced(scoped->v, enumerator);
- basestring->v = pair<SyntaxTreeBasePtr,string>(enumerator, scoped->v);
+ def->v.type = enumerator->type();
+ def->v.value = enumerator;
+ def->v.valueAsString = scoped->v;
+ def->v.valueAsLiteral = scoped->v;
}
- $$ = basestring;
+ $$ = def;
}
| ICE_STRING_LITERAL
{
BuiltinPtr type = unit->builtin(Builtin::KindString);
StringTokPtr literal = StringTokPtr::dynamicCast($1);
- SyntaxTreeBaseStringTokPtr basestring = new SyntaxTreeBaseStringTok;
- basestring->v = pair<SyntaxTreeBasePtr,string>(type, literal->v);
- $$ = basestring;
+ ConstDefTokPtr def = new ConstDefTok;
+ def->v.type = type;
+ def->v.value = type;
+ def->v.valueAsString = literal->v;
+ def->v.valueAsLiteral = literal->literal;
+ $$ = def;
}
| ICE_FALSE
{
BuiltinPtr type = unit->builtin(Builtin::KindBool);
StringTokPtr literal = StringTokPtr::dynamicCast($1);
- SyntaxTreeBaseStringTokPtr basestring = new SyntaxTreeBaseStringTok;
- basestring->v = pair<SyntaxTreeBasePtr,string>(type, literal->v);
- $$ = basestring;
+ ConstDefTokPtr def = new ConstDefTok;
+ def->v.type = type;
+ def->v.value = type;
+ def->v.valueAsString = literal->v;
+ def->v.valueAsLiteral = "false";
+ $$ = def;
}
| ICE_TRUE
{
BuiltinPtr type = unit->builtin(Builtin::KindBool);
StringTokPtr literal = StringTokPtr::dynamicCast($1);
- SyntaxTreeBaseStringTokPtr basestring = new SyntaxTreeBaseStringTok;
- basestring->v = pair<SyntaxTreeBasePtr,string>(type, literal->v);
- $$ = basestring;
+ ConstDefTokPtr def = new ConstDefTok;
+ def->v.type = type;
+ def->v.value = type;
+ def->v.valueAsString = literal->v;
+ def->v.valueAsLiteral = "true";
+ $$ = def;
}
;
@@ -1665,17 +1686,19 @@ const_def
StringListTokPtr metaData = StringListTokPtr::dynamicCast($2);
TypePtr const_type = TypePtr::dynamicCast($3);
StringTokPtr ident = StringTokPtr::dynamicCast($4);
- SyntaxTreeBaseStringTokPtr value = SyntaxTreeBaseStringTokPtr::dynamicCast($6);
- $$ = unit->currentContainer()->createConst(ident->v, const_type, metaData->v, value->v.first, value->v.second);
+ ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($6);
+ $$ = unit->currentContainer()->createConst(ident->v, const_type, metaData->v,
+ value->v.value, value->v.valueAsString, value->v.valueAsLiteral);
}
| ICE_CONST meta_data type '=' const_initializer
{
StringListTokPtr metaData = StringListTokPtr::dynamicCast($2);
TypePtr const_type = TypePtr::dynamicCast($3);
- SyntaxTreeBaseStringTokPtr value = SyntaxTreeBaseStringTokPtr::dynamicCast($5);
+ ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($5);
unit->error("missing constant name");
- $$ = unit->currentContainer()->createConst(IceUtil::generateUUID(), const_type, metaData->v, value->v.first,
- value->v.second, Dummy); // Dummy
+ $$ = unit->currentContainer()->createConst(IceUtil::generateUUID(), const_type, metaData->v,
+ value->v.value, value->v.valueAsString,
+ value->v.valueAsLiteral, Dummy); // Dummy
}
;
diff --git a/cpp/src/Slice/GrammarUtil.h b/cpp/src/Slice/GrammarUtil.h
index d8c6c9d3de6..8acd6e65667 100644
--- a/cpp/src/Slice/GrammarUtil.h
+++ b/cpp/src/Slice/GrammarUtil.h
@@ -25,7 +25,7 @@ class FloatingTok;
class ExceptionListTok;
class ClassListTok;
class EnumeratorListTok;
-class SyntaxTreeBaseStringTok;
+class ConstDefTok;
typedef ::IceUtil::Handle<StringTok> StringTokPtr;
typedef ::IceUtil::Handle<StringListTok> StringListTokPtr;
@@ -37,7 +37,7 @@ typedef ::IceUtil::Handle<FloatingTok> FloatingTokPtr;
typedef ::IceUtil::Handle<ExceptionListTok> ExceptionListTokPtr;
typedef ::IceUtil::Handle<ClassListTok> ClassListTokPtr;
typedef ::IceUtil::Handle<EnumeratorListTok> EnumeratorListTokPtr;
-typedef ::IceUtil::Handle<SyntaxTreeBaseStringTok> SyntaxTreeBaseStringTokPtr;
+typedef ::IceUtil::Handle<ConstDefTok> ConstDefTokPtr;
// ----------------------------------------------------------------------
// StringTok
@@ -49,6 +49,7 @@ public:
StringTok() { }
std::string v;
+ std::string literal;
};
// ----------------------------------------------------------------------
@@ -97,6 +98,7 @@ public:
IntegerTok() { }
IceUtil::Int64 v;
+ std::string literal;
};
// ----------------------------------------------------------------------
@@ -109,6 +111,7 @@ public:
FloatingTok() { }
double v;
+ std::string literal;
};
// ----------------------------------------------------------------------
@@ -160,15 +163,15 @@ public:
};
// ----------------------------------------------------------------------
-// SyntaxTreeBaseStringTok
+// ConstDefTok
// ----------------------------------------------------------------------
-class SLICE_API SyntaxTreeBaseStringTok : public GrammarBase
+class SLICE_API ConstDefTok : public GrammarBase
{
public:
- SyntaxTreeBaseStringTok() { }
- SyntaxTreeBaseString v;
+ ConstDefTok() { }
+ ConstDef v;
};
}
diff --git a/cpp/src/Slice/MD5.cpp b/cpp/src/Slice/MD5.cpp
new file mode 100644
index 00000000000..0583b6ddc32
--- /dev/null
+++ b/cpp/src/Slice/MD5.cpp
@@ -0,0 +1,56 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Slice/MD5.h>
+#include <Slice/MD5I.h>
+
+using namespace std;
+
+//
+// This class is a C++ wrapper around the C implementation contained in
+// MD5I.cpp, obtained from http://sourceforge.net/projects/libmd5-rfc/.
+//
+
+Slice::MD5::MD5()
+{
+ _state = new md5_state_s;
+ md5_init(_state);
+}
+
+Slice::MD5::MD5(const unsigned char* data, int n)
+{
+ _state = new md5_state_s;
+ md5_init(_state);
+ update(data, n);
+ finish();
+}
+
+Slice::MD5::~MD5()
+{
+ delete _state;
+}
+
+void
+Slice::MD5::update(const unsigned char* data, int n)
+{
+ md5_append(_state, data, n);
+}
+
+void
+Slice::MD5::finish()
+{
+ md5_finish(_state, _digest);
+ md5_init(_state);
+}
+
+void
+Slice::MD5::getDigest(unsigned char* digest) const
+{
+ memcpy(digest, _digest, sizeof(unsigned char) * 16);
+}
diff --git a/cpp/src/Slice/MD5.h b/cpp/src/Slice/MD5.h
new file mode 100644
index 00000000000..ae42456f692
--- /dev/null
+++ b/cpp/src/Slice/MD5.h
@@ -0,0 +1,44 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef SLICE_MD5_H
+#define SLICE_MD5_H
+
+#include <IceUtil/Config.h>
+
+extern "C"
+{
+struct md5_state_s;
+}
+
+namespace Slice
+{
+
+class MD5
+{
+public:
+
+ MD5();
+ MD5(const unsigned char*, int);
+ ~MD5();
+
+ void update(const unsigned char*, int);
+ void finish();
+
+ void getDigest(unsigned char*) const;
+
+private:
+
+ md5_state_s* _state;
+ unsigned char _digest[16];
+};
+
+}
+
+#endif
diff --git a/cpp/src/Slice/MD5I.cpp b/cpp/src/Slice/MD5I.cpp
new file mode 100644
index 00000000000..175401d7006
--- /dev/null
+++ b/cpp/src/Slice/MD5I.cpp
@@ -0,0 +1,381 @@
+/*
+ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/* $Id$ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.c is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+ either statically or dynamically; added missing #include <string.h>
+ in library.
+ 2002-03-11 lpd Corrected argument list for main(), and added int return
+ type, in test program and T value program.
+ 2002-02-21 lpd Added missing #include <stdio.h> in test program.
+ 2000-07-03 lpd Patched to eliminate warnings about "constant is
+ unsigned in ANSI C, signed in traditional"; made test program
+ self-checking.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+ 1999-05-03 lpd Original version.
+ */
+
+#include <Slice/MD5I.h>
+#include <string.h>
+
+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+# define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+ md5_word_t
+ a = pms->abcd[0], b = pms->abcd[1],
+ c = pms->abcd[2], d = pms->abcd[3];
+ md5_word_t t;
+#if BYTE_ORDER > 0
+ /* Define storage only for big-endian CPUs. */
+ md5_word_t X[16];
+#else
+ /* Define storage for little-endian or both types of CPUs. */
+ md5_word_t xbuf[16];
+ const md5_word_t *X;
+#endif
+
+ {
+#if BYTE_ORDER == 0
+ /*
+ * Determine dynamically whether this is a big-endian or
+ * little-endian machine, since we can use a more efficient
+ * algorithm on the latter.
+ */
+ static const int w = 1;
+
+ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+ {
+ /*
+ * On little-endian machines, we can process properly aligned
+ * data without copying it.
+ */
+ if (!((data - (const md5_byte_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ } else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+ }
+#endif
+#if BYTE_ORDER == 0
+ else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+ {
+ /*
+ * On big-endian machines, we must arrange the bytes in the
+ * right order.
+ */
+ const md5_byte_t *xp = data;
+ int i;
+
+# if BYTE_ORDER == 0
+ X = xbuf; /* (dynamic only) */
+# else
+# define xbuf X /* (static only) */
+# endif
+ for (i = 0; i < 16; ++i, xp += 4)
+ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+ }
+#endif
+ }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + H(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ pms->abcd[0] += a;
+ pms->abcd[1] += b;
+ pms->abcd[2] += c;
+ pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+ pms->count[0] = pms->count[1] = 0;
+ pms->abcd[0] = 0x67452301;
+ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+ pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+ const md5_byte_t *p = data;
+ int left = nbytes;
+ int offset = (pms->count[0] >> 3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ pms->count[1] += nbytes >> 29;
+ pms->count[0] += nbits;
+ if (pms->count[0] < nbits)
+ pms->count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(pms->buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ md5_process(pms, pms->buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ md5_process(pms, p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+ static const md5_byte_t pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ md5_byte_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ /* Pad to 56 bytes mod 64. */
+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ md5_append(pms, data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
diff --git a/cpp/src/Slice/MD5I.h b/cpp/src/Slice/MD5I.h
new file mode 100644
index 00000000000..66588283e83
--- /dev/null
+++ b/cpp/src/Slice/MD5I.h
@@ -0,0 +1,91 @@
+/*
+ Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/* $Id$ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.h is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Removed support for non-ANSI compilers; removed
+ references to Ghostscript; clarified derivation from RFC 1321;
+ now handles byte order either statically or dynamically.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+ added conditionalization for C++ compilation from Martin
+ Purschke <purschke@bnl.gov>.
+ 1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+# define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Initialize the algorithm. */
+void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile
index d962c852749..db10d93cd5a 100644
--- a/cpp/src/Slice/Makefile
+++ b/cpp/src/Slice/Makefile
@@ -20,7 +20,6 @@ OBJS = Scanner.o \
Parser.o \
CPlusPlusUtil.o \
CsUtil.o \
- VbUtil.o \
JavaUtil.o \
Preprocessor.o \
Checksum.o \
diff --git a/cpp/src/Slice/Makefile.mak b/cpp/src/Slice/Makefile.mak
index 044d12b178c..6b1d7d0d6f7 100644
--- a/cpp/src/Slice/Makefile.mak
+++ b/cpp/src/Slice/Makefile.mak
@@ -19,13 +19,14 @@ OBJS = Scanner.obj \
Parser.obj \
CPlusPlusUtil.obj \
CsUtil.obj \
- VbUtil.obj \
JavaUtil.obj \
Preprocessor.obj \
Checksum.obj \
PythonUtil.obj \
DotNetNames.obj \
- RubyUtil.obj
+ RubyUtil.obj \
+ MD5.obj \
+ MD5I.obj
SRCS = $(OBJS:.obj=.cpp)
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index cdc74772be9..7f79e2bf54c 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -1023,7 +1023,8 @@ Slice::Container::createEnumerator(const string& name)
ConstPtr
Slice::Container::createConst(const string name, const TypePtr& constType, const StringList& metaData,
- const SyntaxTreeBasePtr& literalType, const string& value, NodeType nt)
+ const SyntaxTreeBasePtr& literalType, const string& value, const string& literal,
+ NodeType nt)
{
checkPrefix(name);
@@ -1084,7 +1085,7 @@ Slice::Container::createConst(const string name, const TypePtr& constType, const
return 0;
}
- ConstPtr p = new Const(this, name, constType, metaData, value);
+ ConstPtr p = new Const(this, name, constType, metaData, value, literal);
_contents.push_back(p);
return p;
}
@@ -1449,6 +1450,21 @@ Slice::Container::enums() const
return result;
}
+ConstList
+Slice::Container::consts() const
+{
+ ConstList result;
+ for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ {
+ ConstPtr q = ConstPtr::dynamicCast(*p);
+ if(q)
+ {
+ result.push_back(q);
+ }
+ }
+ return result;
+}
+
ContainedList
Slice::Container::contents() const
{
@@ -4093,6 +4109,12 @@ Slice::Const::value() const
return _value;
}
+string
+Slice::Const::literal() const
+{
+ return _literal;
+}
+
Contained::ContainedType
Slice::Const::containedType() const
{
@@ -4316,12 +4338,13 @@ Slice::Const::isInRange(const string& name, const TypePtr& constType, const stri
}
Slice::Const::Const(const ContainerPtr& container, const string& name, const TypePtr& type,
- const StringList& typeMetaData, const string& value) :
+ const StringList& typeMetaData, const string& value, const string& literal) :
SyntaxTreeBase(container->unit()),
Contained(container, name),
_type(type),
_typeMetaData(typeMetaData),
- _value(value)
+ _value(value),
+ _literal(literal)
{
}
diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l
index b132a4e070d..863c54caffb 100644
--- a/cpp/src/Slice/Scanner.l
+++ b/cpp/src/Slice/Scanner.l
@@ -177,9 +177,11 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e
\" {
StringTokPtr str = new StringTok;
+ str->literal = "\"";
while(true)
{
char c = static_cast<char>(yyinput());
+ str->literal += c;
if(c == '"')
{
break;
@@ -196,6 +198,7 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e
else if(c == '\\')
{
char next = static_cast<char>(yyinput());
+ str->literal += next;
switch(next)
{
case '\\':
@@ -263,6 +266,7 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e
unsigned short us = next - '0';
if(octalDigits.find_first_of(next = static_cast<char>(yyinput())) != string::npos)
{
+ str->literal += next;
us = us * 8 + next - '0';
if(octalDigits.find_first_of(next = static_cast<char>(yyinput())) != string::npos)
{
@@ -289,6 +293,7 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e
IceUtil::Int64 ull = 0;
while(isxdigit(next = static_cast<char>(yyinput())))
{
+ str->literal += next;
ull *= 16;
if(isdigit(next))
{
@@ -332,6 +337,7 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e
{integer_constant} {
IntegerTokPtr itp = new IntegerTok;
+ itp->literal = string(yytext);
*yylvalp = itp;
if(!IceUtilInternal::stringToInt64(string(yytext), itp->v))
{
@@ -349,6 +355,7 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e
FloatingTokPtr ftp = new FloatingTok;
*yylvalp = ftp;
string literal(yytext);
+ ftp->literal = literal;
char lastChar = literal[literal.size() - 1];
if(lastChar == 'f' || lastChar == 'F')
{
diff --git a/cpp/src/Slice/VbUtil.cpp b/cpp/src/Slice/VbUtil.cpp
deleted file mode 100755
index f1b354a3dd7..00000000000
--- a/cpp/src/Slice/VbUtil.cpp
+++ /dev/null
@@ -1,1294 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#include <Slice/VbUtil.h>
-#include <Slice/DotNetNames.h>
-#include <IceUtil/Functional.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef _WIN32
-#include <direct.h>
-#endif
-
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
-using namespace std;
-using namespace Slice;
-using namespace IceUtil;
-using namespace IceUtilInternal;
-
-static string
-lookupKwd(const string& name, int baseTypes, bool mangleCasts = false)
-{
- //
- // Keyword list. *Must* be kept in alphabetical order.
- //
- static const string keywordList[] =
- {
- "AddHandler", "AddressOf", "Alias", "And", "AndAlso", "Ansi", "As", "Assembly", "Auto",
- "Boolean", "ByRef", "Byte", "ByVal", "Call", "Case", "Catch", "CBool", "CByte", "CChar",
- "CDate", "CDbl", "CDec", "Char", "CInt", "Class", "CLng", "CObj", "Const", "CShort", "CSng",
- "CStr", "CType", "Date", "Decimal", "Declare", "Default", "Delegate", "Dim", "DirectCast",
- "Do", "Double", "Each", "Else", "ElseIf", "End", "EndIf", "Enum", "Erase", "Error", "Event",
- "Exit", "False", "Finally", "For", "Friend", "Function", "Get", "GetType", "GoSub", "GoTo",
- "Handles", "If", "Implements", "Imports", "In", "Inherits", "Integer", "Interface", "Is",
- "Let", "Lib", "Like", "Long", "Loop", "Me", "Mod", "Module", "MustInherit", "MustOverride",
- "MyBase", "MyClass", "Namespace", "New", "Next", "Not", "Nothing", "NotInheritable",
- "NotOverridable", "Object", "On", "Option", "Optional", "Or", "OrElse", "Overloads", "Overridable",
- "Overrides", "ParamArray", "Preserve", "Private", "Property", "Protected", "Public", "RaiseEvent",
- "ReadOnly", "ReDim", "REM", "RemoveHandler", "Resume", "Return", "Select", "Set",
- "Shadows", "Shared", "Short", "Single", "Static", "Step", "Stop", "String", "Structure",
- "Sub", "SyncLock", "Then", "Throw", "To", "True", "Try", "TypeOf", "Unicode", "Until",
- "Variant", "Wend", "When", "While", "With", "WithEvents", "WriteOnly", "Xor"
- };
- bool found = binary_search(&keywordList[0],
- &keywordList[sizeof(keywordList) / sizeof(*keywordList)],
- name,
- Slice::CICompare());
- if(found)
- {
- return "[" + name + "]";
- }
- if(mangleCasts && (name == "checkedCast" || name == "uncheckedCast"))
- {
- return string(DotNet::manglePrefix) + name;
- }
- return Slice::DotNet::mangleName(name, baseTypes);
-}
-
-//
-// Split a scoped name into its components and return the components as a list of (unscoped) identifiers.
-//
-static StringList
-splitScopedName(const string& scoped)
-{
- assert(scoped[0] == ':');
- StringList ids;
- string::size_type next = 0;
- string::size_type pos;
- while((pos = scoped.find("::", next)) != string::npos)
- {
- pos += 2;
- if(pos != scoped.size())
- {
- string::size_type endpos = scoped.find("::", pos);
- if(endpos != string::npos)
- {
- ids.push_back(scoped.substr(pos, endpos - pos));
- }
- }
- next = pos;
- }
- if(next != scoped.size())
- {
- ids.push_back(scoped.substr(next));
- }
- else
- {
- ids.push_back("");
- }
-
- return ids;
-}
-
-//
-// If the passed name is a scoped name, return the identical scoped name,
-// but with all components that are VB keywords replaced by
-// their "[]"-surrounded version; otherwise, if the passed name is
-// not scoped, but a VB keyword, return the "[]"-surrounded name;
-// otherwise, check if the name is one of the method names of baseTypes;
-// if so, prefix it with _Ice_; otherwise, reutrn the name unchanged.
-//
-string
-Slice::VbGenerator::fixId(const string& name, int baseTypes, bool mangleCasts)
-{
- if(name.empty())
- {
- return name;
- }
- if(name[0] != ':')
- {
- return lookupKwd(name, baseTypes, mangleCasts);
- }
- StringList ids = splitScopedName(name);
- StringList newIds;
- for(StringList::const_iterator i = ids.begin(); i != ids.end(); ++i)
- {
- newIds.push_back(lookupKwd(*i, baseTypes));
- }
- stringstream result;
- for(StringList::const_iterator j = ids.begin(); j != ids.end(); ++j)
- {
- if(j != ids.begin())
- {
- result << '.';
- }
- result << *j;
- }
- return result.str();
-}
-
-string
-Slice::VbGenerator::typeToString(const TypePtr& type)
-{
- if(!type)
- {
- return "";
- }
-
- static const char* builtinTable[] =
- {
- "Byte",
- "Boolean",
- "Short",
- "Integer",
- "Long",
- "Single",
- "Double",
- "String",
- "Ice.Object",
- "Ice.ObjectPrx",
- "Ice.LocalObject"
- };
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- return builtinTable[builtin->kind()];
- }
-
- ProxyPtr proxy = ProxyPtr::dynamicCast(type);
- if(proxy)
- {
- return fixId(proxy->_class()->scoped() + "Prx");
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq && !seq->hasMetaData("clr:collection"))
- {
- return typeToString(seq->type()) + "()";
- }
-
- ContainedPtr contained = ContainedPtr::dynamicCast(type);
- if(contained)
- {
- return fixId(contained->scoped());
- }
-
- return "???";
-}
-
-bool
-Slice::VbGenerator::isValueType(const TypePtr& type)
-{
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- switch(builtin->kind())
- {
- case Builtin::KindString:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- return false;
- break;
- }
- default:
- {
- return true;
- break;
- }
- }
- }
- StructPtr s = StructPtr::dynamicCast(type);
- if(s)
- {
- if(s->hasMetaData("clr:class"))
- {
- return false;
- }
- DataMemberList dm = s->dataMembers();
- for(DataMemberList::const_iterator i = dm.begin(); i != dm.end(); ++i)
- {
- if(!isValueType((*i)->type()))
- {
- return false;
- }
- }
- return true;
- }
- if(EnumPtr::dynamicCast(type))
- {
- return true;
- }
- return false;
-}
-
-void
-Slice::VbGenerator::writeMarshalUnmarshalCode(Output &out,
- const TypePtr& type,
- const string& param,
- bool marshal,
- bool streamingAPI,
- bool isOutParam,
- const string& patchParams)
-{
- string stream;
-
- if(marshal)
- {
- stream = streamingAPI ? "outS__" : "os__";
- }
- else
- {
- stream = streamingAPI ? "inS__" : "is__";
- }
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- switch(builtin->kind())
- {
- case Builtin::KindByte:
- {
- if(marshal)
- {
- out << nl << stream << ".writeByte(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readByte()";
- }
- break;
- }
- case Builtin::KindBool:
- {
- if(marshal)
- {
- out << nl << stream << ".writeBool(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readBool()";
- }
- break;
- }
- case Builtin::KindShort:
- {
- if(marshal)
- {
- out << nl << stream << ".writeShort(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readShort()";
- }
- break;
- }
- case Builtin::KindInt:
- {
- if(marshal)
- {
- out << nl << stream << ".writeInt(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readInt()";
- }
- break;
- }
- case Builtin::KindLong:
- {
- if(marshal)
- {
- out << nl << stream << ".writeLong(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readLong()";
- }
- break;
- }
- case Builtin::KindFloat:
- {
- if(marshal)
- {
- out << nl << stream << ".writeFloat(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readFloat()";
- }
- break;
- }
- case Builtin::KindDouble:
- {
- if(marshal)
- {
- out << nl << stream << ".writeDouble(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readDouble()";
- }
- break;
- }
- case Builtin::KindString:
- {
- if(marshal)
- {
- out << nl << stream << ".writeString(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readString()";
- }
- break;
- }
- case Builtin::KindObject:
- {
- if(marshal)
- {
- out << nl << stream << ".writeObject(" << param << ')';
- }
- else
- {
- if(isOutParam)
- {
- out << nl << "Dim " << param
- << "_PP As IceInternal.ParamPatcher = New IceInternal.ParamPatcher(GetType(Ice.Object), "
- << "\"::Ice::Object\")";
- if(streamingAPI)
- {
- out << nl << stream << ".readObject(CType(" << param << "_PP, Ice.ReadObjectCallback))";
- }
- else
- {
- out << nl << stream << ".readObject(" << param << "_PP)";
- }
- }
- else
- {
- if(streamingAPI)
- {
- out << nl << stream << ".readObject(CType(New Patcher__(" << patchParams
- << ", Ice.ReadObjectCallback)))";
- }
- else
- {
- out << nl << stream << ".readObject(New Patcher__(" << patchParams << "))";
- }
- }
- }
- break;
- }
- case Builtin::KindObjectProxy:
- {
- if(marshal)
- {
- out << nl << stream << ".writeProxy(" << param << ')';
- }
- else
- {
- out << nl << param << " = " << stream << ".readProxy()";
- }
- break;
- }
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- }
- return;
- }
-
- ProxyPtr prx = ProxyPtr::dynamicCast(type);
- if(prx)
- {
- ContainedPtr contained = ContainedPtr::dynamicCast(type);
- string helperName = fixId((contained ? contained->scoped() : typeToString(type)) + "Helper");
- if(marshal)
- {
- out << nl << helperName << ".write";
- if(!streamingAPI)
- {
- out << "__";
- }
- out << '(' << stream << ", " << param << ')';
- }
- else
- {
- out << nl << param << " = " << helperName << ".read";
- if(!streamingAPI)
- {
- out << "__";
- }
- out << "(" << stream << ')';
- }
- return;
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- if(cl)
- {
- if(marshal)
- {
- out << nl << stream << ".writeObject(" << param << ")";
- }
- else
- {
- if(isOutParam)
- {
- ContainedPtr contained = ContainedPtr::dynamicCast(type);
- out << nl << "Dim " << param
- << "_PP As IceInternal.ParamPatcher = New IceInternal.ParamPatcher(GetType("
- << typeToString(type) << "), \"" << contained->scoped() << "\")";
- if(streamingAPI)
- {
- out << nl << stream << ".readObject(CType(" << param << "_PP, Ice.ReadObjectCallback))";
- }
- else
- {
- out << nl << stream << ".readObject(" << param << "_PP)";
- }
- }
- else
- {
- if(streamingAPI)
- {
- out << nl << stream << ".readObject(New Patcher__(CType(" << patchParams
- << ", Ice.ReadObjectCallback)))";
- }
- else
- {
- out << nl << stream << ".readObject(New Patcher__(" << patchParams << "))";
- }
- }
- }
- return;
- }
-
- StructPtr st = StructPtr::dynamicCast(type);
- if(st)
- {
- if(marshal)
- {
- if(streamingAPI)
- {
- out << nl << param << ".ice_write(" << stream << ')';
- }
- else
- {
- out << nl << param << ".write__(" << stream << ')';
- }
- }
- else
- {
- string typeS = typeToString(type);
- out << nl << param << " = New " << typeS;
- if(streamingAPI)
- {
- out << nl << param << ".ice_read(" << stream << ")";
- }
- else
- {
- out << nl << param << ".read__(" << stream << ")";
- }
- }
- return;
- }
-
- EnumPtr en = EnumPtr::dynamicCast(type);
- if(en)
- {
- string func;
- string cast;
- size_t sz = en->getEnumerators().size();
- if(sz <= 0x7f)
- {
- func = marshal ? "writeByte" : "readByte";
- cast = marshal ? string("Byte") : fixId(en->scoped());
- }
- else if(sz <= 0x7fff)
- {
- func = marshal ? "writeShort" : "readShort";
- cast = marshal ? string("Short") : fixId(en->scoped());
- }
- else
- {
- func = marshal ? "writeInt" : "readInt";
- cast = marshal ? string("Integer") : fixId(en->scoped());
- }
- if(marshal)
- {
- out << nl << stream << '.' << func << "(CType(" << param << ", " << cast << "))";
- }
- else
- {
- out << nl << param << " = CType(" << stream << '.' << func << "(), " << cast << ')';
- }
- return;
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq)
- {
- writeSequenceMarshalUnmarshalCode(out, seq, param, marshal, streamingAPI);
- return;
- }
-
- assert(ConstructedPtr::dynamicCast(type));
- string helperName = fixId(ContainedPtr::dynamicCast(type)->scoped() + "Helper");
- if(marshal)
- {
- out << nl << helperName << ".write(" << stream << ", " << param << ')';
- }
- else
- {
- out << nl << param << " = " << helperName << ".read(" << stream << ')';
- }
-}
-
-void
-Slice::VbGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
- const SequencePtr& seq,
- const string& param,
- bool marshal,
- bool streamingAPI)
-{
- string stream;
- if(marshal)
- {
- stream = streamingAPI ? "outS__" : "os__";
- }
- else
- {
- stream = streamingAPI ? "inS__" : "is__";
- }
-
- TypePtr type = seq->type();
- string typeS = typeToString(type);
-
- bool isArray = !seq->hasMetaData("clr:collection");
- string limitID = isArray ? "Length" : "Count";
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- switch(builtin->kind())
- {
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- {
- if(marshal)
- {
- out << nl << "If " << param << " Is Nothing Then";
- out.inc();
- out << nl << stream << ".writeSize(0)";
- out.dec();
- out << nl << "Else";
- out.inc();
- out << nl << stream << ".writeSize(" << param << '.' << limitID << ")";
- out << nl << "For ix__ As Integer = 0 To " << param << '.' << limitID << " - 1";
- out.inc();
- string func = builtin->kind() == Builtin::KindObject ? "writeObject" : "writeProxy";
- out << nl << stream << '.' << func << '(' << param << "(ix__))";
- out.dec();
- out << nl << "Next";
- out.dec();
- out << nl << "End If";
- }
- else
- {
- out << nl << "For block__ As Integer = 0 To 0";
- out.inc();
- out << nl << "Dim lenx__ As Integer = " << stream << ".readSize()";
- if(!streamingAPI)
- {
- if(builtin->isVariableLength())
- {
- out << nl << stream << ".startSeq(lenx__, " << static_cast<unsigned>(builtin->minWireSize())
- << ")";
- }
- else
- {
- out << nl << stream << ".checkFixedSeq(lenx__, "
- << static_cast<unsigned>(builtin->minWireSize()) << ")";
- }
- }
- out << nl << param << " = New ";
- if(builtin->kind() == Builtin::KindObject)
- {
- if(isArray)
- {
- out << "Ice.Object(lenx__ - 1) {}";
- }
- else
- {
- out << typeToString(seq);
- }
- out << nl << "For ix__ As Integer = 0 To lenx__ - 1";
- out.inc();
- if(streamingAPI)
- {
- out << nl << stream << ".readObject(CType(New IceInternal.SequencePatcher("
- << param << ", GetType(Ice.Object), ix__), Ice.ReadObjectCallback))";
- }
- else
- {
- out << nl << stream << ".readObject(New IceInternal.SequencePatcher("
- << param << ", GetType(Ice.Object), ix__))";
- }
- out.dec();
- out << nl << "Next";
- }
- else
- {
- if(isArray)
- {
- out << "Ice.ObjectPrx(lenx__ - 1) {}";
- }
- else
- {
- out << typeToString(seq);
- }
- out << nl << "For ix__ As Integer = 0 To lenx__ - 1";
- out.inc();
- if(isArray)
- {
- out << nl << param << "(ix__) = " << stream << ".readProxy()";
- }
- else
- {
- out << nl << "Dim val__ As Ice.ObjectPrx = New Ice.ObjectPrxHelperBase";
- out << nl << "val__ = " << stream << ".readProxy()";
- out << nl << param << ".Add(val__)";
- }
- out.dec();
- out << nl << "Next";
- }
- if(!streamingAPI && builtin->isVariableLength())
- {
- out << nl << stream << ".checkSeq()";
- out << nl << stream << ".endElement()";
- out << nl << stream << ".endSeq(lenx__)";
- }
- out.dec();
- out << nl << "Next";
- }
- break;
- }
- default:
- {
- string marshalName = builtin->kindAsString();
- marshalName[0] = toupper(marshalName[0]);
- if(marshal)
- {
- out << nl << stream << ".write" << marshalName << "Seq(" << param;
- if(!isArray)
- {
- out << ".ToArray()";
- }
- out << ')';
- }
- else
- {
- if(!isArray)
- {
- out << nl << param << " = New " << fixId(seq->scoped())
- << '(' << stream << ".read" << marshalName << "Seq())";
- }
- else
- {
- out << nl << param << " = " << stream << ".read" << marshalName << "Seq()";
- }
- }
- break;
- }
- }
- return;
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- if(cl)
- {
- out << nl << "For block__ As Integer = 0 To 0";
- out.inc();
- if(marshal)
- {
- out << nl << "If " << param << " Is Nothing";
- out.inc();
- out << nl << stream << ".writeSize(0)";
- out.dec();
- out << nl << "Else";
- out.inc();
- out << nl << stream << ".writeSize(" << param << '.' << limitID << ")";
- out << nl << "For ix__ As Integer = 0 To " << param << '.' << limitID << " - 1";
- out.inc();
- out << nl << stream << ".writeObject(" << param << "(ix__))";
- out.dec();
- out << nl << "Next";
- out.dec();
- out << nl << "End If";
- }
- else
- {
- out << nl << "Dim szx__ As Integer = " << stream << ".readSize()";
- if(!streamingAPI)
- {
- if(type->isVariableLength())
- {
- out << nl << stream << ".startSeq(szx__, " << static_cast<unsigned>(type->minWireSize()) << ')';
- }
- else
- {
- out << nl << stream << ".checkFixedSeq(szx__, " << static_cast<unsigned>(type->minWireSize()) << ')';
- }
- }
- out << nl << param << " = New ";
- if(isArray)
- {
- out << toArrayAlloc(typeS + "()", "szx__ - 1") << " {}";
- }
- else
- {
- out << fixId(seq->scoped()) << "(szx__)";
- }
- out << nl << "For ix__ As Integer = 0 To szx__ - 1";
- out.inc();
- out << nl << "Dim spx__ As IceInternal.SequencePatcher = New IceInternal.SequencePatcher("
- << param << ", " << "GetType(" << typeS << "), ix__)";
- if(streamingAPI)
- {
- out << nl << stream << ".readObject(CType(spx__, Ice.ReadObjectCallback))";
- }
- else
- {
- out << nl << stream << ".readObject(spx__)";
- }
- if(!streamingAPI && type->isVariableLength())
- {
- out << nl << stream << ".checkSeq()";
- out << nl << stream << ".endElement()";
- }
- out.dec();
- out << nl << "Next";
- if(!streamingAPI && type->isVariableLength())
- {
- out << nl << stream << ".endSeq(szx__)";
- }
- }
- out.dec();
- out << nl << "Next";
- return;
- }
-
- StructPtr st = StructPtr::dynamicCast(type);
- if(st)
- {
- out << nl << "For block__ As Integer = 0 To 0";
- out.inc();
- if(marshal)
- {
- out << nl << "If " << param << " Is Nothing";
- out.inc();
- out << nl << stream << ".writeSize(0)";
- out.dec();
- out << nl << "Else";
- out.inc();
- out << nl << stream << ".writeSize(" << param << '.' << limitID << ")";
- out << nl << "For ix__ As Integer = 0 To " << param << '.' << limitID << " - 1";
- out.inc();
- if(streamingAPI)
- {
- out << nl << param << "(ix__).ice_write(" << stream << ")";
- }
- else
- {
- out << nl << param << "(ix__).write__(" << stream << ")";
- }
- out.dec();
- out << nl << "Next";
- out.dec();
- out << nl << "End If";
- }
- else
- {
- out << nl << "Dim szx__ As Integer = " << stream << ".readSize()";
- if(!streamingAPI)
- {
- if(type->isVariableLength())
- {
- out << nl << stream << ".startSeq(szx__, " << static_cast<unsigned>(type->minWireSize()) << ')';
- }
- else
- {
- out << nl << stream << ".checkFixedSeq(szx__, " << static_cast<unsigned>(type->minWireSize()) << ')';
- }
- }
- out << nl << param << " = New ";
- if(isArray)
- {
- out << toArrayAlloc(typeS + "()", "szx__ - 1") << " {}";
- }
- else
- {
- out << fixId(seq->scoped()) << "(szx__)";
- }
- out << nl << "For ix__ As Integer = 0 To szx__ - 1";
- out.inc();
- if(isArray)
- {
- if(!isValueType(st))
- {
- out << nl << param << "(ix__) = New " << typeS;
- }
- if(streamingAPI)
- {
- out << nl << param << "(ix__).ice_read(" << stream << ")";
- }
- else
- {
- out << nl << param << "(ix__).read__(" << stream << ")";
- }
- }
- else
- {
- out << nl << "Dim val__ As " << typeS << " = New " << typeS;
- if(streamingAPI)
- {
- out << nl << "val__.ice_read(" << stream << ')';
- }
- else
- {
- out << nl << "val__.read__(" << stream << ')';
- }
- out << nl << param << ".Add(val__)";
- }
- if(!streamingAPI && type->isVariableLength())
- {
- out << nl << stream << ".checkSeq()";
- out << nl << stream << ".endElement()";
- }
- out.dec();
- out << nl << "Next";
- if(!streamingAPI && type->isVariableLength())
- {
- out << nl << stream << ".endSeq(szx__)";
- }
- }
- out.dec();
- out << nl << "Next";
- return;
- }
-
- EnumPtr en = EnumPtr::dynamicCast(type);
- if(en)
- {
- out << nl << "For block__ As Integer = 0 To 0";
- out.inc();
- if(marshal)
- {
- out << nl << "If " << param << " Is Nothing";
- out.inc();
- out << nl << stream << ".writeSize(0)";
- out.dec();
- out << nl << "Else";
- out.inc();
- out << nl << stream << ".writeSize(" << param << '.'<< limitID << ')';
- out << nl << "For ix__ As Integer = 0 To " << param << '.' << limitID << " - 1";
- out.inc();
- out << nl << stream << ".writeByte(CType(" << param << "(ix__), Byte))";
- out.dec();
- out << nl << "Next";
- out.dec();
- out << nl << "End If";
- }
- else
- {
- out << nl << "Dim szx__ As Integer = " << stream << ".readSize()";
- if(!streamingAPI)
- {
- out << nl << stream << ".checkFixedSeq(szx__, " << static_cast<unsigned>(type->minWireSize()) << ')';
- }
- out << nl << param << " = New ";
- if(isArray)
- {
- out << toArrayAlloc(typeS + "()", "szx__ - 1") << " {}";
- }
- else
- {
- out << fixId(seq->scoped()) << "(szx__)";
- }
- out << nl << "For ix__ As Integer = 0 To szx__ - 1";
- out.inc();
- if(isArray)
- {
- out << nl << param << "(ix__) = CType(" << stream << ".readByte(), " << typeS << ')';
- }
- else
- {
- out << nl << param << ".Add(CType(" << stream << ".readByte(), " << typeS << "))";
- }
- out.dec();
- out << nl << "Next";
- }
- out.dec();
- out << nl << "Next";
- return;
- }
-
- string helperName;
- if(ProxyPtr::dynamicCast(type))
- {
- helperName = fixId(ProxyPtr::dynamicCast(type)->_class()->scoped() + "PrxHelper");
- }
- else
- {
- helperName = fixId(ContainedPtr::dynamicCast(type)->scoped() + "Helper");
- }
-
- string func;
- if(marshal)
- {
- func = "write";
- if(!streamingAPI && ProxyPtr::dynamicCast(type))
- {
- func += "__";
- }
- out << nl << "If " << param << " Is Nothing";
- out.inc();
- out << nl << stream << ".writeSize(0)";
- out.dec();
- out << nl << "Else";
- out.inc();
- out << nl << stream << ".writeSize(" << param << '.' << limitID << ")";
- out << nl << "For ix__ As Integer = 0 To " << param << '.' << limitID << " - 1";
- out.inc();
- out << nl << helperName << '.' << func << '(' << stream << ", " << param << "(ix__))";
- out.dec();
- out << nl << "Next";
- out.dec();
- out << nl << "End If";
- }
- else
- {
- func = "read";
- if(!streamingAPI && ProxyPtr::dynamicCast(type))
- {
- func += "__";
- }
- out << nl << "For block__ As Integer = 0 To 0";
- out.inc();
- out << nl << "Dim szx__ As Integer = " << stream << ".readSize()";
- if(!streamingAPI)
- {
- if(type->isVariableLength())
- {
- out << nl << stream << ".startSeq(szx__, " << static_cast<unsigned>(type->minWireSize()) << ")";
- }
- else
- {
- out << nl << stream << ".checkFixedSeq(szx__, " << static_cast<unsigned>(type->minWireSize()) << ")";
- }
- }
- out << nl << param << " = New ";
- if(isArray)
- {
- out << toArrayAlloc(typeS + "()", "szx__ - 1") << " {}";
- }
- else
- {
- out << fixId(seq->scoped()) << "(szx__)";
- }
- out << nl << "For ix__ As Integer = 0 To szx__ - 1";
- out.inc();
- if(isArray)
- {
- out << nl << param << "(ix__) = " << helperName << '.' << func << '(' << stream << ")";
- }
- else
- {
- out << nl << param << ".Add(" << helperName << '.' << func << '(' << stream << "))";
- }
- if(!streamingAPI && type->isVariableLength())
- {
- if(!SequencePtr::dynamicCast(type))
- {
- out << nl << stream << ".checkSeq()";
- }
- out << nl << stream << ".endElement()";
- }
- out.dec();
- out << nl << "Next";
- if(!streamingAPI && type->isVariableLength())
- {
- out << nl << stream << ".endSeq(szx__)";
- }
- out.dec();
- out << nl << "Next";
- }
-
- return;
-}
-
-string
-Slice::VbGenerator::toArrayAlloc(const string& decl, const string& sz)
-{
- int count = 0;
- string::size_type pos = decl.size();
- while(pos > 1 && decl.substr(pos - 2, 2) == "()")
- {
- ++count;
- pos -= 2;
- }
- assert(count > 0);
-
- ostringstream o;
- o << decl.substr(0, pos) << '(' << sz << ')' << decl.substr(pos + 2);
- return o.str();
-}
-
-void
-Slice::VbGenerator::validateMetaData(const UnitPtr& u)
-{
- MetaDataVisitor visitor;
- u->visit(&visitor, false);
-}
-
-Slice::VbGenerator::MetaDataVisitor::MetaDataVisitor()
- : _globalMetaDataDone(false)
-{
-}
-
-bool
-Slice::VbGenerator::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
-{
- if(!_globalMetaDataDone)
- {
- //
- // Validate global metadata.
- //
- DefinitionContextPtr dc = p->definitionContext();
- assert(dc);
- StringList globalMetaData = dc->getMetaData();
- string file = dc->filename();
- static const string prefix = "vb:";
- for(StringList::const_iterator q = globalMetaData.begin(); q != globalMetaData.end(); ++q)
- {
- string s = *q;
- if(_history.count(s) == 0)
- {
- if(s.find(prefix) == 0)
- {
- static const string attributePrefix = "vb:attribute:";
- if(s.find(attributePrefix) != 0 || s.size() == attributePrefix.size())
- {
- cout << file << ": warning: ignoring invalid global metadata `" << s << "'" << endl;
- }
- }
- _history.insert(s);
- }
- }
- _globalMetaDataDone = true;
- }
- validate(p);
- return true;
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitModuleEnd(const ModulePtr&)
-{
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitClassDecl(const ClassDeclPtr& p)
-{
- validate(p);
-}
-
-bool
-Slice::VbGenerator::MetaDataVisitor::visitClassDefStart(const ClassDefPtr& p)
-{
- validate(p);
- return true;
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitClassDefEnd(const ClassDefPtr&)
-{
-}
-
-bool
-Slice::VbGenerator::MetaDataVisitor::visitExceptionStart(const ExceptionPtr& p)
-{
- validate(p);
- return true;
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitExceptionEnd(const ExceptionPtr&)
-{
-}
-
-bool
-Slice::VbGenerator::MetaDataVisitor::visitStructStart(const StructPtr& p)
-{
- validate(p);
- return true;
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitStructEnd(const StructPtr&)
-{
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitOperation(const OperationPtr& p)
-{
- validate(p);
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitParamDecl(const ParamDeclPtr& p)
-{
- validate(p);
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
-{
- validate(p);
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitSequence(const SequencePtr& p)
-{
- validate(p);
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitDictionary(const DictionaryPtr& p)
-{
- validate(p);
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitEnum(const EnumPtr& p)
-{
- validate(p);
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::visitConst(const ConstPtr& p)
-{
- validate(p);
-}
-
-void
-Slice::VbGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
-{
- DefinitionContextPtr dc = cont->definitionContext();
- assert(dc);
- string file = dc->filename();
-
- StringList localMetaData = cont->getMetaData();
-
- StringList::const_iterator p;
-
- for(p = localMetaData.begin(); p != localMetaData.end(); ++p)
- {
- string s = *p;
-
- if(s.find("vb:") == 0) // TODO: remove this statement once "vb:" is a hard error.
- {
- if(SequencePtr::dynamicCast(cont))
- {
- if(s.substr(3) == "collection")
- {
- cout << file << ":" << cont->line() << ": warning: `vb:' metadata prefix is deprecated; "
- << "use `clr:' instead" << endl;
- cont->addMetaData("clr:collection");
- }
- }
- else if(StructPtr::dynamicCast(cont))
- {
- if(s.substr(3) == "class")
- {
- cout << file << ":" << cont->line() << ": warning: `vb:' metadata prefix is deprecated; "
- << "use `clr:' instead" << endl;
- cont->addMetaData("clr:class");
- }
- }
- else if(s.find("vb:attribute:") == 0)
- {
- ; // Do nothing, "vb:attribute:" is OK
- }
- else
- {
- cout << file << ":" << cont->line() << ": warning: ignoring invalid metadata `" << s << "'" << endl;
- }
- } // End TODO
-
- string prefix = "clr:";
- if(_history.count(s) == 0)
- {
- if(s.find(prefix) == 0)
- {
- if(SequencePtr::dynamicCast(cont))
- {
- if(s.substr(prefix.size()) == "collection")
- {
- continue;
- }
- }
- if(StructPtr::dynamicCast(cont))
- {
- if(s.substr(prefix.size()) == "class")
- {
- continue;
- }
- if(s.substr(prefix.size()) == "property")
- {
- continue;
- }
- }
- if(ClassDefPtr::dynamicCast(cont))
- {
- if(s.substr(prefix.size()) == "property")
- {
- continue;
- }
- }
- cout << file << ":" << cont->line() << ": warning: ignoring invalid metadata `" << s << "'" << endl;
- }
- _history.insert(s);
- }
-
- prefix = "vb:";
- if(_history.count(s) == 0)
- {
- if(s.find(prefix) == 0)
- {
- if(s.substr(prefix.size()) == "attribute:")
- {
- continue;
- }
- cout << file << ":" << cont->line() << ": warning: ignoring invalid metadata `" << s << "'" << endl;
- }
- _history.insert(s);
- }
- }
-}
diff --git a/cpp/src/slice2html/Gen.cpp b/cpp/src/slice2html/Gen.cpp
index 93e97489b4f..467257c628c 100644
--- a/cpp/src/slice2html/Gen.cpp
+++ b/cpp/src/slice2html/Gen.cpp
@@ -2107,6 +2107,29 @@ Slice::ModuleGenerator::visitContainer(const ContainerPtr& p)
assert(_out.currIndent() == indent);
+ ConstList consts = p->consts();
+
+ if(!consts.empty())
+ {
+ start("h2");
+ _out << "Constant Index";
+ end();
+ start("dl");
+ for(ConstList::const_iterator q = consts.begin(); q != consts.end(); ++q)
+ {
+ start("dt", "Symbol");
+ _out << toString(*q, p, false, true);
+ end();
+ start("dd");
+ string metadata;
+ printSummary(*q, p, (*q)->findMetaData("deprecate", metadata));
+ end();
+ }
+ end();
+ }
+
+ assert(_out.currIndent() == indent);
+
EnumList enums = p->enums();
if(!enums.empty())
@@ -2205,6 +2228,46 @@ Slice::ModuleGenerator::visitContainer(const ContainerPtr& p)
end();
}
}
+
+ if(!consts.empty())
+ {
+ start("h2");
+ _out << "Constants";
+ end();
+ for(ConstList::const_iterator q = consts.begin(); q != consts.end(); ++q)
+ {
+ start("dl");
+ start("dt");
+ start("span", "Synopsis");
+ _out << "const " << toString((*q)->type(), p, false, true) << " " << toString(*q, p) << " = ";
+ if(EnumPtr::dynamicCast((*q)->type()))
+ {
+ _out << toString((*q)->value(), p, false, true);
+ }
+ else
+ {
+ _out << (*q)->literal();
+ }
+ _out << ";";
+ end();
+ end();
+
+ start("dd");
+ string metadata, deprecateReason;
+ if((*q)->findMetaData("deprecate", metadata))
+ {
+ deprecateReason = "This type is deprecated.";
+ if(metadata.find("deprecate:") == 0 && metadata.size() > 10)
+ {
+ deprecateReason = metadata.substr(10);
+ }
+ }
+
+ printComment(*q, p, deprecateReason, true);
+ end();
+ end();
+ }
+ }
}
Slice::ExceptionGenerator::ExceptionGenerator(XMLOutput& o, const Files& files)