Search in sources :

Example 11 with DatabaseStoreMessage

use of net.i2p.data.i2np.DatabaseStoreMessage in project i2p.i2p by i2p.

the class StoreJob method sendStore.

/**
 * Send a store to the given peer, including a reply
 * DeliveryStatusMessage so we know it got there
 */
private void sendStore(RouterInfo router, int responseTime) {
    if (!_state.getTarget().equals(_state.getData().getHash())) {
        _log.error("Hash mismatch StoreJob");
        return;
    }
    DatabaseStoreMessage msg = new DatabaseStoreMessage(getContext());
    if (_state.getData().getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
        if (responseTime > MAX_DIRECT_EXPIRATION)
            responseTime = MAX_DIRECT_EXPIRATION;
    } else if (_state.getData().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
    } else {
        throw new IllegalArgumentException("Storing an unknown data type! " + _state.getData());
    }
    msg.setEntry(_state.getData());
    long now = getContext().clock().now();
    msg.setMessageExpiration(now + _timeoutMs);
    if (router.getIdentity().equals(getContext().router().getRouterInfo().getIdentity())) {
        // don't send it to ourselves
        if (_log.shouldLog(Log.ERROR))
            _log.error(getJobId() + ": Dont send store to ourselves - why did we try?");
        return;
    }
    if (_log.shouldLog(Log.DEBUG))
        _log.debug(getJobId() + ": Send store timeout is " + responseTime);
    sendStore(msg, router, now + responseTime);
}
Also used : DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage)

Example 12 with DatabaseStoreMessage

use of net.i2p.data.i2np.DatabaseStoreMessage in project i2p.i2p by i2p.

the class EstablishmentManager method sendInboundComplete.

/**
 * dont send our info immediately, just send a small data packet, and 5-10s later,
 * if the peer isnt banlisted, *then* send them our info.  this will help kick off
 * the oldnet
 * The "oldnet" was < 0.6.1.10, it is long gone.
 * The delay really slows down the network.
 * The peer is unbanlisted and marked reachable by addRemotePeerState() which calls markReachable()
 * so the check below is fairly pointless.
 * If for some strange reason an oldnet router (NETWORK_ID == 1) does show up,
 *  it's handled in UDPTransport.messageReceived()
 * (where it will get dropped, marked unreachable and banlisted at that time).
 */
private void sendInboundComplete(PeerState peer) {
    // SimpleTimer.getInstance().addEvent(new PublishToNewInbound(peer), 10*1000);
    if (_log.shouldLog(Log.INFO))
        _log.info("Completing to the peer after IB confirm: " + peer);
    DeliveryStatusMessage dsm = new DeliveryStatusMessage(_context);
    // overloaded, sure, but future versions can check this
    dsm.setArrival(_networkID);
    // This causes huge values in the inNetPool.droppedDeliveryStatusDelay stat
    // so it needs to be caught in InNetMessagePool.
    dsm.setMessageExpiration(_context.clock().now() + DATA_MESSAGE_TIMEOUT);
    dsm.setMessageId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
    // sent below
    // just do this inline
    // _context.simpleTimer2().addEvent(new PublishToNewInbound(peer), 0);
    Hash hash = peer.getRemotePeer();
    if ((hash != null) && (!_context.banlist().isBanlisted(hash)) && (!_transport.isUnreachable(hash))) {
        // ok, we are fine with them, send them our latest info
        // if (_log.shouldLog(Log.INFO))
        // _log.info("Publishing to the peer after confirm plus delay (without banlist): " + peer);
        // bundle the two messages together for efficiency
        DatabaseStoreMessage dbsm = getOurInfo();
        List<I2NPMessage> msgs = new ArrayList<I2NPMessage>(2);
        msgs.add(dsm);
        msgs.add(dbsm);
        _transport.send(msgs, peer);
    } else {
        _transport.send(dsm, peer);
        // nuh uh.
        if (_log.shouldLog(Log.WARN))
            _log.warn("NOT publishing to the peer after confirm plus delay (WITH banlist): " + (hash != null ? hash.toString() : "unknown"));
    }
}
Also used : I2NPMessage(net.i2p.data.i2np.I2NPMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) ArrayList(java.util.ArrayList) Hash(net.i2p.data.Hash) DeliveryStatusMessage(net.i2p.data.i2np.DeliveryStatusMessage)

Example 13 with DatabaseStoreMessage

use of net.i2p.data.i2np.DatabaseStoreMessage in project i2p.i2p by i2p.

the class InboundMessageDistributor method handleClove.

/**
 * Handle a clove removed from the garlic message
 */
public void handleClove(DeliveryInstructions instructions, I2NPMessage data) {
    int type = data.getType();
    switch(instructions.getDeliveryMode()) {
        case DeliveryInstructions.DELIVERY_MODE_LOCAL:
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("local delivery instructions for clove: " + data.getClass().getSimpleName());
            if (type == GarlicMessage.MESSAGE_TYPE) {
                _receiver.receive((GarlicMessage) data);
            } else if (type == DatabaseStoreMessage.MESSAGE_TYPE) {
                // Treat db store explicitly here (not in HandleFloodfillDatabaseStoreMessageJob),
                // since we don't want to republish (or flood)
                // unnecessarily. Reply tokens ignored.
                DatabaseStoreMessage dsm = (DatabaseStoreMessage) data;
                // Ensure the reply info is cleared, just in case
                dsm.setReplyToken(0);
                dsm.setReplyTunnel(null);
                dsm.setReplyGateway(null);
                if (dsm.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
                    // Case 1:
                    // store of our own LS.
                    // This is almost certainly a response to a FloodfillVerifyStoreJob search.
                    // We must send to the InNetMessagePool so the message can be matched
                    // and the verify marked as successful.
                    // Case 2:
                    // Store of somebody else's LS.
                    // This could be an encrypted response to an IterativeSearchJob search.
                    // We must send to the InNetMessagePool so the message can be matched
                    // and the search marked as successful.
                    // Or, it's a normal LS bundled with data and a MessageStatusMessage.
                    // ... and inject it.
                    ((LeaseSet) dsm.getEntry()).setReceivedAsReply();
                    if (_log.shouldLog(Log.INFO))
                        _log.info("Storing garlic LS down tunnel for: " + dsm.getKey() + " sent to: " + _client);
                    _context.inNetMessagePool().add(dsm, null, null);
                } else {
                    if (_client != null) {
                        // drop it, since the data we receive shouldn't include router
                        // references, as that might get us to talk to them (and therefore
                        // open an attack vector)
                        _context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1, DatabaseStoreMessage.MESSAGE_TYPE);
                        _log.error("Dropped dangerous message down a tunnel for " + _client + ": " + dsm, new Exception("cause"));
                        return;
                    }
                    // ... and inject it.
                    if (_log.shouldLog(Log.INFO))
                        _log.info("Storing garlic RI down tunnel for: " + dsm.getKey() + " sent to: " + _client);
                    _context.inNetMessagePool().add(dsm, null, null);
                }
            } else if (_client != null && type == DatabaseSearchReplyMessage.MESSAGE_TYPE) {
                // DSRMs show up here now that replies are encrypted
                // TODO: Strip in IterativeLookupJob etc. instead, depending on
                // LS or RI and client or expl., so that we can safely follow references
                // in a reply to a LS lookup over client tunnels.
                // ILJ would also have to follow references via client tunnels
                DatabaseSearchReplyMessage orig = (DatabaseSearchReplyMessage) data;
                /**
                 **
                 *                    if (orig.getNumReplies() > 0) {
                 *                        if (_log.shouldLog(Log.INFO))
                 *                            _log.info("Removing replies from a garlic DSRM down a tunnel for " + _client + ": " + data);
                 *                        DatabaseSearchReplyMessage newMsg = new DatabaseSearchReplyMessage(_context);
                 *                        newMsg.setFromHash(orig.getFromHash());
                 *                        newMsg.setSearchKey(orig.getSearchKey());
                 *                        orig = newMsg;
                 *                     }
                 ***
                 */
                _context.inNetMessagePool().add(orig, null, null);
            } else if (type == DataMessage.MESSAGE_TYPE) {
                // a data message targetting the local router is how we send load tests (real
                // data messages target destinations)
                _context.statManager().addRateData("tunnel.handleLoadClove", 1);
                data = null;
            // _context.inNetMessagePool().add(data, null, null);
            } else if (_client != null && type != DeliveryStatusMessage.MESSAGE_TYPE) {
                // drop it, since the data we receive shouldn't include other stuff,
                // as that might open an attack vector
                _context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1, data.getType());
                _log.error("Dropped dangerous message down a tunnel for " + _client + ": " + data, new Exception("cause"));
            } else {
                _context.inNetMessagePool().add(data, null, null);
            }
            return;
        case DeliveryInstructions.DELIVERY_MODE_DESTINATION:
            Hash to = instructions.getDestination();
            // Can we route UnknownI2NPMessages to a destination too?
            if (type != DataMessage.MESSAGE_TYPE) {
                if (_log.shouldLog(Log.ERROR))
                    _log.error("cant send a " + data.getClass().getSimpleName() + " to a destination");
            } else if (_client != null && _client.equals(to)) {
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("data message came down a tunnel for " + _client);
                DataMessage dm = (DataMessage) data;
                Payload payload = new Payload();
                payload.setEncryptedData(dm.getData());
                ClientMessage m = new ClientMessage(_client, payload);
                _context.clientManager().messageReceived(m);
            } else if (_client != null) {
                // Shared tunnel?
                TunnelPoolSettings tgt = _context.tunnelManager().getInboundSettings(to);
                if (tgt != null && _client.equals(tgt.getAliasOf())) {
                    // same as above, just different log
                    if (_log.shouldLog(Log.DEBUG))
                        _log.debug("data message came down a tunnel for " + _client + " targeting shared " + to);
                    DataMessage dm = (DataMessage) data;
                    Payload payload = new Payload();
                    payload.setEncryptedData(dm.getData());
                    ClientMessage m = new ClientMessage(to, payload);
                    _context.clientManager().messageReceived(m);
                } else {
                    if (_log.shouldLog(Log.ERROR))
                        _log.error("Data message came down a tunnel for " + _client + " but targetted " + to);
                }
            } else {
                if (_log.shouldLog(Log.ERROR))
                    _log.error("Data message came down an exploratory tunnel targeting " + to);
            }
            return;
        // fall through
        case DeliveryInstructions.DELIVERY_MODE_ROUTER:
        case DeliveryInstructions.DELIVERY_MODE_TUNNEL:
            if (_log.shouldLog(Log.INFO))
                _log.info("clove targetted " + instructions.getRouter() + ":" + instructions.getTunnelId() + ", treat recursively to prevent leakage");
            distribute(data, instructions.getRouter(), instructions.getTunnelId());
            return;
        default:
            if (_log.shouldLog(Log.ERROR))
                _log.error("Unknown instruction " + instructions.getDeliveryMode() + ": " + instructions);
            return;
    }
}
Also used : DataMessage(net.i2p.data.i2np.DataMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) DatabaseSearchReplyMessage(net.i2p.data.i2np.DatabaseSearchReplyMessage) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) Payload(net.i2p.data.Payload) ClientMessage(net.i2p.router.ClientMessage) Hash(net.i2p.data.Hash)

Example 14 with DatabaseStoreMessage

use of net.i2p.data.i2np.DatabaseStoreMessage 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 15 with DatabaseStoreMessage

use of net.i2p.data.i2np.DatabaseStoreMessage 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

DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)21 Hash (net.i2p.data.Hash)9 RouterInfo (net.i2p.data.router.RouterInfo)8 OutNetMessage (net.i2p.router.OutNetMessage)5 DatabaseSearchReplyMessage (net.i2p.data.i2np.DatabaseSearchReplyMessage)4 TunnelInfo (net.i2p.router.TunnelInfo)4 TunnelId (net.i2p.data.TunnelId)3 I2NPMessage (net.i2p.data.i2np.I2NPMessage)3 ArrayList (java.util.ArrayList)2 DatabaseEntry (net.i2p.data.DatabaseEntry)2 DeliveryStatusMessage (net.i2p.data.i2np.DeliveryStatusMessage)2 RouterIdentity (net.i2p.data.router.RouterIdentity)2 Job (net.i2p.router.Job)2 IOException (java.io.IOException)1 ServerSocketChannel (java.nio.channels.ServerSocketChannel)1 SocketChannel (java.nio.channels.SocketChannel)1 LeaseSet (net.i2p.data.LeaseSet)1 Payload (net.i2p.data.Payload)1 DataMessage (net.i2p.data.i2np.DataMessage)1 TunnelGatewayMessage (net.i2p.data.i2np.TunnelGatewayMessage)1