Ejemplo n.º 1
0
  /**
   * Safely returns true if a packet has the same address and a socket. Used to determine its own
   * socket.
   */
  private static boolean isSameSocketAddress(DatagramSocket socket, InetSocketAddress addr) {
    if (socket == null || addr == null) return false;

    SocketAddress socketAddr = socket.getLocalSocketAddress();

    return socketAddr != null && socketAddr.equals(addr);
  }
 private void sendResponse(
     TransportAddress remoteAddress, Request request, Response channelBindResponse)
     throws StunException, IOException {
   TransportAddress sendThrough =
       new TransportAddress((InetSocketAddress) turnServerSocket.getLocalSocketAddress(), UDP);
   stunStack.sendResponse(
       request.getTransactionID(), channelBindResponse, sendThrough, remoteAddress);
 }
  private DatagramSocket startFakeTurnServer() throws Exception {
    turnServerSocket = new DatagramSocket(0, InetAddress.getLocalHost());
    logger.info("Fake server listening on " + turnServerSocket.getLocalSocketAddress());

    stunStack = new StunStack();
    stunStack.addSocket(new IceUdpSocketWrapper(turnServerSocket));
    stunStack.addRequestListener(evt -> eventsReceivedByTurnServer.add(evt));

    return turnServerSocket;
  }
Ejemplo n.º 4
0
 /**
  * The NetLoadableServer interface requires a method that will return a representation of the
  * current server state. This server's state is its network location (IP:port).
  */
 @Override
 public String dumpState() {
   StringBuilder sb = new StringBuilder(super.dumpState());
   sb.append("\nListening on:\n\tTCP: ");
   if (mServerSocket != null) sb.append(mServerSocket.toString());
   else sb.append("Not listening");
   sb.append("\n\tUDP: ");
   if (mDatagramSocket != null) sb.append(mDatagramSocket.getLocalSocketAddress());
   else sb.append("Not listening");
   return sb.toString();
 }
Ejemplo n.º 5
0
  public synchronized DatagramSocket getDatagramSocket() throws SocketException {
    if (_socket == null || _socket.isClosed()) {
      _socket = new DatagramSocket(getPort(), getHostAddr());
      _socket.setSoTimeout(_timeout); // FIXME

      LOG.debug(
          "Create the new datagram socket {} for DNS connector", _socket.getLocalSocketAddress());
      _acceptor = new Acceptor();
      new Thread(_acceptor, "DNS acceptor").start();
    }
    return _socket;
  }
Ejemplo n.º 6
0
  public static void main(String[] args) throws IOException {
    if (args[0].equals("listen")) {
      final LinkedBlockingQueue<Pair<InetSocketAddress, byte[]>> queue;
      queue = new LinkedBlockingQueue<Pair<InetSocketAddress, byte[]>>();

      DatagramSocket socket = new DatagramSocket(8888);
      System.out.println(socket.getLocalAddress());

      new Thread() {
        public void run() {
          while (true) {
            Pair<InetSocketAddress, byte[]> pair;

            try {
              pair = queue.take();
            } catch (InterruptedException exc) {
              break;
            }

            System.out.println();
            System.out.println(pair.first());
            System.out.println(Text.ascii(pair.second()));
          }
        }
      }.start();

      byte[] buffer = new byte[4 * 1024];

      while (true) {
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        socket.receive(packet);
        byte[] data = Arrays.copyOf(buffer, packet.getLength());
        InetSocketAddress addr = (InetSocketAddress) packet.getSocketAddress();

        Pair<InetSocketAddress, byte[]> pair;
        pair = new Pair<InetSocketAddress, byte[]>(addr, data);
        try {
          queue.put(pair);
        } catch (InterruptedException exc) {
          break;
        }
      }
    } else if (args[0].equals("shout")) {
      DatagramSocket socket = new DatagramSocket();
      System.out.println(socket.getLocalSocketAddress());

      byte[] data = Text.ascii("hello world");
      DatagramPacket packet = new DatagramPacket(data, 0, data.length);
      packet.setAddress(InetAddress.getByName("localhost"));
      packet.setPort(8888);
      socket.send(packet);
    }
  }
  @Override
  public void setBroadcast(boolean broadcast) {
    try {
      // See: https://github.com/netty/netty/issues/576
      if (broadcast
          && !DetectionUtil.isWindows()
          && !DetectionUtil.isRoot()
          && !socket.getLocalAddress().isAnyLocalAddress()) {
        // Warn a user about the fact that a non-root user can't receive a
        // broadcast packet on *nix if the socket is bound on non-wildcard address.
        logger.warn(
            "A non-root user can't receive a broadcast packet if the socket "
                + "is not bound to a wildcard address; setting the SO_BROADCAST flag "
                + "anyway as requested on the socket which is bound to "
                + socket.getLocalSocketAddress()
                + '.');
      }

      socket.setBroadcast(broadcast);
    } catch (SocketException e) {
      throw new ChannelException(e);
    }
  }
Ejemplo n.º 8
0
    @Override
    public void run() {

      try {
        if (recGP instanceof BroadcastPacket) {
          BroadcastPacket recBP = (BroadcastPacket) recGP;

          Object recO = E2EComm.deserialize(recBP.getBytePayload());
          if (!(recO instanceof UPnPMulticastMessage)) {
            System.out.println("Received a not multicas message on UPnPMulticastHandler");
          } else {
            // System.out.println("Received a multicast message on UPnPMulticastHandler");
            UPnPMulticastMessage msg = (UPnPMulticastMessage) recO;
            if (msg.getMessageType().startsWith("NOTIFY")) {

              // System.out.println("Received UPnP notify message");
              for (Master tempManager : UPnPmanager.getManagerList()) {
                boolean notlocale = true;
                if (recBP.getTraversedIds().length == 0) {
                  String[] senderOttetti = msg.getSenderAddress().split("\\.");
                  String[] tempManagerOttetti = tempManager.getLocalInterface().split("\\.");
                  if (senderOttetti[0].equalsIgnoreCase(tempManagerOttetti[0])
                      && senderOttetti[1].equalsIgnoreCase(tempManagerOttetti[1])
                      && senderOttetti[2].equalsIgnoreCase(tempManagerOttetti[2]))
                    notlocale = false;
                }

                if (tempManager.isIm() && notlocale) {
                  if (msg.getNTS().contains("alive")) {
                    // System.out.println("Received alive messageand I'm the master " +
                    // tempManager.getManagerAdd());
                    ServerSocket localServerSocket = null;
                    UPnPSOAPRemoteServiceHandler temp = null;
                    synchronized (UPnPmanager.lockNewRemoteService) {
                      temp = UPnPmanager.getRemoteService(msg.getUuid());

                      if (temp == null) {
                        localServerSocket =
                            new ServerSocket(
                                0, 0, InetAddress.getByName(tempManager.getLocalInterface()));
                        temp =
                            new UPnPSOAPRemoteServiceHandler(
                                msg.getSenderAddress(),
                                msg.getSenderPort(),
                                tempManager.getLocalInterface(),
                                localServerSocket.getLocalPort(),
                                msg.getUuid(),
                                msg.getMasterID(),
                                msg.getMasterPort(),
                                recBP.getSource(),
                                localServerSocket);

                        UPnPmanager.remoteServiceManaged.add(temp);
                        temp.start();
                      }
                      if (temp != null) localServerSocket = temp.getLocalServerSocket();
                    }
                    String upnpMessage = new String(msg.getMulticastUPnPmessagePayload());
                    // System.out.println(msg.getSenderAddress() + ":" + msg.getSenderPort());
                    // System.out.println(tempManager.getLocalInterface() + ":" +
                    // localServerSocket.getLocalPort());
                    final Pattern pattern =
                        Pattern.compile(msg.getSenderAddress() + ":" + msg.getSenderPort());
                    final Matcher matcher = pattern.matcher(upnpMessage);
                    upnpMessage =
                        matcher.replaceAll(
                            tempManager.getLocalInterface()
                                + ":"
                                + localServerSocket.getLocalPort());
                    DatagramSocket serverSocketUnicast;
                    try {
                      serverSocketUnicast =
                          new DatagramSocket(
                              0, InetAddress.getByName(tempManager.getLocalInterface()));
                      byte[] message = upnpMessage.getBytes();
                      String socketadd = "";
                      try {
                        socketadd = "" + serverSocketUnicast.getLocalSocketAddress();
                        // System.out.println("Local sender socket: " + socketadd);
                        UPnPmanager.localSenderSocket.add(socketadd);
                      } catch (Exception e) {
                        // e.printStackTrace();
                      }
                      DatagramPacket sendPacket =
                          new DatagramPacket(
                              message,
                              message.length,
                              InetAddress.getByName("239.255.255.250"),
                              1900);

                      serverSocketUnicast.send(sendPacket);
                      // System.out.println("Sent alive message");
                      serverSocketUnicast.close();
                    } catch (Exception e) {
                      // e.printStackTrace();
                    }
                  }

                  if (msg.getNTS().contains("bye")) {
                    // System.out.println("Received a BYEBYE notification from uuid: " +
                    // msg.getUuid());
                    DatagramSocket serverSocketUnicast;
                    try {
                      serverSocketUnicast =
                          new DatagramSocket(
                              0, InetAddress.getByName(tempManager.getLocalInterface()));

                      byte[] message = msg.getMulticastUPnPmessagePayload();
                      String socketadd = "";
                      try {
                        socketadd = "" + serverSocketUnicast.getLocalSocketAddress();
                        UPnPmanager.localSenderSocket.add(socketadd);
                      } catch (Exception e) {
                        // e.printStackTrace();
                      }
                      DatagramPacket sendPacket =
                          new DatagramPacket(
                              message,
                              message.length,
                              InetAddress.getByName("239.255.255.250"),
                              1900);

                      serverSocketUnicast.send(sendPacket);
                      // System.out.println("Sent BYE BYE message");

                      serverSocketUnicast.close();
                    } catch (Exception e) {
                      // e.printStackTrace();
                    }
                    synchronized (UPnPmanager.lockNewRemoteService) {
                      UPnPSOAPRemoteServiceHandler tempToRemove =
                          UPnPmanager.getRemoteService(msg.getUuid());
                      if (tempToRemove != null) {
                        tempToRemove.stopRemoteService();
                        UPnPmanager.remoteServiceManaged.remove(tempToRemove);
                      }
                    }
                  }
                }
              }
            }

            if (msg.getMessageType().startsWith("M-SEARCH")) { // someone is doing a research

              System.out.println("Received a search message");
              for (Master tempManager : UPnPmanager.getManagerList()) {
                if (tempManager
                    .isIm()) { //  For every interface that i'm the master I'll send the message and
                               // then I'll wait an answer for mx seconds

                  System.out.println("I received a message and I'm the master of that interface");
                  // if(!UPnPmanager.onlyLocalReader.equalsIgnoreCase(tempManager.getLocalInterface()))

                  new MsearchSendHandler(msg, tempManager.getLocalInterface(), recBP.getSource())
                      .start();

                  // DatagramSocket datagramSocket=new
                  // DatagramSocket(0,
                  // InetAddress.getByName(tempManager.getLocalInterface()));
                  // DatagramPacket sendPacket =
                  // new
                  // DatagramPacket(msg.getMulticastUPnPmessagePayload(),
                  // msg.getMulticastUPnPmessagePayload().length,
                  // InetAddress.getByName("239.255.255.250"),
                  // 1900);
                  //
                  // datagramSocket.send(sendPacket);
                  //
                  // byte[] buf=new byte[50*1024];
                  // DatagramPacket receivePacket = new
                  // DatagramPacket(buf, buf.length);
                }
              }
            }
          }
        }
      } catch (Exception e) {
        // e.printStackTrace();
      }
    }
Ejemplo n.º 9
0
    public void run() {
      DatagramSocket serverSocketUnicast;
      try {
        serverSocketUnicast = new DatagramSocket(0, InetAddress.getByName(localInterface));
        // System.out.println(new
        // String(msg.getMulticastUPnPmessagePayload()));
        // InetAddress interfaceAddress =
        // InetAddress.getByName(localInterface);
        //
        // InetAddress group = InetAddress.getByName("239.255.255.250");
        //
        // serverSocketUnicast = new MulticastSocket(1900);
        //
        // serverSocketUnicast.setNetworkInterface(NetworkInterface
        // .getByInetAddress(interfaceAddress));
        // serverSocketUnicast.setLoopbackMode(true);
        // serverSocketUnicast.joinGroup(group);
        //
        // System.err.println("" + serverSocketUnicast.getLocalSocketAddress());
        String add = "" + serverSocketUnicast.getLocalAddress();
        // System.err.println("" + add.substring(1));
        // if(UPnPmanager.onlyLocalReader.equalsIgnoreCase(add.substring(1)))

        DatagramPacket sendPacket =
            new DatagramPacket(
                msg.getMulticastUPnPmessagePayload(),
                msg.getMulticastUPnPmessagePayload().length,
                InetAddress.getByName("239.255.255.250"),
                1900);
        try {
          UPnPmanager.localSenderSocket.add("" + serverSocketUnicast.getLocalSocketAddress());
        } catch (Exception e) {
          // e.printStackTrace();
        }
        serverSocketUnicast.send(sendPacket);
        System.err.println(
            "Sent a search message from " + serverSocketUnicast.getLocalSocketAddress());
        boolean waitAnswer = true;

        byte[] buf = new byte[50 * 1024];
        DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
        long stopWaiting =
            System.currentTimeMillis()
                + msg.getmX()
                    * 1000; // wait at most MX seconds, maybe it's a little too much because the the
                            // send/receive time is longer in multi-hop scenario
        while (waitAnswer) {

          serverSocketUnicast.setSoTimeout((int) (stopWaiting - System.currentTimeMillis()));

          try {
            serverSocketUnicast.receive(receivePacket);
            System.out.println("Received answer");
            new MsearchReceiveHandler(msg, receivePacket, buf, traversedNode).start();

            buf = new byte[50 * 1024];
            receivePacket = new DatagramPacket(buf, buf.length);

          } catch (SocketTimeoutException e) {
            if (stopWaiting - System.currentTimeMillis() < 0) waitAnswer = false;
          }
        }

        serverSocketUnicast.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
Ejemplo n.º 10
0
  /**
   * Send data to all participants registered as receivers, using the current timeStamp and payload
   * type. The RTP timestamp will be the same for all the packets.
   *
   * @param buffers A buffer of bytes, should not bed padded and less than 1500 bytes on most
   *     networks.
   * @param csrcArray an array with the SSRCs of contributing sources
   * @param markers An array indicating what packets should be marked. Rarely anything but the first
   *     one
   * @param rtpTimestamp The RTP timestamp to be applied to all packets
   * @param seqNumbers An array with the sequence number associated with each byte[]
   * @return null if there was a problem sending the packets, 2-dim array with {RTP Timestamp,
   *     Sequence number}
   */
  public long[][] sendData(
      byte[][] buffers, long[] csrcArray, boolean[] markers, long rtpTimestamp, long[] seqNumbers) {
    logger.debug("-> RTPSession.sendData(byte[])");

    // Same RTP timestamp for all
    if (rtpTimestamp < 0) rtpTimestamp = System.currentTimeMillis();

    // Return values
    long[][] ret = new long[buffers.length][2];

    for (int i = 0; i < buffers.length; i++) {
      byte[] buf = buffers[i];

      boolean marker = false;
      if (markers != null) marker = markers[i];

      if (buf.length > 1500) {
        System.out.println(
            "RTPSession.sendData() called with buffer exceeding 1500 bytes (" + buf.length + ")");
      }

      // Get the return values
      ret[i][0] = rtpTimestamp;
      if (seqNumbers == null) {
        ret[i][1] = getNextSeqNum();
      } else {
        ret[i][1] = seqNumbers[i];
      }
      // Create a new RTP Packet
      RtpPkt pkt = new RtpPkt(rtpTimestamp, this.ssrc, (int) ret[i][1], this.payloadType, buf);

      if (csrcArray != null) pkt.setCsrcs(csrcArray);

      pkt.setMarked(marker);

      // Creates a raw packet
      byte[] pktBytes = pkt.encode();

      // System.out.println(Integer.toString(StaticProcs.bytesToUIntInt(pktBytes, 2)));

      // Pre-flight check, are resolving an SSRC conflict?
      if (this.conflict) {
        System.out.println("RTPSession.sendData() called while trying to resolve conflict.");
        return null;
      }

      if (this.mcSession) {
        DatagramPacket packet = null;

        try {
          packet =
              new DatagramPacket(pktBytes, pktBytes.length, this.mcGroup, this.rtpMCSock.getPort());
        } catch (Exception e) {
          System.out.println("RTPSession.sendData() packet creation failed.");
          e.printStackTrace();
          return null;
        }

        try {
          rtpMCSock.send(packet);
          // Debug
          if (this.debugAppIntf != null) {
            this.debugAppIntf.packetSent(
                1,
                (InetSocketAddress) packet.getSocketAddress(),
                new String(
                    "Sent multicast RTP packet of size "
                        + packet.getLength()
                        + " to "
                        + packet.getSocketAddress().toString()
                        + " via "
                        + rtpMCSock.getLocalSocketAddress().toString()));
          }
        } catch (Exception e) {
          System.out.println("RTPSession.sendData() multicast failed.");
          e.printStackTrace();
          return null;
        }

      } else {
        // Loop over recipients
        Iterator<Participant> iter = partDb.getUnicastReceivers();
        while (iter.hasNext()) {
          InetSocketAddress receiver = iter.next().rtpAddress;
          DatagramPacket packet = null;

          logger.debug("   Sending to {}", receiver);

          try {
            packet = new DatagramPacket(pktBytes, pktBytes.length, receiver);
          } catch (Exception e) {
            System.out.println("RTPSession.sendData() packet creation failed.");
            e.printStackTrace();
            return null;
          }

          // Actually send the packet
          try {
            rtpSock.send(packet);
            // Debug
            if (this.debugAppIntf != null) {
              this.debugAppIntf.packetSent(
                  0,
                  (InetSocketAddress) packet.getSocketAddress(),
                  new String(
                      "Sent unicast RTP packet of size "
                          + packet.getLength()
                          + " to "
                          + packet.getSocketAddress().toString()
                          + " via "
                          + rtpSock.getLocalSocketAddress().toString()));
            }
          } catch (Exception e) {
            System.out.println("RTPSession.sendData() unicast failed.");
            e.printStackTrace();
            return null;
          }
        }
      }

      // Update our stats
      this.sentPktCount++;
      this.sentOctetCount++;

      logger.info("<- RTPSession.sendData(byte[])", pkt.getSeqNumber());
    }

    return ret;
  }
Ejemplo n.º 11
0
  /**
   * A NetLoadableService must provide a public constructor taking no arguments.
   *
   * <p>This service must listen to both a UDP and a TCP port. It creates sockets bound to those
   * ports in this constructor. It also creates a thread per socket - the thread blocks trying to
   * receive data on its socket, and when it does, echoes back whatever it receives.
   *
   * @throws Exception
   */
  public EchoRawService() throws Exception {
    super("echoraw");

    // Sanity check -- code below relies on this property
    if (HEADER_STR.length() != RESPONSE_OKAY_STR.length())
      throw new Exception(
          "Header and response strings must be same length: '"
              + HEADER_STR
              + "' '"
              + RESPONSE_OKAY_STR
              + "'");

    // The echo raw service's IP address is the ip the entire app is running
    // under
    String serverIP = IPFinder.localIP();
    if (serverIP == null)
      throw new Exception("IPFinder isn't providing the local IP address.  Can't run.");

    // There is (purposefully) no config file field to define the echo raw
    // service's ports.
    // Instead, ephemeral ports are used. (You can run the
    // dumpservericestate application
    // to see ports are actually allocated.)

    mServerSocket = new ServerSocket();
    mServerSocket.bind(new InetSocketAddress(serverIP, 0));
    mServerSocket.setSoTimeout(
        NetBase.theNetBase().config().getAsInt("net.timeout.granularity", 500));

    mDatagramSocket = new DatagramSocket(new InetSocketAddress(serverIP, 0));
    mDatagramSocket.setSoTimeout(
        NetBase.theNetBase().config().getAsInt("net.timeout.granularity", 500));

    Log.i(TAG, "Server socket = " + mServerSocket.getLocalSocketAddress());
    Log.i(TAG, "Datagram socket = " + mDatagramSocket.getLocalSocketAddress());

    // Code/thread handling the UDP socket
    Thread dgramThread =
        new Thread() {
          public void run() {
            byte buf[] = new byte[64 * 1024];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);

            // Thread termination in this code is primitive. When shutdown()
            // is called (by the
            // application's main thread, so asynchronously to the threads
            // just mentioned) it
            // closes the sockets. This causes an exception on any thread
            // trying to read from
            // it, which is what provokes thread termination.
            try {
              while (!mAmShutdown) {
                try {
                  mDatagramSocket.receive(packet);
                  if (packet.getLength() < HEADER_STR.length())
                    throw new Exception("Bad header: length = " + packet.getLength());
                  String headerStr = new String(buf, 0, HEADER_STR.length());
                  if (!headerStr.equalsIgnoreCase(HEADER_STR))
                    throw new Exception(
                        "Bad header: got '" + headerStr + "', wanted '" + HEADER_STR + "'");
                  System.arraycopy(RESPONSE_OKAY_STR.getBytes(), 0, buf, 0, HEADER_STR.length());
                  mDatagramSocket.send(
                      new DatagramPacket(
                          buf, packet.getLength(), packet.getAddress(), packet.getPort()));
                } catch (SocketTimeoutException e) {
                  // socket timeout is normal
                } catch (Exception e) {
                  Log.w(
                      TAG,
                      "Dgram reading thread caught "
                          + e.getClass().getName()
                          + " exception: "
                          + e.getMessage());
                }
              }
            } finally {
              if (mDatagramSocket != null) {
                mDatagramSocket.close();
                mDatagramSocket = null;
              }
            }
          }
        };
    dgramThread.start();

    // Code/thread handling the TCP socket
    Thread tcpThread =
        new Thread() {

          public void run() {
            byte[] header = new byte[4];
            byte[] buf = new byte[1024];
            int socketTimeout = NetBase.theNetBase().config().getAsInt("net.timeout.socket", 5000);
            try {
              while (!isShutdown()) {
                Socket sock = null;
                try {
                  // accept() blocks until a client connects. When it
                  // does, a new socket is created that communicates
                  // only
                  // with that client. That socket is returned.
                  sock = mServerSocket.accept();
                  // We're going to read from sock, to get the message
                  // to echo, but we can't risk a client mistake
                  // blocking us forever. So, arrange for the socket
                  // to give up if no data arrives for a while.
                  sock.setSoTimeout(socketTimeout);
                  InputStream is = sock.getInputStream();
                  OutputStream os = sock.getOutputStream();
                  // Read the header. Either it gets here in one chunk
                  // or we ignore it. (That's not exactly the
                  // spec, admittedly.)
                  int len = is.read(header);
                  if (len != HEADER_STR.length())
                    throw new Exception(
                        "Bad header length: got " + len + " but wanted " + HEADER_STR.length());
                  String headerStr = new String(header);
                  if (!headerStr.equalsIgnoreCase(HEADER_STR))
                    throw new Exception(
                        "Bad header: got '" + headerStr + "' but wanted '" + HEADER_STR + "'");
                  os.write(RESPONSE_OKAY_STR.getBytes());

                  // Now read and echo the payload.
                  // Keep reading until the client has closed its side
                  // of the connection
                  while ((len = is.read(buf)) >= 0) os.write(buf, 0, len);

                } catch (SocketTimeoutException e) {
                  // normal behavior, but we're done with the client
                  // we were talking with
                } catch (Exception e) {
                  Log.i(
                      TAG,
                      "TCP thread caught "
                          + e.getClass().getName()
                          + " exception: "
                          + e.getMessage());
                } finally {
                  if (sock != null)
                    try {
                      sock.close();
                      sock = null;
                    } catch (Exception e) {
                    }
                }
              }
            } catch (Exception e) {
              Log.w(TAG, "TCP server thread exiting due to exception: " + e.getMessage());
            } finally {
              if (mServerSocket != null)
                try {
                  mServerSocket.close();
                  mServerSocket = null;
                } catch (Exception e) {
                }
            }
          }
        };
    tcpThread.start();
  }
Ejemplo n.º 12
0
  private boolean test1()
      throws UtilityException, SocketException, UnknownHostException, IOException,
          MessageAttributeParsingException, MessageHeaderParsingException {
    int timeSinceFirstTransmission = 0;
    int timeout = timeoutInitValue;
    while (true) {
      try {
        // Test 1 including response
        socketTest1 = new DatagramSocket(new InetSocketAddress(localAddress, localPort));
        socketTest1.setReuseAddress(true);
        socketTest1.connect(InetAddress.getByName(stunServer), stunPort);
        socketTest1.setSoTimeout(timeout);

        LOGGER.debug("!!!!! SocketAddress: " + socketTest1.getLocalSocketAddress());

        MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
        sendMH.generateTransactionID();

        ChangeRequest changeRequest = new ChangeRequest();
        sendMH.addMessageAttribute(changeRequest);

        byte[] data = sendMH.getBytes();
        DatagramPacket send = new DatagramPacket(data, data.length);
        socketTest1.send(send);
        LOGGER.debug("Test 1: Binding Request sent.");

        MessageHeader receiveMH = new MessageHeader();
        while (!(receiveMH.equalTransactionID(sendMH))) {
          DatagramPacket receive = new DatagramPacket(new byte[200], 200);
          socketTest1.receive(receive);
          receiveMH = MessageHeader.parseHeader(receive.getData());
          receiveMH.parseAttributes(receive.getData());
        }

        ma =
            (MappedAddress)
                receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);
        ca =
            (ChangedAddress)
                receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ChangedAddress);
        ErrorCode ec =
            (ErrorCode)
                receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode);
        if (ec != null) {
          di.setError(ec.getResponseCode(), ec.getReason());
          LOGGER.debug("Message header contains an Errorcode message attribute.");
          return false;
        }
        if ((ma == null) || (ca == null)) {
          di.setError(
              700,
              "The server is sending an incomplete response (Mapped Address and Changed Address message attributes are missing). The client should not retry.");
          LOGGER.debug(
              "Response does not contain a Mapped Address or Changed Address message attribute.");
          return false;
        } else {
          di.setPublicIP(ma.getAddress().getInetAddress());
          di.setLocalPort(socketTest1.getLocalPort());
          if ((ma.getPort() == socketTest1.getLocalPort())
              && (ma.getAddress().getInetAddress().equals(socketTest1.getLocalAddress()))) {
            LOGGER.debug("Node is not natted.");
            di.setPublicPort(socketTest1.getLocalPort());
            nodeNatted = false;
          } else {
            di.setPublicPort(ma.getPort());
            LOGGER.debug("Node is natted.");
          }
          return true;
        }
      } catch (SocketTimeoutException ste) {
        if (timeSinceFirstTransmission < timeoutTest) {
          LOGGER.debug("Test 1: Socket timeout while receiving the response.");
          timeSinceFirstTransmission += timeout;
          int timeoutAddValue = (timeSinceFirstTransmission * 2);
          if (timeoutAddValue > timeoutSecond) // 1600)
          timeoutAddValue = timeoutSecond;
          timeout = timeoutAddValue;
        } else {
          // node is not capable of udp communication
          LOGGER.debug(
              "Test 1: Socket timeout while receiving the response. Maximum retry limit exceed. Give up.");
          di.setBlockedUDP();
          LOGGER.debug("Node is not capable of UDP communication.");
          return false;
        }
      }
    }
  }