aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--tcp.c33
-rw-r--r--tcp_conn.h3
-rw-r--r--tcp_splice.c20
3 files changed, 26 insertions, 30 deletions
diff --git a/tcp.c b/tcp.c
index 0a613e9..67f7fb8 100644
--- a/tcp.c
+++ b/tcp.c
@@ -1398,29 +1398,36 @@ static int tcp_send_flag(const struct ctx *c, struct tcp_tap_conn *conn,
}
/**
- * tcp_sock_rst() - Close TCP connection forcing RST on socket side
- * @c: Execution context
- * @conn: Connection pointer
+ * tcp_linger0_() - Set SO_LINGER with 0 timeout on socket
+ * @f: Flow header (only for debug logging)
+ * @s: Socket to modify
*/
-static void tcp_sock_rst(const struct ctx *c, struct tcp_tap_conn *conn)
+void tcp_linger0_(const struct flow_common *f, int s)
{
const struct linger linger0 = {
.l_onoff = 1,
.l_linger = 0,
};
- /* Force RST on socket to inform the peer
- *
- * We do this by setting SO_LINGER with 0 timeout, which means that
- * close() will send an RST (unless the connection is already closed in
- * both directions).
+ /* Setting SO_LINGER with 0 timeout, means that close() will send an RST
+ * (unless the connection is already closed in both directions).
*/
- if (setsockopt(conn->sock, SOL_SOCKET,
- SO_LINGER, &linger0, sizeof(linger0)) < 0) {
- flow_dbg_perror(conn,
- "SO_LINGER failed, may not send RST to peer");
+ if (setsockopt(s, SOL_SOCKET, SO_LINGER,
+ &linger0, sizeof(linger0)) < 0) {
+ flow_log_perror_(f, LOG_DEBUG,
+ "SO_LINGER failed, may not send RST to peer");
}
+}
+/**
+ * tcp_sock_rst() - Close TCP connection forcing RST on socket side
+ * @c: Execution context
+ * @conn: Connection pointer
+ */
+static void tcp_sock_rst(const struct ctx *c, struct tcp_tap_conn *conn)
+{
+ /* Force RST on socket to inform the peer */
+ tcp_linger0(conn, conn->sock);
conn_event(c, conn, CLOSED);
}
diff --git a/tcp_conn.h b/tcp_conn.h
index c8381aa..d93ada7 100644
--- a/tcp_conn.h
+++ b/tcp_conn.h
@@ -239,6 +239,9 @@ struct tcp_splice_conn {
extern int init_sock_pool4 [TCP_SOCK_POOL_SIZE];
extern int init_sock_pool6 [TCP_SOCK_POOL_SIZE];
+void tcp_linger0_(const struct flow_common *f, int s);
+#define tcp_linger0(flow_, s_) tcp_linger0_(&(flow_)->f, (s_))
+
bool tcp_flow_defer(const struct tcp_tap_conn *conn);
int tcp_flow_repair_on(struct ctx *c, const struct tcp_tap_conn *conn);
diff --git a/tcp_splice.c b/tcp_splice.c
index af50e71..1f969a5 100644
--- a/tcp_splice.c
+++ b/tcp_splice.c
@@ -240,28 +240,14 @@ static void conn_event_do(struct tcp_splice_conn *conn, unsigned long event)
*/
static void tcp_splice_rst(struct tcp_splice_conn *conn)
{
- const struct linger linger0 = {
- .l_onoff = 1,
- .l_linger = 0,
- };
unsigned sidei;
if (conn->flags & CLOSING)
return; /* Nothing to do */
- /* Force RST on sockets to inform the peer
- *
- * We do this by setting SO_LINGER with 0 timeout, which means that
- * close() will send an RST (unless the connection is already closed in
- * both directions).
- */
- flow_foreach_sidei(sidei) {
- if (setsockopt(conn->s[sidei], SOL_SOCKET,
- SO_LINGER, &linger0, sizeof(linger0)) < 0) {
- flow_dbg_perror(conn,
-"SO_LINGER failed, may not send RST to peer");
- }
- }
+ /* Force RST on sockets to inform the peer */
+ flow_foreach_sidei(sidei)
+ tcp_linger0(conn, conn->s[sidei]);
conn_flag(conn, CLOSING);
}