diff options
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r-- | net/dccp/proto.c | 65 |
1 files changed, 7 insertions, 58 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 66c43fce17a6..877c1e0e3c48 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -182,8 +182,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
182 | return -EMSGSIZE; | 182 | return -EMSGSIZE; |
183 | 183 | ||
184 | lock_sock(sk); | 184 | lock_sock(sk); |
185 | 185 | timeo = sock_sndtimeo(sk, noblock); | |
186 | timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); | ||
187 | 186 | ||
188 | /* | 187 | /* |
189 | * We have to use sk_stream_wait_connect here to set sk_write_pending, | 188 | * 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, | |||
192 | /* Wait for a connection to finish. */ | 191 | /* Wait for a connection to finish. */ |
193 | if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN | DCCPF_CLOSING)) | 192 | if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN | DCCPF_CLOSING)) |
194 | if ((rc = sk_stream_wait_connect(sk, &timeo)) != 0) | 193 | if ((rc = sk_stream_wait_connect(sk, &timeo)) != 0) |
195 | goto out_err; | 194 | goto out_release; |
196 | 195 | ||
197 | size = sk->sk_prot->max_header + len; | 196 | size = sk->sk_prot->max_header + len; |
198 | release_sock(sk); | 197 | release_sock(sk); |
199 | skb = sock_alloc_send_skb(sk, size, noblock, &rc); | 198 | skb = sock_alloc_send_skb(sk, size, noblock, &rc); |
200 | lock_sock(sk); | 199 | lock_sock(sk); |
201 | |||
202 | if (skb == NULL) | 200 | if (skb == NULL) |
203 | goto out_release; | 201 | goto out_release; |
204 | 202 | ||
205 | skb_reserve(skb, sk->sk_prot->max_header); | 203 | skb_reserve(skb, sk->sk_prot->max_header); |
206 | rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 204 | rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); |
207 | if (rc == 0) { | 205 | if (rc != 0) |
208 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); | 206 | goto out_discard; |
209 | const struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; | ||
210 | long delay; | ||
211 | |||
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 | 207 | ||
238 | if (sk->sk_state == DCCP_PARTOPEN) { | 208 | rc = dccp_write_xmit(sk, skb, len); |
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 | } | ||
257 | out_release: | 209 | out_release: |
258 | release_sock(sk); | 210 | release_sock(sk); |
259 | return rc ? : len; | 211 | return rc ? : len; |
260 | out_err: | 212 | out_discard: |
261 | rc = sk_stream_error(sk, flags, rc); | 213 | kfree_skb(skb); |
262 | goto out_release; | 214 | goto out_release; |
263 | out_interrupted: | ||
264 | rc = sock_intr_errno(timeo); | ||
265 | goto out_discard; | ||
266 | } | 215 | } |
267 | 216 | ||
268 | EXPORT_SYMBOL(dccp_sendmsg); | 217 | EXPORT_SYMBOL(dccp_sendmsg); |