From 6dac06847559a77b0b65d71ae92a248c9d3c5cd6 Mon Sep 17 00:00:00 2001 From: tuexen Date: Fri, 4 May 2012 17:18:02 +0000 Subject: [PATCH] Add support for the SCTP_ENABLE_STREAM_RESET socket option to getsockopt(). This improves the support of RFC 6525. MFC after: 3 days --- sys/netinet/sctp_usrreq.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 652364147afb..3d415c753c5d 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -3296,6 +3296,33 @@ flags_out: } break; } + case SCTP_ENABLE_STREAM_RESET: + { + struct sctp_assoc_value *av; + + SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); + SCTP_FIND_STCB(inp, stcb, av->assoc_id); + + if (stcb) { + av->assoc_value = (uint32_t) stcb->asoc.local_strreset_support; + SCTP_TCB_UNLOCK(stcb); + } else { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || + (av->assoc_id == SCTP_FUTURE_ASSOC)) { + SCTP_INP_RLOCK(inp); + av->assoc_value = (uint32_t) inp->local_strreset_support; + SCTP_INP_RUNLOCK(inp); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + } + if (error == 0) { + *optsize = sizeof(struct sctp_assoc_value); + } + break; + } default: SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); error = ENOPROTOOPT; @@ -4096,7 +4123,6 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, case SCTP_ENABLE_STREAM_RESET: { struct sctp_assoc_value *av; - uint8_t set_value = 0; SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); if (av->assoc_value & (~SCTP_ENABLE_VALUE_MASK)) { @@ -4104,10 +4130,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, error = EINVAL; break; } - set_value = av->assoc_value & SCTP_ENABLE_VALUE_MASK; SCTP_FIND_STCB(inp, stcb, av->assoc_id); if (stcb) { - stcb->asoc.local_strreset_support = set_value; + stcb->asoc.local_strreset_support = (uint8_t) av->assoc_value; SCTP_TCB_UNLOCK(stcb); } else { if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || @@ -4115,7 +4140,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, (av->assoc_id == SCTP_FUTURE_ASSOC) || (av->assoc_id == SCTP_ALL_ASSOC)) { SCTP_INP_WLOCK(inp); - inp->local_strreset_support = set_value; + inp->local_strreset_support = (uint8_t) av->assoc_value; SCTP_INP_WUNLOCK(inp); } if ((av->assoc_id == SCTP_CURRENT_ASSOC) || @@ -4123,7 +4148,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_INP_RLOCK(inp); LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { SCTP_TCB_LOCK(stcb); - stcb->asoc.local_strreset_support = set_value; + stcb->asoc.local_strreset_support = (uint8_t) av->assoc_value; SCTP_TCB_UNLOCK(stcb); } SCTP_INP_RUNLOCK(inp);