Exemplo n.º 1
0
list *
list_distinct2(list *l, void *data, fcmp2 cmp, fdup dup)
{
	list *res = list_new_(l);
	node *n = NULL;

	for (n = l->h; n; n = n->next) {
		if (!list_find2(res, data, n->data, cmp)) {
			list_append(res, dup?dup(n->data):n->data);
		}
	}
	return res;
}
Exemplo n.º 2
0
void udp_error(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct udp_data *md = (struct udp_data *) module->data;

	//uint32_t src_ip;
	//uint32_t src_port;
	//uint32_t dst_ip;
	//uint32_t dst_port;

	//uint32_t udp_len;
	//uint32_t checksum;

	switch (ff->ctrlFrame.param_id) {
	case UDP_ERROR_TTL:
		PRINT_DEBUG("param_id=UDP_ERROR_TTL (%d)", ff->ctrlFrame.param_id);

		/*
		 struct udp_packet *udp_hdr = (struct udp_packet *) ff->ctrlFrame.data;
		 struct udp_header hdr;

		 hdr.u_src = ntohs(udp_hdr->u_src);
		 hdr.u_dst = ntohs(udp_hdr->u_dst);
		 hdr.u_len = ntohs(udp_hdr->u_len);
		 hdr.u_cksum = ntohs(udp_hdr->u_cksum);
		 */

		//if recv_dst_ip==send_src_ip, recv_dst_port==send_src_port, recv_udp_len==, recv_checksum==,  \\should be unique!
		if (list_is_empty(md->sent_packet_list)) {
			PRINT_WARN("todo error");
			//TODO drop
			freeFinsFrame(ff);
		} else {
			uint8_t *pdu = ff->ctrlFrame.data;
			if (pdu != NULL) { //TODO make func!!
				struct udp_sent *sent = (struct udp_sent *) list_find2(md->sent_packet_list, udp_sent_match_test, &ff->ctrlFrame.data_len, pdu);
				if (sent != NULL) {
					metadata_copy(sent->ff->metaData, ff->metaData);

					ff->ctrlFrame.sender_id = module->index;
					//ff->ctrlFrame.param_id = UDP_ERROR_TTL; //TODO error msg code //ERROR_UDP_TTL?

					ff->ctrlFrame.data_len = sent->ff->dataFrame.pduLength;
					ff->ctrlFrame.data = sent->ff->dataFrame.pdu;
					sent->ff->dataFrame.pdu = NULL;

					if (!module_send_flow(module, ff, UDP_FLOW_DAEMON)) {
						PRINT_WARN("todo error");
						freeFinsFrame(ff);
					}

					list_remove(md->sent_packet_list, sent);
					udp_sent_free(sent);
					PRINT_DEBUG("Freeing: pdu=%p", pdu);
					free(pdu);
				} else {
					PRINT_WARN("todo error");
					freeFinsFrame(ff);
					//TODO drop?
				}
			} else {
				PRINT_WARN("todo");
				freeFinsFrame(ff);
			}
		}
		break;
	case UDP_ERROR_DEST_UNREACH:
		PRINT_DEBUG("param_id=UDP_ERROR_DEST_UNREACH (%d)", ff->ctrlFrame.param_id);

		if (list_is_empty(md->sent_packet_list)) {
			PRINT_WARN("todo error");
			//TODO drop
			freeFinsFrame(ff);
		} else {
			uint8_t *pdu = ff->ctrlFrame.data;
			if (pdu != NULL) {
				struct udp_sent *sent = (struct udp_sent *) list_find2(md->sent_packet_list, udp_sent_match_test, &ff->ctrlFrame.data_len, pdu);
				if (sent != NULL) {
					metadata_copy(sent->ff->metaData, ff->metaData);

					ff->ctrlFrame.sender_id = module->index;
					//ff->ctrlFrame.param_id = UDP_ERROR_DEST_UNREACH; //TODO error msg code //ERROR_UDP_TTL?

					ff->ctrlFrame.data_len = sent->ff->dataFrame.pduLength;
					ff->ctrlFrame.data = sent->ff->dataFrame.pdu;
					sent->ff->dataFrame.pdu = NULL;

					if (!module_send_flow(module, ff, UDP_FLOW_DAEMON)) {
						PRINT_WARN("todo error");
						freeFinsFrame(ff);
					}

					list_remove(md->sent_packet_list, sent);
					udp_sent_free(sent);
					PRINT_DEBUG("Freeing: pdu=%p", pdu);
					free(pdu);
				} else {
					PRINT_WARN("todo error");
					//TODO drop?
					freeFinsFrame(ff);
				}
			} else {
				PRINT_WARN("todo");
				freeFinsFrame(ff);
			}
		}
		break;
	case UDP_ERROR_GET_ADDR:
		PRINT_DEBUG("param_id=UDP_ERROR_GET_ADDR (%d)", ff->ctrlFrame.param_id);

		if (!list_is_empty(md->sent_packet_list)) {
			uint8_t *pdu = ff->ctrlFrame.data;
			if (pdu != NULL) { //TODO make func!!
				struct udp_sent *sent = (struct udp_sent *) list_find2(md->sent_packet_list, udp_sent_match_test, &ff->ctrlFrame.data_len, pdu);
				if (sent != NULL) {
					list_remove(md->sent_packet_list, sent);
					udp_sent_free(sent);
				}
			}
		}

		ff->ctrlFrame.sender_id = module->index;
		//ff->ctrlFrame.param_id = UDP_ERROR_GET_ADDR; //TODO error msg code //ERROR_UDP_TTL?

		if (!module_send_flow(module, ff, UDP_FLOW_DAEMON)) {
			PRINT_WARN("todo error");
			freeFinsFrame(ff);
		}
		break;
	default:
		PRINT_ERROR("Error unknown param_id=%d", ff->ctrlFrame.param_id);
		PRINT_WARN("todo error");
		freeFinsFrame(ff);
		break;
	}
}