Bug 39498

Summary: accept_filter in apr assumes if found in sys/socket.h it is loaded
Product: Apache httpd-2 Reporter: Otto Hirr <otto.hirr>
Component: BuildAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: RESOLVED LATER    
Severity: normal CC: pgollucci, taffy-tyler6464
Priority: P3 Keywords: MassUpdate
Version: 2.2.2   
Target Milestone: ---   
Hardware: Other   
OS: FreeBSD   

Description Otto Hirr 2006-05-06 03:58:57 UTC
Greeting,
srclib/apr/configure assumes that if SO_ACCEPTFILTER is defined in sys/socket.h 
that the kernel module is loaded. Upon httpd startup, there will be a warning 
message about unable to locate file or directory. Searching the web will 
indicate many people have encountered this problem. It would be more user 
friendly to provide a c routine that is compiled and run to test whether or not 
accept_filter is "really" available, not just that it is found in sys/socket.h. 
If it exists in the include file, but is unavailable, then it should be turned 
off, and emit a warning that if the accept_filter feature is wanted, then it 
needs to be loaded in the kernel and configure re-run.
Comment 1 Paul Querna 2006-05-07 06:46:15 UTC
- The message that is currently displayed is a warning, not an error.

- AFAIK, there isn't an easy way to 'test' for accept filters at runtime,
without actually trying to enable them on  a socket.... So... Im not sure what
behavoir change you would like?
Comment 2 Otto Hirr 2006-05-07 23:17:36 UTC
What I'm driving at is that configure makes a blind assumption that if 
SO_ACCEPTFILTER is defined, that it is available in the system, which is not 
the case. To be available, it either needs to be (1) manually loaded via 
kldload, or (2) loaded at boot time by having the administrator modify 
loader.conf, or (3) recompile the kernel and have it static within.

At configure time, prior to compilation of http source, the configure script 
could first check for SO_ACCEPTFILTER, then if it is defined, emit a small c 
program, compile, and observe the result to determine if it is REALLY 
available. Such a program as found below seems to make this determination. I 
ran it on one machine that had accf_http.ko loaded, and it ran with exit of 0, 
that is it was able to set the accept filter. Running on another machine that 
had the kernel module, but not loaded, resulted in the failure of setsockopt() 
with an errno of 2, which is the very thing that is being observed.

It is my belief that there are many people out there that compile up the code 
and expect it to work without emission of warnings. This kind of check at 
source compile time would clean this up. It could make a comment to the user 
attempting to compile httpd, that the option would be available, but is being 
turned off unless either the re-configure with the kernel module already loaded 
or forced via configure option.

/* Debugging of
    Failed to enable the '%s' Accept Filter
    is defined in server/listen.c
    the call is to apr_socket_accept_filter()
    defined in srclib/apr/network_io/unix/sockopt.c

 */
#include <sys/types.h>
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <netinet/in.h>
#include <errno.h>

main () {

    int sock;
    sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    if (sock < 0) {
        printf( "socket(): failed: errno: %d\n", errno );
        exit( -1 );
    }

    struct sockaddr_in saddr;
    bzero( &saddr, sizeof (saddr));
    saddr.sin_family      = AF_INET;
    saddr.sin_addr.s_addr = htonl( INADDR_ANY );
    saddr.sin_port        = 6543;

    if ( bind( sock, (struct sockaddr *) &saddr, sizeof(saddr)) ) {
        printf( "bind(): failed: errno: %d\n", errno );
        exit( -1 );
    }

    if ( listen( sock, 5 )) {
        printf( "listen(): failed: errno: %d\n", errno );
        exit( -1 );
    }

    struct accept_filter_arg af;
    bzero( &af, sizeof (af) );
    strncpy( af.af_name, "httpready",  16 );

    if ((setsockopt( sock, SOL_SOCKET, SO_ACCEPTFILTER,
          &af, sizeof (af) )) < 0) {
        printf( "setsocketopt(): failed: errno: %d\n", errno );
        exit( -1 );
    }
    exit( 0 );
}
Comment 3 Paul Querna 2006-05-08 01:12:03 UTC
I disagree that we should disable this feature via configure.

My personal feeling is that many admins do not even _know_ about accf_http.  Is
there a reason we shouldn't promote the use of it?
Comment 4 Garrett Rooney 2006-05-08 01:57:02 UTC
Just my two cents, it seems silly to disable this via a configure time check,
since it's quite possible for the module to be unloaded during configure but
available at runtime.
Comment 5 Otto Hirr 2006-05-08 06:55:30 UTC
>I disagree that we should disable this feature via configure.
>My personal feeling is that many admins do not even _know_ about accf_http.  Is
>there a reason we shouldn't promote the use of it?

Fine. Then lets put it in the doc. It is known also, but not well doc'd that 
the admin/user must explicitly load it in the kernel. Futhermore the non-
descript error message of file not found, is misleading. Gee if it said 
something more intellegent, like it probably needs to be loaded, (since that 
code was included because the token was found in the sys include file) it would 
futher the cause. I found several people that had posted on the net with this 
problem, but did not find a solution.

>Just my two cents, it seems silly to disable this via a configure time check,
>since it's quite possible for the module to be unloaded during configure but
>available at runtime.

That's fine too. Give the admin/user some info in the configure log file.

What I'm saying is that as it exists, it makes rash assumptions that if it is 
in the sys include file, that it exists and is available, which is not the case 
if it is not loaded, and emits a strange error message that a non-coder would 
not understand.

Furthermore I did not see an easy way to turn OFF this feature at configure 
time. Take a look at srclib/apr/configure, lines beginning at 41729 for version 
2.2.2, and there is no obvious flag that is tested that allows the user to turn 
it off. It simply uses the pre-compiler to test for the flag existance.

I'm trying to make this easier. Documentation would be a great help. By default 
it should compile correctly on a 'default' freebsd machine, which by default 
does not load the kernel module. Adding appropriate documentation would solve 
one problem, adding a flag to turn it off, even though it is found to exist in 
the sys include file solves the other. I had to hand edit an include file to 
turn it off. This is wrong. A flag in the configure file would be a correct 
method.
Comment 6 Ruediger Pluem 2006-05-08 10:32:22 UTC
Just add the following to your configuration file and things work fine even if
the kernel module is not loaded:

AcceptFilter http none
AcceptFilter https none
Comment 7 Otto Hirr 2006-05-08 16:22:01 UTC
>Just add...
>AcceptFilter http none
>AcceptFilter https none

Sorry, not true on freebsd 5.3. At startup it emits the following:

[Mon May 08 09:18:09 2006] [warn] (2)No such file or directory: Failed to 
enable the 'httpready' Accept Filter

and that is with the above AcceptFilter's set to none. If it is correctly 
turning on/off, then it must be seeing the above configure values after it is 
starting up the sockets... (I'm no expert, just reporting what I see.)
Comment 8 Paul Querna 2006-05-08 16:31:08 UTC
Disabling them works fine for me on FreeBSD 6.1.  Are you using httpd from the
ports?  Are you sure its not being overridden later on?
Comment 9 Otto Hirr 2006-05-08 17:51:18 UTC
>Disabling them works fine for me on FreeBSD 6.1.
I'm not there yet. My observation is on 5.3. Next will be 5.4.
So you are not getting any output of errors? Note that these errors
are not going to the error log, but are coming out on std[err|out] at start,
and one for each prefork process that is started.
>Are you using httpd from the ports?
No, I use what I download directly from the main site.
Specifically I am using 'httpd-2.2.2.tar.gz and md5 checksum verifies.
>Are you sure its not being overridden later on?
Overridden where? server info correctly identifies as 'none'.
Comment 10 Philp M. Gollucci 2009-01-18 16:19:11 UTC
CC myself on FreeBSD related bugs
Comment 11 William A. Rowe Jr. 2018-11-07 21:08:38 UTC
Please help us to refine our list of open and current defects; this is a mass update of old and inactive Bugzilla reports which reflect user error, already resolved defects, and still-existing defects in httpd.

As repeatedly announced, the Apache HTTP Server Project has discontinued all development and patch review of the 2.2.x series of releases. The final release 2.2.34 was published in July 2017, and no further evaluation of bug reports or security risks will be considered or published for 2.2.x releases. All reports older than 2.4.x have been updated to status RESOLVED/LATER; no further action is expected unless the report still applies to a current version of httpd.

If your report represented a question or confusion about how to use an httpd feature, an unexpected server behavior, problems building or installing httpd, or working with an external component (a third party module, browser etc.) we ask you to start by bringing your question to the User Support and Discussion mailing list, see [https://httpd.apache.org/lists.html#http-users] for details. Include a link to this Bugzilla report for completeness with your question.

If your report was clearly a defect in httpd or a feature request, we ask that you retest using a modern httpd release (2.4.33 or later) released in the past year. If it can be reproduced, please reopen this bug and change the Version field above to the httpd version you have reconfirmed with.

Your help in identifying defects or enhancements still applicable to the current httpd server software release is greatly appreciated.