Print this page
OS-4647 lx fails to mount nfs share - Transport endpoint is already connected
        
@@ -1581,10 +1581,15 @@
                 case UDP_RCVHDR:
                         mutex_enter(&connp->conn_lock);
                         *i1 = udp->udp_rcvhdr ? 1 : 0;
                         mutex_exit(&connp->conn_lock);
                         return (sizeof (int));
+                case UDP_SND_TO_CONNECTED:
+                        mutex_enter(&connp->conn_lock);
+                        *i1 = udp->udp_snd_to_conn ? 1 : 0;
+                        mutex_exit(&connp->conn_lock);
+                        return (sizeof (int));
                 }
         }
         mutex_enter(&connp->conn_lock);
         retval = conn_opt_get(&coas, level, name, ptr);
         mutex_exit(&connp->conn_lock);
@@ -1716,10 +1721,15 @@
                 case UDP_RCVHDR:
                         mutex_enter(&connp->conn_lock);
                         udp->udp_rcvhdr = onoff;
                         mutex_exit(&connp->conn_lock);
                         return (0);
+                case UDP_SND_TO_CONNECTED:
+                        mutex_enter(&connp->conn_lock);
+                        udp->udp_snd_to_conn = onoff;
+                        mutex_exit(&connp->conn_lock);
+                        return (0);
                 }
                 break;
         }
         error = conn_opt_set(coa, level, name, inlen, invalp,
             checkonly, cr);
@@ -5908,10 +5918,11 @@
         int             error = 0;
         udp_stack_t     *us = udp->udp_us;
         ushort_t        ipversion;
         pid_t           pid = curproc->p_pid;
         ip_xmit_attr_t  *ixa;
+        boolean_t       snd_to_conn;
 
         ASSERT(DB_TYPE(mp) == M_DATA);
 
         /* All Solaris components should pass a cred for this operation. */
         ASSERT(cr != NULL);
@@ -5945,14 +5956,25 @@
                 if (us->us_sendto_ignerr)
                         return (0);
                 else
                         return (error);
         }
-        if (udp->udp_state == TS_DATA_XFER) {
+
+        /*
+         * Check if we're allowed to send to a connection on which we've
+         * already called 'connect'. The posix spec. allows both behaviors but
+         * historically we've returned an error if already connected. The
+         * client can allow this via a sockopt.
+         */
+        mutex_enter(&connp->conn_lock);
+        snd_to_conn = (udp->udp_snd_to_conn != 0);
+        mutex_exit(&connp->conn_lock);
+        if (udp->udp_state == TS_DATA_XFER && !snd_to_conn) {
                 UDPS_BUMP_MIB(us, udpOutErrors);
                 return (EISCONN);
         }
+
         error = proto_verify_ip_addr(connp->conn_family,
             (struct sockaddr *)msg->msg_name, msg->msg_namelen);
         if (error != 0) {
                 UDPS_BUMP_MIB(us, udpOutErrors);
                 return (error);