TCP MSS over WiFi - tcp

The MTU for 802.11 is 2296 bytes. Does this mean that if TCP is used over 802.11, the MSS can only be 2296 - 40 = 2256? Can't one use a higher MSS which would then get fragmented over 802.11?
In short, is there a strict limit on the MSS for TCP?

The MTU for 802.11 is 2296 bytes.
Are you sure about that number? This answer says it's 2304.
Does this mean that if TCP is used over 802.11, the MSS can only be
2296 - 40 = 2256?
Assuming that the MTU is 2296, that's correct. You lose at least 20 bytes for an IPv4 header, and 20 more bytes (at least) on a TCP header.
Can't one use a higher MSS which would then get fragmented over
802.11?
Why would you want that? TCP implementations actively try to avoid IP fragmentation using MTU discovery. If a TCP segment is fragmented, and one of the fragments is lost or corrupted, the entire segment would have to be resent since TCP has no concept of IP fragmentation and as far as it is concerned, the whole segment was lost. In general, this is much more wasteful than sending smaller segments that wouldn't be fragmented. This is especially true in wireless networks where frames tend to become corrupt quite often.

Related

What happens if fragmented IP datagram gets dropped (i.e. one fragment out of many)?

I am a student just beginning to dive into the network stack, so please forgive any misconceptions.
If you are using TCP as a transport layer protocol, and sending payloads that happen to be greater than the MTU lower down in the stack, the Network Layer protocol (IPv4 for example) will fragment the payload into separate IP datagrams. What happens if a single one of these "fragmented" IP datagrams is dropped?
Example
Sending 4000 byte datagram with MTU of 1500 bytes
[MF: 1 Offset: 0 Length: 1500]
[MF: 1 Offset: 185 Length: 1500] <--------- Dropped/Lost
[MF: 0 Offset: 370 Length: 1040]
Which would happen?
Only IP datagram #2 get re-transmitted
The entire 4000 byte datagram be fragmented again and entirely re-transmitted after TCP determines the datagram was lost
I was originally thinking that the individual fragment would be re-transmitted, however given that this is below the reliability ensured by TCP in the transport layer, I am now thinking that the entire TCP datagram is just dropped/re-transmitted (which seems inefficient).
As a follow up, is there any reason that this "fragmentation" occurs below the transport layer (specifically below TCP)? I feel like this could be handled most of the time by ensuring that packets are broken up into a generally acceptable MTU size above/at the transport layer. Upon some research I found some information on how TCP should have nothing to do with packetizing things, which I did not quite understand.
The entire 4000 byte datagram be fragmented again and entirely re-transmitted after TCP determines the datagram was lost. Although TCP should break it up into MTU fit-able chunks (aka segments) in the first place.

TCP ACK of packets in wireshark

I've noticed in wireshark that I'm able to send 4096 bytes of data to a HTTP webserver (from uploading a file) however the server only seems to be acknowledging data 1460 bytes at a time. Why is this the case?
The size of TCP segments is restricted to the MSS (Maximum Segment Size), which is basically the MTU (Maximum Transmission Unit) less the bytes comprising the IP and TCP overhead. On a typical Ethernet link, the MTU is 1500 bytes and basic IP and TCP headers comprise 20 bytes each, so the MSS is 1460 (1500 - 20 - 20).
If you're seeing packets indicated with a length field of 4096 bytes, then it almost certainly means that you're capturing on the transmitting host and Wireshark is being handed the large packet before it's segmented into 1460 byte chunks. If you were to capture at the receiving side, you would see the individual 1460 byte segments arriving and not a single, large 4096 byte packet.
For further reading, I would encourage you to read Jasper Bongertz's blog titled, "The drawbacks of local packet captures".
TCP by default uses path MTU discovery:
When system send packet to the network it set don't fragment flag (DF) in IP header
When IP router or you local machine see DF packet that should be fragmented to match MTU of the next hop link it sends feedback (RTCP fragmentation need) that contains new MTU
When system receives fragmentation needed ICMP it adjusts MSS and send data again.
This procedure is performed to reduce overall load on the network and increase probability of each packet delivery.
This is why you see 1460 packets.
Regarding to you question: the server only seems to be acknowledging data 1460 bytes at a time. Why is this the case?
TCP keep track window that defines "how many bytes of data you can send without acknowledge". Its purpose is to provide flow control mechanisms (sender can't send too much data that can't be processed) and congestion control mechanisms (sender can't send too much data to overload network). Window is defined by receiver side and may be increased during connection when TCP will estimate real channel bandwidth. So you may see one ACK that acknowledges several packets.

How does MTU retransmission work in case of UDP

As we all perfectly know, UDP does not support retransmission along with some other things.
We also aware of such thing like MTU that works basically in the following way -- when one of the network devices on the path between source and destination points does not support packet of some size, it just drops it.
In case of TCP, it's not a problem -- it already knows MSS after handshake that is always less than MTU (am I right?), so there's no possibility to send a packet with the size greater than MTU.
However, I wonder how does it work in case of UDP? As I already said, there's no retransmission in this protocol and there's no such thing like MSS. So what happens when the packet is dropped due to exceeding MTU?
Or it just works because of the MTU nature (it actually belongs to the IP layer, not the transport layer protocols like UDP or TCP)? So the IP layer reconstruct the dropped packet in smaller units and send it again?
First of all, you must distinguish between the local MTU, which is just the MTU of the local link, and the path MTU (PMTU), which is the smallest MTU of the local link. Consider the following topology:
1500 1480 1500
A -------- B -------- C -------- D
then A's local MTU is 1500, but the PMTU is just 1480.
When router B receives a packet of size 1500 which it needs to forward, and the DF bit is set, it sends an ICMP packet back to the sender with the next hop's MTU, 1480 in this case. The sender can then reduce the packet size.
In TCP, this is done transparently by the network stack. In UDP, the application needs to deal with it. There are three ways to do that:
always send packets that are small enough; 1024 is always safe over IPv6, and 512 is usually (but not always) safe over IPv4;
use a connected UDP socket, and react to an EMSGSIZE error by reducing the packet size; or
use any kind of UDP socket, request the PMTU ancillary data, and use the data provided.
Technique (3) is the most efficient. For IPv6, it is described in Section 11.3 of RFC 3542.

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.

Is MSS value fixed in SYN packet?

I wonder how MSS is set in SYN packet? Is it a fixed value in one operating system or the value could be changed in the same operating system? I know that the value is different in different operating systems. Also is the MSS value in SYN related to hardware configuration?
Thanks.
RFC 879 describes how MSS is used and specified.
In short, MSS is specified during TCP handshake via SYN packet. However, this value can later be changed by OS itself or by setting a protocol option.
You can set option TCP_MAXSEG via setsockopt.
Whilst the value of MSS in SYN and SYNACK packets are set by the initiator and responder side, respectively, a widely used practice known as MSS clamping can result in the MSS being altered by a network element on the path - this is often used to reduce the MSS of all connections going over some sort of tunnelled link. For example PPPoE is commonly used on residential broadband and requires an MTU of 1492 and corresponding IPv4 MSS of 1452 so whilst the SYN may leave your machine with an MSS of 1460 (assuming you're using Ethernet with an MTU of 1500) but once it passes the MSS clamping ISP router the MSS in SYN packet will subsequently be changed to 1452, and likewise for the incoming/responder's SYNACK packet so the connection proceeds with reduced MSS of 1452. This practice seems to be used instead of Path MTU Discovery which relies upon the use of ICMP Fragmentation Needed responses from the network as these can be lost on poorly configured networks and by certain load balancing techniques.

Resources