Commit 27258ee54f8cd4a43d09319aa5448145afc2cb8d
Committed by
David S. Miller
1 parent
0d48d93947
Exists in
master
and in
7 other branches
[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
net/dccp/ccid.h
... | ... | @@ -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", |
net/dccp/dccp.h
... | ... | @@ -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, |
net/dccp/output.c
... | ... | @@ -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 |
net/dccp/proto.c
... | ... | @@ -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); |