diff options
author | tuexen <tuexen@FreeBSD.org> | 2015-06-12 16:01:41 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2015-06-12 16:01:41 +0000 |
commit | 9532b4863e03e26ef6172a50a91dcf19783a687f (patch) | |
tree | d4c426e100bbd99bf64f134d1b0ae9247951cdab | |
parent | fd66a5bf8bec61b5fd13d722a18301702fb28be3 (diff) | |
download | FreeBSD-src-9532b4863e03e26ef6172a50a91dcf19783a687f.zip FreeBSD-src-9532b4863e03e26ef6172a50a91dcf19783a687f.tar.gz |
In case of an output error, continue with the next net, don't try to
continue sending on the same net.
This fixes a bug where an invalid mbuf chain was constructed, if a
full size frame of control chunks should be sent and there is a
output error.
Based on a discussion with rrs@, change move to the next net. This fixes
the bug and improves the behaviour.
Thanks to Irene Ruengeler for spending a lot of time in narrowing this
problem down.
MFC after: 3 days
-rw-r--r-- | sys/netinet/sctp_output.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 515ee13..d1c6fac 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -7985,6 +7985,7 @@ again_one_more_time: } else { r_mtu = mtu; } + error = 0; /************************/ /* ASCONF transmission */ /************************/ @@ -8143,7 +8144,7 @@ again_one_more_time: sctp_move_chunks_from_net(stcb, net); } *reason_code = 7; - continue; + break; } else asoc->ifp_had_enobuf = 0; if (*now_filled == 0) { @@ -8186,6 +8187,10 @@ again_one_more_time: } } } + if (error != 0) { + /* try next net */ + continue; + } /************************/ /* Control transmission */ /************************/ @@ -8420,7 +8425,7 @@ again_one_more_time: sctp_move_chunks_from_net(stcb, net); } *reason_code = 7; - continue; + break; } else asoc->ifp_had_enobuf = 0; /* Only HB or ASCONF advances time */ @@ -8466,6 +8471,10 @@ again_one_more_time: } } } + if (error != 0) { + /* try next net */ + continue; + } /* JRI: if dest is in PF state, do not send data to it */ if ((asoc->sctp_cmt_on_off > 0) && (net != stcb->asoc.alternate) && |