Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27258ee5 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller
Browse files

[DCCP]: Introduce dccp_write_xmit from code in dccp_sendmsg



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: default avatarArnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0d48d939
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -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;
}

+7 −6
Original line number Diff line number Diff line
@@ -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",
+3 −2
Original line number Diff line number Diff line
@@ -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,
+37 −1
Original line number Diff line number Diff line
@@ -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;
}

+7 −58
Original line number Diff line number Diff line
@@ -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))
	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);