diff options
Diffstat (limited to 'net/sctp/endpointola.c')
-rw-r--r-- | net/sctp/endpointola.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index c8d5023606a5..2d2d81ef4a69 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 | } | ||
437 | normal: | ||
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 | } |