[PATCH] chunkd: clone chunksrv_req to chunksrv_resp

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This just-committed change prepares for a more significant protocol
change later on (variable-length keys in requests).

This is a network protocol change, though a minor one you probably won't
notice, due to the chunksrv_req/chunksrv_resp structures currently being
twins (that will soon change).


commit 69cf0ae597fd83086c1746a02c776b0bc05d591e
Author: Jeff Garzik <jeff@xxxxxxxxxx>
Date:   Wed Nov 4 16:44:34 2009 -0500

    Clone chunksrv_req into new chunksrv_resp, to separate request and response
    messages.
    
    - resp_code removed from chunksrv_req
    - s/checksum/sig/ in chunksrv_req
    - req_len() used to calculate request size (preparation for future)
    - resp_init_req() used to init response from request, rather than memcpy()
    - improve data-in debugging
    
    Signed-off-by: Jeff Garzik <jgarzik@xxxxxxxxxx>

diff --git a/include/chunk_msg.h b/include/chunk_msg.h
index 610f8c5..4222f27 100644
--- a/include/chunk_msg.h
+++ b/include/chunk_msg.h
@@ -10,6 +10,7 @@ enum {
 	CHD_USER_SZ		= 64,
 	CHD_KEY_SZ		= 64,
 	CHD_CSUM_SZ		= 64,
+	CHD_SIG_SZ		= 64,
 };
 
 enum chunksrv_ops {
@@ -37,6 +38,17 @@ enum errcode {
 struct chunksrv_req {
 	uint8_t			magic[CHD_MAGIC_SZ];	/* CHUNKD_MAGIC */
 	uint8_t			op;			/* CHO_xxx */
+	uint8_t			rsv1[3];
+	uint32_t		nonce;	/* random number, to stir checksum */
+	uint64_t		data_len;		/* len of addn'l data */
+	char			user[CHD_USER_SZ];	/* username */
+	char			key[CHD_KEY_SZ];	/* object id */
+	char			sig[CHD_SIG_SZ];	/* HMAC signature */
+};
+
+struct chunksrv_resp {
+	uint8_t			magic[CHD_MAGIC_SZ];	/* CHUNKD_MAGIC */
+	uint8_t			op;			/* CHO_xxx */
 	uint8_t			resp_code;		/* errcode's */
 	uint8_t			rsv1[2];
 	uint32_t		nonce;	/* random number, to stir checksum */
@@ -47,7 +59,7 @@ struct chunksrv_req {
 };
 
 struct chunksrv_resp_get {
-	struct chunksrv_req	req;
+	struct chunksrv_resp	resp;
 	uint64_t		mtime;
 };
 
diff --git a/include/chunksrv.h b/include/chunksrv.h
index f9f7abc..6cae18a 100644
--- a/include/chunksrv.h
+++ b/include/chunksrv.h
@@ -3,6 +3,7 @@
 
 #include <chunk_msg.h>
 
+extern size_t req_len(const struct chunksrv_req *req);
 extern void chreq_sign(struct chunksrv_req *req, const char *key,
 		       char *b64hmac_out);
 
diff --git a/lib/chunkdc.c b/lib/chunkdc.c
index 121b589..9c00b8c 100644
--- a/lib/chunkdc.c
+++ b/lib/chunkdc.c
@@ -216,7 +216,7 @@ static size_t all_data_cb(void *ptr, size_t size, size_t nmemb, void *user_data)
 static bool stc_get_req(struct st_client *stc, const char *key, uint64_t *plen)
 {
 	struct chunksrv_req req;
-	struct chunksrv_resp_get resp;
+	struct chunksrv_resp_get get_resp;
 
 	if (stc->verbose)
 		fprintf(stderr, "libstc: GET(%s)\n", key);
@@ -230,28 +230,29 @@ static bool stc_get_req(struct st_client *stc, const char *key, uint64_t *plen)
 	strcpy(req.key, key);
 
 	/* sign request */
-	chreq_sign(&req, stc->key, req.checksum);
+	chreq_sign(&req, stc->key, req.sig);
 
 	/* write request */
-	if (!net_write(stc, &req, sizeof(req)))
+	if (!net_write(stc, &req, req_len(&req)))
 		return false;
 
 	/* read response header */
-	if (!net_read(stc, &resp, sizeof(resp.req)))
+	if (!net_read(stc, &get_resp, sizeof(get_resp.resp)))
 		return false;
 
 	/* check response code */
-	if (resp.req.resp_code != Success) {
+	if (get_resp.resp.resp_code != Success) {
 		if (stc->verbose)
-			fprintf(stderr, "GET resp code: %d\n", resp.req.resp_code);
+			fprintf(stderr, "GET resp code: %d\n", get_resp.resp.resp_code);
 		return false;
 	}
 
 	/* read rest of response header */
-	if (!net_read(stc, &resp.mtime, sizeof(resp) - sizeof(resp.req)))
+	if (!net_read(stc, &get_resp.mtime,
+		      sizeof(get_resp) - sizeof(get_resp.resp)))
 		return false;
 
-	*plen = le64_to_cpu(resp.req.data_len);
+	*plen = le64_to_cpu(get_resp.resp.data_len);
 	return true;
 }
 
@@ -330,7 +331,7 @@ bool stc_get_start(struct st_client *stc, const char *key, int *pfd,
  * return a -EPIPE (normally not possible on read in UNIX). Fortunately,
  * applications know the object lengths as reported by stc_get_start.
  */
-size_t stc_get_recv(struct st_client *stc, void *data, size_t req_len)
+size_t stc_get_recv(struct st_client *stc, void *data, size_t data_len)
 {
 	size_t xfer_len;
 	size_t done_cnt;
@@ -340,7 +341,7 @@ size_t stc_get_recv(struct st_client *stc, void *data, size_t req_len)
 	done_cnt = 0;
 	if (stc->ssl) {
 		for (;;) {
-			if (done_cnt == req_len)
+			if (done_cnt == data_len)
 				break;
 			if (ioctl(stc->fd, FIONREAD, &avail))
 				return errno;
@@ -349,8 +350,8 @@ size_t stc_get_recv(struct st_client *stc, void *data, size_t req_len)
 					break;
 			}
 
-			if ((xfer_len = avail) > req_len - done_cnt)
-				xfer_len = req_len - done_cnt;
+			if ((xfer_len = avail) > data_len - done_cnt)
+				xfer_len = data_len - done_cnt;
 
 			rc = SSL_read(stc->ssl, data + done_cnt, xfer_len);
 			if (rc <= 0) {
@@ -371,8 +372,8 @@ size_t stc_get_recv(struct st_client *stc, void *data, size_t req_len)
 		if (ioctl(stc->fd, FIONREAD, &avail))
 			return errno;
 		if (avail) {
-			if ((xfer_len = avail) > req_len)
-				xfer_len = req_len;
+			if ((xfer_len = avail) > data_len)
+				xfer_len = data_len;
 
 			rc = read(stc->fd, data, xfer_len);
 			if (rc < 0)
@@ -390,7 +391,7 @@ bool stc_put(struct st_client *stc, const char *key,
 {
 	char netbuf[4096];
 	struct chunksrv_req req;
-	struct chunksrv_req resp;
+	struct chunksrv_resp resp;
 	uint64_t content_len = len;
 
 	if (stc->verbose)
@@ -407,10 +408,10 @@ bool stc_put(struct st_client *stc, const char *key,
 	strcpy(req.key, key);
 
 	/* sign request */
-	chreq_sign(&req, stc->key, req.checksum);
+	chreq_sign(&req, stc->key, req.sig);
 
 	/* write request */
-	if (!net_write(stc, &req, sizeof(req)))
+	if (!net_write(stc, &req, req_len(&req)))
 		goto err_out;
 
 	while (content_len) {
@@ -477,10 +478,10 @@ bool stc_put_start(struct st_client *stc, const char *key, uint64_t cont_len,
 	strcpy(req.key, key);
 
 	/* sign request */
-	chreq_sign(&req, stc->key, req.checksum);
+	chreq_sign(&req, stc->key, req.sig);
 
 	/* write request */
-	if (!net_write(stc, &req, sizeof(req)))
+	if (!net_write(stc, &req, req_len(&req)))
 		goto err_out;
 
 	*pfd = stc->fd;
@@ -545,7 +546,7 @@ size_t stc_put_send(struct st_client *stc, void *data, size_t len)
  */
 bool stc_put_sync(struct st_client *stc)
 {
-	struct chunksrv_req resp;
+	struct chunksrv_resp resp;
 
 	/* read response header */
 	if (!net_read(stc, &resp, sizeof(resp)))
@@ -597,7 +598,7 @@ bool stc_put_inline(struct st_client *stc, const char *key,
 bool stc_del(struct st_client *stc, const char *key)
 {
 	struct chunksrv_req req;
-	struct chunksrv_resp_get resp;
+	struct chunksrv_resp resp;
 
 	if (stc->verbose)
 		fprintf(stderr, "libstc: DEL(%s)\n", key);
@@ -611,20 +612,20 @@ bool stc_del(struct st_client *stc, const char *key)
 	strcpy(req.key, key);
 
 	/* sign request */
-	chreq_sign(&req, stc->key, req.checksum);
+	chreq_sign(&req, stc->key, req.sig);
 
 	/* write request */
-	if (!net_write(stc, &req, sizeof(req)))
+	if (!net_write(stc, &req, req_len(&req)))
 		return false;
 
 	/* read response header */
-	if (!net_read(stc, &resp, sizeof(resp.req)))
+	if (!net_read(stc, &resp, sizeof(resp)))
 		return false;
 
 	/* check response code */
-	if (resp.req.resp_code != Success) {
+	if (resp.resp_code != Success) {
 		if (stc->verbose)
-			fprintf(stderr, "DEL resp code: %d\n", resp.req.resp_code);
+			fprintf(stderr, "DEL resp code: %d\n", resp.resp_code);
 		return false;
 	}
 
@@ -722,7 +723,7 @@ struct st_keylist *stc_keys(struct st_client *stc)
 	GByteArray *all_data;
 	char netbuf[4096];
 	struct chunksrv_req req;
-	struct chunksrv_resp_get resp;
+	struct chunksrv_resp resp;
 	uint64_t content_len;
 
 	if (stc->verbose)
@@ -736,20 +737,20 @@ struct st_keylist *stc_keys(struct st_client *stc)
 	strcpy(req.user, stc->user);
 
 	/* sign request */
-	chreq_sign(&req, stc->key, req.checksum);
+	chreq_sign(&req, stc->key, req.sig);
 
 	/* write request */
-	if (!net_write(stc, &req, sizeof(req)))
+	if (!net_write(stc, &req, req_len(&req)))
 		return false;
 
 	/* read response header */
-	if (!net_read(stc, &resp, sizeof(resp.req)))
+	if (!net_read(stc, &resp, sizeof(resp)))
 		return false;
 
 	/* check response code */
-	if (resp.req.resp_code != Success) {
+	if (resp.resp_code != Success) {
 		if (stc->verbose)
-			fprintf(stderr, "LIST resp code: %d\n", resp.req.resp_code);
+			fprintf(stderr, "LIST resp code: %d\n", resp.resp_code);
 		return false;
 	}
 
@@ -757,7 +758,7 @@ struct st_keylist *stc_keys(struct st_client *stc)
 	if (!all_data)
 		return NULL;
 
-	content_len = le64_to_cpu(resp.req.data_len);
+	content_len = le64_to_cpu(resp.data_len);
 
 	/* read response data */
 	while (content_len) {
@@ -822,7 +823,7 @@ err_out:
 bool stc_ping(struct st_client *stc)
 {
 	struct chunksrv_req req;
-	struct chunksrv_resp_get resp;
+	struct chunksrv_resp resp;
 
 	if (stc->verbose)
 		fprintf(stderr, "libstc: PING\n");
@@ -835,20 +836,20 @@ bool stc_ping(struct st_client *stc)
 	strcpy(req.user, stc->user);
 
 	/* sign request */
-	chreq_sign(&req, stc->key, req.checksum);
+	chreq_sign(&req, stc->key, req.sig);
 
 	/* write request */
-	if (!net_write(stc, &req, sizeof(req)))
+	if (!net_write(stc, &req, req_len(&req)))
 		return false;
 
 	/* read response header */
-	if (!net_read(stc, &resp, sizeof(resp.req)))
+	if (!net_read(stc, &resp, sizeof(resp)))
 		return false;
 
 	/* check response code */
-	if (resp.req.resp_code != Success) {
+	if (resp.resp_code != Success) {
 		if (stc->verbose)
-			fprintf(stderr, "NOP resp code: %d\n", resp.req.resp_code);
+			fprintf(stderr, "NOP resp code: %d\n", resp.resp_code);
 		return false;
 	}
 
diff --git a/lib/chunksrv.c b/lib/chunksrv.c
index 4f6cfb7..d6482b2 100644
--- a/lib/chunksrv.c
+++ b/lib/chunksrv.c
@@ -5,6 +5,11 @@
 #include <glib.h>
 #include <chunk_msg.h>
 
+size_t req_len(const struct chunksrv_req *req)
+{
+	return sizeof(*req);
+}
+
 void chreq_sign(struct chunksrv_req *req, const char *key, char *b64hmac_out)
 {
 	unsigned int len = 0;
diff --git a/server/chunkd.h b/server/chunkd.h
index d2418d1..8e666e7 100644
--- a/server/chunkd.h
+++ b/server/chunkd.h
@@ -256,6 +256,8 @@ extern bool cli_write_start(struct client *cli);
 extern int cli_req_avail(struct client *cli);
 extern int cli_poll_mod(struct client *cli);
 extern bool srv_poll_del(int fd);
+extern void resp_init_req(struct chunksrv_resp *resp,
+		   const struct chunksrv_req *req);
 
 /* config.c */
 extern void read_config(void);
diff --git a/server/object.c b/server/object.c
index f49cd63..0792b66 100644
--- a/server/object.c
+++ b/server/object.c
@@ -21,7 +21,7 @@ bool object_del(struct client *cli)
 	int rc;
 	enum errcode err = InternalError;
 	bool rcb;
-	struct chunksrv_req *resp = NULL;
+	struct chunksrv_resp *resp = NULL;
 
 	resp = malloc(sizeof(*resp));
 	if (!resp) {
@@ -29,7 +29,7 @@ bool object_del(struct client *cli)
 		return true;
 	}
 
-	memcpy(resp, &cli->creq, sizeof(cli->creq));
+	resp_init_req(resp, &cli->creq);
 
 	rcb = fs_obj_delete(cli->creq.user, obj_key,
 			    strnlen(obj_key, CHD_KEY_SZ), &err);
@@ -66,7 +66,7 @@ static bool object_put_end(struct client *cli)
 	int rc;
 	enum errcode err = InternalError;
 	bool rcb;
-	struct chunksrv_req *resp = NULL;
+	struct chunksrv_resp *resp = NULL;
 
 	resp = malloc(sizeof(*resp));
 	if (!resp) {
@@ -74,7 +74,7 @@ static bool object_put_end(struct client *cli)
 		return true;
 	}
 
-	memcpy(resp, &cli->creq, sizeof(cli->creq));
+	resp_init_req(resp, &cli->creq);
 
 	cli->state = evt_recycle;
 
@@ -92,7 +92,7 @@ static bool object_put_end(struct client *cli)
 	cli_out_end(cli);
 
 	if (debugging)
-		applog(LOG_DEBUG, "REQ(write) seq %x done code %d",
+		applog(LOG_DEBUG, "REQ(data-in) seq %x done code %d",
 		       resp->nonce, resp->resp_code);
 
 	rc = cli_writeq(cli, resp, sizeof(*resp), cli_cb_free, resp);
@@ -113,13 +113,19 @@ bool cli_evt_data_in(struct client *cli, unsigned int events)
 {
 	char *p = cli->netbuf;
 	ssize_t avail, bytes;
+	size_t read_sz;
 
 	if (!cli->out_len)
 		return object_put_end(cli);
 
+	read_sz = MIN(cli->out_len, CLI_DATA_BUF_SZ);
+
+	if (debugging)
+		applog(LOG_DEBUG, "REQ(data-in) seq %x, out_len %ld, read_sz %u",
+		       cli->creq.nonce, cli->out_len, read_sz);
+
 	if (cli->ssl) {
-		int rc = SSL_read(cli->ssl, cli->netbuf,
-				  MIN(cli->out_len, CLI_DATA_BUF_SZ));
+		int rc = SSL_read(cli->ssl, cli->netbuf, read_sz);
 		if (rc <= 0) {
 			if (rc == 0) {
 				cli->state = evt_dispose;
@@ -139,8 +145,7 @@ bool cli_evt_data_in(struct client *cli, unsigned int events)
 		}
 		avail = rc;
 	} else {
-		avail = read(cli->fd, cli->netbuf,
-			     MIN(cli->out_len, CLI_DATA_BUF_SZ));
+		avail = read(cli->fd, cli->netbuf, read_sz);
 		if (avail <= 0) {
 			if (avail == 0) {
 				applog(LOG_ERR, "object read(2) unexpected EOF");
@@ -148,8 +153,11 @@ bool cli_evt_data_in(struct client *cli, unsigned int events)
 				return true;
 			}
 
-			if (errno == EAGAIN)
+			if (errno == EAGAIN) {
+				if (debugging)
+					applog(LOG_ERR, "object read(2) EAGAIN");
 				return false;
+			}
 
 			cli_out_end(cli);
 			applog(LOG_ERR, "object read(2) error: %s",
@@ -158,9 +166,8 @@ bool cli_evt_data_in(struct client *cli, unsigned int events)
 		}
 	}
 
-	if (debugging)
-		applog(LOG_DEBUG, "REQ(write) seq %x avail %ld",
-		       cli->creq.nonce, (long)avail);
+	if (debugging && (avail != read_sz))
+		applog(LOG_DEBUG, "REQ(data-in) avail %ld", (long)avail);
 
 	while (avail > 0) {
 		bytes = fs_obj_write(cli->out_bo, p, avail);
@@ -274,33 +281,33 @@ bool object_get(struct client *cli, bool want_body)
 	int rc;
 	enum errcode err = InternalError;
 	struct backend_obj *obj;
-	struct chunksrv_resp_get *resp = NULL;
+	struct chunksrv_resp_get *get_resp = NULL;
 
-	resp = malloc(sizeof(*resp));
-	if (!resp) {
+	get_resp = calloc(1, sizeof(*get_resp));
+	if (!get_resp) {
 		cli->state = evt_dispose;
 		return true;
 	}
 
-	memcpy(resp, &cli->creq, sizeof(cli->creq));
+	resp_init_req(&get_resp->resp, &cli->creq);
 
 	cli->in_obj = obj = fs_obj_open(cli->creq.user, obj_key,
 					strnlen(obj_key, CHD_KEY_SZ), &err);
 	if (!obj) {
-		free(resp);
+		free(get_resp);
 		return cli_err(cli, err, true);
 	}
 
 	cli->in_len = obj->size;
 
-	resp->req.data_len = cpu_to_le64(obj->size);
-	memcpy(resp->req.checksum, obj->hashstr, sizeof(obj->hashstr));
-	resp->req.checksum[sizeof(obj->hashstr)] = 0;
-	resp->mtime = cpu_to_le64(obj->mtime);
+	get_resp->resp.data_len = cpu_to_le64(obj->size);
+	memcpy(get_resp->resp.checksum, obj->hashstr, sizeof(obj->hashstr));
+	get_resp->resp.checksum[sizeof(obj->hashstr)] = 0;
+	get_resp->mtime = cpu_to_le64(obj->mtime);
 
-	rc = cli_writeq(cli, resp, sizeof(*resp), cli_cb_free, resp);
+	rc = cli_writeq(cli, get_resp, sizeof(*get_resp), cli_cb_free, get_resp);
 	if (rc) {
-		free(resp);
+		free(get_resp);
 		return true;
 	}
 
diff --git a/server/server.c b/server/server.c
index 878ec56..b2911b2 100644
--- a/server/server.c
+++ b/server/server.c
@@ -269,6 +269,18 @@ static bool srv_poll_mask(int fd, short mask_set, short mask_clear)
 	return true;
 }
 
+void resp_init_req(struct chunksrv_resp *resp,
+		   const struct chunksrv_req *req)
+{
+	memset(resp, 0, sizeof(*resp));
+	memcpy(resp->magic, req->magic, CHD_MAGIC_SZ);
+	resp->op = req->op;
+	resp->nonce = req->nonce;
+	resp->data_len = req->data_len;
+	strncpy(resp->user, req->user, CHD_USER_SZ);
+	strncpy(resp->key, req->key, CHD_KEY_SZ);
+}
+
 static bool cli_write_free(struct client *cli, struct client_write *tmp,
 			   bool done)
 {
@@ -648,7 +660,7 @@ out:
 bool cli_err(struct client *cli, enum errcode code, bool recycle_ok)
 {
 	int rc;
-	struct chunksrv_req *resp = NULL;
+	struct chunksrv_resp *resp = NULL;
 
 	if (code != Success)
 		applog(LOG_INFO, "client %s error %s",
@@ -660,7 +672,7 @@ bool cli_err(struct client *cli, enum errcode code, bool recycle_ok)
 		return true;
 	}
 
-	memcpy(resp, &cli->creq, sizeof(cli->creq));
+	resp_init_req(resp, &cli->creq);
 
 	resp->resp_code = code;
 
@@ -683,7 +695,7 @@ static bool cli_resp_xml(struct client *cli, GList *content)
 	int rc;
 	bool rcb;
 	size_t content_len = strlist_len(content);
-	struct chunksrv_req *resp = NULL;
+	struct chunksrv_resp *resp = NULL;
 
 	resp = malloc(sizeof(*resp));
 	if (!resp) {
@@ -691,7 +703,7 @@ static bool cli_resp_xml(struct client *cli, GList *content)
 		return true;
 	}
 
-	memcpy(resp, &cli->creq, sizeof(cli->creq));
+	resp_init_req(resp, &cli->creq);
 
 	resp->data_len = cpu_to_le64(content_len);
 
@@ -787,14 +799,14 @@ static bool authcheck(const struct chunksrv_req *req)
 	char hmac[64];
 
 	memcpy(&tmpreq, req, sizeof(tmpreq));
-	memset(&tmpreq.checksum, 0, sizeof(tmpreq.checksum));
+	memset(&tmpreq.sig, 0, sizeof(tmpreq.sig));
 
 	/* for lack of a better authentication scheme, we
 	 * supply the username as the secret key
 	 */
 	chreq_sign(&tmpreq, req->user, hmac);
 
-	return strcmp(req->checksum, hmac) ? false : true;
+	return strcmp(req->sig, hmac) ? false : true;
 }
 
 static bool valid_req_hdr(const struct chunksrv_req *req)
@@ -812,8 +824,8 @@ static bool valid_req_hdr(const struct chunksrv_req *req)
 	if (len == sizeof(req->key))
 		return false;
 
-	len = strnlen(req->checksum, sizeof(req->checksum));
-	if (len < 1 || len == sizeof(req->checksum))
+	len = strnlen(req->sig, sizeof(req->sig));
+	if (len < 1 || len == sizeof(req->sig))
 		return false;
 
 	return true;
@@ -912,7 +924,8 @@ static bool cli_evt_read_req(struct client *cli, unsigned int events)
 	cli->req_ptr += rc;
 	cli->req_used += rc;
 
-	if (cli->req_used < sizeof(cli->creq))
+	/* poll for more, if fixed-length record not yet received */
+	if (cli->req_used < sizeof(struct chunksrv_req))
 		return false;
 
 	cli->state = evt_exec_req;
--
To unsubscribe from this list: send the line "unsubscribe hail-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Fedora Clound]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux