/** {@inheritDoc} */ @Override public void sessionClosed(IoSession session) throws Exception { String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID); log.debug("Session closed: {} id: {}", session.getId(), sessionId); if (log.isTraceEnabled()) { log.trace("Session attributes: {}", session.getAttributeKeys()); } if (sessionId != null) { RTMPMinaConnection conn = (RTMPMinaConnection) RTMPConnManager.getInstance().getConnectionBySessionId(sessionId); if (conn != null) { // fire-off closed event handler.connectionClosed(conn); // clear any session attributes we may have previously set // TODO: verify this cleanup code is necessary. The session is over and will be garbage // collected surely? if (session.containsAttribute(RTMPConnection.RTMP_HANDSHAKE)) { session.removeAttribute(RTMPConnection.RTMP_HANDSHAKE); } if (session.containsAttribute(RTMPConnection.RTMPE_CIPHER_IN)) { session.removeAttribute(RTMPConnection.RTMPE_CIPHER_IN); session.removeAttribute(RTMPConnection.RTMPE_CIPHER_OUT); } } else { log.warn("Connection was not found for {}", sessionId); } cleanSession(session, false); } else { log.debug("Connections session id was null in session, may already be closed"); } }
@Override public void encode(IoSession session, Object o, ProtocolEncoderOutput out) throws Exception { PacketBuilder message = (PacketBuilder) o; // Allocate a buffer of the exact size for the packet IoBuffer buffer = IoBuffer.allocate(Packet.HEADER_SIZE + message.size(), false); // Write the packet header int ordinal = message.getType().ordinal(); // If encryption is enabled, encrypt the packet type if (session.containsAttribute("encrypter")) { ISAACAlgorithm encrypter = (ISAACAlgorithm) session.getAttribute("encrypter"); ordinal += encrypter.nextInt(); } // Write the packet headers buffer.putInt(ordinal); buffer.putInt(message.size()); // Write the packet payload buffer.put(message.getPayload()); // Flip then output out.write(buffer.flip()); }
private WriteFuture initiateClosure(NextFilter nextFilter, IoSession session) throws SSLException { SslHandler handler = getSslSessionHandler(session); // if already shut down if (!handler.closeOutbound()) { return DefaultWriteFuture.newNotWrittenFuture( session, new IllegalStateException("SSL session is shut down already.")); } // there might be data to write out here? WriteFuture future = handler.writeNetBuffer(nextFilter); if (future == null) { future = DefaultWriteFuture.newWrittenFuture(session); } if (handler.isInboundDone()) { handler.destroy(); } if (session.containsAttribute(USE_NOTIFICATION)) { handler.scheduleMessageReceived(nextFilter, SESSION_UNSECURED); } return future; }
/** * Force the NioSession to be released and cleaned up. * * @param session */ private void forceClose(final IoSession session) { log.warn("Force close - session: {}", session.getId()); if (session.containsAttribute("FORCED_CLOSE")) { log.info("Close already forced on this session: {}", session.getId()); } else { // set flag session.setAttribute("FORCED_CLOSE", Boolean.TRUE); session.suspendRead(); cleanSession(session, true); } }
@Override public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws SSLException { boolean needsFlush = true; SslHandler handler = getSslSessionHandler(session); synchronized (handler) { if (!isSslStarted(session)) { handler.scheduleFilterWrite(nextFilter, writeRequest); } // Don't encrypt the data if encryption is disabled. else if (session.containsAttribute(DISABLE_ENCRYPTION_ONCE)) { // Remove the marker attribute because it is temporary. session.removeAttribute(DISABLE_ENCRYPTION_ONCE); handler.scheduleFilterWrite(nextFilter, writeRequest); } else { // Otherwise, encrypt the buffer. IoBuffer buf = (IoBuffer) writeRequest.getMessage(); if (handler.isWritingEncryptedData()) { // data already encrypted; simply return buffer handler.scheduleFilterWrite(nextFilter, writeRequest); } else if (handler.isHandshakeComplete()) { // SSL encrypt int pos = buf.position(); handler.encrypt(buf.buf()); buf.position(pos); IoBuffer encryptedBuffer = handler.fetchOutNetBuffer(); handler.scheduleFilterWrite( nextFilter, new EncryptedWriteRequest(writeRequest, encryptedBuffer)); } else { if (session.isConnected()) { // Handshake not complete yet. handler.schedulePreHandshakeWriteRequest(nextFilter, writeRequest); } needsFlush = false; } } } if (needsFlush) { handler.flushScheduledEvents(); } }