summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorss146032 <none@none>2007-10-19 04:21:19 -0700
committerss146032 <none@none>2007-10-19 04:21:19 -0700
commit54417eb34f6d4715c3a6c4f674437735278484eb (patch)
tree536718d149460393c049c7e1ba911c5adfde5386 /usr/src
parent801d74ddb3d063919e6cf7c6eb3ddc2591c3921d (diff)
downloadillumos-joyent-54417eb34f6d4715c3a6c4f674437735278484eb.tar.gz
6554681 SCTP accept(3SOCKET) do not always set remote IP address when returning > 0
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/sockfs/socksctp.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/usr/src/uts/common/fs/sockfs/socksctp.c b/usr/src/uts/common/fs/sockfs/socksctp.c
index 0c77f33096..fbaf68195e 100644
--- a/usr/src/uts/common/fs/sockfs/socksctp.c
+++ b/usr/src/uts/common/fs/sockfs/socksctp.c
@@ -521,8 +521,29 @@ sosctp_accept(struct sonode *lso, int fflag, struct sonode **nsop)
/*
* accept() needs remote address right away.
+ * since sosctp_getpeername() is called with
+ * socket lock released, the connection may
+ * get aborted before we return from the
+ * routine. So, we need to to handle aborted
+ * socket connection here.
*/
- (void) sosctp_getpeername(nso);
+ error = sosctp_getpeername(nso);
+ if (error != 0) {
+ vnode_t *nvp;
+ nvp = SOTOV(nso);
+ (void) VOP_CLOSE(nvp, 0, 1, 0, CRED());
+ VN_RELE(nvp);
+
+ /*
+ * We can't return ENOTCONN to accept. accept
+ * either returns connected socket in case no error
+ * has occured or the connection which is getting
+ * accepted is being aborted. This is the reason we
+ * return ECONNABORTED in case sosctp_getpeername()
+ * returns ENOTCONN.
+ */
+ return ((error == ENOTCONN) ? ECONNABORTED : error);
+ }
dprint(2, ("sosctp_accept: new %p\n", nso));