Print this page
OS-4647 lx fails to mount nfs share - Transport endpoint is already connected

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/udp/udp.c
          +++ new/usr/src/uts/common/inet/udp/udp.c
↓ open down ↓ 1575 lines elided ↑ open up ↑
1576 1576                  case UDP_NAT_T_ENDPOINT:
1577 1577                          mutex_enter(&connp->conn_lock);
1578 1578                          *i1 = udp->udp_nat_t_endpoint;
1579 1579                          mutex_exit(&connp->conn_lock);
1580 1580                          return (sizeof (int));
1581 1581                  case UDP_RCVHDR:
1582 1582                          mutex_enter(&connp->conn_lock);
1583 1583                          *i1 = udp->udp_rcvhdr ? 1 : 0;
1584 1584                          mutex_exit(&connp->conn_lock);
1585 1585                          return (sizeof (int));
     1586 +                case UDP_SND_TO_CONNECTED:
     1587 +                        mutex_enter(&connp->conn_lock);
     1588 +                        *i1 = udp->udp_snd_to_conn ? 1 : 0;
     1589 +                        mutex_exit(&connp->conn_lock);
     1590 +                        return (sizeof (int));
1586 1591                  }
1587 1592          }
1588 1593          mutex_enter(&connp->conn_lock);
1589 1594          retval = conn_opt_get(&coas, level, name, ptr);
1590 1595          mutex_exit(&connp->conn_lock);
1591 1596          return (retval);
1592 1597  }
1593 1598  
1594 1599  /*
1595 1600   * This routine retrieves the current status of socket options.
↓ open down ↓ 115 lines elided ↑ open up ↑
1711 1716                                  coa->coa_changed |= COA_HEADER_CHANGED;
1712 1717                                  coa->coa_changed |= COA_WROFF_CHANGED;
1713 1718                          }
1714 1719                          /* Fully handled this option. */
1715 1720                          return (0);
1716 1721                  case UDP_RCVHDR:
1717 1722                          mutex_enter(&connp->conn_lock);
1718 1723                          udp->udp_rcvhdr = onoff;
1719 1724                          mutex_exit(&connp->conn_lock);
1720 1725                          return (0);
     1726 +                case UDP_SND_TO_CONNECTED:
     1727 +                        mutex_enter(&connp->conn_lock);
     1728 +                        udp->udp_snd_to_conn = onoff;
     1729 +                        mutex_exit(&connp->conn_lock);
     1730 +                        return (0);
1721 1731                  }
1722 1732                  break;
1723 1733          }
1724 1734          error = conn_opt_set(coa, level, name, inlen, invalp,
1725 1735              checkonly, cr);
1726 1736          return (error);
1727 1737  }
1728 1738  
1729 1739  /*
1730 1740   * This routine sets socket options.
↓ open down ↓ 4172 lines elided ↑ open up ↑
5903 5913          sin6_t          *sin6;
5904 5914          sin_t           *sin = NULL;
5905 5915          uint_t          srcid;
5906 5916          conn_t          *connp = (conn_t *)proto_handle;
5907 5917          udp_t           *udp = connp->conn_udp;
5908 5918          int             error = 0;
5909 5919          udp_stack_t     *us = udp->udp_us;
5910 5920          ushort_t        ipversion;
5911 5921          pid_t           pid = curproc->p_pid;
5912 5922          ip_xmit_attr_t  *ixa;
     5923 +        boolean_t       snd_to_conn;
5913 5924  
5914 5925          ASSERT(DB_TYPE(mp) == M_DATA);
5915 5926  
5916 5927          /* All Solaris components should pass a cred for this operation. */
5917 5928          ASSERT(cr != NULL);
5918 5929  
5919 5930          /* do an implicit bind if necessary */
5920 5931          if (udp->udp_state == TS_UNBND) {
5921 5932                  error = udp_implicit_bind(connp, cr);
5922 5933                  /*
↓ open down ↓ 17 lines elided ↑ open up ↑
5940 5951                          error = udp_output_ancillary(connp, NULL, NULL, mp,
5941 5952                              NULL, msg, cr, pid);
5942 5953                  } else {
5943 5954                          error = udp_output_connected(connp, mp, cr, pid);
5944 5955                  }
5945 5956                  if (us->us_sendto_ignerr)
5946 5957                          return (0);
5947 5958                  else
5948 5959                          return (error);
5949 5960          }
5950      -        if (udp->udp_state == TS_DATA_XFER) {
     5961 +
     5962 +        /*
     5963 +         * Check if we're allowed to send to a connection on which we've
     5964 +         * already called 'connect'. The posix spec. allows both behaviors but
     5965 +         * historically we've returned an error if already connected. The
     5966 +         * client can allow this via a sockopt.
     5967 +         */
     5968 +        mutex_enter(&connp->conn_lock);
     5969 +        snd_to_conn = (udp->udp_snd_to_conn != 0);
     5970 +        mutex_exit(&connp->conn_lock);
     5971 +        if (udp->udp_state == TS_DATA_XFER && !snd_to_conn) {
5951 5972                  UDPS_BUMP_MIB(us, udpOutErrors);
5952 5973                  return (EISCONN);
5953 5974          }
     5975 +
5954 5976          error = proto_verify_ip_addr(connp->conn_family,
5955 5977              (struct sockaddr *)msg->msg_name, msg->msg_namelen);
5956 5978          if (error != 0) {
5957 5979                  UDPS_BUMP_MIB(us, udpOutErrors);
5958 5980                  return (error);
5959 5981          }
5960 5982          switch (connp->conn_family) {
5961 5983          case AF_INET6:
5962 5984                  sin6 = (sin6_t *)msg->msg_name;
5963 5985  
↓ open down ↓ 499 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX