--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: libc6: Select()don't work properly on squeeze amd64
- From: Luca Sillari <l.sillari@prc-el.it>
- Date: Mon, 21 Feb 2011 16:06:53 +0100
- Message-id: <20110221150653.2562.29192.reportbug@SRV1>
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 ---
- To: Luca Sillari <l.sillari@prc-el.it>, 614378-done@bugs.debian.org
- Subject: Re: Bug#614378: libc6: Select()don't work properly on squeeze amd64
- From: Aurelien Jarno <aurelien@aurel32.net>
- Date: Mon, 21 Feb 2011 20:28:28 +0100
- Message-id: <20110221192828.GA8794@hall.aurel32.net>
- In-reply-to: <20110221150653.2562.29192.reportbug@SRV1>
- References: <20110221150653.2562.29192.reportbug@SRV1>
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 ---