Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Apr 2009 10:21:38 -0300
From:      "Luiz Otavio O Souza" <lists.br@gmail.com>
To:        "Julian Elischer" <julian@elischer.org>
Cc:        Lawrence Stewart <lstewart@freebsd.org>, freebsd-net@freebsd.org
Subject:   Re: Setting the mss for socket
Message-ID:  <3F89BC6021844DC58B956E5433650445@adnote989>
References:  <3FD46C21A487490FB15B89E890790121@adnote989>	<49d5c0de.E5bkeKr%2Bp%2Bfg4K00%perryh@pluto.rain.com> <64D5D9E633734200A603D067ED5A81E9@adnote989> <49D63315.6050108@elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.

------=_NextPart_000_01BF_01C9B50F.239BA6B0
Content-Type: text/plain; format=flowed; charset="iso-8859-1";
	reply-type=response
Content-Transfer-Encoding: 7bit

> Luiz Otavio O Souza wrote:
>>>> Is there a way to set the mss for a socket ? Like you can do
>>>> in linux with setsockopt(TCP_MAXSEG) ?
>>>>
>>>> So i can set the maximum size of packets (or sort of) from a
>>>> simple userland program.
>>>
>>> Depending on exactly what you need to accomplish, you may
>>> find something useful in this thread from last August in
>>> freebsd-questions@
>>>
>>>  setting the other end's TCP segment size
>>
>> Very informative thread, thanks.
>>
>> This thread show me that TCP_MAXSEG is implemented in freebsd but don't
>> work. You can set the setsockopt(IPPROTO_TCP, TCP_MAXSEG), wich will set 
>> the
>> tp->t_maxseg, but this value is recalculated at tcp_input, so in short, 
>> you
>> cannot set the max segment size for a socket.
>>
>> I've posted a completly wrong patch (from style point-of-view - and using
>> SOL_SOCKET instead of IPPROTO_TCP), but with that patch i'm able to set 
>> the
>> mss in iperf.
>
> this thread shoud be in FreeBSD-net@ so tha the right people see it
> many developers do not read hackers every day as it tends to overload 
> them.

The above patch is a better fix for this, it fix the setsockopt(IPPROTO_TCP, 
TCP_MAXSEG), so iperf (and other userland programs) works by default.

It's clear on code that tp->t_maxseg should not be changed, at least in this 
situation (it keeps the maximum mss for connection and it is used to 
calculate the tcp window scaling). tp->t_maxseg is also reseted to maxmtu 
(or rmx_mtu) at tcp_mss_update().

So here is the patch: http://loos.no-ip.org/downloads/mss-patch

Thanks
Luiz 

------=_NextPart_000_01BF_01C9B50F.239BA6B0
Content-Type: text/plain; format=flowed; name="mss-patch.txt";
	reply-type=response
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="mss-patch.txt"

--- netinet/socketvar.h.orig	2009-04-03 22:29:34.000000000 -0300=0A=
+++ netinet/socketvar.h	2009-04-03 22:29:44.000000000 -0300=0A=
@@ -115,6 +115,7 @@=0A=
 		char	*so_accept_filter_str;	/* saved user args */=0A=
 	} *so_accf;=0A=
 	int so_fibnum;		/* routing domain for this socket */=0A=
+	int so_maxseg;		/* maxseg this socket */=0A=
 };=0A=
 =0A=
 /*=0A=
--- netinet/tcp_usrreq.c.orig	2009-04-03 22:24:53.000000000 -0300=0A=
+++ netinet/tcp_usrreq.c	2009-04-03 23:26:35.000000000 -0300=0A=
@@ -1352,9 +1352,8 @@=0A=
 				return (error);=0A=
 =0A=
 			INP_WLOCK_RECHECK(inp);=0A=
-			if (optval > 0 && optval <=3D tp->t_maxseg &&=0A=
-			    optval + 40 >=3D V_tcp_minmss)=0A=
-				tp->t_maxseg =3D optval;=0A=
+			if (optval >=3D 40 && optval <=3D tp->t_maxseg)=0A=
+				so->so_maxseg =3D optval;=0A=
 			else=0A=
 				error =3D EINVAL;=0A=
 			INP_WUNLOCK(inp);=0A=
@@ -1389,7 +1388,10 @@=0A=
 			error =3D sooptcopyout(sopt, &optval, sizeof optval);=0A=
 			break;=0A=
 		case TCP_MAXSEG:=0A=
-			optval =3D tp->t_maxseg;=0A=
+			if (so->so_maxseg)=0A=
+				optval =3D so->so_maxseg;=0A=
+			else=0A=
+				optval =3D tp->t_maxseg;=0A=
 			INP_WUNLOCK(inp);=0A=
 			error =3D sooptcopyout(sopt, &optval, sizeof optval);=0A=
 			break;=0A=
--- netinet/tcp_output.c.orig	2009-04-02 22:48:04.000000000 -0300=0A=
+++ netinet/tcp_output.c	2009-04-03 23:28:07.000000000 -0300=0A=
@@ -493,6 +493,11 @@=0A=
 		}=0A=
 	}=0A=
 =0A=
+	if (so->so_maxseg && len > so->so_maxseg) {=0A=
+	    len =3D so->so_maxseg;=0A=
+	    sendalot =3D 1;=0A=
+	}=0A=
+=0A=
 	if (sack_rxmit) {=0A=
 		if (SEQ_LT(p->rxmit + len, tp->snd_una + so->so_snd.sb_cc))=0A=
 			flags &=3D ~TH_FIN;=0A=
@@ -518,6 +523,8 @@=0A=
 	if (len) {=0A=
 		if (len >=3D tp->t_maxseg)=0A=
 			goto send;=0A=
+		if (so->so_maxseg && len >=3D so->so_maxseg)=0A=
+			goto send;=0A=
 		/*=0A=
 		 * NOTE! on localhost connections an 'ack' from the remote=0A=
 		 * end may occur synchronously with the output and cause=0A=

------=_NextPart_000_01BF_01C9B50F.239BA6B0--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3F89BC6021844DC58B956E5433650445>