several people mailed me, or asked me on-line, why they couldn't
connect to their local ircd on a linux box. Although this is a kernel
bug, I wrote a little patch for ircu2.9.30 that fixes the problem.
The problem occurs when we call
setsockopt(3, SOL_SOCKET, SO_RCVBUF, [8192], 4) = 0
for the socket that we use as listen port.
Because this is not necessary, this patch can be applied to all versions...
[ Note for the linux-kernel list :
Failure with:
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_RCVBUF, [8192], 4) = 0
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [8192], 4) = 0
bind(3, {sin_family=AF_INET, sin_port=htons(7002), sin_addr=inet_addr("0.0.0.0")
listen(3, 5) = 0
accept(3, 0, NULL) = 5
fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0
setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(5, SOL_SOCKET, SO_RCVBUF, [8192], 4) = 0
setsockopt(5, SOL_SOCKET, SO_SNDBUF, [8192], 4) = 0
select(256, [1 3 4 5], [], NULL, {36, 0}) = 0 (Timeout)
send(5, "ERROR :Closing Link: [127.0.0.1]"..., 83, 0) = 83
close(5) = 0
Success after removing the 'setsockopt(3, SOL_SOCKET, SO_RCVBUF, [8192], 4)':
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sin_family=AF_INET, sin_port=htons(7002), sin_addr=inet_addr("0.0.0.0")
listen(3, 5) = 0
accept(3, 0, NULL) = 5
fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0
setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(5, SOL_SOCKET, SO_RCVBUF, [8192], 4) = 0
setsockopt(5, SOL_SOCKET, SO_SNDBUF, [8192], 4) = 0
select(256, [1 3 4 5], [], NULL, {36, 0}) = 1 (in [5]) (left {35, 1234567})
read(5, "NICK Run2\nUSER carlo runaway lo"..., 64) = 51
end note linux-kernel ]
Run
PS I found a bug in libc-5.3.12 that lets gethostbyname() coredump under
certain circumstances (among which that the lookup must fail). Therefore,
this was tested with libc-5.2.18. I used kernel 1.3.90 because 1.3.97
is (still) broken when it comes to tracing (strace and gdb don't work).
--------------------------Knip Rip Scheur-------------------------------------
diff -rc ircu2.9.30.org/ircd/s_bsd.c ircu2.9.30.linux/ircd/s_bsd.c
*** ircu2.9.30.org/ircd/s_bsd.c Thu May 2 18:06:23 1996
--- ircu2.9.30.linux/ircd/s_bsd.c Fri May 3 23:05:27 1996
***************
*** 211,217 ****
int port;
{
static struct sockaddr_in server;
! int ad[4], len = sizeof(server);
char ipname[20];
#ifdef VIRTUAL_HOST
struct hostent *hep;
--- 211,217 ----
int port;
{
static struct sockaddr_in server;
! int ad[4], len = sizeof(server), opt;
char ipname[20];
#ifdef VIRTUAL_HOST
struct hostent *hep;
***************
*** 260,266 ****
(void)close(cptr->fd);
return -1;
}
! set_sock_opts(cptr->fd, cptr);
/*
* Bind a port to listen for new connections if port is non-null,
* else assume it is already open and try get something from it.
--- 260,270 ----
(void)close(cptr->fd);
return -1;
}
!
! opt = 1;
! setsockopt(cptr->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
! /* set_sock_opts(cptr->fd, cptr); */
!
/*
* Bind a port to listen for new connections if port is non-null,
* else assume it is already open and try get something from it.