Esempio n. 1
0
    /**
     * Call when the ports might have changed
     * The transports can call this pretty quickly at startup,
     * which can have multiple UPnP threads running at once, but
     * that should be ok.
     */
    public void update(Set<TransportManager.Port> ports) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("UPnP Update with " + ports.size() + " ports");

        //synchronized(this) {
            // TODO
            // called too often and may block for too long
            // may not have started if net was disconnected previously
            //if (!_isRunning && !ports.isEmpty())
            //    start();
            if (!_isRunning)
                return;
        //}

        Set<ForwardPort> forwards = new HashSet<ForwardPort>(ports.size());
        for (TransportManager.Port entry : ports) {
            String style = entry.style;
            int port = entry.port;
            int protocol = -1;
            if ("SSU".equals(style))
                protocol = ForwardPort.PROTOCOL_UDP_IPV4;
            else if ("NTCP".equals(style))
                protocol = ForwardPort.PROTOCOL_TCP_IPV4;
            else
                continue;
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Adding: " + style + " " + port);
            ForwardPort fp = new ForwardPort(style, false, protocol, port);
            forwards.add(fp);
        }
        // non-blocking
        _upnp.onChangePublicPorts(forwards, _upnpCallback);
    }
Esempio n. 2
0
 /**
  * Fetch to memory
  *
  * @param retries if < 0, set timeout to a few seconds
  * @param initialSize buffer size
  * @param maxSize fails if greater
  * @return null on error
  * @since 0.9.4
  */
 public byte[] get(String url, boolean rewrite, int retries, int initialSize, int maxSize) {
   if (_log.shouldLog(Log.DEBUG)) _log.debug("Fetching [" + url + "] to memory");
   String fetchURL = url;
   if (rewrite) fetchURL = rewriteAnnounce(url);
   int timeout;
   if (retries < 0) {
     if (!connected()) return null;
     timeout = EEPGET_CONNECT_TIMEOUT_SHORT;
     retries = 0;
   } else {
     timeout = EEPGET_CONNECT_TIMEOUT;
     if (!connected()) {
       if (!connect()) return null;
     }
   }
   ByteArrayOutputStream out = new ByteArrayOutputStream(initialSize);
   EepGet get = new I2PSocketEepGet(_context, _manager, retries, -1, maxSize, null, out, fetchURL);
   get.addHeader("User-Agent", EEPGET_USER_AGENT);
   if (get.fetch(timeout)) {
     if (_log.shouldLog(Log.DEBUG))
       _log.debug("Fetch successful [" + url + "]: size=" + out.size());
     return out.toByteArray();
   } else {
     if (_log.shouldLog(Log.WARN)) _log.warn("Fetch failed [" + url + "]");
     return null;
   }
 }
Esempio n. 3
0
  /**
   * SOCKS5 connection initialization. This method assumes that SOCKS "VER" field has been stripped
   * from the input stream.
   */
  private void init(DataInputStream in, DataOutputStream out) throws IOException, SOCKSException {
    int nMethods = in.readUnsignedByte();
    int method = Method.NO_ACCEPTABLE_METHODS;

    for (int i = 0; i < nMethods; ++i) {
      int meth = in.readUnsignedByte();
      if (((!authRequired) && meth == Method.NO_AUTH_REQUIRED)
          || (authRequired && meth == Method.USERNAME_PASSWORD)) {
        // That's fine, we do support this method
        method = meth;
      }
    }

    switch (method) {
      case Method.USERNAME_PASSWORD:
        _log.debug("username/password authentication required");
        sendInitReply(Method.USERNAME_PASSWORD, out);
        verifyPassword(in, out);
        return;
      case Method.NO_AUTH_REQUIRED:
        _log.debug("no authentication required");
        sendInitReply(Method.NO_AUTH_REQUIRED, out);
        return;
      default:
        _log.debug(
            "no suitable authentication methods found (" + Integer.toHexString(method) + ")");
        sendInitReply(Method.NO_ACCEPTABLE_METHODS, out);
        throw new SOCKSException("Unsupported authentication method");
    }
  }
Esempio n. 4
0
 public int allocPage() throws IOException {
   if (freeListStart != 0) {
     try {
       if (flb == null) flb = new FreeListBlock(file, freeListStart);
       if (!flb.isEmpty()) {
         if (log.shouldLog(Log.DEBUG)) log.debug("Alloc from " + flb);
         return flb.takePage();
       } else {
         if (log.shouldLog(Log.DEBUG)) log.debug("Alloc returning empty " + flb);
         freeListStart = flb.getNextPage();
         writeSuperBlock();
         int rv = flb.page;
         flb = null;
         return rv;
       }
     } catch (IOException ioe) {
       log.error("Discarding corrupt free list block page " + freeListStart, ioe);
       freeListStart = 0;
     }
   }
   long offset = file.length();
   fileLen = offset + PAGESIZE;
   file.setLength(fileLen);
   writeSuperBlock();
   return (int) ((offset / PAGESIZE) + 1);
 }
Esempio n. 5
0
  protected boolean execStreamClose(Properties props) {
    if (props == null) {
      _log.debug("No parameters specified in STREAM CLOSE message");
      return false;
    }

    int id;
    {
      String strid = props.getProperty("ID");
      if (strid == null) {
        _log.debug("ID not specified in STREAM CLOSE message");
        return false;
      }
      try {
        id = Integer.parseInt(strid);
      } catch (NumberFormatException e) {
        _log.debug("Invalid STREAM CLOSE ID specified: " + strid);
        return false;
      }
    }

    boolean closed = getStreamSession().closeConnection(id);
    if ((!closed) && (_log.shouldLog(Log.WARN)))
      _log.warn("Stream unable to be closed, but this is non fatal");
    return true;
  }
Esempio n. 6
0
  /**
   * Called when a full chunk (i.e. a piece message) has been received by PeerConnectionIn.
   *
   * <p>This may block quite a while if it is the last chunk for a piece, as it calls the listener,
   * who stores the piece and then calls havePiece for every peer on the torrent (including us).
   */
  void pieceMessage(Request req) {
    int size = req.len;
    peer.downloaded(size);
    listener.downloaded(peer, size);

    if (_log.shouldLog(Log.DEBUG))
      _log.debug(
          "got end of Chunk(" + req.getPiece() + "," + req.off + "," + req.len + ") from " + peer);

    // Last chunk needed for this piece?
    // FIXME if priority changed to skip, we will think we're done when we aren't
    if (getFirstOutstandingRequest(req.getPiece()) == -1) {
      // warning - may block here for a while
      if (listener.gotPiece(peer, req.getPartialPiece())) {
        if (_log.shouldLog(Log.DEBUG)) _log.debug("Got " + req.getPiece() + ": " + peer);
      } else {
        if (_log.shouldLog(Log.WARN)) _log.warn("Got BAD " + req.getPiece() + " from " + peer);
      }
    }

    // ok done with this one
    synchronized (this) {
      pendingRequest = null;
    }
  }
Esempio n. 7
0
File: Peer.java Progetto: hilbix/i2p
  /**
   * Sets DataIn/OutputStreams, does the handshake and returns the id reported by the other side.
   */
  private byte[] handshake(InputStream in, OutputStream out) throws IOException {
    din = new DataInputStream(in);
    dout = new DataOutputStream(out);

    // Handshake write - header
    dout.write(19);
    dout.write("BitTorrent protocol".getBytes("UTF-8"));
    // Handshake write - options
    long myOptions = OPTION_EXTENSION;
    // FIXME get util here somehow
    // if (util.getDHT() != null)
    //    myOptions |= OPTION_I2P_DHT;
    dout.writeLong(myOptions);
    // Handshake write - metainfo hash
    dout.write(infohash);
    // Handshake write - peer id
    dout.write(my_id);
    dout.flush();

    if (_log.shouldLog(Log.DEBUG)) _log.debug("Wrote my shared hash and ID to " + toString());

    // Handshake read - header
    byte b = din.readByte();
    if (b != 19)
      throw new IOException("Handshake failure, expected 19, got " + (b & 0xff) + " on " + sock);

    byte[] bs = new byte[19];
    din.readFully(bs);
    String bittorrentProtocol = new String(bs, "UTF-8");
    if (!"BitTorrent protocol".equals(bittorrentProtocol))
      throw new IOException(
          "Handshake failure, expected "
              + "'Bittorrent protocol', got '"
              + bittorrentProtocol
              + "'");

    // Handshake read - options
    options = din.readLong();

    // Handshake read - metainfo hash
    bs = new byte[20];
    din.readFully(bs);
    if (!Arrays.equals(infohash, bs)) throw new IOException("Unexpected MetaInfo hash");

    // Handshake read - peer id
    din.readFully(bs);
    if (_log.shouldLog(Log.DEBUG))
      _log.debug("Read the remote side's hash and peerID fully from " + toString());

    if (DataHelper.eq(my_id, bs)) throw new IOException("Connected to myself");

    if (options != 0) {
      // send them something in runConnection() above
      if (_log.shouldLog(Log.DEBUG))
        _log.debug("Peer supports options 0x" + Long.toString(options, 16) + ": " + toString());
    }

    return bs;
  }
Esempio n. 8
0
 public void debug(String msg, Object arg0, Object arg1) {
   if (arg0 == null && arg1 == null) {
     _log.debug(msg);
   } else if (arg0 != null && arg1 == null && arg0 instanceof Throwable) {
     _log.debug(msg, (Throwable) arg0);
   } else if (_log.shouldLog(Log.DEBUG)) {
     synchronized (_buffer) {
       format(msg, arg0, arg1);
       _log.debug(_buffer.toString());
     }
   }
 }
Esempio n. 9
0
 /**
  *  Blocking, may take a while, up to 20 seconds
  */
 public synchronized void stop() {
     if (_log.shouldLog(Log.DEBUG))
         _log.debug("UPnP Stop");
     _shouldBeRunning = false;
     _rescanner.cancel();
     if (_isRunning)
         _upnp.terminate();
     _isRunning = false;
     _detectedAddress = null;
     if (_log.shouldLog(Log.DEBUG))
         _log.debug("UPnP Stop Done");
 }
 /**
  * @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;
   }
 }
Esempio n. 11
0
 synchronized void setChoking(boolean choke) {
   if (choking != choke) {
     if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " setChoking(" + choke + ")");
     choking = choke;
     out.sendChoke(choke);
   }
 }
Esempio n. 12
0
  /**
   * @return lowest offset of any request for the piece
   * @since 0.8.2
   */
  private synchronized Request getLowestOutstandingRequest(int piece) {
    Request rv = null;
    int lowest = Integer.MAX_VALUE;
    for (Request r : outstandingRequests) {
      if (r.getPiece() == piece && r.off < lowest) {
        lowest = r.off;
        rv = r;
      }
    }
    if (pendingRequest != null && pendingRequest.getPiece() == piece && pendingRequest.off < lowest)
      rv = pendingRequest;

    if (_log.shouldLog(Log.DEBUG))
      _log.debug(
          peer
              + " lowest for "
              + piece
              + " is "
              + rv
              + " out of "
              + pendingRequest
              + " and "
              + outstandingRequests);
    return rv;
  }
Esempio n. 13
0
  private void connectWithPeers() {
    if (_peerDestFiles != null) {
      for (int i = 0; i < _peerDestFiles.length; i++) {
        try {
          FileInputStream fin = new FileInputStream(_peerDestFiles[i]);
          byte dest[] = new byte[1024];
          int read = DataHelper.read(fin, dest);

          String remDest = new String(dest, 0, read);
          int con = 0;
          Flooder flooder = null;
          synchronized (_remotePeers) {
            con = _remotePeers.size() + 1;
            flooder = new Flooder(con, remDest);
            _remotePeers.put(new Integer(con), flooder);
          }

          byte msg[] =
              (DataHelper.getUTF8("STREAM CONNECT ID=" + con + " DESTINATION=" + remDest + "\n"));
          synchronized (_samOut) {
            _samOut.write(msg);
            _samOut.flush();
          }
          I2PThread flood = new I2PThread(flooder, "Flood " + con);
          flood.start();
          _log.debug("Starting flooder with peer from " + _peerDestFiles[i] + ": " + con);
        } catch (IOException ioe) {
          _log.error("Unable to read the peer from " + _peerDestFiles[i]);
        }
      }
    }
  }
Esempio n. 14
0
  /**
   * This is the callback that PeerConnectionOut calls
   *
   * @return bytes or null for errors
   * @since 0.8.2
   */
  public ByteArray loadData(int piece, int begin, int length) {
    ByteArray pieceBytes = listener.gotRequest(peer, piece, begin, length);
    if (pieceBytes == null) {
      // XXX - Protocol error-> diconnect?
      if (_log.shouldLog(Log.WARN)) _log.warn("Got request for unknown piece: " + piece);
      return null;
    }

    // More sanity checks
    if (length != pieceBytes.getData().length) {
      // XXX - Protocol error-> disconnect?
      if (_log.shouldLog(Log.WARN))
        _log.warn(
            "Got out of range 'request: "
                + piece
                + ", "
                + begin
                + ", "
                + length
                + "' message from "
                + peer);
      return null;
    }

    if (_log.shouldLog(Log.DEBUG))
      _log.debug("Sending (" + piece + ", " + begin + ", " + length + ")" + " to " + peer);
    return pieceBytes;
  }
Esempio n. 15
0
  void bitfieldMessage(byte[] bitmap) {
    synchronized (this) {
      if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " rcv bitfield");
      if (bitfield != null) {
        // XXX - Be liberal in what you accept?
        if (_log.shouldLog(Log.WARN)) _log.warn("Got unexpected bitfield message from " + peer);
        return;
      }

      // XXX - Check for weird bitfield and disconnect?
      // FIXME will have to regenerate the bitfield after we know exactly
      // how many pieces there are, as we don't know how many spare bits there are.
      if (metainfo == null) bitfield = new BitField(bitmap, bitmap.length * 8);
      else bitfield = new BitField(bitmap, metainfo.getPieces());
    }
    if (metainfo == null) return;
    boolean interest = listener.gotBitField(peer, bitfield);
    setInteresting(interest);
    if (bitfield.complete() && !interest) {
      // They are seeding and we are seeding,
      // why did they contact us? (robert)
      // Dump them quick before we send our whole bitmap
      if (_log.shouldLog(Log.WARN)) _log.warn("Disconnecting seed that connects to seeds: " + peer);
      peer.disconnect(true);
    }
  }
  /**
   * Distribute the message. If the dest is local, it blocks until its passed to the target
   * ClientConnectionRunner (which then fires it into a MessageReceivedJob). If the dest is remote,
   * it blocks until it is added into the ClientMessagePool
   */
  MessageId distributeMessage(SendMessageMessage message) {
    Payload payload = message.getPayload();
    Destination dest = message.getDestination();
    MessageId id = new MessageId();
    id.setMessageId(getNextMessageId());
    long expiration = 0;
    int flags = 0;
    if (message.getType() == SendMessageExpiresMessage.MESSAGE_TYPE) {
      SendMessageExpiresMessage msg = (SendMessageExpiresMessage) message;
      expiration = msg.getExpirationTime();
      flags = msg.getFlags();
    }
    if (message.getNonce() != 0 && !_dontSendMSM) _acceptedPending.add(id);

    if (_log.shouldLog(Log.DEBUG))
      _log.debug(
          "** Receiving message "
              + id.getMessageId()
              + " with payload of size "
              + payload.getSize()
              + " for session "
              + _sessionId.getSessionId());
    // long beforeDistribute = _context.clock().now();
    // the following blocks as described above
    SessionConfig cfg = _config;
    if (cfg != null)
      _manager.distributeMessage(cfg.getDestination(), dest, payload, id, expiration, flags);
    // else log error?
    // long timeToDistribute = _context.clock().now() - beforeDistribute;
    // if (_log.shouldLog(Log.DEBUG))
    //    _log.warn("Time to distribute in the manager to "
    //              + dest.calculateHash().toBase64() + ": "
    //              + timeToDistribute);
    return id;
  }
Esempio n. 17
0
 /**
  * Can't find a published standard for this anywhere. See the libtorrent code. Here we use the
  * "added" key as a single string of concatenated 32-byte peer hashes. added.f and dropped
  * unsupported
  *
  * @since 0.8.4
  */
 private static void handlePEX(Peer peer, PeerListener listener, byte[] bs, Log log) {
   if (log.shouldLog(Log.DEBUG)) log.debug("Got PEX msg from " + peer);
   try {
     InputStream is = new ByteArrayInputStream(bs);
     BDecoder dec = new BDecoder(is);
     BEValue bev = dec.bdecodeMap();
     Map<String, BEValue> map = bev.getMap();
     bev = map.get("added");
     if (bev == null) return;
     byte[] ids = bev.getBytes();
     if (ids.length < HASH_LENGTH) return;
     int len = Math.min(ids.length, (I2PSnarkUtil.MAX_CONNECTIONS - 1) * HASH_LENGTH);
     List<PeerID> peers = new ArrayList<PeerID>(len / HASH_LENGTH);
     for (int off = 0; off < len; off += HASH_LENGTH) {
       byte[] hash = new byte[HASH_LENGTH];
       System.arraycopy(ids, off, hash, 0, HASH_LENGTH);
       if (DataHelper.eq(hash, peer.getPeerID().getDestHash())) continue;
       PeerID pID = new PeerID(hash, listener.getUtil());
       peers.add(pID);
     }
     // could include ourselves, listener must remove
     listener.gotPeers(peer, peers);
   } catch (Exception e) {
     if (log.shouldLog(Log.INFO)) log.info("PEX msg exception from " + peer, e);
     // peer.disconnect(false);
   }
 }
  /**
   * There is no more data coming from the I2P side. Does NOT clear pending data. messageReceived()
   * MUST have been called previously with the messageId of the CLOSE packet.
   */
  public void closeReceived() {
    synchronized (_dataLock) {
      if (_log.shouldLog(Log.DEBUG)) {
        StringBuilder buf = new StringBuilder(128);
        buf.append("Close received, ready bytes: ");
        long available = 0;
        for (int i = 0; i < _readyDataBlocks.size(); i++)
          available += _readyDataBlocks.get(i).getValid();
        available -= _readyDataBlockIndex;
        buf.append(available);
        buf.append(" blocks: ").append(_readyDataBlocks.size());

        buf.append(" not ready blocks: ");
        long notAvailable = 0;
        for (Long id : _notYetReadyBlocks.keySet()) {
          ByteArray ba = _notYetReadyBlocks.get(id);
          buf.append(id).append(" ");

          if (ba != null) notAvailable += ba.getValid();
        }

        buf.append("not ready bytes: ").append(notAvailable);
        buf.append(" highest ready block: ").append(_highestReadyBlockId);

        _log.debug(buf.toString(), new Exception("closed"));
      }
      _closeReceived = true;
      _dataLock.notifyAll();
    }
  }
Esempio n. 19
0
    public void run() {
      String header = null;
      String nick;
      String dest;
      String version;

      try {
        header = DataHelper.readLine(is).trim();
        StringTokenizer tok = new StringTokenizer(header, " ");
        if (tok.countTokens() != 3) {
          // This is not a correct message, for sure
          _log.debug("Error in message format");
          return;
        }
        version = tok.nextToken();
        if (!"3.0".equals(version)) return;
        nick = tok.nextToken();
        dest = tok.nextToken();

        byte[] data = new byte[is.available()];
        is.read(data);
        SessionRecord rec = sSessionsHash.get(nick);
        if (rec != null) {
          rec.getHandler().session.sendBytes(dest, data);
        }
      } catch (Exception e) {
      }
    }
Esempio n. 20
0
 /**
  * Send the specified reply during SOCKS5 authorization
  *
  * @since 0.8.2
  */
 private void sendAuthReply(int replyCode, DataOutputStream out) throws IOException {
   byte[] reply = new byte[2];
   reply[0] = AUTH_VERSION;
   reply[1] = (byte) replyCode;
   if (_log.shouldLog(Log.DEBUG)) _log.debug("Sending auth reply:\n" + HexDump.dump(reply));
   out.write(reply);
 }
Esempio n. 21
0
  /**
   * Constructs a new <code>TrustedUpdate</code> with the given {@link net.i2p.I2PAppContext}.
   *
   * @param context An instance of <code>I2PAppContext</code>.
   */
  public TrustedUpdate(I2PAppContext context) {
    _context = context;
    _log = _context.logManager().getLog(TrustedUpdate.class);
    _trustedKeys = new HashMap(4);

    String propertyTrustedKeys = context.getProperty(PROP_TRUSTED_KEYS);

    if ((propertyTrustedKeys != null) && (propertyTrustedKeys.length() > 0)) {
      StringTokenizer propertyTrustedKeysTokens =
          new StringTokenizer(propertyTrustedKeys, " ,\r\n");

      while (propertyTrustedKeysTokens.hasMoreTokens()) {
        // If a key from the defaults, use the same name
        String key = propertyTrustedKeysTokens.nextToken().trim();
        String name = DEFAULT_KEYS.get(key);
        if (name == null) name = "";
        addKey(key, name);
      }
    } else {
      for (Map.Entry<String, String> e : DEFAULT_KEYS.entrySet()) {
        addKey(e.getKey(), e.getValue());
      }
    }
    if (_log.shouldLog(Log.DEBUG))
      _log.debug("TrustedUpdate created, trusting " + _trustedKeys.size() + " keys.");
  }
Esempio n. 22
0
  public void load(Properties props) {
    _successfulLookups = getLong(props, "dbHistory.successfulLookups");
    _failedLookups = getLong(props, "dbHistory.failedLookups");
    _lookupsReceived = getLong(props, "dbHistory.lookupsReceived");
    _lookupReplyDuplicate = getLong(props, "dbHistory.lookupReplyDuplicate");
    _lookupReplyInvalid = getLong(props, "dbHistory.lookupReplyInvalid");
    _lookupReplyNew = getLong(props, "dbHistory.lookupReplyNew");
    _lookupReplyOld = getLong(props, "dbHistory.lookupReplyOld");
    _unpromptedDbStoreNew = getLong(props, "dbHistory.unpromptedDbStoreNew");
    _unpromptedDbStoreOld = getLong(props, "dbHistory.unpromptedDbStoreOld");
    _lastLookupReceived = getLong(props, "dbHistory.lastLookupReceived");
    _avgDelayBetweenLookupsReceived = getLong(props, "dbHistory.avgDelayBetweenLookupsReceived");
    try {
      _failedLookupRate.load(props, "dbHistory.failedLookupRate", true);
      _log.debug("Loading dbHistory.failedLookupRate");
    } catch (IllegalArgumentException iae) {
      _log.warn("DB History failed lookup rate is corrupt, resetting", iae);
    }

    try {
      _invalidReplyRate.load(props, "dbHistory.invalidReplyRate", true);
    } catch (IllegalArgumentException iae) {
      _log.warn("DB History invalid reply rate is corrupt, resetting", iae);
      createRates(_statGroup);
    }
  }
  /**
   * 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;
    }
  }
Esempio n. 24
0
  /**
   * Returns <code>true</code> if one or more client threads are running in a given plugin.
   *
   * @param pluginName
   * @return true if running
   */
  private static boolean isClientThreadRunning(String pluginName, RouterContext ctx) {
    ThreadGroup group = pluginThreadGroups.get(pluginName);
    if (group == null) return false;
    boolean rv = group.activeCount() > 0;

    // Plugins start before the eepsite, and will create the static Timer thread
    // in RolloverFileOutputStream, which never stops. Don't count it.
    if (rv) {
      Log log = ctx.logManager().getLog(PluginStarter.class);
      Thread[] activeThreads = new Thread[128];
      int count = group.enumerate(activeThreads);
      boolean notRollover = false;
      for (int i = 0; i < count; i++) {
        if (activeThreads[i] != null) {
          String name = activeThreads[i].getName();
          if (!"org.eclipse.jetty.util.RolloverFileOutputStream".equals(name)) notRollover = true;
          if (log.shouldLog(Log.DEBUG))
            log.debug(
                "Found " + activeThreads[i].getState() + " thread for " + pluginName + ": " + name);
        }
      }
      rv = notRollover;
    }

    return rv;
  }
Esempio n. 25
0
  public long receiveEncrypted(byte encrypted[]) {
    TunnelDataMessage msg = new TunnelDataMessage(_context);
    msg.setData(encrypted);
    msg.setTunnelId(_config.getConfig(0).getSendTunnel());

    if (_log.shouldLog(Log.DEBUG))
      _log.debug("received encrypted, sending out " + _config + ": " + msg);
    RouterInfo ri = _nextHopCache;
    if (ri == null) ri = _context.netDb().lookupRouterInfoLocally(_config.getPeer(1));
    if (ri != null) {
      _nextHopCache = ri;
      send(msg, ri);
      return msg.getUniqueId();
    } else {
      // It should be rare to forget the router info for a peer in our own tunnel.
      if (_log.shouldLog(Log.WARN))
        _log.warn("lookup of " + _config.getPeer(1) + " required for " + msg);
      _context
          .netDb()
          .lookupRouterInfo(
              _config.getPeer(1),
              new SendJob(_context, msg),
              new FailedJob(_context),
              MAX_LOOKUP_TIME);
      return -1;
    }
  }
Esempio n. 26
0
 /** Create a new search for the routingKey specified */
 public SearchJob(
     RouterContext context,
     KademliaNetworkDatabaseFacade facade,
     Hash key,
     Job onSuccess,
     Job onFailure,
     long timeoutMs,
     boolean keepStats,
     boolean isLease) {
   super(context);
   if ((key == null) || (key.getData() == null))
     throw new IllegalArgumentException("Search for null key?  wtf");
   _log = getContext().logManager().getLog(getClass());
   _facade = facade;
   _state = new SearchState(getContext(), key);
   _onSuccess = onSuccess;
   _onFailure = onFailure;
   _timeoutMs = timeoutMs;
   _keepStats = keepStats;
   _isLease = isLease;
   _deferredSearches = new ArrayList(0);
   _peerSelector = facade.getPeerSelector();
   _startedOn = -1;
   _expiration = getContext().clock().now() + timeoutMs;
   getContext().statManager().addRateData("netDb.searchCount", 1, 0);
   if (_log.shouldLog(Log.DEBUG))
     _log.debug(
         "Search (" + getClass().getName() + " for " + key.toBase64(),
         new Exception("Search enqueued by"));
 }
Esempio n. 27
0
  /** Search totally failed */
  protected void fail() {
    if (isLocal()) {
      if (_log.shouldLog(Log.ERROR))
        _log.error(
            getJobId()
                + ": why did we fail if the target is local?: "
                + _state.getTarget().toBase64(),
            new Exception("failure cause"));
      succeed();
      return;
    }

    if (_log.shouldLog(Log.INFO))
      _log.info(getJobId() + ": Failed search for key " + _state.getTarget());
    if (_log.shouldLog(Log.DEBUG)) _log.debug(getJobId() + ": State of failed search: " + _state);

    long time = getContext().clock().now() - _state.getWhenStarted();
    int attempted = _state.getAttempted().size();
    getContext().statManager().addRateData("netDb.failedAttemptedPeers", attempted, time);

    if (_keepStats) {
      getContext().statManager().addRateData("netDb.failedTime", time, 0);
      // _facade.fail(_state.getTarget());
    }
    if (_onFailure != null) getContext().jobQueue().addJob(_onFailure);

    _facade.searchComplete(_state.getTarget());
    handleDeferred(false);
  }
Esempio n. 28
0
  /** Search was totally successful */
  private void succeed() {
    if (_log.shouldLog(Log.INFO))
      _log.info(
          getJobId()
              + ": Succeeded search for key "
              + _state.getTarget()
              + " after querying "
              + _state.getAttempted().size());
    if (_log.shouldLog(Log.DEBUG))
      _log.debug(getJobId() + ": State of successful search: " + _state);

    if (_keepStats) {
      long time = getContext().clock().now() - _state.getWhenStarted();
      getContext().statManager().addRateData("netDb.successTime", time, 0);
      getContext()
          .statManager()
          .addRateData("netDb.successPeers", _state.getAttempted().size(), time);
    }
    if (_onSuccess != null) getContext().jobQueue().addJob(_onSuccess);

    _facade.searchComplete(_state.getTarget());

    handleDeferred(true);

    resend();
  }
Esempio n. 29
0
 /**
  * Set of Hash structures for routers we want to check next. This is the 'interesting' part of the
  * algorithm. But to keep you on your toes, we've refactored it to the
  * PeerSelector.selectNearestExplicit
  *
  * @return ordered list of Hash objects
  */
 private List getClosestRouters(Hash key, int numClosest, Set alreadyChecked) {
   Hash rkey = getContext().routingKeyGenerator().getRoutingKey(key);
   if (_log.shouldLog(Log.DEBUG))
     _log.debug(getJobId() + ": Current routing key for " + key + ": " + rkey);
   return _peerSelector.selectNearestExplicit(
       rkey, numClosest, alreadyChecked, _facade.getKBuckets());
 }
Esempio n. 30
0
 /**
  * Add the page to the free list. The file is never shrunk. TODO: Reclaim free pages at end of
  * file, or even do a full compaction. Does not throw exceptions; logs on failure.
  */
 public void freePage(int page) {
   if (page <= METAINDEX_PAGE) {
     log.error("Bad page free attempt: " + page);
     return;
   }
   try {
     if (freeListStart == 0) {
       freeListStart = page;
       FreeListBlock.initPage(file, page);
       writeSuperBlock();
       if (log.shouldLog(Log.DEBUG)) log.debug("Freed page " + page + " as new FLB");
       return;
     }
     try {
       if (flb == null) flb = new FreeListBlock(file, freeListStart);
       if (flb.isFull()) {
         // Make the free page a new FLB
         if (log.shouldLog(Log.DEBUG)) log.debug("Full: " + flb);
         FreeListBlock.initPage(file, page);
         if (flb.getNextPage() == 0) {
           // Put it at the tail.
           // Next free will make a new FLB at the head,
           // so we have one more FLB than we need.
           flb.setNextPage(page);
         } else {
           // Put it at the head
           flb = new FreeListBlock(file, page);
           flb.setNextPage(freeListStart);
           freeListStart = page;
           writeSuperBlock();
         }
         if (log.shouldLog(Log.DEBUG)) log.debug("Freed page " + page + " to full " + flb);
         return;
       }
       flb.addPage(page);
       if (log.shouldLog(Log.DEBUG)) log.debug("Freed page " + page + " to " + flb);
     } catch (IOException ioe) {
       log.error("Discarding corrupt free list block page " + freeListStart, ioe);
       freeListStart = page;
       FreeListBlock.initPage(file, page);
       writeSuperBlock();
       flb = null;
     }
   } catch (IOException ioe) {
     log.error("Error freeing page: " + page, ioe);
   }
 }