forked from I2P_Developers/i2p.i2p
SSU2: Fix overhead calculations
This commit is contained in:
@@ -58,14 +58,14 @@ class PacketBuilder2 {
|
||||
static final int TYPE_CREAT = 73;
|
||||
|
||||
/** IPv4 only */
|
||||
public static final int IP_HEADER_SIZE = 20;
|
||||
public static final int IP_HEADER_SIZE = PacketBuilder.IP_HEADER_SIZE;
|
||||
/** Same for IPv4 and IPv6 */
|
||||
public static final int UDP_HEADER_SIZE = 8;
|
||||
public static final int UDP_HEADER_SIZE = PacketBuilder.UDP_HEADER_SIZE;
|
||||
|
||||
/** 74 */
|
||||
public static final int MIN_DATA_PACKET_OVERHEAD = IP_HEADER_SIZE + UDP_HEADER_SIZE + DATA_HEADER_SIZE + MAC_LEN;
|
||||
|
||||
public static final int IPV6_HEADER_SIZE = 40;
|
||||
public static final int IPV6_HEADER_SIZE = PacketBuilder.IPV6_HEADER_SIZE;
|
||||
/** 94 */
|
||||
public static final int MIN_IPV6_DATA_PACKET_OVERHEAD = IPV6_HEADER_SIZE + UDP_HEADER_SIZE + DATA_HEADER_SIZE + MAC_LEN;
|
||||
|
||||
@@ -135,7 +135,7 @@ class PacketBuilder2 {
|
||||
// calculate data size
|
||||
int numFragments = fragments.size();
|
||||
int dataSize = 0;
|
||||
int priority = 0;
|
||||
int priority = PRIORITY_LOW;
|
||||
for (int i = 0; i < numFragments; i++) {
|
||||
Fragment frag = fragments.get(i);
|
||||
OutboundMessageState state = frag.state;
|
||||
@@ -176,7 +176,7 @@ class PacketBuilder2 {
|
||||
|
||||
// add the acks
|
||||
if (availableForAcks >= SSU2Payload.BLOCK_HEADER_SIZE + 5) {
|
||||
int maxRanges = (availableForAcks - (SSU2Payload.BLOCK_HEADER_SIZE + 5)) / 2;
|
||||
int maxRanges = Math.min((availableForAcks - (SSU2Payload.BLOCK_HEADER_SIZE + 5)) / 2, ABSOLUTE_MAX_ACK_RANGES);
|
||||
Block block = peer.getReceivedMessages().toAckBlock(maxRanges);
|
||||
if (block != null) {
|
||||
blocks.add(block);
|
||||
@@ -255,7 +255,7 @@ class PacketBuilder2 {
|
||||
pkt.setLength(off);
|
||||
encryptDataPacket(packet, peer.getSendCipher(), pktNum, peer.getSendHeaderEncryptKey1(), peer.getSendHeaderEncryptKey2());
|
||||
setTo(packet, peer.getRemoteIPAddress(), peer.getRemotePort());
|
||||
packet.setPriority(0);
|
||||
packet.setPriority(PRIORITY_LOW);
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ public class PeerState {
|
||||
*/
|
||||
private volatile int _slowStartThreshold;
|
||||
/** what IP is the peer sending and receiving packets on? */
|
||||
private final byte[] _remoteIP;
|
||||
protected final byte[] _remoteIP;
|
||||
/** cached IP address */
|
||||
private volatile InetAddress _remoteIPAddress;
|
||||
/** what port is the peer sending and receiving packets on? */
|
||||
@@ -160,7 +160,7 @@ public class PeerState {
|
||||
*/
|
||||
private long _theyRelayToUsAs;
|
||||
/** what is the largest packet we can currently send to the peer? */
|
||||
private int _mtu;
|
||||
protected int _mtu;
|
||||
private int _mtuReceive;
|
||||
/** what is the largest packet we will ever send to the peer? */
|
||||
private int _largeMTU;
|
||||
@@ -394,8 +394,6 @@ public class PeerState {
|
||||
_keyEstablishedTime = now;
|
||||
_lastSendTime = now;
|
||||
_lastReceiveTime = now;
|
||||
_currentACKs = new ConcurrentHashSet<Long>();
|
||||
_currentACKsResend = new LinkedBlockingQueue<ResendACK>();
|
||||
_slowStartThreshold = MAX_SEND_WINDOW_BYTES/2;
|
||||
_receivePeriodBegin = now;
|
||||
_remoteIP = addr.getAddress().getAddress();
|
||||
@@ -428,11 +426,14 @@ public class PeerState {
|
||||
_inboundMessages = new HashMap<Long, InboundMessageState>(8);
|
||||
_outboundMessages = new CachedIteratorCollection<OutboundMessageState>();
|
||||
_outboundQueue = new PriBlockingQueue<OutboundMessageState>(ctx, "UDP-PeerState", 32);
|
||||
_ackedMessages = new AckedMessages();
|
||||
_remotePeer = remotePeer;
|
||||
_isInbound = isInbound;
|
||||
_remoteHostId = new RemoteHostId(_remoteIP, _remotePort);
|
||||
_bwEstimator = new SimpleBandwidthEstimator(ctx, this);
|
||||
// Unused in SSU2
|
||||
_currentACKs = null;
|
||||
_currentACKsResend = null;
|
||||
_ackedMessages = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.i2p.router.transport.udp;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.southernstorm.noise.protocol.CipherState;
|
||||
@@ -66,8 +67,59 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
_sentMessages = new SSU2Bitfield(256, 0);
|
||||
}
|
||||
|
||||
// SSU 1 overrides
|
||||
|
||||
@Override
|
||||
public int getVersion() { return 2; }
|
||||
|
||||
/**
|
||||
* how much payload data can we shove in there?
|
||||
* Does NOT leave any room for acks, we'll fit them in when we can.
|
||||
* This is 5 bytes too low for first or only fragment.
|
||||
*
|
||||
* @return MTU - 68 (IPv4), MTU - 88 (IPv6)
|
||||
*/
|
||||
@Override
|
||||
int fragmentSize() {
|
||||
// 20 + 8 + 16 + 3 + 5 + 16 = 68 (IPv4)
|
||||
// 40 + 8 + 16 + 3 + 5 + 16 = 88 (IPv6)
|
||||
return _mtu -
|
||||
(_remoteIP.length == 4 ? PacketBuilder2.MIN_DATA_PACKET_OVERHEAD : PacketBuilder2.MIN_IPV6_DATA_PACKET_OVERHEAD) -
|
||||
DATA_FOLLOWON_EXTRA_SIZE; // Followon fragment block overhead (5)
|
||||
}
|
||||
|
||||
/**
|
||||
* Packet overhead
|
||||
* Does NOT leave any room for acks, we'll fit them in when we can.
|
||||
* This is 5 bytes too high for first or only fragment.
|
||||
*
|
||||
* @return 68 (IPv4), 88 (IPv6)
|
||||
*/
|
||||
@Override
|
||||
int fragmentOverhead() {
|
||||
// 20 + 8 + 16 + 3 + 5 + 16 = 68 (IPv4)
|
||||
// 40 + 8 + 16 + 3 + 5 + 16 = 88 (IPv6)
|
||||
return (_remoteIP.length == 4 ? PacketBuilder2.MIN_DATA_PACKET_OVERHEAD : PacketBuilder2.MIN_IPV6_DATA_PACKET_OVERHEAD) +
|
||||
DATA_FOLLOWON_EXTRA_SIZE; // Followon fragment block overhead (5)
|
||||
}
|
||||
|
||||
// SSU 1 unsupported things
|
||||
|
||||
@Override
|
||||
void setCurrentMACKey(SessionKey key) { throw new UnsupportedOperationException(); }
|
||||
@Override
|
||||
void setCurrentCipherKey(SessionKey key) { throw new UnsupportedOperationException(); }
|
||||
@Override
|
||||
List<Long> getCurrentFullACKs() { throw new UnsupportedOperationException(); }
|
||||
@Override
|
||||
List<Long> getCurrentResendACKs() { throw new UnsupportedOperationException(); }
|
||||
@Override
|
||||
void removeACKMessage(Long messageId) { throw new UnsupportedOperationException(); }
|
||||
@Override
|
||||
void fetchPartialACKs(List<ACKBitfield> rv) { throw new UnsupportedOperationException(); }
|
||||
|
||||
// SSU 2 things
|
||||
|
||||
long getNextPacketNumber() { return _packetNumber.incrementAndGet(); }
|
||||
long getSendConnID() { return _sendConnID; }
|
||||
long getRcvConnID() { return _rcvConnID; }
|
||||
|
||||
@@ -55,17 +55,22 @@ final class SSU2Util {
|
||||
public static final int MIN_HANDSHAKE_DATA_LEN = SESSION_HEADER_SIZE + TOTAL_PROT_SAMPLE_LEN;
|
||||
|
||||
|
||||
/** 3 byte block header + 9 byte I2NP header = 12 */
|
||||
public static final int FULL_I2NP_HEADER_SIZE = SSU2Payload.BLOCK_HEADER_SIZE + 9;
|
||||
/** 3 byte block header */
|
||||
public static final int FULL_I2NP_HEADER_SIZE = SSU2Payload.BLOCK_HEADER_SIZE;
|
||||
|
||||
/** 3 byte block header + 9 byte I2NP header = 12 */
|
||||
public static final int FIRST_FRAGMENT_HEADER_SIZE = SSU2Payload.BLOCK_HEADER_SIZE + 9;
|
||||
/** 3 byte block header */
|
||||
public static final int FIRST_FRAGMENT_HEADER_SIZE = SSU2Payload.BLOCK_HEADER_SIZE;
|
||||
|
||||
/**
|
||||
* 5 for flag and msg number in followon block
|
||||
*/
|
||||
public static final int DATA_FOLLOWON_EXTRA_SIZE = 5;
|
||||
|
||||
/** 3 byte block header + 4 byte msg ID + 1 byte fragment info = 8 */
|
||||
public static final int FOLLOWON_FRAGMENT_HEADER_SIZE = SSU2Payload.BLOCK_HEADER_SIZE + 5;
|
||||
public static final int FOLLOWON_FRAGMENT_HEADER_SIZE = SSU2Payload.BLOCK_HEADER_SIZE + DATA_FOLLOWON_EXTRA_SIZE;
|
||||
|
||||
/** 16 byte block header + 2 + 12 = 30 */
|
||||
public static final int DATA_HEADER_SIZE = SHORT_HEADER_SIZE + 2 + FULL_I2NP_HEADER_SIZE;
|
||||
/** 16 byte short header + 3 = 19 */
|
||||
public static final int DATA_HEADER_SIZE = SHORT_HEADER_SIZE + FULL_I2NP_HEADER_SIZE;
|
||||
|
||||
/**
|
||||
* The message types, 0-10, as bytes
|
||||
|
||||
Reference in New Issue
Block a user