Commit 27258ee54f8cd4a43d09319aa5448145afc2cb8d

Authored by Arnaldo Carvalho de Melo
Committed by David S. Miller
1 parent 0d48d93947

[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: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 5 changed files with 57 additions and 72 deletions Side-by-side Diff

... ... @@ -43,8 +43,7 @@
43 43 unsigned char len, u16 idx,
44 44 unsigned char* value);
45 45 int (*ccid_hc_tx_send_packet)(struct sock *sk,
46   - struct sk_buff *skb, int len,
47   - long *delay);
  46 + struct sk_buff *skb, int len);
48 47 void (*ccid_hc_tx_packet_sent)(struct sock *sk, int more, int len);
49 48 };
50 49  
51 50  
... ... @@ -60,12 +59,11 @@
60 59 }
61 60  
62 61 static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk,
63   - struct sk_buff *skb, int len,
64   - long *delay)
  62 + struct sk_buff *skb, int len)
65 63 {
66 64 int rc = 0;
67 65 if (ccid->ccid_hc_tx_send_packet != NULL)
68   - rc = ccid->ccid_hc_tx_send_packet(sk, skb, len, delay);
  66 + rc = ccid->ccid_hc_tx_send_packet(sk, skb, len);
69 67 return rc;
70 68 }
71 69  
net/dccp/ccids/ccid3.c
... ... @@ -977,13 +977,14 @@
977 977 sock_put(sk);
978 978 }
979 979  
980   -static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb,
981   - int len, long *delay)
  980 +static int ccid3_hc_tx_send_packet(struct sock *sk,
  981 + struct sk_buff *skb, int len)
982 982 {
983 983 struct dccp_sock *dp = dccp_sk(sk);
984 984 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
985 985 struct ccid3_tx_hist_entry *new_packet = NULL;
986 986 struct timeval now;
  987 + long delay;
987 988 int rc = -ENOTCONN;
988 989  
989 990 // ccid3_pr_debug("%s, sk=%p, skb=%p, len=%d\n", dccp_role(sk), sk, skb, len);
990 991  
... ... @@ -1037,11 +1038,11 @@
1037 1038 break;
1038 1039 case TFRC_SSTATE_NO_FBACK:
1039 1040 case TFRC_SSTATE_FBACK:
1040   - *delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta);
1041   - ccid3_pr_debug("send_packet delay=%ld\n",*delay);
1042   - *delay /= -1000;
  1041 + delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta);
  1042 + ccid3_pr_debug("send_packet delay=%ld\n", delay);
  1043 + delay /= -1000;
1043 1044 /* divide by -1000 is to convert to ms and get sign right */
1044   - rc = *delay > 0 ? -EAGAIN : 0;
  1045 + rc = delay > 0 ? -EAGAIN : 0;
1045 1046 break;
1046 1047 default:
1047 1048 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
... ... @@ -122,6 +122,9 @@
122 122 extern void dccp_send_delayed_ack(struct sock *sk);
123 123 extern void dccp_send_sync(struct sock *sk, u64 seq);
124 124  
  125 +extern int dccp_write_xmit(struct sock *sk, struct sk_buff *skb,
  126 + const int len);
  127 +
125 128 extern void dccp_init_xmit_timers(struct sock *sk);
126 129 static inline void dccp_clear_xmit_timers(struct sock *sk)
127 130 {
... ... @@ -194,8 +197,6 @@
194 197 req->rcv_wnd = 0;
195 198 }
196 199  
197   -extern void dccp_v4_send_check(struct sock *sk, struct dccp_hdr *dh, int len,
198   - struct sk_buff *skb);
199 200 extern int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
200 201  
201 202 extern struct sock *dccp_create_openreq_child(struct sock *sk,
... ... @@ -148,6 +148,41 @@
148 148 return mss_now;
149 149 }
150 150  
  151 +int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, const int len)
  152 +{
  153 + const struct dccp_sock *dp = dccp_sk(sk);
  154 + int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb, len);
  155 +
  156 + if (err == 0) {
  157 + const struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
  158 + struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
  159 +
  160 + if (sk->sk_state == DCCP_PARTOPEN) {
  161 + /* See 8.1.5. Handshake Completion */
  162 + inet_csk_schedule_ack(sk);
  163 + inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
  164 + inet_csk(sk)->icsk_rto,
  165 + DCCP_RTO_MAX);
  166 + dcb->dccpd_type = DCCP_PKT_DATAACK;
  167 + /*
  168 + * FIXME: we really should have a
  169 + * dccps_ack_pending or use icsk.
  170 + */
  171 + } else if (inet_csk_ack_scheduled(sk) ||
  172 + (dp->dccps_options.dccpo_send_ack_vector &&
  173 + ap->dccpap_buf_ackno != DCCP_MAX_SEQNO + 1 &&
  174 + ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1))
  175 + dcb->dccpd_type = DCCP_PKT_DATAACK;
  176 + else
  177 + dcb->dccpd_type = DCCP_PKT_DATA;
  178 +
  179 + err = dccp_transmit_skb(sk, skb);
  180 + ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
  181 + }
  182 +
  183 + return err;
  184 +}
  185 +
151 186 int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
152 187 {
153 188 if (inet_sk_rebuild_header(sk) != 0)
... ... @@ -299,7 +334,8 @@
299 334 DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
300 335  
301 336 /* Timer for repeating the REQUEST until an answer. */
302   - inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
  337 + inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
  338 + icsk->icsk_rto, DCCP_RTO_MAX);
303 339 return 0;
304 340 }
305 341  
... ... @@ -182,9 +182,8 @@
182 182 return -EMSGSIZE;
183 183  
184 184 lock_sock(sk);
  185 + timeo = sock_sndtimeo(sk, noblock);
185 186  
186   - timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
187   -
188 187 /*
189 188 * We have to use sk_stream_wait_connect here to set sk_write_pending,
190 189 * so that the trick in dccp_rcv_request_sent_state_process.
191 190  
192 191  
193 192  
194 193  
195 194  
... ... @@ -192,77 +191,27 @@
192 191 /* Wait for a connection to finish. */
193 192 if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN | DCCPF_CLOSING))
194 193 if ((rc = sk_stream_wait_connect(sk, &timeo)) != 0)
195   - goto out_err;
  194 + goto out_release;
196 195  
197 196 size = sk->sk_prot->max_header + len;
198 197 release_sock(sk);
199 198 skb = sock_alloc_send_skb(sk, size, noblock, &rc);
200 199 lock_sock(sk);
201   -
202 200 if (skb == NULL)
203 201 goto out_release;
204 202  
205 203 skb_reserve(skb, sk->sk_prot->max_header);
206 204 rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
207   - if (rc == 0) {
208   - struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
209   - const struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
210   - long delay;
  205 + if (rc != 0)
  206 + goto out_discard;
211 207  
212   - /*
213   - * XXX: This is just to match the Waikato tree CA interaction
214   - * points, after the CCID3 code is stable and I have a better
215   - * understanding of behaviour I'll change this to look more like
216   - * TCP.
217   - */
218   - while (1) {
219   - rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk,
220   - skb, len, &delay);
221   - if (rc == 0)
222   - break;
223   - if (rc != -EAGAIN)
224   - goto out_discard;
225   - if (delay > timeo)
226   - goto out_discard;
227   - release_sock(sk);
228   - delay = schedule_timeout(delay);
229   - lock_sock(sk);
230   - timeo -= delay;
231   - if (signal_pending(current))
232   - goto out_interrupted;
233   - rc = -EPIPE;
234   - if (!(sk->sk_state == DCCP_PARTOPEN || sk->sk_state == DCCP_OPEN))
235   - goto out_discard;
236   - }
237   -
238   - if (sk->sk_state == DCCP_PARTOPEN) {
239   - /* See 8.1.5. Handshake Completion */
240   - inet_csk_schedule_ack(sk);
241   - inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
242   - dcb->dccpd_type = DCCP_PKT_DATAACK;
243   - /* FIXME: we really should have a dccps_ack_pending or use icsk */
244   - } else if (inet_csk_ack_scheduled(sk) ||
245   - (dp->dccps_options.dccpo_send_ack_vector &&
246   - ap->dccpap_buf_ackno != DCCP_MAX_SEQNO + 1 &&
247   - ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1))
248   - dcb->dccpd_type = DCCP_PKT_DATAACK;
249   - else
250   - dcb->dccpd_type = DCCP_PKT_DATA;
251   - dccp_transmit_skb(sk, skb);
252   - ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
253   - } else {
254   -out_discard:
255   - kfree_skb(skb);
256   - }
  208 + rc = dccp_write_xmit(sk, skb, len);
257 209 out_release:
258 210 release_sock(sk);
259 211 return rc ? : len;
260   -out_err:
261   - rc = sk_stream_error(sk, flags, rc);
  212 +out_discard:
  213 + kfree_skb(skb);
262 214 goto out_release;
263   -out_interrupted:
264   - rc = sock_intr_errno(timeo);
265   - goto out_discard;
266 215 }
267 216  
268 217 EXPORT_SYMBOL(dccp_sendmsg);