Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/NioSelectorPool.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/NioSelectorPool.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/NioSelectorPool.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/NioSelectorPool.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.MutableInteger;
+
+/**
+ *
+ * Thread safe non blocking selector pool
+ * @author Filip Hanik
+ * @version 1.0
+ * @since 6.0
+ */
+
+public class NioSelectorPool {
+
+ public NioSelectorPool() {
+ }
+
+ protected static int threadCount = 0;
+
+ protected static Log log = LogFactory.getLog(NioSelectorPool.class);
+
+ protected final static boolean SHARED =
+ Boolean.valueOf(System.getProperty("org.apache.tomcat.util.net.NioSelectorShared", "true")).booleanValue();
+
+ protected NioBlockingSelector blockingSelector;
+
+ protected Selector SHARED_SELECTOR;
+
+ protected int maxSelectors = 200;
+ protected long sharedSelectorTimeout = 30000;
+ protected int maxSpareSelectors = -1;
+ protected boolean enabled = true;
+ protected AtomicInteger active = new AtomicInteger(0);
+ protected AtomicInteger spare = new AtomicInteger(0);
+ protected ConcurrentLinkedQueue<Selector> selectors = new ConcurrentLinkedQueue<Selector>();
+
+ protected Selector getSharedSelector() throws IOException {
+ if (SHARED && SHARED_SELECTOR == null) {
+ synchronized ( NioSelectorPool.class ) {
+ if ( SHARED_SELECTOR == null ) {
+ SHARED_SELECTOR = Selector.open();
+ log.info("Using a shared selector for servlet write/read");
+ }
+ }
+ }
+ return SHARED_SELECTOR;
+ }
+
+ public Selector get() throws IOException{
+ if ( SHARED ) {
+ return getSharedSelector();
+ }
+ if ( (!enabled) || active.incrementAndGet() >= maxSelectors ) {
+ if ( enabled ) active.decrementAndGet();
+ return null;
+ }
+ Selector s = null;
+ try {
+ s = selectors.size()>0?selectors.poll():null;
+ if (s == null) s = Selector.open();
+ else spare.decrementAndGet();
+
+ }catch (NoSuchElementException x ) {
+ try {s = Selector.open();}catch (IOException iox){}
+ } finally {
+ if ( s == null ) active.decrementAndGet();//we were unable to find a selector
+ }
+ return s;
+ }
+
+
+
+ public void put(Selector s) throws IOException {
+ if ( SHARED ) return;
+ if ( enabled ) active.decrementAndGet();
+ if ( enabled && (maxSpareSelectors==-1 || spare.get() < Math.min(maxSpareSelectors,maxSelectors)) ) {
+ spare.incrementAndGet();
+ selectors.offer(s);
+ }
+ else s.close();
+ }
+
+ public void close() throws IOException {
+ enabled = false;
+ Selector s;
+ while ( (s = selectors.poll()) != null ) s.close();
+ spare.set(0);
+ active.set(0);
+ if (blockingSelector!=null) {
+ blockingSelector.close();
+ }
+ if ( SHARED && getSharedSelector()!=null ) {
+ getSharedSelector().close();
+ SHARED_SELECTOR = null;
+ }
+ }
+
+ public void open() throws IOException {
+ enabled = true;
+ getSharedSelector();
+ if (SHARED) {
+ blockingSelector = new NioBlockingSelector();
+ blockingSelector.open(getSharedSelector());
+ }
+
+ }
+
+ /**
+ * Performs a blocking write using the bytebuffer for data to be written and a selector to block.
+ * If the <code>selector</code> parameter is null, then it will perform a busy write that could
+ * take up a lot of CPU cycles.
+ * @param buf ByteBuffer - the buffer containing the data, we will write as long as <code>(buf.hasRemaining()==true)</code>
+ * @param socket SocketChannel - the socket to write data to
+ * @param selector Selector - the selector to use for blocking, if null then a busy write will be initiated
+ * @param writeTimeout long - the timeout for this write operation in milliseconds, -1 means no timeout
+ * @return int - returns the number of bytes written
+ * @throws EOFException if write returns -1
+ * @throws SocketTimeoutException if the write times out
+ * @throws IOException if an IO Exception occurs in the underlying socket logic
+ */
+ public int write(ByteBuffer buf, NioChannel socket, Selector selector, long writeTimeout) throws IOException {
+ return write(buf,socket,selector,writeTimeout,true,null);
+ }
+
+ public int write(ByteBuffer buf, NioChannel socket, Selector selector,
+ long writeTimeout, boolean block,MutableInteger lastWrite) throws IOException {
+ if ( SHARED && block ) {
+ return blockingSelector.write(buf,socket,writeTimeout,lastWrite);
+ }
+ SelectionKey key = null;
+ int written = 0;
+ boolean timedout = false;
+ int keycount = 1; //assume we can write
+ long time = System.currentTimeMillis(); //start the timeout timer
+ try {
+ while ( (!timedout) && buf.hasRemaining() ) {
+ int cnt = 0;
+ if ( keycount > 0 ) { //only write if we were registered for a write
+ cnt = socket.write(buf); //write the data
+ if (lastWrite!=null) lastWrite.set(cnt);
+ if (cnt == -1) throw new EOFException();
+
+ written += cnt;
+ if (cnt > 0) {
+ time = System.currentTimeMillis(); //reset our timeout timer
+ continue; //we successfully wrote, try again without a selector
+ }
+ if (cnt==0 && (!block)) break; //don't block
+ }
+ if ( selector != null ) {
+ //register OP_WRITE to the selector
+ if (key==null) key = socket.getIOChannel().register(selector, SelectionKey.OP_WRITE);
+ else key.interestOps(SelectionKey.OP_WRITE);
+ keycount = selector.select(writeTimeout);
+ }
+ if (writeTimeout > 0 && (selector == null || keycount == 0) ) timedout = (System.currentTimeMillis()-time)>=writeTimeout;
+ }//while
+ if ( timedout ) throw new SocketTimeoutException();
+ } finally {
+ if (key != null) {
+ key.cancel();
+ if (selector != null) selector.selectNow();//removes the key from this selector
+ }
+ }
+ return written;
+ }
+
+ /**
+ * Performs a blocking read using the bytebuffer for data to be read and a selector to block.
+ * If the <code>selector</code> parameter is null, then it will perform a busy read that could
+ * take up a lot of CPU cycles.
+ * @param buf ByteBuffer - the buffer containing the data, we will read as until we have read at least one byte or we timed out
+ * @param socket SocketChannel - the socket to write data to
+ * @param selector Selector - the selector to use for blocking, if null then a busy read will be initiated
+ * @param readTimeout long - the timeout for this read operation in milliseconds, -1 means no timeout
+ * @return int - returns the number of bytes read
+ * @throws EOFException if read returns -1
+ * @throws SocketTimeoutException if the read times out
+ * @throws IOException if an IO Exception occurs in the underlying socket logic
+ */
+ public int read(ByteBuffer buf, NioChannel socket, Selector selector, long readTimeout) throws IOException {
+ return read(buf,socket,selector,readTimeout,true);
+ }
+ /**
+ * Performs a read using the bytebuffer for data to be read and a selector to register for events should
+ * you have the block=true.
+ * If the <code>selector</code> parameter is null, then it will perform a busy read that could
+ * take up a lot of CPU cycles.
+ * @param buf ByteBuffer - the buffer containing the data, we will read as until we have read at least one byte or we timed out
+ * @param socket SocketChannel - the socket to write data to
+ * @param selector Selector - the selector to use for blocking, if null then a busy read will be initiated
+ * @param readTimeout long - the timeout for this read operation in milliseconds, -1 means no timeout
+ * @param block - true if you want to block until data becomes available or timeout time has been reached
+ * @return int - returns the number of bytes read
+ * @throws EOFException if read returns -1
+ * @throws SocketTimeoutException if the read times out
+ * @throws IOException if an IO Exception occurs in the underlying socket logic
+ */
+ public int read(ByteBuffer buf, NioChannel socket, Selector selector, long readTimeout, boolean block) throws IOException {
+ if ( SHARED && block ) {
+ return blockingSelector.read(buf,socket,readTimeout);
+ }
+ SelectionKey key = null;
+ int read = 0;
+ boolean timedout = false;
+ int keycount = 1; //assume we can write
+ long time = System.currentTimeMillis(); //start the timeout timer
+ try {
+ while ( (!timedout) ) {
+ int cnt = 0;
+ if ( keycount > 0 ) { //only read if we were registered for a read
+ cnt = socket.read(buf);
+ if (cnt == -1) throw new EOFException();
+ read += cnt;
+ if (cnt > 0) continue; //read some more
+ if (cnt==0 && (read>0 || (!block) ) ) break; //we are done reading
+ }
+ if ( selector != null ) {//perform a blocking read
+ //register OP_WRITE to the selector
+ if (key==null) key = socket.getIOChannel().register(selector, SelectionKey.OP_READ);
+ else key.interestOps(SelectionKey.OP_READ);
+ keycount = selector.select(readTimeout);
+ }
+ if (readTimeout > 0 && (selector == null || keycount == 0) ) timedout = (System.currentTimeMillis()-time)>=readTimeout;
+ }//while
+ if ( timedout ) throw new SocketTimeoutException();
+ } finally {
+ if (key != null) {
+ key.cancel();
+ if (selector != null) selector.selectNow();//removes the key from this selector
+ }
+ }
+ return read;
+ }
+
+ public void setMaxSelectors(int maxSelectors) {
+ this.maxSelectors = maxSelectors;
+ }
+
+ public void setMaxSpareSelectors(int maxSpareSelectors) {
+ this.maxSpareSelectors = maxSpareSelectors;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public void setSharedSelectorTimeout(long sharedSelectorTimeout) {
+ this.sharedSelectorTimeout = sharedSelectorTimeout;
+ }
+
+ public int getMaxSelectors() {
+ return maxSelectors;
+ }
+
+ public int getMaxSpareSelectors() {
+ return maxSpareSelectors;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public long getSharedSelectorTimeout() {
+ return sharedSelectorTimeout;
+ }
+
+ public ConcurrentLinkedQueue getSelectors() {
+ return selectors;
+ }
+
+ public AtomicInteger getSpare() {
+ return spare;
+ }
+}
\ No newline at end of file
Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,692 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.security.AccessControlException;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.threads.ThreadPool;
+import org.apache.tomcat.util.threads.ThreadPoolRunnable;
+
+/* Similar with MPM module in Apache2.0. Handles all the details related with
+ "tcp server" functionality - thread management, accept policy, etc.
+ It should do nothing more - as soon as it get a socket ( and all socket options
+ are set, etc), it just handle the stream to ConnectionHandler.processConnection. (costin)
+*/
+
+
+
+/**
+ * Handle incoming TCP connections.
+ *
+ * This class implement a simple server model: one listener thread accepts on a socket and
+ * creates a new worker thread for each incoming connection.
+ *
+ * More advanced Endpoints will reuse the threads, use queues, etc.
+ *
+ * @author James Duncan Davidson [duncan@eng.sun.com]
+ * @author Jason Hunter [jch@eng.sun.com]
+ * @author James Todd [gonzo@eng.sun.com]
+ * @author Costin@eng.sun.com
+ * @author Gal Shachor [shachor@il.ibm.com]
+ * @author Yoav Shapira <yoavs@apache.org>
+ */
+public class PoolTcpEndpoint implements Runnable { // implements Endpoint {
+
+ static Log log=LogFactory.getLog(PoolTcpEndpoint.class );
+
+ private StringManager sm =
+ StringManager.getManager("org.apache.tomcat.util.net.res");
+
+ private static final int BACKLOG = 100;
+ private static final int TIMEOUT = 1000;
+
+ private final Object threadSync = new Object();
+
+ private int backlog = BACKLOG;
+ private int serverTimeout = TIMEOUT;
+
+ private InetAddress inet;
+ private int port;
+
+ private ServerSocketFactory factory;
+ private ServerSocket serverSocket;
+
+ private volatile boolean running = false;
+ private volatile boolean paused = false;
+ private boolean initialized = false;
+ private boolean reinitializing = false;
+ static final int debug=0;
+
+ protected boolean tcpNoDelay=false;
+ protected int linger=100;
+ protected int socketTimeout=-1;
+ private boolean lf = true;
+
+
+ // ------ Leader follower fields
+
+
+ TcpConnectionHandler handler;
+ ThreadPoolRunnable listener;
+ ThreadPool tp;
+
+
+ // ------ Master slave fields
+
+ /* The background thread. */
+ private Thread thread = null;
+ /* Available processors. */
+ private Stack workerThreads = new Stack();
+ private int curThreads = 0;
+ private int maxThreads = 20;
+ /* All processors which have been created. */
+ private Vector created = new Vector();
+
+
+ public PoolTcpEndpoint() {
+ tp = new ThreadPool();
+ }
+
+ public PoolTcpEndpoint( ThreadPool tp ) {
+ this.tp=tp;
+ }
+
+ // -------------------- Configuration --------------------
+
+ public void setMaxThreads(int maxThreads) {
+ if( maxThreads > 0)
+ tp.setMaxThreads(maxThreads);
+ }
+
+ public int getMaxThreads() {
+ return tp.getMaxThreads();
+ }
+
+ public void setMaxSpareThreads(int maxThreads) {
+ if(maxThreads > 0)
+ tp.setMaxSpareThreads(maxThreads);
+ }
+
+ public int getMaxSpareThreads() {
+ return tp.getMaxSpareThreads();
+ }
+
+ public void setMinSpareThreads(int minThreads) {
+ if(minThreads > 0)
+ tp.setMinSpareThreads(minThreads);
+ }
+
+ public int getMinSpareThreads() {
+ return tp.getMinSpareThreads();
+ }
+
+ public void setThreadPriority(int threadPriority) {
+ tp.setThreadPriority(threadPriority);
+ }
+
+ public int getThreadPriority() {
+ return tp.getThreadPriority();
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port ) {
+ this.port=port;
+ }
+
+ public InetAddress getAddress() {
+ return inet;
+ }
+
+ public void setAddress(InetAddress inet) {
+ this.inet=inet;
+ }
+
+ public void setServerSocket(ServerSocket ss) {
+ serverSocket = ss;
+ }
+
+ public void setServerSocketFactory( ServerSocketFactory factory ) {
+ this.factory=factory;
+ }
+
+ ServerSocketFactory getServerSocketFactory() {
+ return factory;
+ }
+
+ public void setConnectionHandler( TcpConnectionHandler handler ) {
+ this.handler=handler;
+ }
+
+ public TcpConnectionHandler getConnectionHandler() {
+ return handler;
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+ public boolean isPaused() {
+ return paused;
+ }
+
+ /**
+ * Allows the server developer to specify the backlog that
+ * should be used for server sockets. By default, this value
+ * is 100.
+ */
+ public void setBacklog(int backlog) {
+ if( backlog>0)
+ this.backlog = backlog;
+ }
+
+ public int getBacklog() {
+ return backlog;
+ }
+
+ /**
+ * Sets the timeout in ms of the server sockets created by this
+ * server. This method allows the developer to make servers
+ * more or less responsive to having their server sockets
+ * shut down.
+ *
+ * <p>By default this value is 1000ms.
+ */
+ public void setServerTimeout(int timeout) {
+ this.serverTimeout = timeout;
+ }
+
+ public boolean getTcpNoDelay() {
+ return tcpNoDelay;
+ }
+
+ public void setTcpNoDelay( boolean b ) {
+ tcpNoDelay=b;
+ }
+
+ public int getSoLinger() {
+ return linger;
+ }
+
+ public void setSoLinger( int i ) {
+ linger=i;
+ }
+
+ public int getSoTimeout() {
+ return socketTimeout;
+ }
+
+ public void setSoTimeout( int i ) {
+ socketTimeout=i;
+ }
+
+ public int getServerSoTimeout() {
+ return serverTimeout;
+ }
+
+ public void setServerSoTimeout( int i ) {
+ serverTimeout=i;
+ }
+
+ public String getStrategy() {
+ if (lf) {
+ return "lf";
+ } else {
+ return "ms";
+ }
+ }
+
+ public void setStrategy(String strategy) {
+ if ("ms".equals(strategy)) {
+ lf = false;
+ } else {
+ lf = true;
+ }
+ }
+
+ public int getCurrentThreadCount() {
+ return curThreads;
+ }
+
+ public int getCurrentThreadsBusy() {
+ return curThreads - workerThreads.size();
+ }
+
+ // -------------------- Public methods --------------------
+
+ public void initEndpoint() throws IOException, InstantiationException {
+ try {
+ if(factory==null)
+ factory=ServerSocketFactory.getDefault();
+ if(serverSocket==null) {
+ try {
+ if (inet == null) {
+ serverSocket = factory.createSocket(port, backlog);
+ } else {
+ serverSocket = factory.createSocket(port, backlog, inet);
+ }
+ } catch (BindException orig) {
+ String msg;
+ if (inet == null)
+ msg = orig.getMessage() + "<null>:" + port;
+ else
+ msg = orig.getMessage() + " " +
+ inet.toString() + ":" + port;
+ BindException be = new BindException(msg);
+ be.initCause(orig);
+ throw be;
+ }
+ }
+ if( serverTimeout >= 0 )
+ serverSocket.setSoTimeout( serverTimeout );
+ } catch( IOException ex ) {
+ throw ex;
+ } catch( InstantiationException ex1 ) {
+ throw ex1;
+ }
+ initialized = true;
+ }
+
+ public void startEndpoint() throws IOException, InstantiationException {
+ if (!initialized) {
+ initEndpoint();
+ }
+ if (lf) {
+ tp.start();
+ }
+ running = true;
+ paused = false;
+ if (lf) {
+ listener = new LeaderFollowerWorkerThread(this);
+ tp.runIt(listener);
+ } else {
+ maxThreads = getMaxThreads();
+ threadStart();
+ }
+ }
+
+ public void pauseEndpoint() {
+ if (running && !paused) {
+ paused = true;
+ unlockAccept();
+ }
+ }
+
+ public void resumeEndpoint() {
+ if (running) {
+ paused = false;
+ }
+ }
+
+ public void stopEndpoint() {
+ if (running) {
+ if (lf) {
+ tp.shutdown();
+ }
+ running = false;
+ if (serverSocket != null) {
+ closeServerSocket();
+ }
+ if (!lf) {
+ threadStop();
+ }
+ initialized=false ;
+ }
+ }
+
+ protected void closeServerSocket() {
+ if (!paused)
+ unlockAccept();
+ try {
+ if( serverSocket!=null)
+ serverSocket.close();
+ } catch(Exception e) {
+ log.error(sm.getString("endpoint.err.close"), e);
+ }
+ serverSocket = null;
+ }
+
+ protected void unlockAccept() {
+ Socket s = null;
+ try {
+ // Need to create a connection to unlock the accept();
+ if (inet == null) {
+ s = new Socket(InetAddress.getByName("localhost").getHostAddress(), port);
+ } else {
+ s = new Socket(inet, port);
+ // setting soLinger to a small value will help shutdown the
+ // connection quicker
+ s.setSoLinger(true, 0);
+ }
+ } catch(Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("endpoint.debug.unlock", "" + port), e);
+ }
+ } finally {
+ if (s != null) {
+ try {
+ s.close();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
+ // -------------------- Private methods
+
+ Socket acceptSocket() {
+ if( !running || serverSocket==null ) return null;
+
+ Socket accepted = null;
+
+ try {
+ if(factory==null) {
+ accepted = serverSocket.accept();
+ } else {
+ accepted = factory.acceptSocket(serverSocket);
+ }
+ if (null == accepted) {
+ log.warn(sm.getString("endpoint.warn.nullSocket"));
+ } else {
+ if (!running) {
+ accepted.close(); // rude, but unlikely!
+ accepted = null;
+ } else if (factory != null) {
+ factory.initSocket( accepted );
+ }
+ }
+ }
+ catch(InterruptedIOException iioe) {
+ // normal part -- should happen regularly so
+ // that the endpoint can release if the server
+ // is shutdown.
+ }
+ catch (AccessControlException ace) {
+ // When using the Java SecurityManager this exception
+ // can be thrown if you are restricting access to the
+ // socket with SocketPermission's.
+ // Log the unauthorized access and continue
+ String msg = sm.getString("endpoint.warn.security",
+ serverSocket, ace);
+ log.warn(msg);
+ }
+ catch (IOException e) {
+
+ String msg = null;
+
+ if (running) {
+ msg = sm.getString("endpoint.err.nonfatal",
+ serverSocket, e);
+ log.error(msg, e);
+ }
+
+ if (accepted != null) {
+ try {
+ accepted.close();
+ } catch(Throwable ex) {
+ msg = sm.getString("endpoint.err.nonfatal",
+ accepted, ex);
+ log.warn(msg, ex);
+ }
+ accepted = null;
+ }
+
+ if( ! running ) return null;
+ reinitializing = true;
+ // Restart endpoint when getting an IOException during accept
+ synchronized (threadSync) {
+ if (reinitializing) {
+ reinitializing = false;
+ // 1) Attempt to close server socket
+ closeServerSocket();
+ initialized = false;
+ // 2) Reinit endpoint (recreate server socket)
+ try {
+ msg = sm.getString("endpoint.warn.reinit");
+ log.warn(msg);
+ initEndpoint();
+ } catch (Throwable t) {
+ msg = sm.getString("endpoint.err.nonfatal",
+ serverSocket, t);
+ log.error(msg, t);
+ }
+ // 3) If failed, attempt to restart endpoint
+ if (!initialized) {
+ msg = sm.getString("endpoint.warn.restart");
+ log.warn(msg);
+ try {
+ stopEndpoint();
+ initEndpoint();
+ startEndpoint();
+ } catch (Throwable t) {
+ msg = sm.getString("endpoint.err.fatal",
+ serverSocket, t);
+ log.error(msg, t);
+ }
+ // Current thread is now invalid: kill it
+ throw new ThreadDeath();
+ }
+ }
+ }
+
+ }
+
+ return accepted;
+ }
+
+ void setSocketOptions(Socket socket)
+ throws SocketException {
+ if(linger >= 0 )
+ socket.setSoLinger( true, linger);
+ if( tcpNoDelay )
+ socket.setTcpNoDelay(tcpNoDelay);
+ if( socketTimeout > 0 )
+ socket.setSoTimeout( socketTimeout );
+ }
+
+
+ void processSocket(Socket s, TcpConnection con, Object[] threadData) {
+ // Process the connection
+ int step = 1;
+ try {
+
+ // 1: Set socket options: timeout, linger, etc
+ setSocketOptions(s);
+
+ // 2: SSL handshake
+ step = 2;
+ if (getServerSocketFactory() != null) {
+ getServerSocketFactory().handshake(s);
+ }
+
+ // 3: Process the connection
+ step = 3;
+ con.setEndpoint(this);
+ con.setSocket(s);
+ getConnectionHandler().processConnection(con, threadData);
+
+ } catch (SocketException se) {
+ log.debug(sm.getString("endpoint.err.socket", s.getInetAddress()),
+ se);
+ // Try to close the socket
+ try {
+ s.close();
+ } catch (IOException e) {
+ }
+ } catch (Throwable t) {
+ if (step == 2) {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("endpoint.err.handshake"), t);
+ }
+ } else {
+ log.error(sm.getString("endpoint.err.unexpected"), t);
+ }
+ // Try to close the socket
+ try {
+ s.close();
+ } catch (IOException e) {
+ }
+ } finally {
+ if (con != null) {
+ con.recycle();
+ }
+ }
+ }
+
+
+ // -------------------------------------------------- Master Slave Methods
+
+
+ /**
+ * Create (or allocate) and return an available processor for use in
+ * processing a specific HTTP request, if possible. If the maximum
+ * allowed processors have already been created and are in use, return
+ * <code>null</code> instead.
+ */
+ private MasterSlaveWorkerThread createWorkerThread() {
+
+ synchronized (workerThreads) {
+ if (workerThreads.size() > 0) {
+ return ((MasterSlaveWorkerThread) workerThreads.pop());
+ }
+ if ((maxThreads > 0) && (curThreads < maxThreads)) {
+ return (newWorkerThread());
+ } else {
+ if (maxThreads < 0) {
+ return (newWorkerThread());
+ } else {
+ return (null);
+ }
+ }
+ }
+
+ }
+
+
+ /**
+ * Create and return a new processor suitable for processing HTTP
+ * requests and returning the corresponding responses.
+ */
+ private MasterSlaveWorkerThread newWorkerThread() {
+
+ MasterSlaveWorkerThread workerThread =
+ new MasterSlaveWorkerThread(this, tp.getName() + "-" + (++curThreads));
+ workerThread.start();
+ created.addElement(workerThread);
+ return (workerThread);
+
+ }
+
+
+ /**
+ * Recycle the specified Processor so that it can be used again.
+ *
+ * @param processor The processor to be recycled
+ */
+ void recycleWorkerThread(MasterSlaveWorkerThread workerThread) {
+ workerThreads.push(workerThread);
+ }
+
+
+ /**
+ * The background thread that listens for incoming TCP/IP connections and
+ * hands them off to an appropriate processor.
+ */
+ public void run() {
+
+ // Loop until we receive a shutdown command
+ while (running) {
+
+ // Loop if endpoint is paused
+ while (paused) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+
+ // Allocate a new worker thread
+ MasterSlaveWorkerThread workerThread = createWorkerThread();
+ if (workerThread == null) {
+ try {
+ // Wait a little for load to go down: as a result,
+ // no accept will be made until the concurrency is
+ // lower than the specified maxThreads, and current
+ // connections will wait for a little bit instead of
+ // failing right away.
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ continue;
+ }
+
+ // Accept the next incoming connection from the server socket
+ Socket socket = acceptSocket();
+
+ // Hand this socket off to an appropriate processor
+ workerThread.assign(socket);
+
+ // The processor will recycle itself when it finishes
+
+ }
+
+ // Notify the threadStop() method that we have shut ourselves down
+ synchronized (threadSync) {
+ threadSync.notifyAll();
+ }
+
+ }
+
+
+ /**
+ * Start the background processing thread.
+ */
+ private void threadStart() {
+ thread = new Thread(this, tp.getName());
+ thread.setPriority(getThreadPriority());
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+
+ /**
+ * Stop the background processing thread.
+ */
+ private void threadStop() {
+ thread = null;
+ }
+
+
+}
Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SSLImplementation.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SSLImplementation.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SSLImplementation.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SSLImplementation.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+import java.net.Socket;
+import javax.net.ssl.SSLSession;
+
+/* SSLImplementation:
+
+ Abstract factory and base class for all SSL implementations.
+
+ @author EKR
+*/
+abstract public class SSLImplementation {
+ private static org.apache.juli.logging.Log logger =
+ org.apache.juli.logging.LogFactory.getLog(SSLImplementation.class);
+
+ // The default implementations in our search path
+ private static final String JSSEImplementationClass=
+ "org.apache.tomcat.util.net.jsse.JSSEImplementation";
+
+ private static final String[] implementations=
+ {
+ JSSEImplementationClass
+ };
+
+ public static SSLImplementation getInstance() throws ClassNotFoundException
+ {
+ for(int i=0;i<implementations.length;i++){
+ try {
+ SSLImplementation impl=
+ getInstance(implementations[i]);
+ return impl;
+ } catch (Exception e) {
+ if(logger.isTraceEnabled())
+ logger.trace("Error creating " + implementations[i],e);
+ }
+ }
+
+ // If we can't instantiate any of these
+ throw new ClassNotFoundException("Can't find any SSL implementation");
+ }
+
+ public static SSLImplementation getInstance(String className)
+ throws ClassNotFoundException
+ {
+ if(className==null) return getInstance();
+
+ try {
+ // Workaround for the J2SE 1.4.x classloading problem (under Solaris).
+ // Class.forName(..) fails without creating class using new.
+ // This is an ugly workaround.
+ if( JSSEImplementationClass.equals(className) ) {
+ return new org.apache.tomcat.util.net.jsse.JSSEImplementation();
+ }
+ Class clazz=Class.forName(className);
+ return (SSLImplementation)clazz.newInstance();
+ } catch (Exception e){
+ if(logger.isDebugEnabled())
+ logger.debug("Error loading SSL Implementation "
+ +className, e);
+ throw new ClassNotFoundException("Error loading SSL Implementation "
+ +className+ " :" +e.toString());
+ }
+ }
+
+ abstract public String getImplementationName();
+ abstract public ServerSocketFactory getServerSocketFactory();
+ abstract public SSLSupport getSSLSupport(Socket sock);
+
+ /**
+ * @deprecated This method has been deprecated since it adds a JSSE
+ * dependency to this interface. It will be removed in versions
+ * after 6.0.x.
+ */
+ @Deprecated
+ abstract public SSLSupport getSSLSupport(SSLSession session);
+}
Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SSLSupport.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SSLSupport.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SSLSupport.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SSLSupport.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+
+/* SSLSupport
+
+ Interface for SSL-specific functions
+
+ @author EKR
+*/
+
+public interface SSLSupport {
+ /**
+ * The Request attribute key for the cipher suite.
+ */
+ public static final String CIPHER_SUITE_KEY = "javax.servlet.request.cipher_suite";
+
+ /**
+ * The Request attribute key for the key size.
+ */
+ public static final String KEY_SIZE_KEY = "javax.servlet.request.key_size";
+
+ /**
+ * The Request attribute key for the client certificate chain.
+ */
+ public static final String CERTIFICATE_KEY = "javax.servlet.request.X509Certificate";
+
+ /**
+ * The Request attribute key for the session id.
+ * This one is a Tomcat extension to the Servlet spec.
+ */
+ public static final String SESSION_ID_KEY = "javax.servlet.request.ssl_session";
+
+ /**
+ * A mapping table to determine the number of effective bits in the key
+ * when using a cipher suite containing the specified cipher name. The
+ * underlying data came from the TLS Specification (RFC 2246), Appendix C.
+ */
+ static final CipherData ciphers[] = {
+ new CipherData("_WITH_NULL_", 0),
+ new CipherData("_WITH_IDEA_CBC_", 128),
+ new CipherData("_WITH_RC2_CBC_40_", 40),
+ new CipherData("_WITH_RC4_40_", 40),
+ new CipherData("_WITH_RC4_128_", 128),
+ new CipherData("_WITH_DES40_CBC_", 40),
+ new CipherData("_WITH_DES_CBC_", 56),
+ new CipherData("_WITH_3DES_EDE_CBC_", 168),
+ new CipherData("_WITH_AES_128_CBC_", 128),
+ new CipherData("_WITH_AES_256_CBC_", 256)
+ };
+
+ /**
+ * The cipher suite being used on this connection.
+ */
+ public String getCipherSuite() throws IOException;
+
+ /**
+ * The client certificate chain (if any).
+ */
+ public Object[] getPeerCertificateChain()
+ throws IOException;
+
+ /**
+ * The client certificate chain (if any).
+ * @param force If <code>true</code>, then re-negotiate the
+ * connection if necessary.
+ */
+ public Object[] getPeerCertificateChain(boolean force)
+ throws IOException;
+
+ /**
+ * Get the keysize.
+ *
+ * What we're supposed to put here is ill-defined by the
+ * Servlet spec (S 4.7 again). There are at least 4 potential
+ * values that might go here:
+ *
+ * (a) The size of the encryption key
+ * (b) The size of the MAC key
+ * (c) The size of the key-exchange key
+ * (d) The size of the signature key used by the server
+ *
+ * Unfortunately, all of these values are nonsensical.
+ **/
+ public Integer getKeySize()
+ throws IOException;
+
+ /**
+ * The current session Id.
+ */
+ public String getSessionId()
+ throws IOException;
+ /**
+ * Simple data class that represents the cipher being used, along with the
+ * corresponding effective key size. The specified phrase must appear in the
+ * name of the cipher suite to be recognized.
+ */
+
+ final class CipherData {
+
+ public String phrase = null;
+
+ public int keySize = 0;
+
+ public CipherData(String phrase, int keySize) {
+ this.phrase = phrase;
+ this.keySize = keySize;
+ }
+
+ }
+
+}
+
Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SecureNioChannel.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SecureNioChannel.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SecureNioChannel.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SecureNioChannel.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,489 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+import java.nio.channels.Selector;
+import org.apache.tomcat.util.MutableInteger;
+
+/**
+ *
+ * Implementation of a secure socket channel
+ * @author Filip Hanik
+ * @version 1.0
+ */
+
+public class SecureNioChannel extends NioChannel {
+
+ protected ByteBuffer netInBuffer;
+ protected ByteBuffer netOutBuffer;
+
+ protected SSLEngine sslEngine;
+
+ protected boolean initHandshakeComplete = false;
+ protected HandshakeStatus initHandshakeStatus; //gets set by begin handshake
+
+ protected boolean closed = false;
+ protected boolean closing = false;
+
+ protected NioSelectorPool pool;
+
+ public SecureNioChannel(SocketChannel channel, SSLEngine engine,
+ ApplicationBufferHandler bufHandler, NioSelectorPool pool) throws IOException {
+ super(channel,bufHandler);
+ this.sslEngine = engine;
+ int appBufSize = sslEngine.getSession().getApplicationBufferSize();
+ int netBufSize = sslEngine.getSession().getPacketBufferSize();
+ //allocate network buffers - TODO, add in optional direct non-direct buffers
+ if ( netInBuffer == null ) netInBuffer = ByteBuffer.allocateDirect(netBufSize);
+ if ( netOutBuffer == null ) netOutBuffer = ByteBuffer.allocateDirect(netBufSize);
+
+ //selector pool for blocking operations
+ this.pool = pool;
+
+ //ensure that the application has a large enough read/write buffers
+ //by doing this, we should not encounter any buffer overflow errors
+ bufHandler.expand(bufHandler.getReadBuffer(), appBufSize);
+ bufHandler.expand(bufHandler.getWriteBuffer(), appBufSize);
+ reset();
+ }
+
+ public void reset(SSLEngine engine) throws IOException {
+ this.sslEngine = engine;
+ reset();
+ }
+ public void reset() throws IOException {
+ super.reset();
+ netOutBuffer.position(0);
+ netOutBuffer.limit(0);
+ netInBuffer.position(0);
+ netInBuffer.limit(0);
+ initHandshakeComplete = false;
+ closed = false;
+ closing = false;
+ //initiate handshake
+ sslEngine.beginHandshake();
+ initHandshakeStatus = sslEngine.getHandshakeStatus();
+ }
+
+ public int getBufferSize() {
+ int size = super.getBufferSize();
+ size += netInBuffer!=null?netInBuffer.capacity():0;
+ size += netOutBuffer!=null?netOutBuffer.capacity():0;
+ return size;
+ }
+
+
+//===========================================================================================
+// NIO SSL METHODS
+//===========================================================================================
+ /**
+ * returns true if the network buffer has
+ * been flushed out and is empty
+ * @return boolean
+ */
+ public boolean flush(boolean block, Selector s, long timeout,MutableInteger lastWrite) throws IOException {
+ if (!block) {
+ flush(netOutBuffer);
+ } else {
+ pool.write(netOutBuffer, this, s, timeout,block,lastWrite);
+ }
+ return !netOutBuffer.hasRemaining();
+ }
+
+ /**
+ * Flushes the buffer to the network, non blocking
+ * @param buf ByteBuffer
+ * @return boolean true if the buffer has been emptied out, false otherwise
+ * @throws IOException
+ */
+ protected boolean flush(ByteBuffer buf) throws IOException {
+ int remaining = buf.remaining();
+ if ( remaining > 0 ) {
+ int written = sc.write(buf);
+ return written >= remaining;
+ }else {
+ return true;
+ }
+ }
+
+ /**
+ * Performs SSL handshake, non blocking, but performs NEED_TASK on the same thread.<br>
+ * Hence, you should never call this method using your Acceptor thread, as you would slow down
+ * your system significantly.<br>
+ * The return for this operation is 0 if the handshake is complete and a positive value if it is not complete.
+ * In the event of a positive value coming back, reregister the selection key for the return values interestOps.
+ * @param read boolean - true if the underlying channel is readable
+ * @param write boolean - true if the underlying channel is writable
+ * @return int - 0 if hand shake is complete, otherwise it returns a SelectionKey interestOps value
+ * @throws IOException
+ */
+ public int handshake(boolean read, boolean write) throws IOException {
+ if ( initHandshakeComplete ) return 0; //we have done our initial handshake
+
+ if (!flush(netOutBuffer)) return SelectionKey.OP_WRITE; //we still have data to write
+
+ SSLEngineResult handshake = null;
+
+ while (!initHandshakeComplete) {
+ switch ( initHandshakeStatus ) {
+ case NOT_HANDSHAKING: {
+ //should never happen
+ throw new IOException("NOT_HANDSHAKING during handshake");
+ }
+ case FINISHED: {
+ //we are complete if we have delivered the last package
+ initHandshakeComplete = !netOutBuffer.hasRemaining();
+ //return 0 if we are complete, otherwise we still have data to write
+ return initHandshakeComplete?0:SelectionKey.OP_WRITE;
+ }
+ case NEED_WRAP: {
+ //perform the wrap function
+ handshake = handshakeWrap(write);
+ if ( handshake.getStatus() == Status.OK ){
+ if (initHandshakeStatus == HandshakeStatus.NEED_TASK)
+ initHandshakeStatus = tasks();
+ } else {
+ //wrap should always work with our buffers
+ throw new IOException("Unexpected status:" + handshake.getStatus() + " during handshake WRAP.");
+ }
+ if ( initHandshakeStatus != HandshakeStatus.NEED_UNWRAP || (!flush(netOutBuffer)) ) {
+ //should actually return OP_READ if we have NEED_UNWRAP
+ return SelectionKey.OP_WRITE;
+ }
+ //fall down to NEED_UNWRAP on the same call, will result in a
+ //BUFFER_UNDERFLOW if it needs data
+ }
+ case NEED_UNWRAP: {
+ //perform the unwrap function
+ handshake = handshakeUnwrap(read);
+ if ( handshake.getStatus() == Status.OK ) {
+ if (initHandshakeStatus == HandshakeStatus.NEED_TASK)
+ initHandshakeStatus = tasks();
+ } else if ( handshake.getStatus() == Status.BUFFER_UNDERFLOW ){
+ //read more data, reregister for OP_READ
+ return SelectionKey.OP_READ;
+ } else {
+ throw new IOException("Invalid handshake status:"+initHandshakeStatus+" during handshake UNWRAP.");
+ }//switch
+ break;
+ }
+ case NEED_TASK: {
+ initHandshakeStatus = tasks();
+ break;
+ }
+ default: throw new IllegalStateException("Invalid handshake status:"+initHandshakeStatus);
+ }//switch
+ }//while
+ //return 0 if we are complete, otherwise reregister for any activity that
+ //would cause this method to be called again.
+ return initHandshakeComplete?0:(SelectionKey.OP_WRITE|SelectionKey.OP_READ);
+ }
+
+ /**
+ * Executes all the tasks needed on the same thread.
+ * @return HandshakeStatus
+ */
+ protected SSLEngineResult.HandshakeStatus tasks() {
+ Runnable r = null;
+ while ( (r = sslEngine.getDelegatedTask()) != null) {
+ r.run();
+ }
+ return sslEngine.getHandshakeStatus();
+ }
+
+ /**
+ * Performs the WRAP function
+ * @param doWrite boolean
+ * @return SSLEngineResult
+ * @throws IOException
+ */
+ protected SSLEngineResult handshakeWrap(boolean doWrite) throws IOException {
+ //this should never be called with a network buffer that contains data
+ //so we can clear it here.
+ netOutBuffer.clear();
+ //perform the wrap
+ SSLEngineResult result = sslEngine.wrap(bufHandler.getWriteBuffer(), netOutBuffer);
+ //prepare the results to be written
+ netOutBuffer.flip();
+ //set the status
+ initHandshakeStatus = result.getHandshakeStatus();
+ //optimization, if we do have a writable channel, write it now
+ if ( doWrite ) flush(netOutBuffer);
+ return result;
+ }
+
+ /**
+ * Perform handshake unwrap
+ * @param doread boolean
+ * @return SSLEngineResult
+ * @throws IOException
+ */
+ protected SSLEngineResult handshakeUnwrap(boolean doread) throws IOException {
+
+ if (netInBuffer.position() == netInBuffer.limit()) {
+ //clear the buffer if we have emptied it out on data
+ netInBuffer.clear();
+ }
+ if ( doread ) {
+ //if we have data to read, read it
+ int read = sc.read(netInBuffer);
+ if (read == -1) throw new IOException("EOF encountered during handshake.");
+ }
+ SSLEngineResult result;
+ boolean cont = false;
+ //loop while we can perform pure SSLEngine data
+ do {
+ //prepare the buffer with the incoming data
+ netInBuffer.flip();
+ //call unwrap
+ result = sslEngine.unwrap(netInBuffer, bufHandler.getReadBuffer());
+ //compact the buffer, this is an optional method, wonder what would happen if we didn't
+ netInBuffer.compact();
+ //read in the status
+ initHandshakeStatus = result.getHandshakeStatus();
+ if ( result.getStatus() == SSLEngineResult.Status.OK &&
+ result.getHandshakeStatus() == HandshakeStatus.NEED_TASK ) {
+ //execute tasks if we need to
+ initHandshakeStatus = tasks();
+ }
+ //perform another unwrap?
+ cont = result.getStatus() == SSLEngineResult.Status.OK &&
+ initHandshakeStatus == HandshakeStatus.NEED_UNWRAP;
+ }while ( cont );
+ return result;
+ }
+
+ /**
+ * Sends a SSL close message, will not physically close the connection here.<br>
+ * To close the connection, you could do something like
+ * <pre><code>
+ * close();
+ * while (isOpen() && !myTimeoutFunction()) Thread.sleep(25);
+ * if ( isOpen() ) close(true); //forces a close if you timed out
+ * </code></pre>
+ * @throws IOException if an I/O error occurs
+ * @throws IOException if there is data on the outgoing network buffer and we are unable to flush it
+ * @todo Implement this java.io.Closeable method
+ */
+ public void close() throws IOException {
+ if (closing) return;
+ closing = true;
+ sslEngine.closeOutbound();
+
+ if (!flush(netOutBuffer)) {
+ throw new IOException("Remaining data in the network buffer, can't send SSL close message, force a close with close(true) instead");
+ }
+ //prep the buffer for the close message
+ netOutBuffer.clear();
+ //perform the close, since we called sslEngine.closeOutbound
+ SSLEngineResult handshake = sslEngine.wrap(getEmptyBuf(), netOutBuffer);
+ //we should be in a close state
+ if (handshake.getStatus() != SSLEngineResult.Status.CLOSED) {
+ throw new IOException("Invalid close state, will not send network data.");
+ }
+ //prepare the buffer for writing
+ netOutBuffer.flip();
+ //if there is data to be written
+ flush(netOutBuffer);
+
+ //is the channel closed?
+ closed = (!netOutBuffer.hasRemaining() && (handshake.getHandshakeStatus() != HandshakeStatus.NEED_WRAP));
+ }
+
+ /**
+ * Force a close, can throw an IOException
+ * @param force boolean
+ * @throws IOException
+ */
+ public void close(boolean force) throws IOException {
+ try {
+ close();
+ }finally {
+ if ( force || closed ) {
+ closed = true;
+ sc.socket().close();
+ sc.close();
+ }
+ }
+ }
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer.
+ *
+ * @param dst The buffer into which bytes are to be transferred
+ * @return The number of bytes read, possibly zero, or <tt>-1</tt> if the channel has reached end-of-stream
+ * @throws IOException If some other I/O error occurs
+ * @throws IllegalArgumentException if the destination buffer is different than bufHandler.getReadBuffer()
+ * @todo Implement this java.nio.channels.ReadableByteChannel method
+ */
+ public int read(ByteBuffer dst) throws IOException {
+ //if we want to take advantage of the expand function, make sure we only use the ApplicationBufferHandler's buffers
+ if ( dst != bufHandler.getReadBuffer() ) throw new IllegalArgumentException("You can only read using the application read buffer provided by the handler.");
+ //are we in the middle of closing or closed?
+ if ( closing || closed) return -1;
+ //did we finish our handshake?
+ if (!initHandshakeComplete) throw new IllegalStateException("Handshake incomplete, you must complete handshake before reading data.");
+
+ //read from the network
+ int netread = sc.read(netInBuffer);
+ //did we reach EOF? if so send EOF up one layer.
+ if (netread == -1) return -1;
+
+ //the data read
+ int read = 0;
+ //the SSL engine result
+ SSLEngineResult unwrap;
+ do {
+ //prepare the buffer
+ netInBuffer.flip();
+ //unwrap the data
+ unwrap = sslEngine.unwrap(netInBuffer, dst);
+ //compact the buffer
+ netInBuffer.compact();
+
+ if ( unwrap.getStatus()==Status.OK || unwrap.getStatus()==Status.BUFFER_UNDERFLOW ) {
+ //we did receive some data, add it to our total
+ read += unwrap.bytesProduced();
+ //perform any tasks if needed
+ if (unwrap.getHandshakeStatus() == HandshakeStatus.NEED_TASK) tasks();
+ //if we need more network data, then bail out for now.
+ if ( unwrap.getStatus() == Status.BUFFER_UNDERFLOW ) break;
+ }else if ( unwrap.getStatus()==Status.BUFFER_OVERFLOW && read>0 ) {
+ //buffer overflow can happen, if we have read data, then
+ //empty out the dst buffer before we do another read
+ break;
+ }else {
+ //here we should trap BUFFER_OVERFLOW and call expand on the buffer
+ //for now, throw an exception, as we initialized the buffers
+ //in the constructor
+ throw new IOException("Unable to unwrap data, invalid status: " + unwrap.getStatus());
+ }
+ } while ( (netInBuffer.position() != 0)); //continue to unwrapping as long as the input buffer has stuff
+ return (read);
+ }
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer.
+ *
+ * @param src The buffer from which bytes are to be retrieved
+ * @return The number of bytes written, possibly zero
+ * @throws IOException If some other I/O error occurs
+ * @todo Implement this java.nio.channels.WritableByteChannel method
+ */
+ public int write(ByteBuffer src) throws IOException {
+ if ( src == this.netOutBuffer ) {
+ //we can get here through a recursive call
+ //by using the NioBlockingSelector
+ int written = sc.write(src);
+ return written;
+ } else {
+ //make sure we can handle expand, and that we only use on buffer
+ if ( (!this.isSendFile()) && (src != bufHandler.getWriteBuffer()) ) throw new IllegalArgumentException("You can only write using the application write buffer provided by the handler.");
+ //are we closing or closed?
+ if ( closing || closed) throw new IOException("Channel is in closing state.");
+
+ //the number of bytes written
+ int written = 0;
+
+ if (!flush(netOutBuffer)) {
+ //we haven't emptied out the buffer yet
+ return written;
+ }
+
+ /*
+ * The data buffer is empty, we can reuse the entire buffer.
+ */
+ netOutBuffer.clear();
+
+ SSLEngineResult result = sslEngine.wrap(src, netOutBuffer);
+ written = result.bytesConsumed();
+ netOutBuffer.flip();
+
+ if (result.getStatus() == Status.OK) {
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) tasks();
+ } else {
+ throw new IOException("Unable to wrap data, invalid engine state: " +result.getStatus());
+ }
+
+ //force a flush
+ flush(netOutBuffer);
+
+ return written;
+ }
+ }
+
+ @Override
+ public int getOutboundRemaining() {
+ return netOutBuffer.remaining();
+ }
+
+ @Override
+ public boolean flushOutbound() throws IOException {
+ int remaining = netOutBuffer.remaining();
+ flush(netOutBuffer);
+ int remaining2= netOutBuffer.remaining();
+ return remaining2 < remaining;
+ }
+
+
+ /**
+ * Callback interface to be able to expand buffers
+ * when buffer overflow exceptions happen
+ */
+ public static interface ApplicationBufferHandler {
+ public ByteBuffer expand(ByteBuffer buffer, int remaining);
+ public ByteBuffer getReadBuffer();
+ public ByteBuffer getWriteBuffer();
+ }
+
+ public ApplicationBufferHandler getBufHandler() {
+ return bufHandler;
+ }
+
+ public boolean isInitHandshakeComplete() {
+ return initHandshakeComplete;
+ }
+
+ public boolean isClosing() {
+ return closing;
+ }
+
+ public SSLEngine getSslEngine() {
+ return sslEngine;
+ }
+
+ public ByteBuffer getEmptyBuf() {
+ return emptyBuf;
+ }
+
+ public void setBufHandler(ApplicationBufferHandler bufHandler) {
+ this.bufHandler = bufHandler;
+ }
+
+ public SocketChannel getIOChannel() {
+ return sc;
+ }
+
+}
\ No newline at end of file
Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/ServerSocketFactory.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/ServerSocketFactory.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/ServerSocketFactory.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/ServerSocketFactory.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Hashtable;
+
+/**
+ * This class creates server sockets. It may be subclassed by other
+ * factories, which create particular types of server sockets. This
+ * provides a general framework for the addition of public socket-level
+ * functionality. It it is the server side analogue of a socket factory,
+ * and similarly provides a way to capture a variety of policies related
+ * to the sockets being constructed.
+ *
+ * <P> Like socket factories, Server Socket factory instances have two
+ * categories of methods. First are methods used to create sockets.
+ * Second are methods which set properties used in the production of
+ * sockets, such as networking options. There is also an environment
+ * specific default server socket factory; frameworks will often use
+ * their own customized factory.
+ *
+ * <P><hr><em> It may be desirable to move this interface into the
+ * <b>java.net</b> package, so that is not an extension but the preferred
+ * interface. Should this be serializable, making it a JavaBean which can
+ * be saved along with its networking configuration?
+ * </em>
+ *
+ * @author db@eng.sun.com
+ * @author Harish Prabandham
+ */
+public abstract class ServerSocketFactory implements Cloneable {
+
+ //
+ // NOTE: JDK 1.1 bug in class GC, this can get collected
+ // even though it's always accessible via getDefault().
+ //
+
+ private static ServerSocketFactory theFactory;
+ protected Hashtable attributes=new Hashtable();
+
+ /**
+ * Constructor is used only by subclasses.
+ */
+
+ protected ServerSocketFactory () {
+ /* NOTHING */
+ }
+
+ /** General mechanism to pass attributes from the
+ * ServerConnector to the socket factory.
+ *
+ * Note that the "prefered" mechanism is to
+ * use bean setters and explicit methods, but
+ * this allows easy configuration via server.xml
+ * or simple Properties
+ */
+ public void setAttribute( String name, Object value ) {
+ if( name!=null && value !=null)
+ attributes.put( name, value );
+ }
+
+ /**
+ * Returns a copy of the environment's default socket factory.
+ */
+ public static synchronized ServerSocketFactory getDefault () {
+ //
+ // optimize typical case: no synch needed
+ //
+
+ if (theFactory == null) {
+ //
+ // Different implementations of this method could
+ // work rather differently. For example, driving
+ // this from a system property, or using a different
+ // implementation than JavaSoft's.
+ //
+
+ theFactory = new DefaultServerSocketFactory ();
+ }
+
+ try {
+ return (ServerSocketFactory) theFactory.clone ();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException (e.getMessage ());
+ }
+ }
+
+ /**
+ * Returns a server socket which uses all network interfaces on
+ * the host, and is bound to a the specified port. The socket is
+ * configured with the socket options (such as accept timeout)
+ * given to this factory.
+ *
+ * @param port the port to listen to
+ * @exception IOException for networking errors
+ * @exception InstantiationException for construction errors
+ */
+ public abstract ServerSocket createSocket (int port)
+ throws IOException, InstantiationException;
+
+ /**
+ * Returns a server socket which uses all network interfaces on
+ * the host, is bound to a the specified port, and uses the
+ * specified connection backlog. The socket is configured with
+ * the socket options (such as accept timeout) given to this factory.
+ *
+ * @param port the port to listen to
+ * @param backlog how many connections are queued
+ * @exception IOException for networking errors
+ * @exception InstantiationException for construction errors
+ */
+
+ public abstract ServerSocket createSocket (int port, int backlog)
+ throws IOException, InstantiationException;
+
+ /**
+ * Returns a server socket which uses only the specified network
+ * interface on the local host, is bound to a the specified port,
+ * and uses the specified connection backlog. The socket is configured
+ * with the socket options (such as accept timeout) given to this factory.
+ *
+ * @param port the port to listen to
+ * @param backlog how many connections are queued
+ * @param ifAddress the network interface address to use
+ * @exception IOException for networking errors
+ * @exception InstantiationException for construction errors
+ */
+
+ public abstract ServerSocket createSocket (int port,
+ int backlog, InetAddress ifAddress)
+ throws IOException, InstantiationException;
+
+ public void initSocket( Socket s ) {
+ }
+
+ /**
+ Wrapper function for accept(). This allows us to trap and
+ translate exceptions if necessary
+
+ @exception IOException;
+ */
+ public abstract Socket acceptSocket(ServerSocket socket)
+ throws IOException;
+
+ /**
+ Extra function to initiate the handshake. Sometimes necessary
+ for SSL
+
+ @exception IOException;
+ */
+ public abstract void handshake(Socket sock)
+ throws IOException;
+}
+
Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SocketProperties.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SocketProperties.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SocketProperties.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SocketProperties.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net;
+
+import java.net.Socket;
+import java.net.SocketException;
+/**
+ * Properties that can be set in the <Connector> element
+ * in server.xml. All properties are prefixed with "socket."
+ * and are currently only working for the Nio connector
+ *
+ * @author Filip Hanik
+ */
+public class SocketProperties {
+ /**
+ * Enable/disable key cache, this bounded cache stores
+ * KeyAttachment objects to reduce GC
+ * Default is 500
+ * -1 is unlimited
+ * 0 is disabled
+ */
+ protected int keyCache = 500;
+
+ /**
+ * Enable/disable socket processor cache, this bounded cache stores
+ * SocketProcessor objects to reduce GC
+ * Default is 500
+ * -1 is unlimited
+ * 0 is disabled
+ */
+ protected int processorCache = 500;
+
+
+
+ /**
+ * Enable/disable poller event cache, this bounded cache stores
+ * PollerEvent objects to reduce GC for the poller
+ * Default is 500
+ * -1 is unlimited
+ * 0 is disabled
+ * >0 the max number of objects to keep in cache.
+ */
+ protected int eventCache = 500;
+
+
+ /**
+ * Enable/disable direct buffers for the network buffers
+ * Default value is enabled
+ */
+ protected boolean directBuffer = false;
+ /**
+ * Socket receive buffer size in bytes (SO_RCVBUF)
+ * Default value is 25188
+ */
+ protected int rxBufSize = 25188;
+ /**
+ * Socket send buffer size in bytes (SO_SNDBUF)
+ * Default value is 43800
+ */
+ protected int txBufSize = 43800;
+
+ /**
+ * The application read buffer size in bytes.
+ * Default value is rxBufSize
+ */
+ protected int appReadBufSize = 8192;
+
+ /**
+ * The application write buffer size in bytes
+ * Default value is txBufSize
+ */
+ protected int appWriteBufSize = 8192;
+
+ /**
+ * NioChannel pool size for the endpoint,
+ * this value is how many channels
+ * -1 means unlimited cached, 0 means no cache
+ * Default value is 500
+ */
+ protected int bufferPool = 500;
+
+
+ /**
+ * Buffer pool size in bytes to be cached
+ * -1 means unlimited, 0 means no cache
+ * Default value is 100MB (1024*1024*100 bytes)
+ */
+ protected int bufferPoolSize = 1024*1024*100;
+
+ /**
+ * TCP_NO_DELAY option, default is true
+ */
+ protected boolean tcpNoDelay = true;
+ /**
+ * SO_KEEPALIVE option, default is false
+ */
+ protected boolean soKeepAlive = false;
+ /**
+ * OOBINLINE option, default is true
+ */
+ protected boolean ooBInline = true;
+ /**
+ * SO_REUSEADDR option, default is true
+ */
+ protected boolean soReuseAddress = true;
+ /**
+ * SO_LINGER option, default is true, paired with the <code>soLingerTime</code> value
+ */
+ protected boolean soLingerOn = true;
+ /**
+ * SO_LINGER option, default is 25 seconds.
+ */
+ protected int soLingerTime = 25;
+ /**
+ * SO_TIMEOUT option, default is 5000 milliseconds
+ */
+ protected int soTimeout = 5000;
+ /**
+ * Traffic class option, value between 0 and 255
+ * IPTOS_LOWCOST (0x02)
+ * IPTOS_RELIABILITY (0x04)
+ * IPTOS_THROUGHPUT (0x08)
+ * IPTOS_LOWDELAY (0x10)
+ * Default value is 0x04 | 0x08 | 0x010
+ */
+ protected int soTrafficClass = 0x04 | 0x08 | 0x010;
+ /**
+ * Performance preferences according to
+ * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
+ * Default value is 1
+ */
+ protected int performanceConnectionTime = 1;
+ /**
+ * Performance preferences according to
+ * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
+ * Default value is 0
+ */
+ protected int performanceLatency = 0;
+ /**
+ * Performance preferences according to
+ * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
+ * Default value is 1
+ */
+ protected int performanceBandwidth = 1;
+
+ /**
+ * The minimum frequency of the timeout interval to avoid the
+ * poller going boinkers during high traffic
+ */
+ protected long timeoutInterval = 1000;
+
+ /**
+ * Timeout in milliseconds for an unlock to take place.
+ */
+ protected int unlockTimeout = 250;
+
+
+ private Socket properties;
+
+ public void setProperties(Socket socket) throws SocketException{
+ socket.setReceiveBufferSize(rxBufSize);
+ socket.setSendBufferSize(txBufSize);
+ socket.setOOBInline(ooBInline);
+ socket.setKeepAlive(soKeepAlive);
+ socket.setPerformancePreferences(performanceConnectionTime,performanceLatency,performanceBandwidth);
+ socket.setReuseAddress(soReuseAddress);
+ socket.setSoLinger(soLingerOn,soLingerTime);
+ socket.setSoTimeout(soTimeout);
+ socket.setTcpNoDelay(tcpNoDelay);
+ socket.setTrafficClass(soTrafficClass);
+ }
+
+ public boolean getDirectBuffer() {
+ return directBuffer;
+ }
+
+ public boolean getOoBInline() {
+ return ooBInline;
+ }
+
+ public int getPerformanceBandwidth() {
+ return performanceBandwidth;
+ }
+
+ public int getPerformanceConnectionTime() {
+ return performanceConnectionTime;
+ }
+
+ public int getPerformanceLatency() {
+ return performanceLatency;
+ }
+
+ public int getRxBufSize() {
+ return rxBufSize;
+ }
+
+ public boolean getSoKeepAlive() {
+ return soKeepAlive;
+ }
+
+ public boolean getSoLingerOn() {
+ return soLingerOn;
+ }
+
+ public int getSoLingerTime() {
+ return soLingerTime;
+ }
+
+ public boolean getSoReuseAddress() {
+ return soReuseAddress;
+ }
+
+ public int getSoTimeout() {
+ return soTimeout;
+ }
+
+ public int getSoTrafficClass() {
+ return soTrafficClass;
+ }
+
+ public boolean getTcpNoDelay() {
+ return tcpNoDelay;
+ }
+
+ public int getTxBufSize() {
+ return txBufSize;
+ }
+
+ public int getBufferPool() {
+ return bufferPool;
+ }
+
+ public int getBufferPoolSize() {
+ return bufferPoolSize;
+ }
+
+ public int getEventCache() {
+ return eventCache;
+ }
+
+ public int getKeyCache() {
+ return keyCache;
+ }
+
+ public Socket getProperties() {
+ return properties;
+ }
+
+ public int getAppReadBufSize() {
+ return appReadBufSize;
+ }
+
+ public int getAppWriteBufSize() {
+ return appWriteBufSize;
+ }
+
+ public int getProcessorCache() {
+ return processorCache;
+ }
+
+ public long getTimeoutInterval() {
+ return timeoutInterval;
+ }
+
+ public int getDirectBufferPool() {
+ return bufferPool;
+ }
+
+ public void setPerformanceConnectionTime(int performanceConnectionTime) {
+ this.performanceConnectionTime = performanceConnectionTime;
+ }
+
+ public void setTxBufSize(int txBufSize) {
+ this.txBufSize = txBufSize;
+ }
+
+ public void setTcpNoDelay(boolean tcpNoDelay) {
+ this.tcpNoDelay = tcpNoDelay;
+ }
+
+ public void setSoTrafficClass(int soTrafficClass) {
+ this.soTrafficClass = soTrafficClass;
+ }
+
+ public void setSoTimeout(int soTimeout) {
+ this.soTimeout = soTimeout;
+ }
+
+ public void setSoReuseAddress(boolean soReuseAddress) {
+ this.soReuseAddress = soReuseAddress;
+ }
+
+ public void setSoLingerTime(int soLingerTime) {
+ this.soLingerTime = soLingerTime;
+ }
+
+ public void setSoKeepAlive(boolean soKeepAlive) {
+ this.soKeepAlive = soKeepAlive;
+ }
+
+ public void setRxBufSize(int rxBufSize) {
+ this.rxBufSize = rxBufSize;
+ }
+
+ public void setPerformanceLatency(int performanceLatency) {
+ this.performanceLatency = performanceLatency;
+ }
+
+ public void setPerformanceBandwidth(int performanceBandwidth) {
+ this.performanceBandwidth = performanceBandwidth;
+ }
+
+ public void setOoBInline(boolean ooBInline) {
+ this.ooBInline = ooBInline;
+ }
+
+ public void setDirectBuffer(boolean directBuffer) {
+ this.directBuffer = directBuffer;
+ }
+
+ public void setSoLingerOn(boolean soLingerOn) {
+ this.soLingerOn = soLingerOn;
+ }
+
+ public void setBufferPool(int bufferPool) {
+ this.bufferPool = bufferPool;
+ }
+
+ public void setBufferPoolSize(int bufferPoolSize) {
+ this.bufferPoolSize = bufferPoolSize;
+ }
+
+ public void setEventCache(int eventCache) {
+ this.eventCache = eventCache;
+ }
+
+ public void setKeyCache(int keyCache) {
+ this.keyCache = keyCache;
+ }
+
+ public void setAppReadBufSize(int appReadBufSize) {
+ this.appReadBufSize = appReadBufSize;
+ }
+
+ public void setAppWriteBufSize(int appWriteBufSize) {
+ this.appWriteBufSize = appWriteBufSize;
+ }
+
+ public void setProcessorCache(int processorCache) {
+ this.processorCache = processorCache;
+ }
+
+ public void setTimeoutInterval(long timeoutInterval) {
+ this.timeoutInterval = timeoutInterval;
+ }
+
+ public void setDirectBufferPool(int directBufferPool) {
+ this.bufferPool = directBufferPool;
+ }
+
+ public int getUnlockTimeout() {
+ return unlockTimeout;
+ }
+
+ public void setUnlockTimeout(int unlockTimeout) {
+ this.unlockTimeout = unlockTimeout;
+ }
+
+
+
+}
\ No newline at end of file
Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SocketStatus.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SocketStatus.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SocketStatus.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/SocketStatus.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+/**
+ * Someone, please change the enum name.
+ *
+ * @author remm
+ */
+public enum SocketStatus {
+ OPEN, STOP, TIMEOUT, DISCONNECT, ERROR
+}
Added: geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/TcpConnection.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/TcpConnection.java?rev=1214761&view=auto
==============================================================================
--- geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/TcpConnection.java (added)
+++ geronimo/external/trunk/tomcat-parent-6.0.35/catalina/src/main/java/org/apache/tomcat/util/net/TcpConnection.java Thu Dec 15 13:55:25 2011
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+
+/**
+ *
+ */
+public class TcpConnection { // implements Endpoint {
+ /**
+ * Maxium number of times to clear the socket input buffer.
+ */
+ static int MAX_SHUTDOWN_TRIES=20;
+
+ public TcpConnection() {
+ }
+
+ // -------------------- Properties --------------------
+
+ PoolTcpEndpoint endpoint;
+ Socket socket;
+
+ public static void setMaxShutdownTries(int mst) {
+ MAX_SHUTDOWN_TRIES = mst;
+ }
+ public void setEndpoint(PoolTcpEndpoint endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public PoolTcpEndpoint getEndpoint() {
+ return endpoint;
+ }
+
+ public void setSocket(Socket socket) {
+ this.socket=socket;
+ }
+
+ public Socket getSocket() {
+ return socket;
+ }
+
+ public void recycle() {
+ endpoint = null;
+ socket = null;
+ }
+
+ // Another frequent repetition
+ public static int readLine(InputStream in, byte[] b, int off, int len)
+ throws IOException
+ {
+ if (len <= 0) {
+ return 0;
+ }
+ int count = 0, c;
+
+ while ((c = in.read()) != -1) {
+ b[off++] = (byte)c;
+ count++;
+ if (c == '\n' || count == len) {
+ break;
+ }
+ }
+ return count > 0 ? count : -1;
+ }
+
+
+ // Usefull stuff - avoid having it replicated everywhere
+ public static void shutdownInput(Socket socket)
+ throws IOException
+ {
+ try {
+ InputStream is = socket.getInputStream();
+ int available = is.available ();
+ int count=0;
+
+ // XXX on JDK 1.3 just socket.shutdownInput () which
+ // was added just to deal with such issues.
+
+ // skip any unread (bogus) bytes
+ while (available > 0 && count++ < MAX_SHUTDOWN_TRIES) {
+ is.skip (available);
+ available = is.available();
+ }
+ }catch(NullPointerException npe) {
+ // do nothing - we are just cleaning up, this is
+ // a workaround for Netscape \n\r in POST - it is supposed
+ // to be ignored
+ }
+ }
+}
+
+
|