⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vpnconnectionlistener.java

📁 这是linux下ssl vpn的实现程序
💻 JAVA
字号:
/*
 *  SSL-Explorer
 *
 *  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
			
package com.sslexplorer.vpn.base;

import java.io.*;


import java.net.*;
import java.util.*;
import com.sslexplorer.vpn.util.*;

public class VPNConnectionListener implements Runnable {

    AbstractVPNClient vpn;
    ServerSocket server;
    Thread thread;
    boolean listening;
    Vector activeTunnels;
    TunnelListener listener;
    IOStreamConnectorListener txListener;
    IOStreamConnectorListener rxListener;
    String ticket;
    Tunnel tunnel;
    int id;
    long dataLastTransferred;
    int datagramLength = 65536;
    byte[] datagramBuffer;
    VPNUDPTunnel udpTunnel;
    DatagramSocket datagramSocket;
    boolean stopping;
    int totalTunnels;

    /* DEBUG */static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(VPNConnectionListener.class);

    public VPNConnectionListener(AbstractVPNClient vpn, IOStreamConnectorListener txListener, IOStreamConnectorListener rxListener,
                                 Tunnel tunnel) {
        this.vpn = vpn;
        this.tunnel = tunnel;
        this.txListener = txListener;
        this.rxListener = rxListener;
        this.listener = new TunnelListener();
        this.activeTunnels = new Vector();
        dataLastTransferred = System.currentTimeMillis();
    }
    
    public int getActiveTunnelCount() {
        return activeTunnels.size();
    }
    
    public int getTotalTunnelCount() {
        return totalTunnels;
    }

    public Tunnel getTunnel() {
        return tunnel;
    }

    public int getId() {
        return id;
    }

    public int getLocalPort() {
        return (server == null) ? (datagramSocket == null ? -1 : datagramSocket.getLocalPort()) : server.getLocalPort();
    }

    public boolean isListening() {
        return listening;
    }

    public long getDataLastTransferredTime() {
        return dataLastTransferred;
    }



    public void run() {
        if (tunnel.getTransport().equals(Tunnel.UDP_TUNNEL)) {
            tunnelUDP();
        } else {
            tunnelTCP();
        }
    }

    void tunnelUDP() {
        try {

            // Open an SSL tunnel and connect the socket to the tunnel
            VPNTunnel vpntunnel = new VPNUDPTunnel(this, vpn, tunnel.getSourcePort(), vpn.createTunnel(tunnel), datagramSocket, tunnel
                            .getDestinationHost(), tunnel.getDestinationPort(), txListener, rxListener);

            vpntunnel.addListener(listener);
            vpntunnel.start();

        } catch (Throwable ex) {
            /* DEBUG */log.info("Failed to connect tunneling request", ex);
        } finally {
            vpn.stopListeningSocket(getTicket());
        }
    }

    void tunnelTCP() {

        Socket socket = null;

        try {

            listening = true;

            while (listening) {
                socket = server.accept();

                if (!listening || (socket == null)) {
                    break;
                }

                /* DEBUG */log.info("Tunneling request received for "
                /* DEBUG */+ getAddressToBind()
                /* DEBUG */+ ":"
                /* DEBUG */+ tunnel.getSourcePort());

                try {
                    // Open an SSL tunnel and connect the socket to the tunnel
                    VPNTunnel vpntunnel = new VPNTCPTunnel(this, vpn.createTunnel(tunnel), socket, tunnel.getDestinationHost(), tunnel
                                    .getDestinationPort(), txListener, rxListener);

                    vpntunnel.addListener(listener); 
                    vpntunnel.start();

                } catch (Throwable ex) {
                    /* DEBUG */log.info("Failed to connect tunneling request", ex);
                    try {
                        socket.close();
                    } catch (IOException ioe) {
                    }
                }

                if(!tunnel.isPermanent() && tunnel.isTemporarySingleConnect()) {
                    /* DEBUG */log.info("Not accepting any more connections as this is a temporary tunnel.");
                    break;
                }
            }
        } catch (Throwable ex) {
            if (!stopping) {
                /* DEBUG */log.info("The connection listener thread failed", ex);
            }
        } finally {

            if (tunnel.isPermanent() || !tunnel.isTemporarySingleConnect()) {
                if (!stopping) {
                    vpn.stopListeningSocket(getTicket());
                }
            }

            // Not setting thread to null in order to see if it fixes a problem
            stopping = false;
        }
    }

    String getAddressToBind() {
        if (tunnel.isAllowExternalHosts())
            return "0.0.0.0";
        else
            return tunnel.isLocalhostWorkaround()? "127.0.0.1" : "127.0.0.1";
    }

    public boolean isRunning() {
        return (thread != null) && thread.isAlive();
    }

    public String getTicket() {
        return ticket;
    }

    public void start() throws IOException {
        dataLastTransferred = System.currentTimeMillis();

        /* DEBUG */log.info("Starting "
        /* DEBUG */+ (tunnel.isPermanent() ? "permanent" : "temporary")
        /* DEBUG */+ " VPN connection listener on port " + tunnel.getSourcePort());

        /* Bind server socket */
        if (tunnel.getTransport().equals(Tunnel.UDP_TUNNEL)) {
            /* DEBUG */log.info("UDP socket created on " + InetAddress.getByName(getAddressToBind()) + ":"
            /* DEBUG */+ tunnel.getSourcePort());
            // datagramSocket = new DatagramSocket(tunnel.getSourcePort(),
            // InetAddress.getByName(getAddressToBind()));
            datagramSocket = new DatagramSocket(tunnel.getSourcePort());
        } else {
            /* DEBUG */log.info("TCP socket created on " + InetAddress.getByName(getAddressToBind()) + ":"
            /* DEBUG */+ tunnel.getSourcePort());
            server = new ServerSocket(tunnel.getSourcePort(), 50, InetAddress.getByName(getAddressToBind()));
        }

        XMLElement xml = null;
        try {
            xml = vpn.registerListeningSocket(true, tunnel);
        } catch (Exception e) {
            throw new IOException("Failed to register tunnel. " + e.getMessage());
        }
        if (xml != null) {
            ticket = xml.getStringAttribute("ticket");

            tunnel.setTicket(ticket);

            id = xml.getIntAttribute("id");
            /* DEBUG */log.info("Registration complete");
            /* Create a thread and start it */
            thread = new Thread(this);
            thread.setDaemon(true);
            thread.setName("SocketListener " + getAddressToBind() + ":" + String.valueOf(tunnel.getSourcePort()));
            thread.start();
        } else {
            /* DEBUG */log.info("Failed to register tunnel with server. ");
            vpn.stopListeningSocket(getTicket());
        }
    }

    /**
     *
     */
    public void stop() {
        try {
            stopping = true;

            /* DEBUG */log.info("Closing " + (tunnel.isPermanent() ? "permanent" : "temporary")
            /* DEBUG */+ " listener on "
            /* DEBUG */+ getAddressToBind()
            /* DEBUG */+ ":"
            /* DEBUG */+ tunnel.getSourcePort());

            /* Close the server socket to prevent new connections */
            if (server != null) {
                server.close();
            }

            /* Stop all of the tunnels */
            synchronized (activeTunnels) {
                for (Enumeration e = activeTunnels.elements(); e.hasMoreElements();) {
                    ((VPNTunnel) e.nextElement()).stop();
                }
            }
        } catch (IOException ioe) {
        }

        vpn.unregisterListeningSocket(tunnel);

        server = null;
        listening = false;
    }

    class TunnelListener implements VPNTunnelListener {
        public void started(VPNTunnel tunnel) {
            synchronized (activeTunnels) {
                totalTunnels++;
                activeTunnels.addElement(tunnel);
                vpn.registerForwardingTunnel(tunnel);
                /* DEBUG */log.info("User on " + tunnel.getClientHost() +
                /* DEBUG */" has opened a tunnel to " + tunnel.getDestinationHost()
                /* DEBUG */+ ":" + tunnel.getDestinationPort());
            }
        }

        public void stopped(VPNTunnel tunnel) {
            synchronized (activeTunnels) {
                activeTunnels.removeElement(tunnel);
                vpn.unregisterForwardingTunnel(tunnel);
                /* DEBUG */log.info("User on " + tunnel.getClientHost() +
                /* DEBUG */" has closed the tunnel to " + tunnel.getDestinationHost()
                /* DEBUG */+ ":" + tunnel.getDestinationPort());

                if (!VPNConnectionListener.this.tunnel.isPermanent()
                                && VPNConnectionListener.this.tunnel.isTemporarySingleConnect()) {
                    /* DEBUG */log.info("Closing listener as this is a temporary tunnel");
                    vpn.stopListeningSocket(getTicket());
                    thread = null;
                } else {
                    /* DEBUG */log.info("Not closing listener as this is not a temporary tunnel");
                }
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see com.sslexplorer.vpn.base.VPNTunnelListener#dataTransferred(com.sslexplorer.vpn.base.VPNTunnel,
         *      byte[], int)
         */
        public void dataTransferred(VPNTunnel tunnel, byte[] buffer, int count) {
            dataLastTransferred = System.currentTimeMillis();
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -