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> 155a0e3ad6STejun Heo #include <linux/slab.h> 167c657876SArnaldo Carvalho de Melo 177c657876SArnaldo Carvalho de Melo #include <net/sock.h> 187c657876SArnaldo Carvalho de Melo 19ae31c339SArnaldo Carvalho de Melo #include "ackvec.h" 207c657876SArnaldo Carvalho de Melo #include "ccid.h" 217c657876SArnaldo Carvalho de Melo #include "dccp.h" 227c657876SArnaldo Carvalho de Melo 23bd5435e7SIngo Molnar /* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ 24bd5435e7SIngo Molnar int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; 25bd5435e7SIngo Molnar 2669567d0bSGerrit Renker static void dccp_enqueue_skb(struct sock *sk, struct sk_buff *skb) 277c657876SArnaldo Carvalho de Melo { 287c657876SArnaldo Carvalho de Melo __skb_pull(skb, dccp_hdr(skb)->dccph_doff * 4); 297c657876SArnaldo Carvalho de Melo __skb_queue_tail(&sk->sk_receive_queue, skb); 307c657876SArnaldo Carvalho de Melo skb_set_owner_r(skb, sk); 31676d2369SDavid S. Miller sk->sk_data_ready(sk); 327c657876SArnaldo Carvalho de Melo } 337c657876SArnaldo Carvalho de Melo 3469567d0bSGerrit Renker static void dccp_fin(struct sock *sk, struct sk_buff *skb) 3569567d0bSGerrit Renker { 3669567d0bSGerrit Renker /* 3769567d0bSGerrit Renker * On receiving Close/CloseReq, both RD/WR shutdown are performed. 3869567d0bSGerrit Renker * RFC 4340, 8.3 says that we MAY send further Data/DataAcks after 3969567d0bSGerrit Renker * receiving the closing segment, but there is no guarantee that such 4069567d0bSGerrit Renker * data will be processed at all. 4169567d0bSGerrit Renker */ 4269567d0bSGerrit Renker sk->sk_shutdown = SHUTDOWN_MASK; 4369567d0bSGerrit Renker sock_set_flag(sk, SOCK_DONE); 4469567d0bSGerrit Renker dccp_enqueue_skb(sk, skb); 4569567d0bSGerrit Renker } 4669567d0bSGerrit Renker 470c869620SGerrit Renker static int dccp_rcv_close(struct sock *sk, struct sk_buff *skb) 487c657876SArnaldo Carvalho de Melo { 490c869620SGerrit Renker int queued = 0; 500c869620SGerrit Renker 510c869620SGerrit Renker switch (sk->sk_state) { 520c869620SGerrit Renker /* 530c869620SGerrit Renker * We ignore Close when received in one of the following states: 540c869620SGerrit Renker * - CLOSED (may be a late or duplicate packet) 550c869620SGerrit Renker * - PASSIVE_CLOSEREQ (the peer has sent a CloseReq earlier) 560c869620SGerrit Renker * - RESPOND (already handled by dccp_check_req) 570c869620SGerrit Renker */ 580c869620SGerrit Renker case DCCP_CLOSING: 590c869620SGerrit Renker /* 600c869620SGerrit Renker * Simultaneous-close: receiving a Close after sending one. This 610c869620SGerrit Renker * can happen if both client and server perform active-close and 620c869620SGerrit Renker * will result in an endless ping-pong of crossing and retrans- 630c869620SGerrit Renker * mitted Close packets, which only terminates when one of the 640c869620SGerrit Renker * nodes times out (min. 64 seconds). Quicker convergence can be 650c869620SGerrit Renker * achieved when one of the nodes acts as tie-breaker. 660c869620SGerrit Renker * This is ok as both ends are done with data transfer and each 670c869620SGerrit Renker * end is just waiting for the other to acknowledge termination. 680c869620SGerrit Renker */ 690c869620SGerrit Renker if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) 700c869620SGerrit Renker break; 710c869620SGerrit Renker /* fall through */ 720c869620SGerrit Renker case DCCP_REQUESTING: 730c869620SGerrit Renker case DCCP_ACTIVE_CLOSEREQ: 74017487d7SArnaldo Carvalho de Melo dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED); 750c869620SGerrit Renker dccp_done(sk); 760c869620SGerrit Renker break; 770c869620SGerrit Renker case DCCP_OPEN: 780c869620SGerrit Renker case DCCP_PARTOPEN: 790c869620SGerrit Renker /* Give waiting application a chance to read pending data */ 800c869620SGerrit Renker queued = 1; 817c657876SArnaldo Carvalho de Melo dccp_fin(sk, skb); 820c869620SGerrit Renker dccp_set_state(sk, DCCP_PASSIVE_CLOSE); 830c869620SGerrit Renker /* fall through */ 840c869620SGerrit Renker case DCCP_PASSIVE_CLOSE: 850c869620SGerrit Renker /* 860c869620SGerrit Renker * Retransmitted Close: we have already enqueued the first one. 870c869620SGerrit Renker */ 888d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP); 897c657876SArnaldo Carvalho de Melo } 900c869620SGerrit Renker return queued; 910c869620SGerrit Renker } 927c657876SArnaldo Carvalho de Melo 930c869620SGerrit Renker static int dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb) 947c657876SArnaldo Carvalho de Melo { 950c869620SGerrit Renker int queued = 0; 960c869620SGerrit Renker 977c657876SArnaldo Carvalho de Melo /* 987c657876SArnaldo Carvalho de Melo * Step 7: Check for unexpected packet types 997c657876SArnaldo Carvalho de Melo * If (S.is_server and P.type == CloseReq) 1007c657876SArnaldo Carvalho de Melo * Send Sync packet acknowledging P.seqno 1017c657876SArnaldo Carvalho de Melo * Drop packet and return 1027c657876SArnaldo Carvalho de Melo */ 1037c657876SArnaldo Carvalho de Melo if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) { 104e92ae93aSArnaldo Carvalho de Melo dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC); 1050c869620SGerrit Renker return queued; 1067c657876SArnaldo Carvalho de Melo } 1077c657876SArnaldo Carvalho de Melo 1080c869620SGerrit Renker /* Step 13: process relevant Client states < CLOSEREQ */ 1090c869620SGerrit Renker switch (sk->sk_state) { 1100c869620SGerrit Renker case DCCP_REQUESTING: 1117ad07e7cSArnaldo Carvalho de Melo dccp_send_close(sk, 0); 1120c869620SGerrit Renker dccp_set_state(sk, DCCP_CLOSING); 1130c869620SGerrit Renker break; 1140c869620SGerrit Renker case DCCP_OPEN: 1150c869620SGerrit Renker case DCCP_PARTOPEN: 1160c869620SGerrit Renker /* Give waiting application a chance to read pending data */ 1170c869620SGerrit Renker queued = 1; 1180c869620SGerrit Renker dccp_fin(sk, skb); 1190c869620SGerrit Renker dccp_set_state(sk, DCCP_PASSIVE_CLOSEREQ); 1200c869620SGerrit Renker /* fall through */ 1210c869620SGerrit Renker case DCCP_PASSIVE_CLOSEREQ: 1220c869620SGerrit Renker sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP); 1230c869620SGerrit Renker } 1240c869620SGerrit Renker return queued; 1257c657876SArnaldo Carvalho de Melo } 1267c657876SArnaldo Carvalho de Melo 127d9b52dc6SYoichi Yuasa static u16 dccp_reset_code_convert(const u8 code) 128d8ef2c29SGerrit Renker { 1295e349fc0SColin Ian King static const u16 error_code[] = { 130d8ef2c29SGerrit Renker [DCCP_RESET_CODE_CLOSED] = 0, /* normal termination */ 131d8ef2c29SGerrit Renker [DCCP_RESET_CODE_UNSPECIFIED] = 0, /* nothing known */ 132d8ef2c29SGerrit Renker [DCCP_RESET_CODE_ABORTED] = ECONNRESET, 133d8ef2c29SGerrit Renker 134d8ef2c29SGerrit Renker [DCCP_RESET_CODE_NO_CONNECTION] = ECONNREFUSED, 135d8ef2c29SGerrit Renker [DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED, 136d8ef2c29SGerrit Renker [DCCP_RESET_CODE_TOO_BUSY] = EUSERS, 137d8ef2c29SGerrit Renker [DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT, 138d8ef2c29SGerrit Renker 139d8ef2c29SGerrit Renker [DCCP_RESET_CODE_PACKET_ERROR] = ENOMSG, 140d8ef2c29SGerrit Renker [DCCP_RESET_CODE_BAD_INIT_COOKIE] = EBADR, 141d8ef2c29SGerrit Renker [DCCP_RESET_CODE_BAD_SERVICE_CODE] = EBADRQC, 142d8ef2c29SGerrit Renker [DCCP_RESET_CODE_OPTION_ERROR] = EILSEQ, 143d8ef2c29SGerrit Renker [DCCP_RESET_CODE_MANDATORY_ERROR] = EOPNOTSUPP, 144d8ef2c29SGerrit Renker }; 145d8ef2c29SGerrit Renker 146d8ef2c29SGerrit Renker return code >= DCCP_MAX_RESET_CODES ? 0 : error_code[code]; 147d8ef2c29SGerrit Renker } 148d8ef2c29SGerrit Renker 149d8ef2c29SGerrit Renker static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) 150d8ef2c29SGerrit Renker { 151d9b52dc6SYoichi Yuasa u16 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code); 152d8ef2c29SGerrit Renker 153d8ef2c29SGerrit Renker sk->sk_err = err; 154d8ef2c29SGerrit Renker 155d8ef2c29SGerrit Renker /* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */ 156d8ef2c29SGerrit Renker dccp_fin(sk, skb); 157d8ef2c29SGerrit Renker 158d8ef2c29SGerrit Renker if (err && !sock_flag(sk, SOCK_DEAD)) 1598d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR); 160d8ef2c29SGerrit Renker dccp_time_wait(sk, DCCP_TIME_WAIT, 0); 161d8ef2c29SGerrit Renker } 162d8ef2c29SGerrit Renker 16318219463SGerrit Renker static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb) 1647c657876SArnaldo Carvalho de Melo { 16518219463SGerrit Renker struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec; 1667c657876SArnaldo Carvalho de Melo 16718219463SGerrit Renker if (av == NULL) 16818219463SGerrit Renker return; 16918219463SGerrit Renker if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 17018219463SGerrit Renker dccp_ackvec_clear_state(av, DCCP_SKB_CB(skb)->dccpd_ack_seq); 17118219463SGerrit Renker dccp_ackvec_input(av, skb); 1727c657876SArnaldo Carvalho de Melo } 1737c657876SArnaldo Carvalho de Melo 1748e8c71f1SGerrit Renker static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) 1758e8c71f1SGerrit Renker { 1768e8c71f1SGerrit Renker const struct dccp_sock *dp = dccp_sk(sk); 1778e8c71f1SGerrit Renker 1788e8c71f1SGerrit Renker /* Don't deliver to RX CCID when node has shut down read end. */ 1798e8c71f1SGerrit Renker if (!(sk->sk_shutdown & RCV_SHUTDOWN)) 1808e8c71f1SGerrit Renker ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); 1818e8c71f1SGerrit Renker /* 1828e8c71f1SGerrit Renker * Until the TX queue has been drained, we can not honour SHUT_WR, since 1838e8c71f1SGerrit Renker * we need received feedback as input to adjust congestion control. 1848e8c71f1SGerrit Renker */ 1858e8c71f1SGerrit Renker if (sk->sk_write_queue.qlen > 0 || !(sk->sk_shutdown & SEND_SHUTDOWN)) 1868e8c71f1SGerrit Renker ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); 1878e8c71f1SGerrit Renker } 1888e8c71f1SGerrit Renker 1897c657876SArnaldo Carvalho de Melo static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) 1907c657876SArnaldo Carvalho de Melo { 1917c657876SArnaldo Carvalho de Melo const struct dccp_hdr *dh = dccp_hdr(skb); 1927c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 193cbe1f5f8SGerrit Renker u64 lswl, lawl, seqno = DCCP_SKB_CB(skb)->dccpd_seq, 194cbe1f5f8SGerrit Renker ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; 1957c657876SArnaldo Carvalho de Melo 1967c657876SArnaldo Carvalho de Melo /* 1977c657876SArnaldo Carvalho de Melo * Step 5: Prepare sequence numbers for Sync 1987c657876SArnaldo Carvalho de Melo * If P.type == Sync or P.type == SyncAck, 1997c657876SArnaldo Carvalho de Melo * If S.AWL <= P.ackno <= S.AWH and P.seqno >= S.SWL, 2007c657876SArnaldo Carvalho de Melo * / * P is valid, so update sequence number variables 2017c657876SArnaldo Carvalho de Melo * accordingly. After this update, P will pass the tests 2027c657876SArnaldo Carvalho de Melo * in Step 6. A SyncAck is generated if necessary in 2037c657876SArnaldo Carvalho de Melo * Step 15 * / 2047c657876SArnaldo Carvalho de Melo * Update S.GSR, S.SWL, S.SWH 2057c657876SArnaldo Carvalho de Melo * Otherwise, 2067c657876SArnaldo Carvalho de Melo * Drop packet and return 2077c657876SArnaldo Carvalho de Melo */ 2087c657876SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_SYNC || 2097c657876SArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_SYNCACK) { 210cbe1f5f8SGerrit Renker if (between48(ackno, dp->dccps_awl, dp->dccps_awh) && 211cbe1f5f8SGerrit Renker dccp_delta_seqno(dp->dccps_swl, seqno) >= 0) 212cbe1f5f8SGerrit Renker dccp_update_gsr(sk, seqno); 2137c657876SArnaldo Carvalho de Melo else 2147c657876SArnaldo Carvalho de Melo return -1; 215e92ae93aSArnaldo Carvalho de Melo } 216e92ae93aSArnaldo Carvalho de Melo 2177c657876SArnaldo Carvalho de Melo /* 2187c657876SArnaldo Carvalho de Melo * Step 6: Check sequence numbers 2197c657876SArnaldo Carvalho de Melo * Let LSWL = S.SWL and LAWL = S.AWL 2207c657876SArnaldo Carvalho de Melo * If P.type == CloseReq or P.type == Close or P.type == Reset, 2217c657876SArnaldo Carvalho de Melo * LSWL := S.GSR + 1, LAWL := S.GAR 2227c657876SArnaldo Carvalho de Melo * If LSWL <= P.seqno <= S.SWH 2237c657876SArnaldo Carvalho de Melo * and (P.ackno does not exist or LAWL <= P.ackno <= S.AWH), 2247c657876SArnaldo Carvalho de Melo * Update S.GSR, S.SWL, S.SWH 2257c657876SArnaldo Carvalho de Melo * If P.type != Sync, 2267c657876SArnaldo Carvalho de Melo * Update S.GAR 2277c657876SArnaldo Carvalho de Melo */ 228e92ae93aSArnaldo Carvalho de Melo lswl = dp->dccps_swl; 229e92ae93aSArnaldo Carvalho de Melo lawl = dp->dccps_awl; 230e92ae93aSArnaldo Carvalho de Melo 231e92ae93aSArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_CLOSEREQ || 2327c657876SArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_CLOSE || 2337c657876SArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_RESET) { 234cbe1f5f8SGerrit Renker lswl = ADD48(dp->dccps_gsr, 1); 2357c657876SArnaldo Carvalho de Melo lawl = dp->dccps_gar; 2367c657876SArnaldo Carvalho de Melo } 2377c657876SArnaldo Carvalho de Melo 238cbe1f5f8SGerrit Renker if (between48(seqno, lswl, dp->dccps_swh) && 239cbe1f5f8SGerrit Renker (ackno == DCCP_PKT_WITHOUT_ACK_SEQ || 240cbe1f5f8SGerrit Renker between48(ackno, lawl, dp->dccps_awh))) { 241cbe1f5f8SGerrit Renker dccp_update_gsr(sk, seqno); 2427c657876SArnaldo Carvalho de Melo 2437c657876SArnaldo Carvalho de Melo if (dh->dccph_type != DCCP_PKT_SYNC && 2440ac78870SGerrit Renker ackno != DCCP_PKT_WITHOUT_ACK_SEQ && 2450ac78870SGerrit Renker after48(ackno, dp->dccps_gar)) 246cbe1f5f8SGerrit Renker dp->dccps_gar = ackno; 2477c657876SArnaldo Carvalho de Melo } else { 248a94f0f97SGerrit Renker unsigned long now = jiffies; 249a94f0f97SGerrit Renker /* 250a94f0f97SGerrit Renker * Step 6: Check sequence numbers 251a94f0f97SGerrit Renker * Otherwise, 252a94f0f97SGerrit Renker * If P.type == Reset, 253a94f0f97SGerrit Renker * Send Sync packet acknowledging S.GSR 254a94f0f97SGerrit Renker * Otherwise, 255a94f0f97SGerrit Renker * Send Sync packet acknowledging P.seqno 256a94f0f97SGerrit Renker * Drop packet and return 257a94f0f97SGerrit Renker * 258a94f0f97SGerrit Renker * These Syncs are rate-limited as per RFC 4340, 7.5.4: 259a94f0f97SGerrit Renker * at most 1 / (dccp_sync_rate_limit * HZ) Syncs per second. 260a94f0f97SGerrit Renker */ 261a94f0f97SGerrit Renker if (time_before(now, (dp->dccps_rate_last + 262a94f0f97SGerrit Renker sysctl_dccp_sync_ratelimit))) 2632cf5be93SSamuel Jero return -1; 264a94f0f97SGerrit Renker 2652f34b329SGerrit Renker DCCP_WARN("Step 6 failed for %s packet, " 266a3054d48SArnaldo Carvalho de Melo "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " 267a3054d48SArnaldo Carvalho de Melo "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " 26859348b19SGerrit Renker "sending SYNC...\n", dccp_packet_name(dh->dccph_type), 269cbe1f5f8SGerrit Renker (unsigned long long) lswl, (unsigned long long) seqno, 27058e45131SDavid S. Miller (unsigned long long) dp->dccps_swh, 271cbe1f5f8SGerrit Renker (ackno == DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" 272cbe1f5f8SGerrit Renker : "exists", 273cbe1f5f8SGerrit Renker (unsigned long long) lawl, (unsigned long long) ackno, 27458e45131SDavid S. Miller (unsigned long long) dp->dccps_awh); 275a94f0f97SGerrit Renker 276a94f0f97SGerrit Renker dp->dccps_rate_last = now; 277a94f0f97SGerrit Renker 278e155d769SGerrit Renker if (dh->dccph_type == DCCP_PKT_RESET) 279e155d769SGerrit Renker seqno = dp->dccps_gsr; 280cbe1f5f8SGerrit Renker dccp_send_sync(sk, seqno, DCCP_PKT_SYNC); 2817c657876SArnaldo Carvalho de Melo return -1; 2827c657876SArnaldo Carvalho de Melo } 2837c657876SArnaldo Carvalho de Melo 2847c657876SArnaldo Carvalho de Melo return 0; 2857c657876SArnaldo Carvalho de Melo } 2867c657876SArnaldo Carvalho de Melo 287c25a18baSArnaldo Carvalho de Melo static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, 28895c96174SEric Dumazet const struct dccp_hdr *dh, const unsigned int len) 2897c657876SArnaldo Carvalho de Melo { 2907c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 2917c657876SArnaldo Carvalho de Melo 2927c657876SArnaldo Carvalho de Melo switch (dccp_hdr(skb)->dccph_type) { 2937c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATAACK: 2947c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATA: 2957c657876SArnaldo Carvalho de Melo /* 2968e8c71f1SGerrit Renker * FIXME: schedule DATA_DROPPED (RFC 4340, 11.7.2) if and when 2978e8c71f1SGerrit Renker * - sk_shutdown == RCV_SHUTDOWN, use Code 1, "Not Listening" 2988e8c71f1SGerrit Renker * - sk_receive_queue is full, use Code 2, "Receive Buffer" 2997c657876SArnaldo Carvalho de Melo */ 30069567d0bSGerrit Renker dccp_enqueue_skb(sk, skb); 3017c657876SArnaldo Carvalho de Melo return 0; 3027c657876SArnaldo Carvalho de Melo case DCCP_PKT_ACK: 3037c657876SArnaldo Carvalho de Melo goto discard; 3047c657876SArnaldo Carvalho de Melo case DCCP_PKT_RESET: 3057c657876SArnaldo Carvalho de Melo /* 3067c657876SArnaldo Carvalho de Melo * Step 9: Process Reset 3077c657876SArnaldo Carvalho de Melo * If P.type == Reset, 3087c657876SArnaldo Carvalho de Melo * Tear down connection 3097c657876SArnaldo Carvalho de Melo * S.state := TIMEWAIT 3107c657876SArnaldo Carvalho de Melo * Set TIMEWAIT timer 3117c657876SArnaldo Carvalho de Melo * Drop packet and return 3127c657876SArnaldo Carvalho de Melo */ 313d8ef2c29SGerrit Renker dccp_rcv_reset(sk, skb); 3147c657876SArnaldo Carvalho de Melo return 0; 3157c657876SArnaldo Carvalho de Melo case DCCP_PKT_CLOSEREQ: 3160c869620SGerrit Renker if (dccp_rcv_closereq(sk, skb)) 3170c869620SGerrit Renker return 0; 3187c657876SArnaldo Carvalho de Melo goto discard; 3197c657876SArnaldo Carvalho de Melo case DCCP_PKT_CLOSE: 3200c869620SGerrit Renker if (dccp_rcv_close(sk, skb)) 3217c657876SArnaldo Carvalho de Melo return 0; 3220c869620SGerrit Renker goto discard; 3237c657876SArnaldo Carvalho de Melo case DCCP_PKT_REQUEST: 3247c657876SArnaldo Carvalho de Melo /* Step 7 3257c657876SArnaldo Carvalho de Melo * or (S.is_server and P.type == Response) 3267c657876SArnaldo Carvalho de Melo * or (S.is_client and P.type == Request) 3277c657876SArnaldo Carvalho de Melo * or (S.state >= OPEN and P.type == Request 3287c657876SArnaldo Carvalho de Melo * and P.seqno >= S.OSR) 3297c657876SArnaldo Carvalho de Melo * or (S.state >= OPEN and P.type == Response 3307c657876SArnaldo Carvalho de Melo * and P.seqno >= S.OSR) 3317c657876SArnaldo Carvalho de Melo * or (S.state == RESPOND and P.type == Data), 3327c657876SArnaldo Carvalho de Melo * Send Sync packet acknowledging P.seqno 3337c657876SArnaldo Carvalho de Melo * Drop packet and return 3347c657876SArnaldo Carvalho de Melo */ 3357c657876SArnaldo Carvalho de Melo if (dp->dccps_role != DCCP_ROLE_LISTEN) 3367c657876SArnaldo Carvalho de Melo goto send_sync; 3377c657876SArnaldo Carvalho de Melo goto check_seq; 3387c657876SArnaldo Carvalho de Melo case DCCP_PKT_RESPONSE: 3397c657876SArnaldo Carvalho de Melo if (dp->dccps_role != DCCP_ROLE_CLIENT) 3407c657876SArnaldo Carvalho de Melo goto send_sync; 3417c657876SArnaldo Carvalho de Melo check_seq: 3428d13bf9aSGerrit Renker if (dccp_delta_seqno(dp->dccps_osr, 3438d13bf9aSGerrit Renker DCCP_SKB_CB(skb)->dccpd_seq) >= 0) { 3447c657876SArnaldo Carvalho de Melo send_sync: 345e92ae93aSArnaldo Carvalho de Melo dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, 346e92ae93aSArnaldo Carvalho de Melo DCCP_PKT_SYNC); 3477c657876SArnaldo Carvalho de Melo } 3487c657876SArnaldo Carvalho de Melo break; 349e92ae93aSArnaldo Carvalho de Melo case DCCP_PKT_SYNC: 350e92ae93aSArnaldo Carvalho de Melo dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, 351e92ae93aSArnaldo Carvalho de Melo DCCP_PKT_SYNCACK); 352e92ae93aSArnaldo Carvalho de Melo /* 3530e64e94eSGerrit Renker * From RFC 4340, sec. 5.7 354e92ae93aSArnaldo Carvalho de Melo * 355e92ae93aSArnaldo Carvalho de Melo * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets 356e92ae93aSArnaldo Carvalho de Melo * MAY have non-zero-length application data areas, whose 3570e64e94eSGerrit Renker * contents receivers MUST ignore. 358e92ae93aSArnaldo Carvalho de Melo */ 359e92ae93aSArnaldo Carvalho de Melo goto discard; 3607c657876SArnaldo Carvalho de Melo } 3617c657876SArnaldo Carvalho de Melo 3627309f882SEric Dumazet DCCP_INC_STATS(DCCP_MIB_INERRS); 3637c657876SArnaldo Carvalho de Melo discard: 3647c657876SArnaldo Carvalho de Melo __kfree_skb(skb); 3657c657876SArnaldo Carvalho de Melo return 0; 3667c657876SArnaldo Carvalho de Melo } 3677c657876SArnaldo Carvalho de Melo 368709dd3aaSAndrea Bittau int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, 36995c96174SEric Dumazet const struct dccp_hdr *dh, const unsigned int len) 370709dd3aaSAndrea Bittau { 371709dd3aaSAndrea Bittau if (dccp_check_seqno(sk, skb)) 372709dd3aaSAndrea Bittau goto discard; 373709dd3aaSAndrea Bittau 3748b819412SGerrit Renker if (dccp_parse_options(sk, NULL, skb)) 375ba1a6c7bSWei Yongjun return 1; 376709dd3aaSAndrea Bittau 37718219463SGerrit Renker dccp_handle_ackvec_processing(sk, skb); 3788e8c71f1SGerrit Renker dccp_deliver_input_to_ccids(sk, skb); 379709dd3aaSAndrea Bittau 380709dd3aaSAndrea Bittau return __dccp_rcv_established(sk, skb, dh, len); 381709dd3aaSAndrea Bittau discard: 382709dd3aaSAndrea Bittau __kfree_skb(skb); 383709dd3aaSAndrea Bittau return 0; 384709dd3aaSAndrea Bittau } 385709dd3aaSAndrea Bittau 386f21e68caSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_rcv_established); 387f21e68caSArnaldo Carvalho de Melo 3887c657876SArnaldo Carvalho de Melo static int dccp_rcv_request_sent_state_process(struct sock *sk, 3897c657876SArnaldo Carvalho de Melo struct sk_buff *skb, 3907c657876SArnaldo Carvalho de Melo const struct dccp_hdr *dh, 39195c96174SEric Dumazet const unsigned int len) 3927c657876SArnaldo Carvalho de Melo { 3937c657876SArnaldo Carvalho de Melo /* 3947c657876SArnaldo Carvalho de Melo * Step 4: Prepare sequence numbers in REQUEST 3957c657876SArnaldo Carvalho de Melo * If S.state == REQUEST, 3967c657876SArnaldo Carvalho de Melo * If (P.type == Response or P.type == Reset) 3977c657876SArnaldo Carvalho de Melo * and S.AWL <= P.ackno <= S.AWH, 3987c657876SArnaldo Carvalho de Melo * / * Set sequence number variables corresponding to the 3997c657876SArnaldo Carvalho de Melo * other endpoint, so P will pass the tests in Step 6 * / 4007c657876SArnaldo Carvalho de Melo * Set S.GSR, S.ISR, S.SWL, S.SWH 4017c657876SArnaldo Carvalho de Melo * / * Response processing continues in Step 10; Reset 4027c657876SArnaldo Carvalho de Melo * processing continues in Step 9 * / 4037c657876SArnaldo Carvalho de Melo */ 4047c657876SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_RESPONSE) { 4057c657876SArnaldo Carvalho de Melo const struct inet_connection_sock *icsk = inet_csk(sk); 4067c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 4073393da82SGerrit Renker long tstamp = dccp_timestamp(); 4087c657876SArnaldo Carvalho de Melo 4097690af3fSArnaldo Carvalho de Melo if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq, 4107690af3fSArnaldo Carvalho de Melo dp->dccps_awl, dp->dccps_awh)) { 4117690af3fSArnaldo Carvalho de Melo dccp_pr_debug("invalid ackno: S.AWL=%llu, " 4127690af3fSArnaldo Carvalho de Melo "P.ackno=%llu, S.AWH=%llu\n", 413f6ccf554SDavid S. Miller (unsigned long long)dp->dccps_awl, 414f6ccf554SDavid S. Miller (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, 415f6ccf554SDavid S. Miller (unsigned long long)dp->dccps_awh); 4167c657876SArnaldo Carvalho de Melo goto out_invalid_packet; 4177c657876SArnaldo Carvalho de Melo } 4187c657876SArnaldo Carvalho de Melo 419991d927cSGerrit Renker /* 420991d927cSGerrit Renker * If option processing (Step 8) failed, return 1 here so that 421991d927cSGerrit Renker * dccp_v4_do_rcv() sends a Reset. The Reset code depends on 422991d927cSGerrit Renker * the option type and is set in dccp_parse_options(). 423991d927cSGerrit Renker */ 4248b819412SGerrit Renker if (dccp_parse_options(sk, NULL, skb)) 425991d927cSGerrit Renker return 1; 426afe00251SAndrea Bittau 42759b80802SGerrit Renker /* Obtain usec RTT sample from SYN exchange (used by TFRC). */ 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 432d28934adSGerrit Renker /* Stop the REQUEST timer */ 433d28934adSGerrit Renker inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); 434d28934adSGerrit Renker WARN_ON(sk->sk_send_head == NULL); 435d28934adSGerrit Renker kfree_skb(sk->sk_send_head); 436d28934adSGerrit Renker sk->sk_send_head = NULL; 437d28934adSGerrit Renker 43803ace394SArnaldo Carvalho de Melo /* 4390b53d460SGerrit Renker * Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect 4400b53d460SGerrit Renker * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH 4410b53d460SGerrit Renker * is done as part of activating the feature values below, since 4420b53d460SGerrit Renker * these settings depend on the local/remote Sequence Window 4430b53d460SGerrit Renker * features, which were undefined or not confirmed until now. 44403ace394SArnaldo Carvalho de Melo */ 4450b53d460SGerrit Renker dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; 4467c657876SArnaldo Carvalho de Melo 447d83d8461SArnaldo Carvalho de Melo dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); 4487c657876SArnaldo Carvalho de Melo 4497c657876SArnaldo Carvalho de Melo /* 4507c657876SArnaldo Carvalho de Melo * Step 10: Process REQUEST state (second part) 4517c657876SArnaldo Carvalho de Melo * If S.state == REQUEST, 4527690af3fSArnaldo Carvalho de Melo * / * If we get here, P is a valid Response from the 4537690af3fSArnaldo Carvalho de Melo * server (see Step 4), and we should move to 4547690af3fSArnaldo Carvalho de Melo * PARTOPEN state. PARTOPEN means send an Ack, 4557690af3fSArnaldo Carvalho de Melo * don't send Data packets, retransmit Acks 4567690af3fSArnaldo Carvalho de Melo * periodically, and always include any Init Cookie 4577690af3fSArnaldo Carvalho de Melo * from the Response * / 4587c657876SArnaldo Carvalho de Melo * S.state := PARTOPEN 4597c657876SArnaldo Carvalho de Melo * Set PARTOPEN timer 4607c657876SArnaldo Carvalho de Melo * Continue with S.state == PARTOPEN 4617690af3fSArnaldo Carvalho de Melo * / * Step 12 will send the Ack completing the 4627690af3fSArnaldo Carvalho de Melo * three-way handshake * / 4637c657876SArnaldo Carvalho de Melo */ 4647c657876SArnaldo Carvalho de Melo dccp_set_state(sk, DCCP_PARTOPEN); 4657c657876SArnaldo Carvalho de Melo 466991d927cSGerrit Renker /* 467991d927cSGerrit Renker * If feature negotiation was successful, activate features now; 468991d927cSGerrit Renker * an activation failure means that this host could not activate 469991d927cSGerrit Renker * one ore more features (e.g. insufficient memory), which would 470991d927cSGerrit Renker * leave at least one feature in an undefined state. 471991d927cSGerrit Renker */ 472991d927cSGerrit Renker if (dccp_feat_activate_values(sk, &dp->dccps_featneg)) 473991d927cSGerrit Renker goto unable_to_proceed; 474991d927cSGerrit Renker 4757c657876SArnaldo Carvalho de Melo /* Make sure socket is routed, for correct metrics. */ 47657cca05aSArnaldo Carvalho de Melo icsk->icsk_af_ops->rebuild_header(sk); 4777c657876SArnaldo Carvalho de Melo 4787c657876SArnaldo Carvalho de Melo if (!sock_flag(sk, SOCK_DEAD)) { 4797c657876SArnaldo Carvalho de Melo sk->sk_state_change(sk); 4808d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); 4817c657876SArnaldo Carvalho de Melo } 4827c657876SArnaldo Carvalho de Melo 483*31954cd8SWei Wang if (sk->sk_write_pending || inet_csk_in_pingpong_mode(sk) || 4847c657876SArnaldo Carvalho de Melo icsk->icsk_accept_queue.rskq_defer_accept) { 4857c657876SArnaldo Carvalho de Melo /* Save one ACK. Data will be ready after 4867c657876SArnaldo Carvalho de Melo * several ticks, if write_pending is set. 4877c657876SArnaldo Carvalho de Melo * 4887c657876SArnaldo Carvalho de Melo * It may be deleted, but with this feature tcpdumps 4897c657876SArnaldo Carvalho de Melo * look so _wonderfully_ clever, that I was not able 4907c657876SArnaldo Carvalho de Melo * to stand against the temptation 8) --ANK 4917c657876SArnaldo Carvalho de Melo */ 4927c657876SArnaldo Carvalho de Melo /* 4937c657876SArnaldo Carvalho de Melo * OK, in DCCP we can as well do a similar trick, its 4947c657876SArnaldo Carvalho de Melo * even in the draft, but there is no need for us to 4957c657876SArnaldo Carvalho de Melo * schedule an ack here, as dccp_sendmsg does this for 4967c657876SArnaldo Carvalho de Melo * us, also stated in the draft. -acme 4977c657876SArnaldo Carvalho de Melo */ 4987c657876SArnaldo Carvalho de Melo __kfree_skb(skb); 4997c657876SArnaldo Carvalho de Melo return 0; 5007c657876SArnaldo Carvalho de Melo } 5017c657876SArnaldo Carvalho de Melo dccp_send_ack(sk); 5027c657876SArnaldo Carvalho de Melo return -1; 5037c657876SArnaldo Carvalho de Melo } 5047c657876SArnaldo Carvalho de Melo 5057c657876SArnaldo Carvalho de Melo out_invalid_packet: 5060c10c5d9SArnaldo Carvalho de Melo /* dccp_v4_do_rcv will send a reset */ 5070c10c5d9SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; 5080c10c5d9SArnaldo Carvalho de Melo return 1; 509991d927cSGerrit Renker 510991d927cSGerrit Renker unable_to_proceed: 511991d927cSGerrit Renker DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_ABORTED; 512991d927cSGerrit Renker /* 513991d927cSGerrit Renker * We mark this socket as no longer usable, so that the loop in 514991d927cSGerrit Renker * dccp_sendmsg() terminates and the application gets notified. 515991d927cSGerrit Renker */ 516991d927cSGerrit Renker dccp_set_state(sk, DCCP_CLOSED); 517991d927cSGerrit Renker sk->sk_err = ECOMM; 518991d927cSGerrit Renker return 1; 5197c657876SArnaldo Carvalho de Melo } 5207c657876SArnaldo Carvalho de Melo 5217c657876SArnaldo Carvalho de Melo static int dccp_rcv_respond_partopen_state_process(struct sock *sk, 5227c657876SArnaldo Carvalho de Melo struct sk_buff *skb, 5237c657876SArnaldo Carvalho de Melo const struct dccp_hdr *dh, 52495c96174SEric Dumazet const unsigned int len) 5257c657876SArnaldo Carvalho de Melo { 52659b80802SGerrit Renker struct dccp_sock *dp = dccp_sk(sk); 52759b80802SGerrit Renker u32 sample = dp->dccps_options_received.dccpor_timestamp_echo; 5287c657876SArnaldo Carvalho de Melo int queued = 0; 5297c657876SArnaldo Carvalho de Melo 5307c657876SArnaldo Carvalho de Melo switch (dh->dccph_type) { 5317c657876SArnaldo Carvalho de Melo case DCCP_PKT_RESET: 5327c657876SArnaldo Carvalho de Melo inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 5337c657876SArnaldo Carvalho de Melo break; 5342a9bc9bbSArnaldo Carvalho de Melo case DCCP_PKT_DATA: 5352a9bc9bbSArnaldo Carvalho de Melo if (sk->sk_state == DCCP_RESPOND) 5362a9bc9bbSArnaldo Carvalho de Melo break; 537bc28df6eSGustavo A. R. Silva /* fall through */ 5387c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATAACK: 5397c657876SArnaldo Carvalho de Melo case DCCP_PKT_ACK: 5407c657876SArnaldo Carvalho de Melo /* 541a77b6343SFabian Frederick * FIXME: we should be resetting the PARTOPEN (DELACK) timer 5427690af3fSArnaldo Carvalho de Melo * here but only if we haven't used the DELACK timer for 5437690af3fSArnaldo Carvalho de Melo * something else, like sending a delayed ack for a TIMESTAMP 5447690af3fSArnaldo Carvalho de Melo * echo, etc, for now were not clearing it, sending an extra 5457690af3fSArnaldo Carvalho de Melo * ACK when there is nothing else to do in DELACK is not a big 5467690af3fSArnaldo Carvalho de Melo * deal after all. 5477c657876SArnaldo Carvalho de Melo */ 5487c657876SArnaldo Carvalho de Melo 5497c657876SArnaldo Carvalho de Melo /* Stop the PARTOPEN timer */ 5507c657876SArnaldo Carvalho de Melo if (sk->sk_state == DCCP_PARTOPEN) 5517c657876SArnaldo Carvalho de Melo inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 5527c657876SArnaldo Carvalho de Melo 55359b80802SGerrit Renker /* Obtain usec RTT sample from SYN exchange (used by TFRC). */ 55459b80802SGerrit Renker if (likely(sample)) { 55559b80802SGerrit Renker long delta = dccp_timestamp() - sample; 55659b80802SGerrit Renker 55759b80802SGerrit Renker dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * delta); 55859b80802SGerrit Renker } 55959b80802SGerrit Renker 56059b80802SGerrit Renker dp->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq; 5617c657876SArnaldo Carvalho de Melo dccp_set_state(sk, DCCP_OPEN); 5627c657876SArnaldo Carvalho de Melo 5632a9bc9bbSArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_DATAACK || 5642a9bc9bbSArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_DATA) { 565709dd3aaSAndrea Bittau __dccp_rcv_established(sk, skb, dh, len); 5667690af3fSArnaldo Carvalho de Melo queued = 1; /* packet was queued 567709dd3aaSAndrea Bittau (by __dccp_rcv_established) */ 5687c657876SArnaldo Carvalho de Melo } 5697c657876SArnaldo Carvalho de Melo break; 5707c657876SArnaldo Carvalho de Melo } 5717c657876SArnaldo Carvalho de Melo 5727c657876SArnaldo Carvalho de Melo return queued; 5737c657876SArnaldo Carvalho de Melo } 5747c657876SArnaldo Carvalho de Melo 5757c657876SArnaldo Carvalho de Melo int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, 57695c96174SEric Dumazet struct dccp_hdr *dh, unsigned int len) 5777c657876SArnaldo Carvalho de Melo { 5787c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 5790c10c5d9SArnaldo Carvalho de Melo struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 5807c657876SArnaldo Carvalho de Melo const int old_state = sk->sk_state; 581449809a6SEric Dumazet bool acceptable; 5827c657876SArnaldo Carvalho de Melo int queued = 0; 5837c657876SArnaldo Carvalho de Melo 5848649b0d4SArnaldo Carvalho de Melo /* 5858649b0d4SArnaldo Carvalho de Melo * Step 3: Process LISTEN state 5868649b0d4SArnaldo Carvalho de Melo * 5878649b0d4SArnaldo Carvalho de Melo * If S.state == LISTEN, 588d83ca5acSGerrit Renker * If P.type == Request or P contains a valid Init Cookie option, 589d83ca5acSGerrit Renker * (* Must scan the packet's options to check for Init 590d83ca5acSGerrit Renker * Cookies. Only Init Cookies are processed here, 5918649b0d4SArnaldo Carvalho de Melo * however; other options are processed in Step 8. This 5928649b0d4SArnaldo Carvalho de Melo * scan need only be performed if the endpoint uses Init 593d83ca5acSGerrit Renker * Cookies *) 594d83ca5acSGerrit Renker * (* Generate a new socket and switch to that socket *) 5958649b0d4SArnaldo Carvalho de Melo * Set S := new socket for this port pair 5968649b0d4SArnaldo Carvalho de Melo * S.state = RESPOND 597d83ca5acSGerrit Renker * Choose S.ISS (initial seqno) or set from Init Cookies 598d83ca5acSGerrit Renker * Initialize S.GAR := S.ISS 599d83ca5acSGerrit Renker * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init 600d83ca5acSGerrit Renker * Cookies Continue with S.state == RESPOND 601d83ca5acSGerrit Renker * (* A Response packet will be generated in Step 11 *) 6028649b0d4SArnaldo Carvalho de Melo * Otherwise, 6038649b0d4SArnaldo Carvalho de Melo * Generate Reset(No Connection) unless P.type == Reset 6048649b0d4SArnaldo Carvalho de Melo * Drop packet and return 6058649b0d4SArnaldo Carvalho de Melo */ 6068649b0d4SArnaldo Carvalho de Melo if (sk->sk_state == DCCP_LISTEN) { 6078649b0d4SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_REQUEST) { 608449809a6SEric Dumazet /* It is possible that we process SYN packets from backlog, 6091ad98e9dSEric Dumazet * so we need to make sure to disable BH and RCU right there. 610449809a6SEric Dumazet */ 6111ad98e9dSEric Dumazet rcu_read_lock(); 612449809a6SEric Dumazet local_bh_disable(); 613449809a6SEric Dumazet acceptable = inet_csk(sk)->icsk_af_ops->conn_request(sk, skb) >= 0; 614449809a6SEric Dumazet local_bh_enable(); 6151ad98e9dSEric Dumazet rcu_read_unlock(); 616449809a6SEric Dumazet if (!acceptable) 6178649b0d4SArnaldo Carvalho de Melo return 1; 6185edabca9SAndrey Konovalov consume_skb(skb); 6195edabca9SAndrey Konovalov return 0; 6208649b0d4SArnaldo Carvalho de Melo } 6218649b0d4SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_RESET) 6228649b0d4SArnaldo Carvalho de Melo goto discard; 6238649b0d4SArnaldo Carvalho de Melo 6240c10c5d9SArnaldo Carvalho de Melo /* Caller (dccp_v4_do_rcv) will send Reset */ 6250c10c5d9SArnaldo Carvalho de Melo dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 6268649b0d4SArnaldo Carvalho de Melo return 1; 627720dc34bSGerrit Renker } else if (sk->sk_state == DCCP_CLOSED) { 628720dc34bSGerrit Renker dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 629720dc34bSGerrit Renker return 1; 6308649b0d4SArnaldo Carvalho de Melo } 6318649b0d4SArnaldo Carvalho de Melo 632c0c20150SGerrit Renker /* Step 6: Check sequence numbers (omitted in LISTEN/REQUEST state) */ 633c0c20150SGerrit Renker if (sk->sk_state != DCCP_REQUESTING && dccp_check_seqno(sk, skb)) 6347c657876SArnaldo Carvalho de Melo goto discard; 6357c657876SArnaldo Carvalho de Melo 6367c657876SArnaldo Carvalho de Melo /* 637c0c20150SGerrit Renker * Step 7: Check for unexpected packet types 638c0c20150SGerrit Renker * If (S.is_server and P.type == Response) 639c0c20150SGerrit Renker * or (S.is_client and P.type == Request) 640c0c20150SGerrit Renker * or (S.state == RESPOND and P.type == Data), 641c0c20150SGerrit Renker * Send Sync packet acknowledging P.seqno 642c0c20150SGerrit Renker * Drop packet and return 6437c657876SArnaldo Carvalho de Melo */ 644c0c20150SGerrit Renker if ((dp->dccps_role != DCCP_ROLE_CLIENT && 645c0c20150SGerrit Renker dh->dccph_type == DCCP_PKT_RESPONSE) || 646c0c20150SGerrit Renker (dp->dccps_role == DCCP_ROLE_CLIENT && 647c0c20150SGerrit Renker dh->dccph_type == DCCP_PKT_REQUEST) || 648c0c20150SGerrit Renker (sk->sk_state == DCCP_RESPOND && dh->dccph_type == DCCP_PKT_DATA)) { 649c0c20150SGerrit Renker dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC); 650c0c20150SGerrit Renker goto discard; 651c0c20150SGerrit Renker } 652c0c20150SGerrit Renker 653c0c20150SGerrit Renker /* Step 8: Process options */ 6548b819412SGerrit Renker if (dccp_parse_options(sk, NULL, skb)) 655ba1a6c7bSWei Yongjun return 1; 6567c657876SArnaldo Carvalho de Melo 6577c657876SArnaldo Carvalho de Melo /* 6587c657876SArnaldo Carvalho de Melo * Step 9: Process Reset 6597c657876SArnaldo Carvalho de Melo * If P.type == Reset, 6607c657876SArnaldo Carvalho de Melo * Tear down connection 6617c657876SArnaldo Carvalho de Melo * S.state := TIMEWAIT 6627c657876SArnaldo Carvalho de Melo * Set TIMEWAIT timer 6637c657876SArnaldo Carvalho de Melo * Drop packet and return 6647c657876SArnaldo Carvalho de Melo */ 6657c657876SArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_RESET) { 666d8ef2c29SGerrit Renker dccp_rcv_reset(sk, skb); 6677c657876SArnaldo Carvalho de Melo return 0; 668c0c20150SGerrit Renker } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { /* Step 13 */ 6690c869620SGerrit Renker if (dccp_rcv_closereq(sk, skb)) 6700c869620SGerrit Renker return 0; 6717ad07e7cSArnaldo Carvalho de Melo goto discard; 672c0c20150SGerrit Renker } else if (dh->dccph_type == DCCP_PKT_CLOSE) { /* Step 14 */ 6730c869620SGerrit Renker if (dccp_rcv_close(sk, skb)) 6747ad07e7cSArnaldo Carvalho de Melo return 0; 6750c869620SGerrit Renker goto discard; 6767c657876SArnaldo Carvalho de Melo } 6777c657876SArnaldo Carvalho de Melo 6787c657876SArnaldo Carvalho de Melo switch (sk->sk_state) { 6797c657876SArnaldo Carvalho de Melo case DCCP_REQUESTING: 6807c657876SArnaldo Carvalho de Melo queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); 6817c657876SArnaldo Carvalho de Melo if (queued >= 0) 6827c657876SArnaldo Carvalho de Melo return queued; 6837c657876SArnaldo Carvalho de Melo 6847c657876SArnaldo Carvalho de Melo __kfree_skb(skb); 6857c657876SArnaldo Carvalho de Melo return 0; 6867c657876SArnaldo Carvalho de Melo 687410e27a4SGerrit Renker case DCCP_PARTOPEN: 688c0c20150SGerrit Renker /* Step 8: if using Ack Vectors, mark packet acknowledgeable */ 689c0c20150SGerrit Renker dccp_handle_ackvec_processing(sk, skb); 690c0c20150SGerrit Renker dccp_deliver_input_to_ccids(sk, skb); 691c0c20150SGerrit Renker /* fall through */ 692c0c20150SGerrit Renker case DCCP_RESPOND: 6937690af3fSArnaldo Carvalho de Melo queued = dccp_rcv_respond_partopen_state_process(sk, skb, 6947690af3fSArnaldo Carvalho de Melo dh, len); 6957c657876SArnaldo Carvalho de Melo break; 6967c657876SArnaldo Carvalho de Melo } 6977c657876SArnaldo Carvalho de Melo 6987690af3fSArnaldo Carvalho de Melo if (dh->dccph_type == DCCP_PKT_ACK || 6997690af3fSArnaldo Carvalho de Melo dh->dccph_type == DCCP_PKT_DATAACK) { 7007c657876SArnaldo Carvalho de Melo switch (old_state) { 7017c657876SArnaldo Carvalho de Melo case DCCP_PARTOPEN: 7027c657876SArnaldo Carvalho de Melo sk->sk_state_change(sk); 7038d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); 7047c657876SArnaldo Carvalho de Melo break; 7057c657876SArnaldo Carvalho de Melo } 70608831700SGerrit Renker } else if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) { 70708831700SGerrit Renker dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNCACK); 70808831700SGerrit Renker goto discard; 7097c657876SArnaldo Carvalho de Melo } 7107c657876SArnaldo Carvalho de Melo 7117c657876SArnaldo Carvalho de Melo if (!queued) { 7127c657876SArnaldo Carvalho de Melo discard: 7137c657876SArnaldo Carvalho de Melo __kfree_skb(skb); 7147c657876SArnaldo Carvalho de Melo } 7157c657876SArnaldo Carvalho de Melo return 0; 7167c657876SArnaldo Carvalho de Melo } 717f21e68caSArnaldo Carvalho de Melo 718f21e68caSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_rcv_state_process); 7194712a792SGerrit Renker 7204712a792SGerrit Renker /** 7213393da82SGerrit Renker * dccp_sample_rtt - Validate and finalise computation of RTT sample 7223393da82SGerrit Renker * @delta: number of microseconds between packet and acknowledgment 7232c53040fSBen Hutchings * 7243393da82SGerrit Renker * The routine is kept generic to work in different contexts. It should be 7253393da82SGerrit Renker * called immediately when the ACK used for the RTT sample arrives. 7264712a792SGerrit Renker */ 7273393da82SGerrit Renker u32 dccp_sample_rtt(struct sock *sk, long delta) 7284712a792SGerrit Renker { 7293393da82SGerrit Renker /* dccpor_elapsed_time is either zeroed out or set and > 0 */ 7303393da82SGerrit Renker delta -= dccp_sk(sk)->dccps_options_received.dccpor_elapsed_time * 10; 7314712a792SGerrit Renker 732410e27a4SGerrit Renker if (unlikely(delta <= 0)) { 733410e27a4SGerrit Renker DCCP_WARN("unusable RTT sample %ld, using min\n", delta); 734410e27a4SGerrit Renker return DCCP_SANE_RTT_MIN; 735410e27a4SGerrit Renker } 736410e27a4SGerrit Renker if (unlikely(delta > DCCP_SANE_RTT_MAX)) { 737410e27a4SGerrit Renker DCCP_WARN("RTT sample %ld too large, using max\n", delta); 738410e27a4SGerrit Renker return DCCP_SANE_RTT_MAX; 739410e27a4SGerrit Renker } 740410e27a4SGerrit Renker 741410e27a4SGerrit Renker return delta; 7424712a792SGerrit Renker } 743