Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c10c5d9 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller
Browse files

[DCCP]: More precisely set reset_code when sending RESET packets



Moving the setting of DCCP_SKB_CB(skb)->dccpd_reset_code to the places
where events happen that trigger sending a RESET packet.

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 37f7f421
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -384,9 +384,9 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
	}

out_invalid_packet:
	return 1; /* dccp_v4_do_rcv will send a reset, but...
		     FIXME: the reset code should be
			    DCCP_RESET_CODE_PACKET_ERROR */
	/* dccp_v4_do_rcv will send a reset */
	DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR;
	return 1; 
}

static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
@@ -433,6 +433,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
			   struct dccp_hdr *dh, unsigned len)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
	const int old_state = sk->sk_state;
	int queued = 0;

@@ -473,7 +474,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
		if (dh->dccph_type == DCCP_PKT_RESET)
			goto discard;

		/* Caller (dccp_v4_do_rcv) will send Reset(No Connection)*/
		/* Caller (dccp_v4_do_rcv) will send Reset */
		dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
		return 1;
	}

@@ -487,8 +489,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
		if (dccp_parse_options(sk, skb))
			goto discard;

		if (DCCP_SKB_CB(skb)->dccpd_ack_seq !=
		    DCCP_PKT_WITHOUT_ACK_SEQ)
		if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
			dccp_event_ack_recv(sk, skb);

		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
@@ -500,7 +501,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
		 */
		if (dp->dccps_options.dccpo_send_ack_vector) {
			if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk,
					     DCCP_SKB_CB(skb)->dccpd_seq,
					     dcb->dccpd_seq,
					     DCCP_ACKPKTS_STATE_RECEIVED))
				goto discard;
			/*
@@ -551,8 +552,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
		     dh->dccph_type == DCCP_PKT_REQUEST) ||
		    (sk->sk_state == DCCP_RESPOND &&
		     dh->dccph_type == DCCP_PKT_DATA)) {
		dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
			       DCCP_PKT_SYNC);
		dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC);
		goto discard;
	} else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) {
		dccp_rcv_closereq(sk, skb);
@@ -563,13 +563,13 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
	}

	if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) {
		dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
			       DCCP_PKT_SYNCACK);
		dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNCACK);
		goto discard;
	}

	switch (sk->sk_state) {
	case DCCP_CLOSED:
		dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
		return 1;

	case DCCP_REQUESTING:
+7 −3
Original line number Diff line number Diff line
@@ -669,12 +669,16 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
	struct dccp_request_sock *dreq;
	const __u32 saddr = skb->nh.iph->saddr;
	const __u32 daddr = skb->nh.iph->daddr;
	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
	__u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
	struct dst_entry *dst = NULL;

	/* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
	if (((struct rtable *)skb->dst)->rt_flags &
	    (RTCF_BROADCAST | RTCF_MULTICAST))
	    (RTCF_BROADCAST | RTCF_MULTICAST)) {
		reset_code = DCCP_RESET_CODE_NO_CONNECTION;
		goto drop;
	}

	/*
	 * TW buckets are converted to open requests without
@@ -718,7 +722,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
	 * dccp_create_openreq_child.
	 */
	dreq = dccp_rsk(req);
	dreq->dreq_isr = DCCP_SKB_CB(skb)->dccpd_seq;
	dreq->dreq_isr = dcb->dccpd_seq;
	dreq->dreq_iss = dccp_v4_init_sequence(sk, skb);
	dreq->dreq_service = dccp_hdr_request(skb)->dccph_req_service;

@@ -735,6 +739,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
	__reqsk_free(req);
drop:
	DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
	dcb->dccpd_reset_code = reset_code;
	return -1;
}

@@ -1005,7 +1010,6 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
	return 0;

reset:
	DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
	dccp_v4_ctl_send_reset(skb);
discard:
	kfree_skb(skb);