/*
* TurnServer, the OpenSource Java Solution for TURN protocol. Maintained by the
* Jitsi community (http://jitsi.org).
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.turnserver.stack;
import java.util.Arrays;
import java.util.logging.* ;
import org.ice4j.*;
import org.ice4j.message.*;
import org.ice4j.stack.*;
/**
* Class to handle incoming ChannelData messages coming from Client to Server.
* It first finds if there is a ChannelBind installed for the peer.
* If yes it then sends the UDP message to peer.
* If no it then silently ignores the message.
*
* @author Aakash Garg
*/
public class ServerChannelDataEventHandler implements
ChannelDataEventHandler {
/**
* The <tt>Logger</tt> used by the
* <tt>ServerChannelDataEventHandler</tt> class and its instances for
* logging output.
*/
private static final Logger logger = Logger
.getLogger(ServerChannelDataEventHandler.class.getName());
/**
* The turnStack to call.
*/
private TurnStack turnStack;
/**
* Default Constructor.
*/
public ServerChannelDataEventHandler()
{
}
/**
* Parametrized constructor.
* @param turnStack the turnStack to set for this class.
*/
public ServerChannelDataEventHandler(StunStack turnStack)
{
if (turnStack instanceof TurnStack)
{
this.turnStack = (TurnStack) turnStack;
}
else
{
throw new IllegalArgumentException("This is not a TurnStack!");
}
}
/**
* Sets the TurnStack for this class.
* @param turnStack the turnStack to set for this class.
*/
public void setTurnStack(TurnStack turnStack)
{
this.turnStack = turnStack;
}
/**
* Handles the ChannelDataMessageEvent.
* @param evt the ChannelDataMessageEvent to handle/process.
*/
@Override
public void handleMessageEvent(ChannelDataMessageEvent evt)
{
if(!logger.isLoggable(Level.FINER)){
logger.setLevel(Level.FINER);
}
ChannelData channelData = evt.getChannelDataMessage();
char channelNo = channelData.getChannelNumber();
byte[] data = channelData.getData();
logger.finer("Received a ChannelData message for " + (int)channelNo
+ " , message : " + Arrays.toString(data));
TransportAddress clientAddress = evt.getRemoteAddress();
TransportAddress serverAddress = evt.getLocalAddress();
Transport transport = Transport.UDP;
FiveTuple fiveTuple =
new FiveTuple(clientAddress, serverAddress, transport);
Allocation allocation
= this.turnStack.getServerAllocation(fiveTuple);
if(allocation==null)
{
logger.finer("allocation not found.");
}
else if(!allocation.containsChannel(channelNo))
{
logger.finer("ChannelNo " + (int) channelNo
+ " not found in Allocation!");
return;
}
TransportAddress destAddr = allocation.getPeerAddr(channelNo);
if(destAddr != null)
{
RawMessage message = RawMessage.build(data, data.length, destAddr,
allocation.getClientAddress());
try {
logger.finer("Dispatching a UDP message to " + destAddr
+ ", data: " + Arrays.toString(message.getBytes()));
this.turnStack.sendUdpMessage(message, destAddr,
allocation.getRelayAddress());
} catch (StunException e) {
logger.finer(e.getMessage());
}
}
else
{
logger.finer("Peer address not found for channel "
+ (int) channelNo);
}
}
}