@Override
  public void send(DatagramPacket packet) {
    SocketAddress socketAddress = packet.getSocketAddress();
    if (!peerAddressToChannel.containsKey(socketAddress)) {
      logger.warn("Peer {} is not bound to a channel", socketAddress);
      return;
    }

    Character channelNumber = peerAddressToChannel.get(socketAddress);

    byte[] payload = new byte[packet.getLength()];
    System.arraycopy(
        packet.getData(), packet.getOffset(), payload, packet.getOffset(), payload.length);

    ChannelData channelData = new ChannelData();
    channelData.setData(payload);
    channelData.setChannelNumber(channelNumber);

    if (logger.isTraceEnabled()) {
      logger.trace(
          "Writing {} bytes on channel {}: {}",
          packet.getLength(),
          (int) channelNumber,
          new String(payload, 0, payload.length, StandardCharsets.US_ASCII));
    }
    try {
      stunStack.sendChannelData(channelData, serverAddress, localAddress);
    } catch (StunException e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * Copies the properties of a specific <tt>DatagramPacket</tt> to another <tt>DatagramPacket</tt>.
   * The property values are not cloned.
   *
   * @param src the <tt>DatagramPacket</tt> which is to have its properties copied to <tt>dest</tt>
   * @param dest the <tt>DatagramPacket</tt> which is to have its properties set to the value of the
   *     respective properties of <tt>src</tt>
   */
  public static void copy(DatagramPacket src, DatagramPacket dest) {
    synchronized (dest) {
      dest.setAddress(src.getAddress());
      dest.setPort(src.getPort());

      byte[] srcData = src.getData();

      if (srcData == null) dest.setLength(0);
      else {
        byte[] destData = dest.getData();

        if (destData == null) dest.setLength(0);
        else {
          int destOffset = dest.getOffset();
          int destLength = destData.length - destOffset;
          int srcLength = src.getLength();

          if (destLength >= srcLength) destLength = srcLength;
          else if (logger.isLoggable(Level.WARNING)) {
            logger.log(Level.WARNING, "Truncating received DatagramPacket data!");
          }
          System.arraycopy(srcData, src.getOffset(), destData, destOffset, destLength);
          dest.setLength(destLength);
        }
      }
    }
  }
Exemple #3
0
 public void run() throws IOException {
   final byte[] buf = new byte[2 * 4096];
   final DatagramPacket p = new DatagramPacket(buf, buf.length);
   while (true) {
     socket.receive(p);
     System.out.write(p.getData(), p.getOffset(), p.getLength());
     System.out.flush();
     if (out != null) {
       out.write(p.getData(), p.getOffset(), p.getLength());
       out.flush();
     }
   }
 }
 /** Accept incoming events and processes them. */
 @Override
 public void run() {
   while (isActive()) {
     if (datagramSocket.isClosed()) {
       // OK we're done.
       return;
     }
     try {
       final byte[] buf = new byte[maxBufferSize];
       final DatagramPacket packet = new DatagramPacket(buf, buf.length);
       datagramSocket.receive(packet);
       final ByteArrayInputStream bais =
           new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength());
       logEventInput.logEvents(logEventInput.wrapStream(bais), this);
     } catch (final OptionalDataException e) {
       if (datagramSocket.isClosed()) {
         // OK we're done.
         return;
       }
       logger.error("OptionalDataException eof=" + e.eof + " length=" + e.length, e);
     } catch (final EOFException e) {
       if (datagramSocket.isClosed()) {
         // OK we're done.
         return;
       }
       logger.info("EOF encountered");
     } catch (final IOException e) {
       if (datagramSocket.isClosed()) {
         // OK we're done.
         return;
       }
       logger.error("Exception encountered on accept. Ignoring. Stack Trace :", e);
     }
   }
 }
 /** Process acknowledgments, if requested. */
 @Override
 public void run() {
   try {
     this.ackThreadRunning = true;
     ackLatch.countDown();
     DatagramPacket ackPack = new DatagramPacket(new byte[100], 100);
     while (true) {
       this.getSocket().receive(ackPack);
       String id = new String(ackPack.getData(), ackPack.getOffset(), ackPack.getLength());
       if (logger.isDebugEnabled()) {
         logger.debug("Received ack for " + id + " from " + ackPack.getAddress().getHostAddress());
       }
       CountDownLatch latch = this.ackControl.get(id);
       if (latch != null) {
         latch.countDown();
       }
     }
   } catch (IOException e) {
     if (this.socket != null && !this.socket.isClosed()) {
       logger.error("Error on UDP Acknowledge thread:" + e.getMessage());
     }
   } finally {
     this.ackThreadRunning = false;
   }
 }
  @Override
  public void run() {
    while (true) {
      try {
        byte[] dataBuffer = new byte[25600]; // 25kB buffer
        DatagramPacket packet = new DatagramPacket(dataBuffer, dataBuffer.length);
        multiplexerSocket.receive(packet);
        // Check if packet is valid
        int type = dataBuffer[0] >>> 4;
        int version = dataBuffer[0] & 0x7;
        if (version == Packet.VERSION) {
          try {
            Packet utpPacket = packetFactory.getFromId(type);
            Stream inStream = new Stream(packet.getData(), packet.getOffset(), packet.getLength());
            utpPacket.read(inStream);
            UtpSocket socket = new UtpSocket(utpPacket.getConnectionId());
            socket = utpSockets.find(socket);
            if (socket != null) {
              // log("Received " + utpPacket.getClass().getSimpleName() + " for " +
              // (utpPacket.getConnectionId() & 0xFFFF));
              socket.updateLastInteraction();
              utpPacket.process(socket);
            } else {
              // log("Packet of " + packet.getLength() + " bytes (0x" +
              // Integer.toHexString(dataBuffer[0]) + ") was send to a connection which was not
              // established (" + packet.getAddress() + ":" + packet.getPort() + " | " +
              // utpPacket.getConnectionId() + ")");
            }
          } catch (IllegalArgumentException e) {
            log(
                "Invalid Packet of "
                    + packet.getLength()
                    + " bytes with type "
                    + type
                    + " ("
                    + packet.getAddress()
                    + ":"
                    + packet.getPort()
                    + ")",
                true);
          }
        } else {
          log(
              "Invalid Packet of "
                  + packet.getLength()
                  + " bytes with version "
                  + version
                  + " ("
                  + packet.getAddress()
                  + ":"
                  + packet.getPort()
                  + ")",
              true);
        }
      } catch (IOException e) {

      }
    }
  }
  /**
   * Initializes a new <tt>DatagramPacket</tt> instance which is a clone of a specific
   * <tt>DatagramPacket</tt> i.e. the properties of the clone <tt>DatagramPacket</tt> are clones of
   * the specified <tt>DatagramPacket</tt>.
   *
   * @param p the <tt>DatagramPacket</tt> to clone
   * @return a new <tt>DatagramPacket</tt> instance which is a clone of the specified
   *     <tt>DatagramPacket</tt>
   */
  public static DatagramPacket clone(DatagramPacket p) {
    synchronized (p) {
      byte[] pData = p.getData();
      byte[] cData = (pData == null) ? null : pData.clone();

      return new DatagramPacket(cData, p.getOffset(), p.getLength(), p.getAddress(), p.getPort());
    }
  }
  private void runInReceiveChannelDataThread() {
    int receiveBufferSize = 1500;
    DatagramPacket packet = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize);

    while (connectionState.get() == ConnectionState.CONNECTED) {
      try {
        channelDataSocket.receive(packet);
      } catch (IOException e) {
        if (channelDataSocket.isClosed()) {
          logger.debug("Channel data socket has been closed");
          return;
        } else {
          throw new RuntimeException(e);
        }
      }

      int channelDataLength = packet.getLength();
      if (channelDataLength < (CHANNELDATA_CHANNELNUMBER_LENGTH + CHANNELDATA_LENGTH_LENGTH)) {
        continue;
      }

      byte[] receivedData = packet.getData();
      int channelDataOffset = packet.getOffset();
      char channelNumber =
          (char)
              ((receivedData[channelDataOffset++] << 8)
                  | (receivedData[channelDataOffset++] & 0xFF));

      channelDataLength -= CHANNELDATA_CHANNELNUMBER_LENGTH;

      char length =
          (char)
              ((receivedData[channelDataOffset++] << 8)
                  | (receivedData[channelDataOffset++] & 0xFF));

      channelDataLength -= CHANNELDATA_LENGTH_LENGTH;
      if (length > channelDataLength) {
        continue;
      }

      byte[] payload = new byte[length];
      System.arraycopy(receivedData, channelDataOffset, payload, 0, length);

      ChannelData channelData = new ChannelData();
      channelData.setChannelNumber(channelNumber);
      channelData.setData(payload);
      try {
        onChannelData(
            new ChannelDataMessageEvent(
                stunStack, channelToPeerAddress.get(channelNumber), localAddress, channelData));
      } catch (Exception e) {
        logger.warn("Error while handling channel data", e);
      }
    }

    logger.info("Stopped reading channel data");
  }
  /**
   * Creates a new <tt>RawPacket</tt> from a specific <tt>DatagramPacket</tt> in order to have this
   * instance receive its packet data through its {@link #read(byte[], int, int)} method. Returns an
   * array of <tt>RawPacket</tt> with the created packet as its first element (and <tt>null</tt> for
   * the other elements).
   *
   * <p>Allows extenders to intercept the packet data and possibly filter and/or modify it.
   *
   * @param datagramPacket the <tt>DatagramPacket</tt> containing the packet data
   * @return an array of <tt>RawPacket</tt> containing the <tt>RawPacket</tt> which contains the
   *     packet data of the specified <tt>DatagramPacket</tt> as its first element.
   */
  protected RawPacket[] createRawPacket(DatagramPacket datagramPacket) {
    RawPacket[] pkts = rawPacketArrayPool.poll();
    if (pkts == null) pkts = new RawPacket[1];

    RawPacket pkt = rawPacketPool.poll();
    if (pkt == null) pkt = new RawPacket();

    pkt.setBuffer(datagramPacket.getData());
    pkt.setFlags(0);
    pkt.setLength(datagramPacket.getLength());
    pkt.setOffset(datagramPacket.getOffset());

    pkts[0] = pkt;
    return pkts;
  }
  /* extract the send and receive part in own method */
  public static void sendReceive(
      DatagramSocket socket, String msg, DatagramPacket sendPacket, DatagramPacket receivePacket) {
    try {
      socket.send(sendPacket);
      socket.receive(receivePacket);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    /* Compare sent and received message */
    String receivedString =
        new String(receivePacket.getData(), receivePacket.getOffset(), receivePacket.getLength());
    if (receivedString.compareTo(msg) == 0)
      System.out.printf("%d bytes sent and received\n", receivePacket.getLength());
    else System.out.printf("Sent and received msg not equal!\n");
  }
  private JoinMessage receive() {
    try {
      try {
        multicastSocket.receive(datagramPacketReceive);
      } catch (IOException ignore) {
        return null;
      }
      try {
        final byte[] data = datagramPacketReceive.getData();
        final int offset = datagramPacketReceive.getOffset();
        final BufferObjectDataInput input =
            node.getSerializationService().createObjectDataInput(data);
        input.position(offset);

        final byte packetVersion = input.readByte();
        if (packetVersion != Packet.VERSION) {
          logger.warning(
              "Received a JoinRequest with a different packet version! This -> "
                  + Packet.VERSION
                  + ", Incoming -> "
                  + packetVersion
                  + ", Sender -> "
                  + datagramPacketReceive.getAddress());
          return null;
        }
        try {
          return input.readObject();
        } finally {
          input.close();
        }
      } catch (Exception e) {
        if (e instanceof EOFException || e instanceof HazelcastSerializationException) {
          logger.warning(
              "Received data format is invalid."
                  + " (An old version of Hazelcast may be running here.)",
              e);
        } else {
          throw e;
        }
      }
    } catch (Exception e) {
      logger.warning(e);
    }
    return null;
  }
 private DatagramPacket copyPacket(final DatagramPacket packet) {
   byte[] message = new byte[packet.getLength()];
   System.arraycopy(packet.getData(), 0, message, 0, packet.getLength());
   InetAddress addr = null;
   try {
     addr =
         InetAddress.getByAddress(
             packet.getAddress().getHostName(), packet.getAddress().getAddress());
     DatagramPacket retPacket =
         new DatagramPacket(
             message, packet.getOffset(), packet.getLength(), addr, packet.getPort());
     return retPacket;
   } catch (UnknownHostException e) {
     ThreadCategory.getInstance(getClass())
         .warn("unable to clone InetAddress object for " + packet.getAddress());
   }
   return null;
 }
 public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException {
   synchronized (receiveQueue) {
     if (receiveQueue.isEmpty()) {
       try {
         receiveQueue.wait(waitMillis);
       } catch (InterruptedException e) {
         // TODO Keep waiting until full wait expired?
       }
       if (receiveQueue.isEmpty()) {
         return -1;
       }
     }
     DatagramPacket packet = (DatagramPacket) receiveQueue.remove(0);
     int copyLength = Math.min(len, packet.getLength());
     System.arraycopy(packet.getData(), packet.getOffset(), buf, off, copyLength);
     return copyLength;
   }
 }
  /** @see java.net.DatagramSocketImpl#send(java.net.DatagramPacket) */
  protected void send(DatagramPacket p) throws IOException {

    final IPv4Address dstAddress = new IPv4Address(p.getAddress());
    final IPv4Header ipHdr;
    ipHdr =
        new IPv4Header(
            getTos(), getTimeToLive(), IPPROTO_UDP, dstAddress, p.getLength() + UDP_HLEN);
    if (!getLocalAddress().isAnyLocalAddress() || (getDevice() != null)) {
      ipHdr.setSource(new IPv4Address(getLocalAddress()));
    }
    final UDPHeader udpHdr;
    final int srcPort = getLocalPort();
    // final int srcPort = p.getPort(); // or getLocalPort???? TODO Fix
    // srcPort issue
    udpHdr = new UDPHeader(srcPort, p.getPort(), p.getLength());

    final SocketBuffer skbuf = new SocketBuffer(p.getData(), p.getOffset(), p.getLength());
    skbuf.setDevice(getDevice());
    protocol.send(ipHdr, udpHdr, skbuf);
  }
  @Override
  protected int doReadMessages(MessageBuf<Object> buf) throws Exception {
    if (readSuspended) {
      try {
        Thread.sleep(SO_TIMEOUT);
      } catch (InterruptedException e) {
        // ignore;
      }
      return 0;
    }

    int packetSize = config().getReceivePacketSize();
    byte[] data = new byte[packetSize];
    tmpPacket.setData(data);
    try {
      socket.receive(tmpPacket);
      InetSocketAddress remoteAddr = (InetSocketAddress) tmpPacket.getSocketAddress();
      if (remoteAddr == null) {
        remoteAddr = remoteAddress();
      }
      buf.add(
          new DatagramPacket(
              Unpooled.wrappedBuffer(data, tmpPacket.getOffset(), tmpPacket.getLength()),
              remoteAddr));

      if (readSuspended) {
        return 0;
      } else {
        return 1;
      }
    } catch (SocketTimeoutException e) {
      // Expected
      return 0;
    } catch (SocketException e) {
      if (!e.getMessage().toLowerCase(Locale.US).contains("socket closed")) {
        throw e;
      }
      return -1;
    }
  }
 private void realRun(DatagramPacket packet) {
   // Single receiving thread
   boolean gotPacket = getPacket(packet);
   long now = System.currentTimeMillis();
   if (gotPacket) {
     long startTime = System.currentTimeMillis();
     Peer peer = new Peer(packet.getAddress(), packet.getPort());
     tracker.receivedPacketFrom(peer);
     long endTime = System.currentTimeMillis();
     if (endTime - startTime > 50) {
       if (endTime - startTime > 3000) {
         Logger.error(this, "packet creation took " + (endTime - startTime) + "ms");
       } else {
         if (logMINOR) Logger.minor(this, "packet creation took " + (endTime - startTime) + "ms");
       }
     }
     byte[] data = packet.getData();
     int offset = packet.getOffset();
     int length = packet.getLength();
     try {
       if (logMINOR) Logger.minor(this, "Processing packet of length " + length + " from " + peer);
       startTime = System.currentTimeMillis();
       lowLevelFilter.process(data, offset, length, peer, now);
       endTime = System.currentTimeMillis();
       if (endTime - startTime > 50) {
         if (endTime - startTime > 3000) {
           Logger.error(this, "processing packet took " + (endTime - startTime) + "ms");
         } else {
           if (logMINOR)
             Logger.minor(this, "processing packet took " + (endTime - startTime) + "ms");
         }
       }
       if (logMINOR) Logger.minor(this, "Successfully handled packet length " + length);
     } catch (Throwable t) {
       Logger.error(this, "Caught " + t + " from " + lowLevelFilter, t);
     }
   } else {
     if (logDEBUG) Logger.debug(this, "No packet received");
   }
 }
Exemple #17
0
  public void run() {
    final byte[] receive_buf = new byte[65535];
    DatagramPacket packet = new DatagramPacket(receive_buf, receive_buf.length);
    DataInput inp;

    while (sock != null && receiver != null && Thread.currentThread().equals(receiver)) {
      packet.setData(receive_buf, 0, receive_buf.length);
      try {
        sock.receive(packet);
        inp =
            new ByteArrayDataInputStream(packet.getData(), packet.getOffset(), packet.getLength());
        Message msg = new Message();
        msg.readFrom(inp);
        up(msg);
      } catch (SocketException socketEx) {
        break;
      } catch (Throwable ex) {
        log.error(Util.getMessage("FailedReceivingPacketFrom"), packet.getSocketAddress(), ex);
      }
    }
    if (log.isTraceEnabled()) log.trace("receiver thread terminated");
  }
  /**
   * Determines whether a specific {@code DatagramPacket} is accepted by {@link #channelDataSocket}
   * (i.e. whether {@code channelDataSocket} understands {@code packet} and {@code packet} is meant
   * to be received by {@code channelDataSocket}).
   *
   * @param packet the {@code DatagramPacket} which is to be checked whether it is accepted by
   *     {@code channelDataSocket}
   * @return {@code true} if {@code channelDataSocket} accepts {@code packet} (i.e. {@code
   *     channelDataSocket} understands {@code packet} and {@code p} is meant to be received by
   *     {@code channelDataSocket}); otherwise, {@code false}
   */
  private boolean isChannelData(DatagramPacket packet) {
    // Is it from our TURN server?
    if (!serverAddress.equals(packet.getSocketAddress())) {
      return false;
    }

    int packetLength = packet.getLength();

    if (packetLength < (CHANNELDATA_CHANNELNUMBER_LENGTH + CHANNELDATA_LENGTH_LENGTH)) {
      return false;
    }

    byte[] pData = packet.getData();
    int pOffset = packet.getOffset();

    /*
     * The first two bits should be 0b01 because of the current channel number range 0x4000 - 0x7FFE. But 0b10 and 0b11
     * which are currently reserved and may be used in the future to extend the range of channel numbers.
     */
    if ((pData[pOffset] & 0xC0) == 0) {
      return false;
    }

    pOffset += CHANNELDATA_CHANNELNUMBER_LENGTH;
    packetLength -= CHANNELDATA_CHANNELNUMBER_LENGTH;

    int length = ((pData[pOffset++] << 8) | (pData[pOffset] & 0xFF));

    int padding = ((length % 4) > 0) ? 4 - (length % 4) : 0;

    /*
     * The Length field specifies the length in bytes of the Application Data field. The Length field does not include
     * the padding that is sometimes present in the data of the DatagramPacket.
     */
    return length == packetLength - padding - CHANNELDATA_LENGTH_LENGTH
        || length == packetLength - CHANNELDATA_LENGTH_LENGTH;
  }
  /**
   * Log the packet.
   *
   * @param p packet to log
   */
  @Override
  protected void doLogPacket(DatagramPacket p) {
    if (socket.getLocalAddress() == null) return;

    // Do not log the packet if this one has been processed (and already
    // logged) by the ice4j stack.
    if (socket instanceof MultiplexingDatagramSocket) return;

    PacketLoggingService pktLogging = getPacketLoggingService();

    if (pktLogging != null) {
      pktLogging.logPacket(
          PacketLoggingService.ProtocolName.RTP,
          p.getAddress().getAddress(),
          p.getPort(),
          socket.getLocalAddress().getAddress(),
          socket.getLocalPort(),
          PacketLoggingService.TransportName.UDP,
          false,
          p.getData(),
          p.getOffset(),
          p.getLength());
    }
  }
Exemple #20
0
    /* Event deserialization. Returns the event or null if something wrong
     * happened.
     */
    private void receiveFormatSend(DatagramPacket p) {

      byte[] data = new byte[p.getLength()];
      System.arraycopy(p.getData(), p.getOffset(), data, 0, p.getLength());
      SendableEvent e = null;
      Message msg = null;

      try {
        /* Extract event class name */
        // size of class name
        int sLength = ParseUtils.byteArrayToInt(data, 0);
        // the class name
        String className = new String(data, 4, sLength, "ISO-8859-1");

        /* Create event */
        Class c = Class.forName(className);
        if (debugFull) {
          logReader.debug(":receiveAndFormat: Reader, creating " + className + " event.");
        }
        e = (SendableEvent) c.newInstance();
        msg = e.getMessage();
        msg.setByteArray(data, 4 + sLength, data.length - (4 + sLength));

        /* Extract channel hash and put event in it*/
        mbuf.len = 4;
        msg.pop(mbuf);
        int channelHash = ParseUtils.byteArrayToInt(mbuf.data, mbuf.off);
        Channel msgChannel = (Channel) parentSession.channels.get(new Integer(channelHash));

        /* If channel does not exist, discard message */
        if (msgChannel == null) {
          if (debugFull)
            logReader.debug(
                this.getClass().getName()
                    + ": channel does not exist. message will be discarded. "
                    + "hash="
                    + channelHash
                    + " "
                    + e);
          return;
        }

        if (debugFull)
          logReader.debug(
              ":receiveAndFormat: " + msgChannel.getChannelID() + " (" + channelHash + ")");

        /* Extract the addresses and put them on the event */

        // msg's source, futurely change udpsimple to common
        InetSocketAddress addr = new InetSocketAddress(p.getAddress(), p.getPort());
        e.source = addr;

        // msg's destination
        e.dest = dest;

        // send event
        e.asyncGo(msgChannel, Direction.UP);

      } catch (Exception ex) {
        if (logReader.isDebugEnabled()) {
          ex.printStackTrace();
          logReader.debug(
              "Exception catched while processing message from "
                  + p.getAddress().getHostName()
                  + ":"
                  + p.getPort()
                  + ". Continued operation.");
        }
      }
    }
  private void runOnDtlsTransport(StreamConnector connector) throws IOException {
    DtlsControlImpl dtlsControl = (DtlsControlImpl) getTransportManager().getDtlsControl(this);
    DtlsTransformEngine engine = dtlsControl.getTransformEngine();
    final DtlsPacketTransformer transformer = (DtlsPacketTransformer) engine.getRTPTransformer();

    byte[] receiveBuffer = new byte[SCTP_BUFFER_SIZE];

    if (LOG_SCTP_PACKETS) {
      System.setProperty(
          ConfigurationService.PNAME_SC_HOME_DIR_LOCATION, System.getProperty("java.io.tmpdir"));
      System.setProperty(
          ConfigurationService.PNAME_SC_HOME_DIR_NAME, SctpConnection.class.getName());
    }

    synchronized (this) {
      // FIXME local SCTP port is hardcoded in bridge offer SDP (Jitsi
      // Meet)
      sctpSocket = Sctp.createSocket(5000);
      assocIsUp = false;
      acceptedIncomingConnection = false;
    }

    // Implement output network link for SCTP stack on DTLS transport
    sctpSocket.setLink(
        new NetworkLink() {
          @Override
          public void onConnOut(SctpSocket s, byte[] packet) throws IOException {
            if (LOG_SCTP_PACKETS) {
              LibJitsi.getPacketLoggingService()
                  .logPacket(
                      PacketLoggingService.ProtocolName.ICE4J,
                      new byte[] {0, 0, 0, (byte) debugId},
                      5000,
                      new byte[] {0, 0, 0, (byte) (debugId + 1)},
                      remoteSctpPort,
                      PacketLoggingService.TransportName.UDP,
                      true,
                      packet);
            }

            // Send through DTLS transport
            transformer.sendApplicationData(packet, 0, packet.length);
          }
        });

    if (logger.isDebugEnabled()) {
      logger.debug("Connecting SCTP to port: " + remoteSctpPort + " to " + getEndpoint().getID());
    }

    sctpSocket.setNotificationListener(this);
    sctpSocket.listen();

    // FIXME manage threads
    threadPool.execute(
        new Runnable() {
          @Override
          public void run() {
            SctpSocket sctpSocket = null;
            try {
              // sctpSocket is set to null on close
              sctpSocket = SctpConnection.this.sctpSocket;
              while (sctpSocket != null) {
                if (sctpSocket.accept()) {
                  acceptedIncomingConnection = true;
                  break;
                }
                Thread.sleep(100);
                sctpSocket = SctpConnection.this.sctpSocket;
              }
              if (isReady()) {
                notifySctpConnectionReady();
              }
            } catch (Exception e) {
              logger.error("Error accepting SCTP connection", e);
            }

            if (sctpSocket == null && logger.isInfoEnabled()) {
              logger.info(
                  "SctpConnection " + getID() + " closed" + " before SctpSocket accept()-ed.");
            }
          }
        });

    // Notify that from now on SCTP connection is considered functional
    sctpSocket.setDataCallback(this);

    // Setup iceSocket
    DatagramSocket datagramSocket = connector.getDataSocket();
    if (datagramSocket != null) {
      this.iceSocket = new IceUdpSocketWrapper(datagramSocket);
    } else {
      this.iceSocket = new IceTcpSocketWrapper(connector.getDataTCPSocket());
    }

    DatagramPacket rcvPacket = new DatagramPacket(receiveBuffer, 0, receiveBuffer.length);

    // Receive loop, breaks when SCTP socket is closed
    try {
      do {
        iceSocket.receive(rcvPacket);

        RawPacket raw =
            new RawPacket(rcvPacket.getData(), rcvPacket.getOffset(), rcvPacket.getLength());

        raw = transformer.reverseTransform(raw);
        // Check for app data
        if (raw == null) continue;

        if (LOG_SCTP_PACKETS) {
          LibJitsi.getPacketLoggingService()
              .logPacket(
                  PacketLoggingService.ProtocolName.ICE4J,
                  new byte[] {0, 0, 0, (byte) (debugId + 1)},
                  remoteSctpPort,
                  new byte[] {0, 0, 0, (byte) debugId},
                  5000,
                  PacketLoggingService.TransportName.UDP,
                  false,
                  raw.getBuffer(),
                  raw.getOffset(),
                  raw.getLength());
        }

        // Pass network packet to SCTP stack
        sctpSocket.onConnIn(raw.getBuffer(), raw.getOffset(), raw.getLength());
      } while (true);
    } finally {
      // Eventually, close the socket although it should happen from
      // expire().
      synchronized (this) {
        assocIsUp = false;
        acceptedIncomingConnection = false;
        if (sctpSocket != null) {
          sctpSocket.close();
          sctpSocket = null;
        }
      }
    }
  }
  private void listenBroadCast() throws IOException {

    skt.receive(input);
    InetAddress from = input.getAddress();
    String received = new String(input.getData(), input.getOffset(), input.getLength());

    HttpResponse msg = null;
    try {
      msg = new HttpResponse(received);
    } catch (IllegalArgumentException ex) {
      // crappy http sent

      // log.debug( "Skipping uncompliant HTTP message " + received
      // );

      return;
    }
    String header = msg.getHeader();
    if (header != null
        && header.startsWith("HTTP/1.1 200 OK")
        && msg.getHTTPHeaderField("st") != null) {
      // probably a search repsonse !
      String deviceDescrLoc = msg.getHTTPHeaderField("location");
      if (deviceDescrLoc == null || deviceDescrLoc.trim().length() == 0) {
        // log.debug(
        // "Skipping SSDP message, missing HTTP header 'location' field"
        // );

        return;
      }
      URL loc = new URL(deviceDescrLoc);
      if (MATCH_IP) {
        InetAddress locHost = InetAddress.getByName(loc.getHost());
        if (!from.equals(locHost)) {
          /*
           * log.warn( "Discovery message sender IP " + from +
           * " does not match device description IP " + locHost +
           * " skipping device, set the net.sbbi.upnp.ddos.matchip system property"
           * + " to false to avoid this check" );
           */
          return;
        }
      }
      String st = msg.getHTTPHeaderField("st");
      if (st == null || st.trim().length() == 0) {
        // log.debug(
        // "Skipping SSDP message, missing HTTP header 'st' field"
        // );

        return;
      }
      String usn = msg.getHTTPHeaderField("usn");
      if (usn == null || usn.trim().length() == 0) {
        // log.debug(
        // "Skipping SSDP message, missing HTTP header 'usn' field"
        // );

        return;
      }
      String maxAge = msg.getHTTPFieldElement("Cache-Control", "max-age");
      if (maxAge == null || maxAge.trim().length() == 0) {
        // log.debug(
        // "Skipping SSDP message, missing HTTP header 'max-age' field"
        // );

        return;
      }
      String server = msg.getHTTPHeaderField("server");
      if (server == null || server.trim().length() == 0) {
        // log.debug(
        // "Skipping SSDP message, missing HTTP header 'server' field"
        // );

        return;
      }

      String udn = usn;
      int index = udn.indexOf("::");
      if (index != -1) {
        udn = udn.substring(0, index);
      }
      synchronized (REGISTRATION_PROCESS) {
        Set<DiscoveryResultsHandler> handlers = registeredHandlers.get(st);
        if (handlers != null) {
          for (DiscoveryResultsHandler handler : handlers) {
            handler.discoveredDevice(
                input.getAddress().toString(), usn, udn, st, maxAge, loc, server);
          }
        }
      }
    } else {
      // log.debug( "Skipping uncompliant HTTP message " + received
      // );
    }
  }
Exemple #23
0
  @Override
  public void run() {
    // TODO Auto-generated method stub
    while (running) {
      if (isDebug) Log.i(TAG, "5s扫描设备>>>>>>>>>>>>" + Thread.currentThread());
      receive = 50; // 最大接收数量
      isSend = false;
      String recestr = null;
      try {
        listDevices.clear();
        sendSocket = new DatagramSocket();
        sendSocket.setBroadcast(true);
        sendSocket.setSoTimeout(3000);
        sendSocket.send(sendPacket);
        while (receive-- > 0) {
          sendSocket.receive(recePacket);
          recestr = new String(recedata, recePacket.getOffset(), recePacket.getLength());
          if (recestr.startsWith(DISCOVERY_RESP)) {
            Device device = new Device();
            device.setDeviceName(recestr.substring(9));
            device.setDeviceIp(recePacket.getAddress().getHostAddress());
            if (listDevices.indexOf(device) < 0) {
              listDevices.add(device);
              if (device.getDeviceIp().equals("10.8.8.1")) {
                isSend = true;
                if (isDebug) Log.i(TAG, "扫描到10.8.8.1" + listDevices + "|" + Thread.currentThread());
                sendResult();
                break;
              }
            }
          }

          // 每次接收完UDP数据后,重置长度。否则可能会导致下次收到数据包被截断。
          recePacket.setLength(default_bufferSize);
        }
      } catch (SocketTimeoutException e) {
        if (isDebug) Log.i(TAG, "扫描3s超时" + listDevices + "|" + Thread.currentThread());
        if (!isSend) {
          sendResult();
        }
      } catch (SocketException e) {
        receive = 0;
        if (isDebug) Log.i(TAG, "SocketException>>>>>>" + Thread.currentThread());
        if (mScanListener != null) {
          mScanListener.scanException();
        }
      } catch (IOException e) {
        receive = 0;
        if (isDebug) Log.i(TAG, "SocketException>>>>>>" + Thread.currentThread());
        if (mScanListener != null) {
          mScanListener.scanException();
        }
      }
      sendSocket.close();

      if (wipicoVersion >= 2) {
        // 版本2才进行SSID 扫描
        List<ScanResult> listScanResults = WifiAdmin.getInstance(mContext).getScanResults();
        if (listScanResults != null) {
          for (ScanResult bean : listScanResults) {
            if (DeviceUtil.isMatchSSID(DeviceUtil.ssidCorrect(bean.SSID))) {
              listWifiDevices.add(
                  new Device(DeviceUtil.ssidCorrect(bean.SSID), bean.capabilities, null));
            }
          }
        }
        sendWifiResult();
      }

      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }