|
@@ -1775,9 +1775,22 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net,
|
|
/* Update the content of current association. */
|
|
/* Update the content of current association. */
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
|
- sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
|
|
|
- SCTP_STATE(SCTP_STATE_ESTABLISHED));
|
|
|
|
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
|
|
|
|
|
+ if (sctp_state(asoc, SHUTDOWN_PENDING) &&
|
|
|
|
+ (sctp_sstate(asoc->base.sk, CLOSING) ||
|
|
|
|
+ sock_flag(asoc->base.sk, SOCK_DEAD))) {
|
|
|
|
+ /* if were currently in SHUTDOWN_PENDING, but the socket
|
|
|
|
+ * has been closed by user, don't transition to ESTABLISHED.
|
|
|
|
+ * Instead trigger SHUTDOWN bundled with COOKIE_ACK.
|
|
|
|
+ */
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
|
|
|
+ return sctp_sf_do_9_2_start_shutdown(net, ep, asoc,
|
|
|
|
+ SCTP_ST_CHUNK(0), NULL,
|
|
|
|
+ commands);
|
|
|
|
+ } else {
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
|
|
|
+ SCTP_STATE(SCTP_STATE_ESTABLISHED));
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
|
|
|
+ }
|
|
return SCTP_DISPOSITION_CONSUME;
|
|
return SCTP_DISPOSITION_CONSUME;
|
|
|
|
|
|
nomem_ev:
|
|
nomem_ev:
|