[DCCP]: Set dccp_ctl_socket to NULL in dccp_ctl_sock_exit
[safe/jmp/linux-2.6] / net / dccp / output.c
index 4945eaa..384fd09 100644 (file)
@@ -40,13 +40,13 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                /* XXX For now we're using only 48 bits sequence numbers */
                const int dccp_header_size = sizeof(*dh) +
                                             sizeof(struct dccp_hdr_ext) +
-                                            dccp_packet_hdr_len(dcb->dccpd_type);
+                                         dccp_packet_hdr_len(dcb->dccpd_type);
                int err, set_ack = 1;
                u64 ackno = dp->dccps_gsr;
 
                /*
-                * FIXME: study DCCP_PKT_SYNC[ACK] to see what is the right thing 
-                * to do here...
+                * FIXME: study DCCP_PKT_SYNC[ACK] to see what is the right
+                * thing to do here...
                 */
                dccp_inc_seqno(&dp->dccps_gss);
 
@@ -65,7 +65,9 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                
                skb->h.raw = skb_push(skb, dccp_header_size);
                dh = dccp_hdr(skb);
-               /* Data packets are not cloned as they are never retransmitted */
+               /*
+                * Data packets are not cloned as they are never retransmitted
+                */
                if (skb_cloned(skb))
                        skb_set_owner_w(skb, sk);
 
@@ -86,10 +88,12 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 
                switch (dcb->dccpd_type) {
                case DCCP_PKT_REQUEST:
-                       dccp_hdr_request(skb)->dccph_req_service = dcb->dccpd_service;
+                       dccp_hdr_request(skb)->dccph_req_service =
+                                                       dcb->dccpd_service;
                        break;
                case DCCP_PKT_RESET:
-                       dccp_hdr_reset(skb)->dccph_reset_code = dcb->dccpd_reset_code;
+                       dccp_hdr_reset(skb)->dccph_reset_code =
+                                                       dcb->dccpd_reset_code;
                        break;
                }
 
@@ -123,10 +127,13 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
        int mss_now;
 
        /*
-        * FIXME: we really should be using the af_specific thing to support IPv6.
-        * mss_now = pmtu - tp->af_specific->net_header_len - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
+        * FIXME: we really should be using the af_specific thing to support
+        *        IPv6.
+        * mss_now = pmtu - tp->af_specific->net_header_len -
+        *           sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
         */
-       mss_now = pmtu - sizeof(struct iphdr) - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
+       mss_now = pmtu - sizeof(struct iphdr) - sizeof(struct dccp_hdr) -
+                 sizeof(struct dccp_hdr_ext);
 
        /* Now subtract optional transport overhead */
        mss_now -= dp->dccps_ext_header_len;
@@ -148,6 +155,41 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
        return mss_now;
 }
 
+int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, const int len)
+{
+       const struct dccp_sock *dp = dccp_sk(sk);
+       int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb, len);
+
+       if (err == 0) {
+               const struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
+               struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+
+               if (sk->sk_state == DCCP_PARTOPEN) {
+                       /* See 8.1.5.  Handshake Completion */
+                       inet_csk_schedule_ack(sk);
+                       inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
+                                                 inet_csk(sk)->icsk_rto,
+                                                 DCCP_RTO_MAX);
+                       dcb->dccpd_type = DCCP_PKT_DATAACK;
+                       /*
+                        * FIXME: we really should have a
+                        * dccps_ack_pending or use icsk.
+                        */
+               } else if (inet_csk_ack_scheduled(sk) ||
+                          (dp->dccps_options.dccpo_send_ack_vector &&
+                           ap->dccpap_buf_ackno != DCCP_MAX_SEQNO + 1 &&
+                           ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1))
+                       dcb->dccpd_type = DCCP_PKT_DATAACK;
+               else
+                       dcb->dccpd_type = DCCP_PKT_DATA;
+
+               err = dccp_transmit_skb(sk, skb);
+               ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
+       }
+
+       return err;
+}
+
 int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
        if (inet_sk_rebuild_header(sk) != 0)
@@ -188,7 +230,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
 
        dh->dccph_sport = inet_sk(sk)->sport;
        dh->dccph_dport = inet_rsk(req)->rmt_port;
-       dh->dccph_doff  = (dccp_header_size + DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
+       dh->dccph_doff  = (dccp_header_size +
+                          DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
        dh->dccph_type  = DCCP_PKT_RESPONSE;
        dh->dccph_x     = 1;
        dccp_hdr_set_seq(dh, dccp_rsk(req)->dreq_iss);
@@ -236,7 +279,8 @@ struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
 
        dh->dccph_sport = inet_sk(sk)->sport;
        dh->dccph_dport = inet_sk(sk)->dport;
-       dh->dccph_doff  = (dccp_header_size + DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
+       dh->dccph_doff  = (dccp_header_size +
+                          DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
        dh->dccph_type  = DCCP_PKT_RESET;
        dh->dccph_x     = 1;
        dccp_hdr_set_seq(dh, dp->dccps_gss);
@@ -299,7 +343,8 @@ int dccp_connect(struct sock *sk)
        DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
 
        /* Timer for repeating the REQUEST until an answer. */
-       inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
+       inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+                                 icsk->icsk_rto, DCCP_RTO_MAX);
        return 0;
 }
 
@@ -312,7 +357,9 @@ void dccp_send_ack(struct sock *sk)
                if (skb == NULL) {
                        inet_csk_schedule_ack(sk);
                        inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN;
-                       inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, TCP_DELACK_MAX, TCP_RTO_MAX);
+                       inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
+                                                 TCP_DELACK_MAX,
+                                                 DCCP_RTO_MAX);
                        return;
                }
 
@@ -357,7 +404,8 @@ void dccp_send_delayed_ack(struct sock *sk)
        sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout);
 }
 
-void dccp_send_sync(struct sock *sk, u64 seq)
+void dccp_send_sync(struct sock *sk, const u64 seq,
+                   const enum dccp_pkt_type pkt_type)
 {
        /*
         * We are not putting this on the write queue, so
@@ -373,15 +421,17 @@ void dccp_send_sync(struct sock *sk, u64 seq)
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(skb, MAX_DCCP_HEADER);
        skb->csum = 0;
-       DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_SYNC;
+       DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
        DCCP_SKB_CB(skb)->dccpd_seq = seq;
 
        skb_set_owner_w(skb, sk);
        dccp_transmit_skb(sk, skb);
 }
 
-/* Send a DCCP_PKT_CLOSE/CLOSEREQ.  The caller locks the socket for us.  This cannot be
- * allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under any circumstances.
+/*
+ * Send a DCCP_PKT_CLOSE/CLOSEREQ. The caller locks the socket for us. This
+ * cannot be allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under
+ * any circumstances.
  */
 void dccp_send_close(struct sock *sk)
 {
@@ -399,7 +449,8 @@ void dccp_send_close(struct sock *sk)
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(skb, sk->sk_prot->max_header);
        skb->csum = 0;
-       DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ? DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
+       DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ?
+                                       DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
 
        skb_set_owner_w(skb, sk);
        dccp_transmit_skb(sk, skb);