@Override public void connect() { if (connectionState.get() == ConnectionState.CONNECTED) { return; } stunStack = applicationContext.getBean(StunStack.class); serverAddress = new TransportAddress(turnHost, turnPort, Transport.UDP); connectionState.set(ConnectionState.CONNECTING); try { localSocket = new MultiplexingDatagramSocket(0, getLocalHost()); channelDataSocket = localSocket.getSocket( new TurnDatagramPacketFilter(serverAddress) { @Override public boolean accept(DatagramPacket packet) { return isChannelData(packet); } @Override protected boolean acceptMethod(char method) { return false; } }); localAddress = new TransportAddress( (InetSocketAddress) localSocket.getLocalSocketAddress(), Transport.UDP); stunStack.addSocket(new IceUdpSocketWrapper(localSocket), serverAddress); stunStack.addIndicationListener(localAddress, this::onIndication); releaseAllocation(); allocateAddress(serverAddress); permit(connectivityService.getExternalSocketAddress()); connectionState.set(ConnectionState.CONNECTED); scheduledExecutorService.execute(this::runInReceiveChannelDataThread); } catch (StunException | IOException e) { throw new RuntimeException(e); } }
@VisibleForTesting public InetSocketAddress getLocalSocketAddress() { return (InetSocketAddress) localSocket.getLocalSocketAddress(); }