Search in sources :

Example 11 with I2NPMessage

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

the class StoreJob method sendStoreThroughClient.

/**
 * Send a leaseset store message out the client tunnel,
 * with the reply to come back through a client tunnel.
 * Stores are garlic encrypted to hide the identity from the OBEP.
 *
 * This makes it harder for an exploratory OBEP or IBGW to correlate it
 * with one or more destinations. Since we are publishing the leaseset,
 * it's easy to find out that an IB tunnel belongs to this dest, and
 * it isn't much harder to do the same for an OB tunnel.
 *
 * As a side benefit, client tunnels should be faster and more reliable than
 * exploratory tunnels.
 *
 * @param msg must contain a leaseset
 * @since 0.7.10
 */
private void sendStoreThroughClient(DatabaseStoreMessage msg, RouterInfo peer, long expiration) {
    long token = 1 + getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
    Hash client = msg.getKey();
    Hash to = peer.getIdentity().getHash();
    TunnelInfo replyTunnel = getContext().tunnelManager().selectInboundTunnel(client, to);
    if (replyTunnel == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("No reply inbound tunnels available!");
        fail();
        return;
    }
    TunnelId replyTunnelId = replyTunnel.getReceiveTunnelId(0);
    msg.setReplyToken(token);
    msg.setReplyTunnel(replyTunnelId);
    msg.setReplyGateway(replyTunnel.getPeer(0));
    if (_log.shouldLog(Log.DEBUG))
        _log.debug(getJobId() + ": send(dbStore) w/ token expected " + token);
    TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundTunnel(client, to);
    if (outTunnel != null) {
        I2NPMessage sent;
        boolean shouldEncrypt = supportsEncryption(peer);
        if (shouldEncrypt) {
            // garlic encrypt
            MessageWrapper.WrappedMessage wm = MessageWrapper.wrap(getContext(), msg, client, peer);
            if (wm == null) {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("Fail garlic encrypting from: " + client);
                fail();
                return;
            }
            sent = wm.getMessage();
            _state.addPending(to, wm);
        } else {
            _state.addPending(to);
            // now that almost all floodfills are at 0.7.10,
            // just refuse to store unencrypted to older ones.
            _state.replyTimeout(to);
            getContext().jobQueue().addJob(new WaitJob(getContext()));
            return;
        }
        SendSuccessJob onReply = new SendSuccessJob(getContext(), peer, outTunnel, sent.getMessageSize());
        FailedJob onFail = new FailedJob(getContext(), peer, getContext().clock().now());
        StoreMessageSelector selector = new StoreMessageSelector(getContext(), getJobId(), peer, token, expiration);
        if (_log.shouldLog(Log.DEBUG)) {
            if (shouldEncrypt)
                _log.debug("sending encrypted store to " + peer.getIdentity().getHash() + " through " + outTunnel + ": " + sent);
            else
                _log.debug("sending store to " + peer.getIdentity().getHash() + " through " + outTunnel + ": " + sent);
        // _log.debug("Expiration is " + new Date(sent.getMessageExpiration()));
        }
        getContext().messageRegistry().registerPending(selector, onReply, onFail);
        getContext().tunnelDispatcher().dispatchOutbound(sent, outTunnel.getSendTunnelId(0), null, to);
    } else {
        if (_log.shouldLog(Log.WARN))
            _log.warn("No outbound tunnels to send a dbStore out - delaying...");
        // continueSending() above did an addPending() so remove it here.
        // This means we will skip the peer next time, can't be helped for now
        // without modding StoreState
        _state.replyTimeout(to);
        Job waiter = new WaitJob(getContext());
        waiter.getTiming().setStartAfter(getContext().clock().now() + 3 * 1000);
        getContext().jobQueue().addJob(waiter);
    // fail();
    }
}
Also used : TunnelInfo(net.i2p.router.TunnelInfo) Hash(net.i2p.data.Hash) TunnelId(net.i2p.data.TunnelId) I2NPMessage(net.i2p.data.i2np.I2NPMessage) ReplyJob(net.i2p.router.ReplyJob) Job(net.i2p.router.Job)

Example 12 with I2NPMessage

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

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

the class TunnelGatewayZeroHop method add.

/**
 * Add a message to be sent down the tunnel, where we are the inbound gateway.
 * This requires converting the message included in the TGM from an
 * UnknownI2NPMessage to the correct message class.
 * See TunnelGatewayMessage for details.
 *
 * @param msg message received to be sent through the tunnel
 */
@Override
public void add(TunnelGatewayMessage msg) {
    I2NPMessage imsg = msg.getMessage();
    if (_config.isInbound()) {
        if (imsg instanceof UnknownI2NPMessage) {
            // Do the delayed deserializing - convert to a standard message class
            try {
                UnknownI2NPMessage umsg = (UnknownI2NPMessage) imsg;
                imsg = umsg.convert();
            } catch (I2NPMessageException ime) {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("Unable to convert to std. msg. class at zero-hop IBGW", ime);
                return;
            }
        }
    }
    add(imsg, null, null);
}
Also used : I2NPMessageException(net.i2p.data.i2np.I2NPMessageException) I2NPMessage(net.i2p.data.i2np.I2NPMessage) UnknownI2NPMessage(net.i2p.data.i2np.UnknownI2NPMessage) UnknownI2NPMessage(net.i2p.data.i2np.UnknownI2NPMessage)

Example 14 with I2NPMessage

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

Example 15 with I2NPMessage

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

the class SearchJob method sendLeaseSearch.

/**
 * we're (probably) searching for a LeaseSet, so to be (overly) cautious, we're sending
 * the request out through a tunnel w/ reply back through another tunnel.
 */
protected void sendLeaseSearch(RouterInfo router) {
    Hash to = router.getIdentity().getHash();
    TunnelInfo inTunnel = getContext().tunnelManager().selectInboundExploratoryTunnel(to);
    if (inTunnel == null) {
        _log.warn("No tunnels to get search replies through!");
        getContext().jobQueue().addJob(new FailedJob(getContext(), router));
        return;
    }
    TunnelId inTunnelId = inTunnel.getReceiveTunnelId(0);
    // this will fail if we've banlisted our inbound gateway, but the gw may not necessarily
    // be banlisted by whomever needs to contact them, so we don't need to check this
    // RouterInfo inGateway = getContext().netDb().lookupRouterInfoLocally(inTunnel.getPeer(0));
    // if (inGateway == null) {
    // _log.error("We can't find the gateway to our inbound tunnel?!");
    // getContext().jobQueue().addJob(new FailedJob(getContext(), router));
    // return;
    // }
    int timeout = getPerPeerTimeoutMs(to);
    long expiration = getContext().clock().now() + timeout;
    I2NPMessage msg = buildMessage(inTunnelId, inTunnel.getPeer(0), expiration, router);
    if (msg == null) {
        getContext().jobQueue().addJob(new FailedJob(getContext(), router));
        return;
    }
    TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundExploratoryTunnel(to);
    if (outTunnel == null) {
        _log.warn("No tunnels to send search out through! Impossible?");
        getContext().jobQueue().addJob(new FailedJob(getContext(), router));
        return;
    }
    TunnelId outTunnelId = outTunnel.getSendTunnelId(0);
    if (_log.shouldLog(Log.DEBUG))
        _log.debug(getJobId() + ": Sending search to " + to + " for " + getState().getTarget() + " w/ replies through " + inTunnel.getPeer(0) + " via tunnel " + inTunnelId);
    SearchMessageSelector sel = new SearchMessageSelector(getContext(), router, _expiration, _state);
    SearchUpdateReplyFoundJob reply = new SearchUpdateReplyFoundJob(getContext(), router, _state, _facade, this, outTunnel, inTunnel);
    if (FloodfillNetworkDatabaseFacade.isFloodfill(router))
        _floodfillSearchesOutstanding++;
    getContext().messageRegistry().registerPending(sel, reply, new FailedJob(getContext(), router));
    // TODO pass a priority to the dispatcher
    getContext().tunnelDispatcher().dispatchOutbound(msg, outTunnelId, to);
}
Also used : I2NPMessage(net.i2p.data.i2np.I2NPMessage) TunnelInfo(net.i2p.router.TunnelInfo) Hash(net.i2p.data.Hash) TunnelId(net.i2p.data.TunnelId)

Aggregations

I2NPMessage (net.i2p.data.i2np.I2NPMessage)21 Hash (net.i2p.data.Hash)9 ArrayList (java.util.ArrayList)5 DataMessage (net.i2p.data.i2np.DataMessage)4 I2NPMessageException (net.i2p.data.i2np.I2NPMessageException)4 TunnelInfo (net.i2p.router.TunnelInfo)4 Test (org.junit.Test)4 TunnelId (net.i2p.data.TunnelId)3 DatabaseLookupMessage (net.i2p.data.i2np.DatabaseLookupMessage)3 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)3 RouterInfo (net.i2p.data.router.RouterInfo)3 OutNetMessage (net.i2p.router.OutNetMessage)3 ByteArray (net.i2p.data.ByteArray)2 I2NPMessageHandler (net.i2p.data.i2np.I2NPMessageHandler)2 Job (net.i2p.router.Job)2 ReplyJob (net.i2p.router.ReplyJob)2 IOException (java.io.IOException)1 ServerSocketChannel (java.nio.channels.ServerSocketChannel)1 SocketChannel (java.nio.channels.SocketChannel)1 HashSet (java.util.HashSet)1