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>