diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-10-03 20:51:34 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:51:31 -0400 |
commit | bbd0d59809f923ea2b540cbd781b32110e249f6e (patch) | |
tree | 8a278cfa0e7bcc7b415e93baf6d1a93536efe17a /net/sctp/endpointola.c | |
parent | 4cd57c8078fae0a4b1bf421191e94626d0cba92a (diff) |
[SCTP]: Implement the receive and verification of AUTH chunk
This patch implements the receive path needed to process authenticated
chunks. Add ability to process the AUTH chunk and handle edge cases
for authenticated COOKIE-ECHO as well.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
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 | } |