misc/124160: connect() function loops indefinitely

Alexander Pavlov lup.mail at gmail.com
Sat May 31 11:10:01 UTC 2008


>Number:         124160
>Category:       misc
>Synopsis:       connect() function loops indefinitely
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat May 31 11:10:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Alexander Pavlov
>Release:        6.3-RELEASE
>Organization:
JSC Apriko
>Environment:
FreeBSD torment.skynet 6.3-RELEASE-p1 FreeBSD 6.3-RELEASE-p1 #3: Sun Mar  9 11:59:41 UTC 2008     lup at torment.skynet:/usr/obj/usr/src/sys/CLONED-CORE  i386
>Description:
I have a number of Intel platforms running FreeBSD 6.3-Release (using mpd-5.1, ipfw,ipnat).
Under some circumstances, at arbitrary time, my FreeBSD boxes stop responding to connection requests, but still remain up and running, so I can log in locally. In such state, major network functions are not working: I can't launch ngctl - it simply hangs, I can't add static arp entry - arp also hangs, and so on. I do not even see replies to ping 127.0.0.1 requests.
Trying to find clues to this problem, I wrote small program (in attach to this PR), which in normal state gives such output:
=================
inet socket testing..
1 4510 => server: creating listening socket
4510 => server: bind() ok
4510 => server: listen() ok
2 4511 => client: connecting..
4511 => client: socket() ok
4511 => client: trying to connect()..
4511 => client: connect() ok
3 4510 => server: client connected
4 4510 => server: send: "Anybody here?", res=13, errno=0
5 4511 => client: recieved: "Anybody here?", res=13, errno=0
6 4511 => client: send: "I am.", res=256, errno=0
7 4510 => server: recieved: "I am.", res=256, errno=0
=================
While in "hanged" state it gives:
=================
inet socket testing..
1 97262 => server: creating listening socket
97262 => server: bind() ok
97262 => server: listen() ok
2 97263 => client: connecting..
97263 => client: socket() ok
97263 => client: trying to connect()..
=================
and hangs until killed.
>How-To-Repeat:
It's a pity, but I don't know. In my environment it happens almost daily.
>Fix:


Patch attached with submission follows:

#include <stand.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <netinet/in.h>

#define send_str "Anybody here?"
#define	answer_str "I am."
#define server_port 631
#define listenq 1024

int main()
{ 
    int 	sockets[2];
    char 	buf[256];
    int 	pid;
    int		res;
    
    int			listenfd,connfd;
    struct sockaddr_in	clientaddr,serveraddr;

    printf("inet socket testing..\n");
    
    if (fork() != 0) {

	printf("1 %d => server: creating listening socket\n",getpid());
	listenfd = socket(AF_INET,SOCK_STREAM,0);
	if (listenfd<0) printf("%d => server: socket() error: %d\n",getpid(),errno);
	
	bzero(&serveraddr, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
	serveraddr.sin_port = htons(server_port);

	res = bind(listenfd,(struct sockaddr *) &serveraddr,sizeof(serveraddr));
	if (res<0) {printf("%d => server: bind() error: %d\n",getpid(),errno); } else {printf("%d => server: bind() ok\n",getpid());}
	res = listen(listenfd, listenq);
	if (res<0) {printf("%d => server: listen() error: %d\n",getpid(),errno);} else {printf("%d => server: listen() ok\n",getpid());}

	while (connfd <= 0) {
	    connfd = accept(listenfd, (struct sockaddr *) NULL, NULL);
	    if (connfd > 0) printf("3 %d => server: client connected\n",getpid());
	    res = write(connfd, send_str, strlen(send_str));
	    printf("4 %d => server: send: \"%s\", res=%d, errno=%d\n",getpid(), send_str,res,errno);
	    wait(NULL);
	    res = read(connfd, buf, sizeof(buf));
	    printf("7 %d => server: recieved: \"%s\", res=%d, errno=%d\n",getpid(), buf,res,errno);
	    close(connfd);
	}

	close(listenfd);
	exit(0);

    } else {

	printf("2 %d => client: connecting..\n",getpid());
	connfd = socket(AF_INET,SOCK_STREAM,0);
	if (connfd<0) {printf("%d => client: socket() error: %d\n",getpid(),errno);} else {printf("%d => client: socket() ok\n",getpid());}

	bzero(&serveraddr, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	inet_pton(AF_INET, "127.0.0.1", &serveraddr.sin_addr);
	serveraddr.sin_port = htons(server_port);

	printf("%d => client: trying to connect()..\n",getpid());
	res = connect(connfd,(struct sockaddr *) &serveraddr,sizeof(serveraddr));
	if (res<0) {printf("%d => client: connect() error: %d\n",getpid(),errno);} else {printf("%d => client: connect() ok\n",getpid());}

	res = read(connfd, buf, sizeof(buf));
	printf("5 %d => client: recieved: \"%s\", res=%d, errno=%d\n",getpid(), buf,res,errno);
	res = write(connfd, answer_str, sizeof(buf));
	printf("6 %d => client: send: \"%s\", res=%d, errno=%d\n",getpid(), answer_str,res,errno);
	
	close(connfd);
	exit(0);

    }
    
    return(0);
}


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list