📄 vpnconnectionlistener.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 + -