diff options
| -rw-r--r-- | usr/src/cmd/truss/print.c | 1 | ||||
| -rw-r--r-- | usr/src/lib/libnsl/rpc/svc_generic.c | 8 | ||||
| -rw-r--r-- | usr/src/lib/libnsl/rpc/ti_opts.c | 1 | ||||
| -rw-r--r-- | usr/src/lib/libsocket/inet/rcmd.c | 10 | ||||
| -rw-r--r-- | usr/src/uts/common/inet/sctp/sctp_hash.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/inet/tcp/tcp.c | 40 | ||||
| -rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_opt_data.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/inet/udp/udp.c | 7 | ||||
| -rw-r--r-- | usr/src/uts/common/inet/udp/udp_opt_data.c | 1 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/socket.h | 1 |
10 files changed, 56 insertions, 17 deletions
diff --git a/usr/src/cmd/truss/print.c b/usr/src/cmd/truss/print.c index 99b64d354a..2438bf3ec7 100644 --- a/usr/src/cmd/truss/print.c +++ b/usr/src/cmd/truss/print.c @@ -1759,6 +1759,7 @@ sol_optname(private_t *pri, long val) case SO_TYPE: return ("SO_TYPE"); case SO_PROTOTYPE: return ("SO_PROTOTYPE"); case SO_ALLZONES: return ("SO_ALLZONES"); + case SO_EXCLBIND: return ("SO_EXCLBIND"); default: (void) snprintf(pri->code_buf, CBSIZE, "0x%lx", val); diff --git a/usr/src/lib/libnsl/rpc/svc_generic.c b/usr/src/lib/libnsl/rpc/svc_generic.c index a0673e43c8..553a6390b6 100644 --- a/usr/src/lib/libnsl/rpc/svc_generic.c +++ b/usr/src/lib/libnsl/rpc/svc_generic.c @@ -340,7 +340,7 @@ svc_tli_create_common(const int ofd, const struct netconfig *nconf, } /* - * {TCP,UDP}_EXCLBIND has the following properties + * SO_EXCLBIND has the following properties * - an fd bound to port P via IPv4 will prevent an IPv6 * bind to port P (and vice versa) * - an fd bound to a wildcard IP address for port P will @@ -355,10 +355,8 @@ svc_tli_create_common(const int ofd, const struct netconfig *nconf, (tcp || (strcmp(nconf->nc_proto, NC_UDP) == 0)) && rpc_control(__RPC_SVC_EXCLBIND_GET, &exclbind)) { if (exclbind) { - if (__rpc_tli_set_options(fd, - tcp ? IPPROTO_TCP : IPPROTO_UDP, - tcp ? TCP_EXCLBIND : UDP_EXCLBIND, - 1) < 0) { + if (__rpc_tli_set_options(fd, SOL_SOCKET, + SO_EXCLBIND, 1) < 0) { syslog(LOG_ERR, "svc_tli_create: can't set EXCLBIND [netid='%s']", nconf->nc_netid); diff --git a/usr/src/lib/libnsl/rpc/ti_opts.c b/usr/src/lib/libnsl/rpc/ti_opts.c index ae32fa9788..f01984eabc 100644 --- a/usr/src/lib/libnsl/rpc/ti_opts.c +++ b/usr/src/lib/libnsl/rpc/ti_opts.c @@ -494,6 +494,7 @@ __rpc_tli_set_options(int fd, int optlevel, int optname, int optval) case SO_RECVUCRED: case SO_ANON_MLP: case SO_MAC_EXEMPT: + case SO_EXCLBIND: case TCP_EXCLBIND: case UDP_EXCLBIND: /* LINTED */ diff --git a/usr/src/lib/libsocket/inet/rcmd.c b/usr/src/lib/libsocket/inet/rcmd.c index 0bfecc28c6..5cb0fb674f 100644 --- a/usr/src/lib/libsocket/inet/rcmd.c +++ b/usr/src/lib/libsocket/inet/rcmd.c @@ -444,10 +444,10 @@ _rresvport_addr(int *alport, struct sockaddr_storage *addr) return (-1); /* - * Set TCP_EXCLBIND to get a "unique" port, which is not bound + * Set SO_EXCLBIND to get a "unique" port, which is not bound * to any other sockets. */ - if (setsockopt(s, IPPROTO_TCP, TCP_EXCLBIND, &on, sizeof (on)) < 0) { + if (setsockopt(s, SOL_SOCKET, SO_EXCLBIND, &on, sizeof (on)) < 0) { (void) close(s); return (-1); } @@ -460,8 +460,8 @@ _rresvport_addr(int *alport, struct sockaddr_storage *addr) sin6->sin6_port = htons((ushort_t)*alport); } if (bind(s, (struct sockaddr *)addr, len) >= 0) { - /* To be safe, need to turn off TCP_EXCLBIND. */ - (void) setsockopt(s, IPPROTO_TCP, TCP_EXCLBIND, &off, + /* To be safe, need to turn off SO_EXCLBIND. */ + (void) setsockopt(s, SOL_SOCKET, SO_EXCLBIND, &off, sizeof (off)); return (s); } @@ -510,7 +510,7 @@ _rresvport_addr(int *alport, struct sockaddr_storage *addr) */ (void) setsockopt(s, IPPROTO_TCP, TCP_ANONPRIVBIND, &off, sizeof (off)); - (void) setsockopt(s, IPPROTO_TCP, TCP_EXCLBIND, &off, + (void) setsockopt(s, SOL_SOCKET, SO_EXCLBIND, &off, sizeof (off)); return (s); } diff --git a/usr/src/uts/common/inet/sctp/sctp_hash.c b/usr/src/uts/common/inet/sctp/sctp_hash.c index ff21e9c950..606448d6a3 100644 --- a/usr/src/uts/common/inet/sctp/sctp_hash.c +++ b/usr/src/uts/common/inet/sctp/sctp_hash.c @@ -456,7 +456,7 @@ ip_fanout_sctp(mblk_t *mp, ill_t *recv_ill, ipha_t *ipha, } if ((connp = sctp_fanout(src, dst, ports, ipif_seqid, zoneid, mp)) == NULL) { - ip_fanout_sctp_raw(mp, recv_ill, ipha, isv4, + ip_fanout_sctp_raw(first_mp, recv_ill, ipha, isv4, ports, mctl_present, flags, ip_policy, ipif_seqid, zoneid); return; diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c index ea0175f165..5c34200c3f 100644 --- a/usr/src/uts/common/inet/tcp/tcp.c +++ b/usr/src/uts/common/inet/tcp/tcp.c @@ -3500,6 +3500,9 @@ tcp_bindi(tcp_t *tcp, in_port_t port, const in6_addr_t *laddr, mutex_enter(&tbf->tf_lock); for (ltcp = tbf->tf_tcp; ltcp != NULL; ltcp = ltcp->tcp_bind_hash) { + boolean_t not_socket; + boolean_t exclbind; + if (lport != ltcp->tcp_lport) continue; @@ -3533,7 +3536,7 @@ tcp_bindi(tcp_t *tcp, in_port_t port, const in6_addr_t *laddr, * spec spec yes if A * * For labeled systems, SO_MAC_EXEMPT behaves the same - * as UDP_EXCLBIND, except that zoneid is ignored. + * as TCP_EXCLBIND, except that zoneid is ignored. * * Note: * @@ -3558,12 +3561,18 @@ tcp_bindi(tcp_t *tcp, in_port_t port, const in6_addr_t *laddr, * TCPS_LISTEN and both endpoints have SO_REUSEADDR * set, let the bind succeed. * - * But because of (1), we cannot do that now. If - * in future, we can change this going back semantics, - * we can add the above check. + * Because of (1), we cannot do that for TLI + * endpoints. But we can do that for socket endpoints. + * If in future, we can change this going back + * semantics, we can use the above check for TLI also. */ - if (ltcp->tcp_exclbind || tcp->tcp_exclbind || - lconnp->conn_mac_exempt || connp->conn_mac_exempt) { + not_socket = !(TCP_IS_SOCKET(ltcp) && + TCP_IS_SOCKET(tcp)); + exclbind = ltcp->tcp_exclbind || tcp->tcp_exclbind; + + if (lconnp->conn_mac_exempt || connp->conn_mac_exempt || + (exclbind && (not_socket || + ltcp->tcp_state <= TCPS_ESTABLISHED))) { if (V6_OR_V4_INADDR_ANY( ltcp->tcp_bound_source_v6) || V6_OR_V4_INADDR_ANY(*laddr) || @@ -9599,6 +9608,9 @@ tcp_opt_get(queue_t *q, int level, int name, uchar_t *ptr) case SO_MAC_EXEMPT: *i1 = connp->conn_mac_exempt; break; + case SO_EXCLBIND: + *i1 = tcp->tcp_exclbind ? SO_EXCLBIND : 0; + break; default: return (-1); } @@ -10098,6 +10110,10 @@ tcp_opt_set(queue_t *q, uint_t optset_context, int level, int name, mutex_exit(&connp->conn_lock); } break; + case SO_EXCLBIND: + if (!checkonly) + tcp->tcp_exclbind = onoff; + break; default: *outlenp = 0; return (EINVAL); @@ -14332,6 +14348,12 @@ est: case TCPS_CLOSING: if (tcp->tcp_fin_acked) { tcp->tcp_state = TCPS_TIME_WAIT; + /* + * Unconditionally clear the exclusive binding + * bit so this TIME-WAIT connection won't + * interfere with new ones. + */ + tcp->tcp_exclbind = 0; if (!TCP_IS_DETACHED(tcp)) { TCP_TIMER_RESTART(tcp, tcp_time_wait_interval); @@ -14381,6 +14403,12 @@ est: /* FALLTHRU */ case TCPS_FIN_WAIT_2: tcp->tcp_state = TCPS_TIME_WAIT; + /* + * Unconditionally clear the exclusive binding + * bit so this TIME-WAIT connection won't + * interfere with new ones. + */ + tcp->tcp_exclbind = 0; if (!TCP_IS_DETACHED(tcp)) { TCP_TIMER_RESTART(tcp, tcp_time_wait_interval); diff --git a/usr/src/uts/common/inet/tcp/tcp_opt_data.c b/usr/src/uts/common/inet/tcp/tcp_opt_data.c index 350ff7ec30..468424f1ff 100644 --- a/usr/src/uts/common/inet/tcp/tcp_opt_data.c +++ b/usr/src/uts/common/inet/tcp/tcp_opt_data.c @@ -80,6 +80,8 @@ opdes_t tcp_opt_arr[] = { 0 }, { SO_ALLZONES, SOL_SOCKET, OA_R, OA_RW, OP_CONFIG, OP_PASSNEXT, sizeof (int), 0 }, +{ SO_EXCLBIND, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 }, + { TCP_NODELAY, IPPROTO_TCP, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 }, { TCP_MAXSEG, IPPROTO_TCP, OA_R, OA_R, OP_NP, OP_PASSNEXT, sizeof (uint_t), diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c index b1b6e99445..9206d72a4b 100644 --- a/usr/src/uts/common/inet/udp/udp.c +++ b/usr/src/uts/common/inet/udp/udp.c @@ -3129,6 +3129,9 @@ udp_opt_get(queue_t *q, t_scalar_t level, t_scalar_t name, uchar_t *ptr) case SO_ALLZONES: *i1 = connp->conn_allzones; break; /* goto sizeof (int) option return */ + case SO_EXCLBIND: + *i1 = udp->udp_exclbind ? SO_EXCLBIND : 0; + break; default: return (-1); } @@ -3555,6 +3558,10 @@ udp_opt_set(queue_t *q, uint_t optset_context, int level, } break; } + case SO_EXCLBIND: + if (!checkonly) + udp->udp_exclbind = onoff; + break; default: *outlenp = 0; return (EINVAL); diff --git a/usr/src/uts/common/inet/udp/udp_opt_data.c b/usr/src/uts/common/inet/udp/udp_opt_data.c index 0ac5bb9a62..1d2ccf7259 100644 --- a/usr/src/uts/common/inet/udp/udp_opt_data.c +++ b/usr/src/uts/common/inet/udp/udp_opt_data.c @@ -80,6 +80,7 @@ opdes_t udp_opt_arr[] = { { SO_MAC_EXEMPT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 }, { SCM_UCRED, SOL_SOCKET, OA_W, OA_W, OP_NP, OP_VARLEN|OP_NODEFAULT, 512, 0 }, +{ SO_EXCLBIND, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 }, { IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, (OP_PASSNEXT|OP_VARLEN|OP_NODEFAULT), 40, -1 /* not initialized */ }, diff --git a/usr/src/uts/common/sys/socket.h b/usr/src/uts/common/sys/socket.h index 2d6b58d8c3..7cdcd5b84c 100644 --- a/usr/src/uts/common/sys/socket.h +++ b/usr/src/uts/common/sys/socket.h @@ -154,6 +154,7 @@ typedef void *_RESTRICT_KYWD Psocklen_t; #define SCM_TIMESTAMP SO_TIMESTAMP /* socket control message timestamp */ #define SO_ALLZONES 0x1014 /* bind in all zones */ +#define SO_EXCLBIND 0x1015 /* exclusive binding */ #ifdef _KERNEL #define SO_SRCADDR 0x2001 /* Internal: AF_UNIX source address */ |
