[DCCP]: Introduce dccp_write_xmit from code in dccp_sendmsg
authorArnaldo Carvalho de Melo <acme@mandriva.com>
Wed, 10 Aug 2005 03:30:56 +0000 (20:30 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 29 Aug 2005 22:55:18 +0000 (15:55 -0700)
This way it gets closer to the TCP flow, where congestion window
checks are done, it seems we can map ccid_hc_tx_send_packet in
dccp_write_xmit to tcp_snd_wnd_test in tcp_write_xmit, a CCID2
decision should just fit in here as well...

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dccp/ccid.h
net/dccp/ccids/ccid3.c
net/dccp/dccp.h
net/dccp/output.c
net/dccp/proto.c

index 06105b2a613cbf902999957d4566f2b9f4de308a..469f9a14b4631be3b8cdf190d7a6664bae41fdea 100644 (file)
@@ -43,8 +43,7 @@ struct ccid {
                                                    unsigned char len, u16 idx,
                                                    unsigned char* value);
        int             (*ccid_hc_tx_send_packet)(struct sock *sk,
-                                                 struct sk_buff *skb, int len,
-                                                 long *delay);
+                                                 struct sk_buff *skb, int len);
        void            (*ccid_hc_tx_packet_sent)(struct sock *sk, int more, int len);
 };
 
@@ -60,12 +59,11 @@ static inline void __ccid_get(struct ccid *ccid)
 }
 
 static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk,
-                                        struct sk_buff *skb, int len,
-                                        long *delay)
+                                        struct sk_buff *skb, int len)
 {
        int rc = 0;
        if (ccid->ccid_hc_tx_send_packet != NULL)
-               rc = ccid->ccid_hc_tx_send_packet(sk, skb, len, delay);
+               rc = ccid->ccid_hc_tx_send_packet(sk, skb, len);
        return rc;
 }
 
index 04299c7565f370be0c9121472af8a238e638bcc3..df4adfeaafaca8d19752fe97aa59c07697718dd9 100644 (file)
@@ -977,13 +977,14 @@ out:
        sock_put(sk);
 }
 
-static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb,
-                                  int len, long *delay)
+static int ccid3_hc_tx_send_packet(struct sock *sk,
+                                  struct sk_buff *skb, int len)
 {
        struct dccp_sock *dp = dccp_sk(sk);
        struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
        struct ccid3_tx_hist_entry *new_packet = NULL;
        struct timeval now;
+       long delay;
        int rc = -ENOTCONN;
 
 //     ccid3_pr_debug("%s, sk=%p, skb=%p, len=%d\n", dccp_role(sk), sk, skb, len);
@@ -1037,11 +1038,11 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb,
                break;
        case TFRC_SSTATE_NO_FBACK:
        case TFRC_SSTATE_FBACK:
-               *delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta);
-               ccid3_pr_debug("send_packet delay=%ld\n",*delay);
-               *delay /= -1000;
+               delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta);
+               ccid3_pr_debug("send_packet delay=%ld\n", delay);
+               delay /= -1000;
                /* divide by -1000 is to convert to ms and get sign right */
-               rc = *delay > 0 ? -EAGAIN : 0;
+               rc = delay > 0 ? -EAGAIN : 0;
                break;
        default:
                printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
index 55b690ab61ae22120482f9f592865ef02b12f0b9..8a0d7af649e424b1ba2d3c63ad31aa611269d02f 100644 (file)
@@ -122,6 +122,9 @@ extern void dccp_send_ack(struct sock *sk);
 extern void dccp_send_delayed_ack(struct sock *sk);
 extern void dccp_send_sync(struct sock *sk, u64 seq);
 
+extern int dccp_write_xmit(struct sock *sk, struct sk_buff *skb,
+                          const int len);
+
 extern void dccp_init_xmit_timers(struct sock *sk);
 static inline void dccp_clear_xmit_timers(struct sock *sk)
 {
@@ -194,8 +197,6 @@ static inline void dccp_openreq_init(struct request_sock *req,
        req->rcv_wnd = 0;
 }
 
-extern void dccp_v4_send_check(struct sock *sk, struct dccp_hdr *dh, int len, 
-                              struct sk_buff *skb);
 extern int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
 
 extern struct sock *dccp_create_openreq_child(struct sock *sk,
index 4945eaa9d1a4206a6917cd3fcf7380bb76b384a0..50292c0605fb9a3b09ce068e57834947fc9cfc24 100644 (file)
@@ -148,6 +148,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)
@@ -299,7 +334,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;
 }
 
index 66c43fce17a6c579b7e03bc90bf5ff384a42a804..877c1e0e3c48150022491812749c5a97da5886ae 100644 (file)
@@ -182,8 +182,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                return -EMSGSIZE;
 
        lock_sock(sk);
-
-       timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
+       timeo = sock_sndtimeo(sk, noblock);
 
        /*
         * We have to use sk_stream_wait_connect here to set sk_write_pending,
@@ -192,77 +191,27 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        /* Wait for a connection to finish. */
        if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN | DCCPF_CLOSING))
                if ((rc = sk_stream_wait_connect(sk, &timeo)) != 0)
-                       goto out_err;
+                       goto out_release;
 
        size = sk->sk_prot->max_header + len;
        release_sock(sk);
        skb = sock_alloc_send_skb(sk, size, noblock, &rc);
        lock_sock(sk);
-
        if (skb == NULL)
                goto out_release;
 
        skb_reserve(skb, sk->sk_prot->max_header);
        rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
-       if (rc == 0) {
-               struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
-               const struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
-               long delay; 
-
-               /*
-                * XXX: This is just to match the Waikato tree CA interaction
-                * points, after the CCID3 code is stable and I have a better
-                * understanding of behaviour I'll change this to look more like
-                * TCP.
-                */
-               while (1) {
-                       rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk,
-                                                   skb, len, &delay);
-                       if (rc == 0)
-                               break;
-                       if (rc != -EAGAIN)
-                               goto out_discard;
-                       if (delay > timeo)
-                               goto out_discard;
-                       release_sock(sk);
-                       delay = schedule_timeout(delay);
-                       lock_sock(sk);
-                       timeo -= delay;
-                       if (signal_pending(current))
-                               goto out_interrupted;
-                       rc = -EPIPE;
-                       if (!(sk->sk_state == DCCP_PARTOPEN || sk->sk_state == DCCP_OPEN))
-                               goto out_discard;
-               }
+       if (rc != 0)
+               goto out_discard;
 
-               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, TCP_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;
-               dccp_transmit_skb(sk, skb);
-               ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
-       } else {
-out_discard:
-               kfree_skb(skb);
-       }
+       rc = dccp_write_xmit(sk, skb, len);
 out_release:
        release_sock(sk);
        return rc ? : len;
-out_err:
-       rc = sk_stream_error(sk, flags, rc);
+out_discard:
+       kfree_skb(skb);
        goto out_release;
-out_interrupted:
-       rc = sock_intr_errno(timeo);
-       goto out_discard;
 }
 
 EXPORT_SYMBOL(dccp_sendmsg);