aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_sideeffect.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-05-04 16:55:27 -0400
committerDavid S. Miller <davem@davemloft.net>2007-05-04 16:55:27 -0400
commit07d939677166cc4f000c767196872a9becc2697b (patch)
treebef3d3c75ac3dd56813adbc63281feb4195a5b47 /net/sctp/sm_sideeffect.c
parent827bf12236fbafc02bc899aec1b37c342c8cf4e5 (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.c35
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 */
866static 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 */
881static 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);