RFC791, MTU and a minimum packet size - networking

I was reading rfc791 and trying to understand the relations with MTU as well as with the minimum packet size for IPv4. Here are two quotes from the rfc:
"All hosts must be prepared to accept datagrams of up to 576 octets (whether they arrive whole or in fragments)."
And
"Every internet module must be able to forward a datagram of 68 octets without further fragmentation. This is because an internet header may be up to 60 octets, and the minimum fragment is 8 octets."
Do I understand correctly that first related only to hosts, i.e. only hosts must be able to process minimum packet size of 576 bytes, while the second statement defines the mi packet size for a router? But of so, then it is possible to have a router not being able to receive a packet of 68 bytes for himself ?
Or I'm missing something very fundamental?
Thanks.
Mark

The 576 octet is a "least maximum". In other words, a host needs to be prepared to have a maximum packet size of no less than 576 octets. It can be bigger than that, such as the 1518 limit used by most (non-jumbo) Ethernet devices, but not any smaller.
Anything that is set up to forward packets must not split them into chunks of less than 68 octets.

By standard, 576 Bytes is "minimum MTU" supported over IP infrastructure. This means, any host/router must support this value and any IP packets can be smaller than 576 Bytes (atleast 68 Bytes) which can move IP world without fragmentation.
HTH

The first relates to accepting; the second relates to forwarding.
then it is possible to have a router not being able to receive a packet of 68 bytes for himself
That doesn't make any sense. A host must be able to accept datagrams of up to 576 octets.

Related

xmpp: size of stanzas versus bandwidth

I am trying to estimate bandwidth usage of a XMPP application.
The application is receiving a 150-bytes ping each second, and answering with a ping of the same size.(*)
However, when I measure the data usage, I get something like 900 bytes per ping (and not the 300 expected)
I have a suspicion this might relate to something layer bellow (TCP? IP?) and datagram sizes. But, so far, reading the TCP/IP guide did not lead me anywhere.
Another hypothesis would be that this overhead comes from XMPP itself, somehow.
Can anyone enlighten me ?
(*) to get this "150 bytes" I counted the number of chars in the <iq> (the xml representation of the ping)
I am using TLS, but not BOSH (actually, BOSH on the other connection: I am measuring results in the android client, and the pings are coming from a web application, but I think that should not matter)
The client is Xabber, running on android
Lets try to calculate the worst-case overhead down to the IP level.
For TLS we have:
With TLS 1.1 and up, in CBC mode: an IV of 16 bytes.
Again, in CBC mode: TLS padding. TLS uses blocks of 16 bytes, so it may need to add 15 bytes of padding.
(Technically TLS allows for up to 255 bytes of padding, but in practice I think that's rare.)
With SHA-384: A MAC of 48 bytes.
TLS header of 5 bytes.
That's 84 extra bytes.
TCP and IP headers are 40 bytes (from this answer) if no extra options are used, but for IPv6 this would be 60 bytes.
So you could be seeing 84 + 60 + 150 = 294 bytes per ping.
However, on the TCP level we also need ACKs. If you are pinging a different client (especially over BOSH), then the pong will likely be too late to piggyback the TCP ACK for the ping. So the server must send a 60 byte ACK for the ping and the client also needs to send a 60 byte ACK for the pong.
That brings us to:
294 + 60 + 294 + 60 = 708
900 still sounds a lot too large. Are you sure the ping and the pong are both 150 bytes?

Send packets larger than 64K in TCP

As far as we know the absolute limitation on TCP packet size is 64K (65535 bytes), and in practicality this is far larger than the size of any packet you will see, because the lower layers (e.g. ethernet) have lower packet sizes. The MTU (Maximum Transmission Unit) for Ethernet, for instance, is 1500 bytes.
I want to know, Is there any any way or any tools, to send packets larger than 64k?
I want to test a device in facing with packet larger than 64k! I mean I want to see, if I send a packet larger than 64K, how it behave? Does it drop some part of it? Or something else.
So :
1- How to send this large packets? What is the proper layer for this?
2- How the receiver behave usually?
The IP packet format has only 16 bit for the size of the packet, so you will not be able to create a packet with a size larger than 64k. See http://en.wikipedia.org/wiki/IPv4#Total_Length. Since TCP uses IP as the lower layer this limit applies here too.
There is no such thing as a TCP packet. TCP data is sent and received in segments, which can be as large as you like up to the limits of the API you're using, as they can be comprised of multiple IP packets. At the receiver TCP is indistinguishable from a byte stream.
NB osi has nothing to do with this, or anything else.
TCP segments are not size-limited. The thing which imposes the limit is that IPv4 and IPv6 packets have 16 bit length fields, so a size larger than this limit is not possible to express.
However, RFC 2675 is a proposed standards for IPv6 which would expand the length field to 32 bits, allowing much larger TCP segments.
See here for a talk about why this change could help improve performance and here for a set of (experimental) patches to Linux to enable this RFC.

IP fragmentation

I've encountered the following statement somewhere in the net: "Although
theoretically only 8 bytes of L4 info may be guaranteed in a fragment,
assume complete L4 info is available...". I don't understand how possible
that only 8 bytes of a transport are guaranteed in a fragment, as the IP
fragment can't be less than 46 bytes (minimum payload size for Ethernet
frame), and this includes 20 bytes of IP header and 20bytes of TCP header
(not considering variable-lngth options), UDP will be less.
Thus for the first IP fragment we always can expect IP header at tcp header,
while other fragments will carry only IP header + payload.
I believe I'm missing something, but I still can't understand why only 8
bytes can be guaranteed in a fragment? I would appreaciate if someone helps
to clarify this issue. Thanks !
Mark
Imagine a router receives a TCP packet containing one more byte of data than will fit in the MTU of the destination network. It must split on an 8-byte boundary because that's an IP fragmentation rule.
It won't split into more than two fragments because that would be silly. So it must include at least one byte of data in the first fragment..
Thus the minimum number of data bytes you can place in the first fragment of an IP datagram is 8.

Why are TCP messages in my PC coming in frames of 590 bytes

I am analyzing wireshark log files, when I make a request to a web page using firefox through a proxy server.
Following are details of connection establishment:
I have noted "maximum segment size" when I open options branch in the TCP segment details of the [SYN] message from my PC to the proxy server - it says 1460 bytes
Similarly, maximum segment size eof the [SYN,ACK] message from the proxy server to my PC - it says 1460 bytes
After establishing the TCP connection, should not each of the TCP frames sent from proxy server to my PC be of 1460 bytes? I am puzzled that why are they 590 bytes. Please advice how the 590 size is being set
A plausible explanation is that 590 turns out to be the Path MTU for the particular connection.
In other words whereby the client (one of the end nodes of the connection)accepts packets of a maximum of of 1460 bytes payload, some node(s) on the way accepts smaller packets. For efficiency purposes, the Path MTU Discovery allows the originator of a packet to size it so that it would fit the smaller MTU encountered on the path, and hence avoid fragmentation.
BTW:
1460 is a very common MTU (well MSS), because it it corresponds to 1500, Ethernet v2's maximum, minus 20+20= 40 bytes for the IP header overhead)
See the following Wikipedia entry for an overview of MTU (Maximum Transmission Unit) and a basic description of the Path MTU Discovery method (Basically setting the the DF i.e. do-not-fragment flag and relying on the ICMP ""Destination Unreachable (Datagram Too Big)" messages to detect that some node on the way couldn't handle the packet, and hence try with smaller size until it goes through).
Also, I suggest inspecting the packets when the connection is to a different host, maybe a peer on the very same network segment, without going through the proxy mentioned. Chances are you will then start seeing 1460 bytes frames.

Maximum packet size for a TCP connection

What is the maximum packet size for a TCP connection or how can I get the maximum packet size?
The absolute limitation on TCP packet size is 64K (65535 bytes), but in practicality this is far larger than the size of any packet you will see, because the lower layers (e.g. ethernet) have lower packet sizes.
The MTU (Maximum Transmission Unit) for Ethernet, for instance, is 1500 bytes. Some types of networks (like Token Ring) have larger MTUs, and some types have smaller MTUs, but the values are fixed for each physical technology.
This is an excellent question and I run in to this a lot at work actually. There are a lot of "technically correct" answers such as 65k and 1500. I've done a lot of work writing network interfaces and using 65k is silly, and 1500 can also get you in to big trouble. My work goes on a lot of different hardware / platforms / routers, and to be honest the place I start is 1400 bytes. If you NEED more than 1400 you can start to inch your way up, you can probably go to 1450 and sometimes to 1480'ish? If you need more than that then of course you need to split in to 2 packets, of which there are several obvious ways of doing..
The problem is that you're talking about creating a data packet and writing it out via TCP, but of course there's header data tacked on and so forth, so you have "baggage" that puts you to 1500 or beyond.. and also a lot of hardware has lower limits.
If you "push it" you can get some really weird things going on. Truncated data, obviously, or dropped data I've seen rarely. Corrupted data also rarely but certainly does happen.
At the application level, the application uses TCP as a stream oriented protocol. TCP in turn has segments and abstracts away the details of working with unreliable IP packets.
TCP deals with segments instead of packets. Each TCP segment has a sequence number which is contained inside a TCP header.
The actual data sent in a TCP segment is variable.
There is a value for getsockopt that is supported on some OS that you can use called TCP_MAXSEG which retrieves the maximum TCP segment size (MSS). It is not supported on all OS though.
I'm not sure exactly what you're trying to do but if you want to reduce the buffer size that's used you could also look into: SO_SNDBUF and SO_RCVBUF.
There're no packets in TCP API.
There're packets in underlying protocols often, like when TCP is done over IP, which you have no interest in, because they have nothing to do with the user except for very delicate performance optimizations which you are probably not interested in (according to the question's formulation).
If you ask what is a maximum number of bytes you can send() in one API call, then this is implementation and settings dependent. You would usually call send() for chunks of up to several kilobytes, and be always ready for the system to refuse to accept it totally or partially, in which case you will have to manually manage splitting into smaller chunks to feed your data into the TCP send() API.
According to http://en.wikipedia.org/wiki/Maximum_segment_size, the default largest size for a IPV4 packet on a network is 536 octets (bytes of size 8 bits). See RFC 879
Generally, this will be dependent on the interface the connection is using. You can probably use an ioctl() to get the MTU, and if it is ethernet, you can usually get the maximum packet size by subtracting the size of the hardware header from that, which is 14 for ethernet with no VLAN.
This is only the case if the MTU is at least that large across the network. TCP may use path MTU discovery to reduce your effective MTU.
The question is, why do you care?
If you are with Linux machines, "ifconfig eth0 mtu 9000 up" is the command to set the MTU for an interface. However, I have to say, big MTU has some downsides if the network transmission is not so stable, and it may use more kernel space memories.
One solution can be to set socket option TCP_MAXSEG (http://linux.die.net/man/7/tcp) to a value that is "safe" with underlying network (e.g. set to 1400 to be safe on ethernet) and then use a large buffer in send system call.
This way there can be less system calls which are expensive.
Kernel will split the data to match MSS.
This way you can avoid truncated data and your application doesn't have to worry about small buffers.
It seems most web sites out on the internet use 1460 bytes for the value of MTU. Sometimes it's 1452 and if you are on a VPN it will drop even more for the IPSec headers.
The default window size varies quite a bit up to a max of 65535 bytes. I use http://tcpcheck.com to look at my own source IP values and to check what other Internet vendors are using.
The packet size for a TCP setting in IP protocol(Ip4). For this field(TL), 16 bits are allocated, accordingly the max size of packet is 65535 bytes: IP protocol details

Resources