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])