TCP FIN handling in linux kernel

Discussion in 'Linux Networking' started by patrick.mcgleenon, Nov 14, 2005.

  1. I'm running apache 1.3 on a redhat 2.4.21-27.ELsmp linux kernel. Using
    HTTP/1.1
    persistent connections, the apache server indicates to the client that
    the connection
    should be closed via the TCP FIN flag.

    Now I've seen that sometimes the TCP FIN is sent as a separate packet
    and sometimes it
    is piggybacked with the HTTP data.
    implementation in the linux kernel. Is there any way to force the
    sending of
    FIN as a separate packet? There is a problem with a certain client
    when it
    receives the FIN with HTTP data - ACKS the FIN and then sends RST. If
    it receives the FIN as a separate packet there are no problems

    thanks for any help

    Patrick
     
    patrick.mcgleenon, Nov 14, 2005
    #1
    1. Advertisements

  2. Yeah that sounds complicated, I was hoping for some system
    reconfiguration ;)

    I agree the client should be fixed but we have to work with what's
    out there...
    apache seems to have a home brew "lingering close" because according
    to the apache code:

    /*
    * More machine-dependent networking gooo... on some systems,
    * you've got to be *really* sure that all the packets are acknowledged
    * before closing the connection, since the client will not be able
    * to see the last response if their TCP buffer is flushed by a RST
    * packet from us, which is what the server's TCP stack will send
    * if it receives any request data after closing the connection.
    *
    * In an ideal world, this function would be accomplished by simply
    * setting the socket option SO_LINGER and handling it within the
    * server's TCP stack while the process continues on to the next
    request.
    * Unfortunately, it seems that most (if not all) operating systems
    * block the server process on close() when SO_LINGER is used.
    * For those that don't, see USE_SO_LINGER below. For the rest,
    * we have created a home-brew lingering_close.
    *
    * Many operating systems tend to block, puke, or otherwise mishandle
    * calls to shutdown only half of the connection. You should define
    * NO_LINGCLOSE in ap_config.h if such is the case for your system.
    */


    There's more some info in the apache docs at
    http://httpd.apache.org/docs/1.3/misc/fin_wait_2.html
     
    patrick.mcgleenon, Nov 15, 2005
    #2
    1. Advertisements

  3. patrick.mcgleenon

    Rick Jones Guest

    As you have already surmised, that certain client is FUBAR and needs
    to be patched. IIRC, the stacks which had this problem had patches
    for this a _long_ time ago... Alas, the realities of the marketplace
    suggest that sometimes the "right" thing to do cannot (or more likely
    will not) be done.

    I do not believe there is any way to force the FIN to be on a separate
    segment. At least not one where there is a _guarantee_ that it will
    be so.

    I suppose that if TCP_NODELAY were set on the TCP connection, and the
    server's last bit of real data to send wasn't delayed by say lack of
    receive or congestion window, the FIN would _probably_ be a separate
    segment. However, if that particular "bare FIN" were lost in addition
    to the previous data, the retransmissions of the FIN would most likely
    be piggybacked with the retransmitted data.

    Is your Apache waiting for the FIN reply from the remote, or is it
    simply calling close()?

    rick jones
     
    Rick Jones, Nov 15, 2005
    #3
  4. patrick.mcgleenon

    Rick Jones Guest

    Ever see those old Fram oil filter commercials? Any time I see
    pressure to take the expedient path I remember the tag line uttered by
    the automobile machanic - "You can pay me now, or you can pay me
    later." referring to the price of a new oil filter compared to the
    cost of repairing an engine.
    Still, I would hope that you have at least contacted the owner of the
    client to point-out to them how their system is FUBAR and should be
    patched.
    Probably some variant on:

    shutdown(SHUT_WR)
    select(...timeout)
    if not timeout read/recv/whatever
    else close

    I wonder if Apache2 or some other web server, open-source or
    otherwise, handles this any differently and/or if it would be less
    affected by the effects of the broken remote client - ie not tieing-up
    an entire process thanks to one busted client...

    rick jones
     
    Rick Jones, Nov 15, 2005
    #4
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.