dgaudet     98/02/16 17:45:59

  Modified:    src      CHANGES http_main.c
  Log:
  Increase the robustness of the child_main loop.  When unexpected
  select() or accept() errors occur we exit() the child.  This deals
  with many reported problems where apache would fill the error_log
  with messages.
  
  PR:           1747, 1107, 588, 1787, 987, 588
  
  Revision  Changes    Path
  1.296     +5 -0      apache-1.2/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.2/src/CHANGES,v
  retrieving revision 1.295
  retrieving revision 1.296
  diff -u -r1.295 -r1.296
  --- CHANGES   1998/02/14 13:42:44     1.295
  +++ CHANGES   1998/02/17 01:45:57     1.296
  @@ -1,5 +1,10 @@
   Changes with Apache 1.2.6
   
  +  *) Increase the robustness of the child_main loop.  When unexpected
  +     select() or accept() errors occur we exit() the child.  This deals
  +     with many reported problems where apache would fill the error_log
  +     with messages.  [Dean Gaudet] PR#1747, 1107, 588, 1787, 987, 588
  +
     *) PORT: Add -lm to LIBS for HPUX.  [Dean Gaudet] PR#1639
   
     *) SECURITY: "UserDir /abspath" without a * in the path would allow
  
  
  
  1.151     +62 -15    apache-1.2/src/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.2/src/http_main.c,v
  retrieving revision 1.150
  retrieving revision 1.151
  diff -u -r1.150 -r1.151
  --- http_main.c       1998/01/30 09:13:55     1.150
  +++ http_main.c       1998/02/17 01:45:58     1.151
  @@ -1781,14 +1781,14 @@
   
               errno = errsave;
               if (srv < 0 && errno != EINTR) {
  -#ifdef LINUX
  -             if (errno == EFAULT) {
  -                 log_unixerr("select", "(listen) fatal, exiting",
  -                             NULL, server_conf);
  -                 exit(1);
  -             }
  -#endif
  +             /* Single Unix documents select as returning errnos
  +              * EBADF, EINTR, and EINVAL... and in none of those
  +              * cases does it make sense to continue.  In fact
  +              * on Linux 2.0.x we seem to end up with EFAULT
  +              * occasionally, and we'd loop forever due to it.
  +              */
                   log_unixerr("select", "(listen)", NULL, server_conf);
  +             exit(1);
            }
   
               if (srv <= 0)
  @@ -1819,15 +1819,62 @@
               if (csd >= 0)
                   break;      /* We have a socket ready for reading */
               else {
  -
  -#if defined(EPROTO) && defined(ECONNABORTED)
  -              if ((errno != EPROTO) && (errno != ECONNABORTED))
  -#elif defined(EPROTO)
  -              if (errno != EPROTO)
  -#elif defined(ECONNABORTED)
  -              if (errno != ECONNABORTED)
  +             /* Our old behaviour here was to continue after accept()
  +              * errors.  But this leads us into lots of troubles
  +              * because most of the errors are quite fatal.  For
  +              * example, EMFILE can be caused by slow descriptor
  +              * leaks (say in a 3rd party module, or libc).  It's
  +              * foolish for us to continue after an EMFILE.  We also
  +              * seem to tickle kernel bugs on some platforms which
  +              * lead to never-ending loops here.  So it seems best
  +              * to just exit in most cases.
  +              */
  +                switch (errno) {
  +#ifdef EPROTO
  +                 /* EPROTO on certain older kernels really means
  +                  * ECONNABORTED, so we need to ignore it for them.
  +                  * See discussion in new-httpd archives nh.9701
  +                  * search for EPROTO.
  +                  *
  +                  * Also see nh.9603, search for EPROTO:
  +                  * There is potentially a bug in Solaris 2.x x<6,
  +                  * and other boxes that implement tcp sockets in
  +                  * userland (i.e. on top of STREAMS).  On these
  +                  * systems, EPROTO can actually result in a fatal
  +                  * loop.  See PR#981 for example.  It's hard to
  +                  * handle both uses of EPROTO.
  +                  */
  +                case EPROTO:
  +#endif
  +#ifdef ECONNABORTED
  +                case ECONNABORTED:
  +#endif
  +                 /* Linux generates the rest of these, other tcp
  +                  * stacks (i.e. bsd) tend to hide them behind
  +                  * getsockopt() interfaces.  They occur when
  +                  * the net goes sour or the client disconnects
  +                  * after the three-way handshake has been done
  +                  * in the kernel but before userland has picked
  +                  * up the socket.
  +                  */
  +#ifdef ECONNRESET
  +                case ECONNRESET:
   #endif
  -                log_unixerr("accept", "(client socket)", NULL, server_conf);
  +#ifdef ETIMEDOUT
  +                case ETIMEDOUT:
  +#endif
  +#ifdef EHOSTUNREACH
  +             case EHOSTUNREACH:
  +#endif
  +#ifdef ENETUNREACH
  +             case ENETUNREACH:
  +#endif
  +                    break;
  +
  +             default:
  +                 log_unixerr("accept", "(client socket)", NULL, server_conf);
  +                 exit(1);
  +             }
               }
   
            /* go around again, safe to die */
  
  
  

Reply via email to