diff options
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r-- | net/sctp/sm_statefuns.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index d3f1ea460c50..c8f606324134 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -1775,9 +1775,22 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net, | |||
1775 | /* Update the content of current association. */ | 1775 | /* Update the content of current association. */ |
1776 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); | 1776 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); |
1777 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | 1777 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); |
1778 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 1778 | if (sctp_state(asoc, SHUTDOWN_PENDING) && |
1779 | SCTP_STATE(SCTP_STATE_ESTABLISHED)); | 1779 | (sctp_sstate(asoc->base.sk, CLOSING) || |
1780 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | 1780 | sock_flag(asoc->base.sk, SOCK_DEAD))) { |
1781 | /* if were currently in SHUTDOWN_PENDING, but the socket | ||
1782 | * has been closed by user, don't transition to ESTABLISHED. | ||
1783 | * Instead trigger SHUTDOWN bundled with COOKIE_ACK. | ||
1784 | */ | ||
1785 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
1786 | return sctp_sf_do_9_2_start_shutdown(net, ep, asoc, | ||
1787 | SCTP_ST_CHUNK(0), NULL, | ||
1788 | commands); | ||
1789 | } else { | ||
1790 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | ||
1791 | SCTP_STATE(SCTP_STATE_ESTABLISHED)); | ||
1792 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
1793 | } | ||
1781 | return SCTP_DISPOSITION_CONSUME; | 1794 | return SCTP_DISPOSITION_CONSUME; |
1782 | 1795 | ||
1783 | nomem_ev: | 1796 | nomem_ev: |