X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Fpdu.c;h=601f11023778a28bb71d83b5d1844fce49c19f22;hb=5bf60dc601c70730e4280cdf9c7807f458e1a73b;hp=238d71de4370a153c0dd6b0864d3c95ea5bec385;hpb=84004dbf9bb2ab8a7f8b968affc53ee3065fa911;p=deb_libnfs.git diff --git a/lib/pdu.c b/lib/pdu.c index 238d71d..601f110 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -17,6 +17,9 @@ #include #include +#include +#include +#include #include #include #include "slist.h" @@ -30,13 +33,12 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi struct rpc_msg msg; if (rpc == NULL) { - printf("trying to allocate rpc pdu on NULL context\n"); return NULL; } pdu = malloc(sizeof(struct rpc_pdu)); if (pdu == NULL) { - printf("Failed to allocate pdu structure\n"); + rpc_set_error(rpc, "Out of memory: Failed to allocate pdu structure"); return NULL; } bzero(pdu, sizeof(struct rpc_pdu)); @@ -47,7 +49,9 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi pdu->xdr_decode_bufsize = xdr_decode_bufsize; xdrmem_create(&pdu->xdr, rpc->encodebuf, rpc->encodebuflen, XDR_ENCODE); - xdr_setpos(&pdu->xdr, 4); /* skip past the record marker */ + if (rpc->is_udp == 0) { + xdr_setpos(&pdu->xdr, 4); /* skip past the record marker */ + } bzero(&msg, sizeof(struct rpc_msg)); msg.rm_xid = pdu->xid; @@ -60,7 +64,7 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi msg.rm_call.cb_verf = rpc->auth->ah_verf; if (xdr_callmsg(&pdu->xdr, &msg) == 0) { - printf("xdr_callmsg failed\n"); + rpc_set_error(rpc, "xdr_callmsg failed"); xdr_destroy(&pdu->xdr); free(pdu); return NULL; @@ -83,6 +87,7 @@ void rpc_free_pdu(struct rpc_context *rpc _U_, struct rpc_pdu *pdu) } xdr_destroy(&pdu->xdr); + free(pdu); } @@ -93,6 +98,17 @@ int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) size = xdr_getpos(&pdu->xdr); + /* for udp we dont queue, we just send it straight away */ + if (rpc->is_udp != 0) { + if (sendto(rpc->fd, rpc->encodebuf, size, MSG_DONTWAIT, rpc->udp_dest, sizeof(struct sockaddr_in)) < 0) { + rpc_set_error(rpc, "Sendto failed with errno %s", strerror(errno)); + rpc_free_pdu(rpc, pdu); + return -1; + } + SLIST_ADD_END(&rpc->waitpdu, pdu); + return 0; + } + /* write recordmarker */ xdr_setpos(&pdu->xdr, 0); recordmarker = (size - 4) | 0x80000000; @@ -119,7 +135,7 @@ int rpc_get_pdu_size(char *buf) size = ntohl(*(uint32_t *)buf); if ((size & 0x80000000) == 0) { - printf("cant handle oncrpc fragments\n"); + /* cant handle oncrpc fragments */ return -1; } @@ -135,7 +151,7 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, XDR * if (pdu->xdr_decode_bufsize > 0) { pdu->xdr_decode_buf = malloc(pdu->xdr_decode_bufsize); if (pdu->xdr_decode_buf == NULL) { - printf("xdr_replymsg failed in portmap_getport_reply\n"); + rpc_set_error(rpc, "xdr_replymsg failed in portmap_getport_reply"); pdu->cb(rpc, RPC_STATUS_ERROR, "Failed to allocate buffer for decoding of XDR reply", pdu->private_data); return 0; } @@ -145,7 +161,7 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, XDR * msg.acpted_rply.ar_results.proc = pdu->xdr_decode_fn; if (xdr_replymsg(xdr, &msg) == 0) { - printf("xdr_replymsg failed in portmap_getport_reply\n"); + rpc_set_error(rpc, "xdr_replymsg failed in portmap_getport_reply"); pdu->cb(rpc, RPC_STATUS_ERROR, "Message rejected by server", pdu->private_data); if (pdu->xdr_decode_buf != NULL) { free(pdu->xdr_decode_buf); @@ -194,14 +210,16 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size) bzero(&xdr, sizeof(XDR)); xdrmem_create(&xdr, buf, size, XDR_DECODE); - if (xdr_int(&xdr, &recordmarker) == 0) { - printf("xdr_int reading recordmarker failed\n"); - xdr_destroy(&xdr); - return -1; + if (rpc->is_udp == 0) { + if (xdr_int(&xdr, &recordmarker) == 0) { + rpc_set_error(rpc, "xdr_int reading recordmarker failed"); + xdr_destroy(&xdr); + return -1; + } } pos = xdr_getpos(&xdr); if (xdr_int(&xdr, (int *)&xid) == 0) { - printf("xdr_int reading xid failed\n"); + rpc_set_error(rpc, "xdr_int reading xid failed"); xdr_destroy(&xdr); return -1; } @@ -211,15 +229,19 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size) if (pdu->xid != xid) { continue; } - SLIST_REMOVE(&rpc->waitpdu, pdu); + if (rpc->is_udp == 0 || rpc->is_broadcast == 0) { + SLIST_REMOVE(&rpc->waitpdu, pdu); + } if (rpc_process_reply(rpc, pdu, &xdr) != 0) { - printf("rpc_procdess_reply failed\n"); + rpc_set_error(rpc, "rpc_procdess_reply failed"); } xdr_destroy(&xdr); - rpc_free_pdu(rpc, pdu); + if (rpc->is_udp == 0 || rpc->is_broadcast == 0) { + rpc_free_pdu(rpc, pdu); + } return 0; } - printf("No matching pdu found for xid:%d\n", xid); + rpc_set_error(rpc, "No matching pdu found for xid:%d", xid); xdr_destroy(&xdr); return -1; }