Search in sources :

Example 41 with ByteArray

use of net.i2p.data.ByteArray in project i2p.i2p by i2p.

the class MessageInputStream method closeReceived.

/**
 *  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("Input stream closed"));
        }
        _closeReceived = true;
        _dataLock.notifyAll();
    }
}
Also used : ByteArray(net.i2p.data.ByteArray) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException)

Example 42 with ByteArray

use of net.i2p.data.ByteArray in project i2p.i2p by i2p.

the class MessageInputStream method getTotalReadySize.

/**
 * How many bytes are queued up for reading (or sitting in the out-of-order
 * buffer)?
 *
 * @return Count of bytes waiting to be read
 */
/**
 *    public int getTotalQueuedSize() {
 *        synchronized (_dataLock) {
 *            if (_locallyClosed) return 0;
 *            int numBytes = 0;
 *            for (int i = 0; i < _readyDataBlocks.size(); i++) {
 *                ByteArray cur = _readyDataBlocks.get(i);
 *                if (i == 0)
 *                    numBytes += cur.getValid() - _readyDataBlockIndex;
 *                else
 *                    numBytes += cur.getValid();
 *            }
 *            for (ByteArray cur : _notYetReadyBlocks.values()) {
 *                numBytes += cur.getValid();
 *            }
 *            return numBytes;
 *        }
 *    }
 **
 */
/**
 *  Same as available() but doesn't throw IOE
 */
public int getTotalReadySize() {
    synchronized (_dataLock) {
        if (_locallyClosed)
            return 0;
        int numBytes = 0;
        for (int i = 0; i < _readyDataBlocks.size(); i++) {
            ByteArray cur = _readyDataBlocks.get(i);
            numBytes += cur.getValid();
            if (i == 0)
                numBytes -= _readyDataBlockIndex;
        }
        return numBytes;
    }
}
Also used : ByteArray(net.i2p.data.ByteArray)

Example 43 with ByteArray

use of net.i2p.data.ByteArray in project i2p.i2p by i2p.

the class MessageInputStream method close.

@Override
public void close() {
    synchronized (_dataLock) {
        if (_log.shouldLog(Log.DEBUG)) {
            StringBuilder buf = new StringBuilder(128);
            buf.append("close(), 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());
        }
        // while (_readyDataBlocks.size() > 0)
        // _cache.release((ByteArray)_readyDataBlocks.remove(0));
        _readyDataBlocks.clear();
        // received, so we can ACK accordingly
        for (ByteArray ba : _notYetReadyBlocks.values()) {
            ba.setData(null);
        // _cache.release(ba);
        }
        _locallyClosed = true;
        _dataLock.notifyAll();
    }
}
Also used : ByteArray(net.i2p.data.ByteArray)

Example 44 with ByteArray

use of net.i2p.data.ByteArray in project i2p.i2p by i2p.

the class PacketQueue method enqueue.

/**
 * Add a new packet to be sent out ASAP.
 * This updates the acks.
 *
 * keys and tags disabled since dropped in I2PSession
 * @return true if sent
 */
public boolean enqueue(PacketLocal packet) {
    if (_dead)
        return false;
    if (packet.getAckTime() > 0) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Not resending " + packet);
        return false;
    }
    Connection con = packet.getConnection();
    if (con != null) {
        // this updates the ack/nack fields
        con.getInputStream().updateAcks(packet);
    }
    ByteArray ba = _cache.acquire();
    byte[] buf = ba.getData();
    long begin = 0;
    long end = 0;
    boolean sent = false;
    try {
        int size = 0;
        // long beforeWrite = System.currentTimeMillis();
        if (packet.shouldSign())
            size = packet.writeSignedPacket(buf, 0);
        else
            size = packet.writePacket(buf, 0);
        // last chance to short circuit...
        if (packet.getAckTime() > 0)
            return false;
        // this should not block!
        begin = _context.clock().now();
        long expires = 0;
        Connection.ResendPacketEvent rpe = (Connection.ResendPacketEvent) packet.getResendEvent();
        if (rpe != null)
            // we want the router to expire it a little before we do,
            // so if we retransmit it will use a new tunnel/lease combo
            expires = rpe.getNextSendTime() - 500;
        SendMessageOptions options = new SendMessageOptions();
        if (expires > 0)
            options.setDate(expires);
        boolean listenForStatus = false;
        // FINAL trumps INITIAL, in the case of SYN+CLOSE
        if (packet.isFlagSet(FLAGS_FINAL_TAGS)) {
            if (packet.isFlagSet(Packet.FLAG_ECHO)) {
                // Send LS for PING, not for PONG
                if (// pong
                packet.getSendStreamId() <= 0)
                    options.setSendLeaseSet(false);
            } else {
                options.setSendLeaseSet(false);
            }
            int sendTags = FINAL_TAGS_TO_SEND;
            int tagThresh = FINAL_TAG_THRESHOLD;
            if (con != null) {
                ConnectionOptions copts = con.getOptions();
                int cSendTags = copts.getTagsToSend();
                int cTagThresh = copts.getTagThreshold();
                if (cSendTags < sendTags)
                    sendTags = cSendTags;
                if (cTagThresh < tagThresh)
                    tagThresh = cTagThresh;
            }
            options.setTagsToSend(sendTags);
            options.setTagThreshold(tagThresh);
        } else if (packet.isFlagSet(FLAGS_INITIAL_TAGS)) {
            if (con != null) {
                if (con.isInbound())
                    options.setSendLeaseSet(false);
                else if (ENABLE_STATUS_LISTEN)
                    listenForStatus = true;
            }
            int sendTags = INITIAL_TAGS_TO_SEND;
            int tagThresh = MIN_TAG_THRESHOLD;
            if (con != null) {
                ConnectionOptions copts = con.getOptions();
                int cSendTags = copts.getTagsToSend();
                int cTagThresh = copts.getTagThreshold();
                if (cSendTags < sendTags)
                    sendTags = cSendTags;
                if (cTagThresh < tagThresh)
                    tagThresh = cTagThresh;
            }
            options.setTagsToSend(sendTags);
            options.setTagThreshold(tagThresh);
        } else {
            if (con != null) {
                if (con.isInbound() && con.getLifetime() < 2 * 60 * 1000)
                    options.setSendLeaseSet(false);
                // increase threshold with higher window sizes to prevent stalls
                // after tag delivery failure
                ConnectionOptions copts = con.getOptions();
                int wdw = copts.getWindowSize();
                int thresh = Math.max(MIN_TAG_THRESHOLD, wdw * TAG_WINDOW_FACTOR);
                int cTagThresh = copts.getTagThreshold();
                if (cTagThresh < thresh)
                    thresh = cTagThresh;
                options.setTagThreshold(thresh);
            }
        }
        I2PSession session = packet.getSession();
        if (listenForStatus) {
            long id = session.sendMessage(packet.getTo(), buf, 0, size, I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort(), options, this);
            _messageStatusMap.put(Long.valueOf(id), con);
            sent = true;
        } else {
            sent = session.sendMessage(packet.getTo(), buf, 0, size, I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort(), options);
        }
        end = _context.clock().now();
        if ((end - begin > 1000) && (_log.shouldLog(Log.WARN)))
            _log.warn("Took " + (end - begin) + "ms to sendMessage(...) " + packet);
        _context.statManager().addRateData("stream.con.sendMessageSize", size, packet.getLifetime());
        if (packet.getNumSends() > 1)
            _context.statManager().addRateData("stream.con.sendDuplicateSize", size, packet.getLifetime());
        if (con != null) {
            con.incrementBytesSent(size);
            if (packet.getNumSends() > 1)
                con.incrementDupMessagesSent(1);
        }
    } catch (I2PSessionException ise) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Unable to send the packet " + packet, ise);
    }
    _cache.release(ba);
    if (!sent) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Send failed for " + packet);
        if (// handle race on b0rk
        con != null)
            con.disconnect(false);
    } else {
        // packet.setKeyUsed(keyUsed);
        // packet.setTagsSent(tagsSent);
        packet.incrementSends();
        if (con != null && _log.shouldDebug()) {
            String suffix = "wsize " + con.getOptions().getWindowSize() + " rto " + con.getOptions().getRTO();
            con.getConnectionManager().getPacketHandler().displayPacket(packet, "SEND", suffix);
        }
        if (I2PSocketManagerFull.pcapWriter != null && _context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
            packet.logTCPDump();
    }
    if ((packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE))) {
        // ack only, so release it asap
        packet.releasePayload();
    } else if (packet.isFlagSet(Packet.FLAG_ECHO) && !packet.isFlagSet(Packet.FLAG_SIGNATURE_INCLUDED)) {
        // pong
        packet.releasePayload();
    } else if (packet.isFlagSet(Packet.FLAG_RESET)) {
        // reset
        packet.releasePayload();
    }
    return sent;
}
Also used : SendMessageOptions(net.i2p.client.SendMessageOptions) ByteArray(net.i2p.data.ByteArray) I2PSession(net.i2p.client.I2PSession) I2PSessionException(net.i2p.client.I2PSessionException)

Example 45 with ByteArray

use of net.i2p.data.ByteArray in project i2p.i2p by i2p.

the class MessageInputStreamTest method testGetHighestReadyBlockId.

@Test
public void testGetHighestReadyBlockId() {
    assertThat(in.getHighestReadyBlockId(), is((long) -1));
    in.messageReceived(0, new ByteArray());
    assertThat(in.getHighestReadyBlockId(), is((long) 0));
    in.messageReceived(2, new ByteArray());
    assertThat(in.getHighestReadyBlockId(), is((long) 0));
    in.messageReceived(1, new ByteArray());
    assertThat(in.getHighestReadyBlockId(), is((long) 2));
}
Also used : ByteArray(net.i2p.data.ByteArray) Test(org.junit.Test)

Aggregations

ByteArray (net.i2p.data.ByteArray)53 Test (org.junit.Test)14 IOException (java.io.IOException)9 ArrayList (java.util.ArrayList)3 Destination (net.i2p.data.Destination)3 InterruptedIOException (java.io.InterruptedIOException)2 SessionKey (net.i2p.data.SessionKey)2 I2NPMessage (net.i2p.data.i2np.I2NPMessage)2 I2NPMessageException (net.i2p.data.i2np.I2NPMessageException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InetAddress (java.net.InetAddress)1 ByteBuffer (java.nio.ByteBuffer)1 CancelledKeyException (java.nio.channels.CancelledKeyException)1 NotYetConnectedException (java.nio.channels.NotYetConnectedException)1 SelectionKey (java.nio.channels.SelectionKey)1 ServerSocketChannel (java.nio.channels.ServerSocketChannel)1 SocketChannel (java.nio.channels.SocketChannel)1 MessageDigest (java.security.MessageDigest)1 LinkedBlockingQueue (java.util.concurrent.LinkedBlockingQueue)1 I2PException (net.i2p.I2PException)1