17c657876SArnaldo Carvalho de Melo /* 27c657876SArnaldo Carvalho de Melo * net/dccp/input.c 37c657876SArnaldo Carvalho de Melo * 47c657876SArnaldo Carvalho de Melo * An implementation of the DCCP protocol 57c657876SArnaldo Carvalho de Melo * Arnaldo Carvalho de Melo <acme@conectiva.com.br> 67c657876SArnaldo Carvalho de Melo * 77c657876SArnaldo Carvalho de Melo * This program is free software; you can redistribute it and/or 87c657876SArnaldo Carvalho de Melo * modify it under the terms of the GNU General Public License 97c657876SArnaldo Carvalho de Melo * as published by the Free Software Foundation; either version 107c657876SArnaldo Carvalho de Melo * 2 of the License, or (at your option) any later version. 117c657876SArnaldo Carvalho de Melo */ 127c657876SArnaldo Carvalho de Melo 137c657876SArnaldo Carvalho de Melo #include <linux/dccp.h> 147c657876SArnaldo Carvalho de Melo #include <linux/skbuff.h> 157c657876SArnaldo Carvalho de Melo 167c657876SArnaldo Carvalho de Melo #include <net/sock.h> 177c657876SArnaldo Carvalho de Melo 18ae31c339SArnaldo Carvalho de Melo #include "ackvec.h" 197c657876SArnaldo Carvalho de Melo #include "ccid.h" 207c657876SArnaldo Carvalho de Melo #include "dccp.h" 217c657876SArnaldo Carvalho de Melo 22bd5435e7SIngo Molnar /* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ 23bd5435e7SIngo Molnar int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; 24bd5435e7SIngo Molnar 2569567d0bSGerrit Renker static void dccp_enqueue_skb(struct sock *sk, struct sk_buff *skb) 267c657876SArnaldo Carvalho de Melo { 277c657876SArnaldo Carvalho de Melo __skb_pull(skb, dccp_hdr(skb)->dccph_doff * 4); 287c657876SArnaldo Carvalho de Melo __skb_queue_tail(&sk->sk_receive_queue, skb); 297c657876SArnaldo Carvalho de Melo skb_set_owner_r(skb, sk); 307c657876SArnaldo Carvalho de Melo sk->sk_data_ready(sk, 0); 317c657876SArnaldo Carvalho de Melo } 327c657876SArnaldo Carvalho de Melo 3369567d0bSGerrit Renker static void dccp_fin(struct sock *sk, struct sk_buff *skb) 3469567d0bSGerrit Renker { 3569567d0bSGerrit Renker /* 3669567d0bSGerrit Renker * On receiving Close/CloseReq, both RD/WR shutdown are performed. 3769567d0bSGerrit Renker * RFC 4340, 8.3 says that we MAY send further Data/DataAcks after 3869567d0bSGerrit Renker * receiving the closing segment, but there is no guarantee that such 3969567d0bSGerrit Renker * data will be processed at all. 4069567d0bSGerrit Renker */ 4169567d0bSGerrit Renker sk->sk_shutdown = SHUTDOWN_MASK; 4269567d0bSGerrit Renker sock_set_flag(sk, SOCK_DONE); 4369567d0bSGerrit Renker dccp_enqueue_skb(sk, skb); 4469567d0bSGerrit Renker } 4569567d0bSGerrit Renker 460c869620SGerrit Renker static int dccp_rcv_close(struct sock *sk, struct sk_buff *skb) 477c657876SArnaldo Carvalho de Melo { 480c869620SGerrit Renker int queued = 0; 490c869620SGerrit Renker 500c869620SGerrit Renker switch (sk->sk_state) { 510c869620SGerrit Renker /* 520c869620SGerrit Renker * We ignore Close when received in one of the following states: 530c869620SGerrit Renker * - CLOSED (may be a late or duplicate packet) 540c869620SGerrit Renker * - PASSIVE_CLOSEREQ (the peer has sent a CloseReq earlier) 550c869620SGerrit Renker * - RESPOND (already handled by dccp_check_req) 560c869620SGerrit Renker */ 570c869620SGerrit Renker case DCCP_CLOSING: 580c869620SGerrit Renker /* 590c869620SGerrit Renker * Simultaneous-close: receiving a Close after sending one. This 600c869620SGerrit Renker * can happen if both client and server perform active-close and 610c869620SGerrit Renker * will result in an endless ping-pong of crossing and retrans- 620c869620SGerrit Renker * mitted Close packets, which only terminates when one of the 630c869620SGerrit Renker * nodes times out (min. 64 seconds). Quicker convergence can be 640c869620SGerrit Renker * achieved when one of the nodes acts as tie-breaker. 650c869620SGerrit Renker * This is ok as both ends are done with data transfer and each 660c869620SGerrit Renker * end is just waiting for the other to acknowledge termination. 670c869620SGerrit Renker */ 680c869620SGerrit Renker if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) 690c869620SGerrit Renker break; 700c869620SGerrit Renker /* fall through */ 710c869620SGerrit Renker case DCCP_REQUESTING: 720c869620SGerrit Renker case DCCP_ACTIVE_CLOSEREQ: 73017487d7SArnaldo Carvalho de Melo dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED); 740c869620SGerrit Renker dccp_done(sk); 750c869620SGerrit Renker break; 760c869620SGerrit Renker case DCCP_OPEN: 770c869620SGerrit Renker case DCCP_PARTOPEN: 780c869620SGerrit Renker /* Give waiting application a chance to read pending data */ 790c869620SGerrit Renker queued = 1; 807c657876SArnaldo Carvalho de Melo dccp_fin(sk, skb); 810c869620SGerrit Renker dccp_set_state(sk, DCCP_PASSIVE_CLOSE); 820c869620SGerrit Renker /* fall through */ 830c869620SGerrit Renker case DCCP_PASSIVE_CLOSE: 840c869620SGerrit Renker /* 850c869620SGerrit Renker * Retransmitted Close: we have already enqueued the first one. 860c869620SGerrit Renker */ 878d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP); 887c657876SArnaldo Carvalho de Melo } 890c869620SGerrit Renker return queued; 900c869620SGerrit Renker } 917c657876SArnaldo Carvalho de Melo 920c869620SGerrit Renker static int dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb) 937c657876SArnaldo Carvalho de Melo { 940c869620SGerrit Renker int queued = 0; 950c869620SGerrit Renker 967c657876SArnaldo Carvalho de Melo /* 977c657876SArnaldo Carvalho de Melo * Step 7: Check for unexpected packet types 987c657876SArnaldo Carvalho de Melo * If (S.is_server and P.type == CloseReq) 997c657876SArnaldo Carvalho de Melo * Send Sync packet acknowledging P.seqno 1007c657876SArnaldo Carvalho de Melo * Drop packet and return 1017c657876SArnaldo Carvalho de Melo */ 1027c657876SArnaldo Carvalho de Melo if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) { 103e92ae93aSArnaldo Carvalho de Melo dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC); 1040c869620SGerrit Renker return queued; 1057c657876SArnaldo Carvalho de Melo } 1067c657876SArnaldo Carvalho de Melo 1070c869620SGerrit Renker /* Step 13: process relevant Client states < CLOSEREQ */ 1080c869620SGerrit Renker switch (sk->sk_state) { 1090c869620SGerrit Renker case DCCP_REQUESTING: 1107ad07e7cSArnaldo Carvalho de Melo dccp_send_close(sk, 0); 1110c869620SGerrit Renker dccp_set_state(sk, DCCP_CLOSING); 1120c869620SGerrit Renker break; 1130c869620SGerrit Renker case DCCP_OPEN: 1140c869620SGerrit Renker case DCCP_PARTOPEN: 1150c869620SGerrit Renker /* Give waiting application a chance to read pending data */ 1160c869620SGerrit Renker queued = 1; 1170c869620SGerrit Renker dccp_fin(sk, skb); 1180c869620SGerrit Renker dccp_set_state(sk, DCCP_PASSIVE_CLOSEREQ); 1190c869620SGerrit Renker /* fall through */ 1200c869620SGerrit Renker case DCCP_PASSIVE_CLOSEREQ: 1210c869620SGerrit Renker sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP); 1220c869620SGerrit Renker } 1230c869620SGerrit Renker return queued; 1247c657876SArnaldo Carvalho de Melo } 1257c657876SArnaldo Carvalho de Melo 126d8ef2c29SGerrit Renker static u8 dccp_reset_code_convert(const u8 code) 127d8ef2c29SGerrit Renker { 128d8ef2c29SGerrit Renker const u8 error_code[] = { 129d8ef2c29SGerrit Renker [DCCP_RESET_CODE_CLOSED] = 0, /* normal termination */ 130d8ef2c29SGerrit Renker [DCCP_RESET_CODE_UNSPECIFIED] = 0, /* nothing known */ 131d8ef2c29SGerrit Renker [DCCP_RESET_CODE_ABORTED] = ECONNRESET, 132d8ef2c29SGerrit Renker 133d8ef2c29SGerrit Renker [DCCP_RESET_CODE_NO_CONNECTION] = ECONNREFUSED, 134d8ef2c29SGerrit Renker [DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED, 135d8ef2c29SGerrit Renker [DCCP_RESET_CODE_TOO_BUSY] = EUSERS, 136d8ef2c29SGerrit Renker [DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT, 137d8ef2c29SGerrit Renker 138d8ef2c29SGerrit Renker [DCCP_RESET_CODE_PACKET_ERROR] = ENOMSG, 139d8ef2c29SGerrit Renker [DCCP_RESET_CODE_BAD_INIT_COOKIE] = EBADR, 140d8ef2c29SGerrit Renker [DCCP_RESET_CODE_BAD_SERVICE_CODE] = EBADRQC, 141d8ef2c29SGerrit Renker [DCCP_RESET_CODE_OPTION_ERROR] = EILSEQ, 142d8ef2c29SGerrit Renker [DCCP_RESET_CODE_MANDATORY_ERROR] = EOPNOTSUPP, 143d8ef2c29SGerrit Renker }; 144d8ef2c29SGerrit Renker 145d8ef2c29SGerrit Renker return code >= DCCP_MAX_RESET_CODES ? 0 : error_code[code]; 146d8ef2c29SGerrit Renker } 147d8ef2c29SGerrit Renker 148d8ef2c29SGerrit Renker static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) 149d8ef2c29SGerrit Renker { 150d8ef2c29SGerrit Renker u8 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code); 151d8ef2c29SGerrit Renker 152d8ef2c29SGerrit Renker sk->sk_err = err; 153d8ef2c29SGerrit Renker 154d8ef2c29SGerrit Renker /* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */ 155d8ef2c29SGerrit Renker dccp_fin(sk, skb); 156d8ef2c29SGerrit Renker 157d8ef2c29SGerrit Renker if (err && !sock_flag(sk, SOCK_DEAD)) 1588d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR); 159d8ef2c29SGerrit Renker dccp_time_wait(sk, DCCP_TIME_WAIT, 0); 160d8ef2c29SGerrit Renker } 161d8ef2c29SGerrit Renker 162c25a18baSArnaldo Carvalho de Melo static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) 1637c657876SArnaldo Carvalho de Melo { 1647c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 1657c657876SArnaldo Carvalho de Melo 166a4bf3902SArnaldo Carvalho de Melo if (dccp_msk(sk)->dccpms_send_ack_vector) 167ae31c339SArnaldo Carvalho de Melo dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk, 1687c657876SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_ack_seq); 1697c657876SArnaldo Carvalho de Melo } 1707c657876SArnaldo Carvalho de Melo 1718e8c71f1SGerrit Renker static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) 1728e8c71f1SGerrit Renker { 1738e8c71f1SGerrit Renker const struct dccp_sock *dp = dccp_sk(sk); 1748e8c71f1SGerrit Renker 1758e8c71f1SGerrit Renker /* Don't deliver to RX CCID when node has shut down read end. */ 1768e8c71f1SGerrit Renker if (!(sk->sk_shutdown & RCV_SHUTDOWN)) 1778e8c71f1SGerrit Renker ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); 1788e8c71f1SGerrit Renker /* 1798e8c71f1SGerrit Renker * Until the TX queue has been drained, we can not honour SHUT_WR, since 1808e8c71f1SGerrit Renker * we need received feedback as input to adjust congestion control. 1818e8c71f1SGerrit Renker */ 1828e8c71f1SGerrit Renker if (sk->sk_write_queue.qlen > 0 || !(sk->sk_shutdown & SEND_SHUTDOWN)) 1838e8c71f1SGerrit Renker ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); 1848e8c71f1SGerrit Renker } 1858e8c71f1SGerrit Renker 1867c657876SArnaldo Carvalho de Melo static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) 1877c657876SArnaldo Carvalho de Melo { 1887c657876SArnaldo Carvalho de Melo const struct dccp_hdr *dh = dccp_hdr(skb); 1897c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 190cbe1f5f8SGerrit Renker u64 lswl, lawl, seqno = DCCP_SKB_CB(skb)->dccpd_seq, 191cbe1f5f8SGerrit Renker ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; 1927c657876SArnaldo Carvalho de Melo 1937c657876SArnaldo Carvalho de Melo /* 1947c657876SArnaldo Carvalho de Melo * Step 5: Prepare sequence numbers for Sync 1957c657876SArnaldo Carvalho de Melo * If P.type == Sync or P.type == SyncAck, 1967c657876SArnaldo Carvalho de Melo * If S.AWL <= P.ackno <= S.AWH and P.seqno >= S.SWL, 1977c657876SArnaldo Carvalho de Melo * / * P is valid, so update sequence number variables 1987c657876SArnaldo Carvalho de Melo * accordingly. After this update, P will pass the tests 1997c657876SArnaldo Carvalho de Melo * in Step 6. A SyncAck is generated if necessary in 2007c657876SArnaldo Carvalho de Melo * Step 15 * / 2017c657876SArnaldo Carvalho de Melo * Update S.GSR, S.SWL, S.SWH 2027c657876SArnaldo Carvalho de Melo * Otherwise, 2037c657876SArnaldo Carvalho de Melo * Drop packet and return 2047c657876SArnaldo Carvalho de Melo */ 2057c657876SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_SYNC || 2067c657876SArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_SYNCACK) { 207cbe1f5f8SGerrit Renker if (between48(ackno, dp->dccps_awl, dp->dccps_awh) && 208cbe1f5f8SGerrit Renker dccp_delta_seqno(dp->dccps_swl, seqno) >= 0) 209cbe1f5f8SGerrit Renker dccp_update_gsr(sk, seqno); 2107c657876SArnaldo Carvalho de Melo else 2117c657876SArnaldo Carvalho de Melo return -1; 212e92ae93aSArnaldo Carvalho de Melo } 213e92ae93aSArnaldo Carvalho de Melo 2147c657876SArnaldo Carvalho de Melo /* 2157c657876SArnaldo Carvalho de Melo * Step 6: Check sequence numbers 2167c657876SArnaldo Carvalho de Melo * Let LSWL = S.SWL and LAWL = S.AWL 2177c657876SArnaldo Carvalho de Melo * If P.type == CloseReq or P.type == Close or P.type == Reset, 2187c657876SArnaldo Carvalho de Melo * LSWL := S.GSR + 1, LAWL := S.GAR 2197c657876SArnaldo Carvalho de Melo * If LSWL <= P.seqno <= S.SWH 2207c657876SArnaldo Carvalho de Melo * and (P.ackno does not exist or LAWL <= P.ackno <= S.AWH), 2217c657876SArnaldo Carvalho de Melo * Update S.GSR, S.SWL, S.SWH 2227c657876SArnaldo Carvalho de Melo * If P.type != Sync, 2237c657876SArnaldo Carvalho de Melo * Update S.GAR 2247c657876SArnaldo Carvalho de Melo */ 225e92ae93aSArnaldo Carvalho de Melo lswl = dp->dccps_swl; 226e92ae93aSArnaldo Carvalho de Melo lawl = dp->dccps_awl; 227e92ae93aSArnaldo Carvalho de Melo 228e92ae93aSArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_CLOSEREQ || 2297c657876SArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_CLOSE || 2307c657876SArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_RESET) { 231cbe1f5f8SGerrit Renker lswl = ADD48(dp->dccps_gsr, 1); 2327c657876SArnaldo Carvalho de Melo lawl = dp->dccps_gar; 2337c657876SArnaldo Carvalho de Melo } 2347c657876SArnaldo Carvalho de Melo 235cbe1f5f8SGerrit Renker if (between48(seqno, lswl, dp->dccps_swh) && 236cbe1f5f8SGerrit Renker (ackno == DCCP_PKT_WITHOUT_ACK_SEQ || 237cbe1f5f8SGerrit Renker between48(ackno, lawl, dp->dccps_awh))) { 238cbe1f5f8SGerrit Renker dccp_update_gsr(sk, seqno); 2397c657876SArnaldo Carvalho de Melo 2407c657876SArnaldo Carvalho de Melo if (dh->dccph_type != DCCP_PKT_SYNC && 241cbe1f5f8SGerrit Renker (ackno != DCCP_PKT_WITHOUT_ACK_SEQ)) 242cbe1f5f8SGerrit Renker dp->dccps_gar = ackno; 2437c657876SArnaldo Carvalho de Melo } else { 244a94f0f97SGerrit Renker unsigned long now = jiffies; 245a94f0f97SGerrit Renker /* 246a94f0f97SGerrit Renker * Step 6: Check sequence numbers 247a94f0f97SGerrit Renker * Otherwise, 248a94f0f97SGerrit Renker * If P.type == Reset, 249a94f0f97SGerrit Renker * Send Sync packet acknowledging S.GSR 250a94f0f97SGerrit Renker * Otherwise, 251a94f0f97SGerrit Renker * Send Sync packet acknowledging P.seqno 252a94f0f97SGerrit Renker * Drop packet and return 253a94f0f97SGerrit Renker * 254a94f0f97SGerrit Renker * These Syncs are rate-limited as per RFC 4340, 7.5.4: 255a94f0f97SGerrit Renker * at most 1 / (dccp_sync_rate_limit * HZ) Syncs per second. 256a94f0f97SGerrit Renker */ 257a94f0f97SGerrit Renker if (time_before(now, (dp->dccps_rate_last + 258a94f0f97SGerrit Renker sysctl_dccp_sync_ratelimit))) 259a94f0f97SGerrit Renker return 0; 260a94f0f97SGerrit Renker 26159348b19SGerrit Renker DCCP_WARN("DCCP: Step 6 failed for %s packet, " 262a3054d48SArnaldo Carvalho de Melo "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " 263a3054d48SArnaldo Carvalho de Melo "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " 26459348b19SGerrit Renker "sending SYNC...\n", dccp_packet_name(dh->dccph_type), 265cbe1f5f8SGerrit Renker (unsigned long long) lswl, (unsigned long long) seqno, 26658e45131SDavid S. Miller (unsigned long long) dp->dccps_swh, 267cbe1f5f8SGerrit Renker (ackno == DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" 268cbe1f5f8SGerrit Renker : "exists", 269cbe1f5f8SGerrit Renker (unsigned long long) lawl, (unsigned long long) ackno, 27058e45131SDavid S. Miller (unsigned long long) dp->dccps_awh); 271a94f0f97SGerrit Renker 272a94f0f97SGerrit Renker dp->dccps_rate_last = now; 273a94f0f97SGerrit Renker 274e155d769SGerrit Renker if (dh->dccph_type == DCCP_PKT_RESET) 275e155d769SGerrit Renker seqno = dp->dccps_gsr; 276cbe1f5f8SGerrit Renker dccp_send_sync(sk, seqno, DCCP_PKT_SYNC); 2777c657876SArnaldo Carvalho de Melo return -1; 2787c657876SArnaldo Carvalho de Melo } 2797c657876SArnaldo Carvalho de Melo 2807c657876SArnaldo Carvalho de Melo return 0; 2817c657876SArnaldo Carvalho de Melo } 2827c657876SArnaldo Carvalho de Melo 283c25a18baSArnaldo Carvalho de Melo static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, 284c25a18baSArnaldo Carvalho de Melo const struct dccp_hdr *dh, const unsigned len) 2857c657876SArnaldo Carvalho de Melo { 2867c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 2877c657876SArnaldo Carvalho de Melo 2887c657876SArnaldo Carvalho de Melo switch (dccp_hdr(skb)->dccph_type) { 2897c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATAACK: 2907c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATA: 2917c657876SArnaldo Carvalho de Melo /* 2928e8c71f1SGerrit Renker * FIXME: schedule DATA_DROPPED (RFC 4340, 11.7.2) if and when 2938e8c71f1SGerrit Renker * - sk_shutdown == RCV_SHUTDOWN, use Code 1, "Not Listening" 2948e8c71f1SGerrit Renker * - sk_receive_queue is full, use Code 2, "Receive Buffer" 2957c657876SArnaldo Carvalho de Melo */ 29669567d0bSGerrit Renker dccp_enqueue_skb(sk, skb); 2977c657876SArnaldo Carvalho de Melo return 0; 2987c657876SArnaldo Carvalho de Melo case DCCP_PKT_ACK: 2997c657876SArnaldo Carvalho de Melo goto discard; 3007c657876SArnaldo Carvalho de Melo case DCCP_PKT_RESET: 3017c657876SArnaldo Carvalho de Melo /* 3027c657876SArnaldo Carvalho de Melo * Step 9: Process Reset 3037c657876SArnaldo Carvalho de Melo * If P.type == Reset, 3047c657876SArnaldo Carvalho de Melo * Tear down connection 3057c657876SArnaldo Carvalho de Melo * S.state := TIMEWAIT 3067c657876SArnaldo Carvalho de Melo * Set TIMEWAIT timer 3077c657876SArnaldo Carvalho de Melo * Drop packet and return 3087c657876SArnaldo Carvalho de Melo */ 309d8ef2c29SGerrit Renker dccp_rcv_reset(sk, skb); 3107c657876SArnaldo Carvalho de Melo return 0; 3117c657876SArnaldo Carvalho de Melo case DCCP_PKT_CLOSEREQ: 3120c869620SGerrit Renker if (dccp_rcv_closereq(sk, skb)) 3130c869620SGerrit Renker return 0; 3147c657876SArnaldo Carvalho de Melo goto discard; 3157c657876SArnaldo Carvalho de Melo case DCCP_PKT_CLOSE: 3160c869620SGerrit Renker if (dccp_rcv_close(sk, skb)) 3177c657876SArnaldo Carvalho de Melo return 0; 3180c869620SGerrit Renker goto discard; 3197c657876SArnaldo Carvalho de Melo case DCCP_PKT_REQUEST: 3207c657876SArnaldo Carvalho de Melo /* Step 7 3217c657876SArnaldo Carvalho de Melo * or (S.is_server and P.type == Response) 3227c657876SArnaldo Carvalho de Melo * or (S.is_client and P.type == Request) 3237c657876SArnaldo Carvalho de Melo * or (S.state >= OPEN and P.type == Request 3247c657876SArnaldo Carvalho de Melo * and P.seqno >= S.OSR) 3257c657876SArnaldo Carvalho de Melo * or (S.state >= OPEN and P.type == Response 3267c657876SArnaldo Carvalho de Melo * and P.seqno >= S.OSR) 3277c657876SArnaldo Carvalho de Melo * or (S.state == RESPOND and P.type == Data), 3287c657876SArnaldo Carvalho de Melo * Send Sync packet acknowledging P.seqno 3297c657876SArnaldo Carvalho de Melo * Drop packet and return 3307c657876SArnaldo Carvalho de Melo */ 3317c657876SArnaldo Carvalho de Melo if (dp->dccps_role != DCCP_ROLE_LISTEN) 3327c657876SArnaldo Carvalho de Melo goto send_sync; 3337c657876SArnaldo Carvalho de Melo goto check_seq; 3347c657876SArnaldo Carvalho de Melo case DCCP_PKT_RESPONSE: 3357c657876SArnaldo Carvalho de Melo if (dp->dccps_role != DCCP_ROLE_CLIENT) 3367c657876SArnaldo Carvalho de Melo goto send_sync; 3377c657876SArnaldo Carvalho de Melo check_seq: 3388d13bf9aSGerrit Renker if (dccp_delta_seqno(dp->dccps_osr, 3398d13bf9aSGerrit Renker DCCP_SKB_CB(skb)->dccpd_seq) >= 0) { 3407c657876SArnaldo Carvalho de Melo send_sync: 341e92ae93aSArnaldo Carvalho de Melo dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, 342e92ae93aSArnaldo Carvalho de Melo DCCP_PKT_SYNC); 3437c657876SArnaldo Carvalho de Melo } 3447c657876SArnaldo Carvalho de Melo break; 345e92ae93aSArnaldo Carvalho de Melo case DCCP_PKT_SYNC: 346e92ae93aSArnaldo Carvalho de Melo dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, 347e92ae93aSArnaldo Carvalho de Melo DCCP_PKT_SYNCACK); 348e92ae93aSArnaldo Carvalho de Melo /* 3490e64e94eSGerrit Renker * From RFC 4340, sec. 5.7 350e92ae93aSArnaldo Carvalho de Melo * 351e92ae93aSArnaldo Carvalho de Melo * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets 352e92ae93aSArnaldo Carvalho de Melo * MAY have non-zero-length application data areas, whose 3530e64e94eSGerrit Renker * contents receivers MUST ignore. 354e92ae93aSArnaldo Carvalho de Melo */ 355e92ae93aSArnaldo Carvalho de Melo goto discard; 3567c657876SArnaldo Carvalho de Melo } 3577c657876SArnaldo Carvalho de Melo 3587c657876SArnaldo Carvalho de Melo DCCP_INC_STATS_BH(DCCP_MIB_INERRS); 3597c657876SArnaldo Carvalho de Melo discard: 3607c657876SArnaldo Carvalho de Melo __kfree_skb(skb); 3617c657876SArnaldo Carvalho de Melo return 0; 3627c657876SArnaldo Carvalho de Melo } 3637c657876SArnaldo Carvalho de Melo 364709dd3aaSAndrea Bittau int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, 365709dd3aaSAndrea Bittau const struct dccp_hdr *dh, const unsigned len) 366709dd3aaSAndrea Bittau { 367709dd3aaSAndrea Bittau struct dccp_sock *dp = dccp_sk(sk); 368709dd3aaSAndrea Bittau 369709dd3aaSAndrea Bittau if (dccp_check_seqno(sk, skb)) 370709dd3aaSAndrea Bittau goto discard; 371709dd3aaSAndrea Bittau 3728b819412SGerrit Renker if (dccp_parse_options(sk, NULL, skb)) 373*ba1a6c7bSWei Yongjun return 1; 374709dd3aaSAndrea Bittau 375709dd3aaSAndrea Bittau if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 376709dd3aaSAndrea Bittau dccp_event_ack_recv(sk, skb); 377709dd3aaSAndrea Bittau 378a4bf3902SArnaldo Carvalho de Melo if (dccp_msk(sk)->dccpms_send_ack_vector && 379709dd3aaSAndrea Bittau dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, 380709dd3aaSAndrea Bittau DCCP_SKB_CB(skb)->dccpd_seq, 381709dd3aaSAndrea Bittau DCCP_ACKVEC_STATE_RECEIVED)) 382709dd3aaSAndrea Bittau goto discard; 3838e8c71f1SGerrit Renker dccp_deliver_input_to_ccids(sk, skb); 384709dd3aaSAndrea Bittau 385709dd3aaSAndrea Bittau return __dccp_rcv_established(sk, skb, dh, len); 386709dd3aaSAndrea Bittau discard: 387709dd3aaSAndrea Bittau __kfree_skb(skb); 388709dd3aaSAndrea Bittau return 0; 389709dd3aaSAndrea Bittau } 390709dd3aaSAndrea Bittau 391f21e68caSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_rcv_established); 392f21e68caSArnaldo Carvalho de Melo 3937c657876SArnaldo Carvalho de Melo static int dccp_rcv_request_sent_state_process(struct sock *sk, 3947c657876SArnaldo Carvalho de Melo struct sk_buff *skb, 3957c657876SArnaldo Carvalho de Melo const struct dccp_hdr *dh, 3967c657876SArnaldo Carvalho de Melo const unsigned len) 3977c657876SArnaldo Carvalho de Melo { 3987c657876SArnaldo Carvalho de Melo /* 3997c657876SArnaldo Carvalho de Melo * Step 4: Prepare sequence numbers in REQUEST 4007c657876SArnaldo Carvalho de Melo * If S.state == REQUEST, 4017c657876SArnaldo Carvalho de Melo * If (P.type == Response or P.type == Reset) 4027c657876SArnaldo Carvalho de Melo * and S.AWL <= P.ackno <= S.AWH, 4037c657876SArnaldo Carvalho de Melo * / * Set sequence number variables corresponding to the 4047c657876SArnaldo Carvalho de Melo * other endpoint, so P will pass the tests in Step 6 * / 4057c657876SArnaldo Carvalho de Melo * Set S.GSR, S.ISR, S.SWL, S.SWH 4067c657876SArnaldo Carvalho de Melo * / * Response processing continues in Step 10; Reset 4077c657876SArnaldo Carvalho de Melo * processing continues in Step 9 * / 4087c657876SArnaldo Carvalho de Melo */ 4097c657876SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_RESPONSE) { 4107c657876SArnaldo Carvalho de Melo const struct inet_connection_sock *icsk = inet_csk(sk); 4117c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 4123393da82SGerrit Renker long tstamp = dccp_timestamp(); 4137c657876SArnaldo Carvalho de Melo 4147690af3fSArnaldo Carvalho de Melo if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq, 4157690af3fSArnaldo Carvalho de Melo dp->dccps_awl, dp->dccps_awh)) { 4167690af3fSArnaldo Carvalho de Melo dccp_pr_debug("invalid ackno: S.AWL=%llu, " 4177690af3fSArnaldo Carvalho de Melo "P.ackno=%llu, S.AWH=%llu \n", 418f6ccf554SDavid S. Miller (unsigned long long)dp->dccps_awl, 419f6ccf554SDavid S. Miller (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, 420f6ccf554SDavid S. Miller (unsigned long long)dp->dccps_awh); 4217c657876SArnaldo Carvalho de Melo goto out_invalid_packet; 4227c657876SArnaldo Carvalho de Melo } 4237c657876SArnaldo Carvalho de Melo 4248b819412SGerrit Renker if (dccp_parse_options(sk, NULL, skb)) 425afe00251SAndrea Bittau goto out_invalid_packet; 426afe00251SAndrea Bittau 4273393da82SGerrit Renker /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ 4283393da82SGerrit Renker if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) 4293393da82SGerrit Renker dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp - 4303393da82SGerrit Renker dp->dccps_options_received.dccpor_timestamp_echo)); 43189560b53SGerrit Renker 432a4bf3902SArnaldo Carvalho de Melo if (dccp_msk(sk)->dccpms_send_ack_vector && 4339e377202SAndrea Bittau dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, 4349e377202SAndrea Bittau DCCP_SKB_CB(skb)->dccpd_seq, 4359e377202SAndrea Bittau DCCP_ACKVEC_STATE_RECEIVED)) 4369e377202SAndrea Bittau goto out_invalid_packet; /* FIXME: change error code */ 4379e377202SAndrea Bittau 438d28934adSGerrit Renker /* Stop the REQUEST timer */ 439d28934adSGerrit Renker inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); 440d28934adSGerrit Renker WARN_ON(sk->sk_send_head == NULL); 441d28934adSGerrit Renker kfree_skb(sk->sk_send_head); 442d28934adSGerrit Renker sk->sk_send_head = NULL; 443d28934adSGerrit Renker 4447c657876SArnaldo Carvalho de Melo dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; 44503ace394SArnaldo Carvalho de Melo dccp_update_gsr(sk, dp->dccps_isr); 44603ace394SArnaldo Carvalho de Melo /* 44703ace394SArnaldo Carvalho de Melo * SWL and AWL are initially adjusted so that they are not less than 44803ace394SArnaldo Carvalho de Melo * the initial Sequence Numbers received and sent, respectively: 44903ace394SArnaldo Carvalho de Melo * SWL := max(GSR + 1 - floor(W/4), ISR), 45003ace394SArnaldo Carvalho de Melo * AWL := max(GSS - W' + 1, ISS). 45103ace394SArnaldo Carvalho de Melo * These adjustments MUST be applied only at the beginning of the 45203ace394SArnaldo Carvalho de Melo * connection. 45303ace394SArnaldo Carvalho de Melo * 45403ace394SArnaldo Carvalho de Melo * AWL was adjusted in dccp_v4_connect -acme 45503ace394SArnaldo Carvalho de Melo */ 45603ace394SArnaldo Carvalho de Melo dccp_set_seqno(&dp->dccps_swl, 45703ace394SArnaldo Carvalho de Melo max48(dp->dccps_swl, dp->dccps_isr)); 4587c657876SArnaldo Carvalho de Melo 459d83d8461SArnaldo Carvalho de Melo dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); 4607c657876SArnaldo Carvalho de Melo 4617c657876SArnaldo Carvalho de Melo /* 4627c657876SArnaldo Carvalho de Melo * Step 10: Process REQUEST state (second part) 4637c657876SArnaldo Carvalho de Melo * If S.state == REQUEST, 4647690af3fSArnaldo Carvalho de Melo * / * If we get here, P is a valid Response from the 4657690af3fSArnaldo Carvalho de Melo * server (see Step 4), and we should move to 4667690af3fSArnaldo Carvalho de Melo * PARTOPEN state. PARTOPEN means send an Ack, 4677690af3fSArnaldo Carvalho de Melo * don't send Data packets, retransmit Acks 4687690af3fSArnaldo Carvalho de Melo * periodically, and always include any Init Cookie 4697690af3fSArnaldo Carvalho de Melo * from the Response * / 4707c657876SArnaldo Carvalho de Melo * S.state := PARTOPEN 4717c657876SArnaldo Carvalho de Melo * Set PARTOPEN timer 4727c657876SArnaldo Carvalho de Melo * Continue with S.state == PARTOPEN 4737690af3fSArnaldo Carvalho de Melo * / * Step 12 will send the Ack completing the 4747690af3fSArnaldo Carvalho de Melo * three-way handshake * / 4757c657876SArnaldo Carvalho de Melo */ 4767c657876SArnaldo Carvalho de Melo dccp_set_state(sk, DCCP_PARTOPEN); 4777c657876SArnaldo Carvalho de Melo 4787c657876SArnaldo Carvalho de Melo /* Make sure socket is routed, for correct metrics. */ 47957cca05aSArnaldo Carvalho de Melo icsk->icsk_af_ops->rebuild_header(sk); 4807c657876SArnaldo Carvalho de Melo 4817c657876SArnaldo Carvalho de Melo if (!sock_flag(sk, SOCK_DEAD)) { 4827c657876SArnaldo Carvalho de Melo sk->sk_state_change(sk); 4838d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); 4847c657876SArnaldo Carvalho de Melo } 4857c657876SArnaldo Carvalho de Melo 4867c657876SArnaldo Carvalho de Melo if (sk->sk_write_pending || icsk->icsk_ack.pingpong || 4877c657876SArnaldo Carvalho de Melo icsk->icsk_accept_queue.rskq_defer_accept) { 4887c657876SArnaldo Carvalho de Melo /* Save one ACK. Data will be ready after 4897c657876SArnaldo Carvalho de Melo * several ticks, if write_pending is set. 4907c657876SArnaldo Carvalho de Melo * 4917c657876SArnaldo Carvalho de Melo * It may be deleted, but with this feature tcpdumps 4927c657876SArnaldo Carvalho de Melo * look so _wonderfully_ clever, that I was not able 4937c657876SArnaldo Carvalho de Melo * to stand against the temptation 8) --ANK 4947c657876SArnaldo Carvalho de Melo */ 4957c657876SArnaldo Carvalho de Melo /* 4967c657876SArnaldo Carvalho de Melo * OK, in DCCP we can as well do a similar trick, its 4977c657876SArnaldo Carvalho de Melo * even in the draft, but there is no need for us to 4987c657876SArnaldo Carvalho de Melo * schedule an ack here, as dccp_sendmsg does this for 4997c657876SArnaldo Carvalho de Melo * us, also stated in the draft. -acme 5007c657876SArnaldo Carvalho de Melo */ 5017c657876SArnaldo Carvalho de Melo __kfree_skb(skb); 5027c657876SArnaldo Carvalho de Melo return 0; 5037c657876SArnaldo Carvalho de Melo } 5047c657876SArnaldo Carvalho de Melo dccp_send_ack(sk); 5057c657876SArnaldo Carvalho de Melo return -1; 5067c657876SArnaldo Carvalho de Melo } 5077c657876SArnaldo Carvalho de Melo 5087c657876SArnaldo Carvalho de Melo out_invalid_packet: 5090c10c5d9SArnaldo Carvalho de Melo /* dccp_v4_do_rcv will send a reset */ 5100c10c5d9SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; 5110c10c5d9SArnaldo Carvalho de Melo return 1; 5127c657876SArnaldo Carvalho de Melo } 5137c657876SArnaldo Carvalho de Melo 5147c657876SArnaldo Carvalho de Melo static int dccp_rcv_respond_partopen_state_process(struct sock *sk, 5157c657876SArnaldo Carvalho de Melo struct sk_buff *skb, 5167c657876SArnaldo Carvalho de Melo const struct dccp_hdr *dh, 5177c657876SArnaldo Carvalho de Melo const unsigned len) 5187c657876SArnaldo Carvalho de Melo { 5197c657876SArnaldo Carvalho de Melo int queued = 0; 5207c657876SArnaldo Carvalho de Melo 5217c657876SArnaldo Carvalho de Melo switch (dh->dccph_type) { 5227c657876SArnaldo Carvalho de Melo case DCCP_PKT_RESET: 5237c657876SArnaldo Carvalho de Melo inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 5247c657876SArnaldo Carvalho de Melo break; 5252a9bc9bbSArnaldo Carvalho de Melo case DCCP_PKT_DATA: 5262a9bc9bbSArnaldo Carvalho de Melo if (sk->sk_state == DCCP_RESPOND) 5272a9bc9bbSArnaldo Carvalho de Melo break; 5287c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATAACK: 5297c657876SArnaldo Carvalho de Melo case DCCP_PKT_ACK: 5307c657876SArnaldo Carvalho de Melo /* 5317690af3fSArnaldo Carvalho de Melo * FIXME: we should be reseting the PARTOPEN (DELACK) timer 5327690af3fSArnaldo Carvalho de Melo * here but only if we haven't used the DELACK timer for 5337690af3fSArnaldo Carvalho de Melo * something else, like sending a delayed ack for a TIMESTAMP 5347690af3fSArnaldo Carvalho de Melo * echo, etc, for now were not clearing it, sending an extra 5357690af3fSArnaldo Carvalho de Melo * ACK when there is nothing else to do in DELACK is not a big 5367690af3fSArnaldo Carvalho de Melo * deal after all. 5377c657876SArnaldo Carvalho de Melo */ 5387c657876SArnaldo Carvalho de Melo 5397c657876SArnaldo Carvalho de Melo /* Stop the PARTOPEN timer */ 5407c657876SArnaldo Carvalho de Melo if (sk->sk_state == DCCP_PARTOPEN) 5417c657876SArnaldo Carvalho de Melo inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 5427c657876SArnaldo Carvalho de Melo 5437c657876SArnaldo Carvalho de Melo dccp_sk(sk)->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq; 5447c657876SArnaldo Carvalho de Melo dccp_set_state(sk, DCCP_OPEN); 5457c657876SArnaldo Carvalho de Melo 5462a9bc9bbSArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_DATAACK || 5472a9bc9bbSArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_DATA) { 548709dd3aaSAndrea Bittau __dccp_rcv_established(sk, skb, dh, len); 5497690af3fSArnaldo Carvalho de Melo queued = 1; /* packet was queued 550709dd3aaSAndrea Bittau (by __dccp_rcv_established) */ 5517c657876SArnaldo Carvalho de Melo } 5527c657876SArnaldo Carvalho de Melo break; 5537c657876SArnaldo Carvalho de Melo } 5547c657876SArnaldo Carvalho de Melo 5557c657876SArnaldo Carvalho de Melo return queued; 5567c657876SArnaldo Carvalho de Melo } 5577c657876SArnaldo Carvalho de Melo 5587c657876SArnaldo Carvalho de Melo int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, 5597c657876SArnaldo Carvalho de Melo struct dccp_hdr *dh, unsigned len) 5607c657876SArnaldo Carvalho de Melo { 5617c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 5620c10c5d9SArnaldo Carvalho de Melo struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 5637c657876SArnaldo Carvalho de Melo const int old_state = sk->sk_state; 5647c657876SArnaldo Carvalho de Melo int queued = 0; 5657c657876SArnaldo Carvalho de Melo 5668649b0d4SArnaldo Carvalho de Melo /* 5678649b0d4SArnaldo Carvalho de Melo * Step 3: Process LISTEN state 5688649b0d4SArnaldo Carvalho de Melo * 5698649b0d4SArnaldo Carvalho de Melo * If S.state == LISTEN, 570d83ca5acSGerrit Renker * If P.type == Request or P contains a valid Init Cookie option, 571d83ca5acSGerrit Renker * (* Must scan the packet's options to check for Init 572d83ca5acSGerrit Renker * Cookies. Only Init Cookies are processed here, 5738649b0d4SArnaldo Carvalho de Melo * however; other options are processed in Step 8. This 5748649b0d4SArnaldo Carvalho de Melo * scan need only be performed if the endpoint uses Init 575d83ca5acSGerrit Renker * Cookies *) 576d83ca5acSGerrit Renker * (* Generate a new socket and switch to that socket *) 5778649b0d4SArnaldo Carvalho de Melo * Set S := new socket for this port pair 5788649b0d4SArnaldo Carvalho de Melo * S.state = RESPOND 579d83ca5acSGerrit Renker * Choose S.ISS (initial seqno) or set from Init Cookies 580d83ca5acSGerrit Renker * Initialize S.GAR := S.ISS 581d83ca5acSGerrit Renker * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init 582d83ca5acSGerrit Renker * Cookies Continue with S.state == RESPOND 583d83ca5acSGerrit Renker * (* A Response packet will be generated in Step 11 *) 5848649b0d4SArnaldo Carvalho de Melo * Otherwise, 5858649b0d4SArnaldo Carvalho de Melo * Generate Reset(No Connection) unless P.type == Reset 5868649b0d4SArnaldo Carvalho de Melo * Drop packet and return 5878649b0d4SArnaldo Carvalho de Melo */ 5888649b0d4SArnaldo Carvalho de Melo if (sk->sk_state == DCCP_LISTEN) { 5898649b0d4SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_REQUEST) { 59057cca05aSArnaldo Carvalho de Melo if (inet_csk(sk)->icsk_af_ops->conn_request(sk, 59157cca05aSArnaldo Carvalho de Melo skb) < 0) 5928649b0d4SArnaldo Carvalho de Melo return 1; 5938649b0d4SArnaldo Carvalho de Melo 5948649b0d4SArnaldo Carvalho de Melo /* FIXME: do congestion control initialization */ 5958649b0d4SArnaldo Carvalho de Melo goto discard; 5968649b0d4SArnaldo Carvalho de Melo } 5978649b0d4SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_RESET) 5988649b0d4SArnaldo Carvalho de Melo goto discard; 5998649b0d4SArnaldo Carvalho de Melo 6000c10c5d9SArnaldo Carvalho de Melo /* Caller (dccp_v4_do_rcv) will send Reset */ 6010c10c5d9SArnaldo Carvalho de Melo dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 6028649b0d4SArnaldo Carvalho de Melo return 1; 6038649b0d4SArnaldo Carvalho de Melo } 6048649b0d4SArnaldo Carvalho de Melo 6058649b0d4SArnaldo Carvalho de Melo if (sk->sk_state != DCCP_REQUESTING) { 6067c657876SArnaldo Carvalho de Melo if (dccp_check_seqno(sk, skb)) 6077c657876SArnaldo Carvalho de Melo goto discard; 6087c657876SArnaldo Carvalho de Melo 6097c657876SArnaldo Carvalho de Melo /* 6107c657876SArnaldo Carvalho de Melo * Step 8: Process options and mark acknowledgeable 6117c657876SArnaldo Carvalho de Melo */ 6128b819412SGerrit Renker if (dccp_parse_options(sk, NULL, skb)) 613*ba1a6c7bSWei Yongjun return 1; 6147c657876SArnaldo Carvalho de Melo 6150c10c5d9SArnaldo Carvalho de Melo if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 6167c657876SArnaldo Carvalho de Melo dccp_event_ack_recv(sk, skb); 6177c657876SArnaldo Carvalho de Melo 618a4bf3902SArnaldo Carvalho de Melo if (dccp_msk(sk)->dccpms_send_ack_vector && 619ae31c339SArnaldo Carvalho de Melo dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, 620ae31c339SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_seq, 621ae31c339SArnaldo Carvalho de Melo DCCP_ACKVEC_STATE_RECEIVED)) 6227c657876SArnaldo Carvalho de Melo goto discard; 623e84a9f5eSAndrea Bittau 6248e8c71f1SGerrit Renker dccp_deliver_input_to_ccids(sk, skb); 6257c657876SArnaldo Carvalho de Melo } 6267c657876SArnaldo Carvalho de Melo 6277c657876SArnaldo Carvalho de Melo /* 6287c657876SArnaldo Carvalho de Melo * Step 9: Process Reset 6297c657876SArnaldo Carvalho de Melo * If P.type == Reset, 6307c657876SArnaldo Carvalho de Melo * Tear down connection 6317c657876SArnaldo Carvalho de Melo * S.state := TIMEWAIT 6327c657876SArnaldo Carvalho de Melo * Set TIMEWAIT timer 6337c657876SArnaldo Carvalho de Melo * Drop packet and return 6347c657876SArnaldo Carvalho de Melo */ 6357c657876SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_RESET) { 636d8ef2c29SGerrit Renker dccp_rcv_reset(sk, skb); 6377c657876SArnaldo Carvalho de Melo return 0; 6387c657876SArnaldo Carvalho de Melo /* 6397c657876SArnaldo Carvalho de Melo * Step 7: Check for unexpected packet types 6403159afe0SGerrit Renker * If (S.is_server and P.type == Response) 6417c657876SArnaldo Carvalho de Melo * or (S.is_client and P.type == Request) 6427c657876SArnaldo Carvalho de Melo * or (S.state == RESPOND and P.type == Data), 6437c657876SArnaldo Carvalho de Melo * Send Sync packet acknowledging P.seqno 6447c657876SArnaldo Carvalho de Melo * Drop packet and return 6457c657876SArnaldo Carvalho de Melo */ 6467c657876SArnaldo Carvalho de Melo } else if ((dp->dccps_role != DCCP_ROLE_CLIENT && 6473159afe0SGerrit Renker dh->dccph_type == DCCP_PKT_RESPONSE) || 6487c657876SArnaldo Carvalho de Melo (dp->dccps_role == DCCP_ROLE_CLIENT && 6497c657876SArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_REQUEST) || 6507690af3fSArnaldo Carvalho de Melo (sk->sk_state == DCCP_RESPOND && 6517690af3fSArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_DATA)) { 6520c10c5d9SArnaldo Carvalho de Melo dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC); 6537c657876SArnaldo Carvalho de Melo goto discard; 6547ad07e7cSArnaldo Carvalho de Melo } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { 6550c869620SGerrit Renker if (dccp_rcv_closereq(sk, skb)) 6560c869620SGerrit Renker return 0; 6577ad07e7cSArnaldo Carvalho de Melo goto discard; 6587ad07e7cSArnaldo Carvalho de Melo } else if (dh->dccph_type == DCCP_PKT_CLOSE) { 6590c869620SGerrit Renker if (dccp_rcv_close(sk, skb)) 6607ad07e7cSArnaldo Carvalho de Melo return 0; 6610c869620SGerrit Renker goto discard; 6627c657876SArnaldo Carvalho de Melo } 6637c657876SArnaldo Carvalho de Melo 6647c657876SArnaldo Carvalho de Melo switch (sk->sk_state) { 6657c657876SArnaldo Carvalho de Melo case DCCP_CLOSED: 6660c10c5d9SArnaldo Carvalho de Melo dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 6677c657876SArnaldo Carvalho de Melo return 1; 6687c657876SArnaldo Carvalho de Melo 6697c657876SArnaldo Carvalho de Melo case DCCP_REQUESTING: 6707c657876SArnaldo Carvalho de Melo /* FIXME: do congestion control initialization */ 6717c657876SArnaldo Carvalho de Melo 6727c657876SArnaldo Carvalho de Melo queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); 6737c657876SArnaldo Carvalho de Melo if (queued >= 0) 6747c657876SArnaldo Carvalho de Melo return queued; 6757c657876SArnaldo Carvalho de Melo 6767c657876SArnaldo Carvalho de Melo __kfree_skb(skb); 6777c657876SArnaldo Carvalho de Melo return 0; 6787c657876SArnaldo Carvalho de Melo 6797c657876SArnaldo Carvalho de Melo case DCCP_RESPOND: 6807c657876SArnaldo Carvalho de Melo case DCCP_PARTOPEN: 6817690af3fSArnaldo Carvalho de Melo queued = dccp_rcv_respond_partopen_state_process(sk, skb, 6827690af3fSArnaldo Carvalho de Melo dh, len); 6837c657876SArnaldo Carvalho de Melo break; 6847c657876SArnaldo Carvalho de Melo } 6857c657876SArnaldo Carvalho de Melo 6867690af3fSArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_ACK || 6877690af3fSArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_DATAACK) { 6887c657876SArnaldo Carvalho de Melo switch (old_state) { 6897c657876SArnaldo Carvalho de Melo case DCCP_PARTOPEN: 6907c657876SArnaldo Carvalho de Melo sk->sk_state_change(sk); 6918d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); 6927c657876SArnaldo Carvalho de Melo break; 6937c657876SArnaldo Carvalho de Melo } 69408831700SGerrit Renker } else if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) { 69508831700SGerrit Renker dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNCACK); 69608831700SGerrit Renker goto discard; 6977c657876SArnaldo Carvalho de Melo } 6987c657876SArnaldo Carvalho de Melo 6997c657876SArnaldo Carvalho de Melo if (!queued) { 7007c657876SArnaldo Carvalho de Melo discard: 7017c657876SArnaldo Carvalho de Melo __kfree_skb(skb); 7027c657876SArnaldo Carvalho de Melo } 7037c657876SArnaldo Carvalho de Melo return 0; 7047c657876SArnaldo Carvalho de Melo } 705f21e68caSArnaldo Carvalho de Melo 706f21e68caSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_rcv_state_process); 7074712a792SGerrit Renker 7084712a792SGerrit Renker /** 7093393da82SGerrit Renker * dccp_sample_rtt - Validate and finalise computation of RTT sample 7103393da82SGerrit Renker * @delta: number of microseconds between packet and acknowledgment 7113393da82SGerrit Renker * The routine is kept generic to work in different contexts. It should be 7123393da82SGerrit Renker * called immediately when the ACK used for the RTT sample arrives. 7134712a792SGerrit Renker */ 7143393da82SGerrit Renker u32 dccp_sample_rtt(struct sock *sk, long delta) 7154712a792SGerrit Renker { 7163393da82SGerrit Renker /* dccpor_elapsed_time is either zeroed out or set and > 0 */ 7173393da82SGerrit Renker delta -= dccp_sk(sk)->dccps_options_received.dccpor_elapsed_time * 10; 7184712a792SGerrit Renker 7194712a792SGerrit Renker if (unlikely(delta <= 0)) { 7203393da82SGerrit Renker DCCP_WARN("unusable RTT sample %ld, using min\n", delta); 7214712a792SGerrit Renker return DCCP_SANE_RTT_MIN; 7224712a792SGerrit Renker } 7233393da82SGerrit Renker if (unlikely(delta > DCCP_SANE_RTT_MAX)) { 7243393da82SGerrit Renker DCCP_WARN("RTT sample %ld too large, using max\n", delta); 7254712a792SGerrit Renker return DCCP_SANE_RTT_MAX; 7264712a792SGerrit Renker } 7274712a792SGerrit Renker 7284712a792SGerrit Renker return delta; 7294712a792SGerrit Renker } 7304712a792SGerrit Renker 7314712a792SGerrit Renker EXPORT_SYMBOL_GPL(dccp_sample_rtt); 732