diff options
-rw-r--r-- | cs/CHANGES | 5 | ||||
-rwxr-xr-x | cs/allTests.py | 1 | ||||
-rwxr-xr-x | cs/src/Ice/Ice.csproj | 5 | ||||
-rw-r--r-- | cs/src/Ice/Ice_11.csproj | 5 | ||||
-rw-r--r-- | cs/src/Ice/Makefile | 1 | ||||
-rwxr-xr-x | cs/src/Ice/ProxyFactory.cs | 46 | ||||
-rwxr-xr-x | cs/src/Ice/RouterInfo.cs | 37 | ||||
-rwxr-xr-x | cs/src/Ice/RoutingTable.cs | 65 | ||||
-rw-r--r-- | cs/test/Glacier2/Makefile | 2 | ||||
-rw-r--r-- | cs/test/Glacier2/attack/.depend | 0 | ||||
-rw-r--r-- | cs/test/Glacier2/attack/Backend.ice | 23 | ||||
-rw-r--r-- | cs/test/Glacier2/attack/BackendI.cs | 23 | ||||
-rw-r--r-- | cs/test/Glacier2/attack/Client.cs | 137 | ||||
-rw-r--r-- | cs/test/Glacier2/attack/Makefile | 35 | ||||
-rw-r--r-- | cs/test/Glacier2/attack/Server.cs | 54 | ||||
-rw-r--r-- | cs/test/Glacier2/attack/passwords | 1 | ||||
-rwxr-xr-x | cs/test/Glacier2/attack/run.py | 67 |
17 files changed, 410 insertions, 97 deletions
diff --git a/cs/CHANGES b/cs/CHANGES index 7af065f5a20..1b19d7d2be1 100644 --- a/cs/CHANGES +++ b/cs/CHANGES @@ -1,6 +1,11 @@ Changes since version 3.0.1 --------------------------- +- Added a new method addProxies() to Ice::Router, which can return + evicted proxies. The old method addProxy() is now deprecated. Note + that this is an internal interface for communications between + clients and routers (such as Glacier2). + - Added communicator initialize method which takes a InitializationData structure containing communicator members which are only allowed to be set during communicator creation. Currently included are diff --git a/cs/allTests.py b/cs/allTests.py index b45294a6e04..7acd4d4446a 100755 --- a/cs/allTests.py +++ b/cs/allTests.py @@ -70,6 +70,7 @@ tests = [ \ "Ice/retry", \ "Ice/timeout", \ "Glacier2/router", \ + "Glacier2/attack", \ "IceGrid/simple", \ ] if os.path.exists(os.path.join(toplevel, "bin", "icesslcs.dll")): diff --git a/cs/src/Ice/Ice.csproj b/cs/src/Ice/Ice.csproj index 19ef0f9766e..7a6c5274f71 100755 --- a/cs/src/Ice/Ice.csproj +++ b/cs/src/Ice/Ice.csproj @@ -342,9 +342,6 @@ <Compile Include="RouterInfo.cs">
<SubType>Code</SubType>
</Compile>
- <Compile Include="RoutingTable.cs">
- <SubType>Code</SubType>
- </Compile>
<Compile Include="ServantManager.cs">
<SubType>Code</SubType>
</Compile>
@@ -415,4 +412,4 @@ <PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
-</Project>
\ No newline at end of file +</Project>
diff --git a/cs/src/Ice/Ice_11.csproj b/cs/src/Ice/Ice_11.csproj index 91125e44795..d3b90d7577c 100644 --- a/cs/src/Ice/Ice_11.csproj +++ b/cs/src/Ice/Ice_11.csproj @@ -359,11 +359,6 @@ BuildAction = "Compile"
/>
<File
- RelPath = "RoutingTable.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
RelPath = "ServantManager.cs"
SubType = "Code"
BuildAction = "Compile"
diff --git a/cs/src/Ice/Makefile b/cs/src/Ice/Makefile index ae7030ec394..0b8cf75cf99 100644 --- a/cs/src/Ice/Makefile +++ b/cs/src/Ice/Makefile @@ -70,7 +70,6 @@ SRCS = Acceptor.cs \ Reference.cs \ ReferenceFactory.cs \ RouterInfo.cs \ - RoutingTable.cs \ ServantManager.cs \ Set.cs \ SliceChecksums.cs \ diff --git a/cs/src/Ice/ProxyFactory.cs b/cs/src/Ice/ProxyFactory.cs index f4a04db58b6..d67bf55606e 100755 --- a/cs/src/Ice/ProxyFactory.cs +++ b/cs/src/Ice/ProxyFactory.cs @@ -76,19 +76,46 @@ namespace IceInternal public int checkRetryAfterException(Ice.LocalException ex, Reference @ref, int cnt) { - // - // We retry ObjectNotExistException if the reference is - // indirect. Otherwise, we don't retry other *NotExistException, - // which are all derived from RequestFailedException. - // + TraceLevels traceLevels = instance_.traceLevels(); + Ice.Logger logger = instance_.initializationData().logger; + if(ex is Ice.ObjectNotExistException) { + Ice.ObjectNotExistException one = (Ice.ObjectNotExistException)ex; + LocatorInfo li = @ref.getLocatorInfo(); - if(li == null) + if(li != null) + { + // + // We retry ObjectNotExistException if the reference is + // indirect. + // + li.clearObjectCache((IndirectReference)@ref); + } + else if(@ref.getRouterInfo() != null && one.operation.Equals("ice_add_proxy")) { + // + // If we have a router, an ObjectNotExistException with an + // operation name "ice_add_proxy" indicates to the client + // that the router isn't aware of the proxy (for example, + // because it was evicted by the router). In this case, we + // must *always* retry, so that the missing proxy is added + // to the router. + // + if(traceLevels.retry >= 1) + { + string s = "retrying operation call to add proxy to router\n" + ex; + logger.trace(traceLevels.retryCat, s); + } + return cnt; // We must always retry, so we don't look at the retry count. + } + else + { + // + // For all other cases, we don't retry ObjectNotExistException. + // throw ex; } - li.clearObjectCache((IndirectReference)@ref); } else if(ex is Ice.RequestFailedException) { @@ -124,9 +151,6 @@ namespace IceInternal ++cnt; Debug.Assert(cnt > 0); - TraceLevels traceLevels = instance_.traceLevels(); - Ice.Logger logger = instance_.initializationData().logger; - if(cnt > _retryIntervals.Length) { if(traceLevels.retry >= 1) @@ -141,7 +165,7 @@ namespace IceInternal if(traceLevels.retry >= 1) { - string s = "re-trying operation call"; + string s = "retrying operation call"; if(interval > 0) { s += " in " + interval + "ms"; diff --git a/cs/src/Ice/RouterInfo.cs b/cs/src/Ice/RouterInfo.cs index 2dedc719ced..20443a15593 100755 --- a/cs/src/Ice/RouterInfo.cs +++ b/cs/src/Ice/RouterInfo.cs @@ -19,7 +19,6 @@ namespace IceInternal internal RouterInfo(Ice.RouterPrx router) { _router = router; - _routingTable = new RoutingTable(); Debug.Assert(_router != null); } @@ -31,7 +30,7 @@ namespace IceInternal _clientProxy = null; _serverProxy = null; _adapter = null; - _routingTable.clear(); + _identities.Clear(); } } @@ -137,14 +136,32 @@ namespace IceInternal public void addProxy(Ice.ObjectPrx proxy) { - // - // No mutex lock necessary, _routingTable is immutable, and - // RoutingTable is mutex protected. - // - if(_routingTable.add(proxy)) - // Only add the proxy to the router if it's not already in the routing table. + Debug.Assert(proxy != null); + + lock(this) { - _router.addProxy(proxy); + if(!_identities.Contains(proxy.ice_getIdentity())) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + Ice.ObjectPrx[] proxies = new Ice.ObjectPrx[1]; + proxies[0] = proxy; + Ice.ObjectPrx[] evictedProxies = _router.addProxies(proxies); + + // + // If we successfully added the proxy to the router, we add it to our local map. + // + _identities.Add(proxy.ice_getIdentity()); + + // + // We also must remove whatever proxies the router evicted. + // + for(int i = 0; i < evictedProxies.Length; ++i) + { + _identities.Remove(evictedProxies[i].ice_getIdentity()); + } + } } } @@ -167,7 +184,7 @@ namespace IceInternal private readonly Ice.RouterPrx _router; private Ice.ObjectPrx _clientProxy; private Ice.ObjectPrx _serverProxy; - private readonly RoutingTable _routingTable; + private IceUtil.Set _identities = new IceUtil.Set(); private Ice.ObjectAdapter _adapter; } diff --git a/cs/src/Ice/RoutingTable.cs b/cs/src/Ice/RoutingTable.cs deleted file mode 100755 index e9aec6630c8..00000000000 --- a/cs/src/Ice/RoutingTable.cs +++ /dev/null @@ -1,65 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2006 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. -// -// ********************************************************************** - -namespace IceInternal -{ - - using System.Collections; - - public sealed class RoutingTable - { - public RoutingTable() - { - _table = new Hashtable(); - } - - // - // Clear the contents of the routing table. - // - public void clear() - { - lock(this) - { - _table.Clear(); - } - } - - // - // Returns false if the Proxy exists already. - // - public bool add(Ice.ObjectPrx prx) - { - if(prx == null) - { - return false; - } - - // - // We insert the proxy in its default form into the routing table. - // - Ice.ObjectPrx proxy = prx.ice_twoway().ice_secure(false); - - lock(this) - { - if(!_table.Contains(proxy.ice_getIdentity())) - { - _table[proxy.ice_getIdentity()] = proxy; - return true; - } - else - { - return false; - } - } - } - - private Hashtable _table; - } - -} diff --git a/cs/test/Glacier2/Makefile b/cs/test/Glacier2/Makefile index 019c81ccd10..d09c43112cd 100644 --- a/cs/test/Glacier2/Makefile +++ b/cs/test/Glacier2/Makefile @@ -11,7 +11,7 @@ top_srcdir = ../.. include $(top_srcdir)/config/Make.rules.cs -SUBDIRS = router +SUBDIRS = router attack $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cs/test/Glacier2/attack/.depend b/cs/test/Glacier2/attack/.depend new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/cs/test/Glacier2/attack/.depend diff --git a/cs/test/Glacier2/attack/Backend.ice b/cs/test/Glacier2/attack/Backend.ice new file mode 100644 index 00000000000..33c0e65fd11 --- /dev/null +++ b/cs/test/Glacier2/attack/Backend.ice @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef BACKEND_ICE +#define BACKEND_ICE + +module Test +{ + +interface Backend +{ + void shutdown(); +}; + +}; + +#endif diff --git a/cs/test/Glacier2/attack/BackendI.cs b/cs/test/Glacier2/attack/BackendI.cs new file mode 100644 index 00000000000..af88dc6ec49 --- /dev/null +++ b/cs/test/Glacier2/attack/BackendI.cs @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 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. +// +// ********************************************************************** + +using Test; + +public sealed class BackendI : BackendDisp_ +{ + public BackendI() + { + } + + public override void + shutdown(Ice.Current current) + { + current.adapter.getCommunicator().shutdown(); + } +} diff --git a/cs/test/Glacier2/attack/Client.cs b/cs/test/Glacier2/attack/Client.cs new file mode 100644 index 00000000000..71147669cf4 --- /dev/null +++ b/cs/test/Glacier2/attack/Client.cs @@ -0,0 +1,137 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 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. +// +// ********************************************************************** + +using System; +using System.Collections; +using Test; + +public class Client : Ice.Application +{ + public override int run(string[] args) + { + Console.Out.Write("getting router... "); + Console.Out.Flush(); + Ice.ObjectPrx routerBase = communicator().stringToProxy("Glacier2/router:default -p 12347 -t 10000"); + Glacier2.RouterPrx router = Glacier2.RouterPrxHelper.checkedCast(routerBase); + test(router != null); + Console.Out.WriteLine("ok"); + + Console.Out.Write("creating session... "); + Console.Out.Flush(); + router.createSession("userid", "abc123"); + communicator().setDefaultRouter(router); + Console.Out.WriteLine("ok"); + + Console.Out.Write("making thousands of invocations on proxies... "); + Console.Out.Flush(); + Ice.ObjectPrx backendBase = communicator().stringToProxy("dummy:tcp -p 12010 -t 10000"); + BackendPrx backend = BackendPrxHelper.uncheckedCast(backendBase); + backend.ice_ping(); + + Hashtable backends = new Hashtable(); + Random rand = new Random(unchecked((int)DateTime.Now.Ticks)); + + String msg = ""; + for(int i = 1; i <= 10000; ++i) + { + if(i % 100 == 0) + { + for(int j = 0; j < msg.Length; ++j) + { + Console.Out.Write('\b'); + } + + msg = "" + i; + Console.Out.Write(i); + Console.Out.Flush(); + } + + Ice.Identity ident = new Ice.Identity("", ""); + ident.name += (char)('A' + rand.Next() % 26); + + int len = rand.Next() % 2; + for(int j = 0; j < len; ++j) + { + ident.category += (char)('a' + rand.Next() % 26); + } + + BackendPrx newBackend = BackendPrxHelper.uncheckedCast(backendBase.ice_identity(ident)); + + if(!backends.ContainsKey(newBackend)) + { + backends.Add(newBackend, newBackend); + backend = newBackend; + } + else + { + backend = (BackendPrx)backends[newBackend]; + } + + backend.ice_ping(); + } + + for(int j = 0; j < msg.Length; ++j) + { + Console.Out.Write('\b'); + } + for(int j = 0; j < msg.Length; ++j) + { + Console.Out.Write(' '); + } + for(int j = 0; j < msg.Length; ++j) + { + Console.Out.Write('\b'); + } + Console.Out.WriteLine("ok"); + + Console.Out.Write("testing server and router shutdown... "); + Console.Out.Flush(); + backend.shutdown(); + communicator().setDefaultRouter(null); + Ice.ObjectPrx adminBase = communicator().stringToProxy("Glacier2/admin:tcp -h 127.0.0.1 -p 12348 -t 10000"); + Glacier2.AdminPrx admin = Glacier2.AdminPrxHelper.checkedCast(adminBase); + test(admin != null); + admin.shutdown(); + try + { + admin.ice_ping(); + test(false); + } + catch(Ice.LocalException ex) + { + Console.Out.WriteLine("ok"); + } + + return 0; + } + + private static void + test(bool b) + { + if(!b) + { + throw new Exception(); + } + } + + public static void Main(string[] args) + { + // + // We want to check whether the client retries for evicted + // proxies, even with regular retries disabled. + // + Ice.Properties properties = Ice.Util.getDefaultProperties(ref args); + properties.setProperty("Ice.RetryIntervals", "-1"); + + Client app = new Client(); + int status = app.main(args); + + Environment.Exit(status); + } +} diff --git a/cs/test/Glacier2/attack/Makefile b/cs/test/Glacier2/attack/Makefile new file mode 100644 index 00000000000..959bbdcc06e --- /dev/null +++ b/cs/test/Glacier2/attack/Makefile @@ -0,0 +1,35 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2006 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +TARGETS = client.exe server.exe + +C_SRCS = Client.cs generated/Backend.cs +S_SRCS = Server.cs generated/Backend.cs BackendI.cs + +SLICE_SRCS = $(SDIR)/Backend.ice + +SDIR = . + +GDIR = generated + +include $(top_srcdir)/config/Make.rules.cs + +MCSFLAGS := $(MCSFLAGS) -target:exe + +SLICE2CSFLAGS := $(SLICE2CSFLAGS) --ice -I. -I$(slicedir) + +client.exe: $(C_SRCS) $(GEN_SRCS) + $(MCS) $(MCSFLAGS) -out:$@ $(call ref,icecs) $(call ref,glacier2cs) $^ + +server.exe: $(S_SRCS) $(GEN_SRCS) + $(MCS) $(MCSFLAGS) -out:$@ $(call ref,icecs) $(call ref,glacier2cs) $^ + +include .depend diff --git a/cs/test/Glacier2/attack/Server.cs b/cs/test/Glacier2/attack/Server.cs new file mode 100644 index 00000000000..0eac565d7d2 --- /dev/null +++ b/cs/test/Glacier2/attack/Server.cs @@ -0,0 +1,54 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 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. +// +// ********************************************************************** + +using Test; + +public sealed class ServantLocatorI : Ice.LocalObjectImpl, Ice.ServantLocator +{ + public ServantLocatorI() + { + _backend = new BackendI(); + } + + public Ice.Object locate(Ice.Current curr, out Ice.LocalObject cookie) + { + cookie = null; + return _backend; + } + + public void finished(Ice.Current curr, Ice.Object servant, Ice.LocalObject cookie) + { + } + + public void deactivate(string category) + { + } + + private Backend _backend; +} + +class Server : Ice.Application +{ + public override int run(string[] args) + { + communicator().getProperties().setProperty("BackendAdapter.Endpoints", "tcp -p 12010 -t 10000"); + Ice.ObjectAdapter adapter = communicator().createObjectAdapter("BackendAdapter"); + adapter.addServantLocator(new ServantLocatorI(), ""); + adapter.activate(); + communicator().waitForShutdown(); + return 0; + } + + public static void Main(string[] args) + { + Server app = new Server(); + int status = app.main(args); + System.Environment.Exit(status); + } +} diff --git a/cs/test/Glacier2/attack/passwords b/cs/test/Glacier2/attack/passwords new file mode 100644 index 00000000000..a1527dec2b9 --- /dev/null +++ b/cs/test/Glacier2/attack/passwords @@ -0,0 +1 @@ +userid xxMqsnnDcK8tw
\ No newline at end of file diff --git a/cs/test/Glacier2/attack/run.py b/cs/test/Glacier2/attack/run.py new file mode 100755 index 00000000000..4b332cdfbdc --- /dev/null +++ b/cs/test/Glacier2/attack/run.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2006 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. +# +# ********************************************************************** + +import os, sys, getopt + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "config", "TestUtil.py")): + break +else: + raise "can't find toplevel directory!" + +sys.path.append(os.path.join(toplevel, "config")) +import TestUtil + +if not os.environ.has_key('ICE_HOME'): + print "ICE_HOME is not defined." + sys.exit(0) + +ice_home = os.environ['ICE_HOME'] + +try: + opts, args = getopt.getopt(sys.argv[1:], "m") +except getopt.GetoptError: + usage() + +mono = 0 +for o, a in opts: + if o == "-m": + mono = 1 + +if not TestUtil.isWin32(): + mono = 1 + +router = os.path.join(ice_home, "bin", "glacier2router") + +command = router + TestUtil.clientServerOptions + \ + r' --Ice.PrintProcessId' \ + r' --Glacier2.RoutingTable.MaxSize=10' + \ + r' --Glacier2.Client.Endpoints="default -p 12347 -t 10000"' + \ + r' --Glacier2.Admin.Endpoints="tcp -h 127.0.0.1 -p 12348 -t 10000"' + \ + r' --Glacier2.CryptPasswords="' + toplevel + r'/test/Glacier2/attack/passwords"' + +print "starting router...", +starterPipe = os.popen(command) +TestUtil.getServerPid(starterPipe) +TestUtil.getAdapterReady(starterPipe) +print "ok" + +name = os.path.join("Glacier2", "attack") + +TestUtil.clientServerTest(mono, name) + +starterStatus = TestUtil.closePipe(starterPipe) + +if starterStatus: + TestUtil.killServers() + sys.exit(1) + +sys.exit(0) |