You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Ken Simpson <ks...@larch.mailchannels.com> on 2004/08/27 04:30:33 UTC
Unable to set sockets to non blocking on OpenBSD
(Preamble -- this problem was reported on the modperl mailing list
earlier this week; I was advised to post it here -- I hope I have come
to the right place!)
Before actually setting the blocking or nonblocking state of a socket
by making a system call, the apr_socket_opt_set() function first
checks whether its cached copy of the socket state indicates that the
blocking state needs to be changed:
/* network_io/unix/sockopt.c */
/* If the blocking state needs to be changed, then...
if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) != on) {
/* .. go ahead and toggle the blocking state */
}
Unfortunately, in APR, Unix sockets are assumed to initially be
blocking even though on OpenBSD this appears to not be true:
/* network_io/unix/sockets.c */
static void set_socket_vars(apr_socket_t *sock, int family,
int type, int protocol)
{
sock->type = type;
sock->protocol = protocol;
apr_sockaddr_vars_set(sock->local_addr, family, 0);
apr_sockaddr_vars_set(sock->remote_addr, family, 0);
sock->netmask = 0;
#if defined(BEOS) && !defined(BEOS_BONE)
/* BeOS pre-BONE has TCP_NODELAY on by default and it can't be
* switched off!
*/
sock->netmask |= APR_TCP_NODELAY;
#endif
}
(setting sock->netmask to 0 means that the socket is blocking)
So when you try to set a socket to blocking, Apache just skips your
request because.. obviously there's no need to set a blocking socket
to blocking again.
The permanent fix is to patch up set_socket_vars() that it sets
blocking off by default on OpenBSD; e.g.:
...
sock->netmask = 0;
sock->netmask |= APR_SO_NONBLOCK;
I'd love to put together a full patch, but I don't know what #define I
should #ifdef to check whether OpenBSD is the building platform. Can
someone tell me?
Thanks,
Ken
--
MailChannels: Imagine no more spam
http://www.mailchannels.com
Re: Unable to set sockets to non blocking on OpenBSD
Posted by Ken Simpson <ks...@larch.mailchannels.com>.
Joe Orton [28/08/04 13:15 +0100]:
> On Fri, Aug 27, 2004 at 03:07:44PM -0700, Ken Simpson wrote:
> > My mistake -- I didn't rerun ./buildconf.
> >
> > The patch ought to work.
>
> "Ought to work"... "might work"... "actually doesn't work" :)
>
> Have you tested it to work?
Yes, the patch has been tested to work.
TTUL
Ken
Re: Unable to set sockets to non blocking on OpenBSD
Posted by Joe Orton <jo...@redhat.com>.
On Fri, Aug 27, 2004 at 03:07:44PM -0700, Ken Simpson wrote:
> My mistake -- I didn't rerun ./buildconf.
>
> The patch ought to work.
"Ought to work"... "might work"... "actually doesn't work" :)
Have you tested it to work?
joe
Re: Unable to set sockets to non blocking on OpenBSD
Posted by Ken Simpson <ks...@larch.mailchannels.com>.
My mistake -- I didn't rerun ./buildconf.
The patch ought to work.
TTUL
Ken
Ken Simpson [27/08/04 14:47 -0700]:
> > I expect what you're seeing is that APR thinks that O_NONBLOCK is not
> > inherited across accept(), although it is on OpenBSD. There is a
> > configure test for this, but I bet it doesn't work because binding to an
> > ephemeral port doesn't work on OpenBSD IIRC.
> >
> > If you have all the necessary autofoo installed, you could try this
> > patch (then run ./buildconf):
> >
> > Index: build/apr_hints.m4
> > ===================================================================
> > RCS file: /home/cvs/apr/build/apr_hints.m4,v
> > retrieving revision 1.68
> > diff -u -r1.68 apr_hints.m4
> > --- build/apr_hints.m4 12 Aug 2004 13:44:29 -0000 1.68
> > +++ build/apr_hints.m4 27 Aug 2004 06:12:04 -0000
> > @@ -131,6 +131,7 @@
> > ;;
> > *-openbsd*)
> > APR_ADDTO(CPPFLAGS, [-D_POSIX_THREADS])
> > + APR_SETIFNULL(ac_cv_o_nonblock_inherited, [yes])
> > ;;
> > *-netbsd*)
> > APR_ADDTO(CPPFLAGS, [-DNETBSD])
>
> The patch doesn't seem to work -- my apr.h still says this after ./configure:
>
> /* Is the TCP_NODELAY socket option inherited from listening sockets?
> */
> #define APR_TCP_NODELAY_INHERITED 0
>
> I think it should set that #define to 1 -- am I right?
>
> Thanks,
> Ken
>
> --
> MailChannels: Imagine no more spam
>
> --
> http://www.mailchannels.com
> MailChannels Corporation
> Suite 1600, 1188 West Georgia St.
> Vancouver, BC, Canada
>
> Ken Simpson, CEO
> +1-604-729-1741
--
MailChannels: Imagine no more spam
--
http://www.mailchannels.com
MailChannels Corporation
Suite 1600, 1188 West Georgia St.
Vancouver, BC, Canada
Ken Simpson, CEO
+1-604-729-1741
Re: Unable to set sockets to non blocking on OpenBSD
Posted by Ken Simpson <ks...@larch.mailchannels.com>.
> I expect what you're seeing is that APR thinks that O_NONBLOCK is not
> inherited across accept(), although it is on OpenBSD. There is a
> configure test for this, but I bet it doesn't work because binding to an
> ephemeral port doesn't work on OpenBSD IIRC.
>
> If you have all the necessary autofoo installed, you could try this
> patch (then run ./buildconf):
>
> Index: build/apr_hints.m4
> ===================================================================
> RCS file: /home/cvs/apr/build/apr_hints.m4,v
> retrieving revision 1.68
> diff -u -r1.68 apr_hints.m4
> --- build/apr_hints.m4 12 Aug 2004 13:44:29 -0000 1.68
> +++ build/apr_hints.m4 27 Aug 2004 06:12:04 -0000
> @@ -131,6 +131,7 @@
> ;;
> *-openbsd*)
> APR_ADDTO(CPPFLAGS, [-D_POSIX_THREADS])
> + APR_SETIFNULL(ac_cv_o_nonblock_inherited, [yes])
> ;;
> *-netbsd*)
> APR_ADDTO(CPPFLAGS, [-DNETBSD])
The patch doesn't seem to work -- my apr.h still says this after ./configure:
/* Is the TCP_NODELAY socket option inherited from listening sockets?
*/
#define APR_TCP_NODELAY_INHERITED 0
I think it should set that #define to 1 -- am I right?
Thanks,
Ken
--
MailChannels: Imagine no more spam
--
http://www.mailchannels.com
MailChannels Corporation
Suite 1600, 1188 West Georgia St.
Vancouver, BC, Canada
Ken Simpson, CEO
+1-604-729-1741
Re: Unable to set sockets to non blocking on OpenBSD
Posted by Joe Orton <jo...@redhat.com>.
On Thu, Aug 26, 2004 at 07:30:33PM -0700, Ken Simpson wrote:
> Unfortunately, in APR, Unix sockets are assumed to initially be
> blocking even though on OpenBSD this appears to not be true:
I expect what you're seeing is that APR thinks that O_NONBLOCK is not
inherited across accept(), although it is on OpenBSD. There is a
configure test for this, but I bet it doesn't work because binding to an
ephemeral port doesn't work on OpenBSD IIRC.
If you have all the necessary autofoo installed, you could try this
patch (then run ./buildconf):
Index: build/apr_hints.m4
===================================================================
RCS file: /home/cvs/apr/build/apr_hints.m4,v
retrieving revision 1.68
diff -u -r1.68 apr_hints.m4
--- build/apr_hints.m4 12 Aug 2004 13:44:29 -0000 1.68
+++ build/apr_hints.m4 27 Aug 2004 06:12:04 -0000
@@ -131,6 +131,7 @@
;;
*-openbsd*)
APR_ADDTO(CPPFLAGS, [-D_POSIX_THREADS])
+ APR_SETIFNULL(ac_cv_o_nonblock_inherited, [yes])
;;
*-netbsd*)
APR_ADDTO(CPPFLAGS, [-DNETBSD])