1092 lines
45 KiB
Java
1092 lines
45 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* com.tridium.nre.util.DeadlockUtil
|
|
* com.tridium.nre.util.Version
|
|
* com.tridium.sys.license.Brand
|
|
* com.tridium.sys.station.Station
|
|
* javax.baja.log.Log
|
|
* javax.baja.nre.util.Array
|
|
* javax.baja.security.AuditEvent
|
|
* javax.baja.security.Auditor
|
|
* javax.baja.sys.BObject
|
|
* javax.baja.sys.Context
|
|
* javax.baja.sys.Sys
|
|
* javax.baja.user.BUser
|
|
*/
|
|
package com.tridium.fox.session;
|
|
|
|
import com.tridium.fox.message.FoxMessage;
|
|
import com.tridium.fox.message.FoxString;
|
|
import com.tridium.fox.message.FoxTuple;
|
|
import com.tridium.fox.message.MessageReader;
|
|
import com.tridium.fox.message.MessageWriter;
|
|
import com.tridium.fox.session.Fox;
|
|
import com.tridium.fox.session.FoxAsyncCallbacks;
|
|
import com.tridium.fox.session.FoxBusyException;
|
|
import com.tridium.fox.session.FoxCircuit;
|
|
import com.tridium.fox.session.FoxConnection;
|
|
import com.tridium.fox.session.FoxFrame;
|
|
import com.tridium.fox.session.FoxRequest;
|
|
import com.tridium.fox.session.FoxResponse;
|
|
import com.tridium.fox.session.FoxsRedirectException;
|
|
import com.tridium.fox.session.InvalidChannelException;
|
|
import com.tridium.fox.session.InvalidCommandException;
|
|
import com.tridium.fox.session.SessionBedroom;
|
|
import com.tridium.fox.session.SessionCircuits;
|
|
import com.tridium.fox.session.SessionDispatcher;
|
|
import com.tridium.fox.session.SessionReceiver;
|
|
import com.tridium.fox.session.SessionSender;
|
|
import com.tridium.fox.session.TunnelReceiver;
|
|
import com.tridium.nre.util.DeadlockUtil;
|
|
import com.tridium.nre.util.Version;
|
|
import com.tridium.sys.license.Brand;
|
|
import com.tridium.sys.station.Station;
|
|
import java.io.BufferedInputStream;
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.net.Socket;
|
|
import java.util.Date;
|
|
import javax.baja.log.Log;
|
|
import javax.baja.nre.util.Array;
|
|
import javax.baja.security.AuditEvent;
|
|
import javax.baja.security.Auditor;
|
|
import javax.baja.sys.BObject;
|
|
import javax.baja.sys.Context;
|
|
import javax.baja.sys.Sys;
|
|
import javax.baja.user.BUser;
|
|
|
|
public class FoxSession {
|
|
private static Object idLock = new Object();
|
|
private static int nextId = 0;
|
|
static final String TUNNEL_AUTHORITY = "tunnelAuthority";
|
|
static final String FW_TUNNEL_AUTHORITY = "fwTunnelAuth";
|
|
static final String FW_STATION_TUNNEL_AUTHORITY = "fwSTunnelAuth";
|
|
static final int FW_FOX_SESSION_ID = 801;
|
|
static final int FW_STATION_FOX_SESSION_ID = 802;
|
|
public static final Integer NON_FW_FOX_SESSION = new Integer(-1);
|
|
public static final Integer FW_FOX_SESSION = new Integer(801);
|
|
public static final Integer FW_STATION_FOX_SESSION = new Integer(802);
|
|
public static final String STARTING = "starting";
|
|
public static final String RUNNING = "running";
|
|
public static final String CLOSING = "closing";
|
|
public static final String CLOSED = "closed";
|
|
private static FoxMessage emptyMessage = new FoxMessage();
|
|
private static Class SSLSocketClass = null;
|
|
public Object extra;
|
|
public Object sessionStateLock = new Object();
|
|
private int id;
|
|
private long connectTime;
|
|
private Socket socket;
|
|
private MessageReader in;
|
|
private MessageWriter out;
|
|
private boolean isServer;
|
|
private String string;
|
|
private Object sendLock = new Object();
|
|
private int localNextSequence;
|
|
private int remoteNextSequence;
|
|
private FoxMessage remoteHello;
|
|
private int remoteId;
|
|
private int readCount;
|
|
private int writtenCount;
|
|
private volatile long lastReadTicks;
|
|
private volatile long lastWriteTicks;
|
|
private volatile boolean isClosed;
|
|
private Throwable closeCause;
|
|
private String state = "<init>";
|
|
private SessionSender sender;
|
|
private SessionReceiver receiver;
|
|
private SessionDispatcher dispatcher;
|
|
private SessionBedroom bedroom;
|
|
private SessionCircuits circuits;
|
|
FoxConnection conn;
|
|
FoxMessage remoteWelcome;
|
|
private Socket tunnelSocket;
|
|
private MessageReader tunnelIn;
|
|
private MessageWriter tunnelOut;
|
|
private TunnelReceiver tunnelReceiver;
|
|
public static final IFoxSessionListener[] nullListeners;
|
|
private static volatile IFoxSessionListenerFactory[] listenerFactories;
|
|
private volatile IFoxSessionListener[] listeners = nullListeners;
|
|
public boolean promptForPasswordReset = true;
|
|
BUser user;
|
|
Context sessionContext;
|
|
public static Log deadlockLog;
|
|
private static Object deadlockReboot;
|
|
static /* synthetic */ Class class$com$tridium$fox$session$FoxSession;
|
|
static /* synthetic */ Class class$com$tridium$fox$session$FoxSession$IFoxSessionListenerFactory;
|
|
static /* synthetic */ Class class$com$tridium$fox$session$FoxSession$IFoxSessionListener;
|
|
|
|
public FoxSession(Socket socket, FoxConnection foxConnection) throws IOException {
|
|
this(socket, foxConnection, nullListeners);
|
|
this.initListeners();
|
|
}
|
|
|
|
public FoxSession(Socket socket, FoxConnection foxConnection, IFoxSessionListener[] iFoxSessionListenerArray) throws IOException {
|
|
this.id = FoxSession.nextId();
|
|
this.conn = foxConnection;
|
|
this.socket = socket;
|
|
this.isServer = foxConnection == null || foxConnection.isTunnelServerConnection();
|
|
this.connectTime = System.currentTimeMillis();
|
|
this.in = new MessageReader(new BufferedInputStream(socket.getInputStream()));
|
|
this.out = new MessageWriter(new BufferedOutputStream(socket.getOutputStream()));
|
|
this.localNextSequence = this.isServer ? 0 : 1;
|
|
this.remoteNextSequence = this.isServer ? 1 : 0;
|
|
this.sender = new SessionSender(this);
|
|
this.receiver = new SessionReceiver(this);
|
|
this.dispatcher = new SessionDispatcher(this);
|
|
this.bedroom = new SessionBedroom();
|
|
this.circuits = new SessionCircuits(this);
|
|
this.lastReadTicks = Fox.clock.ticks();
|
|
this.lastWriteTicks = Fox.clock.ticks();
|
|
socket.setSoTimeout(Fox.soTimeout);
|
|
socket.setTcpNoDelay(Fox.tcpNoDelay);
|
|
StringBuffer stringBuffer = new StringBuffer();
|
|
stringBuffer.append(this.id).append(": ").append(this.isServer ? "Server " : "Client ");
|
|
if (!this.isServer) {
|
|
stringBuffer.append(socket.getLocalPort()).append("->");
|
|
}
|
|
stringBuffer.append(this.getRemoteHost()).append(':').append(this.getRemotePort());
|
|
this.string = stringBuffer.toString();
|
|
this.listeners = iFoxSessionListenerArray;
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
private static int nextId() {
|
|
Object object = idLock;
|
|
synchronized (object) {
|
|
return nextId++;
|
|
}
|
|
}
|
|
|
|
public int getId() {
|
|
return this.id;
|
|
}
|
|
|
|
public String getRemoteHost() {
|
|
return this.socket.getInetAddress().getHostAddress();
|
|
}
|
|
|
|
public int getRemotePort() {
|
|
return this.socket.getPort();
|
|
}
|
|
|
|
public FoxMessage getRemoteHello() {
|
|
return this.remoteHello;
|
|
}
|
|
|
|
public FoxMessage getRemoteWelcome() {
|
|
return this.remoteWelcome;
|
|
}
|
|
|
|
public int getRemoteId() {
|
|
return this.remoteId;
|
|
}
|
|
|
|
public FoxConnection conn() {
|
|
return this.conn;
|
|
}
|
|
|
|
public boolean isServer() {
|
|
return this.isServer;
|
|
}
|
|
|
|
public boolean isClosed() {
|
|
return this.isClosed;
|
|
}
|
|
|
|
public long getConnectTime() {
|
|
return this.connectTime;
|
|
}
|
|
|
|
public int getFramesReadCount() {
|
|
return this.readCount;
|
|
}
|
|
|
|
public int getFramesWrittenCount() {
|
|
return this.writtenCount;
|
|
}
|
|
|
|
public long getLastReadTicks() {
|
|
return this.lastReadTicks;
|
|
}
|
|
|
|
public long getLastWriteTicks() {
|
|
return this.lastWriteTicks;
|
|
}
|
|
|
|
public final String getState() {
|
|
return this.state;
|
|
}
|
|
|
|
public final String toString() {
|
|
return this.string;
|
|
}
|
|
|
|
public final BUser getUser() {
|
|
return this.user;
|
|
}
|
|
|
|
public final void setUser(BUser bUser) {
|
|
this.user = bUser;
|
|
}
|
|
|
|
public final Context getSessionContext() {
|
|
return this.sessionContext;
|
|
}
|
|
|
|
public final void setSessionContext(Context context) {
|
|
this.sessionContext = context;
|
|
}
|
|
|
|
public final void start() {
|
|
this.initListeners();
|
|
this.setState(STARTING);
|
|
this.conn.sessionOpened(this);
|
|
this.receiver.start();
|
|
if (this.conn() == null || !this.conn().isTunnelServerConnection()) {
|
|
this.sender.start();
|
|
this.dispatcher.start();
|
|
}
|
|
this.setState(RUNNING);
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
public final void close(Throwable throwable) {
|
|
Object object;
|
|
if (this.isClosed) {
|
|
return;
|
|
}
|
|
this.setState(CLOSING, throwable);
|
|
this.isClosed = true;
|
|
this.sender.kill();
|
|
this.receiver.kill();
|
|
this.dispatcher.kill();
|
|
this.bedroom.wakeAll();
|
|
this.circuits.kill();
|
|
if (this.tunnelReceiver != null) {
|
|
this.tunnelReceiver.kill();
|
|
this.tunnelReceiver = null;
|
|
}
|
|
long l = Fox.clock.ticks();
|
|
boolean bl = false;
|
|
while (this.sender.isRunning()) {
|
|
if (Fox.clock.ticks() - l >= Fox.sessionCloseTimeout) {
|
|
bl = true;
|
|
break;
|
|
}
|
|
object = this.sessionStateLock;
|
|
synchronized (object) {
|
|
try {
|
|
this.sessionStateLock.wait(200L);
|
|
}
|
|
catch (InterruptedException interruptedException) {
|
|
// empty catch block
|
|
}
|
|
}
|
|
}
|
|
if (this.tunnelSocket != null) {
|
|
try {
|
|
this.tunnelSocket.close();
|
|
}
|
|
catch (Exception exception) {
|
|
// empty catch block
|
|
}
|
|
this.tunnelSocket = null;
|
|
}
|
|
if (!bl) {
|
|
try {
|
|
this.socket.close();
|
|
}
|
|
catch (Exception exception) {}
|
|
} else {
|
|
object = new Version(System.getProperty("java.version"));
|
|
if (object.compareTo((Object)"1.6") >= 0) {
|
|
try {
|
|
DeadlockUtil deadlockUtil = DeadlockUtil.getInstance();
|
|
deadlockLog.trace("looking for a deadlock for session " + this.id);
|
|
if (deadlockUtil.countDeadlocksByThreadName(new String[]{"Fox:Sender:" + this.id, "Fox:Receiver:" + this.id}) > 0) {
|
|
deadlockLog.warning("found a matching deadlock for session " + this.id);
|
|
deadlockLog.warning("fox deadlocked thread count at " + ++Fox.deadlocks);
|
|
int n = Integer.parseInt(System.getProperty("niagara.fox.maxDeadlockedThreads", "-1"));
|
|
if (n > 0 && Fox.deadlocks >= n) {
|
|
deadlockLog.message("requesting station stop");
|
|
new Thread(){
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
public void run() {
|
|
Object object = deadlockReboot;
|
|
synchronized (object) {
|
|
try {
|
|
Auditor auditor = Sys.getAuditor();
|
|
if (auditor != null) {
|
|
auditor.audit(new AuditEvent("Shutdown", "FoxDeadlockCount", String.valueOf(Fox.deadlocks), "", "", ""));
|
|
}
|
|
}
|
|
catch (Throwable throwable) {
|
|
throwable.printStackTrace();
|
|
}
|
|
try {
|
|
Station.saveSync();
|
|
Station.shutdown((boolean)false);
|
|
System.exit(-1);
|
|
}
|
|
catch (Exception exception) {
|
|
deadlockLog.error("unable to save and stop station", (Throwable)exception);
|
|
}
|
|
}
|
|
}
|
|
}.start();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exception) {
|
|
deadlockLog.error("Unable to process deadlock check", (Throwable)exception);
|
|
}
|
|
}
|
|
}
|
|
Fox.unregister(this);
|
|
object = this.sessionStateLock;
|
|
synchronized (object) {
|
|
if (this.conn != null) {
|
|
this.conn.sessionClosed(this, throwable);
|
|
}
|
|
}
|
|
this.setState(CLOSED, throwable);
|
|
this.listeners = nullListeners;
|
|
this.user = null;
|
|
this.sessionContext = null;
|
|
}
|
|
|
|
public Object getSessionStateLock() {
|
|
return this.sessionStateLock;
|
|
}
|
|
|
|
void sendHello(String string) throws Exception {
|
|
FoxMessage foxMessage = this.initHello(null, string, this.id, false);
|
|
this.sendTuning("hello", foxMessage);
|
|
}
|
|
|
|
void sendRedirect(int n) throws Exception {
|
|
FoxMessage foxMessage = new FoxMessage();
|
|
foxMessage.add("port", n);
|
|
this.sendTuning("redirect", foxMessage);
|
|
}
|
|
|
|
FoxMessage initHello(FoxMessage foxMessage, String string, int n, boolean bl) throws Exception {
|
|
boolean bl2 = foxMessage != null;
|
|
FoxMessage foxMessage2 = new FoxMessage();
|
|
if (bl2 && bl) {
|
|
try {
|
|
foxMessage2.add("brandId", Brand.getBrandId());
|
|
}
|
|
catch (Exception exception) {}
|
|
} else if (!bl2) {
|
|
foxMessage2.add("fox.version", "1.0.1");
|
|
foxMessage2.add("id", n);
|
|
if (string != null) {
|
|
foxMessage2.add("user", string);
|
|
}
|
|
foxMessage2.add("hostName", Fox.hostName);
|
|
foxMessage2.add("hostAddress", Fox.hostAddress);
|
|
foxMessage2.add("app.name", Fox.appName);
|
|
foxMessage2.add("app.version", Fox.appVersion);
|
|
foxMessage2.add("vm.name", Fox.vmName);
|
|
foxMessage2.add("vm.version", Fox.vmVersion);
|
|
foxMessage2.add("os.name", Fox.osName);
|
|
foxMessage2.add("os.version", Fox.osVersion);
|
|
this.conn.initHello(foxMessage2);
|
|
}
|
|
if (bl2) {
|
|
for (int i = 0; i < foxMessage.count; ++i) {
|
|
String string2 = foxMessage.tuples[i].name;
|
|
if (foxMessage2.getOptional(string2) != null || string2.equals("brandId")) continue;
|
|
foxMessage2.add(foxMessage.tuples[i]);
|
|
}
|
|
}
|
|
return foxMessage2;
|
|
}
|
|
|
|
boolean receiveHello() throws Exception {
|
|
FoxFrame foxFrame = this.readFrame();
|
|
if (foxFrame == null) {
|
|
if (this.tunnelSocket != null) {
|
|
StringBuffer stringBuffer = new StringBuffer();
|
|
stringBuffer.append(this.id).append(": ").append("Tunnel ");
|
|
stringBuffer.append(this.tunnelSocket.getLocalPort()).append("->");
|
|
stringBuffer.append(this.tunnelSocket.getInetAddress().getHostAddress());
|
|
stringBuffer.append(':').append(this.tunnelSocket.getPort());
|
|
this.string = stringBuffer.toString();
|
|
}
|
|
return false;
|
|
}
|
|
if (foxFrame.channel != "fox") {
|
|
throw new InvalidChannelException("Expecting 'fox', not '" + foxFrame.channel + "'");
|
|
}
|
|
if (foxFrame.command != "hello") {
|
|
if (foxFrame.command == "redirect") {
|
|
throw new FoxsRedirectException(foxFrame.message.getInt("port"));
|
|
}
|
|
if (foxFrame.command == "busy") {
|
|
throw new FoxBusyException();
|
|
}
|
|
throw new InvalidCommandException("Expecting 'hello', not '" + foxFrame.command + "'");
|
|
}
|
|
if (foxFrame.replyNumber != -1) {
|
|
throw new IOException("Invalid reply number " + foxFrame.replyNumber);
|
|
}
|
|
this.remoteHello = foxFrame.message;
|
|
FoxMessage foxMessage = this.remoteHello;
|
|
String string = foxMessage.getString("fox.version");
|
|
if (!string.startsWith("1.0")) {
|
|
throw new IOException("Unsupported fox.version '" + string + "'");
|
|
}
|
|
this.remoteId = foxMessage.getInt("id");
|
|
return true;
|
|
}
|
|
|
|
public final void sendTuning(String string, FoxMessage foxMessage) throws Exception {
|
|
this.writeFrame(new FoxFrame(97, this.localNextSequence++, -1, "fox", string, foxMessage));
|
|
}
|
|
|
|
void sendBusy() throws Exception {
|
|
this.writeFrame(new FoxFrame(101, this.localNextSequence++, -1, "fox", "busy", new FoxMessage()));
|
|
}
|
|
|
|
public final FoxMessage receiveTuning(String string) throws Exception {
|
|
FoxFrame foxFrame = this.readFrame();
|
|
if (foxFrame.channel != "fox") {
|
|
throw new InvalidChannelException("Expecting 'fox', not '" + foxFrame.channel + "'");
|
|
}
|
|
if (string != null && foxFrame.command != string) {
|
|
throw new InvalidCommandException("Expecting '" + string + "', not '" + foxFrame.command + "'");
|
|
}
|
|
return foxFrame.message;
|
|
}
|
|
|
|
public final FoxCircuit openCircuit(String string, String string2) throws Exception {
|
|
FoxCircuit foxCircuit = this.circuits.alloc(string, string2);
|
|
try {
|
|
foxCircuit.sendOpen();
|
|
return foxCircuit;
|
|
}
|
|
catch (Exception exception) {
|
|
this.closeCircuit(foxCircuit);
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
void closeCircuit(FoxCircuit foxCircuit) {
|
|
try {
|
|
foxCircuit.sendClose();
|
|
}
|
|
catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
}
|
|
this.circuits.free(foxCircuit);
|
|
}
|
|
|
|
public final FoxResponse sendSync(FoxRequest foxRequest) throws Exception {
|
|
if (this.isClosed) {
|
|
throw new IOException("Session closed");
|
|
}
|
|
SessionBedroom.Bed bed = this.bedroom.getBed(Thread.currentThread());
|
|
this.send(115, bed.replyNumber, foxRequest.channel, foxRequest.command, foxRequest, null);
|
|
this.bedroom.sleep(bed);
|
|
FoxFrame foxFrame = bed.reply;
|
|
if (foxFrame == null) {
|
|
IOException iOException = new IOException("Request timed out: " + foxRequest.channel + "." + foxRequest.command);
|
|
this.close(iOException);
|
|
throw iOException;
|
|
}
|
|
if (foxFrame.frameType == 114) {
|
|
return (FoxResponse)foxFrame.message;
|
|
}
|
|
if (foxFrame.frameType == 110) {
|
|
return null;
|
|
}
|
|
if (bed.reply.frameType == 101) {
|
|
throw Fox.exceptionTranslator.messageToException(foxFrame.message);
|
|
}
|
|
IOException iOException = new IOException("Invalid reply frame type: " + (char)foxFrame.frameType);
|
|
this.close(iOException);
|
|
throw iOException;
|
|
}
|
|
|
|
public final void sendAsync(FoxRequest foxRequest) throws Exception {
|
|
this.sendAsync(foxRequest, null);
|
|
}
|
|
|
|
public final void sendAsync(FoxRequest foxRequest, FoxAsyncCallbacks foxAsyncCallbacks) throws Exception {
|
|
if (this.isClosed) {
|
|
throw new IOException("Session closed");
|
|
}
|
|
this.send(97, -1, foxRequest.channel, foxRequest.command, foxRequest, foxAsyncCallbacks);
|
|
}
|
|
|
|
final void sendReply(FoxFrame foxFrame, FoxMessage foxMessage) throws InterruptedException {
|
|
if (foxFrame.replyNumber == -1) {
|
|
return;
|
|
}
|
|
if (foxMessage == null) {
|
|
this.send(110, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, emptyMessage, null);
|
|
} else {
|
|
this.send(114, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, foxMessage, null);
|
|
}
|
|
}
|
|
|
|
final void sendError(FoxFrame foxFrame, Throwable throwable) throws InterruptedException {
|
|
if (foxFrame == null || foxFrame.replyNumber == -1) {
|
|
return;
|
|
}
|
|
FoxMessage foxMessage = Fox.exceptionTranslator.exceptionToMessage(throwable);
|
|
this.send(101, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, foxMessage, null);
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
private void send(int n, int n2, String string, String string2, FoxMessage foxMessage, FoxAsyncCallbacks foxAsyncCallbacks) throws InterruptedException {
|
|
Object object = this.sendLock;
|
|
synchronized (object) {
|
|
int n3 = this.localNextSequence;
|
|
this.localNextSequence = (this.localNextSequence + 1) % Integer.MAX_VALUE;
|
|
FoxFrame foxFrame = new FoxFrame(n, n3, n2, string, string2, foxMessage);
|
|
foxFrame.callbacks = foxAsyncCallbacks;
|
|
this.sender.enqueue(foxFrame);
|
|
}
|
|
}
|
|
|
|
void requestReceived(FoxFrame foxFrame) throws InterruptedException {
|
|
try {
|
|
if (foxFrame.channel == "circuit") {
|
|
this.circuits.circuitRequestReceived(foxFrame);
|
|
} else {
|
|
this.dispatcher.enqueue(foxFrame);
|
|
}
|
|
}
|
|
catch (Throwable throwable) {
|
|
this.conn.error("Error in request", throwable);
|
|
throwable.printStackTrace();
|
|
foxFrame.dump();
|
|
this.sendError(foxFrame, throwable);
|
|
}
|
|
}
|
|
|
|
void replyReceived(FoxFrame foxFrame) {
|
|
block2: {
|
|
try {
|
|
this.bedroom.wake(foxFrame);
|
|
}
|
|
catch (Throwable throwable) {
|
|
if (this.isClosed) break block2;
|
|
this.conn.error("Error in reply " + foxFrame.replyNumber, throwable);
|
|
throwable.printStackTrace();
|
|
foxFrame.dump();
|
|
}
|
|
}
|
|
}
|
|
|
|
FoxResponse processFoxChannelRequest(FoxRequest foxRequest) {
|
|
String string = foxRequest.command;
|
|
if (string == "ping") {
|
|
return this.ping(foxRequest);
|
|
}
|
|
throw new InvalidCommandException("fox." + string);
|
|
}
|
|
|
|
public void ping() throws Exception {
|
|
this.sendSync(new FoxRequest("fox", "ping"));
|
|
}
|
|
|
|
private FoxResponse ping(FoxRequest foxRequest) {
|
|
return new FoxResponse(foxRequest);
|
|
}
|
|
|
|
public final void setState(String string) {
|
|
this.setState(string, null);
|
|
}
|
|
|
|
public final void setState(String string, Throwable throwable) {
|
|
this.state = string;
|
|
if (Fox.traceSessionStates) {
|
|
System.out.println("-- Fox [" + this.id + "] STATE " + string);
|
|
}
|
|
if (this.listeners != nullListeners) {
|
|
IFoxSessionListener[] iFoxSessionListenerArray = this.listeners;
|
|
for (int i = 0; i < iFoxSessionListenerArray.length; ++i) {
|
|
iFoxSessionListenerArray[i].stateChanged(this, string, throwable);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void spy(PrintWriter printWriter) throws Exception {
|
|
printWriter.print("<table border='0' cellspacing='0'>");
|
|
printWriter.print("<tr><th colspan='2' bgcolor='#d0d0d0'>");
|
|
printWriter.print(this.string);
|
|
printWriter.print("</th></tr>\n");
|
|
this.dumpProps(printWriter);
|
|
printWriter.print("</table>\n");
|
|
}
|
|
|
|
public void dumpProps(PrintWriter printWriter) throws Exception {
|
|
ByteArrayOutputStream byteArrayOutputStream;
|
|
this.dump(printWriter, (Object)"id", this.id);
|
|
this.dump(printWriter, (Object)"state", this.state);
|
|
this.dump(printWriter, (Object)"connectTime", new Date(this.connectTime));
|
|
this.dump(printWriter, (Object)"remoteId", this.remoteId);
|
|
this.dump(printWriter, (Object)"readCount", this.readCount);
|
|
this.dump(printWriter, (Object)"lastRead", Fox.clock.ticks() - this.lastReadTicks + "ms");
|
|
this.dump(printWriter, (Object)"writtenCount", this.writtenCount);
|
|
this.dump(printWriter, (Object)"lastWrite", Fox.clock.ticks() - this.lastWriteTicks + "ms");
|
|
this.dump(printWriter, (Object)"isClosed", this.isClosed);
|
|
this.dump(printWriter, (Object)"closeCause", this.closeCause);
|
|
this.dump(printWriter, (Object)"socket", this.socket);
|
|
this.dump(printWriter, (Object)"sender", this.sender);
|
|
this.dump(printWriter, (Object)"receiver", this.receiver);
|
|
this.dump(printWriter, (Object)"dispatcher", this.dispatcher);
|
|
this.dump(printWriter, (Object)"bedroom", this.bedroom);
|
|
this.dump(printWriter, (Object)"circuits", "<pre>" + this.circuits + "</pre>");
|
|
if (this.remoteHello != null) {
|
|
byteArrayOutputStream = new ByteArrayOutputStream();
|
|
byteArrayOutputStream.write("<pre>".getBytes());
|
|
this.remoteHello.dump(byteArrayOutputStream);
|
|
byteArrayOutputStream.write("</pre>".getBytes());
|
|
this.dump(printWriter, (Object)"remoteHello", new String(byteArrayOutputStream.toByteArray()));
|
|
}
|
|
if (this.remoteWelcome != null) {
|
|
byteArrayOutputStream = new ByteArrayOutputStream();
|
|
byteArrayOutputStream.write("<pre>".getBytes());
|
|
this.remoteWelcome.dump(byteArrayOutputStream);
|
|
byteArrayOutputStream.write("</pre>".getBytes());
|
|
this.dump(printWriter, (Object)"remoteWelcome", new String(byteArrayOutputStream.toByteArray()));
|
|
}
|
|
this.dump(printWriter, (Object)"tunnelSocket", this.tunnelSocket);
|
|
this.dump(printWriter, (Object)"tunnelReceiver", this.tunnelReceiver);
|
|
this.dump(printWriter, (Object)"fwConnType", this.fwConnType(null));
|
|
}
|
|
|
|
private void dump(PrintWriter printWriter, Object object, boolean bl) {
|
|
this.dump(printWriter, object, String.valueOf(bl));
|
|
}
|
|
|
|
private void dump(PrintWriter printWriter, Object object, int n) {
|
|
this.dump(printWriter, object, String.valueOf(n));
|
|
}
|
|
|
|
private void dump(PrintWriter printWriter, Object object, Object object2) {
|
|
printWriter.print("<tr><th align='left'>");
|
|
printWriter.print(object);
|
|
printWriter.print("</th><td align='left' nowrap='true'>");
|
|
printWriter.print(object2);
|
|
printWriter.print("</td></tr>\n");
|
|
}
|
|
|
|
public void dump() {
|
|
System.out.println("id: " + this.id);
|
|
System.out.println("state: " + this.state);
|
|
System.out.println("connectTime: " + new Date(this.connectTime));
|
|
System.out.println("remoteId: " + this.remoteId);
|
|
System.out.println("readCount: " + this.readCount);
|
|
System.out.println("lastRead: " + (Fox.clock.ticks() - this.lastReadTicks) + "ms");
|
|
System.out.println("writtenCount: " + this.writtenCount);
|
|
System.out.println("lastWrite: " + (Fox.clock.ticks() - this.lastWriteTicks) + "ms");
|
|
System.out.println("isClosed: " + this.isClosed);
|
|
System.out.println("closeCause: " + this.closeCause);
|
|
System.out.println("socket: " + this.socket);
|
|
System.out.println("sender: " + this.sender);
|
|
System.out.println("receiver: " + this.receiver);
|
|
System.out.println("dispatcher: " + this.dispatcher);
|
|
System.out.println("bedroom: " + this.bedroom);
|
|
System.out.println("circuits: " + this.circuits);
|
|
System.out.println("tunnelSocket " + this.tunnelSocket);
|
|
System.out.println("tunnelRcvr " + this.tunnelReceiver);
|
|
System.out.println("fwConnType " + this.fwConnType(null));
|
|
}
|
|
|
|
FoxFrame readFrame() throws IOException {
|
|
FoxFrame foxFrame;
|
|
do {
|
|
foxFrame = FoxFrame.read(this.in);
|
|
++this.readCount;
|
|
this.lastReadTicks = Fox.clock.ticks();
|
|
if (this.conn == null || !this.conn.isTunnelServerConnection()) continue;
|
|
try {
|
|
if (this.rerouteTunnelFrame(foxFrame)) {
|
|
return null;
|
|
}
|
|
}
|
|
catch (Exception exception) {
|
|
throw new IOException(exception.toString());
|
|
}
|
|
} while (foxFrame.frameType == 107);
|
|
if (foxFrame.sequenceNumber != this.remoteNextSequence) {
|
|
throw new IOException("Invalid sequence number " + foxFrame.sequenceNumber + " expecting " + this.remoteNextSequence);
|
|
}
|
|
this.remoteNextSequence = (this.remoteNextSequence + 1) % Integer.MAX_VALUE;
|
|
if (Fox.traceReadFrame) {
|
|
System.out.print("-- Fox [" + this.id + "] READ ");
|
|
foxFrame.dump();
|
|
}
|
|
if (this.listeners != nullListeners) {
|
|
IFoxSessionListener[] iFoxSessionListenerArray = this.listeners;
|
|
FoxFrame foxFrame2 = foxFrame;
|
|
if (foxFrame.channel == "fox" && foxFrame.command == "login") {
|
|
foxFrame2 = new FoxFrame(foxFrame.frameType, foxFrame.sequenceNumber, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, emptyMessage);
|
|
}
|
|
for (int i = 0; i < iFoxSessionListenerArray.length; ++i) {
|
|
iFoxSessionListenerArray[i].readFrame(this, foxFrame2);
|
|
}
|
|
}
|
|
return foxFrame;
|
|
}
|
|
|
|
void writeFrame(FoxFrame foxFrame) throws IOException {
|
|
this.encodeTunnelAuthority(foxFrame);
|
|
if (Fox.traceWriteFrame) {
|
|
System.out.print("-- Fox [" + this.id + "] WRITE ");
|
|
foxFrame.dump();
|
|
}
|
|
if (this.listeners != nullListeners) {
|
|
IFoxSessionListener[] iFoxSessionListenerArray = this.listeners;
|
|
FoxFrame foxFrame2 = foxFrame;
|
|
if (foxFrame.channel == "fox" && foxFrame.command == "login") {
|
|
foxFrame2 = new FoxFrame(foxFrame.frameType, foxFrame.sequenceNumber, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, emptyMessage);
|
|
}
|
|
for (int i = 0; i < iFoxSessionListenerArray.length; ++i) {
|
|
iFoxSessionListenerArray[i].writeFrame(this, foxFrame2);
|
|
}
|
|
}
|
|
++this.writtenCount;
|
|
this.lastWriteTicks = Fox.clock.ticks();
|
|
foxFrame.write(this.out);
|
|
this.out.flush();
|
|
if (foxFrame.callbacks != null) {
|
|
foxFrame.callbacks.asyncMessageSent(this, foxFrame.message);
|
|
}
|
|
}
|
|
|
|
boolean rerouteTunnelFrame(FoxFrame foxFrame) throws Exception {
|
|
FoxMessage foxMessage = foxFrame.message;
|
|
String string = TUNNEL_AUTHORITY;
|
|
String[] stringArray = foxMessage.listStrings(string);
|
|
Integer n = NON_FW_FOX_SESSION;
|
|
if (stringArray == null || stringArray.length < 1) {
|
|
string = FW_TUNNEL_AUTHORITY;
|
|
stringArray = foxMessage.listStrings(string);
|
|
n = FW_FOX_SESSION;
|
|
if (stringArray == null || stringArray.length < 1) {
|
|
string = FW_STATION_TUNNEL_AUTHORITY;
|
|
stringArray = foxMessage.listStrings(string);
|
|
n = FW_STATION_FOX_SESSION;
|
|
}
|
|
}
|
|
if (stringArray != null && stringArray.length > 0) {
|
|
int n2;
|
|
this.fwConnType(n);
|
|
if (n == -1 && !Fox.tunnelingEnabled) {
|
|
throw new IOException("Received a fox tunneling request while fox tunneling is disabled. Fox tunneling must be enabled to process the fox request.");
|
|
}
|
|
String string2 = stringArray[stringArray.length - 1];
|
|
FoxTuple[] foxTupleArray = new FoxTuple[foxMessage.tuples.length];
|
|
boolean bl = false;
|
|
int n3 = 0;
|
|
for (n2 = foxMessage.count - 1; n2 >= 0; --n2) {
|
|
if (!bl && string.equals(foxMessage.tuples[n2].name) && foxMessage.tuples[n2] instanceof FoxString && string2.equals(((FoxString)foxMessage.tuples[n2]).value)) {
|
|
bl = true;
|
|
continue;
|
|
}
|
|
foxTupleArray[foxMessage.count - 2 - n3] = foxMessage.tuples[n2];
|
|
++n3;
|
|
}
|
|
foxMessage.count = n3;
|
|
foxMessage.tuples = foxTupleArray;
|
|
if (this.tunnelSocket == null) {
|
|
n2 = 0;
|
|
try {
|
|
if (SSLSocketClass.isAssignableFrom(this.socket.getClass())) {
|
|
n2 = 1;
|
|
}
|
|
}
|
|
catch (Exception exception) {
|
|
// empty catch block
|
|
}
|
|
this.tunnelSocket = this.conn.createTunnelSocket(string2, n2 != 0);
|
|
this.tunnelIn = new MessageReader(new BufferedInputStream(this.tunnelSocket.getInputStream()));
|
|
this.tunnelOut = new MessageWriter(new BufferedOutputStream(this.tunnelSocket.getOutputStream()));
|
|
this.tunnelSocket.setSoTimeout(Fox.soTimeout);
|
|
this.tunnelSocket.setTcpNoDelay(Fox.tcpNoDelay);
|
|
this.tunnelReceiver = new TunnelReceiver(this);
|
|
this.tunnelReceiver.start();
|
|
}
|
|
this.writeTunnelFrame(foxFrame);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void encodeTunnelAuthority(FoxFrame foxFrame) {
|
|
String[] stringArray;
|
|
if (this.conn != null && this.conn.isTunnelClientConnection() && (stringArray = this.conn.getTunnelAuthorities()) != null && stringArray.length > 0) {
|
|
String string = TUNNEL_AUTHORITY;
|
|
switch (this.fwConnType(null)) {
|
|
case 801: {
|
|
string = FW_TUNNEL_AUTHORITY;
|
|
break;
|
|
}
|
|
case 802: {
|
|
string = FW_STATION_TUNNEL_AUTHORITY;
|
|
break;
|
|
}
|
|
}
|
|
FoxMessage foxMessage = foxFrame.message;
|
|
for (int i = stringArray.length - 1; i >= 0; --i) {
|
|
String string2 = stringArray[i];
|
|
if (string2 == null) continue;
|
|
foxMessage.add(string, string2);
|
|
}
|
|
}
|
|
}
|
|
|
|
FoxFrame readTunnelFrame() throws IOException {
|
|
Object object;
|
|
Object object2;
|
|
Integer n = this.fwConnType(null);
|
|
if (n == -1 && !Fox.tunnelingEnabled) {
|
|
throw new IOException("Attempted to read a fox tunnel frame while fox tunneling is disabled. Fox tunneling must be enabled to read the fox frame.");
|
|
}
|
|
FoxFrame foxFrame = null;
|
|
try {
|
|
foxFrame = FoxFrame.read(this.tunnelIn);
|
|
}
|
|
catch (IOException iOException) {
|
|
if (iOException.getClass().getName().equals("javax.net.ssl.SSLHandshakeException")) {
|
|
throw new IOException("SSLHandshakeException: " + iOException.getLocalizedMessage() + " \nCould not establish tunnel connection." + " \nPlease check the certificate management configuration on this proxy host (station '" + Sys.getStation().getStationName() + "'). \nYou might need to approve the target host (" + this.tunnelSocket.getInetAddress() + ") as an allowed host for encrypted communication.");
|
|
}
|
|
throw iOException;
|
|
}
|
|
if (n.intValue() == FW_STATION_FOX_SESSION.intValue() && foxFrame.channel == "fox" && foxFrame.command == "hello") {
|
|
try {
|
|
object2 = this.initHello(foxFrame.message, foxFrame.message.getString("user", null), foxFrame.message.getInt("id"), true);
|
|
object = foxFrame.callbacks;
|
|
FoxFrame foxFrame2 = foxFrame.next;
|
|
foxFrame = new FoxFrame(foxFrame.frameType, foxFrame.sequenceNumber, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, (FoxMessage)object2);
|
|
foxFrame.callbacks = object;
|
|
foxFrame.next = foxFrame2;
|
|
}
|
|
catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
}
|
|
}
|
|
if (Fox.traceReadFrame) {
|
|
System.out.print("-- Fox [" + this.id + "] TUNNEL READ ");
|
|
foxFrame.dump();
|
|
}
|
|
if (this.listeners != nullListeners) {
|
|
object2 = this.listeners;
|
|
object = foxFrame;
|
|
if (foxFrame.channel == "fox" && foxFrame.command == "login") {
|
|
object = new FoxFrame(foxFrame.frameType, foxFrame.sequenceNumber, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, emptyMessage);
|
|
}
|
|
for (int i = 0; i < ((IFoxSessionListener[])object2).length; ++i) {
|
|
object2[i].readTunnelFrame(this, (FoxFrame)object);
|
|
}
|
|
}
|
|
return foxFrame;
|
|
}
|
|
|
|
void writeTunnelFrame(FoxFrame foxFrame) throws IOException {
|
|
Object object;
|
|
Object object2;
|
|
Integer n = this.fwConnType(null);
|
|
if (n == -1 && !Fox.tunnelingEnabled) {
|
|
throw new IOException("Attempted to write a fox tunnel frame while fox tunneling is disabled. Fox tunneling must be enabled to write the fox frame.");
|
|
}
|
|
if (n.intValue() == FW_STATION_FOX_SESSION.intValue() && foxFrame.channel == "fox" && foxFrame.command == "hello") {
|
|
try {
|
|
object2 = this.initHello(foxFrame.message, foxFrame.message.getString("user", null), foxFrame.message.getInt("id"), false);
|
|
object = foxFrame.callbacks;
|
|
FoxFrame foxFrame2 = foxFrame.next;
|
|
foxFrame = new FoxFrame(foxFrame.frameType, foxFrame.sequenceNumber, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, (FoxMessage)object2);
|
|
foxFrame.callbacks = object;
|
|
foxFrame.next = foxFrame2;
|
|
}
|
|
catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
}
|
|
}
|
|
if (Fox.traceWriteFrame) {
|
|
System.out.print("-- Fox [" + this.id + "] TUNNEL WRITE ");
|
|
foxFrame.dump();
|
|
}
|
|
if (this.listeners != nullListeners) {
|
|
object2 = this.listeners;
|
|
object = foxFrame;
|
|
if (foxFrame.channel == "fox" && foxFrame.command == "login") {
|
|
object = new FoxFrame(foxFrame.frameType, foxFrame.sequenceNumber, foxFrame.replyNumber, foxFrame.channel, foxFrame.command, emptyMessage);
|
|
}
|
|
for (int i = 0; i < ((IFoxSessionListener[])object2).length; ++i) {
|
|
object2[i].writeTunnelFrame(this, (FoxFrame)object);
|
|
}
|
|
}
|
|
try {
|
|
foxFrame.write(this.tunnelOut);
|
|
this.tunnelOut.flush();
|
|
}
|
|
catch (IOException iOException) {
|
|
if (iOException.getClass().getName().equals("javax.net.ssl.SSLHandshakeException")) {
|
|
throw new IOException("SSLHandshakeException: " + iOException.getLocalizedMessage() + " \nCould not establish tunnel connection." + " \nPlease check the certificate management configuration on this proxy host (station '" + Sys.getStation().getStationName() + "'). \nYou might need to approve the target host (" + this.tunnelSocket.getInetAddress() + ") as an allowed host for encrypted communication.");
|
|
}
|
|
throw iOException;
|
|
}
|
|
}
|
|
|
|
private Integer fwConnType(Integer n) {
|
|
if (this.conn != null) {
|
|
try {
|
|
Object object;
|
|
if (this.conn instanceof BObject && (object = ((BObject)this.conn).fw(803, (Object)n, null, null, null)) instanceof Integer) {
|
|
return (Integer)object;
|
|
}
|
|
}
|
|
catch (Throwable throwable) {
|
|
throwable.printStackTrace();
|
|
}
|
|
}
|
|
return NON_FW_FOX_SESSION;
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
public static final void registerListenerFactory(IFoxSessionListenerFactory iFoxSessionListenerFactory) {
|
|
Object object;
|
|
if (class$com$tridium$fox$session$FoxSession == null) {
|
|
class$com$tridium$fox$session$FoxSession = FoxSession.class$("com.tridium.fox.session.FoxSession");
|
|
object = class$com$tridium$fox$session$FoxSession;
|
|
} else {
|
|
object = class$com$tridium$fox$session$FoxSession;
|
|
}
|
|
FoxSession[] foxSessionArray = object;
|
|
synchronized (object) {
|
|
Array array = new Array(class$com$tridium$fox$session$FoxSession$IFoxSessionListenerFactory == null ? (class$com$tridium$fox$session$FoxSession$IFoxSessionListenerFactory = FoxSession.class$("com.tridium.fox.session.FoxSession$IFoxSessionListenerFactory")) : class$com$tridium$fox$session$FoxSession$IFoxSessionListenerFactory);
|
|
array.addAll((Object[])listenerFactories);
|
|
if (!array.contains((Object)iFoxSessionListenerFactory)) {
|
|
array.add((Object)iFoxSessionListenerFactory);
|
|
listenerFactories = (IFoxSessionListenerFactory[])array.trim();
|
|
}
|
|
// ** MonitorExit[var1_1] (shouldn't be in output)
|
|
foxSessionArray = Fox.getSessions();
|
|
for (int i = 0; i < foxSessionArray.length; ++i) {
|
|
foxSessionArray[i].initListeners();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
public static final void unregisterListenerFactory(IFoxSessionListenerFactory iFoxSessionListenerFactory) {
|
|
Object object;
|
|
if (class$com$tridium$fox$session$FoxSession == null) {
|
|
class$com$tridium$fox$session$FoxSession = FoxSession.class$("com.tridium.fox.session.FoxSession");
|
|
object = class$com$tridium$fox$session$FoxSession;
|
|
} else {
|
|
object = class$com$tridium$fox$session$FoxSession;
|
|
}
|
|
FoxSession[] foxSessionArray = object;
|
|
synchronized (object) {
|
|
Array array = new Array(class$com$tridium$fox$session$FoxSession$IFoxSessionListenerFactory == null ? (class$com$tridium$fox$session$FoxSession$IFoxSessionListenerFactory = FoxSession.class$("com.tridium.fox.session.FoxSession$IFoxSessionListenerFactory")) : class$com$tridium$fox$session$FoxSession$IFoxSessionListenerFactory);
|
|
array.addAll((Object[])listenerFactories);
|
|
if (array.remove((Object)iFoxSessionListenerFactory)) {
|
|
listenerFactories = (IFoxSessionListenerFactory[])array.trim();
|
|
}
|
|
// ** MonitorExit[var1_1] (shouldn't be in output)
|
|
foxSessionArray = Fox.getSessions();
|
|
for (int i = 0; i < foxSessionArray.length; ++i) {
|
|
foxSessionArray[i].initListeners();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void initListeners() {
|
|
this.listeners = FoxSession.createListeners(this.conn);
|
|
}
|
|
|
|
public static final IFoxSessionListener[] createListeners(FoxConnection foxConnection) {
|
|
IFoxSessionListener[] iFoxSessionListenerArray = nullListeners;
|
|
IFoxSessionListenerFactory[] iFoxSessionListenerFactoryArray = listenerFactories;
|
|
if (iFoxSessionListenerFactoryArray.length > 0) {
|
|
Array array = null;
|
|
for (int i = 0; i < iFoxSessionListenerFactoryArray.length; ++i) {
|
|
IFoxSessionListener iFoxSessionListener = iFoxSessionListenerFactoryArray[i].make(foxConnection);
|
|
if (iFoxSessionListener == null) continue;
|
|
if (array == null) {
|
|
array = new Array(class$com$tridium$fox$session$FoxSession$IFoxSessionListener == null ? FoxSession.class$("com.tridium.fox.session.FoxSession$IFoxSessionListener") : class$com$tridium$fox$session$FoxSession$IFoxSessionListener);
|
|
}
|
|
array.add((Object)iFoxSessionListener);
|
|
}
|
|
if (array != null) {
|
|
iFoxSessionListenerArray = (IFoxSessionListener[])array.trim();
|
|
}
|
|
}
|
|
return iFoxSessionListenerArray;
|
|
}
|
|
|
|
public Socket getSocket() {
|
|
return this.socket;
|
|
}
|
|
|
|
static /* synthetic */ Class class$(String string) {
|
|
try {
|
|
return Class.forName(string);
|
|
}
|
|
catch (ClassNotFoundException classNotFoundException) {
|
|
throw new NoClassDefFoundError(classNotFoundException.getMessage());
|
|
}
|
|
}
|
|
|
|
static {
|
|
try {
|
|
SSLSocketClass = Class.forName("javax.net.ssl.SSLSocket");
|
|
}
|
|
catch (Exception exception) {
|
|
// empty catch block
|
|
}
|
|
nullListeners = new IFoxSessionListener[0];
|
|
listenerFactories = new IFoxSessionListenerFactory[0];
|
|
deadlockLog = Log.getLog((String)"fox.deadlockMonitor");
|
|
deadlockReboot = new Object();
|
|
}
|
|
|
|
public static interface IFoxSessionListener {
|
|
public void connectionAborted(String var1, Throwable var2);
|
|
|
|
public void stateChanged(FoxSession var1, String var2, Throwable var3);
|
|
|
|
public void readFrame(FoxSession var1, FoxFrame var2);
|
|
|
|
public void readTunnelFrame(FoxSession var1, FoxFrame var2);
|
|
|
|
public void writeFrame(FoxSession var1, FoxFrame var2);
|
|
|
|
public void writeTunnelFrame(FoxSession var1, FoxFrame var2);
|
|
}
|
|
|
|
public static interface IFoxSessionListenerFactory {
|
|
public IFoxSessionListener make(FoxConnection var1);
|
|
}
|
|
}
|
|
|