connection.c revision 9bec939825399ac2816ea0d912d2e3c3b2ed91f4
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz/* Licensed to the Apache Software Foundation (ASF) under one or more
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz * contributor license agreements. See the NOTICE file distributed with
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * this work for additional information regarding copyright ownership.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * The ASF licenses this file to You under the Apache License, Version 2.0
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * (the "License"); you may not use this file except in compliance with
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * the License. You may obtain a copy of the License at
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * limitations under the License.
d4f1d9c1ff112a8ab9bee31f196973761329b236rbbAP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection,
7fae9cc4639013f3c04c085547256c68814aee8ftrawick (apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh, apr_bucket_alloc_t *alloc),
7fae9cc4639013f3c04c085547256c68814aee8ftrawickAP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED)
7fae9cc4639013f3c04c085547256c68814aee8ftrawickAP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c, void *csd),(c, csd),OK,DECLINED)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * More machine-dependent networking gooo... on some systems,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * you've got to be *really* sure that all the packets are acknowledged
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * before closing the connection, since the client will not be able
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * to see the last response if their TCP buffer is flushed by a RST
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * packet from us, which is what the server's TCP stack will send
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * if it receives any request data after closing the connection.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * In an ideal world, this function would be accomplished by simply
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * setting the socket option SO_LINGER and handling it within the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * server's TCP stack while the process continues on to the next request.
785be1b6298010956622771c870ab3cd8ca57a2faaron * Unfortunately, it seems that most (if not all) operating systems
785be1b6298010956622771c870ab3cd8ca57a2faaron * block the server process on close() when SO_LINGER is used.
785be1b6298010956622771c870ab3cd8ca57a2faaron * For those that don't, see USE_SO_LINGER below. For the rest,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * we have created a home-brew lingering_close.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Many operating systems tend to block, puke, or otherwise mishandle
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * calls to shutdown only half of the connection. You should define
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * NO_LINGCLOSE in ap_config.h if such is the case for your system.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* FLUSH bucket */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* End Of Connection bucket */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* we now proceed to read from the client until we get EOF, or until
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * MAX_SECS_TO_LINGER has passed. the reasons for doing this are
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * documented in a draft:
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * in a nutshell -- if we don't make this effort we risk causing
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * TCP RST packets to be sent which can tear down a connection before
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * all the response data has been sent to the client.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_update_child_status(c->sbh, SERVER_CLOSING, NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Close the connection, being careful to send out whatever is still
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * in our buffers. If possible, try to avoid a hard close until the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * client has ACKed our FIN and/or has stopped sending us data.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Send any leftover data to the client, but never try to again */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Shut down the socket for write, which will send a FIN
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * to the peer.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (apr_socket_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Read available data from the client whilst it continues sending
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * it, for a maximum time of MAX_SECS_TO_LINGER. If the client
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * does not send any data within 2 seconds (a value pulled from
e8f95a682820a599fe41b22977010636be5c2717jim * Apache 1.3 which seems to work well), give up.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_socket_timeout_set(csd, apr_time_from_sec(SECONDS_TO_LINGER));
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick /* The common path here is that the initial apr_socket_recv() call
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick * will return 0 bytes read; so that case must avoid the expensive
58fd79b56eb624bf011772994e9761d3c2e228c1orlikowski * apr_time_now() call and time arithmetic. */
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick if (apr_socket_recv(csd, dummybuf, &nbytes) || nbytes == 0)
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames * First time through;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames * calculate now + 30 seconds (MAX_SECS_TO_LINGER).
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames * If some module requested a shortened waiting period, only wait for
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames * 2s (SECONDS_TO_LINGER). This is useful for mitigating certain
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames * DoS attacks.
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames if (apr_table_get(c->notes, "short-lingering-close")) {
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames timeup = apr_time_now() + apr_time_from_sec(SECONDS_TO_LINGER);
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick timeup = apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER);