Date: Wed, 25 Jun 1997 04:09:20 -0400 (EDT) From: Brian Mitchell <brian@firehouse.net> To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/3948: nonworking t/tcp server side Message-ID: <199706250809.EAA01275@apocalypse.saturn.net> Resent-Message-ID: <199706250820.BAA09750@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 3948
>Category: kern
>Synopsis: nonworking t/tcp server side
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Jun 25 01:20:01 PDT 1997
>Last-Modified:
>Originator: Brian Mitchell
>Organization:
firehouse.net
>Release: FreeBSD 2.2.1-RELEASE i386
>Environment:
486 running 2.2.1-RELEASE
>Description:
t/tcp seems not to work on server side. To test, I wrote a
simple t/tcp server and sniffed with tcpdump. The packet
traces do not match the description in the manpage. Client
side appears to work, server side does not.
>How-To-Repeat:
(this is somewhat long, but I believe most of it is relevant)
TRANSACTION MODEL
The expected model of a ``transaction'' as used by T/TCP is a fairly sim-
ple one:
1. A client program generates a request to be sent to the server, which
is small enough to fit in a single TCP segment, and sends a SYN PUSH
FIN segment with options and data to the server.
2. The server program accepts the request in the same manner as for
regular TCP connections, interprets it, and generates a reply which
may be small enough to fit in a single segment. If it is, the reply
is sent in a single SYN PUSH FIN ACK segment with (different) op-
tions and data back to the client. If not, then the connection de-
generates into (almost) the usual case for TCP. The server then
closes its socket.
3. The client reads the reply and closes its socket.
My understanding of this is the server gets a SPF segment (as it does) and
replies with a SPFA segment if it is small enough to fit in a single
packet. This is where things appear to fall apart, as is shown in the
following tcpdump log.
03:48:31.553801 localhost.1056 > localhost.finger: SFP 319123411:319123420(9)
win 57344 <mss 16344,nop,wscale 0,nop,nop,timestamp 48396
0,nop,nop,cc[|tcp]> (DF)
03:48:31.555366 localhost.finger > localhost.1056: S 319212645:319212645(0)
ack 319123422 win 57344 <mss 16344,nop,wscale 0,nop,nop,timestamp 48396
48396,nop,nop,cc[|tcp]> (DF)
03:48:31.555998 localhost.1056 > localhost.finger: . ack 1 win 57344
<nop,nop,timestamp 48396 48396,nop,nop,cc 42> (DF)
03:48:31.560896 localhost.finger > localhost.1056: FP 1:7(6) ack 1 win 57344
<nop,nop,timestamp 48396 48396,nop,nop,cc 43> (DF)
03:48:31.561525 localhost.1056 > localhost.finger: . ack 8 win 57338
<nop,nop,timestamp 48396 48396,nop,nop,cc 42> (DF)
Here is the execution of the server program. I'm using port 79 since
finger already has t/tcp support.
# ./ttcp1 79
test123
Here is execution of finger, and the response.
> finger test123@localhost
[localhost]
REPLY
Here I make sure t/tcp is indeed enabled (although there was little doubt
judging from the initial segment from the client).
> /usr/sbin/sysctl net.inet.tcp.rfc1644
net.inet.tcp.rfc1644: 1
Here is the output of uname -r
> uname -r
2.2.1-RELEASE
Here is the code. Perhaps my interpretation of the manpage was incorrect?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
main(int argc, char **argv)
{
u_short port = 79;
struct sockaddr_in sin;
int s;
int i;
char buffer[1024];
if(argc > 1)
port = atoi(argv[1]);
if(port < 1)
port = 79;
s = socket(PF_INET, SOCK_STREAM, 0);
if(s < 0)
{
perror("socket");
exit(1);
}
if(setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, &s, sizeof(s)) < 0)
{
perror("setsockopt");
exit(1);
}
sin.sin_family = PF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;
if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
perror("bind");
exit(1);
}
if(listen(s, 5) < 0)
{
perror("listen");
exit(1);
}
i = sizeof(sin);
s = accept(s, (struct sockaddr *)&sin, &i);
if(s < 0)
{
perror("accept");
exit(1);
}
i = read(s, buffer, 1024);
if(i < 0)
{
perror("read");
exit(1);
}
else if(!i)
{
fprintf(stderr, "peer closed connection\n");
exit(1);
}
else
{
write(1, buffer, i);
write(s, "REPLY\n", 6);
exit(0);
}
}
>Fix:
>Audit-Trail:
>Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199706250809.EAA01275>
