Search in sources :

Example 36 with Hash

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

the class EstablishmentManager method establish.

/**
 *  @param queueIfMaxExceeded true normally, false if called from locked_admit so we don't loop
 *  @since 0.9.2
 */
private void establish(OutNetMessage msg, boolean queueIfMaxExceeded) {
    RouterInfo toRouterInfo = msg.getTarget();
    RouterAddress ra = _transport.getTargetAddress(toRouterInfo);
    if (ra == null) {
        _transport.failed(msg, "Remote peer has no address, cannot establish");
        return;
    }
    RouterIdentity toIdentity = toRouterInfo.getIdentity();
    Hash toHash = toIdentity.calculateHash();
    if (toRouterInfo.getNetworkId() != _networkID) {
        _context.banlist().banlistRouter(toHash);
        _transport.markUnreachable(toHash);
        _transport.failed(msg, "Remote peer is on the wrong network, cannot establish");
        return;
    }
    UDPAddress addr = new UDPAddress(ra);
    RemoteHostId maybeTo = null;
    InetAddress remAddr = addr.getHostAddress();
    int port = addr.getPort();
    // claimed address (which we won't be using if indirect)
    if (remAddr != null && port > 0 && port <= 65535) {
        maybeTo = new RemoteHostId(remAddr.getAddress(), port);
        if ((!_transport.isValid(maybeTo.getIP())) || (Arrays.equals(maybeTo.getIP(), _transport.getExternalIP()) && !_transport.allowLocal())) {
            _transport.failed(msg, "Remote peer's IP isn't valid");
            _transport.markUnreachable(toHash);
            // _context.banlist().banlistRouter(msg.getTarget().getIdentity().calculateHash(), "Invalid SSU address", UDPTransport.STYLE);
            _context.statManager().addRateData("udp.establishBadIP", 1);
            return;
        }
        InboundEstablishState inState = _inboundStates.get(maybeTo);
        if (inState != null) {
            // we have an inbound establishment in progress, queue it there instead
            synchronized (inState) {
                switch(inState.getState()) {
                    case IB_STATE_UNKNOWN:
                    case IB_STATE_REQUEST_RECEIVED:
                    case IB_STATE_CREATED_SENT:
                    case IB_STATE_CONFIRMED_PARTIALLY:
                    case IB_STATE_CONFIRMED_COMPLETELY:
                        // queue it
                        inState.addMessage(msg);
                        if (_log.shouldLog(Log.WARN))
                            _log.debug("OB msg queued to IES");
                        break;
                    case IB_STATE_COMPLETE:
                        // race, send it out (but don't call _transport.send() again and risk a loop)
                        _transport.sendIfEstablished(msg);
                        break;
                    case IB_STATE_FAILED:
                        // race, failed
                        _transport.failed(msg, "OB msg failed during IB establish");
                        break;
                }
            }
            return;
        }
    }
    RemoteHostId to;
    boolean isIndirect = addr.getIntroducerCount() > 0 || maybeTo == null;
    if (isIndirect) {
        to = new RemoteHostId(toHash);
    } else {
        to = maybeTo;
    }
    OutboundEstablishState state = null;
    int deferred = 0;
    boolean rejected = false;
    int queueCount = 0;
    state = _outboundStates.get(to);
    if (state == null) {
        state = _outboundByHash.get(toHash);
        if (state != null && _log.shouldLog(Log.INFO))
            _log.info("Found by hash: " + state);
    }
    if (state == null) {
        if (queueIfMaxExceeded && _outboundStates.size() >= getMaxConcurrentEstablish()) {
            if (_queuedOutbound.size() >= MAX_QUEUED_OUTBOUND && !_queuedOutbound.containsKey(to)) {
                rejected = true;
            } else {
                List<OutNetMessage> newQueued = new ArrayList<OutNetMessage>(MAX_QUEUED_PER_PEER);
                List<OutNetMessage> queued = _queuedOutbound.putIfAbsent(to, newQueued);
                if (queued == null) {
                    queued = newQueued;
                    if (_log.shouldLog(Log.WARN))
                        _log.warn("Queueing outbound establish to " + to + ", increase " + PROP_MAX_CONCURRENT_ESTABLISH);
                }
                // There are still races possible but this should prevent AIOOBE and NPE
                synchronized (queued) {
                    queueCount = queued.size();
                    if (queueCount < MAX_QUEUED_PER_PEER) {
                        queued.add(msg);
                        // increment for the stat below
                        queueCount++;
                    } else {
                        rejected = true;
                    }
                    deferred = _queuedOutbound.size();
                }
            }
        } else {
            // must have a valid session key
            byte[] keyBytes = addr.getIntroKey();
            if (keyBytes == null) {
                _transport.markUnreachable(toHash);
                _transport.failed(msg, "Peer has no key, cannot establish");
                return;
            }
            SessionKey sessionKey;
            try {
                sessionKey = new SessionKey(keyBytes);
            } catch (IllegalArgumentException iae) {
                _transport.markUnreachable(toHash);
                _transport.failed(msg, "Peer has bad key, cannot establish");
                return;
            }
            boolean allowExtendedOptions = VersionComparator.comp(toRouterInfo.getVersion(), VERSION_ALLOW_EXTENDED_OPTIONS) >= 0 && !_context.getBooleanProperty(PROP_DISABLE_EXT_OPTS);
            // w/o ext options, it's always 'requested', no need to set
            // don't ask if they are indirect
            boolean requestIntroduction = allowExtendedOptions && !isIndirect && _transport.introducersMaybeRequired();
            state = new OutboundEstablishState(_context, maybeTo, to, toIdentity, allowExtendedOptions, requestIntroduction, sessionKey, addr, _transport.getDHFactory());
            OutboundEstablishState oldState = _outboundStates.putIfAbsent(to, state);
            boolean isNew = oldState == null;
            if (isNew) {
                if (isIndirect && maybeTo != null)
                    _outboundByClaimedAddress.put(maybeTo, state);
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("Adding new " + state);
            } else {
                // whoops, somebody beat us to it, throw out the state we just created
                state = oldState;
            }
        }
    }
    if (state != null) {
        state.addMessage(msg);
        List<OutNetMessage> queued = _queuedOutbound.remove(to);
        if (queued != null) {
            // see comments above
            synchronized (queued) {
                for (OutNetMessage m : queued) {
                    state.addMessage(m);
                }
            }
        }
    }
    if (rejected) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Too many pending, rejecting outbound establish to " + to);
        _transport.failed(msg, "Too many pending outbound connections");
        _context.statManager().addRateData("udp.establishRejected", deferred);
        return;
    }
    if (queueCount >= MAX_QUEUED_PER_PEER) {
        _transport.failed(msg, "Too many pending messages for the given peer");
        _context.statManager().addRateData("udp.establishOverflow", queueCount, deferred);
        return;
    }
    if (deferred > 0)
        msg.timestamp("too many deferred establishers");
    else if (state != null)
        msg.timestamp("establish state already waiting");
    notifyActivity();
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) RouterIdentity(net.i2p.data.router.RouterIdentity) ArrayList(java.util.ArrayList) RouterAddress(net.i2p.data.router.RouterAddress) Hash(net.i2p.data.Hash) OutNetMessage(net.i2p.router.OutNetMessage) SessionKey(net.i2p.data.SessionKey) InetAddress(java.net.InetAddress)

Example 37 with Hash

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

the class DeliveryInstructionsTest method createDataStructure.

public DataStructure createDataStructure() throws DataFormatException {
    DeliveryInstructions instructions = new DeliveryInstructions();
    // instructions.setDelayRequested(true);
    // instructions.setDelaySeconds(42);
    instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_TUNNEL);
    // encryption key read/write disabled
    // instructions.setEncrypted(true);
    // SessionKey key = new SessionKey();
    // byte keyData[] = new byte[SessionKey.KEYSIZE_BYTES];
    // for (int i = 0; i < keyData.length; i++)
    // keyData[i] = (byte)i;
    // key.setData(keyData);
    // instructions.setEncryptionKey(key);
    Hash hash = new Hash();
    byte[] hashData = new byte[32];
    for (int i = 0; i < hashData.length; i++) hashData[i] = (byte) (i % 32);
    hash.setData(hashData);
    instructions.setRouter(hash);
    TunnelId id = new TunnelId();
    id.setTunnelId(666);
    instructions.setTunnelId(id);
    return instructions;
}
Also used : Hash(net.i2p.data.Hash) TunnelId(net.i2p.data.TunnelId)

Example 38 with Hash

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

the class EstablishState method sendInboundConfirm.

/**
 *  We are Bob. Send message #4 to Alice.
 *
 *  State must be VERIFIED.
 *  Caller must synch.
 */
private void sendInboundConfirm(RouterIdentity alice, long tsA) {
    // send Alice E(S(X+Y+Alice.identHash+tsA+tsB), sk, prev)
    byte[] toSign = new byte[XY_SIZE + XY_SIZE + 32 + 4 + 4];
    int off = 0;
    System.arraycopy(_X, 0, toSign, off, XY_SIZE);
    off += XY_SIZE;
    System.arraycopy(_Y, 0, toSign, off, XY_SIZE);
    off += XY_SIZE;
    Hash h = alice.calculateHash();
    System.arraycopy(h.getData(), 0, toSign, off, 32);
    off += 32;
    DataHelper.toLong(toSign, off, 4, tsA);
    off += 4;
    DataHelper.toLong(toSign, off, 4, _tsB);
    off += 4;
    // handle variable signature size
    Signature sig = _context.dsa().sign(toSign, _context.keyManager().getSigningPrivateKey());
    int siglen = sig.length();
    int rem = siglen % AES_SIZE;
    int padding;
    if (rem > 0)
        padding = AES_SIZE - rem;
    else
        padding = 0;
    byte[] preSig = new byte[siglen + padding];
    System.arraycopy(sig.getData(), 0, preSig, 0, siglen);
    if (padding > 0)
        _context.random().nextBytes(preSig, siglen, padding);
    _e_bobSig = new byte[preSig.length];
    _context.aes().encrypt(preSig, 0, _e_bobSig, 0, _dh.getSessionKey(), _e_hXY_tsB, HXY_TSB_PAD_SIZE - AES_SIZE, _e_bobSig.length);
    if (_log.shouldLog(Log.DEBUG))
        _log.debug(prefix() + "Sending encrypted inbound confirmation");
    _transport.getPumper().wantsWrite(_con, _e_bobSig);
}
Also used : Signature(net.i2p.data.Signature) Hash(net.i2p.data.Hash)

Example 39 with Hash

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

the class NTCPTransport method bid.

public TransportBid bid(RouterInfo toAddress, long dataSize) {
    if (!isAlive())
        return null;
    if (dataSize > NTCPConnection.MAX_MSG_SIZE) {
        // let SSU deal with it
        _context.statManager().addRateData("ntcp.noBidTooLargeI2NP", dataSize);
        return null;
    }
    Hash peer = toAddress.getIdentity().calculateHash();
    if (_context.banlist().isBanlisted(peer, STYLE)) {
        // we aren't banlisted in general (since we are trying to get a bid), but we have
        // recently banlisted the peer on the NTCP transport, so don't try it
        _context.statManager().addRateData("ntcp.attemptBanlistedPeer", 1);
        return null;
    } else if (isUnreachable(peer)) {
        _context.statManager().addRateData("ntcp.attemptUnreachablePeer", 1);
        return null;
    }
    boolean established = isEstablished(toAddress.getIdentity());
    if (established) {
        // _log.debug("fast bid when trying to send to " + peer + " as its already established");
        return _fastBid;
    }
    RouterAddress addr = getTargetAddress(toAddress);
    if (addr == null) {
        markUnreachable(peer);
        return null;
    }
    // Check for supported sig type
    SigType type = toAddress.getIdentity().getSigType();
    if (type == null || !type.isAvailable()) {
        markUnreachable(peer);
        return null;
    }
    // Can we connect to them if we are not DSA?
    RouterInfo us = _context.router().getRouterInfo();
    if (us != null) {
        RouterIdentity id = us.getIdentity();
        if (id.getSigType() != SigType.DSA_SHA1) {
            String v = toAddress.getVersion();
            if (VersionComparator.comp(v, MIN_SIGTYPE_VERSION) < 0) {
                markUnreachable(peer);
                return null;
            }
        }
    }
    if (!allowConnection()) {
        // _log.warn("no bid when trying to send to " + peer + ", max connection limit reached");
        return _transientFail;
    }
    // _log.debug("slow bid when trying to send to " + peer);
    if (haveCapacity()) {
        if (addr.getCost() > DEFAULT_COST)
            return _slowCostBid;
        else
            return _slowBid;
    } else {
        if (addr.getCost() > DEFAULT_COST)
            return _nearCapacityCostBid;
        else
            return _nearCapacityBid;
    }
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) RouterIdentity(net.i2p.data.router.RouterIdentity) RouterAddress(net.i2p.data.router.RouterAddress) Hash(net.i2p.data.Hash) SigType(net.i2p.crypto.SigType)

Example 40 with Hash

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

the class NTCPTransport method inboundEstablished.

/**
 * @param con that is established
 * @return the previous connection to the same peer, must be closed by caller, null if no such.
 */
NTCPConnection inboundEstablished(NTCPConnection con) {
    _context.statManager().addRateData("ntcp.inboundEstablished", 1);
    Hash peer = con.getRemotePeer().calculateHash();
    markReachable(peer, true);
    // _context.banlist().unbanlistRouter(con.getRemotePeer().calculateHash());
    NTCPConnection old;
    synchronized (_conLock) {
        old = _conByIdent.put(peer, con);
    }
    if (con.isIPv6()) {
        _lastInboundIPv6 = con.getCreated();
        _context.statManager().addRateData("ntcp.inboundIPv6Conn", 1);
    } else {
        _lastInboundIPv4 = con.getCreated();
        _context.statManager().addRateData("ntcp.inboundIPv4Conn", 1);
    }
    return old;
}
Also used : Hash(net.i2p.data.Hash)

Aggregations

Hash (net.i2p.data.Hash)235 RouterInfo (net.i2p.data.router.RouterInfo)45 ArrayList (java.util.ArrayList)29 TunnelId (net.i2p.data.TunnelId)20 Destination (net.i2p.data.Destination)18 HashSet (java.util.HashSet)17 ConvertToHash (net.i2p.util.ConvertToHash)17 IOException (java.io.IOException)16 TunnelInfo (net.i2p.router.TunnelInfo)15 DataFormatException (net.i2p.data.DataFormatException)14 Properties (java.util.Properties)13 Date (java.util.Date)12 DatabaseEntry (net.i2p.data.DatabaseEntry)11 SessionKey (net.i2p.data.SessionKey)11 RouterAddress (net.i2p.data.router.RouterAddress)11 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)9 I2NPMessage (net.i2p.data.i2np.I2NPMessage)9 Job (net.i2p.router.Job)9 OutNetMessage (net.i2p.router.OutNetMessage)9 TunnelPoolSettings (net.i2p.router.TunnelPoolSettings)8