+ if (!(recordmarker&0x80000000)) {
+ zdr_destroy(&zdr);
+ if (rpc_add_fragment(rpc, buf+4, size-4) != 0) {
+ rpc_set_error(rpc, "Failed to queue fragment for reassembly.");
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ /* reassembly */
+ if (recordmarker != 0 && rpc->fragments != NULL) {
+ struct rpc_fragment *fragment;
+ uint32_t total = size - 4;
+ char *ptr;
+
+ zdr_destroy(&zdr);
+ for (fragment = rpc->fragments; fragment; fragment = fragment->next) {
+ total += fragment->size;
+ }
+
+ reasbuf = malloc(total);
+ if (reasbuf == NULL) {
+ rpc_set_error(rpc, "Failed to reassemble PDU");
+ rpc_free_all_fragments(rpc);
+ return -1;
+ }
+ ptr = reasbuf;
+ for (fragment = rpc->fragments; fragment; fragment = fragment->next) {
+ memcpy(ptr, fragment->data, fragment->size);
+ ptr += fragment->size;
+ }
+ memcpy(ptr, buf + 4, size - 4);
+ zdrmem_create(&zdr, reasbuf, total, ZDR_DECODE);
+ rpc_free_all_fragments(rpc);