https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=144000 Now, TCP_MAXSEG needs to be called after connect to succeed, but this can only affect the local socket, not the remote MSS, because the MSS is already negotiated at connect, and by tcpdump catch the packet, the MSS value is not negotiate after TCP_MAXSEG is set at the local socket by setsockopt.
The current man page of tcp says for the TCP_MAXSEG socket option: By default, a sender- and receiver-TCP will negotiate among themselves to determine the maximum segment size to be used for each connection. The TCP_MAXSEG option allows the user to determine the result of this negotiation, and to reduce it if desired. Are you saying that the socket option does not work as described above?
(In reply to Michael Tuexen from comment #2) Currently not working as expected.MSS cannot be set before connect.
Do you have an example of open source software using this feature that we can look at?
We discussed this at the transport call. This is not a bug, it is a feature request. However, we are not sure what the use case of this feature would be. So it would be good to answer comment #4.
My Code: int mss; socklen_t mss_size; mss_size = sizeof(mss); getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &mss, &mss_size); //mss <1460 setsockopt(fd2, IPPROTO_TCP, TCP_MAXSEG, &mss, mss_size); //need same mss for more ,you can search "TCP_MAXSEG site:github.com" in google. in rfc793 page 19, Section 3.1, "This field must only be sent in the initial connection request (i.e., in segments with the SYN control bit set)." https://datatracker.ietf.org/doc/html/rfc793#section-3.1 I think this is bug, not feature. https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=144000 is not true.
(In reply to zhh0000zhh from comment #6) But why do you need to synchronise two TCP sockets. TCP provides a byte stream service. So why do you bother what the MSS is? It is clear that the MSS option is only present in SYN and SYN ACK segments. But this has no relation to the question whether an application should have an way to impact the announcement of the MSS to the peer. The argument that this is no a bug is that the code behaves as documented in the man page. After connection setup, you can query what the MSS used by the local endpoint is in send direction. You can even reduce them. Linux also allows you set limit the MSS used by the peer. FreeBSD doesn't allow this right now. So you are asking for this feature to be added. However, I don't understand why you need this feature. TCP is a byte stream protocol. So why do you want to limit the MSS used by your peer?
For high performance ipv6 to ipv4 forwarding, mss is required (TCP_NODELAY ON) and in rfc879 page 2, Section 3, "The MSS can be used completely independently in each direction of data flow. The result may be quite different maximum sizes in the two directions." https://datatracker.ietf.org/doc/html/rfc879#section-3
(In reply to zhh0000zhh from comment #8) Sure, the MSS can be different in each direction. Each node declares its maximum receive size. However, I do not understand * How the Nagle algorithm is involved in this discussion * Why an application cares about the MSS. TCP is a byte stream. At the API level you have no guarantee that the data you receive has any relation to the segmentation which was used by the peer. On the sending side, you don't have to care about the segmentation process.
Turning off the Nagle algorithm causes the system to not wait for buffers. And any socket forwarder should have low latency. This leads to a problem for ipv6 to ipv4 forwarding where When the forwarder accepts a message from ipv4 and forwards it to the ipv6 network, the actual data sent by ipv6 will be split into two packets because the MSS of ipv4 is larger than the MSS of ipv6 (e.g. an ipv4 packet has 1460 bytes payload, this packet will be split into a 1446 bytes packet and a 14 bytes packet in ipv6, with Nagle disabled, This problem can be verified using tcpdump) This leads to a performance problem, as the ipv4 network generates one packet, while the ipv6 network outputs two packets, which has a significant impact on both packet count (there is a direct correlation between packet count and performance) and effective bandwidth (excessive packet header loss leads to reduced bandwidth utilization) Inherently, the inability to set MSS does not lead to program errors, but in high performance and low latency demand scenarios can result in a significant waste of resources.
Has this problem been fixed? thanks
(In reply to Michael Tuexen from comment #5) Just adding a usage example: A popular way to sanity test network performance is the iperf tool. With this tool, the way to control the size of packets sent is with the -M parameter, which according to the documentation: -M, --mss n set TCP maximum segment size using TCP_MAXSEG For example, to get a quick look at pps, what one may like to do is to set the -M parameter to some small number and run the BW test. This gives a good feel for pps. There may be other ways to achieve this, but this is the popular quick and dirty one I know.