summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cs/CHANGES5
-rwxr-xr-xcs/allTests.py1
-rwxr-xr-xcs/src/Ice/Ice.csproj5
-rw-r--r--cs/src/Ice/Ice_11.csproj5
-rw-r--r--cs/src/Ice/Makefile1
-rwxr-xr-xcs/src/Ice/ProxyFactory.cs46
-rwxr-xr-xcs/src/Ice/RouterInfo.cs37
-rwxr-xr-xcs/src/Ice/RoutingTable.cs65
-rw-r--r--cs/test/Glacier2/Makefile2
-rw-r--r--cs/test/Glacier2/attack/.depend0
-rw-r--r--cs/test/Glacier2/attack/Backend.ice23
-rw-r--r--cs/test/Glacier2/attack/BackendI.cs23
-rw-r--r--cs/test/Glacier2/attack/Client.cs137
-rw-r--r--cs/test/Glacier2/attack/Makefile35
-rw-r--r--cs/test/Glacier2/attack/Server.cs54
-rw-r--r--cs/test/Glacier2/attack/passwords1
-rwxr-xr-xcs/test/Glacier2/attack/run.py67
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)