On Apr 22, 2014, at 8:53 AM, Jeff Trawick <[email protected]> wrote: > >> On Mon, Apr 21, 2014 at 1:17 PM, Brian J. France <[email protected]> >> wrote: >> Just ran into a issue where httpd can only set TCP_DEFER_ACCEPT to 1. >> >> apr_socket_opt_set will always set the option value to either 0/1, so even >> adding a directive in httpd to allow tweaking the value it can't get it to >> the raw setsockopt call via apr functions. >> >> Right now we rebuilt our own version of apr with a default of 60, but want >> to work on getting a patch to allow getting a httpd directive. >> >> Thoughts on how what to tweak in apr? Different apr_socket_opt_set type >> function for TCP_DEFER_ACCEPT? >> >> Brian > > apr_socket_opt_set() can theoretically handle non-flag values; see > APR_SO_SNDBUF/APR_SO_RCVBUF for examples.
Doh, this is my bad: on != one http://svn.apache.org/viewvc/apr/apr/trunk/network_io/unix/sockopt.c?view=markup#l113 For some reason I completely missed that. APR is fine, but httpd needs updated as it is hard coded to 1: rv = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, 1); Will move to the httpd list. > Here's my suggestion: > > * Fix the API (code+doc) in APR trunk (future 2.x) to respect the exact value > of the "on" parameter, as with APR_SO_SNDBUF/APR_SO_RCVBUF. > * Applications using APR 1.x that need to set a value other than 1: Use > apr_os_sock_get()+setsockopt() > * If you are so motivated: Add non-default compile flag for APR 1.x that > causes the value passed via apr_socket_opt_set(APR_TCP_DEFER_ACCEPT) to be > respected. > > We occasionally correct broken/limited API behavior that could conceivably > hurt some unknown piece of code somewhere on a minor version change, but it > seems simple enough for the APR 1.x app to handle directly rather than prereq > a certain APR version just for this minor tweak. > > --/-- > > What is the big picture? My Linux tcp man page says: > > TCP_DEFER_ACCEPT (since Linux 2.4) > Allow a listener to be awakened only when data arrives on the > socket. Takes an integer value (seconds), this can bound the > maximum number of attempts TCP will make to complete the > connection. This option should not be used in code intended to be > portable. > > I find that very unclear. "ACCEPT" and "listener...awakened" implies > something with the httpd/kernel interaction, and "complete the connection" is > peer/peer interaction. > > What happens if the 1 second timeout set now when setting > APR_TCP_DEFER_ACCEPT via APR expires? While the man page says it is seconds, it is not a true seconds value as it is translated into "maximum number of attempts TCP". So something like 10 seconds is 3-4 attempts, which could take longer than 10 seconds. > Drop connection without waking up server? This is the behavior up until RHEL 6.x. > Wake up server which then has to wait for data? This is what RHEL 6 is doing and whey we noticed the issue. Our kernel team is looking into what changed between RHEL 5 and RHEL 6 (even between 6.2 to 6.3 is different). Cheers, Brian > If it is "drop connection without waking up server" then IMO we need to > really fix APR 1.5.x in the same manner that I suggested for trunk. > > If it is "wake up server which then has to wait for data" then I wonder what > you really want. No data came for 30 or 60 (or whatever) seconds then the > server has to reach its own timeout before we get rid of the connection? Why > wait so long? The hard-coded 1 second timeout doesn't seem so bad here > (though in the fullness of time the app should choose the timeout). The > optimization for normal scenarios is working, and httpd+kernel both get > involved to clean up basket case connections. > > Maybe TCP_DEFER_ACCEPT does something else. > > I could test and see, but I'm ASSuming that you already know :) TIA for that! > > -- > Born in Roswell... married an alien... > http://emptyhammock.com/ > http://edjective.org/ >
