Re: invalid argument in select() when peer socket is in FD_SET

2011-08-01 Thread Christoph P.U. Kukulies

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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 

#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 *);
voidexit  (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);
charhostname[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 = 500;   /* 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

0How 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

___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"


invalid argument in select() when peer socket is in FD_SET

2011-07-31 Thread 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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 

#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 *);
voidexit  (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);
charhostname[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 = 500;   /* 5 seconds */

printf("Server %s listening on port %d\n", thisHost->h_name, port);
memset((void *)array_of_fds, 0, (size_t) MAXFDS * 
sizeof(*array_of_fds));

nfds = ListenSocket + 1;
while (1) {
FD_ZERO(&readfds);
FD_SET(ListenSocket, &readfds);
for (i = 0; i < MAXFDS; i++) {
if (array_of_fds[i]) {
nfds = max(nfds, array_of_fds[i]) + 1;
FD_SET(array_of_fds[i], &readfds);
}
}
n = select(nfds, &readfds,
   (fd_set *) NULL, /* not interested in write */
   (fd_set *) NULL, /* ...or exceptions */
&tv);/* timeout */

switch (n) {

case 1:
clilen = sizeof(cli_addr);
/* first test if a new client has connected */
if (FD_ISSET(ListenSocket, &readfds)) {
newsockfd = accept(ListenSocket,
(struct sockaddr *)&cli_addr, &clilen);
if (enter(newsockfd)) /* socket of new connection is 
entered*/

printf("\n%d.connect! ", ++connect), fflush(stdout);
else
printf("too many connections"), exit(1);
sprintf(buf, "ENTERED %d of %d", 1, 10);
send(newsockfd, buf, USEDBUFSIZ, 0); /* send to t