Fix a bug where messages would not be sent in SHUTDOWN_RECEIVED state.
This problem was reported by Mark Bonnekessel and Markus Boese. Thanks to Irene Ruengeler for helping me to fix the cause of the problem. It can be tested with the following packetdrill script: +0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3 +0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) +0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 // Check the handshake with an empty(!) cookie +0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) +0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=0, ...] +0.1 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=10000, os=1, is=1, tsn=0, STATE_COOKIE[len=4, val=...]] +0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...] +0.1 < sctp: COOKIE_ACK[flgs=0] +0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 +0.0 write(3, ..., 1024) = 1024 +0.0 > sctp: DATA[flgs=BE, len=1040, tsn=0, sid=0, ssn=0, ppid=0] +0.0 write(3, ..., 1024) = 1024 // Pending due to Nagle +0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0] +0.0 > sctp: DATA[flgs=BE, len=1040, tsn=1, sid=0, ssn=1, ppid=0] +0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=10000, gaps=[], dups=[]] // Do we need another SHUTDOWN here? +0.0 > sctp: SHUTDOWN_ACK[flgs=0] +0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0] +0.0 close(3) = 0 MFC after: 3 days
This commit is contained in:
parent
a2c1487946
commit
70fa550b45
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=283662
@ -1977,7 +1977,8 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* sent when the state goes open.
|
||||
*/
|
||||
if (status == 0 &&
|
||||
SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
|
||||
((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
|
||||
#ifdef SCTP_TIMER_BASED_ASCONF
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
|
||||
stcb, stcb->asoc.primary_destination);
|
||||
@ -2225,7 +2226,8 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* count of queued params. If in the non-open
|
||||
* state, these get sent when the assoc goes open.
|
||||
*/
|
||||
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
|
||||
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
if (status >= 0) {
|
||||
num_queued++;
|
||||
}
|
||||
@ -2285,7 +2287,8 @@ sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
|
||||
"set_primary_ip_address_sa: queued on tcb=%p, ",
|
||||
(void *)stcb);
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
|
||||
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
|
||||
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
#ifdef SCTP_TIMER_BASED_ASCONF
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
|
||||
stcb->sctp_ep, stcb,
|
||||
@ -2321,7 +2324,8 @@ sctp_set_primary_ip_address(struct sctp_ifa *ifa)
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address: queued on stcb=%p, ",
|
||||
(void *)stcb);
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
|
||||
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
|
||||
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
#ifdef SCTP_TIMER_BASED_ASCONF
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
|
||||
stcb->sctp_ep, stcb,
|
||||
|
@ -8535,7 +8535,8 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
||||
omtu = 0;
|
||||
break;
|
||||
}
|
||||
if ((((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) &&
|
||||
if ((((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) &&
|
||||
(skip_data_for_this_net == 0)) ||
|
||||
(cookie)) {
|
||||
TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
|
||||
|
Loading…
Reference in New Issue
Block a user