mirror of
https://github.com/versity/scoutfs.git
synced 2026-09-24 08:54:45 +00:00
scoutfs: ignore connections without greeting
A connecting client must send a greeting message so the server can get their RID and start processing. The server acted on connections that hadn't received a greeting with the RID. It would print messages and would try to fence these connections' client if it disconnected. The server never received the RID, though, so there was nothing to fence. The server would shut down if either fencing raised an error or when the net stack called its notify_down callback with a 0 RID. And all of this is actively triggered in the field by port scans that send either nothing or garbage down connections to the ports that they're sweeping. We fix all this by ignoring the connections until we receive a RID. We don't print the accepted or closed messages, free the connection if it disconnects, and don't call the notify up or down methods. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
+11
-9
@@ -1007,7 +1007,7 @@ static void scoutfs_net_destroy_worker(struct work_struct *work)
|
||||
WARN_ON_ONCE(!list_empty(&conn->accepted_list));
|
||||
|
||||
/* tell callers that accepted connection finally done */
|
||||
if (conn->listening_conn && conn->notify_down)
|
||||
if (conn->listening_conn && conn->notify_down && test_conn_fl(conn, valid_greeting))
|
||||
conn->notify_down(sb, conn, conn->info, conn->rid);
|
||||
|
||||
list_splice_init(&conn->resend_queue, &conn->send_queue);
|
||||
@@ -1179,10 +1179,6 @@ static void scoutfs_net_listen_worker(struct work_struct *work)
|
||||
continue;
|
||||
}
|
||||
|
||||
scoutfs_info(sb, "server accepted "SIN_FMT" -> "SIN_FMT,
|
||||
SIN_ARG(&acc_conn->sockname),
|
||||
SIN_ARG(&acc_conn->peername));
|
||||
|
||||
/* acc_conn isn't visible, conn unlock orders stores */
|
||||
spin_lock(&conn->lock);
|
||||
|
||||
@@ -1303,13 +1299,15 @@ static void scoutfs_net_shutdown_worker(struct work_struct *work)
|
||||
trace_scoutfs_net_shutdown_work_enter(sb, 0, 0);
|
||||
trace_scoutfs_conn_shutdown_start(conn);
|
||||
|
||||
/* connected and accepted conns print a message */
|
||||
if (conn->peername.sin_port != 0)
|
||||
/* (racy) connected client and accepted server with greeting print a message */
|
||||
if (conn->peername.sin_port != 0 &&
|
||||
(!conn->listening_conn || test_conn_fl(conn, valid_greeting))) {
|
||||
scoutfs_info(sb, "%s "SIN_FMT" -> "SIN_FMT,
|
||||
conn->listening_conn ? "server closing" :
|
||||
"client disconnected",
|
||||
SIN_ARG(&conn->sockname),
|
||||
SIN_ARG(&conn->peername));
|
||||
}
|
||||
|
||||
/* ensure that sockets return errors, wakes blocked socket work */
|
||||
if (conn->sock)
|
||||
@@ -1386,9 +1384,10 @@ static void scoutfs_net_shutdown_worker(struct work_struct *work)
|
||||
/* resolve racing with listener shutdown with locked shutting_down */
|
||||
if (conn->listening_conn &&
|
||||
(test_conn_fl(conn->listening_conn, shutting_down) ||
|
||||
test_conn_fl(conn, saw_farewell))) {
|
||||
test_conn_fl(conn, saw_farewell) ||
|
||||
!test_conn_fl(conn, valid_greeting))) {
|
||||
|
||||
/* free accepted sockets after farewell or listener shutdown */
|
||||
/* free accepted sockets after farewell, listener shutdown, or invalid greeting */
|
||||
spin_unlock(&conn->lock);
|
||||
destroy_conn(conn);
|
||||
|
||||
@@ -1886,6 +1885,9 @@ restart:
|
||||
|
||||
spin_unlock(&conn->lock);
|
||||
|
||||
scoutfs_info(sb, "server accepted "SIN_FMT" -> "SIN_FMT,
|
||||
SIN_ARG(&conn->sockname), SIN_ARG(&conn->peername));
|
||||
|
||||
/* only call notify_up the first time we see the rid */
|
||||
if (conn->notify_up && first_contact)
|
||||
conn->notify_up(sb, conn, conn->info, rid);
|
||||
|
||||
Reference in New Issue
Block a user