DCCP protocol discussions
 help / color / mirror / Atom feed
From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
To: dccp@vger.kernel.org
Subject: [PATCH 3/3]: Convert Reset code into socket error number
Date: Sat, 29 Sep 2007 16:44:53 +0000	[thread overview]
Message-ID: <200709291744.53552@strip-the-willow> (raw)

[DCCP]: Convert Reset code into socket error number

This adds support for converting the 11 currently defined Reset codes into system
error numbers, which are stored in sk_err for further interpretation.

This makes the externally visible API behaviour similar to TCP, since a client
connecting to a non-existing port will experience ECONNREFUSED.
 
 * Code 0, Unspecified, is interpreted as non-error (0);
 * Code 1, Closed (normal termination), also maps into 0;
 * Code 2, Aborted, maps into "Connection reset by peer" (ECONNRESET);
 * Code 3, No Connection and
   Code 7, Connection Refused, map into "Connection refused" (ECONNREFUSED);
 * Code 4, Packet Error, maps into "No message of desired type" (ENOMSG);
 * Code 5, Option Error, maps into "Illegal byte sequence" (EILSEQ);
 * Code 6, Mandatory Error, maps into "Operation not supported on transport endpoint" (EOPNOTSUPP);
 * Code 8, Bad Service Code, maps into "Invalid request code" (EBADRQC);
 * Code 9, Too Busy, maps into "Too many users" (EUSERS);
 * Code 10, Bad Init Cookie, maps into "Invalid request descriptor" (EBADR);
 * Code 11, Aggression Penalty, maps into "Quota exceeded" (EDQUOT)
   which makes sense in terms of using more than the `fair share' of bandwidth.

The patch was found to solve the problem reported by Rémi Denis-Courmont - many thanks.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>   
---
 net/dccp/input.c |   48 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 39 insertions(+), 9 deletions(-)

--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -55,6 +55,42 @@ static void dccp_rcv_closereq(struct soc
 	dccp_send_close(sk, 0);
 }
 
+static u8 dccp_reset_code_convert(const u8 code)
+{
+	const u8 error_code[] = {
+	[DCCP_RESET_CODE_CLOSED]	     = 0,	/* normal termination */
+	[DCCP_RESET_CODE_UNSPECIFIED]	     = 0,	/* nothing known */
+	[DCCP_RESET_CODE_ABORTED]	     = ECONNRESET,
+
+	[DCCP_RESET_CODE_NO_CONNECTION]	     = ECONNREFUSED,
+	[DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED,
+	[DCCP_RESET_CODE_TOO_BUSY]	     = EUSERS,
+	[DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT,
+
+	[DCCP_RESET_CODE_PACKET_ERROR]	     = ENOMSG,
+	[DCCP_RESET_CODE_BAD_INIT_COOKIE]    = EBADR,
+	[DCCP_RESET_CODE_BAD_SERVICE_CODE]   = EBADRQC,
+	[DCCP_RESET_CODE_OPTION_ERROR]	     = EILSEQ,
+	[DCCP_RESET_CODE_MANDATORY_ERROR]    = EOPNOTSUPP,
+	};
+
+	return code <= DCCP_RESET_CODE_AGGRESSION_PENALTY? error_code[code] : 0;
+}
+
+static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb)
+{
+	u8 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code);
+
+	sk->sk_err = err;
+
+	/* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */
+	dccp_fin(sk, skb);
+
+	if (err && !sock_flag(sk, SOCK_DEAD))
+		sk_wake_async(sk, 0, POLL_ERR);
+	dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
+}
+
 static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
@@ -175,9 +211,8 @@ static int __dccp_rcv_established(struct
 		 *		S.state := TIMEWAIT
 		 *		Set TIMEWAIT timer
 		 *		Drop packet and return
-		*/
-		dccp_fin(sk, skb);
-		dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
+		 */
+		dccp_rcv_reset(sk, skb);
 		return 0;
 	case DCCP_PKT_CLOSEREQ:
 		dccp_rcv_closereq(sk, skb);
@@ -505,12 +540,7 @@ int dccp_rcv_state_process(struct sock *
 	 *		Drop packet and return
 	*/
 	if (dh->dccph_type = DCCP_PKT_RESET) {
-		/*
-		 * Queue the equivalent of TCP fin so that dccp_recvmsg
-		 * exits the loop
-		 */
-		dccp_fin(sk, skb);
-		dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
+		dccp_rcv_reset(sk, skb);
 		return 0;
 		/*
 		 *   Step 7: Check for unexpected packet types

             reply	other threads:[~2007-09-29 16:44 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-29 16:44 Gerrit Renker [this message]
2007-10-01 19:38 ` [PATCH 3/3]: Convert Reset code into socket error number Ian McDonald
2007-10-01 19:55 ` Arnaldo Carvalho de Melo
2007-10-01 20:07 ` Ian McDonald
2007-10-01 20:15 ` Arnaldo Carvalho de Melo
2007-10-02 10:04 ` Gerrit Renker
2007-10-02 10:08 ` Gerrit Renker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200709291744.53552@strip-the-willow \
    --to=gerrit@erg.abdn.ac.uk \
    --cc=dccp@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox