aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/chunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/chunk.c')
-rw-r--r--net/sctp/chunk.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 7b261afc47b9..7f8baa48e7c2 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -53,6 +53,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
53 msg->send_failed = 0; 53 msg->send_failed = 0;
54 msg->send_error = 0; 54 msg->send_error = 0;
55 msg->can_delay = 1; 55 msg->can_delay = 1;
56 msg->abandoned = 0;
56 msg->expires_at = 0; 57 msg->expires_at = 0;
57 INIT_LIST_HEAD(&msg->chunks); 58 INIT_LIST_HEAD(&msg->chunks);
58} 59}
@@ -304,6 +305,13 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
304 if (!chunk->asoc->peer.prsctp_capable) 305 if (!chunk->asoc->peer.prsctp_capable)
305 return 0; 306 return 0;
306 307
308 if (chunk->msg->abandoned)
309 return 1;
310
311 if (!chunk->has_tsn &&
312 !(chunk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG))
313 return 0;
314
307 if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && 315 if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
308 time_after(jiffies, chunk->msg->expires_at)) { 316 time_after(jiffies, chunk->msg->expires_at)) {
309 struct sctp_stream_out *streamout = 317 struct sctp_stream_out *streamout =
@@ -316,6 +324,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
316 chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; 324 chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
317 streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; 325 streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
318 } 326 }
327 chunk->msg->abandoned = 1;
319 return 1; 328 return 1;
320 } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && 329 } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
321 chunk->sent_count > chunk->sinfo.sinfo_timetolive) { 330 chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
@@ -324,10 +333,12 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
324 333
325 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; 334 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
326 streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++; 335 streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
336 chunk->msg->abandoned = 1;
327 return 1; 337 return 1;
328 } else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) && 338 } else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) &&
329 chunk->msg->expires_at && 339 chunk->msg->expires_at &&
330 time_after(jiffies, chunk->msg->expires_at)) { 340 time_after(jiffies, chunk->msg->expires_at)) {
341 chunk->msg->abandoned = 1;
331 return 1; 342 return 1;
332 } 343 }
333 /* PRIO policy is processed by sendmsg, not here */ 344 /* PRIO policy is processed by sendmsg, not here */