[146] in linux-net channel archive

home help back first fref pref prev next nref lref last post

Possible UDP-bug...

daemon@ATHENA.MIT.EDU (Sverre H. Huseby)
Sun Mar 26 19:53:49 1995

From: "Sverre H. Huseby" <sverrehu@ifi.uio.no>
Date: Fri, 24 Mar 1995 19:41:00 GMT
To: linux-net@vger.rutgers.edu, iialan@iifeak.swan.ac.uk


Sent this to linux-kernel, but there was no reply:
-----------------------------------------------------------------

/**************************************************************************

  This program will attempt to illustrate a possible bug in Linux'
  networking code. I set up a client/server communicating using UDP.

      Server:  loop { read datagram; send a datagram to the caller; }
      Client:  loop { send datagram to server; read datagram; }

  Doing this (seemingly) works fine. The problem shows up when I remove
  the reading from the client, making it _send_ datagrams only. Occationally
  the recvfrom() in the server returns with failure, with errno indicating
  "Connection refused" (ECONNREFUSED, 111). If I make the client sleep
  for a second between each sendto(), things seems to work fine.

  Note: I'm quite new to network programming, so this may all be my fault.
  In that case, please let me know what I'm doing wrong, and excuse me for
  `blaming' Linux. Also: I've tested this on Irix 5.2, and there's
  no problems there.

  [Another scene: If I fully disable the server, and let the client send
  packs at full speed, with no attempt to receive, the sendto() may also
  fail with "Connection refused". This worked fine on DEC OSF/1 V2.1,
  SunOS 4.1.3_U1, ULTRIX 4.4 and Irix 5.2]

  My setup: Linux 1.2.0 with swap- and scheduler-patches for 1.1.95,
            gcc 2.6.2 and libc 4.6.27 running on a Dell 466/MX.

  Sverre H. Huseby <sverrehu@ifi.uio.no>           Oslo, 1995/3/17
  
 **************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>

#define SERV_HOST_ADDR "127.0.0.1"
#define SERV_UDP_PORT 5678
#define REPS 5

/* Undefine (comment out) the following to see the (?)bug */
#define CLIENT_RECV /**/

void client(void)
{
    int q, len, sock;
    char data[80];
    struct sockaddr_in cliaddr, srvaddr;
    
    printf("client started (sleeping 1 second)\n");
    sleep(1);
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("*** client socket()");
	exit(1);
    }
    memset(&cliaddr, 0, sizeof(cliaddr));
    cliaddr.sin_family = AF_INET;
    cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    cliaddr.sin_port = htons(0);
    if (bind(sock, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0) {
	perror("*** client bind()");
	exit(1);
    }
    memset(&srvaddr, 0, sizeof(srvaddr));
    srvaddr.sin_family = AF_INET;
    srvaddr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);
    srvaddr.sin_port = htons(SERV_UDP_PORT);
    for (q = 0; q < REPS; q++) {
	sprintf(data, "chunk #%d", q);
	len = strlen(data);
	printf("client: sending %d bytes: \"%s\"\n", len, data);
	if (sendto(sock, data, len, 0,
		   (struct sockaddr *) &srvaddr, sizeof(srvaddr)) < 0) {
	    perror("*** client send()");
	    continue;
	}
#ifdef CLIENT_RECV
	if ((len = recvfrom(sock, data, 80, 0, NULL, NULL)) < 0) {
	    perror("*** client recv()");
	    continue;
	}
	printf("client: received %d bytes: \"%s\"\n", len, data);
#endif
    }
    close(sock);
}

void server(void)
{
    int q, len, sock, clilen;
    char data[80] = "ok:";
    struct sockaddr_in cliaddr, srvaddr;

    printf("server started\n");
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("*** server socket()");
	exit(1);
    }
    memset(&srvaddr, 0, sizeof(srvaddr));
    srvaddr.sin_family = AF_INET;
    srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    srvaddr.sin_port = htons(SERV_UDP_PORT);
    if (bind(sock, (struct sockaddr *) &srvaddr, sizeof(srvaddr)) < 0) {
	perror("*** server bind()");
	exit(1);
    }
    for (q = 0; q < REPS; q++) {
	if ((len = recvfrom(sock, data + 3, 77, 0,
			    (struct sockaddr *) &cliaddr, &clilen)) < 0) {
	    perror("*** server recvfrom()");
	    continue;
	}
	data[len + 3] = '\0';
	printf("server: received %d bytes: \"%s\"\n", len, data + 3);
	printf("server: sending back %d bytes: \"%s\"\n", len + 3, data);
	if (sendto(sock, data, len + 3, 0,
		   (struct sockaddr *) &cliaddr, clilen) != len + 3)
	    perror("*** server sendto()");
    }
    close(sock);
}

int main(int argc, char *argv[])
{
    int status;
    
    if (fork()) {
	client();
	wait(&status);
    } else {
	server();
    }
    return 0;
}

home help back first fref pref prev next nref lref last post