Improve error reporting when unmarshalling of message headers fail.
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 12 Mar 2014 01:52:48 +0000 (18:52 -0700)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 12 Mar 2014 01:52:48 +0000 (18:52 -0700)
include/nfsc/libnfs-zdr.h
lib/init.c
lib/libnfs-zdr.c
lib/pdu.c

index 501875efd66ba2e640a677da053fcfbeec1a4f5e..6b2ea9123ce99ab86b17fa3cc839c9e230dc2a13 100644 (file)
@@ -266,11 +266,13 @@ uint32_t libnfs_zdr_getpos(ZDR *zdrs);
 #define zdr_free libnfs_zdr_free
 void libnfs_zdr_free(zdrproc_t proc, char *objp);
 
+struct rpc_context;
+
 #define zdr_callmsg libnfs_zdr_callmsg
-bool_t libnfs_zdr_callmsg(ZDR *zdrs, struct rpc_msg *msg);
+bool_t libnfs_zdr_callmsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg);
 
 #define zdr_replymsg libnfs_zdr_replymsg
-bool_t libnfs_zdr_replymsg(ZDR *zdrs, struct rpc_msg *msg);
+bool_t libnfs_zdr_replymsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg);
 
 #define authnone_create libnfs_authnone_create
 struct AUTH *libnfs_authnone_create(void);
index 93d1db8b088b3780601d5251b63fb30d71a0e28e..3c0c2de46c2e7c7880b29420cce9f047ffcb4333 100644 (file)
@@ -132,16 +132,18 @@ void rpc_set_gid(struct rpc_context *rpc, int gid) {
 void rpc_set_error(struct rpc_context *rpc, char *error_string, ...)
 {
         va_list ap;
+       char *old_error_string = rpc->error_string;
 
        assert(rpc->magic == RPC_CONTEXT_MAGIC);
 
-       if (rpc->error_string != NULL) {
-               free(rpc->error_string);
-       }
         va_start(ap, error_string);
        rpc->error_string = malloc(1024);
        vsnprintf(rpc->error_string, 1024, error_string, ap);
         va_end(ap);
+
+       if (old_error_string != NULL) {
+               free(old_error_string);
+       }
 }
 
 char *rpc_get_error(struct rpc_context *rpc)
index 7539b08d7ccf7776a3f0f6cc52391e5f760ed62d..7c971e003eaf104916c20eb8036fd5e6756ad8ab 100644 (file)
@@ -310,29 +310,41 @@ static bool_t libnfs_opaque_auth(ZDR *zdrs, struct opaque_auth *auth)
        return TRUE;
 }
 
-static bool_t libnfs_rpc_call_body(ZDR *zdrs, struct call_body *cmb)
+static bool_t libnfs_rpc_call_body(struct rpc_context *rpc, ZDR *zdrs, struct call_body *cmb)
 {
        if (!libnfs_zdr_u_int(zdrs, &cmb->rpcvers)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "RPCVERS");
                return FALSE;
        }
 
        if (!libnfs_zdr_u_int(zdrs, &cmb->prog)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "PROG");
                return FALSE;
        }
 
        if (!libnfs_zdr_u_int(zdrs, &cmb->vers)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "VERS");
                return FALSE;
        }
 
        if (!libnfs_zdr_u_int(zdrs, &cmb->proc)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "PROC");
                return FALSE;
        }
 
        if (!libnfs_opaque_auth(zdrs, &cmb->cred)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "CRED");
                return FALSE;
        }
 
        if (!libnfs_opaque_auth(zdrs, &cmb->verf)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "VERF");
                return FALSE;
        }
 
@@ -397,58 +409,78 @@ static bool_t libnfs_rejected_reply(ZDR *zdrs, struct rejected_reply *rr)
        return FALSE;
 }
 
-static bool_t libnfs_rpc_reply_body(ZDR *zdrs, struct reply_body *rmb)
+static bool_t libnfs_rpc_reply_body(struct rpc_context *rpc, ZDR *zdrs, struct reply_body *rmb)
 {
        if (!libnfs_zdr_u_int(zdrs, &rmb->stat)) {
+               rpc_set_error(rpc, "libnfs_rpc_reply_body failed to decode "
+                       "STAT");
                return FALSE;
        }
 
        switch (rmb->stat) {
        case MSG_ACCEPTED:
                if (!libnfs_accepted_reply(zdrs, &rmb->reply.areply)) {
+                       rpc_set_error(rpc, "libnfs_rpc_reply_body failed to "
+                               "decode ACCEPTED");
                        return FALSE;
                }
                return TRUE;
        case MSG_DENIED:
                if (!libnfs_rejected_reply(zdrs, &rmb->reply.rreply)) {
+                       rpc_set_error(rpc, "libnfs_rpc_reply_body failed to "
+                               "decode DENIED");
                        return FALSE;
                }
                return TRUE;
        }
 
+       rpc_set_error(rpc, "libnfs_rpc_reply_body failed to "
+               "decode. Neither ACCEPTED nor DENIED");
        return FALSE;
 }
 
-static bool_t libnfs_rpc_msg(ZDR *zdrs, struct rpc_msg *msg)
+static bool_t libnfs_rpc_msg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg)
 {
+       int ret;
+
        if (!libnfs_zdr_u_int(zdrs, &msg->xid)) {
+               rpc_set_error(rpc, "libnfs_rpc_msg failed to decode XID");
                return FALSE;
        }
 
        if (!libnfs_zdr_u_int(zdrs, &msg->direction)) {
+               rpc_set_error(rpc, "libnfs_rpc_msg failed to decode DIRECTION");
                return FALSE;
        }
 
        switch (msg->direction) {
        case CALL:
-               return libnfs_rpc_call_body(zdrs, &msg->body.cbody);
+               ret = libnfs_rpc_call_body(rpc, zdrs, &msg->body.cbody);
+               rpc_set_error(rpc, "libnfs_rpc_msg failed to encode CALL, "
+                       "ret=%d: %s", ret, rpc_get_error(rpc));
+               return ret;
                break;
        case REPLY:
-               return libnfs_rpc_reply_body(zdrs, &msg->body.rbody);
+               ret = libnfs_rpc_reply_body(rpc, zdrs, &msg->body.rbody);
+               rpc_set_error(rpc, "libnfs_rpc_msg failed to decode REPLY, "
+                       "ret=%d: %s", ret, rpc_get_error(rpc));
+               return ret;
                break;
        default:
+               rpc_set_error(rpc, "libnfs_rpc_msg failed to decode. "
+                       "Neither CALL not REPLY");
                return FALSE;
        }
 }
 
-bool_t libnfs_zdr_callmsg(ZDR *zdrs, struct rpc_msg *msg)
+bool_t libnfs_zdr_callmsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg)
 {
-       return libnfs_rpc_msg(zdrs, msg);
+       return libnfs_rpc_msg(rpc, zdrs, msg);
 }
 
-bool_t libnfs_zdr_replymsg(ZDR *zdrs, struct rpc_msg *msg)
+bool_t libnfs_zdr_replymsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg)
 {
-       return libnfs_rpc_msg(zdrs, msg);
+       return libnfs_rpc_msg(rpc, zdrs, msg);
 }
 
 struct AUTH *authnone_create(void)
index c2538efa8e127cf7240545c1a4e42560a112d6ff..5def0bc5d9041363b2bc833b5f50677750e5c517 100644 (file)
--- a/lib/pdu.c
+++ b/lib/pdu.c
@@ -83,8 +83,9 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi
        msg.body.cbody.cred    = rpc->auth->ah_cred;
        msg.body.cbody.verf    = rpc->auth->ah_verf;
 
-       if (zdr_callmsg(&pdu->zdr, &msg) == 0) {
-               rpc_set_error(rpc, "zdr_callmsg failed");
+       if (zdr_callmsg(rpc, &pdu->zdr, &msg) == 0) {
+               rpc_set_error(rpc, "zdr_callmsg failed with %s",
+                             rpc_get_error(rpc));
                zdr_destroy(&pdu->zdr);
                free(pdu);
                return NULL;
@@ -180,8 +181,11 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, ZDR *
                }
                pdu->zdr_decode_buf = malloc(pdu->zdr_decode_bufsize);
                if (pdu->zdr_decode_buf == NULL) {
-                       rpc_set_error(rpc, "zdr_replymsg failed in portmap_getport_reply");
-                       pdu->cb(rpc, RPC_STATUS_ERROR, "Failed to allocate buffer for decoding of ZDR reply", pdu->private_data);
+                       rpc_set_error(rpc, "Failed to allocate memory for "
+                                     "zdr_encode_buf in rpc_process_reply");
+                       pdu->cb(rpc, RPC_STATUS_ERROR, "Failed to allocate "
+                               "buffer for decoding of ZDR reply",
+                               pdu->private_data);
                        return 0;
                }
                memset(pdu->zdr_decode_buf, 0, pdu->zdr_decode_bufsize);
@@ -189,9 +193,11 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, ZDR *
        msg.body.rbody.reply.areply.reply_data.results.where = pdu->zdr_decode_buf;
        msg.body.rbody.reply.areply.reply_data.results.proc  = pdu->zdr_decode_fn;
 
-       if (zdr_replymsg(zdr, &msg) == 0) {
-               rpc_set_error(rpc, "zdr_replymsg failed in portmap_getport_reply");
-               pdu->cb(rpc, RPC_STATUS_ERROR, "Message rejected by server", pdu->private_data);
+       if (zdr_replymsg(rpc, zdr, &msg) == 0) {
+               rpc_set_error(rpc, "zdr_replymsg failed in rpc_process_reply: "
+                             "%s", rpc_get_error(rpc));
+               pdu->cb(rpc, RPC_STATUS_ERROR, "Message rejected by server",
+                       pdu->private_data);
                if (pdu->zdr_decode_buf != NULL) {
                        free(pdu->zdr_decode_buf);
                        pdu->zdr_decode_buf = NULL;