/* * 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.turnClient; import java.io.*; import java.net.*; import org.ice4j.*; import org.ice4j.attribute.*; import org.ice4j.message.*; import org.ice4j.socket.*; import org.ice4j.stack.*; import org.ice4j.stunclient.*; import org.jitsi.turnserver.collectors.*; import org.jitsi.turnserver.listeners.*; import org.jitsi.turnserver.stack.*; /** * Class to run Allocation Client over TCP. * * @author Aakash Garg * */ public class TurnTcpAllocationClient { private static BlockingRequestSender requestSender; private static IceTcpSocketWrapper sock; private static TurnStack turnStack; private static TransportAddress localAddress; private static TransportAddress serverAddress; private static boolean started; private static Socket tcpSocketToServer = null; /** * The instance that should be notified when an incoming TCP message has * been processed and ready for delivery */ private PeerUdpMessageEventHandler peerUdpMessageEventHandler; /** * Puts the discoverer into an operational state. * * @throws IOException if we fail to bind. * @throws StunException if the stun4j stack fails start for some reason. */ public static void start(Transport protocol) throws IOException, StunException { sock = new IceTcpSocketWrapper(tcpSocketToServer); System.out.println("Adding an new TCP connection to : " + serverAddress.getHostAddress()); localAddress = new TransportAddress(InetAddress.getLocalHost(), tcpSocketToServer.getLocalPort(), protocol); System.out.println("Client adress : " + localAddress); System.out.println("Server adress : " + serverAddress); ClientChannelDataEventHandler channelDataHandler = new ClientChannelDataEventHandler(); turnStack = new TurnStack(null, channelDataHandler); channelDataHandler.setTurnStack(turnStack); turnStack.addSocket(sock); requestSender = new BlockingRequestSender(turnStack, localAddress); ConnectionAttemptIndicationListener connectionAttemptIndicationListener = new ConnectionAttemptIndicationListener(turnStack/*,requestSender*/); connectionAttemptIndicationListener.setLocalAddress(localAddress); connectionAttemptIndicationListener.start(); started = true; } /** * @param args * @throws IOException * @throws StunException * @throws InterruptedException */ public static void main(String[] args) throws IOException, StunException, InterruptedException { String[] temp = { InetAddress.getLocalHost().toString(), "3478" }; args = temp; Transport protocol = Transport.TCP; // uses args as server name and port serverAddress = new TransportAddress(InetAddress.getLocalHost(), Integer.valueOf( args[1]).intValue(), protocol); tcpSocketToServer = new Socket(serverAddress.getHostAddress(), 3478); System.out.println("Local port chosen : " + tcpSocketToServer.getLocalPort()); start(protocol); StunMessageEvent evt = null; evt = sendAllocationRequest( localAddress, serverAddress); evt = sendCreatePermissionRequest(8080); // evt = sendCreatePermissionRequest(9999); // evt = sendCreatePermissionRequest(11000); // evt = sendConnectRequest(9999); TransportAddress peerAddr = new TransportAddress(InetAddress.getLocalHost(), 8080, protocol); Thread.sleep(600 * 1000); shutDown(); } public static StunMessageEvent sendAllocationRequest( TransportAddress localAddr, TransportAddress serverAddress) throws IOException { Request request = MessageFactory.createAllocateRequest(); RequestedTransportAttribute requestedTransportAttribute = AttributeFactory .createRequestedTransportAttribute(RequestedTransportAttribute.TCP); request.putAttribute(requestedTransportAttribute); System.out.println("Message type : " + (int) request.getMessageType()); StunMessageEvent evt = null; try { AllocationResponseCollector allocResCollec = new AllocationResponseCollector(turnStack); /* * turnStack.sendRequest(request, serverAddress, localAddress, * allocResCollec); */ evt = requestSender.sendRequestAndWaitForResponse( request, serverAddress); allocResCollec.processResponse((StunResponseEvent) evt); } catch (Exception ex) { // this shouldn't happen since we are the ones that created the // request ex.printStackTrace(); System.out.println("Internal Error. Failed to encode a message"); return null; } if (evt != null) System.out.println("Allocation TEST res=" + (int) (evt.getMessage().getMessageType()) + " - " + evt.getRemoteAddress().getHostAddress()); else System.out.println("NO RESPONSE received to Allocation TEST."); return evt; } public static StunMessageEvent sendCreatePermissionRequest(int peerPort) throws IOException, StunException { System.out.println(); TransportAddress peerAddr = new TransportAddress(serverAddress.getAddress(), peerPort, Transport.TCP); TransactionID tran = TransactionID.createNewTransactionID(); System.out.println("Create request for : " + peerAddr); Request request = MessageFactory.createCreatePermissionRequest( peerAddr, tran.getBytes()); StunMessageEvent evt = null; System.out.println("Permission tran : " + tran); try { evt = requestSender.sendRequestAndWaitForResponse( request, serverAddress, tran); } catch (StunException ex) { // this shouldn't happen since we are the ones that created the // request System.out.println("Internal Error. Failed to encode a message"); return null; } if (evt != null) System.out.println("Permission TEST res=" + (int) (evt.getMessage().getMessageType()) + " - " + evt.getRemoteAddress().getHostAddress()); else System.out.println("NO RESPONSE received to Permission TEST."); return evt; } public static StunMessageEvent sendConnectRequest(int peerPort) throws IOException, StunException { System.out.println(); TransportAddress peerAddr = new TransportAddress(serverAddress.getAddress(), peerPort, Transport.TCP); TransactionID tran = TransactionID.createNewTransactionID(); System.out.println("Connect request for : " + peerAddr); Request request = MessageFactory.createConnectRequest( peerAddr, tran.getBytes()); request.setTransactionID(tran.getBytes()); StunMessageEvent evt = null; System.out.println("Connect Req tran : " + tran); try { evt = requestSender.sendRequestAndWaitForResponse( request, serverAddress, tran); } catch (StunException ex) { // this shouldn't happen since we are the ones that created the // request System.out.println("Internal Error. Failed to encode a message"); return null; } if (evt != null) System.out.println("Connect request TEST res=" + (int) (evt.getMessage().getMessageType()) + " - " + evt.getRemoteAddress().getHostAddress()); else System.out.println("NO RESPONSE received to Connect Request TEST."); return evt; } public static void doInteractiveComm() throws IOException, StunException { System.out.println("---->Interactve Communication started<---------"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = null; while ((line = br.readLine()) != null) { byte[] data = line.getBytes(); TransactionID tran = TransactionID.createNewTransactionID(); TransportAddress peerAddress = new TransportAddress(InetAddress.getLocalHost(), 11000, Transport.TCP); Indication ind = MessageFactory.createSendIndication( peerAddress, data, tran.getBytes()); turnStack.sendIndication( ind, serverAddress, localAddress); } } /** * Shuts down the underlying stack and prepares the object for garbage * collection. */ public static void shutDown() { turnStack.removeSocket(localAddress); sock.close(); sock = null; localAddress = null; requestSender = null; started = false; } }