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 <[email protected]>
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 <[email protected]>

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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to