Example #1
0
 private void receivePing(Packet packet) {
   boolean ok = packet.verifySignature(_context, packet.getOptionalFrom(), null);
   if (!ok) {
     if (_log.shouldLog(Log.WARN)) {
       if (packet.getOptionalFrom() == null)
         _log.warn(
             "Ping with no from (flagged? " + packet.isFlagSet(Packet.FLAG_FROM_INCLUDED) + ")");
       else if (packet.getOptionalSignature() == null)
         _log.warn(
             "Ping with no signature (flagged? "
                 + packet.isFlagSet(Packet.FLAG_SIGNATURE_INCLUDED)
                 + ")");
       else
         _log.warn(
             "Forged ping, discard (from="
                 + packet.getOptionalFrom().calculateHash().toBase64()
                 + " sig="
                 + packet.getOptionalSignature().toBase64()
                 + ")");
     }
   } else {
     PacketLocal pong = new PacketLocal(_context, packet.getOptionalFrom());
     pong.setFlag(Packet.FLAG_ECHO, true);
     pong.setFlag(Packet.FLAG_SIGNATURE_INCLUDED, false);
     pong.setReceiveStreamId(packet.getSendStreamId());
     _manager.getPacketQueue().enqueue(pong);
   }
 }
Example #2
0
 private void sendReset(Packet packet) {
   boolean ok = packet.verifySignature(_context, packet.getOptionalFrom(), null);
   if (!ok) {
     if (_log.shouldLog(Log.WARN))
       _log.warn("Received a spoofed SYN packet: they said they were " + packet.getOptionalFrom());
     return;
   }
   PacketLocal reply = new PacketLocal(_context, packet.getOptionalFrom());
   reply.setFlag(Packet.FLAG_RESET);
   reply.setFlag(Packet.FLAG_SIGNATURE_INCLUDED);
   reply.setAckThrough(packet.getSequenceNum());
   reply.setSendStreamId(packet.getReceiveStreamId());
   reply.setReceiveStreamId(0);
   reply.setOptionalFrom(_manager.getSession().getMyDestination());
   if (_log.shouldLog(Log.DEBUG)) _log.debug("Sending RST: " + reply + " because of " + packet);
   // this just sends the packet - no retries or whatnot
   _manager.getPacketQueue().enqueue(reply);
 }
Example #3
0
 /**
  * This sends a reset back to the place this packet came from. If the packet has no 'optional
  * from' or valid signature, this does nothing. This is not associated with a connection, so no
  * con stats are updated.
  */
 private void sendReset(Packet packet) {
   Destination from = packet.getOptionalFrom();
   if (from == null) return;
   boolean ok = packet.verifySignature(_context, from, null);
   if (!ok) {
     if (_log.shouldLog(Log.WARN))
       _log.warn("Can't send reset after recv spoofed packet: " + packet);
     return;
   }
   PacketLocal reply = new PacketLocal(_context, from);
   reply.setFlag(Packet.FLAG_RESET);
   reply.setFlag(Packet.FLAG_SIGNATURE_INCLUDED);
   reply.setSendStreamId(packet.getReceiveStreamId());
   reply.setReceiveStreamId(packet.getSendStreamId());
   reply.setOptionalFrom(_manager.getSession().getMyDestination());
   // this just sends the packet - no retries or whatnot
   _manager.getPacketQueue().enqueue(reply);
 }
Example #4
0
  /**
   * Receive an incoming connection (built from a received SYN) Non-SYN packets with a zero
   * SendStreamID may also be queued here so that they don't get thrown away while the SYN packet
   * before it is queued.
   *
   * @param timeoutMs max amount of time to wait for a connection (if less than 1ms, wait
   *     indefinitely)
   * @return connection received, or null if there was a timeout or the handler was shut down
   */
  public Connection accept(long timeoutMs) {
    if (_log.shouldLog(Log.DEBUG)) _log.debug("Accept(" + timeoutMs + ") called");

    long expiration = timeoutMs + _context.clock().now();
    while (true) {
      if ((timeoutMs > 0) && (expiration < _context.clock().now())) return null;
      if (!_active) {
        // fail all the ones we had queued up
        while (true) {
          Packet packet = _synQueue.poll(); // fails immediately if empty
          if (packet == null || packet.getOptionalDelay() == PoisonPacket.POISON_MAX_DELAY_REQUEST)
            break;
          sendReset(packet);
        }
        return null;
      }

      Packet syn = null;
      while (_active && syn == null) {
        if (_log.shouldLog(Log.DEBUG))
          _log.debug(
              "Accept(" + timeoutMs + "): active=" + _active + " queue: " + _synQueue.size());
        if (timeoutMs <= 0) {
          try {
            syn = _synQueue.take(); // waits forever
          } catch (InterruptedException ie) {
          } // { break;}
        } else {
          long remaining = expiration - _context.clock().now();
          // (dont think this applies anymore for LinkedBlockingQueue)
          // BUGFIX
          // The specified amount of real time has elapsed, more or less.
          // If timeout is zero, however, then real time is not taken into consideration
          // and the thread simply waits until notified.
          if (remaining < 1) break;
          try {
            syn = _synQueue.poll(remaining, TimeUnit.MILLISECONDS); // waits the specified time max
          } catch (InterruptedException ie) {
          }
          break;
        }
      }

      if (syn != null) {
        if (syn.getOptionalDelay() == PoisonPacket.POISON_MAX_DELAY_REQUEST) return null;

        // deal with forged / invalid syn packets in _manager.receiveConnection()

        // Handle both SYN and non-SYN packets in the queue
        if (syn.isFlagSet(Packet.FLAG_SYNCHRONIZE)) {
          // We are single-threaded here, so this is
          // a good place to check for dup SYNs and drop them
          Destination from = syn.getOptionalFrom();
          if (from == null) {
            if (_log.shouldLog(Log.WARN)) _log.warn("Dropping SYN packet with no FROM: " + syn);
            // drop it
            continue;
          }
          Connection oldcon = _manager.getConnectionByOutboundId(syn.getReceiveStreamId());
          if (oldcon != null) {
            // His ID not guaranteed to be unique to us, but probably is...
            // only drop it on a destination match too
            if (from.equals(oldcon.getRemotePeer())) {
              if (_log.shouldLog(Log.WARN)) _log.warn("Dropping dup SYN: " + syn);
              continue;
            }
          }
          Connection con = _manager.receiveConnection(syn);
          if (con != null) return con;
        } else {
          reReceivePacket(syn);
          // ... and keep looping
        }
      }
      // keep looping...
    }
  }