diff options
author | kcpoon <none@none> | 2006-07-24 23:50:09 -0700 |
---|---|---|
committer | kcpoon <none@none> | 2006-07-24 23:50:09 -0700 |
commit | ae347574c7f17d33bb822cb146d7f67c88ab1f68 (patch) | |
tree | 32acd48faeb75f69fb5f1433a4a9613b76d042ed /usr/src/uts/common/inet/tcp/tcp.c | |
parent | b0f490f41a437c14fba5163cca1e65686e66c84b (diff) | |
download | illumos-joyent-ae347574c7f17d33bb822cb146d7f67c88ab1f68.tar.gz |
PSARC 2006/407 SO_EXCLBIND, socket exclusive binding
6410719 ASSERT() panic in ipsec_in_is_secure()
6442609 TCP_EXCLBIND handling has problem with server restarting
6445396 Add SO_EXCLBIND socket option
Diffstat (limited to 'usr/src/uts/common/inet/tcp/tcp.c')
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp.c | 40 |
1 files changed, 34 insertions, 6 deletions
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); |