aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/sctp_usrreq.c
diff options
context:
space:
mode:
authorRandall Stewart <rrs@FreeBSD.org>2009-02-03 11:04:03 +0000
committerRandall Stewart <rrs@FreeBSD.org>2009-02-03 11:04:03 +0000
commita99b67833a59fc0fa47cb4f0d73b1a0a14b26112 (patch)
treead3c3bea4fec4c5a81ac06bbcfcfc640edc88661 /sys/netinet/sctp_usrreq.c
parent2f4afd21257ea1672763722dae9109bbaced5548 (diff)
downloadsrc-a99b67833a59fc0fa47cb4f0d73b1a0a14b26112.tar.gz
src-a99b67833a59fc0fa47cb4f0d73b1a0a14b26112.zip
- Cleanup checksum code.
- Prepare for CRC offloading, add MIB counters (RS/MT). - Bugfix: Disable CRC computation for IPv6 addresses with local scope (MT). - Bugfix: Handle close() with SO_LINGER correctly when notifications are generated during the close() call(MT). - Bugfix: Generate DRY event when sender is dry during subscription. Only for 1-to-1 style sockets (RS/MT) - Bugfix: Put vtags for the correct amount of time into time-wait (MT). - Bugfix: Clear vtag entries correctly on expiration (MT). - Bugfix: shutdown() indicates ENOTCONN when called for unconnected 1-to-1 style sockets (MT). - Bugfix: In sctp Auth code (PL). - Add support for devices that support SCTP csum offload (igb). - Add missing sctp_associd to mib sysctl xsctp_tcb structure (RS) Obtained from: With help from Peter Lei and Michael Tuexen
Notes
Notes: svn path=/head/; revision=188067
Diffstat (limited to 'sys/netinet/sctp_usrreq.c')
-rw-r--r--sys/netinet/sctp_usrreq.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index c6427629f145..9d04f56e78dc 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -908,6 +908,7 @@ sctp_disconnect(struct socket *so)
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
}
}
+ soisdisconnecting(so);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_RUNLOCK(inp);
return (0);
@@ -980,6 +981,11 @@ sctp_shutdown(struct socket *so)
struct sctp_tcb *stcb;
struct sctp_association *asoc;
+ if ((so->so_state &
+ (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) {
+ SCTP_INP_RUNLOCK(inp);
+ return (ENOTCONN);
+ }
socantsendmore(so);
stcb = LIST_FIRST(&inp->sctp_asoc_list);
@@ -3515,6 +3521,22 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
if (events->sctp_sender_dry_event) {
sctp_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT);
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+ (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
+ stcb = LIST_FIRST(&inp->sctp_asoc_list);
+ if (stcb) {
+ SCTP_TCB_LOCK(stcb);
+ }
+ if (stcb &&
+ TAILQ_EMPTY(&stcb->asoc.send_queue) &&
+ TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
+ (stcb->asoc.stream_queue_cnt == 0)) {
+ sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED);
+ }
+ if (stcb) {
+ SCTP_TCB_UNLOCK(stcb);
+ }
+ }
} else {
sctp_feature_off(inp, SCTP_PCB_FLAGS_DRYEVNT);
}