diff options
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handshake.c | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c index 850427714c0..bc00e99b62f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handshake.c +++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c @@ -38,6 +38,7 @@ extern struct rpc_clnt_program gd_mgmt_v3_prog; #define TRUSTED_PREFIX "trusted-" +#define GD_PEER_ID_KEY "peer-id" typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *data); @@ -955,14 +956,20 @@ out: * Requests are allowed if, * - glusterd has no peers, or * - the request came from a known peer + * A known peer is identified using the following steps + * - the dict is checked for a peer uuid, which if present is matched with the + * peer list, else + * - the incoming request address is matched with the peer list */ gf_boolean_t -gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req) +gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req, dict_t *dict) { int ret = -1; char hostname[UNIX_PATH_MAX + 1] = {0,}; glusterd_peerinfo_t *peer = NULL; xlator_t *this = NULL; + char *uuid_str = NULL; + uuid_t peer_uuid = {0,}; this = THIS; GF_ASSERT (this); @@ -970,6 +977,19 @@ gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req) if (!glusterd_have_peers ()) return _gf_true; + ret = dict_get_str (dict, GD_PEER_ID_KEY, &uuid_str); + /* Try to match uuid only if available, don't fail as older peers will + * not send a uuid + */ + if (!ret) { + gf_uuid_parse (uuid_str, peer_uuid); + rcu_read_lock (); + ret = (glusterd_peerinfo_find (peer_uuid, NULL) != NULL); + rcu_read_unlock (); + if (ret) + return _gf_true; + } + /* If you cannot get the hostname, you cannot authenticate */ ret = glusterd_remote_hostname_get (req, hostname, sizeof (hostname)); if (ret) @@ -999,16 +1019,11 @@ __glusterd_mgmt_hndsk_versions (rpcsvc_request_t *req) int op_errno = EINVAL; gf_mgmt_hndsk_req args = {{0,},}; gf_mgmt_hndsk_rsp rsp = {0,}; + dict_t *args_dict = NULL; this = THIS; conf = this->private; - /* Check if we can service the request */ - if (!gd_validate_mgmt_hndsk_req (req)) { - ret = -1; - goto out; - } - ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gf_mgmt_hndsk_req); if (ret < 0) { @@ -1017,6 +1032,16 @@ __glusterd_mgmt_hndsk_versions (rpcsvc_request_t *req) goto out; } + GF_PROTOCOL_DICT_UNSERIALIZE (this, args_dict, args.hndsk.hndsk_val, + (args.hndsk.hndsk_len), ret, op_errno, + out); + + /* Check if we can service the request */ + if (!gd_validate_mgmt_hndsk_req (req, args_dict)) { + ret = -1; + goto out; + } + dict = dict_new (); if (!dict) goto out; @@ -1093,12 +1118,6 @@ __glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req) this = THIS; conf = this->private; - /* Check if we can service the request */ - if (!gd_validate_mgmt_hndsk_req (req)) { - ret = -1; - goto out; - } - ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gf_mgmt_hndsk_req); if (ret < 0) { @@ -1813,7 +1832,9 @@ glusterd_mgmt_handshake (xlator_t *this, glusterd_peerctx_t *peerctx) call_frame_t *frame = NULL; gf_mgmt_hndsk_req req = {{0,},}; glusterd_peerinfo_t *peerinfo = NULL; + dict_t *req_dict = NULL; int ret = -1; + int op_errno = EINVAL; frame = create_frame (this, this->ctx->pool); if (!frame) @@ -1821,6 +1842,21 @@ glusterd_mgmt_handshake (xlator_t *this, glusterd_peerctx_t *peerctx) frame->local = peerctx; + req_dict = dict_new (); + if (!req_dict) + goto out; + + ret = dict_set_dynstr (req_dict, GD_PEER_ID_KEY, + gf_strdup (uuid_utoa (MY_UUID))); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to set peer ID in dict"); + goto out; + } + + GF_PROTOCOL_DICT_SERIALIZE (this, req_dict, (&req.hndsk.hndsk_val), + req.hndsk.hndsk_len, op_errno, out); + rcu_read_lock (); peerinfo = glusterd_peerinfo_find (peerctx->peerid, peerctx->peername); |