Changeset 950ca71 for router


Ignore:
Timestamp:
Jul 8, 2018 11:00:54 AM (2 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
1c28495
Parents:
fcf82ea
Message:

NTCP2: Refactor padding size calculation
Avoid possible NPEs (ticket #2286)
Bundle up to 5 tunnel messages
Use read buffer to send RI and termination
Temp buf doesn't need 2 bytes for length
RI size check
Log tweaks

Location:
router/java/src/net/i2p/router
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/router/RouterVersion.java

    rfcf82ea r950ca71  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 5;
     21    public final static long BUILD = 6;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/transport/ntcp/NTCP2Options.java

    rfcf82ea r950ca71  
    6464    public String toString() {
    6565        return "Padding options: send min/max %: (" + (_sendMin * 100) + ", " + (_sendMax * 100) +
    66                ") recv min/max %: ( " + (_recvMin * 100) + ", " + (_recvMax * 100) +
    67                ") dummy send/recv B/s: ( " + _sendDummy + ", " + _recvDummy +
    68                ") delay send/recv ms: ( " + _sendDelay + ", " + _recvDelay + ')';
     66               ") recv min/max %: (" + (_recvMin * 100) + ", " + (_recvMax * 100) +
     67               ") dummy send/recv B/s: (" + _sendDummy + ", " + _recvDummy +
     68               ") delay send/recv ms: (" + _sendDelay + ", " + _recvDelay + ')';
    6969    }
    7070}
  • router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java

    rfcf82ea r950ca71  
    187187    private static final long NTCP2_TERMINATION_CLOSE_DELAY = 50;
    188188    // don't make combined messages too big, to minimize latency
    189     private static final int NTCP2_PREFERRED_PAYLOAD_MAX = 5000;
     189    // Tunnel data msgs are 1024 + 4 + 9 + 3 = 1040, allow 5
     190    private static final int NTCP2_PREFERRED_PAYLOAD_MAX = 5 * 1040;
    190191    static final int REASON_UNSPEC = 0;
    191192    static final int REASON_TERMINATION = 1;
     
    898899        int availForPad = BUFFER_SIZE - (size + NTCP2Payload.BLOCK_HEADER_SIZE);
    899900        if (availForPad > 0) {
    900             // what we want to send, calculated in proportion to data size
    901             int minSend = (int) (size * _paddingConfig.getSendMin());
    902             int maxSend = (int) (size * _paddingConfig.getSendMax());
    903             // the absolute min and max we can send
    904             int min = Math.min(minSend, availForPad);
    905             int max = Math.min(maxSend, availForPad);
    906             int range = max - min;
    907             if (range < MIN_PADDING_RANGE) {
    908                 // reduce min to enforce minimum range if possible
    909                 min = Math.max(0, min - (MIN_PADDING_RANGE - range));
    910                 range = max - min;
    911             } else if (range > MAX_PADDING_RANGE) {
    912                 // Don't send too much, no matter what the config says
    913                 range = MAX_PADDING_RANGE;
    914             }
    915             int padlen = min;
    916             if (range > 0)
    917                 padlen += _context.random().nextInt(1 + range);
    918             if (_log.shouldWarn())
    919                 _log.warn("Padding params:" +
    920                           " data size: " + size +
    921                           " avail: " + availForPad +
    922                           " minSend: " + minSend +
    923                           " maxSend: " + maxSend +
    924                           " min: " + min +
    925                           " max: " + max +
    926                           " range: " + range +
    927                           " padlen: " + padlen);
     901            int padlen = getPaddingSize(size, availForPad);
    928902            // all zeros is fine here
    929903            //Block block = new NTCP2Payload.PaddingBlock(_context, padlen);
     
    938912     *  NTCP2 only
    939913     *
     914     *  @param dataSize the total size of the data we are sending
     915     *  @param availForPad the available size for padding, not including padding block header,
     916     *                     must be greater than zero
     917     *  @return min 0 max availForPad
    940918     *  @since 0.9.36
    941919     */
     920    private int getPaddingSize(int dataSize, int availForPad) {
     921        // what we want to send, calculated in proportion to data size
     922        int minSend = (int) (dataSize * _paddingConfig.getSendMin());
     923        int maxSend = (int) (dataSize * _paddingConfig.getSendMax());
     924        // the absolute min and max we can send
     925        int min = Math.min(minSend, availForPad);
     926        int max = Math.min(maxSend, availForPad);
     927        int range = max - min;
     928        if (range < MIN_PADDING_RANGE) {
     929            // reduce min to enforce minimum range if possible
     930            min = Math.max(0, min - (MIN_PADDING_RANGE - range));
     931            range = max - min;
     932        } else if (range > MAX_PADDING_RANGE) {
     933            // Don't send too much, no matter what the config says
     934            range = MAX_PADDING_RANGE;
     935        }
     936        int padlen = min;
     937        if (range > 0)
     938            padlen += _context.random().nextInt(1 + range);
     939        if (_log.shouldWarn())
     940            _log.warn("Padding params:" +
     941                      " data size: " + dataSize +
     942                      " avail: " + availForPad +
     943                      " minSend: " + minSend +
     944                      " maxSend: " + maxSend +
     945                      " min: " + min +
     946                      " max: " + max +
     947                      " range: " + range +
     948                      " padlen: " + padlen);
     949        return padlen;
     950    }
     951
     952    /**
     953     *  NTCP2 only
     954     *
     955     *  @since 0.9.36
     956     */
    942957    private void sendOurRouterInfo(boolean shouldFlood) {
    943         sendRouterInfo(_context.router().getRouterInfo(), shouldFlood);
     958        RouterInfo ri = _context.router().getRouterInfo();
     959        if (ri == null)
     960            return;
     961        sendRouterInfo(ri, shouldFlood);
    944962    }
    945963
     
    954972            _log.warn("Sending router info for: " + ri.getHash() + " flood? " + shouldFlood);
    955973        List<Block> blocks = new ArrayList<Block>(2);
    956         int plen = 2;
    957974        Block block = new NTCP2Payload.RIBlock(ri, shouldFlood);
    958         plen += block.getTotalLength();
     975        int size = block.getTotalLength();
     976        if (size > BUFFER_SIZE) {
     977            if (_log.shouldWarn())
     978                _log.warn("RI too big: " + ri);
     979            return;
     980        }
    959981        blocks.add(block);
    960         int padlen = 1 + _context.random().nextInt(PADDING_MAX);
    961         // all zeros is fine here
    962         //block = new NTCP2Payload.PaddingBlock(_context, padlen);
    963         block = new NTCP2Payload.PaddingBlock(padlen);
    964         plen += block.getTotalLength();
    965         blocks.add(block);
    966         byte[] tmp = new byte[plen];
    967         sendNTCP2(tmp, blocks);
     982        int availForPad = BUFFER_SIZE - (size + NTCP2Payload.BLOCK_HEADER_SIZE);
     983        if (availForPad > 0) {
     984            int padlen = getPaddingSize(size, availForPad);
     985            // all zeros is fine here
     986            //block = new NTCP2Payload.PaddingBlock(_context, padlen);
     987            block = new NTCP2Payload.PaddingBlock(padlen);
     988            size += block.getTotalLength();
     989            blocks.add(block);
     990        }
     991        // use a "read buf" for the temp array
     992        ByteArray dataBuf = acquireReadBuf();
     993        sendNTCP2(dataBuf.getData(), blocks);
     994        releaseReadBuf(dataBuf);
    968995    }
    969996
     
    9791006            _log.warn("Sending termination, reason: " + reason + ", vaild frames rcvd: " + validFramesRcvd);
    9801007        List<Block> blocks = new ArrayList<Block>(2);
    981         int plen = 2;
    9821008        Block block = new NTCP2Payload.TerminationBlock(reason, validFramesRcvd);
    983         plen += block.getTotalLength();
     1009        int plen = block.getTotalLength();
    9841010        blocks.add(block);
    985         int padlen = 1 + _context.random().nextInt(PADDING_MAX);
    986         // all zeros is fine here
    987         //block = new NTCP2Payload.PaddingBlock(_context, padlen);
    988         block = new NTCP2Payload.PaddingBlock(padlen);
    989         plen += block.getTotalLength();
    990         blocks.add(block);
    991         byte[] tmp = new byte[plen];
    992         sendNTCP2(tmp, blocks);
     1011        int padlen = getPaddingSize(plen, PADDING_MAX);
     1012        if (padlen > 0) {
     1013            // all zeros is fine here
     1014            //block = new NTCP2Payload.PaddingBlock(_context, padlen);
     1015            block = new NTCP2Payload.PaddingBlock(padlen);
     1016            plen += block.getTotalLength();
     1017            blocks.add(block);
     1018        }
     1019        // use a "read buf" for the temp array
     1020        ByteArray dataBuf = acquireReadBuf();
     1021        sendNTCP2(dataBuf.getData(), blocks);
     1022        releaseReadBuf(dataBuf);
    9931023    }
    9941024
     
    9991029     *
    10001030     *  @param tmp to be used for output of NTCP2Payload.writePayload(),
    1001      *         must have room for 2 byte length and block output
     1031     *         must have room for block output. May be released immediately on return.
    10021032     *  @since 0.9.36
    10031033     */
    10041034    private synchronized void sendNTCP2(byte[] tmp, List<Block> blocks) {
     1035        if (_sender == null) {
     1036            if (_log.shouldWarn())
     1037                _log.warn("sender gone", new Exception());
     1038            return;
     1039        }
    10051040        int payloadlen = NTCP2Payload.writePayload(tmp, 0, blocks);
    10061041        int framelen = payloadlen + OutboundNTCP2State.MAC_SIZE;
     
    20402075            _lastReceiveTime = _context.clock().now();
    20412076            _messagesRead.incrementAndGet();
    2042             // TEST send back. null RI for target, not necesary
    2043             //if (_context.getBooleanProperty("i2np.ntcp2.loopback"))
    2044             //  send(new OutNetMessage(_context, msg, _context.clock().now() + 10*1000, OutNetMessage.PRIORITY_MY_DATA, null));
    20452077        }
    20462078
Note: See TracChangeset for help on using the changeset viewer.