]> err.no Git - linux-2.6/blobdiff - net/dccp/input.c
[PATCH] parport: add NetMOS 9805 support
[linux-2.6] / net / dccp / input.c
index 4b8638f153a52c9133960beae389833e60bd5aff..ef29cef1dafe238196224bd8aed79cc139a2c329 100644 (file)
@@ -31,14 +31,10 @@ static void dccp_fin(struct sock *sk, struct sk_buff *skb)
 
 static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb)
 {
-       switch (sk->sk_state) {
-       case DCCP_PARTOPEN:
-       case DCCP_OPEN:
-               dccp_v4_send_reset(sk, DCCP_RESET_CODE_CLOSED);
-               dccp_fin(sk, skb);
-               dccp_set_state(sk, DCCP_CLOSED);
-               break;
-       }
+       dccp_v4_send_reset(sk, DCCP_RESET_CODE_CLOSED);
+       dccp_fin(sk, skb);
+       dccp_set_state(sk, DCCP_CLOSED);
+       sk_wake_async(sk, 1, POLL_HUP);
 }
 
 static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
@@ -50,17 +46,12 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
         *        Drop packet and return
         */
        if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) {
-               dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq);
+               dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC);
                return;
        }
 
-       switch (sk->sk_state) {
-       case DCCP_PARTOPEN:
-       case DCCP_OPEN:
-               dccp_set_state(sk, DCCP_CLOSING);
-               dccp_send_close(sk);
-               break;
-       }
+       dccp_set_state(sk, DCCP_CLOSING);
+       dccp_send_close(sk, 0);
 }
 
 static inline void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
@@ -76,8 +67,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
 {
        const struct dccp_hdr *dh = dccp_hdr(skb);
        struct dccp_sock *dp = dccp_sk(sk);
-       u64 lswl = dp->dccps_swl;
-       u64 lawl = dp->dccps_awl;
+       u64 lswl, lawl;
 
        /*
         *   Step 5: Prepare sequence numbers for Sync
@@ -99,6 +89,8 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
                        dccp_update_gsr(sk, DCCP_SKB_CB(skb)->dccpd_seq);
                else
                        return -1;
+       }
+       
        /*
         *   Step 6: Check sequence numbers
         *      Let LSWL = S.SWL and LAWL = S.AWL
@@ -113,9 +105,12 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
         *        Send Sync packet acknowledging P.seqno
         *        Drop packet and return
         */
-       } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ ||
-                  dh->dccph_type == DCCP_PKT_CLOSE ||
-                  dh->dccph_type == DCCP_PKT_RESET) {
+       lswl = dp->dccps_swl;
+       lawl = dp->dccps_awl;
+
+       if (dh->dccph_type == DCCP_PKT_CLOSEREQ ||
+           dh->dccph_type == DCCP_PKT_CLOSE ||
+           dh->dccph_type == DCCP_PKT_RESET) {
                lswl = dp->dccps_gsr;
                dccp_inc_seqno(&lswl);
                lawl = dp->dccps_gar;
@@ -132,8 +127,22 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
                     DCCP_PKT_WITHOUT_ACK_SEQ))
                        dp->dccps_gar = DCCP_SKB_CB(skb)->dccpd_ack_seq;
        } else {
-               dccp_pr_debug("Step 6 failed, sending SYNC...\n");
-               dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq);
+               LIMIT_NETDEBUG(KERN_WARNING "DCCP: Step 6 failed for %s packet, "
+                                           "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and "
+                                           "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), "
+                                           "sending SYNC...\n",
+                              dccp_packet_name(dh->dccph_type),
+                              (unsigned long long) lswl,
+                              (unsigned long long)
+                              DCCP_SKB_CB(skb)->dccpd_seq,
+                              (unsigned long long) dp->dccps_swh,
+                              (DCCP_SKB_CB(skb)->dccpd_ack_seq ==
+                               DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" : "exists",
+                              (unsigned long long) lawl,
+                              (unsigned long long)
+                              DCCP_SKB_CB(skb)->dccpd_ack_seq,
+                              (unsigned long long) dp->dccps_awh);
+               dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC);
                return -1;
        }
 
@@ -164,8 +173,8 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
                if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts,
                                     DCCP_SKB_CB(skb)->dccpd_seq,
                                     DCCP_ACKPKTS_STATE_RECEIVED)) {
-                       LIMIT_NETDEBUG(KERN_INFO "DCCP: acknowledgeable "
-                                                "packets buffer full!\n");
+                       LIMIT_NETDEBUG(KERN_WARNING "DCCP: acknowledgeable "
+                                                   "packets buffer full!\n");
                        ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
                        inet_csk_schedule_ack(sk);
                        inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
@@ -242,9 +251,21 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
 check_seq:
                if (!before48(DCCP_SKB_CB(skb)->dccpd_seq, dp->dccps_osr)) {
 send_sync:
-                       dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq);
+                       dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
+                                      DCCP_PKT_SYNC);
                }
                break;
+       case DCCP_PKT_SYNC:
+               dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
+                              DCCP_PKT_SYNCACK);
+               /*
+                * From the draft:
+                *
+                * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets
+                * MAY have non-zero-length application data areas, whose
+                * contents * receivers MUST ignore.
+                */
+               goto discard;
        }
 
        DCCP_INC_STATS_BH(DCCP_MIB_INERRS);
@@ -290,7 +311,19 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                }
 
                dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
-               dccp_update_gsr(sk, DCCP_SKB_CB(skb)->dccpd_seq);
+               dccp_update_gsr(sk, dp->dccps_isr);
+               /*
+                * SWL and AWL are initially adjusted so that they are not less than
+                * the initial Sequence Numbers received and sent, respectively:
+                *      SWL := max(GSR + 1 - floor(W/4), ISR),
+                *      AWL := max(GSS - W' + 1, ISS).
+                * These adjustments MUST be applied only at the beginning of the
+                * connection.
+                *
+                * AWL was adjusted in dccp_v4_connect -acme
+                */
+               dccp_set_seqno(&dp->dccps_swl,
+                              max48(dp->dccps_swl, dp->dccps_isr));
 
                if (ccid_hc_rx_init(dp->dccps_hc_rx_ccid, sk) != 0 ||
                    ccid_hc_tx_init(dp->dccps_hc_tx_ccid, sk) != 0) {
@@ -402,7 +435,48 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
        const int old_state = sk->sk_state;
        int queued = 0;
 
-       if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING) {
+       /*
+        *  Step 3: Process LISTEN state
+        *      (Continuing from dccp_v4_do_rcv and dccp_v6_do_rcv)
+        *
+        *     If S.state == LISTEN,
+        *        If P.type == Request or P contains a valid Init Cookie
+        *              option,
+        *           * Must scan the packet's options to check for an Init
+        *              Cookie.  Only the Init Cookie is processed here,
+        *              however; other options are processed in Step 8.  This
+        *              scan need only be performed if the endpoint uses Init
+        *              Cookies *
+        *           * Generate a new socket and switch to that socket *
+        *           Set S := new socket for this port pair
+        *           S.state = RESPOND
+        *           Choose S.ISS (initial seqno) or set from Init Cookie
+        *           Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
+        *           Continue with S.state == RESPOND
+        *           * A Response packet will be generated in Step 11 *
+        *        Otherwise,
+        *           Generate Reset(No Connection) unless P.type == Reset
+        *           Drop packet and return
+        *
+        * NOTE: the check for the packet types is done in
+        *       dccp_rcv_state_process
+        */
+       if (sk->sk_state == DCCP_LISTEN) {
+               if (dh->dccph_type == DCCP_PKT_REQUEST) {
+                       if (dccp_v4_conn_request(sk, skb) < 0)
+                               return 1;
+
+                       /* FIXME: do congestion control initialization */
+                       goto discard;
+               }
+               if (dh->dccph_type == DCCP_PKT_RESET)
+                       goto discard;
+
+               /* Caller (dccp_v4_do_rcv) will send Reset(No Connection)*/
+               return 1;
+       }
+
+       if (sk->sk_state != DCCP_REQUESTING) {
                if (dccp_check_seqno(sk, skb))
                        goto discard;
 
@@ -476,31 +550,21 @@ 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_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
+                              DCCP_PKT_SYNC);
+               goto discard;
+       } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) {
+               dccp_rcv_closereq(sk, skb);
                goto discard;
+       } else if (dh->dccph_type == DCCP_PKT_CLOSE) {
+               dccp_rcv_close(sk, skb);
+               return 0;
        }
 
        switch (sk->sk_state) {
        case DCCP_CLOSED:
                return 1;
 
-       case DCCP_LISTEN:
-               if (dh->dccph_type == DCCP_PKT_ACK ||
-                   dh->dccph_type == DCCP_PKT_DATAACK)
-                       return 1;
-
-               if (dh->dccph_type == DCCP_PKT_RESET)
-                       goto discard;
-
-               if (dh->dccph_type == DCCP_PKT_REQUEST) {
-                       if (dccp_v4_conn_request(sk, skb) < 0)
-                               return 1;
-
-                       /* FIXME: do congestion control initialization */
-                       goto discard;
-               }
-               goto discard;
-
        case DCCP_REQUESTING:
                /* FIXME: do congestion control initialization */