X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Fpdu.c;h=d6e823201e99393efa9d1bd3df0988da44c27ef2;hb=b7e444c6cf557fb0b2609217260826fc13a7ed1c;hp=fb03061c5a3192664aaddeb60b259854d73c8f62;hpb=df5af25fd2ce5f5da48fe0c35d8ea337725bd15a;p=deb_libnfs.git diff --git a/lib/pdu.c b/lib/pdu.c index fb03061..d6e8232 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -48,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; @@ -95,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; @@ -135,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"); @@ -196,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) { @@ -213,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);