Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 01 Aug 2011 17:09:37 +0200
From:      "Christoph P.U. Kukulies" <kuku@kukulies.org>
To:        freebsd-questions@freebsd.org
Subject:   Re: invalid argument in select() when peer socket is in FD_SET
Message-ID:  <4E36C1B1.4090708@kukulies.org>
In-Reply-To: <4E352563.2070808@kukulies.org>
References:  <4E352563.2070808@kukulies.org>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help
Am 31.07.2011 11:50, schrieb Christoph P.U. Kukulies:
> I have written a  small to test TCP/IP roundtrip times of the packets 
> in a proprietary protocol and while
> compiling and running this server on different platforms (Windows 
> 7/cygwin, UbuntuLinux, FreeBSD 8.0 Release), I found
> that the server produces an error when the listening socket (on which 
> the accpet() is performed) is member of the select()
> fd_set.
>
> On the other platforms the program works without error, just under 
> FreeBSD I'm getting this "invalid argument" error.
>
> Comments appreciated (despite comments about the error checking logic :)
>
> Here is the code:
> // testsrv.c
> //  gcc -o testsrv testsrv.c
> //
>
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <arpa/inet.h>
> #include <netdb.h>
> #include <string.h>
>
> #include <sys/select.h>
>
> #define USEDBUFSIZ 60
> #define MAX_HOSTNAME 256
> #define MAXFDS 256
> #define CLRBUF  memset(buf,0,sizeof(buf))
> #define max(a,b)        (((a) > (b)) ? (a) : (b))
> static unsigned char buf[256];
> int             array_of_fds[MAXFDS];
> static fd_set   clientfds;
> #define SOCKET int
> void           *memset(void *, int, size_t);
> int             enter      (int);
> int             remov      (int);
> int             invalidip  (char *);
> void            exit      (int);
> int             getv       (int, unsigned char *, int);
> int             getfds     ();
>
> int
> main(int argc, char **argv)
> {
>     int             nfds;
>     static fd_set   readfds;
>     SOCKET          ListenSocket, newsockfd;
>     struct sockaddr_in cli_addr;
>     struct sockaddr_in service;
>     struct hostent *thisHost;
>     int             bOptVal = 0;
>     int             bOptLen = sizeof(int);
>     char            hostname[256];
>     char           *host_addr;
>     struct in_addr  addr = {0};
>     char           *ip;
>     u_short         port;
>     int             iResult = 0;
>     int             i     , n, m, clilen, dummy, connect = 0;
>     struct timeval  tv;
>     //---------------------------------------
>         //Create a listening socket
>         ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
>     if (ListenSocket == -1) {
>         perror("socket creation");
>         return 1;
>     } else
>         printf("ListenSocket=%d\n", ListenSocket);
>     //---------------------------------------
>         //Bind the socket to the local IP address
>         // and port 3210
>         port = 3210;
>     if (gethostname(hostname, 256))
>         perror("gethostname failed\n"), exit(3);
>     printf("%s\n", hostname), fflush(stdout);
>     thisHost = gethostbyname(hostname);
>     ip = inet_ntoa(*(struct in_addr *)(*thisHost->h_addr_list));
>
>
>     if (argc == 2) {
>         host_addr = argv[1];
>         service.sin_addr.s_addr = inet_addr(host_addr);
>         thisHost = gethostbyaddr((const char *)&service.sin_addr.s_addr,
>                                  sizeof(service.sin_addr.s_addr), 
> AF_INET);
>         if (thisHost == 0)
>             printf("host unknown\n"), exit(3);
>         if (invalidip(host_addr))
>             printf("invalid IP\n"), exit(4);
>     } else {
>         service.sin_addr.s_addr = inet_addr(ip);
>     }
>     service.sin_port = htons(port);
>     service.sin_family = AF_INET;
>
>     iResult = bind(ListenSocket, (struct sockaddr *)&service, 
> sizeof(service));
>     if (iResult == -1) {
>         perror("bind");
>         shutdown(ListenSocket, SHUT_RDWR);
>         return 1;
>     }
>     listen(ListenSocket, SOMAXCONN);
>     printf("SOMAXCONN=%d %d\n", SOMAXCONN, FD_SETSIZE);
>     /* all sockets are put into an own array_of_fs */
>     /* in the while() loop below the FD_SET id used by looping through 
> the */
>     /* array_of_fds to fill the readfds array in the select() */
>
>     enter(ListenSocket);
>
>     /*
>      * Wait for connect
>      */
>     tv.tv_sec = 0;
>     tv.tv_usec = 5000000;       /* 5 seconds */
A friendly soul on FreeBSD-hackers told me that my
tv_usec value is wrong in the timeval struct above. FreeBSD checks if it 
is in the range of
0<tv_usec<1000000 and not negative.

How I came to think that the socket could be the invaid parameter, I 
don't know.
Maybe I did two changes to the code at once and was blaming the wrong one.

Thanks anyway for listening.
--
Christoph




Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?4E36C1B1.4090708>