All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.lastbamboo.common.turn.client.TurnLocalIoHandler Maven / Gradle / Ivy

package org.lastbamboo.common.turn.client;

import java.net.InetSocketAddress;
import java.util.Collection;

import org.littleshoot.stun.stack.message.turn.SendIndication;
import org.littleshoot.util.mina.MinaUtils;
import org.littleshoot.mina.common.ByteBuffer;
import org.littleshoot.mina.common.IdleStatus;
import org.littleshoot.mina.common.IoHandler;
import org.littleshoot.mina.common.IoHandlerAdapter;
import org.littleshoot.mina.common.IoSession;
import org.littleshoot.mina.util.SessionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * {@link IoHandler} for local sockets to the HTTP server. There is one
 * socket/session for each remote host we're exchanging data with. This
 * effectively mimics the remote host connecting directly to the local
 * HTTP server, with the data already extracted from the TURN messages and
 * forwarded along these sockets.

* * This class is also responsible for wrapping data from the HTTP server * in TURN Send Indication messages. */ public class TurnLocalIoHandler extends IoHandlerAdapter { private final Logger m_log = LoggerFactory.getLogger(getClass()); /** * This is the limit on the length of the data to encapsulate in a Send * Request. TURN messages cannot be larger than 0xffff, so this leaves * room for other attributes in the message as well as for headers. */ private static final int LENGTH_LIMIT = 0xffff - 1000; private final InetSocketAddress m_remoteAddress; private final IoSession m_ioSession; /** * Creates a new TURN local IO handler. * * @param ioSession The connection to the TURN server itself. * @param remoteAddress The remote host we're exchanging data with. */ public TurnLocalIoHandler( final IoSession ioSession, final InetSocketAddress remoteAddress) { m_ioSession = ioSession; m_remoteAddress = remoteAddress; } @Override public void messageReceived(final IoSession session, final Object message) { m_log.debug("Received local data message."); // This is data received from the local HTTP server -- // the raw data of an HTTP response. It might be // larger than the maximum allowed size for TURN messages, // so we make sure to split it up. final ByteBuffer in = (ByteBuffer) message; // Send the data broken up into chunks if necessary. This // is because TURN messages cannot be larger than 0xffff. sendSplitBuffers(in); } @Override public void messageSent(final IoSession session, final Object message) { m_log.debug("Sent local TURN message number: {}", session.getWrittenMessages()); } @Override public void sessionClosed(final IoSession session) { // Remember this is only a local "proxied" session. m_log.debug("Received **local** session closed!!"); } @Override public void sessionCreated(final IoSession session) { SessionUtil.initialize(session); // We consider a connection to be idle if there's been no // traffic in either direction for awhile. //session.setIdleTime(IdleStatus.BOTH_IDLE, 60 * 2); } @Override public void sessionIdle(final IoSession session, final IdleStatus status) throws Exception { // We close idle sessions to make sure we don't consume // too many client resources. // Note closing the session here will create the // appropriate event handlers to clean up all mappings // and references. session.close(); } @Override public void exceptionCaught(final IoSession session, final Throwable cause) { m_log.error("Error processing data for **local** session: "+ session, cause); } /** * Splits the main read buffer into smaller buffers that will * fit in TURN messages. * * @param remoteHost The host the data came from. * @param buffer The main read buffer to split. * @param session The session for reading and writing data. * @param nextFilter The next class for processing the message. */ private void sendSplitBuffers(final ByteBuffer buffer) { // Break up the data into smaller chunks. final Collection buffers = MinaUtils.splitToByteArrays(buffer, LENGTH_LIMIT); m_log.debug("Split single buffer into {}", buffers.size()); for (final byte[] data : buffers) { m_log.debug("Sending buffer with capacity: {}", data.length); //m_log.info("Sending bytes: {}", data); final SendIndication indication = new SendIndication(m_remoteAddress, data); m_ioSession.write(indication); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy