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

Bug#614378: marked as done (libc6: Select()don't work properly on squeeze amd64)



Your message dated Mon, 21 Feb 2011 20:28:28 +0100
with message-id <20110221192828.GA8794@hall.aurel32.net>
and subject line Re: Bug#614378: libc6: Select()don't work properly on squeeze amd64
has caused the Debian Bug report #614378,
regarding libc6: Select()don't work properly on squeeze amd64
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
614378: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=614378
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: libc6
Version: 2.11.2-10
Severity: important



/ Author : L.Sillari
// Date: 17/02/2011

// This example show a bug on debian 6 64 bit .
// using nonblocking socket .
// On this example the code must run forever if you use an unknown destination.
// On Debina 6 64bit that not appen .. after the same time it stop because of "Select()" (the Select returns 1 and not 0) .
// No problem using Debian 6 32bit or Debian 5 64 bit

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>



    int sockfd; // Global variable
    main(int argc, char *argv[])
{

    //socket structure
    struct sockaddr_in serv_addr;
    struct hostent *server;
    int opts; // Socket Option
    int value=1;

    int _port=35; // TCP port 
    


    /// Open  socket 
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
    	/// Error opening socket
        printf("\n Error on socket() exit.\n");
	    exit(1);
    }

    /// NonBlocking socket setup
    opts = fcntl(sockfd, F_GETFL, 0);
    if (opts!=-1) 
    {
    	opts=fcntl(sockfd, F_SETFL, opts | O_NONBLOCK);
    }
    if (opts==-1)
    {
    	/// Error
        printf("\n Error on fcntl()\n");
	    exit(1);
    }

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value)) < 0) 
{
        printf("\n Error on setsockopt()\n");
	    exit(1);
}

    /// Put an unknown address to verify the bug
    server = gethostbyname("192.168.79.110");
    if (server == NULL) 
    {
    	/// Error
        printf("\n Error on gethostbyname()\n");
	    exit(1);
    }
    memset((char *) &serv_addr, 0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    memcpy((char *)&serv_addr.sin_addr.s_addr,(char *)server->h_addr, server->h_length);
    serv_addr.sin_port = htons(_port);


    /// NONBLOCKING Connection 
    //opts=connect(sockfd,(const sockaddr *)&serv_addr,sizeof(serv_addr));
     opts=connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
    if ((opts < 0 ) && (errno != EINPROGRESS))
    {
        printf("\n Error on connect()\n");
        exit(1);
    }

    while (waitConnection(100) == 0)  // We poll the connection ..
    {
        printf("WaitConnection \n");
    }
    printf("\n This is the bug: on Debian 6 squeeze(64bit) not on Debian 5 Lenny(64bit) \n");
}


int waitConnection(int _ms)
{
    // wait the connection
    extern int sockfd;
    struct timeval tv;
    int retval;
    int valopt;
     socklen_t len;


    /// Connection handle
    fd_set cnds;
    FD_ZERO(&cnds);


    /// Init Timeout
    tv.tv_sec = 0;
    tv.tv_usec = _ms * 1000;

    FD_SET(sockfd,&cnds);

    /// Wait on the select.
    /// to verify the connection : writing channel
    retval = select(sockfd+1, NULL, &cnds, NULL , &tv);


    /// Error
    if ( retval < 0 ) 
    {
        printf("\n Error on select ... \n");
        exit(1);
    }

    /// Something appened
    if ( retval > 0 )
    {
	if ( FD_ISSET(sockfd,&cnds) )
		{
		
			//Error check
			
			len=sizeof(valopt);
			if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &len) < 0) return 0;
			if (valopt!=0) return 0;
			printf("\n Wrong event : the destination doesn't exist but it seems connected !!!\n");
			return 1;
		}
    }
    return 0;
}





-- System Information:
Debian Release: 6.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.32-5-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libc6 depends on:
ii  libc-bin                      2.11.2-10  Embedded GNU C Library: Binaries
ii  libgcc1                       1:4.4.5-8  GCC support library

libc6 recommends no packages.

Versions of packages libc6 suggests:
ii  debconf [debconf-2.0]         1.5.36.1   Debian configuration management sy
pn  glibc-doc                     <none>     (no description available)
ii  locales                       2.11.2-10  Embedded GNU C Library: National L

-- debconf information:
  glibc/upgrade: true
  glibc/disable-screensaver:
  glibc/restart-failed:
  glibc/restart-services:



--- End Message ---
--- Begin Message ---
On Mon, Feb 21, 2011 at 04:06:53PM +0100, Luca Sillari wrote:
> Package: libc6
> Version: 2.11.2-10
> Severity: important
> 
> 
> 
> / Author : L.Sillari
> // Date: 17/02/2011
> 
> // This example show a bug on debian 6 64 bit .
> // using nonblocking socket .
> // On this example the code must run forever if you use an unknown destination.
> // On Debina 6 64bit that not appen .. after the same time it stop because of "Select()" (the Select returns 1 and not 0) .
> // No problem using Debian 6 32bit or Debian 5 64 bit
> 

Actually the "issue" is present for both 32 or 64-bit, it simply depends
on the kernel version, no on the libc version. On old kernels (like the 
2.6.26 in lenny), the connection never timeouts, so WaitConnection is 
printed indefinitely. On recent kernels (like in squeeze), select 
returns 1 to return an  error, which can get catched with getsockopt().
In this case it is returning ETIMEDOUT. Your code call getsockopt(), but
doesn't stop the loop in case of error. Replacing the return 0 by
exit(0) should fix your "issue".

Note the timeout can have different values depending on the network
configuration, routers and so on.

-- 
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net


--- End Message ---

Reply to: