diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index a69349780..43e82c702 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 89102adc0..a9bf47aee 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: