/**
  * @param claimedAddress an IP/port based RemoteHostId, or null if unknown
  * @param remoteHostId non-null, == claimedAddress if direct, or a hash-based one if indirect
  * @param addr non-null
  */
 public OutboundEstablishState(
     RouterContext ctx,
     RemoteHostId claimedAddress,
     RemoteHostId remoteHostId,
     RouterIdentity remotePeer,
     SessionKey introKey,
     UDPAddress addr,
     DHSessionKeyBuilder.Factory dh) {
   _context = ctx;
   _log = ctx.logManager().getLog(OutboundEstablishState.class);
   if (claimedAddress != null) {
     _bobIP = claimedAddress.getIP();
     _bobPort = claimedAddress.getPort();
   } else {
     // _bobIP = null;
     _bobPort = -1;
   }
   _claimedAddress = claimedAddress;
   _remoteHostId = remoteHostId;
   _remotePeer = remotePeer;
   _introKey = introKey;
   _queuedMessages = new LinkedBlockingQueue<OutNetMessage>();
   _establishBegin = ctx.clock().now();
   _remoteAddress = addr;
   _introductionNonce = -1;
   _keyFactory = dh;
   if (addr.getIntroducerCount() > 0) {
     if (_log.shouldLog(Log.DEBUG))
       _log.debug(
           "new outbound establish to " + remotePeer.calculateHash() + ", with address: " + addr);
     _currentState = OutboundState.OB_STATE_PENDING_INTRO;
   } else {
     _currentState = OutboundState.OB_STATE_UNKNOWN;
   }
 }
  /**
   * Blocking call (run in the establisher thread) to determine if the session was created properly.
   * If it wasn't, all the SessionCreated remnants are dropped (perhaps they were spoofed, etc) so
   * that we can receive another one
   *
   * <p>Generates session key and mac key.
   *
   * @return true if valid
   */
  public synchronized boolean validateSessionCreated() {
    if (_currentState == OutboundState.OB_STATE_VALIDATION_FAILED) {
      if (_log.shouldLog(Log.WARN)) _log.warn("Session created already failed");
      return false;
    }
    if (_receivedSignature != null) {
      if (_log.shouldLog(Log.WARN)) _log.warn("Session created already validated");
      return true;
    }

    boolean valid = true;
    try {
      generateSessionKey();
    } catch (DHSessionKeyBuilder.InvalidPublicParameterException ippe) {
      if (_log.shouldLog(Log.WARN))
        _log.warn("Peer " + getRemoteHostId() + " sent us an invalid DH parameter", ippe);
      valid = false;
    }
    if (valid) decryptSignature();

    if (valid && verifySessionCreated()) {
      if (_log.shouldLog(Log.DEBUG)) _log.debug("Session created passed validation");
      return true;
    } else {
      if (_log.shouldLog(Log.WARN))
        _log.warn(
            "Session created failed validation, clearing state for " + _remoteHostId.toString());
      fail();
      return false;
    }
  }
示例#3
0
  /**
   * BLOCKING if queue between here and PacketHandler is full.
   *
   * @return zero (was queue size)
   */
  private final int doReceive(UDPPacket packet) {
    if (!_keepRunning) return 0;

    if (_log.shouldLog(Log.INFO)) _log.info("Received: " + packet);

    RemoteHostId from = packet.getRemoteHost();
    if (_transport.isInDropList(from)) {
      if (_log.shouldLog(Log.INFO)) _log.info("Ignoring packet from the drop-listed peer: " + from);
      _context.statManager().addRateData("udp.ignorePacketFromDroplist", packet.getLifetime());
      packet.release();
      return 0;
    }

    // drop anything apparently from our IP (any port)
    if (Arrays.equals(from.getIP(), _transport.getExternalIP()) && !_transport.allowLocal()) {
      if (_log.shouldLog(Log.WARN)) _log.warn("Dropping (spoofed?) packet from ourselves");
      packet.release();
      return 0;
    }

    /**
     * ** packet.enqueue(); boolean rejected = false; int queueSize = 0; long headPeriod = 0;
     *
     * <p>UDPPacket head = _inboundQueue.peek(); if (head != null) { headPeriod =
     * head.getLifetime(); if (headPeriod > MAX_QUEUE_PERIOD) { rejected = true; } } if (!rejected)
     * { **
     */
    try {
      _handler.queueReceived(packet);
    } catch (InterruptedException ie) {
      packet.release();
      _keepRunning = false;
    }
    // return queueSize + 1;
    return 0;
    /**
     * ** }
     *
     * <p>// rejected packet.release(); _context.statManager().addRateData("udp.droppedInbound",
     * queueSize, headPeriod); if (_log.shouldLog(Log.WARN)) { queueSize = _inboundQueue.size();
     * StringBuilder msg = new StringBuilder(); msg.append("Dropping inbound packet with ");
     * msg.append(queueSize); msg.append(" queued for "); msg.append(headPeriod); msg.append("
     * packet handlers: ").append(_transport.getPacketHandlerStatus()); _log.warn(msg.toString()); }
     * return queueSize; **
     */
  }