| /* |
| * 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. |
| */ |
| |
| /*** |
| * Java TelnetD library (embeddable telnet daemon) |
| * Copyright (c) 2000-2005 Dieter Wimberger |
| * All rights reserved. |
| * <p/> |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * <p/> |
| * Neither the name of the author nor the names of its contributors |
| * may be used to endorse or promote products derived from this software |
| * without specific prior written permission. |
| * <p/> |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS |
| * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| ***/ |
| |
| package org.apache.felix.gogo.jline.telnet; |
| |
| import java.io.IOException; |
| import java.net.ServerSocket; |
| import java.net.Socket; |
| import java.net.SocketException; |
| import java.text.MessageFormat; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| /** |
| * Class that implements a <tt>PortListener</tt>.<br> |
| * If available, it accepts incoming connections and passes them |
| * to an associated <tt>ConnectionManager</tt>. |
| * |
| * @author Dieter Wimberger |
| * @version 2.0 (16/07/2006) |
| * @see ConnectionManager |
| */ |
| public class PortListener |
| implements Runnable { |
| |
| private static final Logger LOG = Logger.getLogger(PortListener.class.getName()); |
| private static final String logmsg = |
| "Listening to Port {0,number,integer} with a connectivity queue size of {1,number,integer}."; |
| private String name; |
| private int port; //port number running on |
| private int floodProtection; //flooding protection |
| private ServerSocket serverSocket = null; //server socket |
| private Thread thread; |
| private ConnectionManager connectionManager; //connection management thread |
| private boolean stopping = false; |
| private boolean available; //Flag for availability |
| |
| /** |
| * Constructs a PortListener instance.<br> |
| * |
| * @param port int that specifies the port number of the server socket. |
| * @param floodprot that specifies the server socket queue size. |
| */ |
| public PortListener(String name, int port, int floodprot) { |
| this.name = name; |
| available = false; |
| this.port = port; |
| floodProtection = floodprot; |
| }//constructor |
| |
| /** |
| * Returns the name of this <tt>PortListener</tt>. |
| * |
| * @return the name as <tt>String</tt>. |
| */ |
| public String getName() { |
| return name; |
| }//getName |
| |
| /** |
| * Tests if this <tt>PortListener</tt> is available. |
| * |
| * @return true if available, false otherwise. |
| */ |
| public boolean isAvailable() { |
| return available; |
| }//isAvailable |
| |
| /** |
| * Sets the availability flag of this <tt>PortListener</tt>. |
| * |
| * @param b true if to be available, false otherwise. |
| */ |
| public void setAvailable(boolean b) { |
| available = b; |
| }//setAvailable |
| |
| /** |
| * Starts this <tt>PortListener</tt>. |
| */ |
| public void start() { |
| LOG.log(Level.FINE, "start()"); |
| thread = new Thread(this); |
| thread.start(); |
| available = true; |
| }//start |
| |
| /** |
| * Stops this <tt>PortListener</tt>, and returns |
| * when everything was stopped successfully. |
| */ |
| public void stop() { |
| LOG.log(Level.FINE, "stop()::" + this.toString()); |
| //flag stop |
| stopping = true; |
| available = false; |
| //take down all connections |
| connectionManager.stop(); |
| |
| //close server socket |
| try { |
| serverSocket.close(); |
| } catch (IOException ex) { |
| LOG.log(Level.SEVERE, "stop()", ex); |
| } |
| |
| //wait for thread to die |
| try { |
| thread.join(); |
| } catch (InterruptedException iex) { |
| LOG.log(Level.SEVERE, "stop()", iex); |
| } |
| |
| LOG.info("stop()::Stopped " + this.toString()); |
| }//stop |
| |
| /** |
| * Listen constantly to a server socket and handles incoming connections |
| * through the associated {a:link ConnectionManager}. |
| * |
| * @see ConnectionManager |
| */ |
| public void run() { |
| try { |
| /* |
| A server socket is opened with a connectivity queue of a size specified |
| in int floodProtection. Concurrent login handling under normal circumstances |
| should be handled properly, but denial of service attacks via massive parallel |
| program logins should be prevented with this. |
| */ |
| serverSocket = new ServerSocket(port, floodProtection); |
| |
| //log entry |
| LOG.info(MessageFormat.format(logmsg, port, floodProtection)); |
| |
| do { |
| try { |
| Socket s = serverSocket.accept(); |
| if (available) { |
| connectionManager.makeConnection(s); |
| } else { |
| //just shut down the socket |
| s.close(); |
| } |
| } catch (SocketException ex) { |
| if (stopping) { |
| //server socket was closed blocked in accept |
| LOG.log(Level.FINE, "run(): ServerSocket closed by stop()"); |
| } else { |
| LOG.log(Level.SEVERE, "run()", ex); |
| } |
| } |
| } while (!stopping); |
| |
| } catch (IOException e) { |
| LOG.log(Level.SEVERE, "run()", e); |
| } |
| LOG.log(Level.FINE, "run(): returning."); |
| }//run |
| |
| /** |
| * Returns reference to ConnectionManager instance associated |
| * with the PortListener. |
| * |
| * @return the associated ConnectionManager. |
| */ |
| public ConnectionManager getConnectionManager() { |
| return connectionManager; |
| }//getConnectionManager |
| |
| public void setConnectionManager(ConnectionManager connectionManager) { |
| this.connectionManager = connectionManager; |
| } |
| |
| }//class PortListener |