Search in sources :

Example 26 with OutNetMessage

use of net.i2p.router.OutNetMessage in project i2p.i2p by i2p.

the class TestJob method runJob.

public void runJob() {
    if (_pool == null || !_pool.isAlive())
        return;
    long lag = getContext().jobQueue().getMaxLag();
    if (lag > 3000) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Deferring test of " + _cfg + " due to job lag = " + lag);
        getContext().statManager().addRateData("tunnel.testAborted", _cfg.getLength(), 0);
        scheduleRetest();
        return;
    }
    if (getContext().router().gracefulShutdownInProgress())
        // don't reschedule
        return;
    _found = false;
    // note: testing with exploratory tunnels always, even if the tested tunnel
    // is a client tunnel (per _cfg.getDestination())
    // should we test with the tunnel that we exposed the creation with?
    // (accessible as _cfg.getPairedTunnel())
    _replyTunnel = null;
    _outTunnel = null;
    if (_cfg.isInbound()) {
        _replyTunnel = _cfg;
        // TODO if testing is re-enabled, pick closest to far end
        _outTunnel = getContext().tunnelManager().selectOutboundTunnel();
        _otherTunnel = (PooledTunnelCreatorConfig) _outTunnel;
    } else {
        // TODO if testing is re-enabled, pick closest to far end
        _replyTunnel = getContext().tunnelManager().selectInboundTunnel();
        _outTunnel = _cfg;
        _otherTunnel = (PooledTunnelCreatorConfig) _replyTunnel;
    }
    if ((_replyTunnel == null) || (_outTunnel == null)) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Insufficient tunnels to test " + _cfg + " with: " + _replyTunnel + " / " + _outTunnel);
        getContext().statManager().addRateData("tunnel.testAborted", _cfg.getLength(), 0);
        scheduleRetest();
    } else {
        int testPeriod = getTestPeriod();
        long testExpiration = getContext().clock().now() + testPeriod;
        DeliveryStatusMessage m = new DeliveryStatusMessage(getContext());
        m.setArrival(getContext().clock().now());
        m.setMessageExpiration(testExpiration);
        m.setMessageId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
        ReplySelector sel = new ReplySelector(getContext(), m.getMessageId(), testExpiration);
        OnTestReply onReply = new OnTestReply(getContext());
        OnTestTimeout onTimeout = new OnTestTimeout(getContext());
        OutNetMessage msg = getContext().messageRegistry().registerPending(sel, onReply, onTimeout);
        onReply.setSentMessage(msg);
        sendTest(m);
    }
}
Also used : OutNetMessage(net.i2p.router.OutNetMessage) DeliveryStatusMessage(net.i2p.data.i2np.DeliveryStatusMessage)

Example 27 with OutNetMessage

use of net.i2p.router.OutNetMessage in project i2p.i2p by i2p.

the class InboundGatewayReceiver method receiveEncrypted.

public long receiveEncrypted(byte[] encrypted, boolean alreadySearched) {
    if (!alreadySearched)
        _config.incrementProcessedMessages();
    if (_target == null) {
        _target = _context.netDb().lookupRouterInfoLocally(_config.getSendTo());
        if (_target == null) {
            // It should be rare to forget the router info for the next peer
            ReceiveJob j = null;
            if (alreadySearched)
                _context.statManager().addRateData("tunnel.inboundLookupSuccess", 0);
            else
                j = new ReceiveJob(_context, encrypted);
            _context.netDb().lookupRouterInfo(_config.getSendTo(), j, j, MAX_LOOKUP_TIME);
            return -1;
        }
    }
    if (alreadySearched)
        _context.statManager().addRateData("tunnel.inboundLookupSuccess", 1);
    // We do this before the preprocessor now (i.e. before fragmentation)
    // if (_context.tunnelDispatcher().shouldDropParticipatingMessage("IBGW", encrypted.length))
    // return -1;
    // _config.incrementSentMessages();
    _context.bandwidthLimiter().sentParticipatingMessage(1024);
    TunnelDataMessage msg = new TunnelDataMessage(_context);
    msg.setData(encrypted);
    msg.setTunnelId(_config.getSendTunnel());
    OutNetMessage out = new OutNetMessage(_context, msg, msg.getMessageExpiration(), PRIORITY, _target);
    _context.outNetMessagePool().add(out);
    return msg.getUniqueId();
}
Also used : OutNetMessage(net.i2p.router.OutNetMessage) TunnelDataMessage(net.i2p.data.i2np.TunnelDataMessage)

Example 28 with OutNetMessage

use of net.i2p.router.OutNetMessage in project i2p.i2p by i2p.

the class NTCPConnection method enqueueInfoMessage.

/**
 *  Inject a DatabaseStoreMessage with our RouterInfo
 */
public void enqueueInfoMessage() {
    int priority = INFO_PRIORITY;
    // }
    if (_log.shouldLog(Log.INFO))
        _log.info("SENDING INFO message pri. " + priority + ": " + toString());
    DatabaseStoreMessage dsm = new DatabaseStoreMessage(_context);
    dsm.setEntry(_context.router().getRouterInfo());
    // We are injecting directly, so we can use a null target.
    OutNetMessage infoMsg = new OutNetMessage(_context, dsm, _context.clock().now() + 10 * 1000, priority, null);
    infoMsg.beginSend();
    // _context.statManager().addRateData("ntcp.infoMessageEnqueued", 1);
    send(infoMsg);
}
Also used : OutNetMessage(net.i2p.router.OutNetMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage)

Example 29 with OutNetMessage

use of net.i2p.router.OutNetMessage in project i2p.i2p by i2p.

the class NTCPConnection method prepareNextWriteFast.

/**
 ********  nobody's tried this one in years
 *    private void prepareNextWriteSmall() {
 *        if (_log.shouldLog(Log.DEBUG))
 *            _log.debug("prepare next write w/ isInbound? " + _isInbound + " established? " + _established);
 *        if (!_isInbound && !_established) {
 *            if (_establishState == null) {
 *                _establishState = new EstablishState(_context, _transport, this);
 *                _establishState.prepareOutbound();
 *            } else {
 *                if (_log.shouldLog(Log.DEBUG))
 *                    _log.debug("prepare next write, but we have already prepared the first outbound and we are not yet established..." + toString());
 *            }
 *            return;
 *        }
 *
 *        if (_nextMetaTime <= System.currentTimeMillis()) {
 *            sendMeta();
 *            _nextMetaTime = System.currentTimeMillis() + _context.random().nextInt(META_FREQUENCY);
 *        }
 *
 *        OutNetMessage msg = null;
 *        synchronized (_outbound) {
 *            if (_currentOutbound != null) {
 *                if (_log.shouldLog(Log.WARN))
 *                    _log.warn("attempt for multiple outbound messages with " + System.identityHashCode(_currentOutbound) + " already waiting and " + _outbound.size() + " queued");
 *                return;
 *            }
 *                //throw new RuntimeException("We should not be preparing a write while we still have one pending");
 *            if (!_outbound.isEmpty()) {
 *                msg = (OutNetMessage)_outbound.remove(0);
 *                _currentOutbound = msg;
 *            } else {
 *                return;
 *            }
 *        }
 *
 *        msg.beginTransmission();
 *        msg.beginPrepare();
 *        long begin = System.currentTimeMillis();
 *        // prepare the message as a binary array, then encrypt it w/ a checksum
 *        // and add it to the _writeBufs
 *        // E(sizeof(data)+data+pad+crc, sessionKey, prevEncrypted)
 *        I2NPMessage m = msg.getMessage();
 *        int sz = m.getMessageSize();
 *        int min = 2 + sz + 4;
 *        int rem = min % 16;
 *        int padding = 0;
 *        if (rem > 0)
 *            padding = 16 - rem;
 *
 *        byte unencrypted[] = new byte[min+padding];
 *        byte base[] = m.toByteArray();
 *        DataHelper.toLong(unencrypted, 0, 2, sz);
 *        System.arraycopy(base, 0, unencrypted, 2, base.length);
 *        if (padding > 0) {
 *            byte pad[] = new byte[padding];
 *            _context.random().nextBytes(pad);
 *            System.arraycopy(pad, 0, unencrypted, 2+sz, padding);
 *        }
 *
 *        long serialized = System.currentTimeMillis();
 *        Adler32 crc = new Adler32();
 *        crc.reset();
 *        crc.update(unencrypted, 0, unencrypted.length-4);
 *        long val = crc.getValue();
 *        DataHelper.toLong(unencrypted, unencrypted.length-4, 4, val);
 *
 *        if (_log.shouldLog(Log.DEBUG))
 *            _log.debug("Outbound message " + _messagesWritten + " has crc " + val);
 *
 *        long crced = System.currentTimeMillis();
 *        byte encrypted[] = new byte[unencrypted.length];
 *        _context.aes().encrypt(unencrypted, 0, encrypted, 0, _sessionKey, _prevWriteEnd, 0, unencrypted.length);
 *        System.arraycopy(encrypted, encrypted.length-16, _prevWriteEnd, 0, _prevWriteEnd.length);
 *        long encryptedTime = System.currentTimeMillis();
 *        msg.prepared();
 *        if (_log.shouldLog(Log.DEBUG)) {
 *            _log.debug("prepared outbound " + System.identityHashCode(msg)
 *                       + " serialize=" + (serialized-begin)
 *                       + " crc=" + (crced-serialized)
 *                       + " encrypted=" + (encryptedTime-crced)
 *                       + " prepared=" + (encryptedTime-begin));
 *        }
 *        //if (_log.shouldLog(Log.DEBUG))
 *        //    _log.debug("Encrypting " + msg + " [" + System.identityHashCode(msg) + "] crc=" + crc.getValue() + "\nas: "
 *        //               + Base64.encode(encrypted, 0, 16) + "...\ndecrypted: "
 *        //               + Base64.encode(unencrypted, 0, 16) + "..." + "\nIV=" + Base64.encode(_prevWriteEnd, 0, 16));
 *        _transport.getPumper().wantsWrite(this, encrypted);
 *
 *        // for every 6-12 hours that we are connected to a peer, send them
 *	// our updated netDb info (they may not accept it and instead query
 *	// the floodfill netDb servers, but they may...)
 *        if (_nextInfoTime <= System.currentTimeMillis()) {
 *            enqueueInfoMessage();
 *            _nextInfoTime = System.currentTimeMillis() + (INFO_FREQUENCY / 2) + _context.random().nextInt(INFO_FREQUENCY);
 *        }
 *    }
 *********
 */
/**
 * prepare the next i2np message for transmission.  this should be run from
 * the Writer thread pool.
 *
 * Caller must synchronize.
 * @param buf a PrepBuffer to use as scratch space
 */
private void prepareNextWriteFast(PrepBuffer buf) {
    if (_closed.get())
        return;
    // enqueueInfoMessage() is called at end of IB establishment.
    if (!isEstablished()) {
        return;
    }
    long now = _context.clock().now();
    if (_nextMetaTime <= now) {
        sendMeta();
        _nextMetaTime = now + (META_FREQUENCY / 2) + _context.random().nextInt(META_FREQUENCY / 2);
    }
    OutNetMessage msg = null;
    // Todo: figure out how to remove the synchronization
    synchronized (_outbound) {
        if (_currentOutbound != null) {
            if (_log.shouldLog(Log.INFO))
                _log.info("attempt for multiple outbound messages with " + System.identityHashCode(_currentOutbound) + " already waiting and " + _outbound.size() + " queued");
            return;
        }
        /**
         **
         *                //throw new RuntimeException("We should not be preparing a write while we still have one pending");
         *            if (queueTime() > 3*1000) {  // don't stall low-priority messages
         ***
         */
        msg = _outbound.poll();
        if (msg == null)
            return;
        /**
         **
         *            } else {
         *                // FIXME
         *                // This is a linear search to implement a priority queue, O(n**2)
         *                // Also race with unsynchronized removal in close() above
         *                // Either implement a real (concurrent?) priority queue or just comment out all of this,
         *                // as it isn't clear how effective the priorities on a per-connection basis are.
         *                int slot = 0;  // only for logging
         *                Iterator<OutNetMessage> it = _outbound.iterator();
         *                for (int i = 0; it.hasNext() && i < 75; i++) {  //arbitrary bound
         *                    OutNetMessage mmsg = it.next();
         *                    if (msg == null || mmsg.getPriority() > msg.getPriority()) {
         *                        msg = mmsg;
         *                        slot = i;
         *                    }
         *                }
         *                if (msg == null)
         *                    return;
         *                // if (_outbound.indexOf(msg) > 0)
         *                //     _log.debug("Priority message sent, pri = " + msg.getPriority() + " pos = " + _outbound.indexOf(msg) + "/" +_outbound.size());
         *                if (_log.shouldLog(Log.INFO))
         *                    _log.info("Type " + msg.getMessage().getType() + " pri " + msg.getPriority() + " slot " + slot);
         *                boolean removed = _outbound.remove(msg);
         *                if ((!removed) && _log.shouldLog(Log.WARN))
         *                    _log.warn("Already removed??? " + msg.getMessage().getType());
         *            }
         ***
         */
        _currentOutbound = msg;
    }
    // long begin = System.currentTimeMillis();
    bufferedPrepare(msg, buf);
    _context.aes().encrypt(buf.unencrypted, 0, buf.encrypted, 0, _sessionKey, _prevWriteEnd, 0, buf.unencryptedLength);
    System.arraycopy(buf.encrypted, buf.encrypted.length - 16, _prevWriteEnd, 0, _prevWriteEnd.length);
    // long encryptedTime = System.currentTimeMillis();
    // if (_log.shouldLog(Log.DEBUG))
    // _log.debug("Encrypting " + msg + " [" + System.identityHashCode(msg) + "] crc=" + crc.getValue() + "\nas: "
    // + Base64.encode(encrypted, 0, 16) + "...\ndecrypted: "
    // + Base64.encode(unencrypted, 0, 16) + "..." + "\nIV=" + Base64.encode(_prevWriteEnd, 0, 16));
    _transport.getPumper().wantsWrite(this, buf.encrypted);
    // the floodfill netDb servers, but they may...)
    if (_nextInfoTime <= now) {
        // perhaps this should check to see if we are bw throttled, etc?
        enqueueInfoMessage();
        _nextInfoTime = now + (INFO_FREQUENCY / 2) + _context.random().nextInt(INFO_FREQUENCY);
    }
}
Also used : OutNetMessage(net.i2p.router.OutNetMessage)

Example 30 with OutNetMessage

use of net.i2p.router.OutNetMessage in project i2p.i2p by i2p.

the class NTCPTransport method outboundMessageReady.

protected void outboundMessageReady() {
    OutNetMessage msg = getNextMessage();
    if (msg != null) {
        RouterInfo target = msg.getTarget();
        RouterIdentity ident = target.getIdentity();
        Hash ih = ident.calculateHash();
        NTCPConnection con = null;
        boolean isNew = false;
        boolean fail = false;
        synchronized (_conLock) {
            con = _conByIdent.get(ih);
            if (con == null) {
                isNew = true;
                RouterAddress addr = getTargetAddress(target);
                if (addr != null) {
                    con = new NTCPConnection(_context, this, ident, addr);
                    // if (_log.shouldLog(Log.DEBUG))
                    // _log.debug("Send on a new con: " + con + " at " + addr + " for " + ih);
                    // Note that outbound conns go in the map BEFORE establishment
                    _conByIdent.put(ih, con);
                } else {
                    // race, RI changed out from under us
                    // call afterSend below outside of conLock
                    fail = true;
                }
            }
        }
        if (fail) {
            // race, RI changed out from under us, maybe SSU can handle it
            if (_log.shouldLog(Log.WARN))
                _log.warn("we bid on a peer who doesn't have an ntcp address? " + target);
            afterSend(msg, false);
            return;
        }
        if (isNew) {
            // doesn't do anything yet, just enqueues it
            con.send(msg);
            // As of 0.9.12, don't send our info if the first message is
            // doing the same (common when connecting to a floodfill).
            // Also, put the info message after whatever we are trying to send
            // (it's a priority queue anyway and the info is low priority)
            // Prior to 0.9.12, Bob would not send his RI unless he had ours,
            // but that's fixed in 0.9.12.
            boolean shouldSkipInfo = false;
            I2NPMessage m = msg.getMessage();
            if (m.getType() == DatabaseStoreMessage.MESSAGE_TYPE) {
                DatabaseStoreMessage dsm = (DatabaseStoreMessage) m;
                if (dsm.getKey().equals(_context.routerHash())) {
                    shouldSkipInfo = true;
                }
            }
            if (!shouldSkipInfo) {
                con.enqueueInfoMessage();
            } else if (_log.shouldLog(Log.INFO)) {
                _log.info("SKIPPING INFO message: " + con);
            }
            try {
                SocketChannel channel = SocketChannel.open();
                con.setChannel(channel);
                channel.configureBlocking(false);
                _pumper.registerConnect(con);
                con.getEstablishState().prepareOutbound();
            } catch (IOException ioe) {
                if (_log.shouldLog(Log.ERROR))
                    _log.error("Error opening a channel", ioe);
                _context.statManager().addRateData("ntcp.outboundFailedIOEImmediate", 1);
                con.close();
            }
        } else {
            con.send(msg);
        }
    /*
            NTCPConnection con = getCon(ident);
            remove the race here
            if (con != null) {
                //if (_log.shouldLog(Log.DEBUG))
                //    _log.debug("Send on an existing con: " + con);
                con.send(msg);
            } else {
                RouterAddress addr = msg.getTarget().getTargetAddress(STYLE);
                if (addr != null) {
                    NTCPAddress naddr = new NTCPAddress(addr);
                    con = new NTCPConnection(_context, this, ident, naddr);
                    Hash ih = ident.calculateHash();
                    if (_log.shouldLog(Log.DEBUG))
                        _log.debug("Send on a new con: " + con + " at " + addr + " for " + ih.toBase64());
                    NTCPConnection old = null;
                    synchronized (_conLock) {
                        old = (NTCPConnection)_conByIdent.put(ih, con);
                    }
                    if (old != null) {
                        if (_log.shouldLog(Log.WARN))
                            _log.warn("Multiple connections on out ready, closing " + old + " and keeping " + con);
                        old.close();
                    }
                    con.enqueueInfoMessage(); // enqueues a netDb store of our own info
                    con.send(msg); // doesn't do anything yet, just enqueues it

                    try {
                        SocketChannel channel = SocketChannel.open();
                        con.setChannel(channel);
                        channel.configureBlocking(false);
                        _pumper.registerConnect(con);
                    } catch (IOException ioe) {
                        if (_log.shouldLog(Log.ERROR))
                            _log.error("Error opening a channel", ioe);
                        con.close();
                    }
                } else {
                    con.close();
                }
            }
             */
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) ServerSocketChannel(java.nio.channels.ServerSocketChannel) OutNetMessage(net.i2p.router.OutNetMessage) RouterInfo(net.i2p.data.router.RouterInfo) RouterIdentity(net.i2p.data.router.RouterIdentity) I2NPMessage(net.i2p.data.i2np.I2NPMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) RouterAddress(net.i2p.data.router.RouterAddress) IOException(java.io.IOException) Hash(net.i2p.data.Hash)

Aggregations

OutNetMessage (net.i2p.router.OutNetMessage)36 ArrayList (java.util.ArrayList)9 Hash (net.i2p.data.Hash)9 RouterInfo (net.i2p.data.router.RouterInfo)9 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)5 List (java.util.List)4 RouterIdentity (net.i2p.data.router.RouterIdentity)4 I2NPMessage (net.i2p.data.i2np.I2NPMessage)3 RouterAddress (net.i2p.data.router.RouterAddress)3 MessageSelector (net.i2p.router.MessageSelector)3 IOException (java.io.IOException)2 TunnelGatewayMessage (net.i2p.data.i2np.TunnelGatewayMessage)2 Job (net.i2p.router.Job)2 TunnelInfo (net.i2p.router.TunnelInfo)2 TunnelManagerFacade (net.i2p.router.TunnelManagerFacade)2 InetAddress (java.net.InetAddress)1 ByteBuffer (java.nio.ByteBuffer)1 ServerSocketChannel (java.nio.channels.ServerSocketChannel)1 SocketChannel (java.nio.channels.SocketChannel)1 Map (java.util.Map)1