From: Willy Tarreau Date: Tue, 29 Dec 2009 13:36:34 +0000 (+0100) Subject: [MINOR] stream_sock: add SI_FL_NOLINGER for faster close X-Git-Tag: v1.4-dev5~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4c283dce4b37472d16dfcb7215710c194365f182;p=thirdparty%2Fhaproxy.git [MINOR] stream_sock: add SI_FL_NOLINGER for faster close This new flag may be set by any user on a stream interface to tell the underlying protocol that there is no need for lingering on the socket since we know the other side either received everything or does not care about what we sent. This will typically be used with forced server close in HTTP mode, where we want to quickly close a server connection after receiving its response. Otherwise the system would prevent us from reusing the same port for some time. --- diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index a693497807..43e82c702c 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -1,23 +1,23 @@ /* - include/types/stream_interface.h - This file describes the stream_interface struct and associated constants. - - Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation, version 2.1 - exclusively. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * include/types/stream_interface.h + * This file describes the stream_interface struct and associated constants. + * + * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, version 2.1 + * exclusively. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ #ifndef _TYPES_STREAM_INTERFACE_H #define _TYPES_STREAM_INTERFACE_H @@ -70,6 +70,7 @@ enum { SI_FL_CAP_SPLTCP = 0x0010, /* splicing possible from/to TCP */ SI_FL_DONT_WAKE = 0x0020, /* resync in progress, don't wake up */ SI_FL_INDEP_STR = 0x0040, /* independant streams = don't update rex on write */ + SI_FL_NOLINGER = 0x0080, /* may close without lingering. One-shot. */ }; #define SI_FL_CAP_SPLICE (SI_FL_CAP_SPLTCP) diff --git a/src/stream_sock.c b/src/stream_sock.c index 89102adc06..a9bf47aeef 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -837,12 +837,20 @@ void stream_sock_shutw(struct stream_interface *si) /* we have to shut before closing, otherwise some short messages * may never leave the system, especially when there are remaining * unread data in the socket input buffer, or when nolinger is set. + * However, if SI_FL_NOLINGER is explicitly set, we know there is + * no risk so we close both sides immediately. */ - EV_FD_CLR(si->fd, DIR_WR); - shutdown(si->fd, SHUT_WR); + if (si->flags & SI_FL_NOLINGER) { + si->flags &= ~SI_FL_NOLINGER; + setsockopt(si->fd, SOL_SOCKET, SO_LINGER, + (struct linger *) &nolinger, sizeof(struct linger)); + } else { + EV_FD_CLR(si->fd, DIR_WR); + shutdown(si->fd, SHUT_WR); - if (!(si->ib->flags & (BF_SHUTR|BF_DONT_READ))) - return; + if (!(si->ib->flags & (BF_SHUTR|BF_DONT_READ))) + return; + } /* fall through */ case SI_ST_CON: