kern/144000: [tcp] ignore set TCP_MAXSEG by setsockopt()

Andrey Zonov andrey.zonov at gmail.com
Tue Feb 16 12:20:03 UTC 2010


>Number:         144000
>Category:       kern
>Synopsis:       [tcp] ignore set TCP_MAXSEG by setsockopt()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 16 12:20:02 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Andrey Zonov
>Release:        7.2-STABLE, 8.0-STABLE
>Organization:
>Environment:
>Description:
After reading Stevens and man 4 tcp, i trying to set mss for connections by setsockopt(TCP_MAXSEG), but it's not worked for me.

In Linux it's work fine.
>How-To-Repeat:
Compile test programs and look into tcpdump.


>Fix:


Patch attached with submission follows:

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <err.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>

static char buf[] = "test echo";

int
main(void)
{
	int s, maxseg;
	struct sockaddr_in serv;

	bzero(&serv, sizeof(serv));
	serv.sin_family = AF_INET;
	serv.sin_port = htons(5555);
	inet_pton(AF_INET, "localhost", &serv.sin_addr);

	s = socket(AF_INET, SOCK_STREAM, 0);

	maxseg = 300;
	if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, (const void *) &maxseg, sizeof(maxseg)) != 0) {
		err(1, "setsockopt():");
	}

	if ((connect(s, (const struct sockaddr *) &serv, sizeof(serv))) == 0) {
		write(s, buf, 9);
	}
	close(s);

	exit(0);
}

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>

#define SIZE 4096

int
main(void)
{
	int s, s1, r;
	char buf[SIZE];
	struct sockaddr_in sin;

	s = socket(AF_INET, SOCK_STREAM, 0);

	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(5555);

	bind(s, (const struct sockaddr *)&sin, sizeof(sin));

	listen(s, -1);

	s1 = accept(s, (struct sockaddr *) NULL, NULL);

	while ((r = read(s1, buf, SIZE)) > 0) {
		write(s1, buf, r);
	}
	close(s1);

	exit(0);
}

# tcpdump -pni lo0 port 5555
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type NULL (BSD loopback), capture size 96 bytes
15:05:57.371757 IP 127.0.0.1.39043 > 127.0.0.1.5555: Flags [S], seq 2639122865, win 65535, options [mss 16344,nop,wscale 3,sackOK,TS val 27362 ecr 0], length 0
15:05:57.371900 IP 127.0.0.1.5555 > 127.0.0.1.39043: Flags [S.], seq 1718559353, ack 2639122866, win 65535, options [mss 16344,nop,wscale 3,sackOK,TS val 604177474 ecr 27362], length 0
15:05:57.371902 IP 127.0.0.1.39043 > 127.0.0.1.5555: Flags [.], ack 1, win 8960, options [nop,nop,TS val 27362 ecr 604177474], length 0
15:05:57.372005 IP 127.0.0.1.39043 > 127.0.0.1.5555: Flags [P.], ack 1, win 8960, options [nop,nop,TS val 27362 ecr 604177474], length 9
15:05:57.372081 IP 127.0.0.1.39043 > 127.0.0.1.5555: Flags [F.], seq 10, ack 1, win 8960, options [nop,nop,TS val 27362 ecr 604177474], length 0
15:05:57.372104 IP 127.0.0.1.5555 > 127.0.0.1.39043: Flags [.], ack 11, win 8958, options [nop,nop,TS val 604177474 ecr 27362], length 0
15:05:57.372263 IP 127.0.0.1.5555 > 127.0.0.1.39043: Flags [P.], ack 11, win 8960, options [nop,nop,TS val 604177474 ecr 27362], length 9
15:05:57.372265 IP 127.0.0.1.39043 > 127.0.0.1.5555: Flags [R], seq 2639122876, win 0, length 0


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list