|
@@ -140,18 +140,9 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
|
|
} else {
|
|
} else {
|
|
/* Nothing to do. Next chunk in the packet, please. */
|
|
/* Nothing to do. Next chunk in the packet, please. */
|
|
ch = (sctp_chunkhdr_t *) chunk->chunk_end;
|
|
ch = (sctp_chunkhdr_t *) chunk->chunk_end;
|
|
-
|
|
|
|
/* Force chunk->skb->data to chunk->chunk_end. */
|
|
/* Force chunk->skb->data to chunk->chunk_end. */
|
|
- skb_pull(chunk->skb,
|
|
|
|
- chunk->chunk_end - chunk->skb->data);
|
|
|
|
-
|
|
|
|
- /* Verify that we have at least chunk headers
|
|
|
|
- * worth of buffer left.
|
|
|
|
- */
|
|
|
|
- if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) {
|
|
|
|
- sctp_chunk_free(chunk);
|
|
|
|
- chunk = queue->in_progress = NULL;
|
|
|
|
- }
|
|
|
|
|
|
+ skb_pull(chunk->skb, chunk->chunk_end - chunk->skb->data);
|
|
|
|
+ /* We are guaranteed to pull a SCTP header. */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -187,24 +178,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
|
|
skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
|
|
skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
|
|
chunk->subh.v = NULL; /* Subheader is no longer valid. */
|
|
chunk->subh.v = NULL; /* Subheader is no longer valid. */
|
|
|
|
|
|
- if (chunk->chunk_end < skb_tail_pointer(chunk->skb)) {
|
|
|
|
|
|
+ if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) <
|
|
|
|
+ skb_tail_pointer(chunk->skb)) {
|
|
/* This is not a singleton */
|
|
/* This is not a singleton */
|
|
chunk->singleton = 0;
|
|
chunk->singleton = 0;
|
|
} else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) {
|
|
} else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) {
|
|
- /* RFC 2960, Section 6.10 Bundling
|
|
|
|
- *
|
|
|
|
- * Partial chunks MUST NOT be placed in an SCTP packet.
|
|
|
|
- * If the receiver detects a partial chunk, it MUST drop
|
|
|
|
- * the chunk.
|
|
|
|
- *
|
|
|
|
- * Since the end of the chunk is past the end of our buffer
|
|
|
|
- * (which contains the whole packet, we can freely discard
|
|
|
|
- * the whole packet.
|
|
|
|
- */
|
|
|
|
- sctp_chunk_free(chunk);
|
|
|
|
- chunk = queue->in_progress = NULL;
|
|
|
|
-
|
|
|
|
- return NULL;
|
|
|
|
|
|
+ /* Discard inside state machine. */
|
|
|
|
+ chunk->pdiscard = 1;
|
|
|
|
+ chunk->chunk_end = skb_tail_pointer(chunk->skb);
|
|
} else {
|
|
} else {
|
|
/* We are at the end of the packet, so mark the chunk
|
|
/* We are at the end of the packet, so mark the chunk
|
|
* in case we need to send a SACK.
|
|
* in case we need to send a SACK.
|