Problem with sockets

Oliver Elphick (olly@linda.lfix.co.uk)
Tue, 03 Dec 1996 09:49:09 +0000


I came across this problem while trying to get INN to work.

Setup:
Kernel: 2.1.13
Libc: 5.4.12
gcc: 2.7.2.1
binutils: 2.7.0.3

This program reproduces the problem every time:
/* trysock.c

To test opening of socket with reused address

*/

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <syslog.h>

int
main()
{
struct sockaddr_in server;
register int i;
register int j;
int on;
int result;

(void)openlog("trysock", LOG_PERROR & LOG_PID, LOG_USER);


/* Create a socket and name it. */
if ((i = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
syslog(LOG_ERR, "trysock cant socket %m");
exit(1);
}
on = 1;
if (setsockopt(i, SOL_SOCKET, SO_REUSEADDR, (caddr_t)&on, sizeof on) < 0)
syslog(LOG_ERR, "trysock cant setsockopt %m");
(void)memset((void *)&server, 0, sizeof server);
server.sin_port = htons(119);
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
on = 0;
getsockopt(i, SOL_SOCKET, SO_REUSEADDR, (caddr_t)&on, (int *) sizeof on);
printf("SO_REUSEADDR value is %d\n",on);
on = 1;
getsockopt(i, SOL_SOCKET, SO_REUSEADDR, (caddr_t)&on, (int *) sizeof on);
printf("SO_REUSEADDR value is %d\n",on);
result = (bind(i, (struct sockaddr *)&server, sizeof server));
if (result < 0) {
syslog(LOG_ERR, "trysock cannot bind %m");
exit(1);
}
}

bind() always fails with the message "Address in use"

getsockopt(), according to the manual page, should return the value of the
specified option in the fourth parameter. In fact, this is unchanged; the
output of the program is:
SO_REUSEADDR value is 0
SO_REUSEADDR value is 1

I have followed this in the debugger through the libc code, which looks
OK. The problem appears to be in the system call itself, but I don't
know how to use the debugger on the kernel.