TCP ACK of packets in wireshark - http

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.

Related

How much data it cost to set up a TCP connection?

I am building an app where my phone frequently send data to my server. Since I would be using my mobile data, I was wondering how much data it cost to set up (and tear down?) a TCP connection to my server.
TCP Three-way handshake
Device 1 sends its TCP sequence number and maximum segment size to Device 2.
Device 2 responds by sending its sequence number and maximum segment size to Device 1.
Device 1 acknowledges receipt of the sequence number and segment size information.
Each packet is composed of an IP header and data (payload). In this case, the data section contains TCP. The TCP header contains various fields including the source and destination ports, sequence and acknowledgment numbers, window size, TCP flags, urgent pointer, and reserved bits.
Like the IP header, the TCP header may also contain options. (Note that TCP options and IP options are two different things.) Because the TCP options change the length of the TCP header, the length is set in the header.
IPv4 header is five 4-byte chunks, or 20 bytes total.
TCP typically usually uses 24 bytes of the header for handshake (first two packets) and about 20 for normal packet transmission.
Maximum Segment Size (MSS): 4 bytes
Window Scale (WSCALE): 3 bytes
Timestamp (TS): 10 bytes
No Operation (NOP): 1 byte
Selective Acknowledgment Permitted (SackOK): 2 bytes
Selective Acknowledgment Data: 10 bytes (plus 8 bytes for each additional pair of sequence numbers)
Terminating a Connection
Even though establishing a connection using 3-way handshake requires only 3 packets to be transmitted, tearing down one requires 4!
In the first frame the client sends a FIN that is accompanied by an ACK. The FIN parameter is set, it will inform the server that it has no more data to send.
The response (2nd frame) would be simply the server acknowledging the FIN sent from the client.
Even though TCP has established connections between the two computers, the connections are still independent of one another. Therefore, the server will also transmit a FIN to the client.
You guessed it right ... the client would ACK the FIN of the server in the last forth packet.
The offset of each of the frames is typically 20 bytes.
To sum it up.
Establishing a connection: ~ 128-136 bytes
Tearing down a connection: ~ 160 bytes
If you plan to use TLS / SSL handshake, this is estimated to be between 4.5k-6.5k.
Note: Please also take a look at TCP/IP Header Compression
Sources:
Inside the TCP Handshake
Explanation of the Three-Way Handshake via TCP/IP
Studying Normal Traffic, Part Three: TCP Headers | Symantec Connect

TCP file Transfer window size

I'm trying to reverse engineer an application, and i need help understanding how TCP window size works. My MTU is 1460
My application transfers a file using TCP from point A to B. I know the following:
The file is split into segments of size 8K
Each segment is compressed
Then each segment is sent to point B over TCP. These segment for a text file can be of size 148 Bytes, and for a pdf 6000 Bytes.
For a text file, am i supposed to see the segments of 148 attached to one another to form one large TCP stream? and then it is split according to the Window Size?
Any help is appreciated.
The receiver application should see the data in teh same way, the sender application sent it. TCP uses byte-streaming and so it collects all the bytes in an in-order manner and delivers it to the application. MTU is largely an internal semantics to TCP and does not take into application-layer packet boundaries. If TCP has enough data to send in its send buffer (each TCP socket has its own send buffer, btw), then it will package its next segment worth MTU size and sends it; to be more precise, it deducts TCP and IP header from the MTU size.

UDP Networking Fundamentals

I've been doing some work with C# Networking using UDP. I'm getting on fine but need the answer to a couple of fundamental questions I'm having problems testing:
Currently I'm sending data in a ~16000 byte datagrams, which according to wireshark is getting split into several 1500 byte packets (because of max packet size limits) and then reassembled at the other end.
Am I right in understanding the datagram will be received complete at the other end OR not at all. IE it's an all or nothing thing. There is no chance of ending up with a fragmented datagram due to packet loss?
Therefore, I only need to ACK per datagram, rather than ensuring my datagrams are < 1500 bytes and ACK each one?
I've looked in a lot of places but there seems to be a lot of confusion between the differences between datagrams and the underlying packets...
Thanks for you help!
There is no chance of ending up with a fragmented datagram due to packet loss?
I believe that's true: that fragmentation and fragment reassembly is handled by the protocol layer below UDP, i.e. that it's handled by the "IP" layer, which will error if it fails to reassemble the packet-fragments into a datagram (for example, search for "fragment" in RFC 792).
http://www.pcvr.nl/tcpip/udp_user.htm#11_5 says,
"The IP layer at the destination performs the reassembly. The goal is to make fragmentation and reassembly transparent to the transport layer (TCP and UDP), which it is, except for possible performance degradation."
As you may now 16 bit UDP length field indicates that you can send a total of 65535 bytes. However, the data can be theoretically (sizeof(IP Header) + sizeof(UDP Header)) = 65535-(20+8) = 65507 bytes.
But this does not mean that all applications that are using UDP will send this amount of data as an example DNS packets limits to 512 bytes. This is because you don't get any ACK packets from server. This is one reason that packets may get lost in the network (packet transmission problems and loss). Secondly intermediate nodes may encapsulate datagrams inside of another protocol, as an example IPSEC or other protocols do that.
For UDP there is no ACK packets, so in your case if underlying application uses UDP you should not see any ACK packets. Secondly, some of the server limit their sizes to the max UDP packets depending on the application, so if you have data transfer from client to server you should see same bytes e.g 512 bytes. going and coming back in wireshark. Mostly, source makes the request and destination sends X bytes UDP datagrams back.
These links may be good for your questions:
Wireshark UDP analysis
RFC 1122 (states that 576 is the minimum maximum reassembly buffer size)
Am I right in understanding the datagram will be received complete at the other end OR not at all. IE it's an all or nothing thing. There is no chance of ending up with a fragmented datagram due to packet loss?
That is correct.
Therefore, I only need to ACK per datagram, rather than ensuring my datagrams are < 1500 bytes and ACK each one?
I don't understand this question. You need to ACK each datagram regardless of its size, and you should make them < 1500 bytes so they won't get fragmented. Otherwise you may never be able to transmit any specific datagrams at all, if it repeatedly gets fragmented and a fragment repeatedly gets lost.

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 buffer length for sendto?

How do you get the maximum number of bytes that can be passed to a sendto(..) call for a socket opened as a UDP port?
Use getsockopt(). This site has a good breakdown of the usage and options you can retrieve.
In Windows, you can do:
int optlen = sizeof(int);
int optval;
getsockopt(socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (int *)&optval, &optlen);
For Linux, according to the UDP man page, the kernel will use MTU discovery (it will check what the maximum UDP packet size is between here and the destination, and pick that), or if MTU discovery is off, it'll set the maximum size to the interface MTU and fragment anything larger. If you're sending over Ethernet, the typical MTU is 1500 bytes.
On Mac OS X there are different values for sending (SO_SNDBUF) and receiving (SO_RCVBUF).
This is the size of the send buffer (man getsockopt):
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (int *)&optval, &optlen);
Trying to send a bigger message (on Leopard 9216 octets on UDP sent via the local loopback) will result in "Message too long / EMSGSIZE".
As UDP is not connection oriented there's no way to indicate that two packets belong together. As a result you're limited by the maximum size of a single IP packet (65535). The data you can send is somewhat less that that, because the IP packet size also includes the IP header (usually 20 bytes) and the UDP header (8 bytes).
Note that this IP packet can be fragmented to fit in smaller packets (eg. ~1500 bytes for ethernet).
I'm not aware of any OS restricting this further.
Bonus
SO_MAX_MSG_SIZE of UDP packet
IPv4: 65,507 bytes
IPv6: 65,527 bytes

Resources