You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by "Brian J. France" <br...@brianfrance.com> on 2014/04/21 19:17:38 UTC

apr_socket_opt_set always sets TCP_DEFER_ACCEPT to 1

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

Re: apr_socket_opt_set always sets TCP_DEFER_ACCEPT to 1

Posted by "Brian J. France" <br...@brianfrance.com>.
On Apr 30, 2014, at 5:59 AM, Yann Ylavic <yl...@gmail.com> wrote:

> On Tue, Apr 29, 2014 at 5:41 PM, Jim Jagielski <ji...@jagunet.com> wrote:
>> 
>> On Apr 22, 2014, at 9:43 AM, Brian J. France <br...@brianfrance.com> wrote:
>>> 
>>> 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.
>> 
>> 
>> Did I miss this on dev@httpd?


No, you didn't miss it.  Got tied up with other stuff at work and didn't get back to it.

Was also looking at what it would take patch httpd before posting.



> I seems that httpd trunk and 2.4.x use "apr_socket_opt_set(s,
> APR_TCP_DEFER_ACCEPT, 30);" whereas 2.2.x uses a value of 1.


This is kinda good news.

Brian

Re: apr_socket_opt_set always sets TCP_DEFER_ACCEPT to 1

Posted by Yann Ylavic <yl...@gmail.com>.
On Tue, Apr 29, 2014 at 5:41 PM, Jim Jagielski <ji...@jagunet.com> wrote:
>
> On Apr 22, 2014, at 9:43 AM, Brian J. France <br...@brianfrance.com> wrote:
>>
>> 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.
>
>
> Did I miss this on dev@httpd?

I seems that httpd trunk and 2.4.x use "apr_socket_opt_set(s,
APR_TCP_DEFER_ACCEPT, 30);" whereas 2.2.x uses a value of 1.

Re: apr_socket_opt_set always sets TCP_DEFER_ACCEPT to 1

Posted by Jim Jagielski <ji...@jaguNET.com>.
On Apr 22, 2014, at 9:43 AM, Brian J. France <br...@brianfrance.com> wrote:
> 
> 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.


Did I miss this on dev@httpd?

Re: apr_socket_opt_set always sets TCP_DEFER_ACCEPT to 1

Posted by "Brian J. France" <br...@brianfrance.com>.
On Apr 22, 2014, at 8:53 AM, Jeff Trawick <tr...@gmail.com> wrote:
> 
>> On Mon, Apr 21, 2014 at 1:17 PM, Brian J. France <br...@brianfrance.com> 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/
> 


Re: apr_socket_opt_set always sets TCP_DEFER_ACCEPT to 1

Posted by Jeff Trawick <tr...@gmail.com>.
On Mon, Apr 21, 2014 at 1:17 PM, Brian J. France <br...@brianfrance.com>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.

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?  Drop connection without waking up
server?  Wake up server which then has to wait for data?

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/