X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Fpdu.c;h=d6e823201e99393efa9d1bd3df0988da44c27ef2;hb=b7e444c6cf557fb0b2609217260826fc13a7ed1c;hp=a12d30b2501e342a9d76fa91102521b973b668c7;hpb=a19924120d7297f60a4995e555e21ff9f92ca248;p=deb_libnfs.git diff --git a/lib/pdu.c b/lib/pdu.c index a12d30b..d6e8232 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -97,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; @@ -137,6 +149,9 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, XDR * bzero(&msg, sizeof(struct rpc_msg)); msg.acpted_rply.ar_verf = _null_auth; if (pdu->xdr_decode_bufsize > 0) { + if (pdu->xdr_decode_buf != NULL) { + free(pdu->xdr_decode_buf); + } pdu->xdr_decode_buf = malloc(pdu->xdr_decode_bufsize); if (pdu->xdr_decode_buf == NULL) { rpc_set_error(rpc, "xdr_replymsg failed in portmap_getport_reply"); @@ -198,10 +213,12 @@ 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) { - rpc_set_error(rpc, "xdr_int reading recordmarker failed"); - 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) { @@ -215,12 +232,16 @@ 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) { 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; } rpc_set_error(rpc, "No matching pdu found for xid:%d", xid);