From f6121ea342641eb36f7cd67c7c877a1c70ec3055 Mon Sep 17 00:00:00 2001 From: Benoit Foucher Date: Wed, 19 Dec 2007 22:06:38 +0100 Subject: - Merge IPv6 support from Dwayne's branch. - Reviewed and fixed IPv6 bugs. - Fixed bug in the outgoing connection factory where an assert could be triggered if the proxy contained identical endpoints --- cpp/src/Glacier2/SessionRouterI.cpp | 10 +- cpp/src/Ice/Application.cpp | 2 +- cpp/src/Ice/ConnectionFactory.cpp | 18 +- cpp/src/Ice/EndpointFactoryManager.cpp | 2 +- cpp/src/Ice/EndpointFactoryManager.h | 1 + cpp/src/Ice/EndpointI.cpp | 10 +- cpp/src/Ice/EndpointI.h | 5 +- cpp/src/Ice/Instance.cpp | 34 +- cpp/src/Ice/Instance.h | 2 + cpp/src/Ice/Network.cpp | 933 +++++++++++++++++++++------------ cpp/src/Ice/Network.h | 33 +- cpp/src/Ice/ObjectAdapterI.cpp | 71 ++- cpp/src/Ice/ObjectAdapterI.h | 2 +- cpp/src/Ice/PropertyNames.cpp | 2 + cpp/src/Ice/ProtocolPluginFacade.cpp | 6 + cpp/src/Ice/ReferenceFactory.cpp | 43 +- cpp/src/Ice/TcpAcceptor.cpp | 10 +- cpp/src/Ice/TcpAcceptor.h | 6 +- cpp/src/Ice/TcpConnector.cpp | 7 +- cpp/src/Ice/TcpConnector.h | 6 +- cpp/src/Ice/TcpEndpointI.cpp | 74 ++- cpp/src/Ice/TcpEndpointI.h | 2 +- cpp/src/Ice/ThreadPool.cpp | 1 - cpp/src/Ice/UdpConnector.cpp | 3 +- cpp/src/Ice/UdpConnector.h | 7 +- cpp/src/Ice/UdpEndpointI.cpp | 74 +-- cpp/src/Ice/UdpEndpointI.h | 2 +- cpp/src/Ice/UdpTransceiver.cpp | 78 ++- cpp/src/Ice/UdpTransceiver.h | 6 +- cpp/src/Ice/UnknownEndpointI.cpp | 1 - cpp/src/IceGrid/RegistryI.cpp | 22 +- cpp/src/IceSSL/AcceptorI.cpp | 17 +- cpp/src/IceSSL/AcceptorI.h | 7 +- cpp/src/IceSSL/ConnectorI.cpp | 5 +- cpp/src/IceSSL/ConnectorI.h | 7 +- cpp/src/IceSSL/EndpointI.cpp | 72 ++- cpp/src/IceSSL/EndpointI.h | 2 +- cpp/src/IceSSL/Instance.cpp | 6 + cpp/src/IceSSL/Instance.h | 1 + cpp/src/IceSSL/TransceiverI.cpp | 2 +- 40 files changed, 1046 insertions(+), 546 deletions(-) (limited to 'cpp/src') 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 5bf86ba46a2..e9752a9eb86 100644 --- a/cpp/src/Ice/Application.cpp +++ b/cpp/src/Ice/Application.cpp @@ -651,7 +651,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/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp index 835c75c6912..97f5ddc8940 100644 --- a/cpp/src/Ice/ConnectionFactory.cpp +++ b/cpp/src/Ice/ConnectionFactory.cpp @@ -679,7 +679,7 @@ IceInternal::OutgoingConnectionFactory::getConnection(const vector::const_iterator r = connectors.begin(); r != connectors.end(); ++r) { - assert(_pending.find(*r) == _pending.end()); - _pending.insert(pair >(*r, set())); + if(_pending.find(*r) == _pending.end()) + { + _pending.insert(pair >(*r, set())); + } } } @@ -769,9 +771,11 @@ IceInternal::OutgoingConnectionFactory::finishGetConnection(const vector::const_iterator p = connectors.begin(); p != connectors.end(); ++p) { map >::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 #include #include +#include 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 -IceInternal::EndpointI::connectors(const vector& addrs) const +IceInternal::EndpointI::connectors(const vector& 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 addrs = getAddresses(host, port, false); + vector 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::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 #include #include +#include #ifdef _WIN32 # include @@ -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 expand() const = 0; @@ -149,7 +150,7 @@ public: private: - virtual std::vector connectors(const std::vector&) const; + virtual std::vector connectors(const std::vector&) 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 9349990bb63..de7a679739b 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/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 #elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__) # include +# include #else # include # include @@ -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 +getLocalAddresses(ProtocolSupport protocol) +{ + vector 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 buffer; + buffer.resize(1024); + unsigned long len = 0; + DWORD rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, + &buffer[0], static_cast(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(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(&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(&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(&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(&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(&addr)->sin6_addr)) + { + result.push_back(*reinterpret_cast(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(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(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(&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(&addr)->sin6_addr)) + { + result.push_back(*reinterpret_cast(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(&addr)->sin_port = htons(port); + } + else if(info->ai_family != AF_INET6) + { + reinterpret_cast(&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(&addr); + if(addrin->sin_addr.s_addr == INADDR_ANY) + { + return true; + } + } + else if(addr.ss_family) + { + struct sockaddr_in6* addrin6 = reinterpret_cast(&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(&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(&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(&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(&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 +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 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(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(&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(&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(&addr1); + const struct sockaddr_in* addr2in = reinterpret_cast(&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(&addr1); + const struct sockaddr_in6* addr2in = reinterpret_cast(&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(&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 ""; } - 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(sizeof(struct sockaddr_in)); + socklen_t len = static_cast(sizeof(struct sockaddr_storage)); if(getsockname(fd, reinterpret_cast(&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(sizeof(struct sockaddr_in)); + socklen_t len = static_cast(sizeof(struct sockaddr_storage)); if(getpeername(fd, reinterpret_cast(&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(&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(&addr); + s << ntohs(addrin->sin_port); + } + else + { + const struct sockaddr_in6* addrin = reinterpret_cast(&addr); + s << ntohs(addrin->sin6_port); + } return s.str(); } -vector -IceInternal::getAddresses(const string& host, int port, bool blocking) +int +IceInternal::getPort(const struct sockaddr_storage& addr) { - vector result; - - if(host == "0.0.0.0") + if(addr.ss_family == AF_INET) { - vector 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(&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(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(&addr)->sin6_port); } - - return result; } vector -IceInternal::getLocalHosts() +IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport protocolSupport) { - vector result; - -#if defined(_WIN32) - try + vector hosts; + if(host.empty() || isWildcard(host, protocolSupport)) { - SOCKET fd = createSocket(false); - - vector buffer; - buffer.resize(1024); - unsigned long len = 0; - DWORD rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, - &buffer[0], static_cast(buffer.size()), - &len, 0, 0); - if(rs == SOCKET_ERROR) + vector addrs = getLocalAddresses(protocolSupport); + for(vector::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(&(*p))->sin6_addr)) { - buffer.resize(len); - rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, - &buffer[0], static_cast(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(&buffer[0]); - for (int i = 0; i < addrs->iAddressCount; ++i) - { - result.push_back( - inetAddrToString(reinterpret_cast(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(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(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(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(&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 #include // For setTcpBufSize #include // For setTcpBufSize +#include #ifdef _WIN32 # include +# include typedef int ssize_t; #else # include @@ -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 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 getAddresses(const std::string&, int, bool = true); -ICE_API std::vector 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 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 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::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 -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 endpoints = parseEndpoints(endpts); - if(endpoints.empty()) + vector 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 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 parseEndpoints(const std::string&) const; + std::vector parseEndpoints(const std::string&, bool) const; std::vector 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 0e894056597..ac8ebec8c10 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 #ifndef _WIN32 -# include // For struct sockaddr_in +# include // 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 #else -# include // For struct sockaddr_in +# include // 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(_host) = _instance->defaultsAndOverrides()->defaultHost; - if(_host.empty()) - { - if(server) - { - const_cast(_host) = "0.0.0.0"; - } - else - { - const_cast(_host) = "127.0.0.1"; - } - } } else if(_host == "*") { - const_cast(_host) = "0.0.0.0"; + if(oaEndpoint) + { + const_cast(_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 IceInternal::TcpEndpointI::connectors() const { - return connectors(getAddresses(_host, _port)); + return connectors(getAddresses(_host, _port, _instance->protocolSupport(), true)); } void @@ -314,21 +333,18 @@ vector IceInternal::TcpEndpointI::expand() const { vector endps; - if(_host == "0.0.0.0") + vector hosts = getHostsForEndpointExpand(_host, _instance->protocolSupport()); + if(hosts.empty()) { - vector 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(this)); } else { - endps.push_back(const_cast(this)); - } + for(vector::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 -IceInternal::TcpEndpointI::connectors(const vector& addresses) const +IceInternal::TcpEndpointI::connectors(const vector& addresses) const { vector 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 connectors(const std::vector&) const; + virtual std::vector connectors(const std::vector&) 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::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 #include #include +#include #ifdef _WIN32 # include #else -# include // For struct sockaddr_in +# include // 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(_host) = _instance->defaultsAndOverrides()->defaultHost; - if(_host.empty()) - { - if(server) - { - const_cast(_host) = "0.0.0.0"; - } - else - { - const_cast(_host) = "127.0.0.1"; - } - } } else if(_host == "*") { - const_cast(_host) = "0.0.0.0"; + if(oaEndpoint) + { + const_cast(_host) = string(); + } + else + { + EndpointParseException ex(__FILE__, __LINE__); + ex.str = "udp " + str; + throw ex; + } } } @@ -372,7 +374,22 @@ IceInternal::UdpEndpointI::toString() const << static_cast(static_cast(_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 IceInternal::UdpEndpointI::connectors() const { - return connectors(getAddresses(_host, _port)); + return connectors(getAddresses(_host, _port, _instance->protocolSupport(), true)); } void @@ -500,22 +517,19 @@ vector IceInternal::UdpEndpointI::expand() const { vector endps; - if(_host == "0.0.0.0") + vector hosts = getHostsForEndpointExpand(_host, _instance->protocolSupport()); + if(hosts.empty()) { - vector 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(this)); } else { - endps.push_back(const_cast(this)); + for(vector::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 -IceInternal::UdpEndpointI::connectors(const vector& addresses) const +IceInternal::UdpEndpointI::connectors(const vector& addresses) const { vector 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 connectors(const std::vector&) const; + virtual std::vector connectors(const std::vector&) 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(&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(sizeof(peerAddr)); assert(_fd != INVALID_SOCKET); ret = recvfrom(_fd, reinterpret_cast(&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(&_addr); + multicast = IN_MULTICAST(ntohl(addrin->sin_addr.s_addr)); + port = ntohs(addrin->sin_port); + } + /* + else + { + struct sockaddr_in6* addrin = reinterpret_cast(&_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(&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(&_addr); + multicast = IN_MULTICAST(ntohl(addrin->sin_addr.s_addr)); + port = ntohs(addrin->sin_port); + } + /* + else + { + struct sockaddr_in6* addrin = reinterpret_cast(&_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(&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(&_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 #ifndef _WIN32 -# include // For struct sockaddr_in +# include // 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 e7762649979..7611eb10b03 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 = IceUtil::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(&info.remoteAddr)->sin_port); + } + else + { + sslinfo.remotePort = ntohs(reinterpret_cast(&info.remoteAddr)->sin6_port); + } + sslinfo.remoteHost = IceInternal::inetAddrToString(info.remoteAddr); + if(info.remoteAddr.ss_family == AF_INET) + { + sslinfo.localPort = ntohs(reinterpret_cast(&info.localAddr)->sin_port); + } + else + { + sslinfo.localPort = ntohs(reinterpret_cast(&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(&_addr)->sin_port); + } + else + { + return ntohs(reinterpret_cast(&_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 #include #include +#include #include #ifndef _WIN32 -# include // For struct sockaddr_in +# include // 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 #else -# include // For struct sockaddr_in +# include // 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(_host) = _instance->defaultHost(); - if(_host.empty()) - { - if(server) - { - const_cast(_host) = "0.0.0.0"; - } - else - { - const_cast(_host) = "127.0.0.1"; - } - } } else if(_host == "*") { - const_cast(_host) = "0.0.0.0"; + if(oaEndpoint) + { + const_cast(_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 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 IceSSL::EndpointI::expand() const { vector endps; - if(_host == "0.0.0.0") + vector hosts = IceInternal::getHostsForEndpointExpand(_host, _instance->protocolSupport()); + if(hosts.empty()) { - vector 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(this)); } else { - endps.push_back(const_cast(this)); + for(vector::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 -IceSSL::EndpointI::connectors(const vector& addresses) const +IceSSL::EndpointI::connectors(const vector& addresses) const { vector 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 connectors(const std::vector&) const; + virtual std::vector connectors(const std::vector&) 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)) { -- cgit v1.2.3 From 9fb06a7110c3999a95a5838d637ac1ddf298ca1e Mon Sep 17 00:00:00 2001 From: Michi Henning Date: Thu, 20 Dec 2007 11:09:18 +1000 Subject: Bug 2619 -- Removed VbUtil.cpp. --- cpp/src/Slice/Makefile | 1 - cpp/src/Slice/Makefile.mak | 1 - cpp/src/Slice/VbUtil.cpp | 1293 -------------------------------------------- 3 files changed, 1295 deletions(-) delete mode 100755 cpp/src/Slice/VbUtil.cpp (limited to 'cpp/src') diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile index c3e4fa7e867..ca3c5c0327c 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..2b28cc20294 100644 --- a/cpp/src/Slice/Makefile.mak +++ b/cpp/src/Slice/Makefile.mak @@ -19,7 +19,6 @@ OBJS = Scanner.obj \ Parser.obj \ CPlusPlusUtil.obj \ CsUtil.obj \ - VbUtil.obj \ JavaUtil.obj \ Preprocessor.obj \ Checksum.obj \ diff --git a/cpp/src/Slice/VbUtil.cpp b/cpp/src/Slice/VbUtil.cpp deleted file mode 100755 index 68ce6b8942e..00000000000 --- a/cpp/src/Slice/VbUtil.cpp +++ /dev/null @@ -1,1293 +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 -#include -#include - -#include -#include - -#ifdef _WIN32 -#include -#endif - -#ifndef _WIN32 -#include -#endif - -using namespace std; -using namespace Slice; -using namespace IceUtil; - -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(builtin->minWireSize()) - << ")"; - } - else - { - out << nl << stream << ".checkFixedSeq(lenx__, " - << static_cast(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(type->minWireSize()) << ')'; - } - else - { - out << nl << stream << ".checkFixedSeq(szx__, " << static_cast(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(type->minWireSize()) << ')'; - } - else - { - out << nl << stream << ".checkFixedSeq(szx__, " << static_cast(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(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(type->minWireSize()) << ")"; - } - else - { - out << nl << stream << ".checkFixedSeq(szx__, " << static_cast(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); - } - } -} -- cgit v1.2.3 From 4af75dd83279303101a04c4332b9bb0ffc48ab30 Mon Sep 17 00:00:00 2001 From: Michi Henning Date: Thu, 20 Dec 2007 13:10:13 +1000 Subject: Bug 2477. --- cpp/CHANGES | 2 ++ cpp/include/Slice/Parser.h | 18 ++++++++++-- cpp/src/Slice/Grammar.y | 71 ++++++++++++++++++++++++++++++--------------- cpp/src/Slice/GrammarUtil.h | 15 ++++++---- cpp/src/Slice/Parser.cpp | 31 +++++++++++++++++--- cpp/src/Slice/Scanner.l | 7 +++++ cpp/src/slice2html/Gen.cpp | 61 ++++++++++++++++++++++++++++++++++++++ slice/Ice/Identity.ice | 7 +++++ 8 files changed, 175 insertions(+), 37 deletions(-) (limited to 'cpp/src') diff --git a/cpp/CHANGES b/cpp/CHANGES index 1e567c310d2..76c290b1c06 100644 --- a/cpp/CHANGES +++ b/cpp/CHANGES @@ -11,6 +11,8 @@ Changes since version 3.2.X (binary incompatible) now generates a hyperlink to the base. (Previously, only the name of the base was shown, without a hyperlink.) +- slice2html now generates documentation for Slice constant definitions. + - slice2html now generates the scoped name for the

element of each page instead of the unqualified name. For example, it now shows "Ice::DNSException" instead of "DNSException". diff --git a/cpp/include/Slice/Parser.h b/cpp/include/Slice/Parser.h index 8608af9b070..490875d91b1 100644 --- a/cpp/include/Slice/Parser.h +++ b/cpp/include/Slice/Parser.h @@ -134,11 +134,19 @@ typedef std::list StructList; typedef std::list SequenceList; typedef std::list DictionaryList; typedef std::list EnumList; +typedef std::list ConstList; typedef std::list OperationList; typedef std::list DataMemberList; typedef std::list ParamDeclList; typedef std::list EnumeratorList; -typedef std::pair SyntaxTreeBaseString; + +struct ConstDef +{ + TypePtr type; + SyntaxTreeBasePtr value; + std::string valueAsString; + std::string valueAsLiteral; +}; // ---------------------------------------------------------------------- // CICompare -- function object to do case-insensitive string comparison. @@ -406,7 +414,7 @@ public: EnumPtr createEnum(const std::string&, bool, NodeType = Real); EnumeratorPtr createEnumerator(const std::string&); ConstPtr createConst(const std::string, const TypePtr&, const StringList&, const SyntaxTreeBasePtr&, - const std::string&, NodeType = Real); + const std::string&, const std::string&, NodeType = Real); TypeList lookupType(const std::string&, bool = true); TypeList lookupTypeNoBuiltin(const std::string&, bool = true); ContainedList lookupContained(const std::string&, bool = true); @@ -418,6 +426,7 @@ public: SequenceList sequences() const; DictionaryList dictionaries() const; EnumList enums() const; + ConstList consts() const; ContainedList contents() const; bool hasNonLocalClassDecls() const; bool hasNonLocalClassDefs() const; @@ -840,6 +849,7 @@ public: TypePtr type() const; StringList typeMetaData() const; std::string value() const; + std::string literal() const; virtual bool uses(const ContainedPtr&) const; virtual ContainedType containedType() const; virtual std::string kindOf() const; @@ -852,12 +862,14 @@ public: protected: - Const(const ContainerPtr&, const std::string&, const TypePtr&, const StringList&, const std::string&); + Const(const ContainerPtr&, const std::string&, const TypePtr&, + const StringList&, const std::string&, const std::string&); friend class Container; TypePtr _type; StringList _typeMetaData; std::string _value; + std::string _literal; }; // ---------------------------------------------------------------------- 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(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(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(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(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(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(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(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 StringTokPtr; typedef ::IceUtil::Handle StringListTokPtr; @@ -37,7 +37,7 @@ typedef ::IceUtil::Handle FloatingTokPtr; typedef ::IceUtil::Handle ExceptionListTokPtr; typedef ::IceUtil::Handle ClassListTokPtr; typedef ::IceUtil::Handle EnumeratorListTokPtr; -typedef ::IceUtil::Handle SyntaxTreeBaseStringTokPtr; +typedef ::IceUtil::Handle 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/Parser.cpp b/cpp/src/Slice/Parser.cpp index e58f65d9ec6..e285263110e 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -1022,7 +1022,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); @@ -1083,7 +1084,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; } @@ -1448,6 +1449,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 { @@ -4092,6 +4108,12 @@ Slice::Const::value() const return _value; } +string +Slice::Const::literal() const +{ + return _literal; +} + Contained::ContainedType Slice::Const::containedType() const { @@ -4315,12 +4337,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 bfad0da0545..ab223e51bdc 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(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(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(yyinput())) != string::npos) { + str->literal += next; us = us * 8 + next - '0'; if(octalDigits.find_first_of(next = static_cast(yyinput())) != string::npos) { @@ -289,6 +293,7 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e IceUtil::Int64 ull = 0; while(isxdigit(next = static_cast(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(!IceUtil::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/slice2html/Gen.cpp b/cpp/src/slice2html/Gen.cpp index e88d3d7e2ea..8a946ca2dfc 100644 --- a/cpp/src/slice2html/Gen.cpp +++ b/cpp/src/slice2html/Gen.cpp @@ -2127,6 +2127,27 @@ Slice::ModuleGenerator::visitContainer(const ContainerPtr& p) end(); } + 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); if(!sequences.empty()) @@ -2204,6 +2225,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) diff --git a/slice/Ice/Identity.ice b/slice/Ice/Identity.ice index 3f5062e1919..c5d47f085e8 100644 --- a/slice/Ice/Identity.ice +++ b/slice/Ice/Identity.ice @@ -13,6 +13,13 @@ module Ice { +/** + * A constant. + * + * More blah about the constant... + **/ + const int i = 000; + /** * * The identity of an Ice object. An empty [name] denotes a null -- cgit v1.2.3 From 4285cce5116a52af08f0d883d65440d08ecee1eb Mon Sep 17 00:00:00 2001 From: Michi Henning Date: Thu, 20 Dec 2007 13:20:29 +1000 Subject: Fix to changes for bug 2477. --- cpp/src/slice2html/Gen.cpp | 18 ++++++++++-------- slice/Ice/Identity.ice | 7 ------- 2 files changed, 10 insertions(+), 15 deletions(-) (limited to 'cpp/src') diff --git a/cpp/src/slice2html/Gen.cpp b/cpp/src/slice2html/Gen.cpp index 8a946ca2dfc..649e46a0ef4 100644 --- a/cpp/src/slice2html/Gen.cpp +++ b/cpp/src/slice2html/Gen.cpp @@ -2106,15 +2106,15 @@ Slice::ModuleGenerator::visitContainer(const ContainerPtr& p) assert(_out.currIndent() == indent); - EnumList enums = p->enums(); + ConstList consts = p->consts(); - if(!enums.empty()) + if(!consts.empty()) { start("h2"); - _out << "Enumeration Index"; + _out << "Constant Index"; end(); start("dl"); - for(EnumList::const_iterator q = enums.begin(); q != enums.end(); ++q) + for(ConstList::const_iterator q = consts.begin(); q != consts.end(); ++q) { start("dt", "Symbol"); _out << toString(*q, p, false, true); @@ -2127,15 +2127,17 @@ Slice::ModuleGenerator::visitContainer(const ContainerPtr& p) end(); } - ConstList consts = p->consts(); + assert(_out.currIndent() == indent); - if(!consts.empty()) + EnumList enums = p->enums(); + + if(!enums.empty()) { start("h2"); - _out << "Constant Index"; + _out << "Enumeration Index"; end(); start("dl"); - for(ConstList::const_iterator q = consts.begin(); q != consts.end(); ++q) + for(EnumList::const_iterator q = enums.begin(); q != enums.end(); ++q) { start("dt", "Symbol"); _out << toString(*q, p, false, true); diff --git a/slice/Ice/Identity.ice b/slice/Ice/Identity.ice index c5d47f085e8..3f5062e1919 100644 --- a/slice/Ice/Identity.ice +++ b/slice/Ice/Identity.ice @@ -13,13 +13,6 @@ module Ice { -/** - * A constant. - * - * More blah about the constant... - **/ - const int i = 000; - /** * * The identity of an Ice object. An empty [name] denotes a null -- cgit v1.2.3