17c657876SArnaldo Carvalho de Melo /* 27c657876SArnaldo Carvalho de Melo * net/dccp/output.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> 1448918a4dSHerbert Xu #include <linux/kernel.h> 157c657876SArnaldo Carvalho de Melo #include <linux/skbuff.h> 167c657876SArnaldo Carvalho de Melo 1714c85021SArnaldo Carvalho de Melo #include <net/inet_sock.h> 187c657876SArnaldo Carvalho de Melo #include <net/sock.h> 197c657876SArnaldo Carvalho de Melo 20ae31c339SArnaldo Carvalho de Melo #include "ackvec.h" 217c657876SArnaldo Carvalho de Melo #include "ccid.h" 227c657876SArnaldo Carvalho de Melo #include "dccp.h" 237c657876SArnaldo Carvalho de Melo 247c657876SArnaldo Carvalho de Melo static inline void dccp_event_ack_sent(struct sock *sk) 257c657876SArnaldo Carvalho de Melo { 267c657876SArnaldo Carvalho de Melo inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 277c657876SArnaldo Carvalho de Melo } 287c657876SArnaldo Carvalho de Melo 29c25a18baSArnaldo Carvalho de Melo static void dccp_skb_entail(struct sock *sk, struct sk_buff *skb) 3048918a4dSHerbert Xu { 3148918a4dSHerbert Xu skb_set_owner_w(skb, sk); 3248918a4dSHerbert Xu WARN_ON(sk->sk_send_head); 3348918a4dSHerbert Xu sk->sk_send_head = skb; 3448918a4dSHerbert Xu } 3548918a4dSHerbert Xu 367c657876SArnaldo Carvalho de Melo /* 377c657876SArnaldo Carvalho de Melo * All SKB's seen here are completely headerless. It is our 387c657876SArnaldo Carvalho de Melo * job to build the DCCP header, and pass the packet down to 397c657876SArnaldo Carvalho de Melo * IP so it can do the same plus pass the packet off to the 407c657876SArnaldo Carvalho de Melo * device. 417c657876SArnaldo Carvalho de Melo */ 4248918a4dSHerbert Xu static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) 437c657876SArnaldo Carvalho de Melo { 447c657876SArnaldo Carvalho de Melo if (likely(skb != NULL)) { 457c657876SArnaldo Carvalho de Melo const struct inet_sock *inet = inet_sk(sk); 4657cca05aSArnaldo Carvalho de Melo const struct inet_connection_sock *icsk = inet_csk(sk); 477c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 487c657876SArnaldo Carvalho de Melo struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 497c657876SArnaldo Carvalho de Melo struct dccp_hdr *dh; 507c657876SArnaldo Carvalho de Melo /* XXX For now we're using only 48 bits sequence numbers */ 51118b2c95SArnaldo Carvalho de Melo const u32 dccp_header_size = sizeof(*dh) + 527c657876SArnaldo Carvalho de Melo sizeof(struct dccp_hdr_ext) + 537c657876SArnaldo Carvalho de Melo dccp_packet_hdr_len(dcb->dccpd_type); 547c657876SArnaldo Carvalho de Melo int err, set_ack = 1; 557c657876SArnaldo Carvalho de Melo u64 ackno = dp->dccps_gsr; 5673f18fdbSGerrit Renker /* 5773f18fdbSGerrit Renker * Increment GSS here already in case the option code needs it. 5873f18fdbSGerrit Renker * Update GSS for real only if option processing below succeeds. 5973f18fdbSGerrit Renker */ 6073f18fdbSGerrit Renker dcb->dccpd_seq = ADD48(dp->dccps_gss, 1); 617c657876SArnaldo Carvalho de Melo 627c657876SArnaldo Carvalho de Melo switch (dcb->dccpd_type) { 637c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATA: 647c657876SArnaldo Carvalho de Melo set_ack = 0; 65edc9e819SHerbert Xu /* fall through */ 66edc9e819SHerbert Xu case DCCP_PKT_DATAACK: 67ee1a1592SGerrit Renker case DCCP_PKT_RESET: 687c657876SArnaldo Carvalho de Melo break; 69edc9e819SHerbert Xu 70afe00251SAndrea Bittau case DCCP_PKT_REQUEST: 71afe00251SAndrea Bittau set_ack = 0; 7273f18fdbSGerrit Renker /* Use ISS on the first (non-retransmitted) Request. */ 7373f18fdbSGerrit Renker if (icsk->icsk_retransmits == 0) 7473f18fdbSGerrit Renker dcb->dccpd_seq = dp->dccps_iss; 75afe00251SAndrea Bittau /* fall through */ 76afe00251SAndrea Bittau 777c657876SArnaldo Carvalho de Melo case DCCP_PKT_SYNC: 787c657876SArnaldo Carvalho de Melo case DCCP_PKT_SYNCACK: 79b0d045caSGerrit Renker ackno = dcb->dccpd_ack_seq; 80edc9e819SHerbert Xu /* fall through */ 81edc9e819SHerbert Xu default: 82edc9e819SHerbert Xu /* 83ee1a1592SGerrit Renker * Set owner/destructor: some skbs are allocated via 84ee1a1592SGerrit Renker * alloc_skb (e.g. when retransmission may happen). 85ee1a1592SGerrit Renker * Only Data, DataAck, and Reset packets should come 86ee1a1592SGerrit Renker * through here with skb->sk set. 87edc9e819SHerbert Xu */ 88edc9e819SHerbert Xu WARN_ON(skb->sk); 89edc9e819SHerbert Xu skb_set_owner_w(skb, sk); 907c657876SArnaldo Carvalho de Melo break; 917c657876SArnaldo Carvalho de Melo } 927c657876SArnaldo Carvalho de Melo 932d0817d1SArnaldo Carvalho de Melo if (dccp_insert_options(sk, skb)) { 942d0817d1SArnaldo Carvalho de Melo kfree_skb(skb); 952d0817d1SArnaldo Carvalho de Melo return -EPROTO; 962d0817d1SArnaldo Carvalho de Melo } 9724117727SArnaldo Carvalho de Melo 98fda0fd6cSHerbert Xu 997c657876SArnaldo Carvalho de Melo /* Build DCCP header and checksum it. */ 1009b42078eSGerrit Renker dh = dccp_zeroed_hdr(skb, dccp_header_size); 1017c657876SArnaldo Carvalho de Melo dh->dccph_type = dcb->dccpd_type; 1027c657876SArnaldo Carvalho de Melo dh->dccph_sport = inet->sport; 1037c657876SArnaldo Carvalho de Melo dh->dccph_dport = inet->dport; 1047c657876SArnaldo Carvalho de Melo dh->dccph_doff = (dccp_header_size + dcb->dccpd_opt_len) / 4; 1057c657876SArnaldo Carvalho de Melo dh->dccph_ccval = dcb->dccpd_ccval; 1066f4e5fffSGerrit Renker dh->dccph_cscov = dp->dccps_pcslen; 1077c657876SArnaldo Carvalho de Melo /* XXX For now we're using only 48 bits sequence numbers */ 1087c657876SArnaldo Carvalho de Melo dh->dccph_x = 1; 1097c657876SArnaldo Carvalho de Melo 11073f18fdbSGerrit Renker dccp_update_gss(sk, dcb->dccpd_seq); 1117c657876SArnaldo Carvalho de Melo dccp_hdr_set_seq(dh, dp->dccps_gss); 1127c657876SArnaldo Carvalho de Melo if (set_ack) 1137c657876SArnaldo Carvalho de Melo dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), ackno); 1147c657876SArnaldo Carvalho de Melo 1157c657876SArnaldo Carvalho de Melo switch (dcb->dccpd_type) { 1167c657876SArnaldo Carvalho de Melo case DCCP_PKT_REQUEST: 1177690af3fSArnaldo Carvalho de Melo dccp_hdr_request(skb)->dccph_req_service = 11867e6b629SArnaldo Carvalho de Melo dp->dccps_service; 11973f18fdbSGerrit Renker /* 12073f18fdbSGerrit Renker * Limit Ack window to ISS <= P.ackno <= GSS, so that 12173f18fdbSGerrit Renker * only Responses to Requests we sent are considered. 12273f18fdbSGerrit Renker */ 12373f18fdbSGerrit Renker dp->dccps_awl = dp->dccps_iss; 1247c657876SArnaldo Carvalho de Melo break; 1257c657876SArnaldo Carvalho de Melo case DCCP_PKT_RESET: 1267690af3fSArnaldo Carvalho de Melo dccp_hdr_reset(skb)->dccph_reset_code = 1277690af3fSArnaldo Carvalho de Melo dcb->dccpd_reset_code; 1287c657876SArnaldo Carvalho de Melo break; 1297c657876SArnaldo Carvalho de Melo } 1307c657876SArnaldo Carvalho de Melo 1316f4e5fffSGerrit Renker icsk->icsk_af_ops->send_check(sk, 0, skb); 1327c657876SArnaldo Carvalho de Melo 1337ad07e7cSArnaldo Carvalho de Melo if (set_ack) 1347c657876SArnaldo Carvalho de Melo dccp_event_ack_sent(sk); 1357c657876SArnaldo Carvalho de Melo 1367c657876SArnaldo Carvalho de Melo DCCP_INC_STATS(DCCP_MIB_OUTSEGS); 1377c657876SArnaldo Carvalho de Melo 138e89862f4SDavid S. Miller err = icsk->icsk_af_ops->queue_xmit(skb, 0); 139b9df3cb8SGerrit Renker return net_xmit_eval(err); 1407c657876SArnaldo Carvalho de Melo } 1417c657876SArnaldo Carvalho de Melo return -ENOBUFS; 1427c657876SArnaldo Carvalho de Melo } 1437c657876SArnaldo Carvalho de Melo 1446179983aSGerrit Renker /** 1456179983aSGerrit Renker * dccp_determine_ccmps - Find out about CCID-specfic packet-size limits 1466179983aSGerrit Renker * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.), 1476179983aSGerrit Renker * since the RX CCID is restricted to feedback packets (Acks), which are small 1486179983aSGerrit Renker * in comparison with the data traffic. A value of 0 means "no current CCMPS". 1496179983aSGerrit Renker */ 1506179983aSGerrit Renker static u32 dccp_determine_ccmps(const struct dccp_sock *dp) 1516179983aSGerrit Renker { 1526179983aSGerrit Renker const struct ccid *tx_ccid = dp->dccps_hc_tx_ccid; 1536179983aSGerrit Renker 1546179983aSGerrit Renker if (tx_ccid == NULL || tx_ccid->ccid_ops == NULL) 1556179983aSGerrit Renker return 0; 1566179983aSGerrit Renker return tx_ccid->ccid_ops->ccid_ccmps; 1576179983aSGerrit Renker } 1586179983aSGerrit Renker 1597c657876SArnaldo Carvalho de Melo unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) 1607c657876SArnaldo Carvalho de Melo { 161d83d8461SArnaldo Carvalho de Melo struct inet_connection_sock *icsk = inet_csk(sk); 1627c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 1636179983aSGerrit Renker u32 ccmps = dccp_determine_ccmps(dp); 164361a5c1dSGerrit Renker u32 cur_mps = ccmps ? min(pmtu, ccmps) : pmtu; 1657c657876SArnaldo Carvalho de Melo 1666179983aSGerrit Renker /* Account for header lengths and IPv4/v6 option overhead */ 1676179983aSGerrit Renker cur_mps -= (icsk->icsk_af_ops->net_header_len + icsk->icsk_ext_hdr_len + 1686179983aSGerrit Renker sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)); 1697c657876SArnaldo Carvalho de Melo 1707c657876SArnaldo Carvalho de Melo /* 171361a5c1dSGerrit Renker * Leave enough headroom for common DCCP header options. 172361a5c1dSGerrit Renker * This only considers options which may appear on DCCP-Data packets, as 173361a5c1dSGerrit Renker * per table 3 in RFC 4340, 5.8. When running out of space for other 174361a5c1dSGerrit Renker * options (eg. Ack Vector which can take up to 255 bytes), it is better 175361a5c1dSGerrit Renker * to schedule a separate Ack. Thus we leave headroom for the following: 176361a5c1dSGerrit Renker * - 1 byte for Slow Receiver (11.6) 177361a5c1dSGerrit Renker * - 6 bytes for Timestamp (13.1) 178361a5c1dSGerrit Renker * - 10 bytes for Timestamp Echo (13.3) 179361a5c1dSGerrit Renker * - 8 bytes for NDP count (7.7, when activated) 180361a5c1dSGerrit Renker * - 6 bytes for Data Checksum (9.3) 181361a5c1dSGerrit Renker * - %DCCPAV_MIN_OPTLEN bytes for Ack Vector size (11.4, when enabled) 1827c657876SArnaldo Carvalho de Melo */ 183361a5c1dSGerrit Renker cur_mps -= roundup(1 + 6 + 10 + dp->dccps_send_ndp_count * 8 + 6 + 184361a5c1dSGerrit Renker (dp->dccps_hc_rx_ackvec ? DCCPAV_MIN_OPTLEN : 0), 4); 1857c657876SArnaldo Carvalho de Melo 1867c657876SArnaldo Carvalho de Melo /* And store cached results */ 187d83d8461SArnaldo Carvalho de Melo icsk->icsk_pmtu_cookie = pmtu; 1886179983aSGerrit Renker dp->dccps_mss_cache = cur_mps; 1897c657876SArnaldo Carvalho de Melo 1906179983aSGerrit Renker return cur_mps; 1917c657876SArnaldo Carvalho de Melo } 1927c657876SArnaldo Carvalho de Melo 193f21e68caSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_sync_mss); 194f21e68caSArnaldo Carvalho de Melo 195c530cfb1SArnaldo Carvalho de Melo void dccp_write_space(struct sock *sk) 196c530cfb1SArnaldo Carvalho de Melo { 197c530cfb1SArnaldo Carvalho de Melo read_lock(&sk->sk_callback_lock); 198c530cfb1SArnaldo Carvalho de Melo 199c530cfb1SArnaldo Carvalho de Melo if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) 200c530cfb1SArnaldo Carvalho de Melo wake_up_interruptible(sk->sk_sleep); 201c530cfb1SArnaldo Carvalho de Melo /* Should agree with poll, otherwise some programs break */ 202c530cfb1SArnaldo Carvalho de Melo if (sock_writeable(sk)) 2038d8ad9d7SPavel Emelyanov sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); 204c530cfb1SArnaldo Carvalho de Melo 205c530cfb1SArnaldo Carvalho de Melo read_unlock(&sk->sk_callback_lock); 206c530cfb1SArnaldo Carvalho de Melo } 207c530cfb1SArnaldo Carvalho de Melo 208d6809c12SArnaldo Carvalho de Melo /** 209d6809c12SArnaldo Carvalho de Melo * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet 210d6809c12SArnaldo Carvalho de Melo * @sk: socket to wait for 211bc849872SGerrit Renker * @skb: current skb to pass on for waiting 212bc849872SGerrit Renker * @delay: sleep timeout in milliseconds (> 0) 213bc849872SGerrit Renker * This function is called by default when the socket is closed, and 214bc849872SGerrit Renker * when a non-zero linger time is set on the socket. For consistency 215d6809c12SArnaldo Carvalho de Melo */ 216bc849872SGerrit Renker static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay) 217d6809c12SArnaldo Carvalho de Melo { 218d6809c12SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 219d6809c12SArnaldo Carvalho de Melo DEFINE_WAIT(wait); 220bc849872SGerrit Renker unsigned long jiffdelay; 221d6809c12SArnaldo Carvalho de Melo int rc; 222d6809c12SArnaldo Carvalho de Melo 223bc849872SGerrit Renker do { 224bc849872SGerrit Renker dccp_pr_debug("delayed send by %d msec\n", delay); 225bc849872SGerrit Renker jiffdelay = msecs_to_jiffies(delay); 226bc849872SGerrit Renker 227d6809c12SArnaldo Carvalho de Melo prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 228d6809c12SArnaldo Carvalho de Melo 229bc849872SGerrit Renker sk->sk_write_pending++; 230bc849872SGerrit Renker release_sock(sk); 231bc849872SGerrit Renker schedule_timeout(jiffdelay); 232bc849872SGerrit Renker lock_sock(sk); 233bc849872SGerrit Renker sk->sk_write_pending--; 234bc849872SGerrit Renker 23597e5848dSIan McDonald if (sk->sk_err) 236d6809c12SArnaldo Carvalho de Melo goto do_error; 237d6809c12SArnaldo Carvalho de Melo if (signal_pending(current)) 238d6809c12SArnaldo Carvalho de Melo goto do_interrupted; 239d6809c12SArnaldo Carvalho de Melo 2406b57c93dSGerrit Renker rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); 241bc849872SGerrit Renker } while ((delay = rc) > 0); 242d6809c12SArnaldo Carvalho de Melo out: 243d6809c12SArnaldo Carvalho de Melo finish_wait(sk->sk_sleep, &wait); 244d6809c12SArnaldo Carvalho de Melo return rc; 245d6809c12SArnaldo Carvalho de Melo 246d6809c12SArnaldo Carvalho de Melo do_error: 247d6809c12SArnaldo Carvalho de Melo rc = -EPIPE; 248d6809c12SArnaldo Carvalho de Melo goto out; 249d6809c12SArnaldo Carvalho de Melo do_interrupted: 2505cc3741dSIan McDonald rc = -EINTR; 251d6809c12SArnaldo Carvalho de Melo goto out; 252d6809c12SArnaldo Carvalho de Melo } 253d6809c12SArnaldo Carvalho de Melo 25497e5848dSIan McDonald void dccp_write_xmit(struct sock *sk, int block) 25527258ee5SArnaldo Carvalho de Melo { 25697e5848dSIan McDonald struct dccp_sock *dp = dccp_sk(sk); 25797e5848dSIan McDonald struct sk_buff *skb; 25897e5848dSIan McDonald 25997e5848dSIan McDonald while ((skb = skb_peek(&sk->sk_write_queue))) { 2606b57c93dSGerrit Renker int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); 261d6809c12SArnaldo Carvalho de Melo 26297e5848dSIan McDonald if (err > 0) { 26397e5848dSIan McDonald if (!block) { 26497e5848dSIan McDonald sk_reset_timer(sk, &dp->dccps_xmit_timer, 26597e5848dSIan McDonald msecs_to_jiffies(err)+jiffies); 26697e5848dSIan McDonald break; 2675cc3741dSIan McDonald } else 268bc849872SGerrit Renker err = dccp_wait_for_ccid(sk, skb, err); 269f6282f4dSGerrit Renker if (err && err != -EINTR) 27059348b19SGerrit Renker DCCP_BUG("err=%d after dccp_wait_for_ccid", err); 27197e5848dSIan McDonald } 27227258ee5SArnaldo Carvalho de Melo 27397e5848dSIan McDonald skb_dequeue(&sk->sk_write_queue); 27427258ee5SArnaldo Carvalho de Melo if (err == 0) { 27527258ee5SArnaldo Carvalho de Melo struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 276d6809c12SArnaldo Carvalho de Melo const int len = skb->len; 27727258ee5SArnaldo Carvalho de Melo 27827258ee5SArnaldo Carvalho de Melo if (sk->sk_state == DCCP_PARTOPEN) { 27927258ee5SArnaldo Carvalho de Melo /* See 8.1.5. Handshake Completion */ 28027258ee5SArnaldo Carvalho de Melo inet_csk_schedule_ack(sk); 28127258ee5SArnaldo Carvalho de Melo inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, 28227258ee5SArnaldo Carvalho de Melo inet_csk(sk)->icsk_rto, 28327258ee5SArnaldo Carvalho de Melo DCCP_RTO_MAX); 28427258ee5SArnaldo Carvalho de Melo dcb->dccpd_type = DCCP_PKT_DATAACK; 285ae31c339SArnaldo Carvalho de Melo } else if (dccp_ack_pending(sk)) 28627258ee5SArnaldo Carvalho de Melo dcb->dccpd_type = DCCP_PKT_DATAACK; 28727258ee5SArnaldo Carvalho de Melo else 28827258ee5SArnaldo Carvalho de Melo dcb->dccpd_type = DCCP_PKT_DATA; 28927258ee5SArnaldo Carvalho de Melo 29027258ee5SArnaldo Carvalho de Melo err = dccp_transmit_skb(sk, skb); 29127258ee5SArnaldo Carvalho de Melo ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len); 29259348b19SGerrit Renker if (err) 29359348b19SGerrit Renker DCCP_BUG("err=%d after ccid_hc_tx_packet_sent", 29459348b19SGerrit Renker err); 295f6282f4dSGerrit Renker } else { 2966626e362SGerrit Renker dccp_pr_debug("packet discarded due to err=%d\n", err); 297b08d5840SPatrick McHardy kfree_skb(skb); 29897e5848dSIan McDonald } 29927258ee5SArnaldo Carvalho de Melo } 300f6282f4dSGerrit Renker } 30127258ee5SArnaldo Carvalho de Melo 30259435444SGerrit Renker /** 30359435444SGerrit Renker * dccp_retransmit_skb - Retransmit Request, Close, or CloseReq packets 30459435444SGerrit Renker * There are only four retransmittable packet types in DCCP: 30559435444SGerrit Renker * - Request in client-REQUEST state (sec. 8.1.1), 30659435444SGerrit Renker * - CloseReq in server-CLOSEREQ state (sec. 8.3), 30759435444SGerrit Renker * - Close in node-CLOSING state (sec. 8.3), 30859435444SGerrit Renker * - Acks in client-PARTOPEN state (sec. 8.1.5, handled by dccp_delack_timer()). 30959435444SGerrit Renker * This function expects sk->sk_send_head to contain the original skb. 31059435444SGerrit Renker */ 31159435444SGerrit Renker int dccp_retransmit_skb(struct sock *sk) 3127c657876SArnaldo Carvalho de Melo { 31359435444SGerrit Renker WARN_ON(sk->sk_send_head == NULL); 31459435444SGerrit Renker 31557cca05aSArnaldo Carvalho de Melo if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0) 3167c657876SArnaldo Carvalho de Melo return -EHOSTUNREACH; /* Routing failure or similar. */ 3177c657876SArnaldo Carvalho de Melo 31859435444SGerrit Renker /* this count is used to distinguish original and retransmitted skb */ 31959435444SGerrit Renker inet_csk(sk)->icsk_retransmits++; 32059435444SGerrit Renker 32159435444SGerrit Renker return dccp_transmit_skb(sk, skb_clone(sk->sk_send_head, GFP_ATOMIC)); 3227c657876SArnaldo Carvalho de Melo } 3237c657876SArnaldo Carvalho de Melo 3247c657876SArnaldo Carvalho de Melo struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, 3257c657876SArnaldo Carvalho de Melo struct request_sock *req) 3267c657876SArnaldo Carvalho de Melo { 3277c657876SArnaldo Carvalho de Melo struct dccp_hdr *dh; 32867e6b629SArnaldo Carvalho de Melo struct dccp_request_sock *dreq; 329118b2c95SArnaldo Carvalho de Melo const u32 dccp_header_size = sizeof(struct dccp_hdr) + 3307c657876SArnaldo Carvalho de Melo sizeof(struct dccp_hdr_ext) + 3317c657876SArnaldo Carvalho de Melo sizeof(struct dccp_hdr_response); 332118b2c95SArnaldo Carvalho de Melo struct sk_buff *skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1, 3337c657876SArnaldo Carvalho de Melo GFP_ATOMIC); 3347c657876SArnaldo Carvalho de Melo if (skb == NULL) 3357c657876SArnaldo Carvalho de Melo return NULL; 3367c657876SArnaldo Carvalho de Melo 3377c657876SArnaldo Carvalho de Melo /* Reserve space for headers. */ 338118b2c95SArnaldo Carvalho de Melo skb_reserve(skb, sk->sk_prot->max_header); 3397c657876SArnaldo Carvalho de Melo 3407c657876SArnaldo Carvalho de Melo skb->dst = dst_clone(dst); 3417c657876SArnaldo Carvalho de Melo 34267e6b629SArnaldo Carvalho de Melo dreq = dccp_rsk(req); 343e11d9d30SGerrit Renker if (inet_rsk(req)->acked) /* increase ISS upon retransmission */ 344e11d9d30SGerrit Renker dccp_inc_seqno(&dreq->dreq_iss); 3457c657876SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; 34667e6b629SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; 3472d0817d1SArnaldo Carvalho de Melo 3480c116839SGerrit Renker /* Resolve feature dependencies resulting from choice of CCID */ 3490c116839SGerrit Renker if (dccp_feat_server_ccid_dependencies(dreq)) 3500c116839SGerrit Renker goto response_failed; 3510c116839SGerrit Renker 3520c116839SGerrit Renker if (dccp_insert_options_rsk(dreq, skb)) 3530c116839SGerrit Renker goto response_failed; 3547c657876SArnaldo Carvalho de Melo 35509dbc389SGerrit Renker /* Build and checksum header */ 3569b42078eSGerrit Renker dh = dccp_zeroed_hdr(skb, dccp_header_size); 3577c657876SArnaldo Carvalho de Melo 358944f7502SGerrit Renker dh->dccph_sport = inet_rsk(req)->loc_port; 3597c657876SArnaldo Carvalho de Melo dh->dccph_dport = inet_rsk(req)->rmt_port; 3607690af3fSArnaldo Carvalho de Melo dh->dccph_doff = (dccp_header_size + 3617690af3fSArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_opt_len) / 4; 3627c657876SArnaldo Carvalho de Melo dh->dccph_type = DCCP_PKT_RESPONSE; 3637c657876SArnaldo Carvalho de Melo dh->dccph_x = 1; 36467e6b629SArnaldo Carvalho de Melo dccp_hdr_set_seq(dh, dreq->dreq_iss); 36567e6b629SArnaldo Carvalho de Melo dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr); 36667e6b629SArnaldo Carvalho de Melo dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service; 3677c657876SArnaldo Carvalho de Melo 3686f4e5fffSGerrit Renker dccp_csum_outgoing(skb); 3696f4e5fffSGerrit Renker 370e11d9d30SGerrit Renker /* We use `acked' to remember that a Response was already sent. */ 371e11d9d30SGerrit Renker inet_rsk(req)->acked = 1; 3727c657876SArnaldo Carvalho de Melo DCCP_INC_STATS(DCCP_MIB_OUTSEGS); 3737c657876SArnaldo Carvalho de Melo return skb; 3740c116839SGerrit Renker response_failed: 3750c116839SGerrit Renker kfree_skb(skb); 3760c116839SGerrit Renker return NULL; 3777c657876SArnaldo Carvalho de Melo } 3787c657876SArnaldo Carvalho de Melo 379f21e68caSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_make_response); 380f21e68caSArnaldo Carvalho de Melo 381e356d37aSGerrit Renker /* answer offending packet in @rcv_skb with Reset from control socket @ctl */ 3827630f026SDenis V. Lunev struct sk_buff *dccp_ctl_make_reset(struct sock *sk, struct sk_buff *rcv_skb) 383e356d37aSGerrit Renker { 384e356d37aSGerrit Renker struct dccp_hdr *rxdh = dccp_hdr(rcv_skb), *dh; 385e356d37aSGerrit Renker struct dccp_skb_cb *dcb = DCCP_SKB_CB(rcv_skb); 386e356d37aSGerrit Renker const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) + 387e356d37aSGerrit Renker sizeof(struct dccp_hdr_ext) + 388e356d37aSGerrit Renker sizeof(struct dccp_hdr_reset); 389e356d37aSGerrit Renker struct dccp_hdr_reset *dhr; 390e356d37aSGerrit Renker struct sk_buff *skb; 391e356d37aSGerrit Renker 3927630f026SDenis V. Lunev skb = alloc_skb(sk->sk_prot->max_header, GFP_ATOMIC); 393e356d37aSGerrit Renker if (skb == NULL) 394e356d37aSGerrit Renker return NULL; 395e356d37aSGerrit Renker 3967630f026SDenis V. Lunev skb_reserve(skb, sk->sk_prot->max_header); 397e356d37aSGerrit Renker 398e356d37aSGerrit Renker /* Swap the send and the receive. */ 399e356d37aSGerrit Renker dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len); 400e356d37aSGerrit Renker dh->dccph_type = DCCP_PKT_RESET; 401e356d37aSGerrit Renker dh->dccph_sport = rxdh->dccph_dport; 402e356d37aSGerrit Renker dh->dccph_dport = rxdh->dccph_sport; 403e356d37aSGerrit Renker dh->dccph_doff = dccp_hdr_reset_len / 4; 404e356d37aSGerrit Renker dh->dccph_x = 1; 405e356d37aSGerrit Renker 406e356d37aSGerrit Renker dhr = dccp_hdr_reset(skb); 407e356d37aSGerrit Renker dhr->dccph_reset_code = dcb->dccpd_reset_code; 408e356d37aSGerrit Renker 409e356d37aSGerrit Renker switch (dcb->dccpd_reset_code) { 410e356d37aSGerrit Renker case DCCP_RESET_CODE_PACKET_ERROR: 411e356d37aSGerrit Renker dhr->dccph_reset_data[0] = rxdh->dccph_type; 412e356d37aSGerrit Renker break; 413e356d37aSGerrit Renker case DCCP_RESET_CODE_OPTION_ERROR: /* fall through */ 414e356d37aSGerrit Renker case DCCP_RESET_CODE_MANDATORY_ERROR: 415e356d37aSGerrit Renker memcpy(dhr->dccph_reset_data, dcb->dccpd_reset_data, 3); 416e356d37aSGerrit Renker break; 417e356d37aSGerrit Renker } 418e356d37aSGerrit Renker /* 419e356d37aSGerrit Renker * From RFC 4340, 8.3.1: 420e356d37aSGerrit Renker * If P.ackno exists, set R.seqno := P.ackno + 1. 421e356d37aSGerrit Renker * Else set R.seqno := 0. 422e356d37aSGerrit Renker */ 423e356d37aSGerrit Renker if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 424e356d37aSGerrit Renker dccp_hdr_set_seq(dh, ADD48(dcb->dccpd_ack_seq, 1)); 425e356d37aSGerrit Renker dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dcb->dccpd_seq); 426e356d37aSGerrit Renker 427e356d37aSGerrit Renker dccp_csum_outgoing(skb); 428e356d37aSGerrit Renker return skb; 429e356d37aSGerrit Renker } 430e356d37aSGerrit Renker 431e356d37aSGerrit Renker EXPORT_SYMBOL_GPL(dccp_ctl_make_reset); 432e356d37aSGerrit Renker 433ee1a1592SGerrit Renker /* send Reset on established socket, to close or abort the connection */ 434017487d7SArnaldo Carvalho de Melo int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code) 435017487d7SArnaldo Carvalho de Melo { 436ee1a1592SGerrit Renker struct sk_buff *skb; 437017487d7SArnaldo Carvalho de Melo /* 438017487d7SArnaldo Carvalho de Melo * FIXME: what if rebuild_header fails? 439017487d7SArnaldo Carvalho de Melo * Should we be doing a rebuild_header here? 440017487d7SArnaldo Carvalho de Melo */ 441f53dc67cSGerrit Renker int err = inet_csk(sk)->icsk_af_ops->rebuild_header(sk); 442017487d7SArnaldo Carvalho de Melo 443ee1a1592SGerrit Renker if (err != 0) 444017487d7SArnaldo Carvalho de Melo return err; 445ee1a1592SGerrit Renker 446ee1a1592SGerrit Renker skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1, GFP_ATOMIC); 447ee1a1592SGerrit Renker if (skb == NULL) 448ee1a1592SGerrit Renker return -ENOBUFS; 449ee1a1592SGerrit Renker 450ee1a1592SGerrit Renker /* Reserve space for headers and prepare control bits. */ 451ee1a1592SGerrit Renker skb_reserve(skb, sk->sk_prot->max_header); 452ee1a1592SGerrit Renker DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESET; 453ee1a1592SGerrit Renker DCCP_SKB_CB(skb)->dccpd_reset_code = code; 454ee1a1592SGerrit Renker 455ee1a1592SGerrit Renker return dccp_transmit_skb(sk, skb); 456017487d7SArnaldo Carvalho de Melo } 457017487d7SArnaldo Carvalho de Melo 4587c657876SArnaldo Carvalho de Melo /* 4597c657876SArnaldo Carvalho de Melo * Do all connect socket setups that can be done AF independent. 4607c657876SArnaldo Carvalho de Melo */ 4617c657876SArnaldo Carvalho de Melo static inline void dccp_connect_init(struct sock *sk) 4627c657876SArnaldo Carvalho de Melo { 463f21e68caSArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 4647c657876SArnaldo Carvalho de Melo struct dst_entry *dst = __sk_dst_get(sk); 4657c657876SArnaldo Carvalho de Melo struct inet_connection_sock *icsk = inet_csk(sk); 4667c657876SArnaldo Carvalho de Melo 4677c657876SArnaldo Carvalho de Melo sk->sk_err = 0; 4687c657876SArnaldo Carvalho de Melo sock_reset_flag(sk, SOCK_DONE); 4697c657876SArnaldo Carvalho de Melo 4707c657876SArnaldo Carvalho de Melo dccp_sync_mss(sk, dst_mtu(dst)); 4717c657876SArnaldo Carvalho de Melo 47273f18fdbSGerrit Renker /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */ 473d7f7365fSGerrit Renker dp->dccps_gar = dp->dccps_iss; 474d7f7365fSGerrit Renker 4757c657876SArnaldo Carvalho de Melo icsk->icsk_retransmits = 0; 4767c657876SArnaldo Carvalho de Melo } 4777c657876SArnaldo Carvalho de Melo 4787c657876SArnaldo Carvalho de Melo int dccp_connect(struct sock *sk) 4797c657876SArnaldo Carvalho de Melo { 4807c657876SArnaldo Carvalho de Melo struct sk_buff *skb; 4817c657876SArnaldo Carvalho de Melo struct inet_connection_sock *icsk = inet_csk(sk); 4827c657876SArnaldo Carvalho de Melo 4839eca0a47SGerrit Renker /* do not connect if feature negotiation setup fails */ 4849eca0a47SGerrit Renker if (dccp_feat_finalise_settings(dccp_sk(sk))) 4859eca0a47SGerrit Renker return -EPROTO; 4869eca0a47SGerrit Renker 4877c657876SArnaldo Carvalho de Melo dccp_connect_init(sk); 4887c657876SArnaldo Carvalho de Melo 489118b2c95SArnaldo Carvalho de Melo skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation); 4907c657876SArnaldo Carvalho de Melo if (unlikely(skb == NULL)) 4917c657876SArnaldo Carvalho de Melo return -ENOBUFS; 4927c657876SArnaldo Carvalho de Melo 4937c657876SArnaldo Carvalho de Melo /* Reserve space for headers. */ 494118b2c95SArnaldo Carvalho de Melo skb_reserve(skb, sk->sk_prot->max_header); 4957c657876SArnaldo Carvalho de Melo 4967c657876SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST; 4977c657876SArnaldo Carvalho de Melo 49848918a4dSHerbert Xu dccp_skb_entail(sk, skb); 4997c657876SArnaldo Carvalho de Melo dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); 5007c657876SArnaldo Carvalho de Melo DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); 5017c657876SArnaldo Carvalho de Melo 5027c657876SArnaldo Carvalho de Melo /* Timer for repeating the REQUEST until an answer. */ 50327258ee5SArnaldo Carvalho de Melo inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 50427258ee5SArnaldo Carvalho de Melo icsk->icsk_rto, DCCP_RTO_MAX); 5057c657876SArnaldo Carvalho de Melo return 0; 5067c657876SArnaldo Carvalho de Melo } 5077c657876SArnaldo Carvalho de Melo 508f21e68caSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_connect); 509f21e68caSArnaldo Carvalho de Melo 5107c657876SArnaldo Carvalho de Melo void dccp_send_ack(struct sock *sk) 5117c657876SArnaldo Carvalho de Melo { 5127c657876SArnaldo Carvalho de Melo /* If we have been reset, we may not send again. */ 5137c657876SArnaldo Carvalho de Melo if (sk->sk_state != DCCP_CLOSED) { 514118b2c95SArnaldo Carvalho de Melo struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header, 515118b2c95SArnaldo Carvalho de Melo GFP_ATOMIC); 5167c657876SArnaldo Carvalho de Melo 5177c657876SArnaldo Carvalho de Melo if (skb == NULL) { 5187c657876SArnaldo Carvalho de Melo inet_csk_schedule_ack(sk); 5197c657876SArnaldo Carvalho de Melo inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN; 5207690af3fSArnaldo Carvalho de Melo inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, 5217690af3fSArnaldo Carvalho de Melo TCP_DELACK_MAX, 5227690af3fSArnaldo Carvalho de Melo DCCP_RTO_MAX); 5237c657876SArnaldo Carvalho de Melo return; 5247c657876SArnaldo Carvalho de Melo } 5257c657876SArnaldo Carvalho de Melo 5267c657876SArnaldo Carvalho de Melo /* Reserve space for headers */ 527118b2c95SArnaldo Carvalho de Melo skb_reserve(skb, sk->sk_prot->max_header); 5287c657876SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK; 5297c657876SArnaldo Carvalho de Melo dccp_transmit_skb(sk, skb); 5307c657876SArnaldo Carvalho de Melo } 5317c657876SArnaldo Carvalho de Melo } 5327c657876SArnaldo Carvalho de Melo 5337c657876SArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_send_ack); 5347c657876SArnaldo Carvalho de Melo 5351e2f0e5eSGerrit Renker #if 0 536727ecc5fSGerrit Renker /* FIXME: Is this still necessary (11.3) - currently nowhere used by DCCP. */ 5377c657876SArnaldo Carvalho de Melo void dccp_send_delayed_ack(struct sock *sk) 5387c657876SArnaldo Carvalho de Melo { 5397c657876SArnaldo Carvalho de Melo struct inet_connection_sock *icsk = inet_csk(sk); 5407c657876SArnaldo Carvalho de Melo /* 5417c657876SArnaldo Carvalho de Melo * FIXME: tune this timer. elapsed time fixes the skew, so no problem 5427c657876SArnaldo Carvalho de Melo * with using 2s, and active senders also piggyback the ACK into a 5437c657876SArnaldo Carvalho de Melo * DATAACK packet, so this is really for quiescent senders. 5447c657876SArnaldo Carvalho de Melo */ 5457c657876SArnaldo Carvalho de Melo unsigned long timeout = jiffies + 2 * HZ; 5467c657876SArnaldo Carvalho de Melo 5477c657876SArnaldo Carvalho de Melo /* Use new timeout only if there wasn't a older one earlier. */ 5487c657876SArnaldo Carvalho de Melo if (icsk->icsk_ack.pending & ICSK_ACK_TIMER) { 5497c657876SArnaldo Carvalho de Melo /* If delack timer was blocked or is about to expire, 5507c657876SArnaldo Carvalho de Melo * send ACK now. 5517c657876SArnaldo Carvalho de Melo * 5527c657876SArnaldo Carvalho de Melo * FIXME: check the "about to expire" part 5537c657876SArnaldo Carvalho de Melo */ 5547c657876SArnaldo Carvalho de Melo if (icsk->icsk_ack.blocked) { 5557c657876SArnaldo Carvalho de Melo dccp_send_ack(sk); 5567c657876SArnaldo Carvalho de Melo return; 5577c657876SArnaldo Carvalho de Melo } 5587c657876SArnaldo Carvalho de Melo 5597c657876SArnaldo Carvalho de Melo if (!time_before(timeout, icsk->icsk_ack.timeout)) 5607c657876SArnaldo Carvalho de Melo timeout = icsk->icsk_ack.timeout; 5617c657876SArnaldo Carvalho de Melo } 5627c657876SArnaldo Carvalho de Melo icsk->icsk_ack.pending |= ICSK_ACK_SCHED | ICSK_ACK_TIMER; 5637c657876SArnaldo Carvalho de Melo icsk->icsk_ack.timeout = timeout; 5647c657876SArnaldo Carvalho de Melo sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout); 5657c657876SArnaldo Carvalho de Melo } 5661e2f0e5eSGerrit Renker #endif 5677c657876SArnaldo Carvalho de Melo 568b0d045caSGerrit Renker void dccp_send_sync(struct sock *sk, const u64 ackno, 569e92ae93aSArnaldo Carvalho de Melo const enum dccp_pkt_type pkt_type) 5707c657876SArnaldo Carvalho de Melo { 5717c657876SArnaldo Carvalho de Melo /* 5727c657876SArnaldo Carvalho de Melo * We are not putting this on the write queue, so 5737c657876SArnaldo Carvalho de Melo * dccp_transmit_skb() will set the ownership to this 5747c657876SArnaldo Carvalho de Melo * sock. 5757c657876SArnaldo Carvalho de Melo */ 576118b2c95SArnaldo Carvalho de Melo struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header, GFP_ATOMIC); 5777c657876SArnaldo Carvalho de Melo 578b0d045caSGerrit Renker if (skb == NULL) { 5797c657876SArnaldo Carvalho de Melo /* FIXME: how to make sure the sync is sent? */ 580b0d045caSGerrit Renker DCCP_CRIT("could not send %s", dccp_packet_name(pkt_type)); 5817c657876SArnaldo Carvalho de Melo return; 582b0d045caSGerrit Renker } 5837c657876SArnaldo Carvalho de Melo 5847c657876SArnaldo Carvalho de Melo /* Reserve space for headers and prepare control bits. */ 585118b2c95SArnaldo Carvalho de Melo skb_reserve(skb, sk->sk_prot->max_header); 586e92ae93aSArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_type = pkt_type; 587b0d045caSGerrit Renker DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno; 5887c657876SArnaldo Carvalho de Melo 5897c657876SArnaldo Carvalho de Melo dccp_transmit_skb(sk, skb); 5907c657876SArnaldo Carvalho de Melo } 5917c657876SArnaldo Carvalho de Melo 592b61fafc4SArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(dccp_send_sync); 593b61fafc4SArnaldo Carvalho de Melo 5947690af3fSArnaldo Carvalho de Melo /* 5957690af3fSArnaldo Carvalho de Melo * Send a DCCP_PKT_CLOSE/CLOSEREQ. The caller locks the socket for us. This 5967690af3fSArnaldo Carvalho de Melo * cannot be allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under 5977690af3fSArnaldo Carvalho de Melo * any circumstances. 5987c657876SArnaldo Carvalho de Melo */ 5997ad07e7cSArnaldo Carvalho de Melo void dccp_send_close(struct sock *sk, const int active) 6007c657876SArnaldo Carvalho de Melo { 6017c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 6027c657876SArnaldo Carvalho de Melo struct sk_buff *skb; 6037d877f3bSAl Viro const gfp_t prio = active ? GFP_KERNEL : GFP_ATOMIC; 6047c657876SArnaldo Carvalho de Melo 6057ad07e7cSArnaldo Carvalho de Melo skb = alloc_skb(sk->sk_prot->max_header, prio); 6067ad07e7cSArnaldo Carvalho de Melo if (skb == NULL) 6077ad07e7cSArnaldo Carvalho de Melo return; 6087c657876SArnaldo Carvalho de Melo 6097c657876SArnaldo Carvalho de Melo /* Reserve space for headers and prepare control bits. */ 6107c657876SArnaldo Carvalho de Melo skb_reserve(skb, sk->sk_prot->max_header); 611b8599d20SGerrit Renker if (dp->dccps_role == DCCP_ROLE_SERVER && !dp->dccps_server_timewait) 612b8599d20SGerrit Renker DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSEREQ; 613b8599d20SGerrit Renker else 614b8599d20SGerrit Renker DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE; 6157c657876SArnaldo Carvalho de Melo 6167ad07e7cSArnaldo Carvalho de Melo if (active) { 61797e5848dSIan McDonald dccp_write_xmit(sk, 1); 61848918a4dSHerbert Xu dccp_skb_entail(sk, skb); 6197ad07e7cSArnaldo Carvalho de Melo dccp_transmit_skb(sk, skb_clone(skb, prio)); 62092d31920SGerrit Renker /* 62192d31920SGerrit Renker * Retransmission timer for active-close: RFC 4340, 8.3 requires 62292d31920SGerrit Renker * to retransmit the Close/CloseReq until the CLOSING/CLOSEREQ 62392d31920SGerrit Renker * state can be left. The initial timeout is 2 RTTs. 62492d31920SGerrit Renker * Since RTT measurement is done by the CCIDs, there is no easy 62592d31920SGerrit Renker * way to get an RTT sample. The fallback RTT from RFC 4340, 3.4 62692d31920SGerrit Renker * is too low (200ms); we use a high value to avoid unnecessary 62792d31920SGerrit Renker * retransmissions when the link RTT is > 0.2 seconds. 62892d31920SGerrit Renker * FIXME: Let main module sample RTTs and use that instead. 62992d31920SGerrit Renker */ 63092d31920SGerrit Renker inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 63192d31920SGerrit Renker DCCP_TIMEOUT_INIT, DCCP_RTO_MAX); 6327ad07e7cSArnaldo Carvalho de Melo } else 6337c657876SArnaldo Carvalho de Melo dccp_transmit_skb(sk, skb); 6347c657876SArnaldo Carvalho de Melo } 635