From 7ad07e7cf343181002c10c39d3f57a88e4903d4f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 23 Aug 2005 21:50:06 -0700 Subject: [DCCP]: Implement the CLOSING timer So that we retransmit CLOSE/CLOSEREQ packets till they elicit an answer or we hit a timeout. Most of the machinery uses TCP approaches, this code has to be polished & audited, but this is better than we had before. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/dccp/output.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'net/dccp/output.c') diff --git a/net/dccp/output.c b/net/dccp/output.c index 708fc3c0a96..630ca774102 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -96,8 +96,7 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr); - if (dcb->dccpd_type == DCCP_PKT_ACK || - dcb->dccpd_type == DCCP_PKT_DATAACK) + if (set_ack) dccp_event_ack_sent(sk); DCCP_INC_STATS(DCCP_MIB_OUTSEGS); @@ -429,18 +428,15 @@ void dccp_send_sync(struct sock *sk, const u64 seq, * cannot be allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under * any circumstances. */ -void dccp_send_close(struct sock *sk) +void dccp_send_close(struct sock *sk, const int active) { struct dccp_sock *dp = dccp_sk(sk); struct sk_buff *skb; + const unsigned int prio = active ? GFP_KERNEL : GFP_ATOMIC; - /* Socket is locked, keep trying until memory is available. */ - for (;;) { - skb = alloc_skb(sk->sk_prot->max_header, GFP_KERNEL); - if (skb != NULL) - break; - yield(); - } + skb = alloc_skb(sk->sk_prot->max_header, prio); + if (skb == NULL) + return; /* Reserve space for headers and prepare control bits. */ skb_reserve(skb, sk->sk_prot->max_header); @@ -449,7 +445,12 @@ void dccp_send_close(struct sock *sk) DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; skb_set_owner_w(skb, sk); - dccp_transmit_skb(sk, skb); + if (active) { + BUG_TRAP(sk->sk_send_head == NULL); + sk->sk_send_head = skb; + dccp_transmit_skb(sk, skb_clone(skb, prio)); + } else + dccp_transmit_skb(sk, skb); ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk); ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk); -- cgit v1.2.3