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_sideeffect.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_sideeffect.c')
-rw-r--r-- | net/sctp/sm_sideeffect.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index b37a7adeb150..d9fad4f6ffc3 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -862,6 +862,33 @@ static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error) | |||
862 | sk->sk_err = error; | 862 | sk->sk_err = error; |
863 | } | 863 | } |
864 | 864 | ||
865 | /* Helper function to generate an association change event */ | ||
866 | static void sctp_cmd_assoc_change(sctp_cmd_seq_t *commands, | ||
867 | struct sctp_association *asoc, | ||
868 | u8 state) | ||
869 | { | ||
870 | struct sctp_ulpevent *ev; | ||
871 | |||
872 | ev = sctp_ulpevent_make_assoc_change(asoc, 0, state, 0, | ||
873 | asoc->c.sinit_num_ostreams, | ||
874 | asoc->c.sinit_max_instreams, | ||
875 | NULL, GFP_ATOMIC); | ||
876 | if (ev) | ||
877 | sctp_ulpq_tail_event(&asoc->ulpq, ev); | ||
878 | } | ||
879 | |||
880 | /* Helper function to generate an adaptation indication event */ | ||
881 | static void sctp_cmd_adaptation_ind(sctp_cmd_seq_t *commands, | ||
882 | struct sctp_association *asoc) | ||
883 | { | ||
884 | struct sctp_ulpevent *ev; | ||
885 | |||
886 | ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC); | ||
887 | |||
888 | if (ev) | ||
889 | sctp_ulpq_tail_event(&asoc->ulpq, ev); | ||
890 | } | ||
891 | |||
865 | /* These three macros allow us to pull the debugging code out of the | 892 | /* These three macros allow us to pull the debugging code out of the |
866 | * main flow of sctp_do_sm() to keep attention focused on the real | 893 | * main flow of sctp_do_sm() to keep attention focused on the real |
867 | * functionality there. | 894 | * functionality there. |
@@ -1485,6 +1512,14 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1485 | case SCTP_CMD_SET_SK_ERR: | 1512 | case SCTP_CMD_SET_SK_ERR: |
1486 | sctp_cmd_set_sk_err(asoc, cmd->obj.error); | 1513 | sctp_cmd_set_sk_err(asoc, cmd->obj.error); |
1487 | break; | 1514 | break; |
1515 | case SCTP_CMD_ASSOC_CHANGE: | ||
1516 | sctp_cmd_assoc_change(commands, asoc, | ||
1517 | cmd->obj.u8); | ||
1518 | break; | ||
1519 | case SCTP_CMD_ADAPTATION_IND: | ||
1520 | sctp_cmd_adaptation_ind(commands, asoc); | ||
1521 | break; | ||
1522 | |||
1488 | default: | 1523 | default: |
1489 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1524 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
1490 | cmd->verb, cmd->obj.ptr); | 1525 | cmd->verb, cmd->obj.ptr); |