Beispiel #1
0
void rpc_destroy_context(struct rpc_context *rpc)
{
	struct rpc_pdu *pdu;
	unsigned int i;

	assert(rpc->magic == RPC_CONTEXT_MAGIC);

        /* If we are a server context, free all registered endpoints. */
        while (rpc->endpoints != NULL) {
                struct rpc_endpoint *next = rpc->endpoints->next;

                free(rpc->endpoints);
                rpc->endpoints = next;
        }

	while((pdu = rpc->outqueue.head) != NULL) {
		pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data);
		LIBNFS_LIST_REMOVE(&rpc->outqueue.head, pdu);
		rpc_free_pdu(rpc, pdu);
	}

	for (i = 0; i < HASHES; i++) {
		struct rpc_queue *q = &rpc->waitpdu[i];

		while((pdu = q->head) != NULL) {
			pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data);
			LIBNFS_LIST_REMOVE(&q->head, pdu);
			rpc_free_pdu(rpc, pdu);
		}
	}

	rpc_free_all_fragments(rpc);

        if (rpc->auth) {
                auth_destroy(rpc->auth);
                rpc->auth =NULL;
        }

	if (rpc->fd != -1) {
 		close(rpc->fd);
	}

	if (rpc->error_string != NULL) {
		free(rpc->error_string);
		rpc->error_string = NULL;
	}

	rpc->magic = 0;
	free(rpc);
}
Beispiel #2
0
void rpc_destroy_context(struct rpc_context *rpc)
{
	struct rpc_pdu *pdu;
	unsigned int i;

	assert(rpc->magic == RPC_CONTEXT_MAGIC);

	while((pdu = rpc->outqueue.head) != NULL) {
		pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data);
		LIBNFS_LIST_REMOVE(&rpc->outqueue.head, pdu);
		rpc_free_pdu(rpc, pdu);
	}

	for (i = 0; i < HASHES; i++) {
		struct rpc_queue *q = &rpc->waitpdu[i];

		while((pdu = q->head) != NULL) {
			pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data);
			LIBNFS_LIST_REMOVE(&q->head, pdu);
			rpc_free_pdu(rpc, pdu);
		}
	}

	rpc_free_all_fragments(rpc);

	auth_destroy(rpc->auth);
	rpc->auth =NULL;

	if (rpc->fd != -1) {
 		close(rpc->fd);
	}

	if (rpc->encodebuf != NULL) {
		free(rpc->encodebuf);
		rpc->encodebuf = NULL;
	}

	if (rpc->error_string != NULL) {
		free(rpc->error_string);
		rpc->error_string = NULL;
	}

	if (rpc->udp_dest != NULL) {
		free(rpc->udp_dest);
		rpc->udp_dest = NULL;
	}

	rpc->magic = 0;
	free(rpc);
}
Beispiel #3
0
void rpc_destroy_context(struct rpc_context *rpc)
{
	struct rpc_pdu *pdu;

	assert(rpc->magic == RPC_CONTEXT_MAGIC);

	while((pdu = rpc->outqueue) != NULL) {
		pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data);
		SLIST_REMOVE(&rpc->outqueue, pdu);
		rpc_free_pdu(rpc, pdu);
	}
	while((pdu = rpc->waitpdu) != NULL) {
		pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data);
		SLIST_REMOVE(&rpc->waitpdu, pdu);
		rpc_free_pdu(rpc, pdu);
	}

	rpc_free_all_fragments(rpc);

	auth_destroy(rpc->auth);
	rpc->auth =NULL;

	if (rpc->fd != -1) {
#if defined(WIN32)
		closesocket(rpc->fd);
#else
 		close(rpc->fd);
#endif
	}

	if (rpc->encodebuf != NULL) {
		free(rpc->encodebuf);
		rpc->encodebuf = NULL;
	}

	if (rpc->error_string != NULL) {
		free(rpc->error_string);
		rpc->error_string = NULL;
	}

	if (rpc->udp_dest != NULL) {
		free(rpc->udp_dest);
		rpc->udp_dest = NULL;
	}

	rpc->magic = 0;
	free(rpc);
}
Beispiel #4
0
int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size)
{
	struct rpc_pdu *pdu, *prev_pdu;
	struct rpc_queue *q;
	ZDR zdr;
	int pos, recordmarker = 0;
	unsigned int hash;
	uint32_t xid;
	char *reasbuf = NULL;

	assert(rpc->magic == RPC_CONTEXT_MAGIC);

	memset(&zdr, 0, sizeof(ZDR));

	zdrmem_create(&zdr, buf, size, ZDR_DECODE);
	if (rpc->is_udp == 0) {
		if (zdr_int(&zdr, &recordmarker) == 0) {
			rpc_set_error(rpc, "zdr_int reading recordmarker failed");
			zdr_destroy(&zdr);
			return -1;
		}
		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;
                        if (total < fragment->size) {
                                rpc_set_error(rpc, "Fragments too large");
                                rpc_free_all_fragments(rpc);
                                return -1;
                        }
		}

		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);
	}

        if (rpc->is_server_context) {
                int ret;

                ret = rpc_process_call(rpc, &zdr);
                zdr_destroy(&zdr);
                if (reasbuf != NULL) {
                        free(reasbuf);
                }
                return ret;
        }

	pos = zdr_getpos(&zdr);
	if (zdr_int(&zdr, (int *)&xid) == 0) {
		rpc_set_error(rpc, "zdr_int reading xid failed");
		zdr_destroy(&zdr);
		if (reasbuf != NULL) {
			free(reasbuf);
		}
		return -1;
	}
	zdr_setpos(&zdr, pos);

	/* Look up the transaction in a hash table of our requests */
	hash = rpc_hash_xid(xid);
	q = &rpc->waitpdu[hash];

	/* Follow the hash chain.  Linear traverse singly-linked list,
	 * but track previous entry for optimised removal */
	prev_pdu = NULL;
	for (pdu=q->head; pdu; pdu=pdu->next) {
		if (pdu->xid != xid) {
			prev_pdu = pdu;
			continue;
		}
		if (rpc->is_udp == 0 || rpc->is_broadcast == 0) {
			/* Singly-linked but we track head and tail */
			if (pdu == q->head)
				q->head = pdu->next;
			if (pdu == q->tail)
				q->tail = prev_pdu;
			if (prev_pdu != NULL)
				prev_pdu->next = pdu->next;
			rpc->waitpdu_len--;
		}
		if (rpc_process_reply(rpc, pdu, &zdr) != 0) {
			rpc_set_error(rpc, "rpc_procdess_reply failed");
		}
		zdr_destroy(&zdr);
		if (rpc->is_udp == 0 || rpc->is_broadcast == 0) {
			rpc_free_pdu(rpc, pdu);
		}
		if (reasbuf != NULL) {
			free(reasbuf);
		}
		return 0;
	}

	zdr_destroy(&zdr);
	if (reasbuf != NULL) {
		free(reasbuf);
	}
	return 0;
}