/** write the message body to the output array, starting at the given index */
  protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
    if ((_tunnelId == null) || ((_msg == null) && (_msgData == null))) {
      _log.log(Log.CRIT, "failing to write out gateway message");
      throw new I2NPMessageException(
          "Not enough data to write out (id=" + _tunnelId + " data=" + _msg + ")");
    }

    DataHelper.toLong(out, curIndex, 4, _tunnelId.getTunnelId());
    curIndex += 4;
    synchronized (this) {
      if (_msgData == null) {
        _msgData = _msg.toByteArray();
        _msg = null;
      }
    }
    DataHelper.toLong(out, curIndex, 2, _msgData.length);
    curIndex += 2;
    // where is this coming from?
    if (curIndex + _msgData.length > out.length) {
      _log.log(
          Log.ERROR,
          "output buffer too small idx: "
              + curIndex
              + " len: "
              + _msgData.length
              + " outlen: "
              + out.length);
      throw new I2NPMessageException(
          "Too much data to write out (id=" + _tunnelId + " data=" + _msg + ")");
    }
    System.arraycopy(_msgData, 0, out, curIndex, _msgData.length);
    curIndex += _msgData.length;
    return curIndex;
  }
Exemple #2
0
 /**
  * The local router has detected a failure in the given tunnel
  *
  * @param tunnel tunnel failed
  */
 public void tunnelFailed(TunnelId tunnel) {
   if (!_doLog) return;
   if (tunnel == null) return;
   StringBuilder buf = new StringBuilder(128);
   buf.append(getPrefix());
   buf.append("failing tunnel [").append(tunnel.getTunnelId()).append("]");
   addEntry(buf.toString());
 }
Exemple #3
0
 /**
  * The peer did not accept the tunnel join for the given reason (this may be because of a timeout
  * or an explicit refusal).
  */
 public void tunnelRequestTimedOut(Hash peer, TunnelId tunnel) {
   if (!_doLog) return;
   if ((tunnel == null) || (peer == null)) return;
   StringBuilder buf = new StringBuilder(128);
   buf.append(getPrefix());
   buf.append("tunnel [").append(tunnel.getTunnelId()).append("] timed out on [");
   buf.append(getName(peer)).append("]");
   addEntry(buf.toString());
 }
 @Override
 protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException {
   try {
     _sessionId = new SessionId();
     _sessionId.readBytes(in);
     int numTunnels = (int) DataHelper.readLong(in, 1);
     _endpoints.clear();
     for (int i = 0; i < numTunnels; i++) {
       // Hash router = new Hash();
       // router.readBytes(in);
       Hash router = Hash.create(in);
       TunnelId tunnel = new TunnelId();
       tunnel.readBytes(in);
       _endpoints.add(new TunnelEndpoint(router, tunnel));
     }
     _end = DataHelper.readDate(in);
   } catch (DataFormatException dfe) {
     throw new I2CPMessageException("Unable to load the message data", dfe);
   }
 }
 @Override
 protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
   if (_sessionId == null)
     throw new I2CPMessageException("Unable to write out the message as there is not enough data");
   ByteArrayOutputStream os = new ByteArrayOutputStream(256);
   try {
     _sessionId.writeBytes(os);
     DataHelper.writeLong(os, 1, _endpoints.size());
     for (int i = 0; i < _endpoints.size(); i++) {
       Hash router = getRouter(i);
       router.writeBytes(os);
       TunnelId tunnel = getTunnelId(i);
       tunnel.writeBytes(os);
     }
     DataHelper.writeDate(os, _end);
   } catch (DataFormatException dfe) {
     throw new I2CPMessageException("Error writing out the message data", dfe);
   }
   return os.toByteArray();
 }
Exemple #6
0
 /**
  * We don't know about the given tunnel, so we are dropping a message sent to us by the given
  * router
  *
  * @param id tunnel ID we received a message for
  * @param from peer that sent us this message (if known)
  */
 public void droppedTunnelMessage(TunnelId id, long msgId, Date expiration, Hash from) {
   if (!_doLog) return;
   StringBuilder buf = new StringBuilder(128);
   buf.append(getPrefix());
   buf.append("dropped message ")
       .append(msgId)
       .append(" for unknown tunnel [")
       .append(id.getTunnelId());
   buf.append("] from [").append(getName(from)).append("]").append(" expiring on ");
   buf.append(getTime(expiration.getTime()));
   addEntry(buf.toString());
 }
Exemple #7
0
 /** The peer did not accept the tunnel join for the given reason */
 public void tunnelRejected(Hash peer, TunnelId tunnel, Hash replyThrough, String reason) {
   if (!_doLog) return;
   if ((tunnel == null) || (peer == null)) return;
   StringBuilder buf = new StringBuilder(128);
   buf.append(getPrefix());
   buf.append("tunnel [").append(tunnel.getTunnelId()).append("] was rejected by [");
   buf.append(getName(peer)).append("] for [").append(reason).append("]");
   if (replyThrough != null)
     buf.append(" with their reply intended to come through [")
         .append(getName(replyThrough))
         .append("]");
   addEntry(buf.toString());
 }
  /**
   * Note that for efficiency at the IBGW, this does not fully deserialize the included I2NP
   * Message. It just puts it in an UnknownI2NPMessage.
   *
   * @param handler unused, may be null
   */
  @Override
  public void readMessage(
      byte data[], int offset, int dataSize, int type, I2NPMessageHandler handler)
      throws I2NPMessageException {
    if (type != MESSAGE_TYPE)
      throw new I2NPMessageException("Message type is incorrect for this message");
    int curIndex = offset;

    _tunnelId = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
    curIndex += 4;

    if (_tunnelId.getTunnelId() <= 0)
      throw new I2NPMessageException("Invalid tunnel Id " + _tunnelId);

    int len = (int) DataHelper.fromLong(data, curIndex, 2);
    curIndex += 2;
    if (len <= 1 || curIndex + len > data.length || len > dataSize - 6)
      throw new I2NPMessageException(
          "I2NP length in TGM: "
              + len
              + " but remaining bytes: "
              + Math.min(data.length - curIndex, dataSize - 6));

    // OLD WAY full message parsing and instantiation
    // handler.readMessage(data, curIndex);
    // _msg = handler.lastRead();
    // if (_msg == null)
    //    throw new I2NPMessageException("impossible? message read has no payload?!");

    // NEW WAY save lots of effort at the IBGW by reading as an UnknownI2NPMessage instead
    // This will save a lot of object churn and processing,
    // primarily for unencrypted msgs (V)TBRM, DatabaseStoreMessage, and DSRMs.
    // DatabaseStoreMessages in particluar are intensive for readBytes()
    // since the RI is decompressed.
    // For a zero-hop IB tunnel, where we do need the real thing,
    // it is converted to a real message class in TunnelGatewayZeroHop
    // using UnknownI2NPMessage.convert() in TunnelGatewayZeroHop.
    // We also skip processing the checksum as it's covered by the TGM checksum.
    // If a zero-hop, the checksum will be verified in convert().
    int utype = data[curIndex++] & 0xff;
    UnknownI2NPMessage umsg = new UnknownI2NPMessage(_context, utype);
    umsg.readBytes(data, utype, curIndex);
    _msg = umsg;
  }
 /**
  * Add a message to be sent down the tunnel (immediately forwarding it to the {@link
  * InboundMessageDistributor} or {@link OutboundMessageDistributor}, as necessary).
  *
  * @param msg message to be sent through the tunnel
  * @param toRouter router to send to after the endpoint (or null for endpoint processing)
  * @param toTunnel tunnel to send to after the endpoint (or null for endpoint or router
  *     processing)
  */
 @Override
 public void add(I2NPMessage msg, Hash toRouter, TunnelId toTunnel) {
   if (_log.shouldLog(Log.DEBUG))
     _log.debug(
         "zero hop gateway: distribute "
             + (_config.isInbound() ? "inbound" : " outbound")
             + " to "
             + (toRouter != null ? toRouter.toBase64().substring(0, 4) : "")
             + "."
             + (toTunnel != null ? toTunnel.getTunnelId() + "" : "")
             + ": "
             + msg);
   if (_config.isInbound()) {
     _inDistributor.distribute(msg, toRouter, toTunnel);
   } else {
     _outDistributor.distribute(msg, toRouter, toTunnel);
   }
   _config.incrementProcessedMessages();
 }
Exemple #10
0
 public void setReceiveTunnelId(TunnelId id) {
   _receiveTunnelId = DataHelper.toLong(4, id.getTunnelId());
 }