aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/endpointola.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/endpointola.c')
-rw-r--r--net/sctp/endpointola.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index c8d5023606a..2d2d81ef4a6 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -400,6 +400,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
400 sctp_subtype_t subtype; 400 sctp_subtype_t subtype;
401 sctp_state_t state; 401 sctp_state_t state;
402 int error = 0; 402 int error = 0;
403 int first_time = 1; /* is this the first time through the looop */
403 404
404 if (ep->base.dead) 405 if (ep->base.dead)
405 return; 406 return;
@@ -411,6 +412,29 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
411 while (NULL != (chunk = sctp_inq_pop(inqueue))) { 412 while (NULL != (chunk = sctp_inq_pop(inqueue))) {
412 subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); 413 subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
413 414
415 /* If the first chunk in the packet is AUTH, do special
416 * processing specified in Section 6.3 of SCTP-AUTH spec
417 */
418 if (first_time && (subtype.chunk == SCTP_CID_AUTH)) {
419 struct sctp_chunkhdr *next_hdr;
420
421 next_hdr = sctp_inq_peek(inqueue);
422 if (!next_hdr)
423 goto normal;
424
425 /* If the next chunk is COOKIE-ECHO, skip the AUTH
426 * chunk while saving a pointer to it so we can do
427 * Authentication later (during cookie-echo
428 * processing).
429 */
430 if (next_hdr->type == SCTP_CID_COOKIE_ECHO) {
431 chunk->auth_chunk = skb_clone(chunk->skb,
432 GFP_ATOMIC);
433 chunk->auth = 1;
434 continue;
435 }
436 }
437normal:
414 /* We might have grown an association since last we 438 /* We might have grown an association since last we
415 * looked, so try again. 439 * looked, so try again.
416 * 440 *
@@ -426,6 +450,8 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
426 } 450 }
427 451
428 state = asoc ? asoc->state : SCTP_STATE_CLOSED; 452 state = asoc ? asoc->state : SCTP_STATE_CLOSED;
453 if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
454 continue;
429 455
430 /* Remember where the last DATA chunk came from so we 456 /* Remember where the last DATA chunk came from so we
431 * know where to send the SACK. 457 * know where to send the SACK.
@@ -449,5 +475,8 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
449 */ 475 */
450 if (!sctp_sk(sk)->ep) 476 if (!sctp_sk(sk)->ep)
451 break; 477 break;
478
479 if (first_time)
480 first_time = 0;
452 } 481 }
453} 482}