mirror of
https://github.com/versity/scoutfs.git
synced 2026-02-07 11:10:44 +00:00
scoutfs: add network greeting message
Add a network greeting message that's exchanged between the client and server on every connection to make sure that we have the correct file system and format hash. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -251,9 +251,11 @@ static int client_connect(struct client_info *client)
|
||||
{
|
||||
struct super_block *sb = client->sb;
|
||||
struct scoutfs_super_block super;
|
||||
struct scoutfs_net_greeting greet;
|
||||
struct sockaddr_in *sin;
|
||||
struct socket *sock = NULL;
|
||||
struct timeval tv;
|
||||
struct kvec kv;
|
||||
int retries;
|
||||
int addrlen;
|
||||
int optval;
|
||||
@@ -323,6 +325,34 @@ static int client_connect(struct client_info *client)
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
greet.fsid = super.id;
|
||||
greet.format_hash = super.format_hash;
|
||||
kv.iov_base = &greet;
|
||||
kv.iov_len = sizeof(greet);
|
||||
ret = scoutfs_sock_sendmsg(sock, &kv, 1);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
ret = scoutfs_sock_recvmsg(sock, &greet, sizeof(greet));
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
if (greet.fsid != super.id) {
|
||||
scoutfs_warn(sb, "server "SIN_FMT" has fsid 0x%llx, expected 0x%llx",
|
||||
SIN_ARG(&client->peername),
|
||||
le64_to_cpu(greet.fsid),
|
||||
le64_to_cpu(super.id));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (greet.format_hash != super.format_hash) {
|
||||
scoutfs_warn(sb, "server "SIN_FMT" has format hash 0x%llx, expected 0x%llx",
|
||||
SIN_ARG(&client->peername),
|
||||
le64_to_cpu(greet.format_hash),
|
||||
le64_to_cpu(super.format_hash));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* but use a keepalive timeout instead of send timeout */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
@@ -566,6 +566,11 @@ struct scoutfs_lock_name {
|
||||
* messages over the wire.
|
||||
*/
|
||||
|
||||
struct scoutfs_net_greeting {
|
||||
__le64 fsid;
|
||||
__le64 format_hash;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* This header precedes and describes all network messages sent over
|
||||
* sockets. The id is set by the request and sent in the reply. The
|
||||
|
||||
@@ -765,11 +765,16 @@ static void scoutfs_server_recv_func(struct work_struct *work)
|
||||
recv_work);
|
||||
struct server_info *server = conn->server;
|
||||
struct super_block *sb = server->sb;
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct scoutfs_super_block *super = &sbi->super;
|
||||
struct socket *sock = conn->sock;
|
||||
struct workqueue_struct *req_wq;
|
||||
struct scoutfs_net_greeting greet;
|
||||
struct scoutfs_net_header nh;
|
||||
struct server_request *req;
|
||||
bool passed_greeting;
|
||||
unsigned data_len;
|
||||
struct kvec kv;
|
||||
int ret;
|
||||
|
||||
req_wq = alloc_workqueue("scoutfs_server_requests",
|
||||
@@ -779,13 +784,45 @@ static void scoutfs_server_recv_func(struct work_struct *work)
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* first bounce the greeting */
|
||||
ret = scoutfs_sock_recvmsg(sock, &greet, sizeof(greet));
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* we'll close conn after failed greeting to let client see ours */
|
||||
passed_greeting = false;
|
||||
|
||||
if (greet.fsid != super->id) {
|
||||
scoutfs_warn(sb, "client "SIN_FMT" has fsid 0x%llx, expected 0x%llx",
|
||||
SIN_ARG(&conn->peername),
|
||||
le64_to_cpu(greet.fsid),
|
||||
le64_to_cpu(super->id));
|
||||
} else if (greet.format_hash != super->format_hash) {
|
||||
scoutfs_warn(sb, "client "SIN_FMT" has format hash 0x%llx, expected 0x%llx",
|
||||
SIN_ARG(&conn->peername),
|
||||
le64_to_cpu(greet.format_hash),
|
||||
le64_to_cpu(super->format_hash));
|
||||
} else {
|
||||
passed_greeting = true;
|
||||
}
|
||||
|
||||
greet.fsid = super->id;
|
||||
greet.format_hash = super->format_hash;
|
||||
kv.iov_base = &greet;
|
||||
kv.iov_len = sizeof(greet);
|
||||
ret = scoutfs_sock_sendmsg(sock, &kv, 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
for (;;) {
|
||||
/* receive the header */
|
||||
ret = scoutfs_sock_recvmsg(sock, &nh, sizeof(nh));
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (!passed_greeting)
|
||||
break;
|
||||
|
||||
trace_scoutfs_server_recv_request(conn->server->sb,
|
||||
&conn->sockname,
|
||||
&conn->peername, &nh);
|
||||
|
||||
Reference in New Issue
Block a user