diff --git a/src/main/java/tigase/io/TLSIO.java b/src/main/java/tigase/io/TLSIO.java /src/main/java/tigase/io/TLSIO.java @@ -74,6 +93,8 @@ public class TLSIO implements IOInterface { * protocol. */ private TLSWrapper tlsWrapper = null; + // Hot fix + private ByteBuffer closeSample = ByteBuffer.wrap("".getBytes("UTF-8")); // ~--- constructors --------------------------------------------------------- @@ -208,6 +229,16 @@ public class TLSIO implements IOInterface { return decodeData(tmpBuffer); } else { + if (tlsInput.capacity() > tlsWrapper.getAppBuffSize() && tlsInput.capacity() == tlsInput.remaining()) { + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "Resizing tlsInput to {0} bytes, {1}", new Object[] { tlsWrapper.getAppBuffSize(), toString() }); + } + ByteBuffer bb = ByteBuffer.allocate(tlsWrapper.getAppBuffSize()); + + bb.order(tlsInput.order()); + + tlsInput = bb; + } return null; } // end of else } @@ -470,6 +501,11 @@ public class TLSIO implements IOInterface { int loop_cnt = 0; int max_loop_runs = 100000; + // <<< Hotfix + int max_loop_runs_for_close_oper = 20; + boolean fl_need_check_close_detection = true; + // >>> Hotfix + do { if (tlsWrapper.getStatus() == TLSStatus.NEED_READ) { @@ -498,12 +534,35 @@ public class TLSIO implements IOInterface { new Object[] {buff.remaining(), toString() } ); } + // <<< Hotfix + // try detect close oper "" on dead connection and fix cpu overload + // if tls break we also repeat code by TLSStatus.NEED_READ + if (fl_need_check_close_detection /*performance*/)) { + if (max_loop_runs < max_loop_runs_for_close_oper) { + fl_need_check_close_detection = false; + } + else if (buff.position() > 0) { // have data + fl_need_check_close_detection = false; + } + else if (loop_cnt >= max_loop_runs_for_close_oper) { // need check "" + fl_need_check_close_detection = false; + boolean flCloseDetected = buff.equals(closeSample); + if (flCloseDetected) { + log.log(Level.WARNING, + "TLS CLOSE OPER detected (broken connection) io: {0}", toString()); + max_loop_runs = max_loop_runs_for_close_oper; + } + } + } + // >>> Hotfix } while (buff.hasRemaining() && (++loop_cnt < max_loop_runs)); if (loop_cnt > (max_loop_runs / 2)) { log.warning("Infinite loop detected in writeBuff(buff) TLS code, " + "tlsWrapper.getStatus(): " + tlsWrapper.getStatus() - + ", buff.remaining(): " + buff.remaining() + " io: " + toString() ); + + ", buff.remaining(): " + buff.remaining() + + ", buff.position(): " + buff.position() + + " io: " + toString() ); // Let's close the connection now throw new EOFException("Socket has been closed due to TLS problems.");