Subject: socket SO_REUSEADDR not working
To: None <netbsd-help@NetBSD.org>
From: Prasanta Sadhukhan <Prasanta.Sadhukhan@Sun.COM>
List: netbsd-help
Date: 12/07/2006 18:16:39
This is a multi-part message in MIME format.

--Boundary_(ID_1USQsnuElXhQyDBjnqM5og)
Content-type: text/plain; format=flowed; charset=us-ascii
Content-transfer-encoding: 7BIT

Hi,

I am using the attached program.c#testreuseaddress(). I wanted to use 
the same address for different socket
but am getting errno=EADDRINUSE for netbsd for 2nd bind although for 
linux, there is no problem
Attached are the output from linux and netbsd

Can anyone point as to what I need to do extra for netbsd to make the 
address reusable?! Or is it a bug in netbsd?

Regards
Prasanta

--Boundary_(ID_1USQsnuElXhQyDBjnqM5og)
Content-type: text/x-csrc; name=program.c
Content-transfer-encoding: 7BIT
Content-disposition: inline; filename=program.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>

void testlinger();
void testreuseaddress();

int main(int argc, char *argv[])
{
//	testlinger();
	testreuseaddress();
}

void testlinger()
{
	int fd, ret, optlen;
	union {
		int i;
		struct linger ling;
	} optval;
	void *result;
	fd = socket(PF_INET, SOCK_DGRAM, 0);
	printf("socket fd %d\n", fd);
	
	struct linger ling;
	optval.ling.l_onoff = 1;
	optval.ling.l_linger = 32768;
	optlen = sizeof(optval.ling);
	ret = setsockopt(fd, SOL_SOCKET, SO_LINGER, (const void *)&optval, optlen);
	printf("setsockopt retval %d, optlen %d\n", ret,optlen);

	ret = getsockopt(fd, SOL_SOCKET, SO_LINGER, result, &optlen);
	printf("getsockopt retval %d\n", ret);
	printf("get linger onoff %d, linger value %d, optlen %d\n",
			((struct linger*)result)->l_onoff,
			((struct linger*)result)->l_linger, optlen);
}
	
void testreuseaddress()
{
	int fd, fd1, ret, optlen;
	union {
		int i;
		struct linger ling;
	} optval;
	struct sockaddr_in in;

	fd = socket(PF_INET, SOCK_DGRAM, 0);
	printf("socket fd %d\n", fd);

	memset((char *)&in, 0, sizeof(struct sockaddr_in));
	in.sin_addr.s_addr = htonl(0x819ee0e6); //inet_addr("129.158.224.230");
	in.sin_port = 57767;
	in.sin_family = AF_INET;
	
	optval.i = 1;
	optlen = sizeof(optval.i);
	ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, optlen);
	printf("setsockopt ret %d\n", ret);

	errno = 0;
	ret = bind(fd, (struct sockaddr *)&in, sizeof(struct sockaddr_in));
	printf("bind ret %d, errno %d\n", ret, errno);

	fd1 = socket(PF_INET, SOCK_DGRAM, 0);
	printf("2nd socket fd %d\n", fd1);
	
	optval.i = 1;
	optlen = sizeof(optval.i);
	ret = setsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, optlen);
	printf("setsockopt ret %d\n", ret);
	
	errno = 0;
	ret = bind(fd1, (struct sockaddr *)&in, sizeof(struct sockaddr_in));
	printf("2nd bind ret %d errno %d\n", ret, errno);
}

--Boundary_(ID_1USQsnuElXhQyDBjnqM5og)
Content-type: text/plain; name=linux.out
Content-transfer-encoding: 7BIT
Content-disposition: inline; filename=linux.out

socket fd 3
setsockopt ret 0
bind ret 0, errno 0
2nd socket fd 4
setsockopt ret 0
2nd bind ret 0 errno 0

--Boundary_(ID_1USQsnuElXhQyDBjnqM5og)
Content-type: text/plain; name=netbsd.out
Content-transfer-encoding: 7BIT
Content-disposition: inline; filename=netbsd.out

socket fd 3
setsockopt ret 0
bind ret 0, errno 0
2nd socket fd 4
setsockopt ret 0
2nd bind ret -1 errno 48

--Boundary_(ID_1USQsnuElXhQyDBjnqM5og)--