diff options
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 | ||