diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-05-04 16:55:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-05-04 16:55:27 -0400 |
commit | 07d939677166cc4f000c767196872a9becc2697b (patch) | |
tree | bef3d3c75ac3dd56813adbc63281feb4195a5b47 /net/sctp/sm_statefuns.c | |
parent | 827bf12236fbafc02bc899aec1b37c342c8cf4e5 (diff) |
[SCTP]: Set assoc_id correctly during INIT collision.
During the INIT/COOKIE-ACK collision cases, it's possible to get
into a situation where the association id is not yet set at the time
of the user event generation. As a result, user events have an
association id set to 0 which will confuse applications.
This happens if we hit case B of duplicate cookie processing.
In the particular example found and provided by Oscar Isaula
<Oscar.Isaula@motorola.com>, flow looks like this:
A B
---- INIT-------> (lost)
<---------INIT------
---- INIT-ACK--->
<------ Cookie ECHO
When the Cookie Echo is received, we end up trying to update the
association that was created on A as a result of the (lost) INIT,
but that association doesn't have the ID set yet.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r-- | net/sctp/sm_statefuns.c | 29 |
1 files changed, 11 insertions, 18 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 9e28a5d51200..f02ce3dddb7b 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -1656,7 +1656,6 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep, | |||
1656 | struct sctp_association *new_asoc) | 1656 | struct sctp_association *new_asoc) |
1657 | { | 1657 | { |
1658 | sctp_init_chunk_t *peer_init; | 1658 | sctp_init_chunk_t *peer_init; |
1659 | struct sctp_ulpevent *ev; | ||
1660 | struct sctp_chunk *repl; | 1659 | struct sctp_chunk *repl; |
1661 | 1660 | ||
1662 | /* new_asoc is a brand-new association, so these are not yet | 1661 | /* new_asoc is a brand-new association, so these are not yet |
@@ -1687,34 +1686,28 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep, | |||
1687 | * D) IMPLEMENTATION NOTE: An implementation may choose to | 1686 | * D) IMPLEMENTATION NOTE: An implementation may choose to |
1688 | * send the Communication Up notification to the SCTP user | 1687 | * send the Communication Up notification to the SCTP user |
1689 | * upon reception of a valid COOKIE ECHO chunk. | 1688 | * upon reception of a valid COOKIE ECHO chunk. |
1689 | * | ||
1690 | * Sadly, this needs to be implemented as a side-effect, because | ||
1691 | * we are not guaranteed to have set the association id of the real | ||
1692 | * association and so these notifications need to be delayed until | ||
1693 | * the association id is allocated. | ||
1690 | */ | 1694 | */ |
1691 | ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP, 0, | ||
1692 | new_asoc->c.sinit_num_ostreams, | ||
1693 | new_asoc->c.sinit_max_instreams, | ||
1694 | NULL, GFP_ATOMIC); | ||
1695 | if (!ev) | ||
1696 | goto nomem_ev; | ||
1697 | 1695 | ||
1698 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | 1696 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_CHANGE, SCTP_U8(SCTP_COMM_UP)); |
1699 | 1697 | ||
1700 | /* Sockets API Draft Section 5.3.1.6 | 1698 | /* Sockets API Draft Section 5.3.1.6 |
1701 | * When a peer sends a Adaptation Layer Indication parameter , SCTP | 1699 | * When a peer sends a Adaptation Layer Indication parameter , SCTP |
1702 | * delivers this notification to inform the application that of the | 1700 | * delivers this notification to inform the application that of the |
1703 | * peers requested adaptation layer. | 1701 | * peers requested adaptation layer. |
1702 | * | ||
1703 | * This also needs to be done as a side effect for the same reason as | ||
1704 | * above. | ||
1704 | */ | 1705 | */ |
1705 | if (asoc->peer.adaptation_ind) { | 1706 | if (asoc->peer.adaptation_ind) |
1706 | ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC); | 1707 | sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL()); |
1707 | if (!ev) | ||
1708 | goto nomem_ev; | ||
1709 | |||
1710 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | ||
1711 | SCTP_ULPEVENT(ev)); | ||
1712 | } | ||
1713 | 1708 | ||
1714 | return SCTP_DISPOSITION_CONSUME; | 1709 | return SCTP_DISPOSITION_CONSUME; |
1715 | 1710 | ||
1716 | nomem_ev: | ||
1717 | sctp_chunk_free(repl); | ||
1718 | nomem: | 1711 | nomem: |
1719 | return SCTP_DISPOSITION_NOMEM; | 1712 | return SCTP_DISPOSITION_NOMEM; |
1720 | } | 1713 | } |