Skip to content

Commit

Permalink
[DCCP]: Introduce dccp_write_xmit from code in dccp_sendmsg
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arnaldo Carvalho de Melo authored and David S. Miller committed Aug 29, 2005
1 parent 0d48d93 commit 27258ee
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 72 deletions.
8 changes: 3 additions & 5 deletions net/dccp/ccid.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};

Expand All @@ -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;
}

Expand Down
13 changes: 7 additions & 6 deletions net/dccp/ccids/ccid3.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,13 +977,14 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
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);
Expand Down Expand Up @@ -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",
Expand Down
5 changes: 3 additions & 2 deletions net/dccp/dccp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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,
Expand Down
38 changes: 37 additions & 1 deletion net/dccp/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

Expand Down
65 changes: 7 additions & 58 deletions net/dccp/proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down

0 comments on commit 27258ee

Please sign in to comment.