lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-users] [lwip] Problems with TCP


From: Rajaraman Krishnan
Subject: [lwip-users] [lwip] Problems with TCP
Date: Wed, 08 Jan 2003 22:18:07 -0000

This is a multi-part message in MIME format.

------=_NextPart_000_0011_01C1AFDA.E390E620
Content-Type: text/plain;
        charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hi Everyone,

I am having a problem with LwIP. I have implemented a TCP server using LwIP
(the usual bind, accept and read data). The client runs on Linux using the
standard socket interface (usual connect and write data). The client and
server talk through a TAP/TUN interface. I have attached the lwip_server.c
and client.cc code for these two with this Email.

When I run the server and client, the server comes up listens for connection
and when the client connects, the connection comes through fine (i.e. the
function passed to tcp_accept gets called). But when the client writes data
I do not get called back on the function passed to tcp_recv.

I tried debugging by putting couple of printfs in tcp_input. I then also
added a tcpdump call to the first line of ip_input.c (and modified tcpdump
to print on stdout). I also ran tcpdump on the machine where I am running
this (as tcpdump -l -n -i tap0). I have attached the outputs from
lwip_server and tcpdump.
If you see tcpdump.out, I can account for the arp packets and the next 4
packets. For these you see the corresponding tcpdumps in the lwip_server
side. After that there are absolutely no more tcpdumps on the server side
(i.e. ip_input function did not get called). The client did send several
more packets including the actual data packet containing 6 bytes of data
several times. The ip_input function did not get called even once for all
these packets.

Can someone throw some light on what is going on? BTW I did think about
using the TCP code from shell.c but that doesnt use the Raw API and the API
it uses (i.e. netconn_*) is not documented anywhere.

Rajaram

------=_NextPart_000_0011_01C1AFDA.E390E620
Content-Type: application/octet-stream;
        name="lwip_server.out"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
        filename="lwip_server.out"

address@hidden lwip_tcp]# lwip_server 192.160.50.1 6789
System initialized.
netif: added interface tp IP addr 192.160.50.1 netmask 255.255.255.0 gw =
192.160.50.2
netif: setting default interface tp
netif: added interface lo IP addr 127.0.0.1 netmask 255.0.0.0 gw =
127.0.0.1
TCP/IP initialized.
Bind OK. Listening for connect.
Listen socket =3D 0x8054839.
Hmm tcp_accept returns.
192.160.50.2.1054 > 192.160.50.1.6789: S 953338656:953338656(0) wnd =
32120
Some TCP packet received. From:1054, To:6789.
TCP packet received for PCB: 0x8054839.=20
192.160.50.2.1054 > 192.160.50.1.6789: ack 6535 wnd 32120
Some TCP packet received. From:1054, To:6789.
TCP packet received for PCB: 0x805458c.=20
Receiving message from client.
Data socket =3D 0x805458c.


------=_NextPart_000_0011_01C1AFDA.E390E620
Content-Type: application/octet-stream;
        name="tcpdump.out"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
        filename="tcpdump.out"

address@hidden core]# tcpdump -l -n -i tap0
Kernel filter, protocol ALL, datagram packet socket
tcpdump: listening on tap0
13:14:04.845168 > arp who-has 192.160.50.1 tell 192.160.50.2 =
(0:ff:15:4:d5:1)
13:14:04.845221 < arp reply 192.160.50.1 is-at 1:0:12:0:23:0 =
(0:ff:15:4:d5:1)
13:14:04.845227 > 192.160.50.2.1054 > 192.160.50.1.6789: S =
953338656:953338656(0) win 32120 <mss 1460,sackOK,timestamp 1378781 =
0,nop,wscale 0> (DF)
13:14:04.845616 < 192.160.50.1.6789 > 192.160.50.2.1054: S 6534:6534(0) =
ack 953338657 win 1024 <mss 64>
13:14:04.845667 > 192.160.50.2.1054 > 192.160.50.1.6789: . 1:1(0) ack 1 =
win 32120 (DF)
13:14:07.856926 < 192.160.50.1.6789 > 192.160.50.2.1054: S 6534:6534(0) =
ack 953338657 win 1024 <mss 64>
13:14:07.856967 > 192.160.50.2.1054 > 192.160.50.1.6789: . 1:1(0) ack 1 =
win 32704 (DF)
13:14:09.857903 > 192.160.50.2.1054 > 192.160.50.1.6789: P 1:7(6) ack 1 =
win 32704 (DF)
13:14:12.856923 > 192.160.50.2.1054 > 192.160.50.1.6789: P 1:7(6) ack 1 =
win 32704 (DF)
13:14:14.216921 < 192.160.50.1.6789 > 192.160.50.2.1054: S 6534:6534(0) =
ack 953338657 win 1024 <mss 64>
13:14:14.216957 > 192.160.50.2.1054 > 192.160.50.1.6789: . 7:7(0) ack 1 =
win 32704 (DF)
13:14:18.856923 > 192.160.50.2.1054 > 192.160.50.1.6789: P 1:7(6) ack 1 =
win 32704 (DF)
13:14:26.936934 < 192.160.50.1.6789 > 192.160.50.2.1054: S 6534:6534(0) =
ack 953338657 win 1024 <mss 64>
13:14:26.936974 > 192.160.50.2.1054 > 192.160.50.1.6789: . 7:7(0) ack 1 =
win 32704 (DF)
13:14:30.856922 > 192.160.50.2.1054 > 192.160.50.1.6789: P 1:7(6) ack 1 =
win 32704 (DF)
13:14:37.556923 > 192.160.50.2.1052 > 192.160.50.1.4445: P =
674313621:674313627(6) ack 6514 win 32704 (DF)

16 packets received by filter

------=_NextPart_000_0011_01C1AFDA.E390E620
Content-Type: application/octet-stream;
        name="lwip_server.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
        filename="lwip_server.c"

#include "lwip/debug.h"

#include <unistd.h>


#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/sys.h"

#include "lwip/stats.h"


#include "lwip/tcpip.h"

#include "netif/tapif.h"
#include "netif/tunif.h"

#include "netif/unixif.h"
#include "netif/dropif.h"

#include "netif/loopif.h"

#include "netif/tcpdump.h"

#include "netif/sioslipif.h"


#include "lwip/ip_addr.h"

#include <stdio.h>

#define MAX_STRING 100

typedef struct
{
    sys_sem_t sem;
    char msg[MAX_STRING];
    int len;
} ReceiveDetails;

struct ip_addr host, gw;
int port;

// Read the message from socket
err_t ReadSocket(void * arg, struct tcp_pcb *dsock, struct pbuf *p, =
err_t err)
{
    struct pbuf* np;
    ReceiveDetails *recv =3D (ReceiveDetails *)arg;

    printf("Data to be read in connection.\n");

    if (err !=3D 0)
    {
        printf("Error in HandleNewConn.\n");
        exit(1);
    }

    if (p =3D=3D NULL)
    {
        printf("Client closed connection.\n");
        return 0;
    }

    np =3D p;
    while (np !=3D NULL)
    {
        memcpy(recv->msg+recv->len, np->payload, np->len);
        recv->len +=3D np->len;
        np =3D np->next;
    }

    tcp_recved(dsock, p->tot_len);

    /* Check if a full string has been received. */
    if (recv->msg[recv->len-1] !=3D '\0')
    {
        sys_sem_signal(recv->sem);
    }

    return 0;
}

err_t HandleNewConn(void *arg, struct tcp_pcb *dsock, err_t err)
{
    ReceiveDetails *recv;

    recv =3D (ReceiveDetails *) malloc(sizeof(ReceiveDetails));

    if (err !=3D 0)
    {
        printf("Error in HandleNewConn.\n");
        exit(1);
    }

    printf("Receiving message from client.\n");

    printf("Data socket =3D %p.\n", dsock);
   =20
    recv->sem =3D sys_sem_new(0);
    recv->len =3D 0;
    tcp_arg(dsock, &arg);

    tcp_recv(dsock, ReadSocket);

    sys_sem_wait(recv->sem);
    sys_sem_free(recv->sem);

    printf("Message Received: %s. \nSending Reply: Hi2U2.\n", =
recv->msg);

    tcp_write(dsock, "Hi2U2", 6, 1);
    printf("Message Sent.\n");

    /* Close the Dsock. */
    tcp_close(dsock);
    return 0;
}


/*-----------------------------------------------------------------------=
----
|  Setup socket
|------------------------------------------------------------------------=
--*/
void TcpCommunicate(int port)=20
{
    struct tcp_pcb *sock;

    /* create what looks like an ordinary TCP socket */
    if ((sock =3D tcp_new()) =3D=3D NULL)
    {
        printf("Problems with tcp_new.\n");
        exit(1);
    }

    /* bind to receive address */
    if (tcp_bind(sock, IP_ADDR_ANY, port) < 0)
    {
        printf("bind failed: ");
        exit(1);
    }
   =20

    /* listen on this socket */
    printf("Bind OK. Listening for connect.\n");
    if ((sock =3D tcp_listen(sock)) =3D=3D NULL)
    {
        printf("Error in listen.\n");
        exit(1);
    }

    printf("Listen socket =3D %p.\n", sock);
   =20
    /* accept the socket, and create a peer socket to listen */
    tcp_accept(sock, HandleNewConn);
    printf("Hmm tcp_accept returns.\n");
}

void lwip_if_init()
{
    struct ip_addr lbaddr, netmask, lbgw;

   =20
    IP4_ADDR(&netmask, 255,255,255,0);
 =20
    netif_set_default(netif_add(&host, &netmask, &gw, tapif_init,
                                tcpip_input));

    IP4_ADDR(&lbgw, 127,0,0,1);
    IP4_ADDR(&lbaddr, 127,0,0,1);
    IP4_ADDR(&netmask, 255,0,0,0);
 =20
    netif_add(&lbaddr, &netmask, &lbgw, loopif_init, tcpip_input);
}

static void
tcpip_init_done(void *arg)
{
  sys_sem_t *sem;
  sem =3D arg;
  sys_sem_signal(*sem);
}   =20

void lwip_init()
{
    sys_init();
    mem_init();
    memp_init();
    pbuf_init();

    tcpdump_init();
}

void main_thread(void *arg)
{
    sys_sem_t sem;

    lwip_if_init();

    sem =3D sys_sem_new(0);
    tcpip_init(tcpip_init_done, &sem);
    sys_sem_wait(sem);
    sys_sem_free(sem);
    printf("TCP/IP initialized.\n");

    TcpCommunicate(port);

    /* Block for ever. */
    sem =3D sys_sem_new(0);
    sys_sem_wait(sem);
}


int parse_addr(char *caddr, struct ip_addr *ipaddr1, struct ip_addr =
*ipaddr2)
{
    int a, b, c, d;

    if (sscanf(caddr, "%d.%d.%d.%d", &a, &b, &c, &d) !=3D 4)
        return 0;

    if ((a < 0) || (a > 255) || (b < 0) || (b > 255) || (c < 0) || (c > =
255) ||
        (d < 0) || (d > 254))
        return 0;

    IP4_ADDR(ipaddr1, a, b, c, d);
    IP4_ADDR(ipaddr2, a, b, c, (d+1));
    return 1;
}


int main(int argc, char **argv)
{
    if (argc !=3D 3)
    {
        printf("Usage: %s <Sim IP Address> <portNo>\n",  argv[0]);
        exit(1);
    }

    if (!parse_addr(argv[1], &host, &gw))
    {
        printf("Usage: %s <Sim IP Address> <portNo>\n",  argv[0]);
        printf("\t<Sim IP Address> should be of the form A.B.C.D.\n");

        exit(1);
    }

    lwip_init(&host, &gw);

    printf("System initialized.\n");

    if (sscanf(argv[2], "%d", &port) !=3D 1)
    {
        printf("Usage: %s <Sim IP Address> <portNo>\n",  argv[0]);
        printf("\t<Sim IP Address> should be of the form A.B.C.D.\n");

        exit(1);
    }

    sys_thread_new((void *)(main_thread), NULL);
    pause();
    return 0;
}

------=_NextPart_000_0011_01C1AFDA.E390E620
Content-Type: application/octet-stream;
        name="client.cc"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
        filename="client.cc"

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>

#define MAX_STRING 10

int sockfd;

// Send a buffer to the Wrapper.
int WriteSocket(char *msg)
{
    ulong bufLen =3D strlen(msg)+1;
    ulong tmpLen, writeLen =3D 0;

    printf("Writing %d bytes on socket %d.\n", bufLen, sockfd);

    while (writeLen < bufLen)
    {
        if ((tmpLen =3D write(sockfd, msg+writeLen, bufLen)) <=3D 0)
        {
            printf("write error\n");
            return 1;
        }
        writeLen +=3D tmpLen;
    }

    return 0;
}

// Read the message from socket
int ReadSocket(char *msg)
{
    ulong tmpLen, readLen =3D 0;

    while (1)
    {
        if ((tmpLen =3D read(sockfd, msg+readLen, MAX_STRING)) <=3D 0)
        {
            printf("read error\n");
            return 1;
        }
        printf("Read Something.\n");
        readLen +=3D tmpLen;
        if (msg[readLen-1] =3D=3D '\0') return 0;
    }
}

/*-----------------------------------------------------------------------=
----
|  Setup socket
|------------------------------------------------------------------------=
--*/
void SetupClientSocket(char* addr, int port)=20
{
    if ((sockfd =3D socket(AF_INET, SOCK_STREAM, 0)) <0)
    {
        fprintf(stderr, "Create socket failed.\n");
        exit(1);
    }

    struct sockaddr_in remoteAddr;

    bzero((char *) &remoteAddr, sizeof(remoteAddr));
    remoteAddr.sin_family =3D AF_INET;
    remoteAddr.sin_port =3D htons(port);

    inet_aton(addr, &remoteAddr.sin_addr);
=20
    printf("Connecting to %s on port %d.\n", =
inet_ntoa(remoteAddr.sin_addr),
           port);
    if (connect(sockfd, (struct sockaddr *)&remoteAddr, =
sizeof(remoteAddr)) < 0)
    {
        perror("Connect failed: ");
        exit(1);
    }
    printf("Connected on socket: %d.\n", sockfd);
}

main(int argc, char **argv)
{
    ulong port;
    char reply[MAX_STRING];

    if (argc !=3D 3)
    {
        printf("Usage: %s <IP Address> <portNo>\n",  argv[0]);
        exit(1);
    }

    if (sscanf(argv[2], "%d", &port) !=3D 1)
    {
        printf("Usage: %s <IP Address> <portNo>\n",  argv[0]);
        exit(1);
    }

    SetupClientSocket(argv[1], port);
    printf("Sending message to Server: Hello.\n");
    sleep(5);
    WriteSocket("Hello");
    printf("Message Sent.\n");
    ReadSocket(reply);
    printf("Message Received: %s.\n", reply);
}

------=_NextPart_000_0011_01C1AFDA.E390E620--

[This message was sent through the lwip discussion list.]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]