summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_sysctl.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2010-06-06 20:34:17 +0000
committerrrs <rrs@FreeBSD.org>2010-06-06 20:34:17 +0000
commit3bcf4834bbfb8c8c8023e0c832e654f827c1ff0d (patch)
treec75fb516496af43a786e1c0f886c80957c2cdcf8 /sys/netinet/sctp_sysctl.c
parent6bf375889db714097da8272c8ad55ea17dc466ae (diff)
downloadFreeBSD-src-3bcf4834bbfb8c8c8023e0c832e654f827c1ff0d.zip
FreeBSD-src-3bcf4834bbfb8c8c8023e0c832e654f827c1ff0d.tar.gz
1) Optimize the cleanup and don't always depend on
the timer. This is done by considering the locks we will destroy and if they are contended we consider it the same as a reference count being up. Fixing this appears to cleanup another crash that was appearing with all the timers where the socket buf lock got corrupted. 2) Fix the sysctl code to take a lot more care when looking at INP's that are in the GONE or ALLGONE state. MFC after: 1 week
Diffstat (limited to 'sys/netinet/sctp_sysctl.c')
-rw-r--r--sys/netinet/sctp_sysctl.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index c9967ea..9ba7dd4 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -331,6 +331,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
struct xsctp_inpcb xinpcb;
struct xsctp_tcb xstcb;
struct xsctp_raddr xraddr;
+ struct socket *so;
number_of_endpoints = 0;
number_of_local_addresses = 0;
@@ -369,6 +370,10 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
}
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
SCTP_INP_RLOCK(inp);
+ if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
+ /* if its allgone it is being freed - skip it */
+ goto skip;
+ }
xinpcb.last = 0;
xinpcb.local_port = ntohs(inp->sctp_lport);
xinpcb.flags = inp->sctp_flags;
@@ -377,13 +382,14 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
xinpcb.total_recvs = inp->total_recvs;
xinpcb.total_nospaces = inp->total_nospaces;
xinpcb.fragmentation_point = inp->sctp_frag_point;
- if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
+ so = inp->sctp_socket;
+ if ((so == NULL) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
xinpcb.qlen = 0;
xinpcb.maxqlen = 0;
} else {
- xinpcb.qlen = inp->sctp_socket->so_qlen;
- xinpcb.maxqlen = inp->sctp_socket->so_qlimit;
+ xinpcb.qlen = so->so_qlen;
+ xinpcb.maxqlen = so->so_qlimit;
}
SCTP_INP_INCR_REF(inp);
SCTP_INP_RUNLOCK(inp);
@@ -501,6 +507,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
if (error) {
return error;
}
+skip:
SCTP_INP_INFO_RLOCK();
}
SCTP_INP_INFO_RUNLOCK();
OpenPOWER on IntegriCloud