/* * 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 = ""; 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(""); printWriter.print("\n"); this.dumpProps(printWriter); printWriter.print("
"); printWriter.print(this.string); printWriter.print("
\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", "
" + this.circuits + "
"); if (this.remoteHello != null) { byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write("
".getBytes());
            this.remoteHello.dump(byteArrayOutputStream);
            byteArrayOutputStream.write("
".getBytes()); this.dump(printWriter, (Object)"remoteHello", new String(byteArrayOutputStream.toByteArray())); } if (this.remoteWelcome != null) { byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write("
".getBytes());
            this.remoteWelcome.dump(byteArrayOutputStream);
            byteArrayOutputStream.write("
".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(""); printWriter.print(object); printWriter.print(""); printWriter.print(object2); printWriter.print("\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); } }