Search in sources :

Example 61 with SessionKey

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

the class TransientSessionKeyManager method renderStatusHTML.

@Override
public void renderStatusHTML(Writer out) throws IOException {
    StringBuilder buf = new StringBuilder(1024);
    buf.append("<h3 class=\"debug_inboundsessions\">Inbound sessions</h3>" + "<table>");
    Map<SessionKey, Set<TagSet>> inboundSets = getInboundTagSetsBySessionKey();
    int total = 0;
    int totalSets = 0;
    long now = _context.clock().now();
    Set<TagSet> sets = new TreeSet<TagSet>(new TagSetComparator());
    for (Map.Entry<SessionKey, Set<TagSet>> e : inboundSets.entrySet()) {
        SessionKey skey = e.getKey();
        sets.clear();
        sets.addAll(e.getValue());
        totalSets += sets.size();
        buf.append("<tr><td><b>Session key:</b> ").append(skey.toBase64()).append("</td>" + "<td><b>Sets:</b> ").append(sets.size()).append("</td></tr>" + "<tr class=\"expiry\"><td colspan=\"2\"><ul>");
        for (TagSet ts : sets) {
            int size = ts.getTags().size();
            total += size;
            buf.append("<li><b>ID: ").append(ts.getID());
            long expires = ts.getDate() - now;
            if (expires > 0)
                buf.append(" expires in:</b> ").append(DataHelper.formatDuration2(expires)).append(" with ");
            else
                buf.append(" expired:</b> ").append(DataHelper.formatDuration2(0 - expires)).append(" ago with ");
            buf.append(size).append('/').append(ts.getOriginalSize()).append(" tags remaining</li>");
        }
        buf.append("</ul></td></tr>\n");
        out.write(buf.toString());
        buf.setLength(0);
    }
    buf.append("<tr><th colspan=\"2\">Total inbound tags: ").append(total).append(" (").append(DataHelper.formatSize2(32 * total)).append("B); sets: ").append(totalSets).append("; sessions: ").append(inboundSets.size()).append("</th></tr>\n" + "</table>" + "<h3 class=\"debug_outboundsessions\">Outbound sessions</h3>" + "<table>");
    total = 0;
    totalSets = 0;
    Set<OutboundSession> outbound = getOutboundSessions();
    for (Iterator<OutboundSession> iter = outbound.iterator(); iter.hasNext(); ) {
        OutboundSession sess = iter.next();
        sets.clear();
        sets.addAll(sess.getTagSets());
        totalSets += sets.size();
        buf.append("<tr class=\"debug_outboundtarget\"><td><div class=\"debug_targetinfo\"><b>Target public key:</b> ").append(toString(sess.getTarget())).append("<br>" + "<b>Established:</b> ").append(DataHelper.formatDuration2(now - sess.getEstablishedDate())).append(" ago<br>" + "<b>Ack Received?</b> ").append(sess.getAckReceived()).append("<br>" + "<b>Last Used:</b> ").append(DataHelper.formatDuration2(now - sess.getLastUsedDate())).append(" ago<br>" + "<b>Session key:</b> ").append(sess.getCurrentKey().toBase64()).append("</div></td>" + "<td><b># Sets:</b> ").append(sess.getTagSets().size()).append("</td></tr>" + "<tr><td colspan=\"2\"><ul>");
        for (Iterator<TagSet> siter = sets.iterator(); siter.hasNext(); ) {
            TagSet ts = siter.next();
            int size = ts.getTags().size();
            total += size;
            buf.append("<li><b>ID: ").append(ts.getID()).append(" Sent:</b> ").append(DataHelper.formatDuration2(now - ts.getDate())).append(" ago with ");
            buf.append(size).append('/').append(ts.getOriginalSize()).append(" tags remaining; acked? ").append(ts.getAcked()).append("</li>");
        }
        buf.append("</ul></td></tr>\n");
        out.write(buf.toString());
        buf.setLength(0);
    }
    buf.append("<tr><th colspan=\"2\">Total outbound tags: ").append(total).append(" (").append(DataHelper.formatSize2(32 * total)).append("B); sets: ").append(totalSets).append("; sessions: ").append(outbound.size()).append("</th></tr>\n</table>");
    out.write(buf.toString());
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) SessionKey(net.i2p.data.SessionKey) TreeSet(java.util.TreeSet) HashMap(java.util.HashMap) Map(java.util.Map)

Example 62 with SessionKey

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

the class PersistentKeyRing method remove.

@Override
public SessionKey remove(Object o) {
    SessionKey rv = super.remove(o);
    if (rv != null && o != null && o instanceof Hash) {
        Hash h = (Hash) o;
        _ctx.router().saveConfig(PROP_PFX + h.toBase64().replace("=", "$"), null);
    }
    return rv;
}
Also used : SessionKey(net.i2p.data.SessionKey) Hash(net.i2p.data.Hash)

Example 63 with SessionKey

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

the class PersistentKeyRing method addFromProperties.

private void addFromProperties() {
    for (String prop : _ctx.getPropertyNames()) {
        if (!prop.startsWith(PROP_PFX))
            continue;
        String key = _ctx.getProperty(prop);
        if (key == null || key.length() != 44)
            continue;
        String hb = prop.substring(PROP_PFX.length());
        hb = hb.replace("$", "=");
        Hash dest = new Hash();
        SessionKey sk = new SessionKey();
        try {
            dest.fromBase64(hb);
            sk.fromBase64(key);
            super.put(dest, sk);
        } catch (DataFormatException dfe) {
            continue;
        }
    }
}
Also used : DataFormatException(net.i2p.data.DataFormatException) SessionKey(net.i2p.data.SessionKey) Hash(net.i2p.data.Hash)

Example 64 with SessionKey

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

the class OutboundClientMessageOneShotJob method send.

/**
 * Send the message to the specified tunnel by creating a new garlic message containing
 * the (already created) payload clove as well as a new delivery status message.  This garlic
 * message is sent out one of our tunnels, destined for the lease (tunnel+router) specified, and the delivery
 * status message is targetting one of our free inbound tunnels as well.  We use a new
 * reply selector to keep an eye out for that delivery status message's token
 */
private void send() {
    synchronized (this) {
        if (_finished != Result.NONE) {
            if (_log.shouldLog(Log.WARN))
                _log.warn(OutboundClientMessageOneShotJob.this.getJobId() + ": SEND-AFTER-" + _finished);
            return;
        }
    }
    long now = getContext().clock().now();
    if (now >= _overallExpiration) {
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_EXPIRED);
        return;
    }
    _outTunnel = selectOutboundTunnel(_to);
    if (_outTunnel == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn(getJobId() + ": Could not find any outbound tunnels to send the payload through... this might take a while");
        getContext().statManager().addRateData("client.dispatchNoTunnels", now - _start);
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_NO_TUNNELS);
        return;
    }
    // boolean wantACK = _wantACK || existingTags <= 30 || getContext().random().nextInt(100) < 5;
    // what's the point of 5% random? possible improvements or replacements:
    // DONE (getNextLease() is called before this): wantACK if we changed their inbound lease (getNextLease() sets _wantACK)
    // DONE (selectOutboundTunnel() moved above here): wantACK if we changed our outbound tunnel (selectOutboundTunnel() sets _wantACK)
    // DONE (added new cache): wantACK if we haven't in last 1m (requires a new static cache probably)
    Long lastReplyRequestSent = _cache.lastReplyRequestCache.get(_hashPair);
    boolean shouldRequestReply = lastReplyRequestSent == null || lastReplyRequestSent.longValue() < now - REPLY_REQUEST_INTERVAL;
    int sendFlags = _clientMessage.getFlags();
    // Per-message flag > 0 overrides per-session option
    int tagsRequired = SendMessageOptions.getTagThreshold(sendFlags);
    boolean wantACK = _wantACK || shouldRequestReply || GarlicMessageBuilder.needsTags(getContext(), _leaseSet.getEncryptionKey(), _from.calculateHash(), tagsRequired);
    LeaseSet replyLeaseSet;
    // Per-message flag == false overrides session option which is default true
    String allow = _clientMessage.getSenderConfig().getOptions().getProperty(BUNDLE_REPLY_LEASESET);
    boolean allowLeaseBundle = SendMessageOptions.getSendLeaseSet(sendFlags) && (allow == null || Boolean.parseBoolean(allow));
    if (allowLeaseBundle) {
        // If we want an ack, bundle a leaseSet...
        // replyLeaseSet = getReplyLeaseSet(wantACK);
        // Only when necessary. We don't need to force.
        // ACKs find their own way back, they don't need a leaseset.
        replyLeaseSet = getReplyLeaseSet(false);
        // ... and vice versa  (so we know he got it)
        if (replyLeaseSet != null)
            wantACK = true;
    } else {
        replyLeaseSet = null;
    }
    long token;
    if (wantACK) {
        _cache.lastReplyRequestCache.put(_hashPair, Long.valueOf(now));
        token = getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
        _inTunnel = selectInboundTunnel();
    } else {
        token = -1;
    }
    PayloadGarlicConfig clove = buildClove();
    if (clove == null) {
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_UNSUPPORTED_ENCRYPTION);
        return;
    }
    // if (_log.shouldLog(Log.DEBUG))
    // _log.debug(getJobId() + ": Clove built to " + _toString);
    PublicKey key = _leaseSet.getEncryptionKey();
    SessionKey sessKey = new SessionKey();
    Set<SessionTag> tags = new HashSet<SessionTag>();
    // Per-message flag > 0 overrides per-session option
    int tagsToSend = SendMessageOptions.getTagsToSend(sendFlags);
    GarlicMessage msg = OutboundClientMessageJobHelper.createGarlicMessage(getContext(), token, _overallExpiration, key, clove, _from.calculateHash(), _to, _inTunnel, tagsToSend, tagsRequired, sessKey, tags, wantACK, replyLeaseSet);
    if (msg == null) {
        // we dont receive the reply? hmm...)
        if (_log.shouldLog(Log.WARN))
            _log.warn(getJobId() + ": Unable to create the garlic message (no tunnels left or too lagged) to " + _toString);
        getContext().statManager().addRateData("client.dispatchNoTunnels", now - _start);
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_NO_TUNNELS);
        return;
    }
    // if (_log.shouldLog(Log.DEBUG))
    // _log.debug(getJobId() + ": send() - token expected " + token + " to " + _toString);
    SendSuccessJob onReply = null;
    SendTimeoutJob onFail = null;
    ReplySelector selector = null;
    if (wantACK) {
        TagSetHandle tsh = null;
        if (!tags.isEmpty()) {
            SessionKeyManager skm = getContext().clientManager().getClientSessionKeyManager(_from.calculateHash());
            if (skm != null)
                tsh = skm.tagsDelivered(_leaseSet.getEncryptionKey(), sessKey, tags);
        }
        onReply = new SendSuccessJob(getContext(), sessKey, tsh);
        onFail = new SendTimeoutJob(getContext(), sessKey, tsh);
        long expiration = Math.max(_overallExpiration, _start + REPLY_TIMEOUT_MS_MIN);
        selector = new ReplySelector(token, expiration);
    }
    if (_log.shouldLog(Log.DEBUG))
        _log.debug(getJobId() + ": Sending msg out " + _outTunnel.getSendTunnelId(0) + " to " + _toString + " at " + _lease.getTunnelId() + " on " + _lease.getGateway());
    DispatchJob dispatchJob = new DispatchJob(getContext(), msg, selector, onReply, onFail);
    // if (false) // dispatch may take 100+ms, so toss it in its own job
    // getContext().jobQueue().addJob(dispatchJob);
    // else
    dispatchJob.runJob();
    getContext().statManager().addRateData("client.dispatchPrepareTime", now - _start);
    if (!wantACK)
        getContext().statManager().addRateData("client.dispatchNoACK", 1);
}
Also used : PublicKey(net.i2p.data.PublicKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager) TagSetHandle(net.i2p.crypto.TagSetHandle) LeaseSet(net.i2p.data.LeaseSet) SessionKey(net.i2p.data.SessionKey) GarlicMessage(net.i2p.data.i2np.GarlicMessage) SessionTag(net.i2p.data.SessionTag) HashSet(java.util.HashSet)

Example 65 with SessionKey

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

the class HandleDatabaseLookupMessageJob method sendThroughTunnel.

private void sendThroughTunnel(I2NPMessage message, Hash toPeer, TunnelId replyTunnel) {
    if (getContext().routerHash().equals(toPeer)) {
        // if we are the gateway, act as if we received it
        TunnelGatewayMessage m = new TunnelGatewayMessage(getContext());
        m.setMessage(message);
        m.setTunnelId(replyTunnel);
        m.setMessageExpiration(message.getMessageExpiration());
        getContext().tunnelDispatcher().dispatch(m);
    } else {
        // if we aren't the gateway, forward it on
        if (!_replyKeyConsumed) {
            // if we send a followup DSM w/ our RI, don't reuse key
            SessionKey replyKey = _message.getReplyKey();
            if (replyKey != null) {
                // encrypt the reply
                if (_log.shouldLog(Log.INFO))
                    _log.info("Sending encrypted reply to " + toPeer + ' ' + replyKey + ' ' + _message.getReplyTag());
                message = MessageWrapper.wrap(getContext(), message, replyKey, _message.getReplyTag());
                if (message == null) {
                    _log.error("Encryption error");
                    return;
                }
                _replyKeyConsumed = true;
            }
        }
        TunnelGatewayMessage m = new TunnelGatewayMessage(getContext());
        m.setMessage(message);
        m.setMessageExpiration(message.getMessageExpiration());
        m.setTunnelId(replyTunnel);
        SendMessageDirectJob j = new SendMessageDirectJob(getContext(), m, toPeer, 10 * 1000, MESSAGE_PRIORITY);
        j.runJob();
    // getContext().jobQueue().addJob(j);
    }
}
Also used : TunnelGatewayMessage(net.i2p.data.i2np.TunnelGatewayMessage) SessionKey(net.i2p.data.SessionKey) SendMessageDirectJob(net.i2p.router.message.SendMessageDirectJob)

Aggregations

SessionKey (net.i2p.data.SessionKey)69 SessionTag (net.i2p.data.SessionTag)15 PublicKey (net.i2p.data.PublicKey)14 I2PAppContext (net.i2p.I2PAppContext)13 HashSet (java.util.HashSet)11 Hash (net.i2p.data.Hash)11 SessionKeyManager (net.i2p.crypto.SessionKeyManager)10 PrivateKey (net.i2p.data.PrivateKey)10 InetAddress (java.net.InetAddress)9 DataFormatException (net.i2p.data.DataFormatException)9 UnknownHostException (java.net.UnknownHostException)7 TagSetHandle (net.i2p.crypto.TagSetHandle)5 Map (java.util.Map)4 GarlicMessage (net.i2p.data.i2np.GarlicMessage)4 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Set (java.util.Set)3 EncryptedBuildRecord (net.i2p.data.i2np.EncryptedBuildRecord)3 BigInteger (java.math.BigInteger)2