Print this page
OS-4865 lxbrand async socket errors catch programs off guard
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4213 lxbrand should be able to set TCP_DEFER_ACCEPT after other socket operations
OS-3893 sendfile compat checks shouldn't be done in so_sendmblk
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
        
@@ -126,11 +126,11 @@
 so_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen,
     int flags, struct cred *cr)
 {
         int error;
 
-        SO_BLOCK_FALLBACK(so, SOP_BIND(so, name, namelen, flags, cr));
+        SO_BLOCK_FALLBACK_SAFE(so, SOP_BIND(so, name, namelen, flags, cr));
 
         ASSERT(flags == _SOBIND_XPG4_2 || flags == _SOBIND_SOCKBSD);
 
         /* X/Open requires this check */
         if ((so->so_state & SS_CANTSENDMORE) && !xnet_skip_checks) {
@@ -303,11 +303,11 @@
         /*
          * If there is a pending error, return error
          * This can happen if a non blocking operation caused an error.
          */
 
-        if (so->so_error != 0) {
+        if (so->so_error != 0 && (so->so_mode & SM_DEFERERR) == 0) {
                 mutex_enter(&so->so_lock);
                 error = sogeterr(so, B_TRUE);
                 mutex_exit(&so->so_lock);
                 if (error != 0)
                         goto done;
@@ -402,11 +402,11 @@
                 if (so->so_state & SS_CANTSENDMORE) {
                         error = EPIPE;
                         break;
                 }
 
-                if (so->so_error != 0) {
+                if (so->so_error != 0 && (so->so_mode & SM_DEFERERR) == 0) {
                         mutex_enter(&so->so_lock);
                         error = sogeterr(so, B_TRUE);
                         mutex_exit(&so->so_lock);
                         if (error != 0)
                                 break;
@@ -511,11 +511,11 @@
 
                 if (so->so_state & SS_CANTSENDMORE) {
                         error = EPIPE;
                         break;
                 }
-                if (so->so_error != 0) {
+                if (so->so_error != 0 && (so->so_mode & SM_DEFERERR) == 0) {
                         mutex_enter(&so->so_lock);
                         error = sogeterr(so, B_TRUE);
                         mutex_exit(&so->so_lock);
                         if (error != 0)
                                 break;
@@ -584,15 +584,10 @@
 {
         int error;
 
         SO_BLOCK_FALLBACK(so, SOP_SENDMBLK(so, msg, fflag, cr, mpp));
 
-        if ((so->so_mode & SM_SENDFILESUPP) == 0) {
-                SO_UNBLOCK_FALLBACK(so);
-                return (EOPNOTSUPP);
-        }
-
         error = so_sendmblk_impl(so, msg, fflag, cr, mpp, so->so_filter_top,
             B_FALSE);
 
         SO_UNBLOCK_FALLBACK(so);
 
@@ -651,11 +646,11 @@
 so_getsockname(struct sonode *so, struct sockaddr *addr,
     socklen_t *addrlen, struct cred *cr)
 {
         int error;
 
-        SO_BLOCK_FALLBACK(so, SOP_GETSOCKNAME(so, addr, addrlen, cr));
+        SO_BLOCK_FALLBACK_SAFE(so, SOP_GETSOCKNAME(so, addr, addrlen, cr));
 
         if (so->so_filter_active == 0 ||
             (error = sof_filter_getsockname(so, addr, addrlen, cr)) < 0)
                 error = (*so->so_downcalls->sd_getsockname)
                     (so->so_proto_handle, addr, addrlen, cr);
@@ -700,11 +695,11 @@
         int error = 0;
 
         if (level == SOL_FILTER)
                 return (sof_getsockopt(so, option_name, optval, optlenp, cr));
 
-        SO_BLOCK_FALLBACK(so,
+        SO_BLOCK_FALLBACK_SAFE(so,
             SOP_GETSOCKOPT(so, level, option_name, optval, optlenp, flags, cr));
 
         if ((so->so_filter_active == 0 ||
             (error = sof_filter_getsockopt(so, level, option_name, optval,
             optlenp, cr)) < 0) &&
@@ -789,11 +784,11 @@
         const void *opt = optval;
 
         if (level == SOL_FILTER)
                 return (sof_setsockopt(so, option_name, optval, optlen, cr));
 
-        SO_BLOCK_FALLBACK(so,
+        SO_BLOCK_FALLBACK_SAFE(so,
             SOP_SETSOCKOPT(so, level, option_name, optval, optlen, cr));
 
         /* X/Open requires this check */
         if (so->so_state & SS_CANTSENDMORE && !xnet_skip_checks) {
                 SO_UNBLOCK_FALLBACK(so);
@@ -874,11 +869,11 @@
 
         /*
          * If there is a pending error, return error
          * This can happen if a non blocking operation caused an error.
          */
-        if (so->so_error != 0) {
+        if (so->so_error != 0 && (so->so_mode & SM_DEFERERR) == 0) {
                 mutex_enter(&so->so_lock);
                 error = sogeterr(so, B_TRUE);
                 mutex_exit(&so->so_lock);
                 if (error != 0)
                         goto done;