[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>
This commit is contained in:
committed by
David S. Miller
parent
827bf12236
commit
07d9396771
@@ -1656,7 +1656,6 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
|
||||
struct sctp_association *new_asoc)
|
||||
{
|
||||
sctp_init_chunk_t *peer_init;
|
||||
struct sctp_ulpevent *ev;
|
||||
struct sctp_chunk *repl;
|
||||
|
||||
/* 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,
|
||||
* D) IMPLEMENTATION NOTE: An implementation may choose to
|
||||
* send the Communication Up notification to the SCTP user
|
||||
* upon reception of a valid COOKIE ECHO chunk.
|
||||
*
|
||||
* Sadly, this needs to be implemented as a side-effect, because
|
||||
* we are not guaranteed to have set the association id of the real
|
||||
* association and so these notifications need to be delayed until
|
||||
* the association id is allocated.
|
||||
*/
|
||||
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP, 0,
|
||||
new_asoc->c.sinit_num_ostreams,
|
||||
new_asoc->c.sinit_max_instreams,
|
||||
NULL, GFP_ATOMIC);
|
||||
if (!ev)
|
||||
goto nomem_ev;
|
||||
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_CHANGE, SCTP_U8(SCTP_COMM_UP));
|
||||
|
||||
/* Sockets API Draft Section 5.3.1.6
|
||||
* When a peer sends a Adaptation Layer Indication parameter , SCTP
|
||||
* delivers this notification to inform the application that of the
|
||||
* peers requested adaptation layer.
|
||||
*
|
||||
* This also needs to be done as a side effect for the same reason as
|
||||
* above.
|
||||
*/
|
||||
if (asoc->peer.adaptation_ind) {
|
||||
ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
|
||||
if (!ev)
|
||||
goto nomem_ev;
|
||||
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
|
||||
SCTP_ULPEVENT(ev));
|
||||
}
|
||||
if (asoc->peer.adaptation_ind)
|
||||
sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL());
|
||||
|
||||
return SCTP_DISPOSITION_CONSUME;
|
||||
|
||||
nomem_ev:
|
||||
sctp_chunk_free(repl);
|
||||
nomem:
|
||||
return SCTP_DISPOSITION_NOMEM;
|
||||
}
|
||||
|
Reference in New Issue
Block a user