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:
Zach Brown
2017-10-11 11:27:23 -07:00
committed by Mark Fasheh
parent ce4daa817a
commit cb879d9f37
3 changed files with 73 additions and 1 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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);