Search in sources :

Example 11 with RouterIdentity

use of net.i2p.data.router.RouterIdentity in project i2p.i2p by i2p.

the class EstablishmentManager method handleInbound.

/**
 * Drive through the inbound establishment states, adjusting one of them
 * as necessary. Called from Establisher thread only.
 * @return next requested time or -1
 */
private long handleInbound() {
    long now = _context.clock().now();
    long nextSendTime = -1;
    InboundEstablishState inboundState = null;
    boolean expired = false;
    for (Iterator<InboundEstablishState> iter = _inboundStates.values().iterator(); iter.hasNext(); ) {
        InboundEstablishState cur = iter.next();
        if (cur.getState() == IB_STATE_CONFIRMED_COMPLETELY) {
            // completely received (though the signature may be invalid)
            iter.remove();
            inboundState = cur;
            // _log.debug("Removing completely confirmed inbound state");
            break;
        } else if (cur.getLifetime() > MAX_IB_ESTABLISH_TIME) {
            // took too long
            iter.remove();
            inboundState = cur;
            // _context.statManager().addRateData("udp.inboundEstablishFailedState", cur.getState(), cur.getLifetime());
            // if (_log.shouldLog(Log.DEBUG))
            // _log.debug("Removing expired inbound state");
            expired = true;
            break;
        } else if (cur.getState() == IB_STATE_FAILED) {
            iter.remove();
        // _context.statManager().addRateData("udp.inboundEstablishFailedState", cur.getState(), cur.getLifetime());
        } else {
            if (cur.getNextSendTime() <= now) {
                // our turn...
                inboundState = cur;
                // _log.debug("Processing inbound that wanted activity");
                break;
            } else {
                // nothin to do but wait for them to send us
                // stuff, so lets move on to the next one being
                // established
                long when = -1;
                if (cur.getNextSendTime() <= 0) {
                    when = cur.getEstablishBeginTime() + MAX_IB_ESTABLISH_TIME;
                } else {
                    when = cur.getNextSendTime();
                }
                if (when < nextSendTime)
                    nextSendTime = when;
            }
        }
    }
    if (inboundState != null) {
        // _log.debug("Processing for inbound: " + inboundState);
        synchronized (inboundState) {
            switch(inboundState.getState()) {
                case IB_STATE_REQUEST_RECEIVED:
                    if (expired)
                        processExpired(inboundState);
                    else
                        sendCreated(inboundState);
                    break;
                // fallthrough
                case IB_STATE_CREATED_SENT:
                case IB_STATE_CONFIRMED_PARTIALLY:
                    if (expired) {
                        sendDestroy(inboundState);
                        processExpired(inboundState);
                    } else if (inboundState.getNextSendTime() <= now) {
                        sendCreated(inboundState);
                    }
                    break;
                case IB_STATE_CONFIRMED_COMPLETELY:
                    RouterIdentity remote = inboundState.getConfirmedIdentity();
                    if (remote != null) {
                        if (_context.banlist().isBanlistedForever(remote.calculateHash())) {
                            if (_log.shouldLog(Log.WARN))
                                _log.warn("Dropping inbound connection from permanently banlisted peer: " + remote.calculateHash());
                            // So next time we will not accept the con, rather than doing the whole handshake
                            _context.blocklist().add(inboundState.getSentIP());
                            inboundState.fail();
                            processExpired(inboundState);
                        } else {
                            handleCompletelyEstablished(inboundState);
                        }
                    } else {
                        if (_log.shouldLog(Log.WARN))
                            _log.warn("confirmed with invalid? " + inboundState);
                        inboundState.fail();
                        processExpired(inboundState);
                    }
                    break;
                // fall through
                case IB_STATE_COMPLETE:
                case // leak here if fail() was called in IES???
                IB_STATE_FAILED:
                    // already removed;
                    break;
                case IB_STATE_UNKNOWN:
                    // Can't happen, always call receiveSessionRequest() before putting in map
                    if (_log.shouldLog(Log.ERROR))
                        _log.error("hrm, state is unknown for " + inboundState);
            }
        }
        // ok, since there was something to do, we want to loop again
        nextSendTime = now;
    }
    return nextSendTime;
}
Also used : RouterIdentity(net.i2p.data.router.RouterIdentity)

Example 12 with RouterIdentity

use of net.i2p.data.router.RouterIdentity in project i2p.i2p by i2p.

the class InboundEstablishState method buildIdentity.

/**
 *  Construct Alice's RouterIdentity.
 *  Must have received all fragments.
 *  Sets _receivedUnconfirmedIdentity, unless invalid.
 *
 *  Caller must synch on this.
 *
 *  @since 0.9.16 was in verifyIdentity()
 */
private void buildIdentity() {
    if (_receivedUnconfirmedIdentity != null)
        // dup pkt?
        return;
    int frags = _receivedIdentity.length;
    byte[] ident;
    if (frags > 1) {
        int identSize = 0;
        for (int i = 0; i < _receivedIdentity.length; i++) identSize += _receivedIdentity[i].length;
        ident = new byte[identSize];
        int off = 0;
        for (int i = 0; i < _receivedIdentity.length; i++) {
            int len = _receivedIdentity[i].length;
            System.arraycopy(_receivedIdentity[i], 0, ident, off, len);
            off += len;
        }
    } else {
        // no need to copy
        ident = _receivedIdentity[0];
    }
    ByteArrayInputStream in = new ByteArrayInputStream(ident);
    RouterIdentity peer = new RouterIdentity();
    try {
        peer.readBytes(in);
        _receivedUnconfirmedIdentity = peer;
    } catch (DataFormatException dfe) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Improperly formatted yet fully received ident", dfe);
    } catch (IOException ioe) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Improperly formatted yet fully received ident", ioe);
    }
}
Also used : DataFormatException(net.i2p.data.DataFormatException) ByteArrayInputStream(java.io.ByteArrayInputStream) RouterIdentity(net.i2p.data.router.RouterIdentity) IOException(java.io.IOException)

Example 13 with RouterIdentity

use of net.i2p.data.router.RouterIdentity 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 14 with RouterIdentity

use of net.i2p.data.router.RouterIdentity in project i2p.i2p by i2p.

the class TransportManager method getNextBid.

TransportBid getNextBid(OutNetMessage msg) {
    int unreachableTransports = 0;
    Hash peer = msg.getTarget().getIdentity().calculateHash();
    Set<String> failedTransports = msg.getFailedTransports();
    TransportBid rv = null;
    for (Transport t : _transports.values()) {
        if (t.isUnreachable(peer)) {
            unreachableTransports++;
            // this keeps GetBids() from banlisting for "no common transports"
            // right after we banlisted for "unreachable on any transport" below...
            msg.transportFailed(t.getStyle());
            continue;
        }
        if (failedTransports.contains(t.getStyle())) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Skipping transport " + t.getStyle() + " as it already failed");
            continue;
        }
        // we always want to try all transports, in case there is a faster bidirectional one
        // already connected (e.g. peer only has a public PHTTP address, but they've connected
        // to us via TCP, send via TCP)
        TransportBid bid = t.bid(msg.getTarget(), msg.getMessageSize());
        if (bid != null) {
            if (bid.getLatencyMs() == TransportBid.TRANSIENT_FAIL)
                // this keeps GetBids() from banlisting for "no common transports"
                msg.transportFailed(t.getStyle());
            else if ((rv == null) || (rv.getLatencyMs() > bid.getLatencyMs()))
                rv = bid;
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Transport " + t.getStyle() + " bid: " + bid + " currently winning? " + (rv == bid) + " (winning latency: " + rv.getLatencyMs() + " / " + rv + ")");
        } else {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Transport " + t.getStyle() + " did not produce a bid");
            if (t.isUnreachable(peer))
                unreachableTransports++;
        }
    }
    if (unreachableTransports >= _transports.size()) {
        if (msg.getTarget().getIdentity().getSigningPublicKey().getType() == null) {
            // we don't support his crypto
            _context.statManager().addRateData("transport.banlistOnUnsupportedSigType", 1);
            _context.banlist().banlistRouterForever(peer, _x("Unsupported signature type"));
        } else if (unreachableTransports >= _transports.size() && countActivePeers() > 0) {
            // Don't banlist if we aren't talking to anybody, as we may have a network connection issue
            boolean incompat = false;
            RouterInfo us = _context.router().getRouterInfo();
            if (us != null) {
                RouterIdentity id = us.getIdentity();
                if (id.getSigType() != SigType.DSA_SHA1) {
                    String v = msg.getTarget().getVersion();
                    // NTCP is earlier than SSU, use that one
                    if (VersionComparator.comp(v, NTCPTransport.MIN_SIGTYPE_VERSION) < 0)
                        incompat = true;
                }
            }
            if (incompat) {
                // they don't support our crypto
                _context.statManager().addRateData("transport.banlistOnUnsupportedSigType", 1);
                _context.banlist().banlistRouter(peer, _x("No support for our signature type"), null, null, _context.clock().now() + SIGTYPE_BANLIST_DURATION);
            } else {
                _context.statManager().addRateData("transport.banlistOnUnreachable", msg.getLifetime(), msg.getLifetime());
                _context.banlist().banlistRouter(peer, _x("Unreachable on any transport"));
            }
        }
    } else if (rv == null) {
        _context.statManager().addRateData("transport.noBidsYetNotAllUnreachable", unreachableTransports, msg.getLifetime());
    }
    return rv;
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) RouterIdentity(net.i2p.data.router.RouterIdentity) Hash(net.i2p.data.Hash) NTCPTransport(net.i2p.router.transport.ntcp.NTCPTransport) UDPTransport(net.i2p.router.transport.udp.UDPTransport)

Example 15 with RouterIdentity

use of net.i2p.data.router.RouterIdentity in project i2p.i2p by i2p.

the class LoadRouterInfoJob method readKeyData.

/**
 *  @param rkf1 in router.keys format, tried second
 *  @param rkf2 in eepPriv.dat format, tried first
 *  @return non-null, throws IOE if neither exisits
 *  @since 0.9.16
 */
public static KeyData readKeyData(File rkf1, File rkf2) throws DataFormatException, IOException {
    RouterIdentity ri;
    PrivateKey privkey;
    SigningPrivateKey signingPrivKey;
    if (rkf2.exists()) {
        RouterPrivateKeyFile pkf = new RouterPrivateKeyFile(rkf2);
        ri = pkf.getRouterIdentity();
        if (!pkf.validateKeyPairs())
            throw new DataFormatException("Key pairs invalid");
        privkey = pkf.getPrivKey();
        signingPrivKey = pkf.getSigningPrivKey();
    } else {
        InputStream fis = null;
        try {
            fis = new BufferedInputStream(new FileInputStream(rkf1));
            privkey = new PrivateKey();
            privkey.readBytes(fis);
            signingPrivKey = new SigningPrivateKey();
            signingPrivKey.readBytes(fis);
            PublicKey pubkey = new PublicKey();
            pubkey.readBytes(fis);
            SigningPublicKey signingPubKey = new SigningPublicKey();
            signingPubKey.readBytes(fis);
            // validate
            try {
                if (!pubkey.equals(KeyGenerator.getPublicKey(privkey)))
                    throw new DataFormatException("Key pairs invalid");
                if (!signingPubKey.equals(KeyGenerator.getSigningPublicKey(signingPrivKey)))
                    throw new DataFormatException("Key pairs invalid");
            } catch (IllegalArgumentException iae) {
                throw new DataFormatException("Key pairs invalid", iae);
            }
            ri = new RouterIdentity();
            ri.setPublicKey(pubkey);
            ri.setSigningPublicKey(signingPubKey);
            ri.setCertificate(Certificate.NULL_CERT);
        } finally {
            if (fis != null)
                try {
                    fis.close();
                } catch (IOException ioe) {
                }
        }
    }
    return new KeyData(ri, privkey, signingPrivKey);
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) PrivateKey(net.i2p.data.PrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) RouterIdentity(net.i2p.data.router.RouterIdentity) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) SigningPrivateKey(net.i2p.data.SigningPrivateKey) RouterPrivateKeyFile(net.i2p.data.router.RouterPrivateKeyFile) DataFormatException(net.i2p.data.DataFormatException) BufferedInputStream(java.io.BufferedInputStream)

Aggregations

RouterIdentity (net.i2p.data.router.RouterIdentity)17 RouterInfo (net.i2p.data.router.RouterInfo)10 IOException (java.io.IOException)6 DataFormatException (net.i2p.data.DataFormatException)5 Hash (net.i2p.data.Hash)5 RouterAddress (net.i2p.data.router.RouterAddress)5 SigType (net.i2p.crypto.SigType)4 OutNetMessage (net.i2p.router.OutNetMessage)4 Certificate (net.i2p.data.Certificate)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 InetAddress (java.net.InetAddress)2 ArrayList (java.util.ArrayList)2 KeyCertificate (net.i2p.data.KeyCertificate)2 PrivateKey (net.i2p.data.PrivateKey)2 PublicKey (net.i2p.data.PublicKey)2 SigningPrivateKey (net.i2p.data.SigningPrivateKey)2 SigningPublicKey (net.i2p.data.SigningPublicKey)2 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)2 BufferedInputStream (java.io.BufferedInputStream)1 BufferedOutputStream (java.io.BufferedOutputStream)1