Hi,
We actively use TTCP and we like it (www.xiplink.com). The problem is that it does not behave exactly like in Steven's book. I have sample code if you want to try it. But basically you need to set the NOPUSH flag (setsockopt()) before using sendto() _and_ in the server as well. For short duration connections over satellite links, its very useful since it can save one RTT per connections (minimum 600ms) which can be very important when dealing with thousands of connections. See attachment for example and dumps. It does have to be used carefully (with security concerns), but can still be very useful.


We are currently based on 4.8 and will port to 5.x whenever it becomes stable. I for one, would be very happy if FreeBSD continues supporting T/TCP. There are systems and users out there!

Here is the dump:

12:44:01.851882 192.168.27.2.1096 > 192.168.28.2.8908: SFP 919859592:919859992(400) win 65535 <mss 1460,nop,wscale 3,opt-20:5000,nop,nop,timestamp 68099116 0,nop,nop,cc 146> (DF)
12:44:01.852185 192.168.28.2.8908 > 192.168.27.2.1096: S 3400625327:3400625327(0) ack 919859994 win 65535 <mss 1460,nop,wscale 3,nop,nop,timestamp 68113687 68099116,nop,nop,cc 309,nop,nop,ccecho 146> (DF)
12:44:01.852355 192.168.27.2.1096 > 192.168.28.2.8908: . ack 1 win 62640 <nop,nop,timestamp 68099117 68113687,nop,nop,cc 146> (DF)
12:44:01.852472 192.168.28.2.8908 > 192.168.27.2.1096: . ack 1 win 62500 <nop,nop,timestamp 68113687 68099117,nop,nop,cc 309> (DF)
12:44:01.852718 192.168.28.2.8908 > 192.168.27.2.1096: F 1:1(0) ack 1 win 62500 <nop,nop,timestamp 68113687 68099117,nop,nop,cc 309> (DF)
12:44:01.852846 192.168.27.2.1096 > 192.168.28.2.8908: . ack 2 win 62640 <nop,nop,timestamp 68099117 68113687,nop,nop,cc 146> (DF)


First packet you see the SYN-FIN PUSH, then second packet it gets acked (data + SYN + FIN) then the connection closes. BTW don't mind the option 20 (opt-20) Its our implementation of SCPS-TP.


Karim Xiphos Technologies.

Andre Oppermann wrote:

Danny Braniss wrote:


I have been the last one fuzz around in the TTCP code areas. However
there could be problems that were lurking there before in other code
parts (syncache maybe). TTCP isn't used in production by anyone (AFAIK)
and only minimally tested.


I have to disagree here :)

ahh, that's one realy good piece of info so far.
this is one more step away from 'don't judge a book by it's cover' ...
reading the specs of ttcp, it seemed promising, but i guess it becomes
insignificat when the world uses ssl:-)



There are who like it and there are people who hate it.




What FreeBSD version are you using?


4.8, 4.9 and current.



In 4.8 and 4.9 is the legacy code. When it doesn't work between a
4.x client and server then the TTCP as such is broken. My changes
(tcp hostcache) are in 5.2 for the first time. Before it it's the
legacy code as well. I hope I haven't broken TTCP more than it was
before.




and solaris(but i guess they don't do ttcp) and linux (not yet).



Linux never will. They consider TTCP broken by design. Solaris I dont know.

The problem is that TTCP will never make it mainstream or even
little side stream.  FreeBSD is the only BSD implementing it.
Removing it would make maintainance of the tcp code a bit easier.
Yet there are a couple of our FreeBSD folks emotionally attached
to it (but they do not actively or even passively maintain it).




#include "cliserv.h"

int read_stream (int fd, char *ptr, int maxbytes)
{
        int nleft, nread;

        nleft = maxbytes;
        while (nleft > 0) {
                if ((nread = read(fd, ptr, nleft)) < 0)
                        return (nread);         /* error return < 0 */
                else if (nread == 0)
                        break;                  /* EOF, return #bytes read */
                nleft -= nread;
                ptr += nread;
        }
        return (maxbytes - nleft);
}


int main (int argc, char *argv[])
{
        struct sockaddr_in serv, cli;
        char *request;
        int listenfd, sockfd, n, clilen;
        int One = 1;

        if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
                printf("socket error\n");
                exit(0);
        }

        memset(&serv, sizeof(serv), 0);
        serv.sin_family = AF_INET;
        serv.sin_port = htons(TCP_SERV_PORT);
        serv.sin_addr.s_addr = htonl(INADDR_ANY); 

        if (bind(listenfd, (SA)&serv, sizeof(serv)) < 0) {
                perror("bind error");
                exit(0);
        }


        if (listen(listenfd, SOMAXCONN) < 0) {
                printf("listen error\n");
                exit(0);
        }


        for(;;) {
                clilen = sizeof(cli);
                printf("waiting for client to connect\n");
                setsockopt(listenfd, IPPROTO_TCP, TCP_NOPUSH, &One, sizeof (One));
                if ((sockfd = accept(listenfd, (SA)&cli, &clilen)) < 0) {
                        printf("accept error\n");
                        exit(0);
                }

                One = 0;        
                setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, &One, sizeof (One));

                if ((n = read(sockfd, request, REQUEST)) < 0) {
                        printf("read error\n");
                        exit(0);
                }
                printf("%d\n", n);
                close(sockfd);
        }
}
#include <netdb.h>
#include "cliserv.h"

int read_stream (int fd, char *ptr, int maxbytes)
{
        int nleft, nread;

        nleft = maxbytes;
        while (nleft > 0) {
                if ((nread = read(fd, ptr, nleft)) < 0)
                        return (nread);         /* error return < 0 */
                else if (nread == 0)
                        break;                  /* EOF, return #bytes read */
                nleft -= nread;
                ptr += nread;
        }
        return (maxbytes - nleft);
}

int main (int argc, char *argv[])
{
        struct sockaddr_in serv;
        struct hostent *host;
        char request[REQUEST];
        uint32_t ipAddr;
        int sockfd, n;
        int eof;
        int One = 1;

        if (argc !=3) {
                printf("usage: ttcpcli <IP address or name of server> <EOF>\n");
                exit(0);
        }
        sscanf(argv[2], "%d", &eof);

        if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
                printf("socket error\n");
                exit(0);
        }

        memset(&serv, sizeof(serv), 0);
        serv.sin_family = AF_INET;
        serv.sin_port = htons(TCP_SERV_PORT);
        if ((ipAddr = inet_addr(argv[1])) != -1) {
                serv.sin_addr.s_addr = ipAddr;
        }
        else if ((host = gethostbyname(argv[1])) != NULL) {
                bcopy((char *)host->h_addr, (char *)&serv.sin_addr, host->h_length);
        }
        else {
                printf("unknown host\n");
                exit(0);
        }

        /* form request */
        strcpy(request, "This is a T/TCP payload");
        setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, &One, sizeof (One));

        if (eof) {
                if (sendto (sockfd, request, REQUEST, MSG_EOF, (SA)&serv, 
sizeof(serv)) != REQUEST) {
                        printf("sendto error\n");
                        exit(0);
                }
        }
        else {
                if (sendto (sockfd, request, REQUEST, 0, (SA)&serv, sizeof(serv)) != 
REQUEST) {
                        printf("sendto error\n");
                        exit(0);
                }
        }

        setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, &One, sizeof (One));

        /* Normally we would receive data and do some processing */
        read(sockfd, request, REQUEST);
        exit(0);
}
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define SA struct sockaddr *
#define REQUEST 400
#define REPLY   400
#define TCP_SERV_PORT 8908

_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to