diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/input.c | 13 | ||||
-rw-r--r-- | net/sctp/output.c | 7 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 3 |
3 files changed, 18 insertions, 5 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index bf612d954d41..2e4a8646dbc3 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -249,6 +249,19 @@ int sctp_rcv(struct sk_buff *skb) | |||
249 | */ | 249 | */ |
250 | sctp_bh_lock_sock(sk); | 250 | sctp_bh_lock_sock(sk); |
251 | 251 | ||
252 | if (sk != rcvr->sk) { | ||
253 | /* Our cached sk is different from the rcvr->sk. This is | ||
254 | * because migrate()/accept() may have moved the association | ||
255 | * to a new socket and released all the sockets. So now we | ||
256 | * are holding a lock on the old socket while the user may | ||
257 | * be doing something with the new socket. Switch our veiw | ||
258 | * of the current sk. | ||
259 | */ | ||
260 | sctp_bh_unlock_sock(sk); | ||
261 | sk = rcvr->sk; | ||
262 | sctp_bh_lock_sock(sk); | ||
263 | } | ||
264 | |||
252 | if (sock_owned_by_user(sk)) { | 265 | if (sock_owned_by_user(sk)) { |
253 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG); | 266 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG); |
254 | sctp_add_backlog(sk, skb); | 267 | sctp_add_backlog(sk, skb); |
diff --git a/net/sctp/output.c b/net/sctp/output.c index c3f417f7ec6e..73639355157e 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -324,14 +324,16 @@ append: | |||
324 | switch (chunk->chunk_hdr->type) { | 324 | switch (chunk->chunk_hdr->type) { |
325 | case SCTP_CID_DATA: | 325 | case SCTP_CID_DATA: |
326 | retval = sctp_packet_append_data(packet, chunk); | 326 | retval = sctp_packet_append_data(packet, chunk); |
327 | if (SCTP_XMIT_OK != retval) | ||
328 | goto finish; | ||
327 | /* Disallow SACK bundling after DATA. */ | 329 | /* Disallow SACK bundling after DATA. */ |
328 | packet->has_sack = 1; | 330 | packet->has_sack = 1; |
329 | /* Disallow AUTH bundling after DATA */ | 331 | /* Disallow AUTH bundling after DATA */ |
330 | packet->has_auth = 1; | 332 | packet->has_auth = 1; |
331 | /* Let it be knows that packet has DATA in it */ | 333 | /* Let it be knows that packet has DATA in it */ |
332 | packet->has_data = 1; | 334 | packet->has_data = 1; |
333 | if (SCTP_XMIT_OK != retval) | 335 | /* timestamp the chunk for rtx purposes */ |
334 | goto finish; | 336 | chunk->sent_at = jiffies; |
335 | break; | 337 | break; |
336 | case SCTP_CID_COOKIE_ECHO: | 338 | case SCTP_CID_COOKIE_ECHO: |
337 | packet->has_cookie_echo = 1; | 339 | packet->has_cookie_echo = 1; |
@@ -470,7 +472,6 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
470 | } else | 472 | } else |
471 | chunk->resent = 1; | 473 | chunk->resent = 1; |
472 | 474 | ||
473 | chunk->sent_at = jiffies; | ||
474 | has_data = 1; | 475 | has_data = 1; |
475 | } | 476 | } |
476 | 477 | ||
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 247ebc95c1e5..bc411c896216 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -929,7 +929,6 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
929 | } | 929 | } |
930 | 930 | ||
931 | /* Finally, transmit new packets. */ | 931 | /* Finally, transmit new packets. */ |
932 | start_timer = 0; | ||
933 | while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { | 932 | while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { |
934 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid | 933 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid |
935 | * stream identifier. | 934 | * stream identifier. |
@@ -1028,7 +1027,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
1028 | list_add_tail(&chunk->transmitted_list, | 1027 | list_add_tail(&chunk->transmitted_list, |
1029 | &transport->transmitted); | 1028 | &transport->transmitted); |
1030 | 1029 | ||
1031 | sctp_transport_reset_timers(transport, start_timer-1); | 1030 | sctp_transport_reset_timers(transport, 0); |
1032 | 1031 | ||
1033 | q->empty = 0; | 1032 | q->empty = 0; |
1034 | 1033 | ||