diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-12-20 17:11:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:59:23 -0500 |
commit | a08de64d074b36a56ee3bb985cd171281db78e96 (patch) | |
tree | 15b3c77a7078b5dc0510a23cc7d95922f7ad420a /net/sctp/outqueue.c | |
parent | ba8a06daed7d7c8785c92c343da9e202e6988fda (diff) |
[SCTP]: Update ASCONF processing to conform to spec.
The processing of the ASCONF chunks has changed a lot in the
spec. New items are:
1. A list of ASCONF-ACK chunks is now cached
2. The source of the packet is used in response.
3. New handling for unexpect ASCONF chunks.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r-- | net/sctp/outqueue.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index fa76f235169b..a42af865c2ef 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -716,7 +716,29 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
716 | new_transport = chunk->transport; | 716 | new_transport = chunk->transport; |
717 | 717 | ||
718 | if (!new_transport) { | 718 | if (!new_transport) { |
719 | new_transport = asoc->peer.active_path; | 719 | /* |
720 | * If we have a prior transport pointer, see if | ||
721 | * the destination address of the chunk | ||
722 | * matches the destination address of the | ||
723 | * current transport. If not a match, then | ||
724 | * try to look up the transport with a given | ||
725 | * destination address. We do this because | ||
726 | * after processing ASCONFs, we may have new | ||
727 | * transports created. | ||
728 | */ | ||
729 | if (transport && | ||
730 | sctp_cmp_addr_exact(&chunk->dest, | ||
731 | &transport->ipaddr)) | ||
732 | new_transport = transport; | ||
733 | else | ||
734 | new_transport = sctp_assoc_lookup_paddr(asoc, | ||
735 | &chunk->dest); | ||
736 | |||
737 | /* if we still don't have a new transport, then | ||
738 | * use the current active path. | ||
739 | */ | ||
740 | if (!new_transport) | ||
741 | new_transport = asoc->peer.active_path; | ||
720 | } else if ((new_transport->state == SCTP_INACTIVE) || | 742 | } else if ((new_transport->state == SCTP_INACTIVE) || |
721 | (new_transport->state == SCTP_UNCONFIRMED)) { | 743 | (new_transport->state == SCTP_UNCONFIRMED)) { |
722 | /* If the chunk is Heartbeat or Heartbeat Ack, | 744 | /* If the chunk is Heartbeat or Heartbeat Ack, |
@@ -729,9 +751,12 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
729 | * address of the IP datagram containing the | 751 | * address of the IP datagram containing the |
730 | * HEARTBEAT chunk to which this ack is responding. | 752 | * HEARTBEAT chunk to which this ack is responding. |
731 | * ... | 753 | * ... |
754 | * | ||
755 | * ASCONF_ACKs also must be sent to the source. | ||
732 | */ | 756 | */ |
733 | if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT && | 757 | if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT && |
734 | chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT_ACK) | 758 | chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT_ACK && |
759 | chunk->chunk_hdr->type != SCTP_CID_ASCONF_ACK) | ||
735 | new_transport = asoc->peer.active_path; | 760 | new_transport = asoc->peer.active_path; |
736 | } | 761 | } |
737 | 762 | ||