18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * net/dccp/input.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * An implementation of the DCCP protocol 68c2ecf20Sopenharmony_ci * Arnaldo Carvalho de Melo <acme@conectiva.com.br> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/dccp.h> 108c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 118c2ecf20Sopenharmony_ci#include <linux/slab.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <net/sock.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include "ackvec.h" 168c2ecf20Sopenharmony_ci#include "ccid.h" 178c2ecf20Sopenharmony_ci#include "dccp.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ 208c2ecf20Sopenharmony_ciint sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic void dccp_enqueue_skb(struct sock *sk, struct sk_buff *skb) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci __skb_pull(skb, dccp_hdr(skb)->dccph_doff * 4); 258c2ecf20Sopenharmony_ci __skb_queue_tail(&sk->sk_receive_queue, skb); 268c2ecf20Sopenharmony_ci skb_set_owner_r(skb, sk); 278c2ecf20Sopenharmony_ci sk->sk_data_ready(sk); 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic void dccp_fin(struct sock *sk, struct sk_buff *skb) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci /* 338c2ecf20Sopenharmony_ci * On receiving Close/CloseReq, both RD/WR shutdown are performed. 348c2ecf20Sopenharmony_ci * RFC 4340, 8.3 says that we MAY send further Data/DataAcks after 358c2ecf20Sopenharmony_ci * receiving the closing segment, but there is no guarantee that such 368c2ecf20Sopenharmony_ci * data will be processed at all. 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci sk->sk_shutdown = SHUTDOWN_MASK; 398c2ecf20Sopenharmony_ci sock_set_flag(sk, SOCK_DONE); 408c2ecf20Sopenharmony_ci dccp_enqueue_skb(sk, skb); 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic int dccp_rcv_close(struct sock *sk, struct sk_buff *skb) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci int queued = 0; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci switch (sk->sk_state) { 488c2ecf20Sopenharmony_ci /* 498c2ecf20Sopenharmony_ci * We ignore Close when received in one of the following states: 508c2ecf20Sopenharmony_ci * - CLOSED (may be a late or duplicate packet) 518c2ecf20Sopenharmony_ci * - PASSIVE_CLOSEREQ (the peer has sent a CloseReq earlier) 528c2ecf20Sopenharmony_ci * - RESPOND (already handled by dccp_check_req) 538c2ecf20Sopenharmony_ci */ 548c2ecf20Sopenharmony_ci case DCCP_CLOSING: 558c2ecf20Sopenharmony_ci /* 568c2ecf20Sopenharmony_ci * Simultaneous-close: receiving a Close after sending one. This 578c2ecf20Sopenharmony_ci * can happen if both client and server perform active-close and 588c2ecf20Sopenharmony_ci * will result in an endless ping-pong of crossing and retrans- 598c2ecf20Sopenharmony_ci * mitted Close packets, which only terminates when one of the 608c2ecf20Sopenharmony_ci * nodes times out (min. 64 seconds). Quicker convergence can be 618c2ecf20Sopenharmony_ci * achieved when one of the nodes acts as tie-breaker. 628c2ecf20Sopenharmony_ci * This is ok as both ends are done with data transfer and each 638c2ecf20Sopenharmony_ci * end is just waiting for the other to acknowledge termination. 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) 668c2ecf20Sopenharmony_ci break; 678c2ecf20Sopenharmony_ci fallthrough; 688c2ecf20Sopenharmony_ci case DCCP_REQUESTING: 698c2ecf20Sopenharmony_ci case DCCP_ACTIVE_CLOSEREQ: 708c2ecf20Sopenharmony_ci dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED); 718c2ecf20Sopenharmony_ci dccp_done(sk); 728c2ecf20Sopenharmony_ci break; 738c2ecf20Sopenharmony_ci case DCCP_OPEN: 748c2ecf20Sopenharmony_ci case DCCP_PARTOPEN: 758c2ecf20Sopenharmony_ci /* Give waiting application a chance to read pending data */ 768c2ecf20Sopenharmony_ci queued = 1; 778c2ecf20Sopenharmony_ci dccp_fin(sk, skb); 788c2ecf20Sopenharmony_ci dccp_set_state(sk, DCCP_PASSIVE_CLOSE); 798c2ecf20Sopenharmony_ci fallthrough; 808c2ecf20Sopenharmony_ci case DCCP_PASSIVE_CLOSE: 818c2ecf20Sopenharmony_ci /* 828c2ecf20Sopenharmony_ci * Retransmitted Close: we have already enqueued the first one. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP); 858c2ecf20Sopenharmony_ci } 868c2ecf20Sopenharmony_ci return queued; 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic int dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci int queued = 0; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci /* 948c2ecf20Sopenharmony_ci * Step 7: Check for unexpected packet types 958c2ecf20Sopenharmony_ci * If (S.is_server and P.type == CloseReq) 968c2ecf20Sopenharmony_ci * Send Sync packet acknowledging P.seqno 978c2ecf20Sopenharmony_ci * Drop packet and return 988c2ecf20Sopenharmony_ci */ 998c2ecf20Sopenharmony_ci if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) { 1008c2ecf20Sopenharmony_ci dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC); 1018c2ecf20Sopenharmony_ci return queued; 1028c2ecf20Sopenharmony_ci } 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci /* Step 13: process relevant Client states < CLOSEREQ */ 1058c2ecf20Sopenharmony_ci switch (sk->sk_state) { 1068c2ecf20Sopenharmony_ci case DCCP_REQUESTING: 1078c2ecf20Sopenharmony_ci dccp_send_close(sk, 0); 1088c2ecf20Sopenharmony_ci dccp_set_state(sk, DCCP_CLOSING); 1098c2ecf20Sopenharmony_ci break; 1108c2ecf20Sopenharmony_ci case DCCP_OPEN: 1118c2ecf20Sopenharmony_ci case DCCP_PARTOPEN: 1128c2ecf20Sopenharmony_ci /* Give waiting application a chance to read pending data */ 1138c2ecf20Sopenharmony_ci queued = 1; 1148c2ecf20Sopenharmony_ci dccp_fin(sk, skb); 1158c2ecf20Sopenharmony_ci dccp_set_state(sk, DCCP_PASSIVE_CLOSEREQ); 1168c2ecf20Sopenharmony_ci fallthrough; 1178c2ecf20Sopenharmony_ci case DCCP_PASSIVE_CLOSEREQ: 1188c2ecf20Sopenharmony_ci sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP); 1198c2ecf20Sopenharmony_ci } 1208c2ecf20Sopenharmony_ci return queued; 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic u16 dccp_reset_code_convert(const u8 code) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci static const u16 error_code[] = { 1268c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_CLOSED] = 0, /* normal termination */ 1278c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_UNSPECIFIED] = 0, /* nothing known */ 1288c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_ABORTED] = ECONNRESET, 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_NO_CONNECTION] = ECONNREFUSED, 1318c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED, 1328c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_TOO_BUSY] = EUSERS, 1338c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT, 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_PACKET_ERROR] = ENOMSG, 1368c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_BAD_INIT_COOKIE] = EBADR, 1378c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_BAD_SERVICE_CODE] = EBADRQC, 1388c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_OPTION_ERROR] = EILSEQ, 1398c2ecf20Sopenharmony_ci [DCCP_RESET_CODE_MANDATORY_ERROR] = EOPNOTSUPP, 1408c2ecf20Sopenharmony_ci }; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci return code >= DCCP_MAX_RESET_CODES ? 0 : error_code[code]; 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistatic void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci u16 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci sk->sk_err = err; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci /* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */ 1528c2ecf20Sopenharmony_ci dccp_fin(sk, skb); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci if (err && !sock_flag(sk, SOCK_DEAD)) 1558c2ecf20Sopenharmony_ci sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR); 1568c2ecf20Sopenharmony_ci dccp_time_wait(sk, DCCP_TIME_WAIT, 0); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci if (av == NULL) 1648c2ecf20Sopenharmony_ci return; 1658c2ecf20Sopenharmony_ci if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 1668c2ecf20Sopenharmony_ci dccp_ackvec_clear_state(av, DCCP_SKB_CB(skb)->dccpd_ack_seq); 1678c2ecf20Sopenharmony_ci dccp_ackvec_input(av, skb); 1688c2ecf20Sopenharmony_ci} 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_cistatic void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci const struct dccp_sock *dp = dccp_sk(sk); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci /* Don't deliver to RX CCID when node has shut down read end. */ 1758c2ecf20Sopenharmony_ci if (!(sk->sk_shutdown & RCV_SHUTDOWN)) 1768c2ecf20Sopenharmony_ci ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); 1778c2ecf20Sopenharmony_ci /* 1788c2ecf20Sopenharmony_ci * Until the TX queue has been drained, we can not honour SHUT_WR, since 1798c2ecf20Sopenharmony_ci * we need received feedback as input to adjust congestion control. 1808c2ecf20Sopenharmony_ci */ 1818c2ecf20Sopenharmony_ci if (sk->sk_write_queue.qlen > 0 || !(sk->sk_shutdown & SEND_SHUTDOWN)) 1828c2ecf20Sopenharmony_ci ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); 1838c2ecf20Sopenharmony_ci} 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_cistatic int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci const struct dccp_hdr *dh = dccp_hdr(skb); 1888c2ecf20Sopenharmony_ci struct dccp_sock *dp = dccp_sk(sk); 1898c2ecf20Sopenharmony_ci u64 lswl, lawl, seqno = DCCP_SKB_CB(skb)->dccpd_seq, 1908c2ecf20Sopenharmony_ci ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci /* 1938c2ecf20Sopenharmony_ci * Step 5: Prepare sequence numbers for Sync 1948c2ecf20Sopenharmony_ci * If P.type == Sync or P.type == SyncAck, 1958c2ecf20Sopenharmony_ci * If S.AWL <= P.ackno <= S.AWH and P.seqno >= S.SWL, 1968c2ecf20Sopenharmony_ci * / * P is valid, so update sequence number variables 1978c2ecf20Sopenharmony_ci * accordingly. After this update, P will pass the tests 1988c2ecf20Sopenharmony_ci * in Step 6. A SyncAck is generated if necessary in 1998c2ecf20Sopenharmony_ci * Step 15 * / 2008c2ecf20Sopenharmony_ci * Update S.GSR, S.SWL, S.SWH 2018c2ecf20Sopenharmony_ci * Otherwise, 2028c2ecf20Sopenharmony_ci * Drop packet and return 2038c2ecf20Sopenharmony_ci */ 2048c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_SYNC || 2058c2ecf20Sopenharmony_ci dh->dccph_type == DCCP_PKT_SYNCACK) { 2068c2ecf20Sopenharmony_ci if (between48(ackno, dp->dccps_awl, dp->dccps_awh) && 2078c2ecf20Sopenharmony_ci dccp_delta_seqno(dp->dccps_swl, seqno) >= 0) 2088c2ecf20Sopenharmony_ci dccp_update_gsr(sk, seqno); 2098c2ecf20Sopenharmony_ci else 2108c2ecf20Sopenharmony_ci return -1; 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci /* 2148c2ecf20Sopenharmony_ci * Step 6: Check sequence numbers 2158c2ecf20Sopenharmony_ci * Let LSWL = S.SWL and LAWL = S.AWL 2168c2ecf20Sopenharmony_ci * If P.type == CloseReq or P.type == Close or P.type == Reset, 2178c2ecf20Sopenharmony_ci * LSWL := S.GSR + 1, LAWL := S.GAR 2188c2ecf20Sopenharmony_ci * If LSWL <= P.seqno <= S.SWH 2198c2ecf20Sopenharmony_ci * and (P.ackno does not exist or LAWL <= P.ackno <= S.AWH), 2208c2ecf20Sopenharmony_ci * Update S.GSR, S.SWL, S.SWH 2218c2ecf20Sopenharmony_ci * If P.type != Sync, 2228c2ecf20Sopenharmony_ci * Update S.GAR 2238c2ecf20Sopenharmony_ci */ 2248c2ecf20Sopenharmony_ci lswl = dp->dccps_swl; 2258c2ecf20Sopenharmony_ci lawl = dp->dccps_awl; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_CLOSEREQ || 2288c2ecf20Sopenharmony_ci dh->dccph_type == DCCP_PKT_CLOSE || 2298c2ecf20Sopenharmony_ci dh->dccph_type == DCCP_PKT_RESET) { 2308c2ecf20Sopenharmony_ci lswl = ADD48(dp->dccps_gsr, 1); 2318c2ecf20Sopenharmony_ci lawl = dp->dccps_gar; 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci if (between48(seqno, lswl, dp->dccps_swh) && 2358c2ecf20Sopenharmony_ci (ackno == DCCP_PKT_WITHOUT_ACK_SEQ || 2368c2ecf20Sopenharmony_ci between48(ackno, lawl, dp->dccps_awh))) { 2378c2ecf20Sopenharmony_ci dccp_update_gsr(sk, seqno); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci if (dh->dccph_type != DCCP_PKT_SYNC && 2408c2ecf20Sopenharmony_ci ackno != DCCP_PKT_WITHOUT_ACK_SEQ && 2418c2ecf20Sopenharmony_ci after48(ackno, dp->dccps_gar)) 2428c2ecf20Sopenharmony_ci dp->dccps_gar = ackno; 2438c2ecf20Sopenharmony_ci } else { 2448c2ecf20Sopenharmony_ci unsigned long now = jiffies; 2458c2ecf20Sopenharmony_ci /* 2468c2ecf20Sopenharmony_ci * Step 6: Check sequence numbers 2478c2ecf20Sopenharmony_ci * Otherwise, 2488c2ecf20Sopenharmony_ci * If P.type == Reset, 2498c2ecf20Sopenharmony_ci * Send Sync packet acknowledging S.GSR 2508c2ecf20Sopenharmony_ci * Otherwise, 2518c2ecf20Sopenharmony_ci * Send Sync packet acknowledging P.seqno 2528c2ecf20Sopenharmony_ci * Drop packet and return 2538c2ecf20Sopenharmony_ci * 2548c2ecf20Sopenharmony_ci * These Syncs are rate-limited as per RFC 4340, 7.5.4: 2558c2ecf20Sopenharmony_ci * at most 1 / (dccp_sync_rate_limit * HZ) Syncs per second. 2568c2ecf20Sopenharmony_ci */ 2578c2ecf20Sopenharmony_ci if (time_before(now, (dp->dccps_rate_last + 2588c2ecf20Sopenharmony_ci sysctl_dccp_sync_ratelimit))) 2598c2ecf20Sopenharmony_ci return -1; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci DCCP_WARN("Step 6 failed for %s packet, " 2628c2ecf20Sopenharmony_ci "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " 2638c2ecf20Sopenharmony_ci "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " 2648c2ecf20Sopenharmony_ci "sending SYNC...\n", dccp_packet_name(dh->dccph_type), 2658c2ecf20Sopenharmony_ci (unsigned long long) lswl, (unsigned long long) seqno, 2668c2ecf20Sopenharmony_ci (unsigned long long) dp->dccps_swh, 2678c2ecf20Sopenharmony_ci (ackno == DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" 2688c2ecf20Sopenharmony_ci : "exists", 2698c2ecf20Sopenharmony_ci (unsigned long long) lawl, (unsigned long long) ackno, 2708c2ecf20Sopenharmony_ci (unsigned long long) dp->dccps_awh); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci dp->dccps_rate_last = now; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_RESET) 2758c2ecf20Sopenharmony_ci seqno = dp->dccps_gsr; 2768c2ecf20Sopenharmony_ci dccp_send_sync(sk, seqno, DCCP_PKT_SYNC); 2778c2ecf20Sopenharmony_ci return -1; 2788c2ecf20Sopenharmony_ci } 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci return 0; 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, 2848c2ecf20Sopenharmony_ci const struct dccp_hdr *dh, const unsigned int len) 2858c2ecf20Sopenharmony_ci{ 2868c2ecf20Sopenharmony_ci struct dccp_sock *dp = dccp_sk(sk); 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci switch (dccp_hdr(skb)->dccph_type) { 2898c2ecf20Sopenharmony_ci case DCCP_PKT_DATAACK: 2908c2ecf20Sopenharmony_ci case DCCP_PKT_DATA: 2918c2ecf20Sopenharmony_ci /* 2928c2ecf20Sopenharmony_ci * FIXME: schedule DATA_DROPPED (RFC 4340, 11.7.2) if and when 2938c2ecf20Sopenharmony_ci * - sk_shutdown == RCV_SHUTDOWN, use Code 1, "Not Listening" 2948c2ecf20Sopenharmony_ci * - sk_receive_queue is full, use Code 2, "Receive Buffer" 2958c2ecf20Sopenharmony_ci */ 2968c2ecf20Sopenharmony_ci dccp_enqueue_skb(sk, skb); 2978c2ecf20Sopenharmony_ci return 0; 2988c2ecf20Sopenharmony_ci case DCCP_PKT_ACK: 2998c2ecf20Sopenharmony_ci goto discard; 3008c2ecf20Sopenharmony_ci case DCCP_PKT_RESET: 3018c2ecf20Sopenharmony_ci /* 3028c2ecf20Sopenharmony_ci * Step 9: Process Reset 3038c2ecf20Sopenharmony_ci * If P.type == Reset, 3048c2ecf20Sopenharmony_ci * Tear down connection 3058c2ecf20Sopenharmony_ci * S.state := TIMEWAIT 3068c2ecf20Sopenharmony_ci * Set TIMEWAIT timer 3078c2ecf20Sopenharmony_ci * Drop packet and return 3088c2ecf20Sopenharmony_ci */ 3098c2ecf20Sopenharmony_ci dccp_rcv_reset(sk, skb); 3108c2ecf20Sopenharmony_ci return 0; 3118c2ecf20Sopenharmony_ci case DCCP_PKT_CLOSEREQ: 3128c2ecf20Sopenharmony_ci if (dccp_rcv_closereq(sk, skb)) 3138c2ecf20Sopenharmony_ci return 0; 3148c2ecf20Sopenharmony_ci goto discard; 3158c2ecf20Sopenharmony_ci case DCCP_PKT_CLOSE: 3168c2ecf20Sopenharmony_ci if (dccp_rcv_close(sk, skb)) 3178c2ecf20Sopenharmony_ci return 0; 3188c2ecf20Sopenharmony_ci goto discard; 3198c2ecf20Sopenharmony_ci case DCCP_PKT_REQUEST: 3208c2ecf20Sopenharmony_ci /* Step 7 3218c2ecf20Sopenharmony_ci * or (S.is_server and P.type == Response) 3228c2ecf20Sopenharmony_ci * or (S.is_client and P.type == Request) 3238c2ecf20Sopenharmony_ci * or (S.state >= OPEN and P.type == Request 3248c2ecf20Sopenharmony_ci * and P.seqno >= S.OSR) 3258c2ecf20Sopenharmony_ci * or (S.state >= OPEN and P.type == Response 3268c2ecf20Sopenharmony_ci * and P.seqno >= S.OSR) 3278c2ecf20Sopenharmony_ci * or (S.state == RESPOND and P.type == Data), 3288c2ecf20Sopenharmony_ci * Send Sync packet acknowledging P.seqno 3298c2ecf20Sopenharmony_ci * Drop packet and return 3308c2ecf20Sopenharmony_ci */ 3318c2ecf20Sopenharmony_ci if (dp->dccps_role != DCCP_ROLE_LISTEN) 3328c2ecf20Sopenharmony_ci goto send_sync; 3338c2ecf20Sopenharmony_ci goto check_seq; 3348c2ecf20Sopenharmony_ci case DCCP_PKT_RESPONSE: 3358c2ecf20Sopenharmony_ci if (dp->dccps_role != DCCP_ROLE_CLIENT) 3368c2ecf20Sopenharmony_ci goto send_sync; 3378c2ecf20Sopenharmony_cicheck_seq: 3388c2ecf20Sopenharmony_ci if (dccp_delta_seqno(dp->dccps_osr, 3398c2ecf20Sopenharmony_ci DCCP_SKB_CB(skb)->dccpd_seq) >= 0) { 3408c2ecf20Sopenharmony_cisend_sync: 3418c2ecf20Sopenharmony_ci dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, 3428c2ecf20Sopenharmony_ci DCCP_PKT_SYNC); 3438c2ecf20Sopenharmony_ci } 3448c2ecf20Sopenharmony_ci break; 3458c2ecf20Sopenharmony_ci case DCCP_PKT_SYNC: 3468c2ecf20Sopenharmony_ci dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, 3478c2ecf20Sopenharmony_ci DCCP_PKT_SYNCACK); 3488c2ecf20Sopenharmony_ci /* 3498c2ecf20Sopenharmony_ci * From RFC 4340, sec. 5.7 3508c2ecf20Sopenharmony_ci * 3518c2ecf20Sopenharmony_ci * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets 3528c2ecf20Sopenharmony_ci * MAY have non-zero-length application data areas, whose 3538c2ecf20Sopenharmony_ci * contents receivers MUST ignore. 3548c2ecf20Sopenharmony_ci */ 3558c2ecf20Sopenharmony_ci goto discard; 3568c2ecf20Sopenharmony_ci } 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci DCCP_INC_STATS(DCCP_MIB_INERRS); 3598c2ecf20Sopenharmony_cidiscard: 3608c2ecf20Sopenharmony_ci __kfree_skb(skb); 3618c2ecf20Sopenharmony_ci return 0; 3628c2ecf20Sopenharmony_ci} 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ciint dccp_rcv_established(struct sock *sk, struct sk_buff *skb, 3658c2ecf20Sopenharmony_ci const struct dccp_hdr *dh, const unsigned int len) 3668c2ecf20Sopenharmony_ci{ 3678c2ecf20Sopenharmony_ci if (dccp_check_seqno(sk, skb)) 3688c2ecf20Sopenharmony_ci goto discard; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci if (dccp_parse_options(sk, NULL, skb)) 3718c2ecf20Sopenharmony_ci return 1; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci dccp_handle_ackvec_processing(sk, skb); 3748c2ecf20Sopenharmony_ci dccp_deliver_input_to_ccids(sk, skb); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci return __dccp_rcv_established(sk, skb, dh, len); 3778c2ecf20Sopenharmony_cidiscard: 3788c2ecf20Sopenharmony_ci __kfree_skb(skb); 3798c2ecf20Sopenharmony_ci return 0; 3808c2ecf20Sopenharmony_ci} 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(dccp_rcv_established); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_cistatic int dccp_rcv_request_sent_state_process(struct sock *sk, 3858c2ecf20Sopenharmony_ci struct sk_buff *skb, 3868c2ecf20Sopenharmony_ci const struct dccp_hdr *dh, 3878c2ecf20Sopenharmony_ci const unsigned int len) 3888c2ecf20Sopenharmony_ci{ 3898c2ecf20Sopenharmony_ci /* 3908c2ecf20Sopenharmony_ci * Step 4: Prepare sequence numbers in REQUEST 3918c2ecf20Sopenharmony_ci * If S.state == REQUEST, 3928c2ecf20Sopenharmony_ci * If (P.type == Response or P.type == Reset) 3938c2ecf20Sopenharmony_ci * and S.AWL <= P.ackno <= S.AWH, 3948c2ecf20Sopenharmony_ci * / * Set sequence number variables corresponding to the 3958c2ecf20Sopenharmony_ci * other endpoint, so P will pass the tests in Step 6 * / 3968c2ecf20Sopenharmony_ci * Set S.GSR, S.ISR, S.SWL, S.SWH 3978c2ecf20Sopenharmony_ci * / * Response processing continues in Step 10; Reset 3988c2ecf20Sopenharmony_ci * processing continues in Step 9 * / 3998c2ecf20Sopenharmony_ci */ 4008c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_RESPONSE) { 4018c2ecf20Sopenharmony_ci const struct inet_connection_sock *icsk = inet_csk(sk); 4028c2ecf20Sopenharmony_ci struct dccp_sock *dp = dccp_sk(sk); 4038c2ecf20Sopenharmony_ci long tstamp = dccp_timestamp(); 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq, 4068c2ecf20Sopenharmony_ci dp->dccps_awl, dp->dccps_awh)) { 4078c2ecf20Sopenharmony_ci dccp_pr_debug("invalid ackno: S.AWL=%llu, " 4088c2ecf20Sopenharmony_ci "P.ackno=%llu, S.AWH=%llu\n", 4098c2ecf20Sopenharmony_ci (unsigned long long)dp->dccps_awl, 4108c2ecf20Sopenharmony_ci (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, 4118c2ecf20Sopenharmony_ci (unsigned long long)dp->dccps_awh); 4128c2ecf20Sopenharmony_ci goto out_invalid_packet; 4138c2ecf20Sopenharmony_ci } 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci /* 4168c2ecf20Sopenharmony_ci * If option processing (Step 8) failed, return 1 here so that 4178c2ecf20Sopenharmony_ci * dccp_v4_do_rcv() sends a Reset. The Reset code depends on 4188c2ecf20Sopenharmony_ci * the option type and is set in dccp_parse_options(). 4198c2ecf20Sopenharmony_ci */ 4208c2ecf20Sopenharmony_ci if (dccp_parse_options(sk, NULL, skb)) 4218c2ecf20Sopenharmony_ci return 1; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci /* Obtain usec RTT sample from SYN exchange (used by TFRC). */ 4248c2ecf20Sopenharmony_ci if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) 4258c2ecf20Sopenharmony_ci dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp - 4268c2ecf20Sopenharmony_ci dp->dccps_options_received.dccpor_timestamp_echo)); 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci /* Stop the REQUEST timer */ 4298c2ecf20Sopenharmony_ci inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); 4308c2ecf20Sopenharmony_ci WARN_ON(sk->sk_send_head == NULL); 4318c2ecf20Sopenharmony_ci kfree_skb(sk->sk_send_head); 4328c2ecf20Sopenharmony_ci sk->sk_send_head = NULL; 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci /* 4358c2ecf20Sopenharmony_ci * Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect 4368c2ecf20Sopenharmony_ci * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH 4378c2ecf20Sopenharmony_ci * is done as part of activating the feature values below, since 4388c2ecf20Sopenharmony_ci * these settings depend on the local/remote Sequence Window 4398c2ecf20Sopenharmony_ci * features, which were undefined or not confirmed until now. 4408c2ecf20Sopenharmony_ci */ 4418c2ecf20Sopenharmony_ci dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci /* 4468c2ecf20Sopenharmony_ci * Step 10: Process REQUEST state (second part) 4478c2ecf20Sopenharmony_ci * If S.state == REQUEST, 4488c2ecf20Sopenharmony_ci * / * If we get here, P is a valid Response from the 4498c2ecf20Sopenharmony_ci * server (see Step 4), and we should move to 4508c2ecf20Sopenharmony_ci * PARTOPEN state. PARTOPEN means send an Ack, 4518c2ecf20Sopenharmony_ci * don't send Data packets, retransmit Acks 4528c2ecf20Sopenharmony_ci * periodically, and always include any Init Cookie 4538c2ecf20Sopenharmony_ci * from the Response * / 4548c2ecf20Sopenharmony_ci * S.state := PARTOPEN 4558c2ecf20Sopenharmony_ci * Set PARTOPEN timer 4568c2ecf20Sopenharmony_ci * Continue with S.state == PARTOPEN 4578c2ecf20Sopenharmony_ci * / * Step 12 will send the Ack completing the 4588c2ecf20Sopenharmony_ci * three-way handshake * / 4598c2ecf20Sopenharmony_ci */ 4608c2ecf20Sopenharmony_ci dccp_set_state(sk, DCCP_PARTOPEN); 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci /* 4638c2ecf20Sopenharmony_ci * If feature negotiation was successful, activate features now; 4648c2ecf20Sopenharmony_ci * an activation failure means that this host could not activate 4658c2ecf20Sopenharmony_ci * one ore more features (e.g. insufficient memory), which would 4668c2ecf20Sopenharmony_ci * leave at least one feature in an undefined state. 4678c2ecf20Sopenharmony_ci */ 4688c2ecf20Sopenharmony_ci if (dccp_feat_activate_values(sk, &dp->dccps_featneg)) 4698c2ecf20Sopenharmony_ci goto unable_to_proceed; 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci /* Make sure socket is routed, for correct metrics. */ 4728c2ecf20Sopenharmony_ci icsk->icsk_af_ops->rebuild_header(sk); 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci if (!sock_flag(sk, SOCK_DEAD)) { 4758c2ecf20Sopenharmony_ci sk->sk_state_change(sk); 4768c2ecf20Sopenharmony_ci sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); 4778c2ecf20Sopenharmony_ci } 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_ci if (sk->sk_write_pending || inet_csk_in_pingpong_mode(sk) || 4808c2ecf20Sopenharmony_ci icsk->icsk_accept_queue.rskq_defer_accept) { 4818c2ecf20Sopenharmony_ci /* Save one ACK. Data will be ready after 4828c2ecf20Sopenharmony_ci * several ticks, if write_pending is set. 4838c2ecf20Sopenharmony_ci * 4848c2ecf20Sopenharmony_ci * It may be deleted, but with this feature tcpdumps 4858c2ecf20Sopenharmony_ci * look so _wonderfully_ clever, that I was not able 4868c2ecf20Sopenharmony_ci * to stand against the temptation 8) --ANK 4878c2ecf20Sopenharmony_ci */ 4888c2ecf20Sopenharmony_ci /* 4898c2ecf20Sopenharmony_ci * OK, in DCCP we can as well do a similar trick, its 4908c2ecf20Sopenharmony_ci * even in the draft, but there is no need for us to 4918c2ecf20Sopenharmony_ci * schedule an ack here, as dccp_sendmsg does this for 4928c2ecf20Sopenharmony_ci * us, also stated in the draft. -acme 4938c2ecf20Sopenharmony_ci */ 4948c2ecf20Sopenharmony_ci __kfree_skb(skb); 4958c2ecf20Sopenharmony_ci return 0; 4968c2ecf20Sopenharmony_ci } 4978c2ecf20Sopenharmony_ci dccp_send_ack(sk); 4988c2ecf20Sopenharmony_ci return -1; 4998c2ecf20Sopenharmony_ci } 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ciout_invalid_packet: 5028c2ecf20Sopenharmony_ci /* dccp_v4_do_rcv will send a reset */ 5038c2ecf20Sopenharmony_ci DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; 5048c2ecf20Sopenharmony_ci return 1; 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ciunable_to_proceed: 5078c2ecf20Sopenharmony_ci DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_ABORTED; 5088c2ecf20Sopenharmony_ci /* 5098c2ecf20Sopenharmony_ci * We mark this socket as no longer usable, so that the loop in 5108c2ecf20Sopenharmony_ci * dccp_sendmsg() terminates and the application gets notified. 5118c2ecf20Sopenharmony_ci */ 5128c2ecf20Sopenharmony_ci dccp_set_state(sk, DCCP_CLOSED); 5138c2ecf20Sopenharmony_ci sk->sk_err = ECOMM; 5148c2ecf20Sopenharmony_ci return 1; 5158c2ecf20Sopenharmony_ci} 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_cistatic int dccp_rcv_respond_partopen_state_process(struct sock *sk, 5188c2ecf20Sopenharmony_ci struct sk_buff *skb, 5198c2ecf20Sopenharmony_ci const struct dccp_hdr *dh, 5208c2ecf20Sopenharmony_ci const unsigned int len) 5218c2ecf20Sopenharmony_ci{ 5228c2ecf20Sopenharmony_ci struct dccp_sock *dp = dccp_sk(sk); 5238c2ecf20Sopenharmony_ci u32 sample = dp->dccps_options_received.dccpor_timestamp_echo; 5248c2ecf20Sopenharmony_ci int queued = 0; 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci switch (dh->dccph_type) { 5278c2ecf20Sopenharmony_ci case DCCP_PKT_RESET: 5288c2ecf20Sopenharmony_ci inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 5298c2ecf20Sopenharmony_ci break; 5308c2ecf20Sopenharmony_ci case DCCP_PKT_DATA: 5318c2ecf20Sopenharmony_ci if (sk->sk_state == DCCP_RESPOND) 5328c2ecf20Sopenharmony_ci break; 5338c2ecf20Sopenharmony_ci fallthrough; 5348c2ecf20Sopenharmony_ci case DCCP_PKT_DATAACK: 5358c2ecf20Sopenharmony_ci case DCCP_PKT_ACK: 5368c2ecf20Sopenharmony_ci /* 5378c2ecf20Sopenharmony_ci * FIXME: we should be resetting the PARTOPEN (DELACK) timer 5388c2ecf20Sopenharmony_ci * here but only if we haven't used the DELACK timer for 5398c2ecf20Sopenharmony_ci * something else, like sending a delayed ack for a TIMESTAMP 5408c2ecf20Sopenharmony_ci * echo, etc, for now were not clearing it, sending an extra 5418c2ecf20Sopenharmony_ci * ACK when there is nothing else to do in DELACK is not a big 5428c2ecf20Sopenharmony_ci * deal after all. 5438c2ecf20Sopenharmony_ci */ 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci /* Stop the PARTOPEN timer */ 5468c2ecf20Sopenharmony_ci if (sk->sk_state == DCCP_PARTOPEN) 5478c2ecf20Sopenharmony_ci inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci /* Obtain usec RTT sample from SYN exchange (used by TFRC). */ 5508c2ecf20Sopenharmony_ci if (likely(sample)) { 5518c2ecf20Sopenharmony_ci long delta = dccp_timestamp() - sample; 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * delta); 5548c2ecf20Sopenharmony_ci } 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci dp->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq; 5578c2ecf20Sopenharmony_ci dccp_set_state(sk, DCCP_OPEN); 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_DATAACK || 5608c2ecf20Sopenharmony_ci dh->dccph_type == DCCP_PKT_DATA) { 5618c2ecf20Sopenharmony_ci __dccp_rcv_established(sk, skb, dh, len); 5628c2ecf20Sopenharmony_ci queued = 1; /* packet was queued 5638c2ecf20Sopenharmony_ci (by __dccp_rcv_established) */ 5648c2ecf20Sopenharmony_ci } 5658c2ecf20Sopenharmony_ci break; 5668c2ecf20Sopenharmony_ci } 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci return queued; 5698c2ecf20Sopenharmony_ci} 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ciint dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, 5728c2ecf20Sopenharmony_ci struct dccp_hdr *dh, unsigned int len) 5738c2ecf20Sopenharmony_ci{ 5748c2ecf20Sopenharmony_ci struct dccp_sock *dp = dccp_sk(sk); 5758c2ecf20Sopenharmony_ci struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 5768c2ecf20Sopenharmony_ci const int old_state = sk->sk_state; 5778c2ecf20Sopenharmony_ci bool acceptable; 5788c2ecf20Sopenharmony_ci int queued = 0; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci /* 5818c2ecf20Sopenharmony_ci * Step 3: Process LISTEN state 5828c2ecf20Sopenharmony_ci * 5838c2ecf20Sopenharmony_ci * If S.state == LISTEN, 5848c2ecf20Sopenharmony_ci * If P.type == Request or P contains a valid Init Cookie option, 5858c2ecf20Sopenharmony_ci * (* Must scan the packet's options to check for Init 5868c2ecf20Sopenharmony_ci * Cookies. Only Init Cookies are processed here, 5878c2ecf20Sopenharmony_ci * however; other options are processed in Step 8. This 5888c2ecf20Sopenharmony_ci * scan need only be performed if the endpoint uses Init 5898c2ecf20Sopenharmony_ci * Cookies *) 5908c2ecf20Sopenharmony_ci * (* Generate a new socket and switch to that socket *) 5918c2ecf20Sopenharmony_ci * Set S := new socket for this port pair 5928c2ecf20Sopenharmony_ci * S.state = RESPOND 5938c2ecf20Sopenharmony_ci * Choose S.ISS (initial seqno) or set from Init Cookies 5948c2ecf20Sopenharmony_ci * Initialize S.GAR := S.ISS 5958c2ecf20Sopenharmony_ci * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init 5968c2ecf20Sopenharmony_ci * Cookies Continue with S.state == RESPOND 5978c2ecf20Sopenharmony_ci * (* A Response packet will be generated in Step 11 *) 5988c2ecf20Sopenharmony_ci * Otherwise, 5998c2ecf20Sopenharmony_ci * Generate Reset(No Connection) unless P.type == Reset 6008c2ecf20Sopenharmony_ci * Drop packet and return 6018c2ecf20Sopenharmony_ci */ 6028c2ecf20Sopenharmony_ci if (sk->sk_state == DCCP_LISTEN) { 6038c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_REQUEST) { 6048c2ecf20Sopenharmony_ci /* It is possible that we process SYN packets from backlog, 6058c2ecf20Sopenharmony_ci * so we need to make sure to disable BH and RCU right there. 6068c2ecf20Sopenharmony_ci */ 6078c2ecf20Sopenharmony_ci rcu_read_lock(); 6088c2ecf20Sopenharmony_ci local_bh_disable(); 6098c2ecf20Sopenharmony_ci acceptable = inet_csk(sk)->icsk_af_ops->conn_request(sk, skb) >= 0; 6108c2ecf20Sopenharmony_ci local_bh_enable(); 6118c2ecf20Sopenharmony_ci rcu_read_unlock(); 6128c2ecf20Sopenharmony_ci if (!acceptable) 6138c2ecf20Sopenharmony_ci return 1; 6148c2ecf20Sopenharmony_ci consume_skb(skb); 6158c2ecf20Sopenharmony_ci return 0; 6168c2ecf20Sopenharmony_ci } 6178c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_RESET) 6188c2ecf20Sopenharmony_ci goto discard; 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci /* Caller (dccp_v4_do_rcv) will send Reset */ 6218c2ecf20Sopenharmony_ci dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 6228c2ecf20Sopenharmony_ci return 1; 6238c2ecf20Sopenharmony_ci } else if (sk->sk_state == DCCP_CLOSED) { 6248c2ecf20Sopenharmony_ci dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 6258c2ecf20Sopenharmony_ci return 1; 6268c2ecf20Sopenharmony_ci } 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci /* Step 6: Check sequence numbers (omitted in LISTEN/REQUEST state) */ 6298c2ecf20Sopenharmony_ci if (sk->sk_state != DCCP_REQUESTING && dccp_check_seqno(sk, skb)) 6308c2ecf20Sopenharmony_ci goto discard; 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci /* 6338c2ecf20Sopenharmony_ci * Step 7: Check for unexpected packet types 6348c2ecf20Sopenharmony_ci * If (S.is_server and P.type == Response) 6358c2ecf20Sopenharmony_ci * or (S.is_client and P.type == Request) 6368c2ecf20Sopenharmony_ci * or (S.state == RESPOND and P.type == Data), 6378c2ecf20Sopenharmony_ci * Send Sync packet acknowledging P.seqno 6388c2ecf20Sopenharmony_ci * Drop packet and return 6398c2ecf20Sopenharmony_ci */ 6408c2ecf20Sopenharmony_ci if ((dp->dccps_role != DCCP_ROLE_CLIENT && 6418c2ecf20Sopenharmony_ci dh->dccph_type == DCCP_PKT_RESPONSE) || 6428c2ecf20Sopenharmony_ci (dp->dccps_role == DCCP_ROLE_CLIENT && 6438c2ecf20Sopenharmony_ci dh->dccph_type == DCCP_PKT_REQUEST) || 6448c2ecf20Sopenharmony_ci (sk->sk_state == DCCP_RESPOND && dh->dccph_type == DCCP_PKT_DATA)) { 6458c2ecf20Sopenharmony_ci dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC); 6468c2ecf20Sopenharmony_ci goto discard; 6478c2ecf20Sopenharmony_ci } 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci /* Step 8: Process options */ 6508c2ecf20Sopenharmony_ci if (dccp_parse_options(sk, NULL, skb)) 6518c2ecf20Sopenharmony_ci return 1; 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci /* 6548c2ecf20Sopenharmony_ci * Step 9: Process Reset 6558c2ecf20Sopenharmony_ci * If P.type == Reset, 6568c2ecf20Sopenharmony_ci * Tear down connection 6578c2ecf20Sopenharmony_ci * S.state := TIMEWAIT 6588c2ecf20Sopenharmony_ci * Set TIMEWAIT timer 6598c2ecf20Sopenharmony_ci * Drop packet and return 6608c2ecf20Sopenharmony_ci */ 6618c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_RESET) { 6628c2ecf20Sopenharmony_ci dccp_rcv_reset(sk, skb); 6638c2ecf20Sopenharmony_ci return 0; 6648c2ecf20Sopenharmony_ci } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { /* Step 13 */ 6658c2ecf20Sopenharmony_ci if (dccp_rcv_closereq(sk, skb)) 6668c2ecf20Sopenharmony_ci return 0; 6678c2ecf20Sopenharmony_ci goto discard; 6688c2ecf20Sopenharmony_ci } else if (dh->dccph_type == DCCP_PKT_CLOSE) { /* Step 14 */ 6698c2ecf20Sopenharmony_ci if (dccp_rcv_close(sk, skb)) 6708c2ecf20Sopenharmony_ci return 0; 6718c2ecf20Sopenharmony_ci goto discard; 6728c2ecf20Sopenharmony_ci } 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci switch (sk->sk_state) { 6758c2ecf20Sopenharmony_ci case DCCP_REQUESTING: 6768c2ecf20Sopenharmony_ci queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); 6778c2ecf20Sopenharmony_ci if (queued >= 0) 6788c2ecf20Sopenharmony_ci return queued; 6798c2ecf20Sopenharmony_ci 6808c2ecf20Sopenharmony_ci __kfree_skb(skb); 6818c2ecf20Sopenharmony_ci return 0; 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci case DCCP_PARTOPEN: 6848c2ecf20Sopenharmony_ci /* Step 8: if using Ack Vectors, mark packet acknowledgeable */ 6858c2ecf20Sopenharmony_ci dccp_handle_ackvec_processing(sk, skb); 6868c2ecf20Sopenharmony_ci dccp_deliver_input_to_ccids(sk, skb); 6878c2ecf20Sopenharmony_ci fallthrough; 6888c2ecf20Sopenharmony_ci case DCCP_RESPOND: 6898c2ecf20Sopenharmony_ci queued = dccp_rcv_respond_partopen_state_process(sk, skb, 6908c2ecf20Sopenharmony_ci dh, len); 6918c2ecf20Sopenharmony_ci break; 6928c2ecf20Sopenharmony_ci } 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci if (dh->dccph_type == DCCP_PKT_ACK || 6958c2ecf20Sopenharmony_ci dh->dccph_type == DCCP_PKT_DATAACK) { 6968c2ecf20Sopenharmony_ci switch (old_state) { 6978c2ecf20Sopenharmony_ci case DCCP_PARTOPEN: 6988c2ecf20Sopenharmony_ci sk->sk_state_change(sk); 6998c2ecf20Sopenharmony_ci sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); 7008c2ecf20Sopenharmony_ci break; 7018c2ecf20Sopenharmony_ci } 7028c2ecf20Sopenharmony_ci } else if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) { 7038c2ecf20Sopenharmony_ci dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNCACK); 7048c2ecf20Sopenharmony_ci goto discard; 7058c2ecf20Sopenharmony_ci } 7068c2ecf20Sopenharmony_ci 7078c2ecf20Sopenharmony_ci if (!queued) { 7088c2ecf20Sopenharmony_cidiscard: 7098c2ecf20Sopenharmony_ci __kfree_skb(skb); 7108c2ecf20Sopenharmony_ci } 7118c2ecf20Sopenharmony_ci return 0; 7128c2ecf20Sopenharmony_ci} 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(dccp_rcv_state_process); 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci/** 7178c2ecf20Sopenharmony_ci * dccp_sample_rtt - Validate and finalise computation of RTT sample 7188c2ecf20Sopenharmony_ci * @sk: socket structure 7198c2ecf20Sopenharmony_ci * @delta: number of microseconds between packet and acknowledgment 7208c2ecf20Sopenharmony_ci * 7218c2ecf20Sopenharmony_ci * The routine is kept generic to work in different contexts. It should be 7228c2ecf20Sopenharmony_ci * called immediately when the ACK used for the RTT sample arrives. 7238c2ecf20Sopenharmony_ci */ 7248c2ecf20Sopenharmony_ciu32 dccp_sample_rtt(struct sock *sk, long delta) 7258c2ecf20Sopenharmony_ci{ 7268c2ecf20Sopenharmony_ci /* dccpor_elapsed_time is either zeroed out or set and > 0 */ 7278c2ecf20Sopenharmony_ci delta -= dccp_sk(sk)->dccps_options_received.dccpor_elapsed_time * 10; 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci if (unlikely(delta <= 0)) { 7308c2ecf20Sopenharmony_ci DCCP_WARN("unusable RTT sample %ld, using min\n", delta); 7318c2ecf20Sopenharmony_ci return DCCP_SANE_RTT_MIN; 7328c2ecf20Sopenharmony_ci } 7338c2ecf20Sopenharmony_ci if (unlikely(delta > DCCP_SANE_RTT_MAX)) { 7348c2ecf20Sopenharmony_ci DCCP_WARN("RTT sample %ld too large, using max\n", delta); 7358c2ecf20Sopenharmony_ci return DCCP_SANE_RTT_MAX; 7368c2ecf20Sopenharmony_ci } 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ci return delta; 7398c2ecf20Sopenharmony_ci} 740