Setting the mss for socket
Luiz Otavio O Souza
lists.br at gmail.com
Sat Apr 4 06:50:55 PDT 2009
> 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
-------------- next part --------------
--- netinet/socketvar.h.orig 2009-04-03 22:29:34.000000000 -0300
+++ netinet/socketvar.h 2009-04-03 22:29:44.000000000 -0300
@@ -115,6 +115,7 @@
char *so_accept_filter_str; /* saved user args */
} *so_accf;
int so_fibnum; /* routing domain for this socket */
+ int so_maxseg; /* maxseg this socket */
};
/*
--- netinet/tcp_usrreq.c.orig 2009-04-03 22:24:53.000000000 -0300
+++ netinet/tcp_usrreq.c 2009-04-03 23:26:35.000000000 -0300
@@ -1352,9 +1352,8 @@
return (error);
INP_WLOCK_RECHECK(inp);
- if (optval > 0 && optval <= tp->t_maxseg &&
- optval + 40 >= V_tcp_minmss)
- tp->t_maxseg = optval;
+ if (optval >= 40 && optval <= tp->t_maxseg)
+ so->so_maxseg = optval;
else
error = EINVAL;
INP_WUNLOCK(inp);
@@ -1389,7 +1388,10 @@
error = sooptcopyout(sopt, &optval, sizeof optval);
break;
case TCP_MAXSEG:
- optval = tp->t_maxseg;
+ if (so->so_maxseg)
+ optval = so->so_maxseg;
+ else
+ optval = tp->t_maxseg;
INP_WUNLOCK(inp);
error = sooptcopyout(sopt, &optval, sizeof optval);
break;
--- netinet/tcp_output.c.orig 2009-04-02 22:48:04.000000000 -0300
+++ netinet/tcp_output.c 2009-04-03 23:28:07.000000000 -0300
@@ -493,6 +493,11 @@
}
}
+ if (so->so_maxseg && len > so->so_maxseg) {
+ len = so->so_maxseg;
+ sendalot = 1;
+ }
+
if (sack_rxmit) {
if (SEQ_LT(p->rxmit + len, tp->snd_una + so->so_snd.sb_cc))
flags &= ~TH_FIN;
@@ -518,6 +523,8 @@
if (len) {
if (len >= tp->t_maxseg)
goto send;
+ if (so->so_maxseg && len >= so->so_maxseg)
+ goto send;
/*
* NOTE! on localhost connections an 'ack' from the remote
* end may occur synchronously with the output and cause
More information about the freebsd-net
mailing list