netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* strange tcp behavior
@ 2007-08-02  6:19 john
  2007-08-02  9:55 ` Evgeniy Polyakov
  0 siblings, 1 reply; 28+ messages in thread
From: john @ 2007-08-02  6:19 UTC (permalink / raw)
  To: netdev

1186035057.207629    127.0.0.1 -> 127.0.0.1    TCP 50000 > smtp [SYN]
Seq=0 Len=0
1186035057.207632    127.0.0.1 -> 127.0.0.1    TCP smtp > 50000 [SYN, ACK]
Seq=0 Ack=1 Win=32792 Len=0 MSS=16396
1186035057.207666    127.0.0.1 -> 127.0.0.1    TCP 50000 > smtp [ACK]
Seq=1 Ack=1 Win=1500 Len=0
1186035057.207699    127.0.0.1 -> 127.0.0.1    SMTP Command: EHLO localhost
1186035057.207718    127.0.0.1 -> 127.0.0.1    TCP smtp > 50000 [ACK]
Seq=1 Ack=17 Win=32792 Len=0
1186035057.207736    127.0.0.1 -> 127.0.0.1    TCP 50000 > smtp [RST]
Seq=17 Len=0
1186035057.223934    127.0.0.1 -> 127.0.0.1    TCP 33787 > 50000 [RST,
ACK] Seq=0 Ack=0 Win=32792 Len=0



Can someone please comment as to why, tcp  stack sends rst packet from the
wrong source port in this situation.

This is the same problem that was described in my first two posts, witch 
unfortunately nobody seemed to notice.

Here is source code witch can reproduce the behavior described, the client
side code is a complete mess but with a little bit it works.

Server:

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <poll.h>
#include <fcntl.h>

void main(void) {
        int ms;
        int ss;
        struct sockaddr_in sa;
        char *str = "HELLO FRIEND";
        struct pollfd fd;
        int flags;

        ms = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        flags = fcntl(ms, F_GETFL, 0);
        fcntl(ms, F_SETFL, flags | O_NONBLOCK);

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

        bind(ms, (struct sockaddr *) &sa, sizeof(sa));

        listen(ms, 0);

        fd.fd = ms;
        fd.events = POLLIN;

        while(poll(&fd, 1, -1)) {
                ss = accept(ms, NULL, NULL);

                usleep(10000);
                send(ss, str, strlen(str), MSG_NOSIGNAL);
                close(ss);

                memset(&fd, 0, sizeof(fd));
                fd.fd = ms;
                fd.events = POLLIN;
        }
}

Client:


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <linux/if_ether.h>
//#include <arpa/inet.h>

//#include <linux/if_ether.h>

struct sockaddr_in localaddr;
struct sockaddr_in remoteaddr;

struct sockaddr rawaddr;

int sdl, sdr;

struct tcphdr header;

struct pheader_t {
        uint32_t saddr;
        uint32_t daddr;
        uint8_t r;
        uint8_t protocol;
        uint16_t length;
};

struct pheader_t pheader;

unsigned short tbuf[2048];
unsigned char buf[2048];

char *msg = "EHLO localhost\r\n";

unsigned char *p;

char *src_addr = "127.0.0.1";
char *dst_addr = "127.0.0.1";

unsigned short sprt = 50000;
unsigned short dprt = 25;


struct timeval tv;

unsigned seq, ack_seq;

int data;

void mysend(void) {
        int i, sum;
        int len;

        if(data) {
                len = strlen(msg);
                memcpy((char *) tbuf + sizeof(pheader) + sizeof(header),
msg, len);
        } else
                len = 0;

        bzero(&pheader, sizeof(pheader));
        pheader.saddr = (in_addr_t) inet_addr(src_addr);
        pheader.daddr = (in_addr_t) inet_addr(dst_addr);
        pheader.protocol = 6;
        pheader.length = htons(sizeof(header) + len);

        memcpy(tbuf, &pheader, sizeof(pheader));
        memcpy((char *) tbuf + sizeof(pheader), &header, sizeof(header));



        sum = 0;

        for(i = 0; i < (sizeof(pheader) + sizeof(header)) / 2 + len / 2;
i++) {
                sum += tbuf[i];
                sum = (sum & 0x0000ffff) + (sum >> 16);
        }

        header.check = ~sum;

        memcpy((char *) tbuf + sizeof(pheader), &header, sizeof(header));

        sendto(sdr,  (char *) tbuf + sizeof(pheader), sizeof(header) +
len, 0, (struct sockaddr *) &remoteaddr, sizeof(remoteaddr));
}


void main(void)
{
        gettimeofday(&tv, NULL);
        srand(tv.tv_sec & tv.tv_usec);

        remoteaddr.sin_family = AF_INET;
        remoteaddr.sin_addr.s_addr = (in_addr_t) inet_addr(dst_addr);


        sdl = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
        strcpy(rawaddr.sa_data, "lo");
        bind(sdl, (struct sockaddr *) &rawaddr, sizeof(rawaddr));

        sdr = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);


        bzero(&header, sizeof(header));
        header.source = htons(sprt);
        header.dest = htons(dprt);

        seq = rand();
        ack_seq = 0;

        header.seq = htonl(seq);
        header.ack_seq = htonl(ack_seq);

        header.doff = sizeof(header) / 4;

        header.syn = 1;

        header.window = htons(1500);

        mysend();

        while(1) {
                recvfrom(sdl, buf, sizeof(buf), 0, NULL, NULL);
//              p = buf + (*buf & 0x0f) * 4;
                p = (buf + 14) + (*(buf + 14) & 0x0f) * 4;
                if(ntohs(((struct tcphdr *)p)->source) == dprt &&
ntohs(((struct tcphdr *)p)->dest) == sprt && ((struct
tcphdr *)p)->syn == 1 && ((struct tcphdr *)p)->ack == 1)
                        break;
        }


        bzero(&header, sizeof(header));
        header.source = htons(sprt);
        header.dest = htons(dprt);

        seq = ntohl(((struct tcphdr *)p)->ack_seq);
        ack_seq = ntohl(((struct tcphdr *)p)->seq) + 1;

        header.seq = htonl(seq);
        header.ack_seq = htonl(ack_seq);

        header.doff = sizeof(header) / 4;

        header.ack = 1;

        header.window = htons(1500);

        mysend();


        bzero(&header, sizeof(header));
        header.source = htons(sprt);
        header.dest = htons(dprt);

        header.seq = htonl(seq);
        header.ack_seq = htonl(ack_seq);

        header.doff = sizeof(header) / 4;

        header.ack = 1;
        header.psh = 1;

        header.window = htons(1500);

        data = 1;
        mysend();
        data = 0;

//      usleep(300);


        bzero(&header, sizeof(header));
        header.source = htons(sprt);
        header.dest = htons(dprt);

        seq += strlen(msg);

        header.seq = htonl(seq);
        header.ack_seq = htonl(ack_seq);

        header.doff = sizeof(header) / 4;

        header.rst = 1;

        header.window = htons(1500);

        mysend();
}




I traced this behavior way back to 2.4.0-test9-pre3 kernel.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2007-08-05  3:21 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-02  6:19 strange tcp behavior john
2007-08-02  9:55 ` Evgeniy Polyakov
2007-08-02 10:16   ` Evgeniy Polyakov
2007-08-02 11:38     ` Simon Arlott
2007-08-02 12:04       ` Evgeniy Polyakov
2007-08-02 12:28         ` Evgeniy Polyakov
     [not found]       ` <46860.212.93.96.73.1186055105.squirrel@mail.screen.lv>
2007-08-02 12:15         ` Simon Arlott
2007-08-02 17:15           ` Simon Arlott
2007-08-02 18:08             ` Evgeniy Polyakov
2007-08-02 18:48               ` Evgeniy Polyakov
2007-08-02 22:02                 ` David Miller
2007-08-03  2:21                 ` David Miller
2007-08-03  8:22                   ` Evgeniy Polyakov
2007-08-03 20:04                     ` David Miller
2007-08-04 16:49                       ` Evgeniy Polyakov
2007-08-03 21:17                     ` David Miller
2007-08-04 16:51                       ` Evgeniy Polyakov
2007-08-05  3:21                         ` David Miller
2007-08-02 18:58               ` Simon Arlott
2007-08-03  8:25                 ` Evgeniy Polyakov
2007-08-03 11:21                   ` Simon Arlott
2007-08-03 11:56                     ` Evgeniy Polyakov
2007-08-03 12:03                       ` Simon Arlott
2007-08-03 12:09                         ` Evgeniy Polyakov
2007-08-03 16:51                           ` Simon Arlott
2007-08-03 17:39                             ` Evgeniy Polyakov
2007-08-03 18:29                               ` Simon Arlott
2007-08-04 16:03                                 ` Evgeniy Polyakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).