Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set "don't fragment" flag bit for TCP packet in Go?

Tags:

tcp

go

sockets

I intend to set the "don't fragment" flag bit in Go, the same thing as this post while it is in C. I checked the constant list but I didn't find this option. So what is the corresponding option in Go?

Thanks in advance!

like image 798
zzy Avatar asked Jun 11 '16 08:06

zzy


1 Answers

How to set "don't fragment" flag bit for TCP packet in Go?

First up you should know that TCP really doesn't like IP fragments. Most if not all major implementations avoid fragmentation for TCP segments by using path MTU discovery.

The TL;DR is that the typical IP packet containing a TCP segment has a DF bit set. You can (and should) try this out. Here I am sniffing a few seconds of traffic between my machine and stackoverflow.com:

% tshark -w /tmp/tcp.pcap tcp and host stackoverflow.com
<wait a few seconds>
% tshark -r /tmp/tcp.pcap -T fields -e ip.flags | sort | uniq -c
    186 0x00000002

0x02 means the DF bit is set. I confess in other captures I have seen the occasional TCP segment in an IP packet without a DF bit; I suspect rfc1191 has an explanation for this.


Now back to your question, I think there's no portable way to set the DF bit and this is a more widespread question (there isn't even a POSIX-portable way). There is (likely) an escape hatch in the relevant package for your implementation under golang.org/x/sys.

For example, on a Unix that supports IP_DONTFRAG such as FreeBSD one could use unix.SetsockoptInt and dig the relevant constant value.

On Linux there is not IP_DONTFRAG, as you discovered from the question you linked. The workaround seems to be to use IP_MTU_DISCOVER which happens to be available as a constant in the unix package. You can use that same unix.SetsockoptInt to set it.

like image 191
cnicutar Avatar answered Sep 29 '22 09:09

cnicutar