Changeset ba0408a


Ignore:
Timestamp:
Aug 24, 2012 10:11:02 PM (7 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
9d383d6
Parents:
07c21c3
Message:
  • I2CP:
    • Add methods for sending a message with extended options
    • Fix cases where the efficient sendNoEffort() wasn't being used
  • OCMOSJ:
    • Implement per-message overrides for tag threshold, tags to send, and bundle leaseset
    • Fix bug adjusting timeouts
    • Warn on client expiration time bugs
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • core/java/src/net/i2p/client/I2CPMessageProducer.java

    r07c21c3 rba0408a  
    160160
    161161    /**
     162     * Package up and send the payload to the router for delivery
     163     * @since 0.9.2
     164     */
     165    public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload,
     166                            SendMessageOptions options) throws I2PSessionException {
     167
     168        long expires = options.getTime();
     169        if (!updateBps(payload.length, expires))
     170            // drop the message... send fail notification?
     171            return;
     172        SendMessageMessage msg = new SendMessageExpiresMessage(options);
     173        msg.setDestination(dest);
     174        msg.setSessionId(session.getSessionId());
     175        msg.setNonce(nonce);
     176        Payload data = createPayload(dest, payload, null, null, null, null);
     177        msg.setPayload(data);
     178        session.sendMessage(msg);
     179    }
     180
     181    /**
    162182     *  Super-simple bandwidth throttler.
    163183     *  We only calculate on a one-second basis, so large messages
  • core/java/src/net/i2p/client/I2PSession.java

    r07c21c3 rba0408a  
    9898     * @param keyUsed UNUSED, IGNORED.
    9999     * @param tagsSent UNUSED, IGNORED.
     100     * @param expire absolute expiration timestamp, NOT interval from now
    100101     * @since 0.7.1
    101102     */
     
    117118     * @param keyUsed UNUSED, IGNORED.
    118119     * @param tagsSent UNUSED, IGNORED.
     120     * @param expire absolute expiration timestamp, NOT interval from now
    119121     * @since 0.7.1
    120122     */
     
    127129     * @param keyUsed UNUSED, IGNORED.
    128130     * @param tagsSent UNUSED, IGNORED.
     131     * @param expire absolute expiration timestamp, NOT interval from now
    129132     * @since 0.8.4
    130133     */
    131134    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent, long expire,
    132135                               int proto, int fromport, int toport, int flags) throws I2PSessionException;
     136
     137    /**
     138     * See I2PSessionMuxedImpl for proto/port details.
     139     * See SendMessageOptions for option details.
     140     * @since 0.9.2
     141     */
     142    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size,
     143                               int proto, int fromport, int toport, SendMessageOptions options) throws I2PSessionException;
    133144
    134145    /** Receive a message that the router has notified the client about, returning
  • core/java/src/net/i2p/client/I2PSessionImpl2.java

    r07c21c3 rba0408a  
    4343    private final static boolean SHOULD_DECOMPRESS = true;
    4444    /** Don't expect any MSMs from the router for outbound traffic @since 0.8.1 */
    45     private boolean _noEffort;
     45    protected boolean _noEffort;
    4646
    4747    /** for extension */
     
    140140        throw new IllegalArgumentException("Use MuxedImpl");
    141141    }
    142 
     142    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size,
     143                               int proto, int fromport, int toport, SendMessageOptions options) throws I2PSessionException {
     144        throw new IllegalArgumentException("Use MuxedImpl");
     145    }
     146
     147    /** unused, see MuxedImpl override */
    143148    @Override
    144149    public boolean sendMessage(Destination dest, byte[] payload) throws I2PSessionException {
    145150        return sendMessage(dest, payload, 0, payload.length);
    146151    }
     152
    147153    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size) throws I2PSessionException {
    148154        // we don't do end-to-end crypto any more
     
    170176
    171177    /**
     178     * Unused? see MuxedImpl override
     179     *
    172180     * @param keyUsed unused - no end-to-end crypto
    173181     * @param tagsSent unused - no end-to-end crypto
     
    203211        _context.statManager().addRateData("i2cp.tx.msgExpanded", size, 0);
    204212        if (_noEffort)
    205             return sendNoEffort(dest, payload, expires);
     213            return sendNoEffort(dest, payload, expires, 0);
    206214        else
    207215            return sendBestEffort(dest, payload, keyUsed, tagsSent, expires);
     
    408416     * @since 0.8.1
    409417     */
    410     protected boolean sendNoEffort(Destination dest, byte payload[], long expires)
     418    protected boolean sendNoEffort(Destination dest, byte payload[], long expires, int flags)
    411419                    throws I2PSessionException {
    412420        // nonce always 0
    413         _producer.sendMessage(this, dest, 0, payload, null, null, null, null, expires);
     421        _producer.sendMessage(this, dest, 0, payload, expires, flags);
    414422        return true;
    415423    }
  • core/java/src/net/i2p/client/I2PSessionMuxedImpl.java

    r07c21c3 rba0408a  
    6464 *
    6565 * @author zzz
     66 * @since 0.7.1
    6667 */
    6768class I2PSessionMuxedImpl extends I2PSessionImpl2 {
     
    209210        _context.statManager().addRateData("i2cp.tx.msgCompressed", payload.length, 0);
    210211        _context.statManager().addRateData("i2cp.tx.msgExpanded", size, 0);
    211         return sendBestEffort(dest, payload, expires, flags);
     212        if (_noEffort)
     213            return sendNoEffort(dest, payload, expires, flags);
     214        else
     215            return sendBestEffort(dest, payload, expires, flags);
     216    }
     217
     218    /**
     219     *  See SendMessageOptions for option details.
     220     *
     221     *  Always uses sendNoEffort for now. These are presumed to be datagrams.
     222     *  SendMessageOptions 16-bit flag field is currently undefined, so
     223     *  serialization won't work; therefore this only makes sense in RouterContext,
     224     *  for now.
     225     *
     226     *  @param proto 1-254 or 0 for unset; recommended:
     227     *         I2PSession.PROTO_UNSPECIFIED
     228     *         I2PSession.PROTO_STREAMING
     229     *         I2PSession.PROTO_DATAGRAM
     230     *         255 disallowed
     231     *  @param fromPort 1-65535 or 0 for unset
     232     *  @param toPort 1-65535 or 0 for unset
     233     *  @param options to be passed to the router
     234     *  @since 0.9.2
     235     */
     236    @Override
     237    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size,
     238                               int proto, int fromPort, int toPort, SendMessageOptions options) throws I2PSessionException {
     239        if (isClosed()) throw new I2PSessionException("Already closed");
     240        updateActivity();
     241
     242        boolean sc = shouldCompress(size);
     243        if (sc)
     244            payload = DataHelper.compress(payload, offset, size);
     245        else
     246            payload = DataHelper.compress(payload, offset, size, DataHelper.NO_COMPRESSION);
     247
     248        setProto(payload, proto);
     249        setFromPort(payload, fromPort);
     250        setToPort(payload, toPort);
     251
     252        _context.statManager().addRateData("i2cp.tx.msgCompressed", payload.length, 0);
     253        _context.statManager().addRateData("i2cp.tx.msgExpanded", size, 0);
     254        //if (_noEffort) {
     255            sendNoEffort(dest, payload, options);
     256            return true;
     257        //} else {
     258            // unimplemented
     259            //return sendBestEffort(dest, payload, options);
     260        //}
     261    }
     262
     263    /**
     264     * @since 0.9.2
     265     */
     266    private void sendNoEffort(Destination dest, byte payload[], SendMessageOptions options)
     267                    throws I2PSessionException {
     268        // nonce always 0
     269        _producer.sendMessage(this, dest, 0, payload, options);
    212270    }
    213271
  • core/java/src/net/i2p/data/DateAndFlags.java

    r07c21c3 rba0408a  
    2929 */
    3030public class DateAndFlags extends DataStructureImpl {
    31     private int _flags;
     31    protected int _flags;
    3232    private long _date;
    3333
  • core/java/src/net/i2p/data/i2cp/SendMessageExpiresMessage.java

    r07c21c3 rba0408a  
    3232
    3333    public SendMessageExpiresMessage() {
     34        this(new DateAndFlags());
     35    }
     36
     37    /** @since 0.9.2 */
     38    public SendMessageExpiresMessage(DateAndFlags options) {
    3439        super();
    35         _daf = new DateAndFlags();
     40        _daf = options;
    3641    }
    3742
  • router/java/src/net/i2p/router/message/GarlicMessageBuilder.java

    r07c21c3 rba0408a  
    3434public class GarlicMessageBuilder {
    3535
    36     /** @param local non-null; do not use this method for the router's SessionKeyManager */
    37     public static boolean needsTags(RouterContext ctx, PublicKey key, Hash local) {
     36    /**
     37     *  @param local non-null; do not use this method for the router's SessionKeyManager
     38     *  @param minTagOverride 0 for no override, > 0 to override SKM's settings
     39     */
     40    static boolean needsTags(RouterContext ctx, PublicKey key, Hash local, int minTagOverride) {
    3841        SessionKeyManager skm = ctx.clientManager().getClientSessionKeyManager(local);
    3942        if (skm == null)
     
    4245        if (curKey == null)
    4346            return true;
     47        if (minTagOverride > 0)
     48            return skm.shouldSendTags(key, curKey, minTagOverride);
    4449        return skm.shouldSendTags(key, curKey);
    4550    }
     
    142147       
    143148        if (log.shouldLog(Log.INFO))
    144             log.info("Encrypted with public key " + key + " to expire on " + new Date(config.getExpiration()));
     149            log.info("Encrypted with public key to expire on " + new Date(config.getExpiration()));
    145150       
    146151        SessionKey curKey = skm.getCurrentOrNewKey(key);
     
    149154            curTag = skm.consumeNextAvailableTag(key, curKey);
    150155           
    151             int availTags = skm.getAvailableTags(key, curKey);
    152             if (log.shouldLog(Log.DEBUG))
    153                 log.debug("Available tags for encryption to " + key + ": " + availTags);
     156            if (log.shouldLog(Log.DEBUG)) {
     157                int availTags = skm.getAvailableTags(key, curKey);
     158                log.debug("Available tags for encryption: " + availTags + " low threshold: " + lowTagsThreshold);
     159            }
    154160
    155161            if (numTagsToDeliver > 0 && skm.shouldSendTags(key, curKey, lowTagsThreshold)) {
  • router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java

    r07c21c3 rba0408a  
    6262                                             boolean requireAck, LeaseSet bundledReplyLeaseSet) {
    6363        PayloadGarlicConfig dataClove = buildDataClove(ctx, data, dest, expiration);
    64         return createGarlicMessage(ctx, replyToken, expiration, recipientPK, dataClove, from, dest, replyTunnel, wrappedKey,
    65                                    wrappedTags, requireAck, bundledReplyLeaseSet);
     64        return createGarlicMessage(ctx, replyToken, expiration, recipientPK, dataClove, from, dest, replyTunnel,
     65                                   0, 0, wrappedKey, wrappedTags, requireAck, bundledReplyLeaseSet);
    6666    }
    6767    /**
     
    7171     * This is called from OCMOSJ
    7272     *
     73     * @param tagsToSendOverride if > 0, use this instead of skm's default
     74     * @param lowTagsOverride if > 0, use this instead of skm's default
    7375     * @param wrappedKey output parameter that will be filled with the sessionKey used
    7476     * @param wrappedTags output parameter that will be filled with the sessionTags used
     
    7678     */
    7779    static GarlicMessage createGarlicMessage(RouterContext ctx, long replyToken, long expiration, PublicKey recipientPK,
    78                                              PayloadGarlicConfig dataClove, Hash from, Destination dest, TunnelInfo replyTunnel, SessionKey wrappedKey,
     80                                             PayloadGarlicConfig dataClove, Hash from, Destination dest, TunnelInfo replyTunnel,
     81                                             int tagsToSendOverride, int lowTagsOverride, SessionKey wrappedKey,
    7982                                             Set<SessionTag> wrappedTags, boolean requireAck, LeaseSet bundledReplyLeaseSet) {
    8083        GarlicConfig config = createGarlicConfig(ctx, replyToken, expiration, recipientPK, dataClove, from, dest, replyTunnel, requireAck, bundledReplyLeaseSet);
     
    8588            return null;
    8689        // no use sending tags unless we have a reply token set up already
    87         int tagsToSend = replyToken >= 0 ? skm.getTagsToSend() : 0;
     90        int tagsToSend = replyToken >= 0 ? (tagsToSendOverride > 0 ? tagsToSendOverride : skm.getTagsToSend()) : 0;
     91        int lowThreshold = lowTagsOverride > 0 ? lowTagsOverride : skm.getLowThreshold();
    8892        GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, config, wrappedKey, wrappedTags,
    89                                                               tagsToSend, skm);
     93                                                              tagsToSend, lowThreshold, skm);
    9094        return msg;
    9195    }
  • router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java

    r07c21c3 rba0408a  
    88import java.util.Set;
    99
     10import net.i2p.client.SendMessageOptions;
    1011import net.i2p.crypto.SessionKeyManager;
    1112import net.i2p.crypto.TagSetHandle;
     
    136137        long overallExpiration = msg.getExpiration();
    137138        if (overallExpiration > 0) {
     139            if (overallExpiration < 24*60*60*1000l) {
     140                if (_log.shouldLog(Log.WARN))
     141                    _log.warn("Client bug - interval instead of timestamp " + overallExpiration);
     142                overallExpiration += _start;
     143            }
    138144            // Unless it's already expired, set a min and max expiration
    139             if (overallExpiration <= _start) {
     145            if (overallExpiration > _start) {
    140146                overallExpiration = Math.max(overallExpiration, _start + OVERALL_TIMEOUT_MS_MIN);
    141147                overallExpiration = Math.min(overallExpiration, _start + OVERALL_TIMEOUT_MS_DEFAULT);
     
    431437                                     lastReplyRequestSent.longValue() < now - REPLY_REQUEST_INTERVAL;
    432438
     439        int sendFlags = _clientMessage.getFlags();
     440        // Per-message flag > 0 overrides per-session option
     441        int tagsRequired = SendMessageOptions.getTagThreshold(sendFlags);
    433442        boolean wantACK = _wantACK ||
    434443                          shouldRequestReply ||
    435                           // TODO: check the per-message flags also
    436                           GarlicMessageBuilder.needsTags(getContext(), _leaseSet.getEncryptionKey(), _from.calculateHash());
     444                          GarlicMessageBuilder.needsTags(getContext(), _leaseSet.getEncryptionKey(),
     445                                                         _from.calculateHash(), tagsRequired);
    437446       
    438447        PublicKey key = _leaseSet.getEncryptionKey();
     
    441450
    442451        LeaseSet replyLeaseSet;
    443         // TODO: check the per-message flags also
     452        // Per-message flag == false overrides session option which is default true
    444453        String allow = _clientMessage.getSenderConfig().getOptions().getProperty(BUNDLE_REPLY_LEASESET);
    445         boolean allowLeaseBundle = allow == null || Boolean.valueOf(allow).booleanValue();
     454        boolean allowLeaseBundle = SendMessageOptions.getSendLeaseSet(sendFlags) &&
     455                                   (allow == null || Boolean.valueOf(allow).booleanValue());
    446456        if (allowLeaseBundle) {
    447457            // If we want an ack, bundle a leaseSet...
     
    474484        //    _log.debug(getJobId() + ": Clove built to " + _toString);
    475485        long msgExpiration = _overallExpiration; // getContext().clock().now() + OVERALL_TIMEOUT_MS_DEFAULT;
     486        // Per-message flag > 0 overrides per-session option
     487        int tagsToSend = SendMessageOptions.getTagsToSend(sendFlags);
    476488        GarlicMessage msg = OutboundClientMessageJobHelper.createGarlicMessage(getContext(), token,
    477489                                                                               msgExpiration, key,
    478490                                                                               _clove, _from.calculateHash(),
    479                                                                                _to, _inTunnel,
    480                                                                                sessKey, tags,
     491                                                                               _to, _inTunnel, tagsToSend,
     492                                                                               tagsRequired, sessKey, tags,
    481493                                                                               wantACK, replyLeaseSet);
    482494        if (msg == null) {
Note: See TracChangeset for help on using the changeset viewer.