Beispiel #1
0
/**
 * "ars" means add, remove, send
 */
static bool test_pkt_queue_ars(void)
{
	struct session_entry *session;
	struct sk_buff *skb;
	struct tuple tuple4;
	struct tcphdr *hdr_tcp;
	bool success = true;

	/* Prepare */
	if (is_error(init_ipv4_tuple(&tuple4, "5.6.7.8", 5678, "192.168.2.1", 8765, L4PROTO_TCP)))
		return false;
	session = session_create_str_tcp("1::2", 1212, "3::4", 3434, "192.168.2.1", 8765, "5.6.7.8", 5678,
			V4_INIT); /* The session entry that is supposed to be created in "tcp_close_state_handle". */
	if (!session)
		return false;

	if (is_error(create_skb4_tcp(&tuple4, &skb, 100, 32))) {
		session_return(session);
		return false;
	}
	hdr_tcp = tcp_hdr(skb);
	hdr_tcp->syn = true;
	hdr_tcp->rst = false;
	hdr_tcp->fin = false;

	success &= assert_equals_int(0, pktqueue_add(session, skb), "pktqueue_add 1");
	success &= assert_equals_int(0, pktqueue_remove(session), "pktqueue_remove 1");
	success &= assert_equals_int(-ENOENT, pktqueue_send(session), "pktqueue_send 1");
	success &= assert_equals_int(0, icmp64_pop(), "pktqueue not sent an icmp error");


	session_return(session);
	/* kfree_skb(skb); "skb" kfreed when pktqueue_remove is executed */
	return success;
}
/**
 * Second half of the filtering and updating done during the CLOSED state of the TCP state machine.
 * Processes IPv4 SYN packets when there's no state.
 * Part of RFC 6146 section 3.5.2.2.
 */
static verdict tcp_closed_v4_syn(struct packet *pkt, struct tuple *tuple4)
{
	struct bib_entry *bib;
	struct session_entry *session;
	int error;
	verdict result = VERDICT_DROP;

	if (config_get_drop_external_connections()) {
		log_debug("Applying policy: Dropping externally initiated TCP connections.");
		return VERDICT_DROP;
	}

	error = bibdb_get(tuple4, &bib);
	if (error) {
		if (error != -ESRCH)
			return VERDICT_DROP;
		bib = NULL;
	}
	log_bib(bib);

	error = create_session_ipv4(tuple4, bib, &session);
	if (error)
		goto end_bib;
	log_session(session);

	session->state = V4_INIT;

	if (!bib || config_get_addr_dependent_filtering()) {
		error = pktqueue_add(session, pkt);
		if (error) {
			if (error == -E2BIG) {
				/* Fall back to assume there's no Simultaneous Open. */
				icmp64_send(pkt, ICMPERR_PORT_UNREACHABLE, 0);
			}
			goto end_session;
		}

		/* At this point, skb's original skb completely belongs to pktqueue. */
		result = VERDICT_STOLEN;

		error = sessiondb_add(session, SESSIONTIMER_SYN);
		if (error) {
			log_debug("Error code %d while adding the session to the DB.", error);
			pktqueue_remove(session);
			goto end_session;
		}

	} else {
		error = sessiondb_add(session, SESSIONTIMER_TRANS);
		if (error) {
			log_debug("Error code %d while adding the session to the DB.", error);
			goto end_session;
		}

		result = VERDICT_CONTINUE;
	}

	/* Fall through. */

end_session:
	session_return(session);
	/* Fall through. */

end_bib:
	if (bib)
		bib_return(bib);
	return result;
}