001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.mts.std;
028:
029: import java.net.InetAddress;
030: import java.net.Socket;
031: import java.util.HashMap;
032:
033: import org.cougaar.mts.base.ServerSocketWrapper;
034: import org.cougaar.mts.base.SocketDelegateImplBase;
035:
036: /**
037: * This test entity can be used as a wrapper for RMI ServerSockets.
038: * If too many outstanding connections are open from any one client
039: * host, it will not allow any more.
040: */
041: public class FuseServerSocket extends ServerSocketWrapper {
042: private static final int MAX_CONNECTIONS = 10;
043:
044: private class FuseSocket extends SocketDelegateImplBase {
045: FuseSocket(Socket delegatee) {
046: super (delegatee);
047: }
048:
049: public void close() throws java.io.IOException {
050: InetAddress client = getInetAddress();
051: boolean alreadyClosed = isClosed();
052: super .close();
053: if (!alreadyClosed) {
054: ConnectionStats record = getRecord(client);
055: record.decrementCount();
056: System.err.println(this + " closed");
057: }
058: }
059: }
060:
061: private static class ConnectionStats {
062: String client;
063: int count;
064:
065: ConnectionStats(String client) {
066: this .client = client;
067: count = 0;
068: }
069:
070: synchronized int incrementCount() {
071: System.err.println(client + " inc= " + count);
072: return ++count;
073: }
074:
075: synchronized int decrementCount() {
076: System.err.println(client + " dec= " + count);
077: return --count;
078: }
079: }
080:
081: private HashMap stats;
082:
083: public FuseServerSocket() throws java.io.IOException {
084: super ();
085: stats = new HashMap();
086: }
087:
088: private ConnectionStats getRecord(InetAddress address) {
089: String client = address.getCanonicalHostName();
090: ConnectionStats stat = null;
091: synchronized (stats) {
092: stat = (ConnectionStats) stats.get(client);
093: if (stat == null) {
094: stat = new ConnectionStats(client);
095: stats.put(client, stat);
096: }
097: }
098: return stat;
099: }
100:
101: public Socket accept() throws java.io.IOException {
102: Socket socket = super .accept();
103: socket = new FuseSocket(socket);
104: InetAddress source = socket.getInetAddress();
105: ConnectionStats record = getRecord(source);
106: int count = record.incrementCount();
107: if (count > MAX_CONNECTIONS) {
108: try {
109: socket.close();
110: } catch (java.io.IOException io_ex) {
111: }
112: }
113:
114: return socket;
115: }
116:
117: }
|