]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stream-interface: provide a generic stream_sock_read0() function
authorWilly Tarreau <wtarreau@exceliance.fr>
Mon, 20 Aug 2012 13:38:41 +0000 (15:38 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Sep 2012 19:54:55 +0000 (21:54 +0200)
This function is used by the data layer when a zero has been read over a
connection. At the moment it only handles sockets and nothing else. Once
the complete split is done between buffers and stream interfaces, it should
become possible to work regardless on the connection type.

include/proto/stream_interface.h
src/sock_raw.c
src/stream_interface.c

index 8a4cf3a2aeea6f0012b2785838e8969d96d11302..909d040961819451e565599cf851d77d2b45bf65 100644 (file)
@@ -42,6 +42,7 @@ int stream_int_shutw(struct stream_interface *si);
 void stream_int_chk_rcv_conn(struct stream_interface *si);
 void stream_int_chk_snd_conn(struct stream_interface *si);
 void si_conn_send_cb(struct connection *conn);
+void stream_sock_read0(struct stream_interface *si);
 
 extern struct sock_ops stream_int_embedded;
 extern struct sock_ops stream_int_task;
index 5b20f2ff59baf9c5ca141a522e06f2daf528836b..991b46b9f385535feba5b6b31163beeb704089e6 100644 (file)
@@ -44,7 +44,6 @@
 
 /* main event functions used to move data between sockets and buffers */
 static void sock_raw_read(struct connection *conn);
-static void sock_raw_read0(struct stream_interface *si);
 
 
 #if defined(CONFIG_HAP_LINUX_SPLICE)
@@ -436,7 +435,7 @@ static void sock_raw_read(struct connection *conn)
        b->flags |= BF_READ_NULL;
        if (b->flags & BF_AUTO_CLOSE)
                buffer_shutw_now(b);
-       sock_raw_read0(si);
+       stream_sock_read0(si);
        return;
 
  out_error:
@@ -591,55 +590,6 @@ static int sock_raw_write_loop(struct connection *conn)
 }
 
 
-/*
- * This function propagates a null read received on a connection. It updates
- * the stream interface. If the stream interface has SI_FL_NOHALF, we also
- * forward the close to the write side.
- */
-static void sock_raw_read0(struct stream_interface *si)
-{
-       si->ib->flags &= ~BF_SHUTR_NOW;
-       if (si->ib->flags & BF_SHUTR)
-               return;
-       si->ib->flags |= BF_SHUTR;
-       si->ib->rex = TICK_ETERNITY;
-       si->flags &= ~SI_FL_WAIT_ROOM;
-
-       if (si->state != SI_ST_EST && si->state != SI_ST_CON)
-               return;
-
-       if (si->ob->flags & BF_SHUTW)
-               goto do_close;
-
-       if (si->flags & SI_FL_NOHALF) {
-               /* 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.
-                */
-               if (si->flags & SI_FL_NOLINGER) {
-                       si->flags &= ~SI_FL_NOLINGER;
-                       setsockopt(si_fd(si), SOL_SOCKET, SO_LINGER,
-                                  (struct linger *) &nolinger, sizeof(struct linger));
-               }
-               goto do_close;
-       }
-
-       /* otherwise that's just a normal read shutdown */
-       conn_data_stop_recv(&si->conn);
-       return;
-
- do_close:
-       conn_data_close(&si->conn);
-       fd_delete(si_fd(si));
-       si->state = SI_ST_DIS;
-       si->exp = TICK_ETERNITY;
-       if (si->release)
-               si->release(si);
-       return;
-}
-
 /* stream sock operations */
 struct sock_ops sock_raw = {
        .update  = stream_int_update_conn,
index 6be0354e8dca4c6f6ebf8233c096b189ba7111c5..17f2447db1d7155594b982a3d5c50c17db1372e6 100644 (file)
@@ -898,6 +898,55 @@ void si_conn_send_cb(struct connection *conn)
        conn_data_stop_both(conn);
 }
 
+/*
+ * This function propagates a null read received on a socket-based connection.
+ * It updates the stream interface. If the stream interface has SI_FL_NOHALF,
+ * the close is also forwarded to the write side as an abort. This function is
+ * still socket-specific as it handles a setsockopt() call to set the SO_LINGER
+ * state on the socket.
+ */
+void stream_sock_read0(struct stream_interface *si)
+{
+       si->ib->flags &= ~BF_SHUTR_NOW;
+       if (si->ib->flags & BF_SHUTR)
+               return;
+       si->ib->flags |= BF_SHUTR;
+       si->ib->rex = TICK_ETERNITY;
+       si->flags &= ~SI_FL_WAIT_ROOM;
+
+       if (si->state != SI_ST_EST && si->state != SI_ST_CON)
+               return;
+
+       if (si->ob->flags & BF_SHUTW)
+               goto do_close;
+
+       if (si->flags & SI_FL_NOHALF) {
+               /* we want to immediately forward this close to the write side */
+               if (si->flags & SI_FL_NOLINGER) {
+                       si->flags &= ~SI_FL_NOLINGER;
+                       setsockopt(si_fd(si), SOL_SOCKET, SO_LINGER,
+                                  (struct linger *) &nolinger, sizeof(struct linger));
+               }
+               /* force flag on ssl to keep session in cache */
+               if (si->conn.data->shutw)
+                       si->conn.data->shutw(&si->conn, 0);
+               goto do_close;
+       }
+
+       /* otherwise that's just a normal read shutdown */
+       conn_data_stop_recv(&si->conn);
+       return;
+
+ do_close:
+       conn_data_close(&si->conn);
+       fd_delete(si_fd(si));
+       si->state = SI_ST_DIS;
+       si->exp = TICK_ETERNITY;
+       if (si->release)
+               si->release(si);
+       return;
+}
+
 
 /*
  * Local variables: