2026-03-17 13:31:18 -07:00

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);
}
}