# HG changeset patch # User Anders Persson # Date 1276820639 25200 # Node ID 4f9a0cd40c5fa91d27a622f8e06607b4b579a1bb # Parent 044ff822d2127fececc2f735febc1897908edd94 6939100 convert KSSL into a socket filter diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/cmd/cmd-inet/usr.sbin/Makefile --- a/usr/src/cmd/cmd-inet/usr.sbin/Makefile Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/cmd/cmd-inet/usr.sbin/Makefile Thu Jun 17 17:23:59 2010 -0700 @@ -36,7 +36,7 @@ ndd $(SYNCPROG) $(DHCPPROG) $(XMODPROG) MANIFEST= rarp.xml telnet.xml comsat.xml finger.xml \ - login.xml shell.xml rexec.xml + login.xml shell.xml rexec.xml socket-filter-kssl.xml SVCMETHOD= svc-sockfilter ROOTFS_PROG= hostconfig route soconfig @@ -71,8 +71,8 @@ snoop sppptun traceroute wificonfig MSGSUBDIRS= bootconfchk htable ifconfig ilbadm in.ftpd in.routed in.talkd \ - inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils kssl/ksslcfg \ - nwamadm nwamcfg routeadm sppptun snoop wificonfig + inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils \ + kssl/ksslcfg nwamadm nwamcfg routeadm sppptun snoop wificonfig # As programs get lint-clean, add them here and to the 'lint' target. # Eventually this hack should go away, and all in PROG should be @@ -85,8 +85,9 @@ # with SUBDIRS. Also (sigh) deal with the commented-out build lines # for the lint rule. LINTSUBDIRS= bootconfchk ilbadm in.rdisc in.routed in.talkd inetadm \ - inetconv ipmpstat ipqosconf ipsecutils nwamadm nwamcfg ping \ - routeadm sppptun traceroute wificonfig + inetconv ipmpstat ipqosconf ipsecutils kssl/kssladm \ + kssl/ksslcfg nwamadm nwamcfg ping routeadm sppptun traceroute \ + wificonfig # And as programs are verified not to attempt to write into constants, # -xstrconst should be used to ensure they stay that way. CONSTCLEAN= diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml --- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml Thu Jun 17 17:23:59 2010 -0700 @@ -1,15 +1,13 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/pkg/manifests/SUNWcs.mf --- a/usr/src/pkg/manifests/SUNWcs.mf Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/pkg/manifests/SUNWcs.mf Thu Jun 17 17:23:59 2010 -0700 @@ -552,6 +552,7 @@ file path=lib/svc/manifest/network/rpc/keyserv.xml group=sys mode=0444 file path=lib/svc/manifest/network/shares/group.xml group=sys mode=0444 file path=lib/svc/manifest/network/shares/reparsed.xml group=sys mode=0444 +file path=lib/svc/manifest/network/socket-filter-kssl.xml group=sys mode=0444 file path=lib/svc/manifest/network/ssl/kssl-proxy.xml group=sys mode=0444 file path=lib/svc/manifest/system/auditd.xml group=sys mode=0444 file path=lib/svc/manifest/system/boot-archive-update.xml group=sys mode=0444 diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/pkg/manifests/system-kernel.mf --- a/usr/src/pkg/manifests/system-kernel.mf Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/pkg/manifests/system-kernel.mf Thu Jun 17 17:23:59 2010 -0700 @@ -716,8 +716,10 @@ $(i386_ONLY)file path=kernel/sched/SDC group=sys mode=0755 $(i386_ONLY)file path=kernel/sched/TS group=sys mode=0755 $(i386_ONLY)file path=kernel/sched/TS_DPTBL group=sys mode=0755 +file path=kernel/socketmod/$(ARCH64)/ksslf group=sys mode=0755 file path=kernel/socketmod/$(ARCH64)/socksctp group=sys mode=0755 file path=kernel/socketmod/$(ARCH64)/trill group=sys mode=0755 +$(i386_ONLY)file path=kernel/socketmod/ksslf group=sys mode=0755 $(i386_ONLY)file path=kernel/socketmod/socksctp group=sys mode=0755 $(i386_ONLY)file path=kernel/socketmod/trill group=sys mode=0755 file path=kernel/strmod/$(ARCH64)/bufmod group=sys mode=0755 diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/Makefile.files --- a/usr/src/uts/common/Makefile.files Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/Makefile.files Thu Jun 17 17:23:59 2010 -0700 @@ -524,10 +524,9 @@ IP_ICMP_OBJS = icmp.o icmp_opt_data.o IP_RTS_OBJS = rts.o rts_opt_data.o -IP_TCP_OBJS = tcp.o tcp_fusion.o tcp_kssl.o tcp_opt_data.o tcp_sack.o \ - tcp_stats.o tcp_misc.o tcp_timers.o tcp_time_wait.o tcp_tpi.o \ - tcp_output.o tcp_input.o tcp_socket.o tcp_bind.o tcp_cluster.o \ - tcp_tunables.o +IP_TCP_OBJS = tcp.o tcp_fusion.o tcp_opt_data.o tcp_sack.o tcp_stats.o \ + tcp_misc.o tcp_timers.o tcp_time_wait.o tcp_tpi.o tcp_output.o \ + tcp_input.o tcp_socket.o tcp_bind.o tcp_cluster.o tcp_tunables.o IP_UDP_OBJS = udp.o udp_opt_data.o udp_tunables.o IP_SCTP_OBJS = sctp.o sctp_opt_data.o sctp_output.o \ sctp_init.o sctp_input.o sctp_cookie.o \ @@ -1258,7 +1257,7 @@ SPEC_OBJS += specsubr.o specvfsops.o specvnops.o SOCK_OBJS += socksubr.o sockvfsops.o sockparams.o \ - socksyscalls.o socktpi.o sockstr.o sockssl.o \ + socksyscalls.o socktpi.o sockstr.o \ sockcommon_vnops.o sockcommon_subr.o \ sockcommon_sops.o sockcommon.o \ sock_notsupp.o socknotify.o \ @@ -1544,7 +1543,9 @@ # # kernel SSL # -KSSL_OBJS += kssl.o ksslioctl.o ksslapi.o ksslrec.o +KSSL_OBJS += kssl.o ksslioctl.o + +KSSL_SOCKFIL_MOD_OBJS += ksslfilter.o ksslapi.o ksslrec.o # # misc. modules diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/fs/sockfs/sockcommon_sops.c --- a/usr/src/uts/common/fs/sockfs/sockcommon_sops.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/fs/sockfs/sockcommon_sops.c Thu Jun 17 17:23:59 2010 -0700 @@ -54,8 +54,6 @@ #include #include #include -#include - extern int xnet_skip_checks; extern int xnet_check_print; @@ -255,40 +253,6 @@ else return (SOP_BIND(so, name, namelen, flags, cr)); } - } else if (so->so_type == SOCK_STREAM) { - /* Check if KSSL has been configured for this address */ - kssl_ent_t ent; - kssl_endpt_type_t type; - struct T_bind_req bind_req; - mblk_t *mp; - - /* - * TODO: Check with KSSL team if we could add a function call - * that only queries whether KSSL is enabled for the given - * address. - */ - bind_req.PRIM_type = T_BIND_REQ; - bind_req.ADDR_length = namelen; - bind_req.ADDR_offset = (t_scalar_t)sizeof (bind_req); - mp = soallocproto2(&bind_req, sizeof (bind_req), - name, namelen, 0, _ALLOC_SLEEP, cr); - - type = kssl_check_proxy(mp, so, &ent); - freemsg(mp); - - if (type != KSSL_NO_PROXY) { - /* - * KSSL has been configured for this address, so - * we must fall back to TPI. - */ - kssl_release_ent(ent, so, type); - error = so_tpi_fallback(so, cr); - SO_UNBLOCK_FALLBACK(so); - if (error) - return (error); - else - return (SOP_BIND(so, name, namelen, flags, cr)); - } } dobind: diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/fs/sockfs/sockfilter.c --- a/usr/src/uts/common/fs/sockfs/sockfilter.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/fs/sockfs/sockfilter.c Thu Jun 17 17:23:59 2010 -0700 @@ -1768,3 +1768,45 @@ *flowctrld = (avail > 0) ? B_FALSE : B_TRUE; return (error); } + +/* + * sof_newconn_move(handle, newparent) + * + * Private interface only to be used by KSSL. + * + * Moves the socket associated with `handle' from its current listening + * socket to the listener associated with `newparent'. The socket being + * moved must be in a deferred state and it is up to the consumer of the + * interface to ensure that the `newparent' does not go away while this + * operation is pending. + */ +boolean_t +sof_newconn_move(sof_handle_t handle, sof_handle_t newparent) +{ + sof_instance_t *inst = (sof_instance_t *)handle; + sof_instance_t *newpinst = (sof_instance_t *)newparent; + struct sonode *so, *old, *new; + + so = inst->sofi_sonode; + ASSERT(so->so_state & SS_FIL_DEFER); + + if (inst->sofi_next != NULL || inst->sofi_prev != NULL || + !(so->so_state & SS_FIL_DEFER)) + return (B_FALSE); + + old = so->so_listener; + mutex_enter(&old->so_acceptq_lock); + list_remove(&old->so_acceptq_defer, so); + old->so_acceptq_len--; + mutex_exit(&old->so_acceptq_lock); + + new = newpinst->sofi_sonode; + mutex_enter(&new->so_acceptq_lock); + list_insert_tail(&new->so_acceptq_defer, so); + new->so_acceptq_len++; + mutex_exit(&new->so_acceptq_lock); + + so->so_listener = new; + + return (B_TRUE); +} diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/fs/sockfs/sockssl.c --- a/usr/src/uts/common/fs/sockfs/sockssl.c Thu Jun 17 17:22:09 2010 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -/* - * This routine is registered with the stream head to be called by kstrgetmsg() - * with every packet received on the read queue, and before copying its - * content to user buffers. kstrgetmsg() calls only once with the same - * message. - * If the message is successfully procssed, then it is returned. - * A failed message will be freed. - */ -/* ARGSUSED */ -mblk_t * -strsock_kssl_input(vnode_t *vp, mblk_t *mp, - strwakeup_t *wakeups, strsigset_t *firstmsgsigs, - strsigset_t *allmsgsigs, strpollset_t *pollwakeups) -{ - struct sonode *so = VTOSO(vp); - kssl_ctx_t kssl_ctx = SOTOTPI(so)->sti_kssl_ctx; - kssl_cmd_t kssl_cmd; - mblk_t *out; - - dprintso(so, 1, ("strsock_kssl_input(%p, %p)\n", - (void *)vp, (void *)mp)); - - kssl_cmd = kssl_handle_mblk(kssl_ctx, &mp, &out); - - switch (kssl_cmd) { - case KSSL_CMD_NONE: - return (NULL); - - case KSSL_CMD_DELIVER_PROXY: - return (mp); - - case KSSL_CMD_SEND: { - ASSERT(out != NULL); - - putnext(vp->v_stream->sd_wrq, out); - } - /* FALLTHRU */ - default: - /* transient error. */ - return (NULL); - } -} - -/* - * This routine is registered with the stream head be called by - * kstrmakedata() with every packet sent downstreams. - * If the message is successfully processed, then it is returned. - */ -/* ARGSUSED */ -mblk_t * -strsock_kssl_output(vnode_t *vp, mblk_t *mp, - strwakeup_t *wakeups, strsigset_t *firstmsgsigs, - strsigset_t *allmsgsigs, strpollset_t *pollwakeups) -{ - struct sonode *so = VTOSO(vp); - kssl_ctx_t kssl_ctx = SOTOTPI(so)->sti_kssl_ctx; - mblk_t *recmp; - - dprintso(so, 1, ("strsock_kssl_output(%p, %p)\n", - (void *)vp, (void *)mp)); - - if ((recmp = kssl_build_record(kssl_ctx, mp)) == NULL) { - /* The caller will free the bogus message */ - return (NULL); - } - return (recmp); -} diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/fs/sockfs/sockstr.c --- a/usr/src/uts/common/fs/sockfs/sockstr.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/fs/sockfs/sockstr.c Thu Jun 17 17:23:59 2010 -0700 @@ -20,8 +20,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. */ #include @@ -64,8 +63,6 @@ #define _SUN_TPI_VERSION 2 #include -#include - #include #include @@ -1228,19 +1225,6 @@ so->so_error = ECONNABORTED; mutex_exit(&so->so_lock); - /* - * T_KSSL_PROXY_CONN_IND may carry a handle for - * an SSL context, and needs to be released. - */ - if ((tci->PRIM_type == T_SSL_PROXY_CONN_IND) && - (mp->b_cont != NULL)) { - kssl_ctx_t kssl_ctx; - - ASSERT(MBLKL(mp->b_cont) == - sizeof (kssl_ctx_t)); - kssl_ctx = *((kssl_ctx_t *)mp->b_cont->b_rptr); - kssl_release_ctx(kssl_ctx); - } freemsg(mp); return (0); } @@ -2262,11 +2246,6 @@ return (NULL); } - /* - * Extra processing in case of an SSL proxy, before queuing or - * forwarding to the fallback endpoint - */ - case T_SSL_PROXY_CONN_IND: case T_CONN_IND: /* * Verify the min size and queue the message on @@ -2289,27 +2268,6 @@ return (NULL); } - if (tpr->type == T_SSL_PROXY_CONN_IND && mp->b_cont == NULL) { - /* No context: need to fall back */ - struct sonode *fbso; - stdata_t *fbstp; - - tpr->type = T_CONN_IND; - - fbso = kssl_find_fallback(sti->sti_kssl_ent); - - /* - * No fallback: the remote will timeout and - * disconnect. - */ - if (fbso == NULL) { - freemsg(mp); - return (NULL); - } - fbstp = SOTOV(fbso)->v_stream; - qreply(fbstp->sd_wrq->q_next, mp); - return (NULL); - } soqueueconnind(so, mp); *allmsgsigs = S_INPUT | S_RDNORM; *pollwakeups = POLLIN | POLLRDNORM; diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/fs/sockfs/socksyscalls.c --- a/usr/src/uts/common/fs/sockfs/socksyscalls.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c Thu Jun 17 17:23:59 2010 -0700 @@ -2091,18 +2091,12 @@ iosize = (int)MIN(sr->sr_maxpsz, size); /* - * For sockets acting as an SSL proxy, we - * need to adjust the size to the maximum - * SSL record size set in the stream head. - * * Socket filters can limit the mblk size, * so limit reads to maxblk if there are * filters present. */ if (vp->v_type == VSOCK && - (!SOCK_IS_NONSTR(so) && - SOTOTPI(so)->sti_kssl_ctx != NULL) || - (so->so_filter_active > 0 && maxblk != INFPSZ)) + so->so_filter_active > 0 && maxblk != INFPSZ) iosize = (int)MIN(iosize, maxblk); if (is_system_labeled()) { @@ -2704,16 +2698,11 @@ iosize = (int)MIN(maxpsz, size); /* - * For sockets acting as an SSL proxy, we - * need to adjust the size to the maximum - * SSL record size set in the stream head. - * * Socket filters can limit the mblk size, * so limit reads to maxblk if there are + * filters present. */ if (vp->v_type == VSOCK && - (!SOCK_IS_NONSTR(so) && - SOTOTPI(so)->sti_kssl_ctx != NULL) || so->so_filter_active > 0 && maxblk != INFPSZ) iosize = (int)MIN(iosize, maxblk); diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/fs/sockfs/socktpi.c --- a/usr/src/uts/common/fs/sockfs/socktpi.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/fs/sockfs/socktpi.c Thu Jun 17 17:23:59 2010 -0700 @@ -79,8 +79,6 @@ #include #include -#include - #include #include #include @@ -197,12 +195,6 @@ extern void sigintr(k_sigset_t *, int); extern void sigunintr(k_sigset_t *); -/* Sockets acting as an in-kernel SSL proxy */ -extern mblk_t *strsock_kssl_input(vnode_t *, mblk_t *, strwakeup_t *, - strsigset_t *, strsigset_t *, strpollset_t *); -extern mblk_t *strsock_kssl_output(vnode_t *, mblk_t *, strwakeup_t *, - strsigset_t *, strsigset_t *, strpollset_t *); - static int sotpi_unbind(struct sonode *, int); /* TPI sockfs sonode operations */ @@ -1088,38 +1080,6 @@ /* Done using sti_laddr_sa - can drop the lock */ mutex_exit(&so->so_lock); - /* - * Intercept the bind_req message here to check if this
- * was configured as an SSL proxy server, or if another endpoint was - * already configured to act as a proxy for us. - * - * Note, only if NL7C not enabled for this socket. - */ - if (nl7c == NULL && - (so->so_family == AF_INET || so->so_family == AF_INET6) && - so->so_type == SOCK_STREAM) { - - if (sti->sti_kssl_ent != NULL) { - kssl_release_ent(sti->sti_kssl_ent, so, - sti->sti_kssl_type); - sti->sti_kssl_ent = NULL; - } - - sti->sti_kssl_type = kssl_check_proxy(mp, so, - &sti->sti_kssl_ent); - switch (sti->sti_kssl_type) { - case KSSL_NO_PROXY: - break; - - case KSSL_HAS_PROXY: - mutex_enter(&so->so_lock); - goto skip_transport; - - case KSSL_IS_PROXY: - break; - } - } - error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0, MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0); if (error) { @@ -1135,7 +1095,6 @@ eprintsoline(so, error); goto done; } -skip_transport: ASSERT(mp); /* * Even if some TPI message (e.g. T_DISCON_IND) was received in @@ -1493,17 +1452,6 @@ vnode_t *vp; if ((vp = sti->sti_ux_bound_vp) != NULL) { - - /* Undo any SSL proxy setup */ - if ((so->so_family == AF_INET || - so->so_family == AF_INET6) && - (so->so_type == SOCK_STREAM) && - (sti->sti_kssl_ent != NULL)) { - kssl_release_ent(sti->sti_kssl_ent, so, - sti->sti_kssl_type); - sti->sti_kssl_ent = NULL; - sti->sti_kssl_type = KSSL_NO_PROXY; - } sti->sti_ux_bound_vp = NULL; vn_rele_stream(vp); } @@ -1694,7 +1642,7 @@ struct T_conn_ind *conn_ind; struct T_conn_res *conn_res; int error = 0; - mblk_t *mp, *ctxmp, *ack_mp; + mblk_t *mp, *ack_mp; struct sonode *nso; vnode_t *nvp; void *src; @@ -1726,7 +1674,6 @@ ASSERT(mp != NULL); conn_ind = (struct T_conn_ind *)mp->b_rptr; - ctxmp = mp->b_cont; /* * Save SEQ_number for error paths. @@ -1818,23 +1765,6 @@ nvp = SOTOV(nso); nsti = SOTOTPI(nso); - /* - * If the transport sent up an SSL connection context, then attach - * it the new socket, and set the (sd_wputdatafunc)() and - * (sd_rputdatafunc)() stream head hooks to intercept and process - * SSL records. - */ - if (ctxmp != NULL) { - /* - * This kssl_ctx_t is already held for us by the transport. - * So, we don't need to do a kssl_hold_ctx() here. - */ - nsti->sti_kssl_ctx = *((kssl_ctx_t *)ctxmp->b_rptr); - freemsg(ctxmp); - mp->b_cont = NULL; - strsetrwputdatahooks(nvp, strsock_kssl_input, - strsock_kssl_output); - } #ifdef DEBUG /* * SO_DEBUG is used to trigger the dprint* and eprint* macros thus @@ -5767,19 +5697,6 @@ sti->sti_ux_bound_vp = NULL; vn_rele_stream(ux_vp); } - if (so->so_family == AF_INET || so->so_family == AF_INET6) { - strsetrwputdatahooks(SOTOV(so), NULL, NULL); - if (sti->sti_kssl_ent != NULL) { - kssl_release_ent(sti->sti_kssl_ent, so, - sti->sti_kssl_type); - sti->sti_kssl_ent = NULL; - } - if (sti->sti_kssl_ctx != NULL) { - kssl_release_ctx(sti->sti_kssl_ctx); - sti->sti_kssl_ctx = NULL; - } - sti->sti_kssl_type = KSSL_NO_PROXY; - } error = strclose(vp, flag, cr); vp->v_stream = NULL; mutex_enter(&so->so_lock); @@ -6749,11 +6666,6 @@ ASSERT(sti->sti_conn_ind_head == NULL); ASSERT(sti->sti_conn_ind_tail == NULL); - - /* Initialize the kernel SSL proxy fields */ - sti->sti_kssl_type = KSSL_NO_PROXY; - sti->sti_kssl_ent = NULL; - sti->sti_kssl_ctx = NULL; } /* diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/fs/sockfs/socktpi.h --- a/usr/src/uts/common/fs/sockfs/socktpi.h Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/fs/sockfs/socktpi.h Thu Jun 17 17:23:59 2010 -0700 @@ -26,8 +26,6 @@ #ifndef _SOCKFS_SOCKTPI_H #define _SOCKFS_SOCKTPI_H -#include - #ifdef __cplusplus extern "C" { #endif @@ -245,11 +243,6 @@ void *sti_nl7c_uri; time_t sti_nl7c_rtime; void *sti_nl7c_addr; - - /* For sockets acting as an in-kernel SSL proxy */ - kssl_endpt_type_t sti_kssl_type; /* is proxy/is proxied/none */ - kssl_ent_t sti_kssl_ent; /* SSL config entry */ - kssl_ctx_t sti_kssl_ctx; /* SSL session context */ } sotpi_info_t; struct T_capability_ack; diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/kssl/kssl.c --- a/usr/src/uts/common/inet/kssl/kssl.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/kssl/kssl.c Thu Jun 17 17:23:59 2010 -0700 @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ @@ -145,8 +144,10 @@ }; struct kmem_cache *kssl_cache; +static crypto_notify_handle_t prov_update_handle = NULL; static void kssl_global_init(); +static void kssl_global_fini(); static void kssl_init_mechs(); static void kssl_event_callback(uint32_t, void *); @@ -156,7 +157,31 @@ int _init(void) { - return (mod_install(&modlinkage)); + int error; + + kssl_global_init(); + + if ((error = mod_install(&modlinkage)) != 0) { + kssl_global_fini(); + return (error); + } + return (0); +} + +int +_fini(void) +{ + int error; + + if ((error = mod_remove(&modlinkage)) != 0) + return (error); + + if (prov_update_handle != NULL) + crypto_unnotify_events(prov_update_handle); + + kssl_global_fini(); + + return (0); } int @@ -203,8 +228,6 @@ kssl_dip = dip; - kssl_global_init(); - return (DDI_SUCCESS); } @@ -216,29 +239,16 @@ if (cmd != DDI_DETACH) return (DDI_FAILURE); - if (kssl_entry_tab_nentries != 0 || kssl_cache_count != 0) + if (kssl_entry_tab_nentries != 0) return (DDI_FAILURE); - mutex_destroy(&kssl_tab_mutex); kssl_dip = NULL; - if (kssl_cache != NULL) { - kmem_cache_destroy(kssl_cache); - kssl_cache = NULL; - } - - if (kssl_ksp != NULL) { - kstat_delete(kssl_ksp); - kssl_ksp = NULL; - } - ddi_remove_minor_node(dip, NULL); return (DDI_SUCCESS); } -static crypto_notify_handle_t prov_update_handle = NULL; - /* ARGSUSED */ static int kssl_open(dev_t *devp, int flag, int otyp, cred_t *credp) @@ -586,6 +596,22 @@ }; } +static void +kssl_global_fini(void) +{ + mutex_destroy(&kssl_tab_mutex); + + if (kssl_cache != NULL) { + kmem_cache_destroy(kssl_cache); + kssl_cache = NULL; + } + + if (kssl_ksp != NULL) { + kstat_delete(kssl_ksp); + kssl_ksp = NULL; + } +} + /*ARGSUSED*/ static int kssl_constructor(void *buf, void *arg, int kmflags) @@ -593,6 +619,7 @@ ssl_t *ssl = buf; mutex_init(&ssl->kssl_lock, NULL, MUTEX_DEFAULT, NULL); + cv_init(&ssl->async_cv, NULL, CV_DEFAULT, NULL); return (0); } @@ -603,6 +630,7 @@ { ssl_t *ssl = buf; mutex_destroy(&ssl->kssl_lock); + cv_destroy(&ssl->async_cv); } /* diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/kssl/ksslapi.c --- a/usr/src/uts/common/inet/kssl/ksslapi.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/kssl/ksslapi.c Thu Jun 17 17:23:59 2010 -0700 @@ -48,7 +48,7 @@ static kssl_status_t kssl_build_single_record(ssl_t *ssl, mblk_t *mp); /* - * The socket T_bind_req message is intercepted and re-routed here + * The socket bind request is intercepted and re-routed here * to see is there is SSL relevant job to do, based on the kssl config * in the kssl_entry_tab. * Looks up the kernel SSL proxy table, to find an entry that matches the @@ -72,14 +72,14 @@ */ kssl_endpt_type_t -kssl_check_proxy(mblk_t *bindmp, void *cookie, kssl_ent_t *ksslent) +kssl_check_proxy(struct sockaddr *addr, socklen_t len, void *cookie, + kssl_ent_t *ksslent) { int i; kssl_endpt_type_t ret; kssl_entry_t *ep; sin_t *sin; sin6_t *sin6; - struct T_bind_req *tbr; in6_addr_t mapped_v4addr; in6_addr_t *v6addr; in_port_t in_port; @@ -89,11 +89,9 @@ } ret = KSSL_NO_PROXY; + sin = (struct sockaddr_in *)addr; - tbr = (struct T_bind_req *)bindmp->b_rptr; - sin = (sin_t *)(bindmp->b_rptr + tbr->ADDR_offset); - - switch (tbr->ADDR_length) { + switch (len) { case sizeof (sin_t): in_port = ntohs(sin->sin_port); IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &mapped_v4addr); @@ -138,13 +136,6 @@ break; } - /* - * Now transform the T_BIND_REQ into - * a T_BIND_ACK. - */ - tbr->PRIM_type = T_BIND_ACK; - bindmp->b_datap->db_type = M_PCPROTO; - KSSL_ENTRY_REFHOLD(ep); *ksslent = (kssl_ent_t)ep; @@ -154,27 +145,10 @@ /* This is a proxy port. */ if (ep->ke_proxy_port == in_port) { - mblk_t *entmp; - - /* Append this entry to the bind_req mblk */ - - entmp = allocb(sizeof (kssl_entry_t), - BPRI_MED); - if (entmp == NULL) - break; - *((kssl_entry_t **)entmp->b_rptr) = ep; - - entmp->b_wptr = entmp->b_rptr + - sizeof (kssl_entry_t); - - bindmp->b_cont = entmp; - /* Add the caller's cookie to proxies list */ if (!kssl_enqueue((kssl_chain_t **) &(ep->ke_proxy_head), cookie)) { - freeb(bindmp->b_cont); - bindmp->b_cont = NULL; break; } @@ -184,8 +158,6 @@ */ sin->sin_port = htons(ep->ke_ssl_port); - tbr->PRIM_type = T_SSL_PROXY_BIND_REQ; - KSSL_ENTRY_REFHOLD(ep); *ksslent = (kssl_ent_t)ep; @@ -310,23 +282,26 @@ } /* - * Holds the kssl context - */ -void -kssl_hold_ctx(kssl_ctx_t ksslctx) -{ - ssl_t *ssl = (ssl_t *)ksslctx; - - KSSL_SSL_REFHOLD(ssl); -} - -/* * Releases the kssl_context */ void kssl_release_ctx(kssl_ctx_t ksslctx) { - KSSL_SSL_REFRELE((ssl_t *)ksslctx); + kssl_free_context((ssl_t *)ksslctx); +} + +/* + * Done with asynchronous processing + */ +void +kssl_async_done(kssl_ctx_t ksslctx) +{ + ssl_t *ssl = (ssl_t *)ksslctx; + + mutex_enter(&ssl->kssl_lock); + if (--ssl->async_ops_pending == 0) + cv_signal(&ssl->async_cv); + mutex_exit(&ssl->kssl_lock); } /* @@ -403,7 +378,6 @@ if ((mp->b_cont == NULL) && (mplen == rec_sz)) { - DB_FLAGS(mp) &= ~DBLK_COOKED; *decrmp = mp; mutex_exit(&ssl->kssl_lock); return (KSSL_CMD_DELIVER_PROXY); @@ -541,19 +515,8 @@ } /* - * Process mblk b_cont chain returned from stream head. The chain could - * contain a mixture (albeit continuous) of processed and unprocessed - * mblks. This situation could happen when more data was available in - * stream head queue than requested. In such case the rest of processed - * data would be putback(). - * - * Processed mblks in this function contain either a full or partial portion - * of a decrypted and verified SSL record. The former case is produced - * by the function itself, the latter case is explained above. - * - * In case of unprocessed mblks, decrypt and verify the MAC of an incoming - * chain of application_data record. Each block has exactly one SSL record. - * This routine recycles incoming mblks, and flags them as DBLK_COOKED. + * Decrypt and verify the MAC of an incoming chain of application_data record. + * Each block has exactly one SSL record. */ kssl_cmd_t kssl_handle_mblk(kssl_ctx_t ctx, mblk_t **mpp, mblk_t **outmp) @@ -579,23 +542,10 @@ mp = firstmp = *mpp; *outmp = NULL; - - /* - * Skip over already processed mblks. This prevents a case where - * struiocopyout() copies unprocessed data to userland. - */ - while ((mp != NULL) && (DB_FLAGS(mp) & DBLK_COOKED)) { - ASSERT(DB_TYPE(mp) == M_DATA); - DTRACE_PROBE1(kssl_mblk__already_processed_mblk, mblk_t *, mp); - mp = mp->b_cont; - } - more: while (mp != NULL) { - /* only unprocessed mblks should reach us */ ASSERT(DB_TYPE(mp) == M_DATA); - ASSERT(!(DB_FLAGS(mp) & DBLK_COOKED)); if (DB_REF(mp) > 1) { /* @@ -771,7 +721,6 @@ } mp->b_wptr = recend; - DB_FLAGS(mp) |= DBLK_COOKED; DTRACE_PROBE1(kssl_mblk__dblk_cooked, mblk_t *, mp); KSSL_COUNTER(appdata_record_ins, 1); @@ -1186,26 +1135,26 @@ * address. The ssl structure is returned held. */ kssl_status_t -kssl_init_context(kssl_ent_t kssl_ent, void *addr, boolean_t is_v4, - int mss, kssl_ctx_t *kssl_ctxp) +kssl_init_context(kssl_ent_t kssl_ent, struct sockaddr *addr, int mss, + kssl_ctx_t *kssl_ctxp) { ssl_t *ssl = kmem_cache_alloc(kssl_cache, KM_NOSLEEP); + struct sockaddr_in *sin = (struct sockaddr_in *)addr; if (ssl == NULL) { return (KSSL_STS_ERR); } - kssl_cache_count++; - bzero(ssl, sizeof (ssl_t)); ssl->kssl_entry = (kssl_entry_t *)kssl_ent; KSSL_ENTRY_REFHOLD(ssl->kssl_entry); - if (is_v4) { - IN6_IPADDR_TO_V4MAPPED(*((ipaddr_t *)addr), &ssl->faddr); + if (sin->sin_family == AF_INET) { + IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &ssl->faddr); } else { - ssl->faddr = *((in6_addr_t *)addr); /* struct assignment */ + /* struct assignment */ + ssl->faddr = ((struct sockaddr_in6 *)addr)->sin6_addr; } ssl->tcp_mss = mss; ssl->sendalert_level = alert_warning; @@ -1213,10 +1162,16 @@ ssl->sid.cached = B_FALSE; *kssl_ctxp = (kssl_ctx_t)ssl; - KSSL_SSL_REFHOLD(ssl); return (KSSL_STS_OK); } +void +kssl_set_mss(kssl_ctx_t ctx, uint32_t mss) +{ + ssl_t *ssl = (ssl_t *)ctx; + ssl->tcp_mss = mss; +} + /* * Builds SSL records out of the chain of mblks, and returns it. * Takes a copy of the message before encrypting it if it has another diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/kssl/ksslapi.h --- a/usr/src/uts/common/inet/kssl/ksslapi.h Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/kssl/ksslapi.h Thu Jun 17 17:23:59 2010 -0700 @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _INET_KSSL_KSSLAPI_H @@ -74,17 +73,19 @@ #define SSL3_MAX_RECORD_LEN 16384 - 1 - SSL3_HDR_LEN - SSL3_MAX_TAIL_LEN -kssl_endpt_type_t kssl_check_proxy(mblk_t *, void *, kssl_ent_t *); +kssl_endpt_type_t kssl_check_proxy(struct sockaddr *, socklen_t, void *, + kssl_ent_t *); -kssl_status_t kssl_init_context(kssl_ent_t, void *, boolean_t, - int, kssl_ctx_t *); +kssl_status_t kssl_init_context(kssl_ent_t, struct sockaddr *, int, + kssl_ctx_t *); +void kssl_set_mss(kssl_ctx_t, uint32_t); void kssl_hold_ent(kssl_ent_t); void kssl_release_ent(kssl_ent_t, void *, kssl_endpt_type_t); void *kssl_find_fallback(kssl_ent_t); -void kssl_hold_ctx(kssl_ctx_t); void kssl_release_ctx(kssl_ctx_t); +void kssl_async_done(kssl_ctx_t); typedef void (*kssl_callback_t)(void *arg, mblk_t *mp, kssl_cmd_t cmd); diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/kssl/ksslfilter.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/inet/kssl/ksslfilter.c Thu Jun 17 17:23:59 2010 -0700 @@ -0,0 +1,578 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name of the KSSL filter + */ +#define KSSL_FILNAME "ksslf" + +static struct modlmisc ksslf_modlmisc = { + &mod_miscops, + "Kernel SSL socket filter" +}; + +static struct modlinkage ksslf_modlinkage = { + MODREV_1, + &ksslf_modlmisc, + NULL +}; + +/* + * kssl filter cookie + */ +typedef struct ksslf { + boolean_t ksslf_pending; /* waiting for 1st SSL rec. */ + boolean_t ksslf_inhandshake; /* during SSL handshake */ + kssl_ent_t ksslf_ent; /* SSL table entry */ + kssl_ctx_t ksslf_ctx; /* SSL session */ + kssl_endpt_type_t ksslf_type; /* is proxy/is proxied/none */ + struct sockaddr_in6 ksslf_laddr; /* local address */ + socklen_t ksslf_laddrlen; + struct ksslf *ksslf_listener; +} ksslf_t; + +static void kssl_input_callback(void *, mblk_t *, kssl_cmd_t); + +/* + * Allocate kssl state + */ +sof_rval_t +kssl_attach_passive_cb(sof_handle_t handle, sof_handle_t ph, + void *parg, struct sockaddr *laddr, socklen_t laddrlen, + struct sockaddr *faddr, socklen_t faddrlen, void **cookiep) +{ + ksslf_t *listener = (ksslf_t *)parg; + ksslf_t *new; + + _NOTE(ARGUNUSED(handle, ph, faddrlen, laddr, laddrlen)); + + if (listener == NULL || listener->ksslf_ent == NULL) + return (SOF_RVAL_DETACH); + /* + * Only way for a fallback listener to receive connections is when + * a handshake fails and socket is moved from the proxy to the fallback. + * Connections that come in directly on the fallback are denied. + */ + if (listener->ksslf_type == KSSL_HAS_PROXY) + return (SOF_RVAL_EACCES); + + /* Allocate the SSL context for the new connection */ + new = kmem_zalloc(sizeof (ksslf_t), KM_NOSLEEP); + if (new == NULL) + return (SOF_RVAL_ENOMEM); + + /* + * The mss is initialized to SSL3_MAX_RECORD_LEN, but might be + * updated by the mblk_prop callback. + */ + if (kssl_init_context(listener->ksslf_ent, faddr, SSL3_MAX_RECORD_LEN, + &new->ksslf_ctx) != KSSL_STS_OK) + return (SOF_RVAL_ENOMEM); + + new->ksslf_pending = B_TRUE; + new->ksslf_inhandshake = B_TRUE; + ASSERT(laddrlen <= sizeof (new->ksslf_laddr)); + new->ksslf_laddrlen = laddrlen; + bcopy(laddr, &new->ksslf_laddr, laddrlen); + new->ksslf_laddr.sin6_port = listener->ksslf_laddr.sin6_port; + new->ksslf_listener = listener; + + *cookiep = new; + /* + * We are in handshake, defer the notification of this connection + * until it is completed. + */ + return (SOF_RVAL_DEFER); +} + +void +kssl_detach_cb(sof_handle_t handle, void *cookie, cred_t *cr) +{ + ksslf_t *kssl = (ksslf_t *)cookie; + + _NOTE(ARGUNUSED(handle, cr)); + + if (kssl == NULL) + return; + + if (kssl->ksslf_ent != NULL) { + kssl_release_ent(kssl->ksslf_ent, handle, kssl->ksslf_type); + kssl->ksslf_ent = NULL; + } + if (kssl->ksslf_ctx != NULL) { + kssl_release_ctx(kssl->ksslf_ctx); + kssl->ksslf_ctx = NULL; + } + + kmem_free(kssl, sizeof (ksslf_t)); +} + +sof_rval_t +kssl_bind_cb(sof_handle_t handle, void *cookie, struct sockaddr *name, + socklen_t *namelen, cred_t *cr) +{ + kssl_ent_t ent; + kssl_endpt_type_t type; + ksslf_t *kssl; + in_port_t origport; + + _NOTE(ARGUNUSED(cr)); + + if (cookie != NULL) + return (SOF_RVAL_EINVAL); + + if (*namelen < sizeof (struct sockaddr_in)) { + sof_bypass(handle); + return (SOF_RVAL_CONTINUE); + } + + origport = ((struct sockaddr_in *)name)->sin_port; + /* Check if KSSL has been configured for this address */ + type = kssl_check_proxy(name, *namelen, handle, &ent); + + switch (type) { + case KSSL_NO_PROXY: + sof_bypass(handle); + break; + case KSSL_HAS_PROXY: + case KSSL_IS_PROXY: + kssl = kmem_zalloc(sizeof (ksslf_t), KM_SLEEP); + kssl->ksslf_type = type; + kssl->ksslf_ent = ent; + + /* + * In the unlikely event that there are multiple simultaneous + * bind requests, and the cookie was already swapped out, then + * just drop this cookie and let the bind continue unmodified. + */ + if (sof_cas_cookie(handle, cookie, kssl) != cookie) { + kssl_release_ent(ent, handle, type); + kmem_free(kssl, sizeof (ksslf_t)); + ((struct sockaddr_in *)name)->sin_port = origport; + break; + } + + kssl->ksslf_laddrlen = *namelen; + bcopy(name, &kssl->ksslf_laddr, kssl->ksslf_laddrlen); + kssl->ksslf_laddr.sin6_port = origport; + /* + * kssl_check_proxy updated the sockaddr, so just + * pass it along to the protocol. + */ + return ((type == KSSL_HAS_PROXY) ? SOF_RVAL_RETURN : + SOF_RVAL_CONTINUE); + } + return (SOF_RVAL_CONTINUE); +} + +sof_rval_t +kssl_listen_cb(sof_handle_t handle, void *cookie, int *backlog, cred_t *cr) +{ + ksslf_t *kssl = (ksslf_t *)cookie; + + _NOTE(ARGUNUSED(backlog, cr)); + + /* + * The cookie can be NULL in the unlikely event of an application doing + * listen() without binding to an address. Those listeners are of no + * interest. + */ + if (kssl == NULL) { + sof_bypass(handle); + return (SOF_RVAL_CONTINUE); + } + + return (SOF_RVAL_CONTINUE); + +} + +/* + * Outgoing connections are not of interest, so just bypass the filter. + */ +sof_rval_t +kssl_connect_cb(sof_handle_t handle, void *cookie, struct sockaddr *name, + socklen_t *namelen, cred_t *cr) +{ + _NOTE(ARGUNUSED(cookie, name, namelen, cr)); + + sof_bypass(handle); + return (SOF_RVAL_CONTINUE); +} + +static void +kssl_mblk_prop_cb(sof_handle_t handle, void *cookie, ssize_t *maxblk, + ushort_t *wroff, ushort_t *tail) +{ + ksslf_t *kssl = (ksslf_t *)cookie; + + _NOTE(ARGUNUSED(handle)); + + /* only care about passively opened sockets */ + if (kssl == NULL || !kssl->ksslf_pending) + return; + /* + * If this is endpoint is handling SSL, then reserve extra + * offset and space at the end. Also have sockfs allocate + * SSL3_MAX_RECORD_LEN packets, overriding the previous setting. + * The extra cost of signing and encrypting multiple MSS-size + * records (12 of them with Ethernet), instead of a single + * contiguous one by the stream head largely outweighs the + * statistical reduction of ACKs, when applicable. The peer + * will also save on decryption and verification costs. + */ + if (*maxblk == INFPSZ || *maxblk > SSL3_MAX_RECORD_LEN) + *maxblk = SSL3_MAX_RECORD_LEN; + else + kssl_set_mss(kssl->ksslf_ctx, *maxblk); + *wroff += SSL3_WROFFSET; + *tail += SSL3_MAX_TAIL_LEN; +} + +sof_rval_t +kssl_getsockname_cb(sof_handle_t handle, void *cookie, struct sockaddr *addr, + socklen_t *addrlen, cred_t *cr) +{ + ksslf_t *kssl = (ksslf_t *)cookie; + + _NOTE(ARGUNUSED(handle, cr)); + + if (kssl == NULL) + return (SOF_RVAL_CONTINUE); + + if (*addrlen < kssl->ksslf_laddrlen) + return (SOF_RVAL_EINVAL); + + *addrlen = kssl->ksslf_laddrlen; + bcopy(&kssl->ksslf_laddr, addr, kssl->ksslf_laddrlen); + + return (SOF_RVAL_RETURN); +} + +/* + * Called for every packet sent to the protocol. + * If the message is successfully processed, then it is returned. + */ +mblk_t * +kssl_data_out_cb(sof_handle_t handle, void *cookie, mblk_t *mp, + struct nmsghdr *msg, cred_t *cr, sof_rval_t *rv) +{ + ksslf_t *kssl = (ksslf_t *)cookie; + kssl_ctx_t kssl_ctx = kssl->ksslf_ctx; + mblk_t *recmp; + + _NOTE(ARGUNUSED(handle, msg, cr)); + + *rv = SOF_RVAL_CONTINUE; + if (kssl_ctx == NULL) + return (mp); + + if ((recmp = kssl_build_record(kssl_ctx, mp)) == NULL) { + freemsg(mp); + *rv = SOF_RVAL_EINVAL; + return (NULL); + } + return (recmp); +} + +/* + * Called for each incoming segment. + * + * A packet may carry multiple SSL records, so the function calls + * kssl_input() in a loop, until all records are handled. + */ +mblk_t * +kssl_data_in_cb(sof_handle_t handle, void *cookie, mblk_t *mp, int flags, + size_t *lenp) +{ + ksslf_t *kssl = cookie; + kssl_cmd_t kssl_cmd; + mblk_t *outmp, *retmp = NULL, **tail = &retmp; + boolean_t more = B_FALSE; + boolean_t flowctrld; + + _NOTE(ARGUNUSED(flags)); + + if (kssl == NULL || kssl->ksslf_ctx == NULL) { + sof_bypass(handle); + return (mp); + } + + *lenp = 0; + do { + kssl_cmd = kssl_input(kssl->ksslf_ctx, mp, &outmp, + &more, kssl_input_callback, (void *)handle); + + switch (kssl_cmd) { + case KSSL_CMD_SEND: { + struct nmsghdr msg; + + DTRACE_PROBE(kssl_cmd_send); + bzero(&msg, sizeof (msg)); + (void) sof_inject_data_out(handle, outmp, &msg, + &flowctrld); + } + /* FALLTHROUGH */ + case KSSL_CMD_NONE: + DTRACE_PROBE(kssl_cmd_none); + if (kssl->ksslf_pending) { + kssl->ksslf_pending = B_FALSE; + sof_newconn_ready(handle); + } + break; + + case KSSL_CMD_QUEUED: + DTRACE_PROBE(kssl_cmd_queued); + break; + + case KSSL_CMD_DELIVER_PROXY: + case KSSL_CMD_DELIVER_SSL: + DTRACE_PROBE(kssl_cmd_proxy__ssl); + /* + * We're at a phase where records are sent upstreams, + * past the handshake + */ + kssl->ksslf_inhandshake = B_FALSE; + + *tail = outmp; + *lenp += MBLKL(outmp); + while (outmp->b_cont != NULL) { + outmp = outmp->b_cont; + *lenp += MBLKL(outmp); + } + tail = &outmp->b_cont; + break; + + case KSSL_CMD_NOT_SUPPORTED: { + ksslf_t *listener = kssl->ksslf_listener; + sof_handle_t fallback; + + DTRACE_PROBE(kssl_cmd_not_supported); + /* + * Stop the SSL processing by the proxy, and + * switch to the userland SSL + */ + if (kssl->ksslf_pending) { + kssl->ksslf_pending = B_FALSE; + + DTRACE_PROBE1(kssl_no_can_do, sof_handle_t, + handle); + + sof_bypass(handle); + + ASSERT(listener->ksslf_ent != NULL); + fallback = + kssl_find_fallback(listener->ksslf_ent); + /* + * No fallback: the remote will timeout and + * disconnect. + */ + if (fallback != NULL && + sof_newconn_move(handle, fallback)) + sof_newconn_ready(handle); + } + if (mp != NULL) { + *tail = mp; + *lenp += MBLKL(mp); + while (mp->b_cont != NULL) { + mp = mp->b_cont; + *lenp += MBLKL(mp); + } + tail = &mp->b_cont; + } + break; + } + } + mp = NULL; + } while (more); + + return (retmp); +} + +/* + * Process queued data before it's copied by the user. + * + * If the message is successfully processed, then it is returned. + * A failed message will be freed. + */ +mblk_t * +kssl_data_in_proc_cb(sof_handle_t handle, void *cookie, mblk_t *mp, + cred_t *cr, size_t *lenp) +{ + ksslf_t *kssl = (ksslf_t *)cookie; + kssl_ctx_t kssl_ctx = kssl->ksslf_ctx; + kssl_cmd_t kssl_cmd; + mblk_t *out; + + _NOTE(ARGUNUSED(cr)); + + *lenp = 0; + + kssl_cmd = kssl_handle_mblk(kssl_ctx, &mp, &out); + + switch (kssl_cmd) { + case KSSL_CMD_NONE: + return (NULL); + case KSSL_CMD_DELIVER_PROXY: + *lenp = msgdsize(mp); + return (mp); + case KSSL_CMD_SEND: { + struct nmsghdr msg; + boolean_t flowctrld; + + ASSERT(out != NULL); + bzero(&msg, sizeof (msg)); + + (void) sof_inject_data_out(handle, out, &msg, + &flowctrld); + return (NULL); + } + default: + /* transient error. */ + return (NULL); + } +} + +/* + * Continue processing the incoming flow after an asynchronous callback. + */ +static void +kssl_input_asynch(void *arg) +{ + sof_handle_t handle = (sof_handle_t)arg; + ksslf_t *kssl = (ksslf_t *)sof_get_cookie(handle); + size_t len = 0; + boolean_t flowctrld; + mblk_t *mp; + + if ((mp = kssl_data_in_cb(handle, kssl, NULL, 0, &len)) != NULL) { + ASSERT(len != 0); + (void) sof_inject_data_in(handle, mp, len, 0, &flowctrld); + } + kssl_async_done(kssl->ksslf_ctx); +} + +/* + * Callback function for the cases kssl_input() had to submit an asynchronous + * job and need to come back when done to carry on the input processing. + * This routine follows the conentions of timeout and interrupt handlers. + * (no blocking, ...) + */ +static void +kssl_input_callback(void *arg, mblk_t *mp, kssl_cmd_t kssl_cmd) +{ + sof_handle_t handle = (sof_handle_t)arg; + ksslf_t *kssl = (ksslf_t *)sof_get_cookie(handle); + boolean_t flowctrld; + + ASSERT(kssl != NULL); + + switch (kssl_cmd) { + case KSSL_CMD_SEND: { + struct nmsghdr msg; + + if (mp == NULL) + break; + bzero(&msg, sizeof (msg)); + + (void) sof_inject_data_out(handle, mp, &msg, &flowctrld); + } + /* FALLTHROUGH */ + case KSSL_CMD_NONE: + break; + + case KSSL_CMD_DELIVER_PROXY: + case KSSL_CMD_DELIVER_SSL: + (void) sof_inject_data_in(handle, mp, msgdsize(mp), 0, + &flowctrld); + break; + + case KSSL_CMD_NOT_SUPPORTED: + /* Stop the SSL processing */ + sof_bypass(handle); + } + /* + * Process any input that may have accumulated while we're waiting for + * the call-back. This must be done by a taskq because kssl_input might + * block when handling client_finish messages. + */ + if (taskq_dispatch(system_taskq, kssl_input_asynch, handle, + TQ_NOSLEEP) == NULL) { + DTRACE_PROBE(kssl_err__taskq_dispatch_failed); + kssl_async_done(kssl->ksslf_ctx); + } +} + +sof_ops_t ksslf_ops = { + .sofop_attach_passive = kssl_attach_passive_cb, + .sofop_detach = kssl_detach_cb, + .sofop_bind = kssl_bind_cb, + .sofop_connect = kssl_connect_cb, + .sofop_listen = kssl_listen_cb, + .sofop_data_in = kssl_data_in_cb, + .sofop_data_in_proc = kssl_data_in_proc_cb, + .sofop_data_out = kssl_data_out_cb, + .sofop_mblk_prop = kssl_mblk_prop_cb, + .sofop_getsockname = kssl_getsockname_cb, +}; + +int +_init(void) +{ + int error; + + if ((error = sof_register(SOF_VERSION, KSSL_FILNAME, + &ksslf_ops, 0)) != 0) + return (error); + if ((error = mod_install(&ksslf_modlinkage)) != 0) + (void) sof_unregister(KSSL_FILNAME); + + return (error); +} + +int +_fini(void) +{ + int error; + + if ((error = sof_unregister(KSSL_FILNAME)) != 0) + return (error); + + return (mod_remove(&ksslf_modlinkage)); +} + +int +_info(struct modinfo *modinfop) +{ + return (mod_info(&ksslf_modlinkage, modinfop)); +} diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/kssl/ksslimpl.h --- a/usr/src/uts/common/inet/kssl/ksslimpl.h Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/kssl/ksslimpl.h Thu Jun 17 17:23:59 2010 -0700 @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _INET_KSSL_KSSLIMPL_H @@ -136,21 +135,6 @@ } \ } -#define KSSL_SSL_REFHOLD(ssl) { \ - atomic_add_32(&(ssl)->kssl_refcnt, 1); \ - ASSERT((ssl)->kssl_refcnt != 0); \ - ASSERT((ssl)->kssl_refcnt < 100000); \ -} - -#define KSSL_SSL_REFRELE(ssl) { \ - ASSERT((ssl)->kssl_refcnt != 0); \ - ASSERT((ssl)->kssl_refcnt < 100000); \ - membar_exit(); \ - if (atomic_add_32_nv(&(ssl)->kssl_refcnt, -1) == 0) { \ - kssl_free_context((ssl)); \ - } \ -} - #define CRYPTO_ERR(r) ((r) != CRYPTO_SUCCESS && (r) != CRYPTO_QUEUED) /* @@ -181,7 +165,6 @@ extern crypto_call_flag_t kssl_call_flag; extern KSSLCipherDef cipher_defs[]; -extern int kssl_cache_count; extern struct kmem_cache *kssl_cache; #define KSSL_TAB_INITSIZE 4 diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/kssl/ksslproto.h --- a/usr/src/uts/common/inet/kssl/ksslproto.h Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/kssl/ksslproto.h Thu Jun 17 17:23:59 2010 -0700 @@ -275,14 +275,13 @@ } KSSLCipherSpec; /* - * SSL connection state. This one hangs off of a tcp_t structure. + * SSL connection state. This one hangs off of a ksslf_t structure. */ typedef struct ssl_s { kmutex_t kssl_lock; struct kssl_entry_s *kssl_entry; mblk_t *rec_ass_head; mblk_t *rec_ass_tail; - uint_t kssl_refcnt; in6_addr_t faddr; uint32_t tcp_mss; SSL3WaitState hs_waitstate; @@ -320,6 +319,8 @@ uchar_t major_version; uchar_t minor_version; boolean_t secure_renegotiation; + uint_t async_ops_pending; + kcondvar_t async_cv; } ssl_t; #define IS_TLS(s) (s->major_version == 3 && s->minor_version == 1) diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/kssl/ksslrec.c --- a/usr/src/uts/common/inet/kssl/ksslrec.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/kssl/ksslrec.c Thu Jun 17 17:23:59 2010 -0700 @@ -110,7 +110,6 @@ 0x5c, 0x5c, 0x5c, 0x5c }; -int kssl_cache_count; static boolean_t kssl_synchronous = B_FALSE; static void kssl_update_handshake_hashes(ssl_t *, uchar_t *, uint_t); @@ -232,14 +231,12 @@ /* * The calling context can tolerate a blocking call here. - * For outgoing traffic, we are in user context - * when called from strsock_kssl_output(). For incoming - * traffic past the SSL handshake, we are in user - * context when called from strsock_kssl_input(). During the - * SSL handshake, we are called for client_finished message - * handling from a squeue worker thread that gets scheduled - * by an SQ_FILL call. This thread is not in interrupt - * context and so can block. + * For outgoing traffic, we are in user context when called + * from kssl_data_out_cb(). For incoming traffic past the + * SSL handshake, we are in user context when called from + * kssl_data_in_proc_cb(). During the SSL handshake, we are + * called for client_finished message handling from a taskq + * thread. */ rv = crypto_mac(&spec->hmac_mech, &dd, &spec->hmac_key, NULL, &mac, NULL); @@ -1077,7 +1074,7 @@ { int rv = 0; uchar_t A1[MAX_HASH_LEN], result[MAX_HASH_LEN]; - int bytes_left = datalen; + int bytes_left = (int)datalen; crypto_data_t dd, mac; crypto_context_t ctx; @@ -1625,7 +1622,7 @@ uchar_t *rstart; uchar_t *versionp; SSL3Hashes ssl3hashes; - size_t finish_len; + uchar_t finish_len; int ret; uint16_t adj_len = 0; @@ -1912,9 +1909,6 @@ creq.cr_callback_func = kssl_cke_done; creq.cr_callback_arg = ssl; - /* The callback routine will release this one */ - KSSL_SSL_REFHOLD(ssl); - creqp = &creq; } @@ -2295,22 +2289,15 @@ ssl->activeinput = B_FALSE; - /* If we're the only ones left, then we won't callback */ - if (ssl->kssl_refcnt == 1) { - mutex_exit(&ssl->kssl_lock); - KSSL_SSL_REFRELE(ssl); - return; - } - cbfn = ssl->cke_callback_func; cbarg = ssl->cke_callback_arg; alertmp = ssl->alert_sendbuf; ssl->alert_sendbuf = NULL; + /* dropped by callback when it has completed */ + ssl->async_ops_pending++; mutex_exit(&ssl->kssl_lock); - KSSL_SSL_REFRELE(ssl); - /* Now call the callback routine */ (*(cbfn))(cbarg, alertmp, kssl_cmd); } @@ -2485,20 +2472,42 @@ void kssl_free_context(ssl_t *ssl) { + crypto_req_id_t reqid; + ASSERT(ssl != NULL); if (!(MUTEX_HELD(&ssl->kssl_lock))) { /* we're coming from an external API entry point */ mutex_enter(&ssl->kssl_lock); } - if (ssl->job.kjob != NULL) { - crypto_cancel_req(ssl->job.kjob); - kmem_free(ssl->job.buf, ssl->job.buflen); + /* + * Cancel any active crypto request and wait for pending async + * operations to complete. We loop here because the async thread + * might submit a new cryto request. + */ + do { + if (ssl->job.kjob != NULL) { + /* + * Drop the lock before canceling the request; + * otherwise we might deadlock if the completion + * callback is running. + */ + reqid = ssl->job.kjob; + mutex_exit(&ssl->kssl_lock); + crypto_cancel_req(reqid); + mutex_enter(&ssl->kssl_lock); - ssl->job.kjob = 0; - ssl->job.buf = NULL; - ssl->job.buflen = 0; - } + /* completion callback might have done the cleanup */ + if (ssl->job.kjob != NULL) { + kmem_free(ssl->job.buf, ssl->job.buflen); + ssl->job.kjob = 0; + ssl->job.buf = NULL; + ssl->job.buflen = 0; + } + } + while (ssl->async_ops_pending > 0) + cv_wait(&ssl->async_cv, &ssl->kssl_lock); + } while (ssl->job.kjob != NULL); kssl_mblksfree(ssl); kssl_specsfree(ssl); @@ -2509,5 +2518,4 @@ mutex_exit(&ssl->kssl_lock); kmem_cache_free(kssl_cache, ssl); - kssl_cache_count--; } diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/sockmods/sockmod_sdp.c --- a/usr/src/uts/common/inet/sockmods/sockmod_sdp.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/sockmods/sockmod_sdp.c Thu Jun 17 17:23:59 2010 -0700 @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #include @@ -30,10 +29,7 @@ #include #include #include -#include #include -#include -#include #include #include #include "socksdp.h" diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp.h --- a/usr/src/uts/common/inet/tcp.h Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/tcp.h Thu Jun 17 17:23:59 2010 -0700 @@ -43,7 +43,6 @@ #include #include #include -#include /* TCP states */ #define TCPS_CLOSED -6 @@ -423,13 +422,6 @@ /* protected by the tcp_non_sq_lock lock */ uint32_t tcp_squeue_bytes; - /* - * Kernel SSL session information - */ - boolean_t tcp_kssl_pending; /* waiting for 1st SSL rec. */ - boolean_t tcp_kssl_inhandshake; /* during SSL handshake */ - kssl_ent_t tcp_kssl_ent; /* SSL table entry */ - kssl_ctx_t tcp_kssl_ctx; /* SSL session */ /* * tcp_closemp_used is protected by listener's tcp_eager_lock diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp/tcp.c --- a/usr/src/uts/common/inet/tcp/tcp.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/tcp/tcp.c Thu Jun 17 17:23:59 2010 -0700 @@ -95,7 +95,6 @@ #include #include #include -#include #include #include #include @@ -527,18 +526,6 @@ tcp_free(tcp); - /* Release any SSL context */ - if (tcp->tcp_kssl_ent != NULL) { - kssl_release_ent(tcp->tcp_kssl_ent, NULL, KSSL_NO_PROXY); - tcp->tcp_kssl_ent = NULL; - } - - if (tcp->tcp_kssl_ctx != NULL) { - kssl_release_ctx(tcp->tcp_kssl_ctx); - tcp->tcp_kssl_ctx = NULL; - } - tcp->tcp_kssl_pending = B_FALSE; - /* * Since we will bzero the entire structure, we need to * remove it and reinsert it in global hash list. We @@ -1355,17 +1342,6 @@ ASSERT(tcp->tcp_time_wait_prev == NULL); ASSERT(tcp->tcp_time_wait_expire == 0); - /* Release any SSL context */ - if (tcp->tcp_kssl_ent != NULL) { - kssl_release_ent(tcp->tcp_kssl_ent, NULL, KSSL_NO_PROXY); - tcp->tcp_kssl_ent = NULL; - } - if (tcp->tcp_kssl_ctx != NULL) { - kssl_release_ctx(tcp->tcp_kssl_ctx); - tcp->tcp_kssl_ctx = NULL; - } - tcp->tcp_kssl_pending = B_FALSE; - tcp_ipsec_cleanup(tcp); } @@ -1996,20 +1972,6 @@ ASSERT(tcp->tcp_time_wait_prev == NULL); ASSERT(tcp->tcp_time_wait_expire == 0); - if (tcp->tcp_kssl_pending) { - tcp->tcp_kssl_pending = B_FALSE; - - /* Don't reset if the initialized by bind. */ - if (tcp->tcp_kssl_ent != NULL) { - kssl_release_ent(tcp->tcp_kssl_ent, NULL, - KSSL_NO_PROXY); - } - } - if (tcp->tcp_kssl_ctx != NULL) { - kssl_release_ctx(tcp->tcp_kssl_ctx); - tcp->tcp_kssl_ctx = NULL; - } - /* * Reset/preserve other values */ @@ -2335,10 +2297,6 @@ PRESERVE(tcp->tcp_squeue_bytes); - ASSERT(tcp->tcp_kssl_ctx == NULL); - ASSERT(!tcp->tcp_kssl_pending); - PRESERVE(tcp->tcp_kssl_ent); - tcp->tcp_closemp_used = B_FALSE; PRESERVE(tcp->tcp_rsrv_mp); @@ -2583,10 +2541,7 @@ * chunks. We round up the buffer size to the nearest SMSS. */ maxpsz = MSS_ROUNDUP(connp->conn_sndbuf, mss); - if (tcp->tcp_kssl_ctx == NULL) - mss = INFPSZ; - else - mss = SSL3_MAX_RECORD_LEN; + mss = INFPSZ; } else { /* * Set sd_qn_maxpsz to approx half the (receivers) buffer @@ -3183,28 +3138,6 @@ (tcp->tcp_loopback ? 0 : tcp->tcp_tcps->tcps_wroff_xtra); } - /* - * If this is endpoint is handling SSL, then reserve extra - * offset and space at the end. - * Also have the stream head allocate SSL3_MAX_RECORD_LEN packets, - * overriding the previous setting. The extra cost of signing and - * encrypting multiple MSS-size records (12 of them with Ethernet), - * instead of a single contiguous one by the stream head - * largely outweighs the statistical reduction of ACKs, when - * applicable. The peer will also save on decryption and verification - * costs. - */ - if (tcp->tcp_kssl_ctx != NULL) { - sopp.sopp_wroff += SSL3_WROFFSET; - - sopp.sopp_flags |= SOCKOPT_TAIL; - sopp.sopp_tail = SSL3_MAX_TAIL_LEN; - - sopp.sopp_flags |= SOCKOPT_ZCOPY; - sopp.sopp_zcopyflag = ZCVMUNSAFE; - - sopp.sopp_maxblk = SSL3_MAX_RECORD_LEN; - } if (tcp->tcp_loopback) { sopp->sopp_flags |= SOCKOPT_LOOPBACK; sopp->sopp_loopback = B_TRUE; diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp/tcp_fusion.c --- a/usr/src/uts/common/inet/tcp/tcp_fusion.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/tcp/tcp_fusion.c Thu Jun 17 17:23:59 2010 -0700 @@ -153,21 +153,18 @@ /* * Fuse the endpoints; we perform further checks against both * tcp endpoints to ensure that a fusion is allowed to happen. - * In particular we bail out if kernel SSL exists. */ ns = tcps->tcps_netstack; ipst = ns->netstack_ip; if (!tcp->tcp_unfusable && !peer_tcp->tcp_unfusable && - (tcp->tcp_kssl_ent == NULL) && (tcp->tcp_xmit_head == NULL) && - (peer_tcp->tcp_xmit_head == NULL)) { + tcp->tcp_xmit_head == NULL && peer_tcp->tcp_xmit_head == NULL) { mblk_t *mp; queue_t *peer_rq = peer_connp->conn_rq; ASSERT(!TCP_IS_DETACHED(peer_tcp)); ASSERT(tcp->tcp_fused_sigurg_mp == NULL); ASSERT(peer_tcp->tcp_fused_sigurg_mp == NULL); - ASSERT(tcp->tcp_kssl_ctx == NULL); /* * We need to drain data on both endpoints during unfuse. diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp/tcp_input.c --- a/usr/src/uts/common/inet/tcp/tcp_input.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/tcp/tcp_input.c Thu Jun 17 17:23:59 2010 -0700 @@ -165,8 +165,6 @@ static void tcp_set_rto(tcp_t *, time_t); static void tcp_setcred_data(mblk_t *, ip_recv_attr_t *); -extern void tcp_kssl_input(tcp_t *, mblk_t *, cred_t *); - /* * Set the MSS associated with a particular tcp based on its current value, * and a new one passed in. Observe minimums and maximums, and reset other @@ -1535,13 +1533,6 @@ mblk_setcred(tpi_mp, ira->ira_cred, ira->ira_cpid); eager->tcp_conn.tcp_eager_conn_ind = tpi_mp; - - /* Inherit the listener's SSL protection state */ - if ((eager->tcp_kssl_ent = listener->tcp_kssl_ent) != NULL) { - kssl_hold_ent(eager->tcp_kssl_ent); - eager->tcp_kssl_pending = B_TRUE; - } - ASSERT(eager->tcp_ordrel_mp == NULL); /* Inherit the listener's non-STREAMS flag */ @@ -2014,13 +2005,6 @@ #ifdef DEBUG cnt += msgdsize(mp); #endif - /* Does this need SSL processing first? */ - if ((tcp->tcp_kssl_ctx != NULL) && (DB_TYPE(mp) == M_DATA)) { - DTRACE_PROBE1(kssl_mblk__ksslinput_rcvdrain, - mblk_t *, mp); - tcp_kssl_input(tcp, mp, NULL); - continue; - } putnext(q, mp); } #ifdef DEBUG @@ -2787,22 +2771,7 @@ (seg_len > 0 && SEQ_GT(seg_seq + seg_len, tcp->tcp_rnxt))) { TCPS_BUMP_MIB(tcps, tcpInClosed); DTRACE_PROBE2(tcp__trace__recv, mblk_t *, mp, tcp_t *, tcp); - freemsg(mp); - /* - * This could be an SSL closure alert. We're detached so just - * acknowledge it this last time. - */ - if (tcp->tcp_kssl_ctx != NULL) { - kssl_release_ctx(tcp->tcp_kssl_ctx); - tcp->tcp_kssl_ctx = NULL; - - tcp->tcp_rnxt += seg_len; - tcp->tcp_tcpha->tha_ack = htonl(tcp->tcp_rnxt); - flags |= TH_ACK_NEEDED; - goto ack_check; - } - tcp_xmit_ctl("new data when detached", tcp, tcp->tcp_snxt, 0, TH_RST); (void) tcp_clean_death(tcp, EPROTO); @@ -3647,8 +3616,7 @@ DTRACE_TCP5(accept__established, mlbk_t *, NULL, ip_xmit_attr_t *, connp->conn_ixa, void_ip_t *, iphdr, tcp_t *, tcp, tcph_t *, tcpha); - } else if (((tcp->tcp_kssl_ent == NULL) || - !tcp->tcp_kssl_pending)) { + } else { /* * 3-way handshake complete - this is a STREAMS based * socket, so pass up the T_CONN_IND. @@ -4629,9 +4597,6 @@ if (IPCL_IS_NONSTR(connp)) { /* * Non-STREAMS socket - * - * Note that no KSSL processing is done here, because - * KSSL is not supported for non-STREAMS sockets. */ boolean_t push = flags & (TH_PUSH|TH_FIN); int error; @@ -4661,13 +4626,7 @@ * Making M_PCPROTO and MARK messages skip the eager case */ - if (tcp->tcp_kssl_pending) { - DTRACE_PROBE1(kssl_mblk__ksslinput_pending, - mblk_t *, mp); - tcp_kssl_input(tcp, mp, ira->ira_cred); - } else { - tcp_rcv_enqueue(tcp, mp, seg_len, ira->ira_cred); - } + tcp_rcv_enqueue(tcp, mp, seg_len, ira->ira_cred); } else { /* Active STREAMS socket */ if (mp->b_datap->db_type != M_DATA || @@ -4689,25 +4648,12 @@ flags &= ~TH_MARKNEXT_NEEDED; } - /* Does this need SSL processing first? */ - if ((tcp->tcp_kssl_ctx != NULL) && - (DB_TYPE(mp) == M_DATA)) { - DTRACE_PROBE1(kssl_mblk__ksslinput_data1, - mblk_t *, mp); - tcp_kssl_input(tcp, mp, ira->ira_cred); - } else { - if (is_system_labeled()) - tcp_setcred_data(mp, ira); - - putnext(connp->conn_rq, mp); - if (!canputnext(connp->conn_rq)) - tcp->tcp_rwnd -= seg_len; - } - } else if ((tcp->tcp_kssl_ctx != NULL) && - (DB_TYPE(mp) == M_DATA)) { - /* Does this need SSL processing first? */ - DTRACE_PROBE1(kssl_mblk__ksslinput_data2, mblk_t *, mp); - tcp_kssl_input(tcp, mp, ira->ira_cred); + if (is_system_labeled()) + tcp_setcred_data(mp, ira); + + putnext(connp->conn_rq, mp); + if (!canputnext(connp->conn_rq)) + tcp->tcp_rwnd -= seg_len; } else if ((flags & (TH_PUSH|TH_FIN)) || tcp->tcp_rcv_cnt + seg_len >= connp->conn_rcvbuf >> 3) { if (tcp->tcp_rcv_list != NULL) { diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp/tcp_kssl.c --- a/usr/src/uts/common/inet/tcp/tcp_kssl.c Thu Jun 17 17:22:09 2010 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,425 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * For the Kernel SSL proxy - * - * Routines in this file are called on tcp's incoming path, - * tcp_input_data() mainly, and right before the message is - * to be putnext()'ed upstreams. - */ - -static void tcp_kssl_input_callback(void *, mblk_t *, kssl_cmd_t); -static void tcp_kssl_input_asynch(void *, mblk_t *, void *, - ip_recv_attr_t *); - -extern void tcp_output(void *, mblk_t *, void *, ip_recv_attr_t *); -extern void tcp_send_conn_ind(void *, mblk_t *, void *); - -/* - * tcp_input_data() calls this routine for all packet destined to a - * connection to the SSL port, when the SSL kernel proxy is configured - * to intercept and process those packets. - * A packet may carry multiple SSL records, so the function - * calls kssl_input() in a loop, until all records are - * handled. - * As long as this connection is in handshake, that is until the first - * time kssl_input() returns a record to be delivered ustreams, - * we maintain the tcp_kssl_inhandshake, and keep an extra reference on - * the tcp/connp across the call to kssl_input(). The reason is, that - * function may return KSSL_CMD_QUEUED after scheduling an asynchronous - * request and cause tcp_kssl_callback() to be called on a different CPU, - * which could decrement the conn/tcp reference before we get to increment it. - */ -void -tcp_kssl_input(tcp_t *tcp, mblk_t *mp, cred_t *cr) -{ - struct conn_s *connp = tcp->tcp_connp; - tcp_t *listener; - mblk_t *ind_mp; - kssl_cmd_t kssl_cmd; - mblk_t *outmp; - struct T_conn_ind *tci; - boolean_t more = B_FALSE; - boolean_t conn_held = B_FALSE; - boolean_t is_v4; - void *addr; - - if (is_system_labeled() && mp != NULL) { - ASSERT(cr != NULL || msg_getcred(mp, NULL) != NULL); - /* - * Provide for protocols above TCP such as RPC. NOPID leaves - * db_cpid unchanged. - * The cred could have already been set. - */ - if (cr != NULL) - mblk_setcred(mp, cr, NOPID); - } - - /* First time here, allocate the SSL context */ - if (tcp->tcp_kssl_ctx == NULL) { - ASSERT(tcp->tcp_kssl_pending); - - is_v4 = (connp->conn_ipversion == IPV4_VERSION); - if (is_v4) { - addr = &connp->conn_faddr_v4; - } else { - addr = &connp->conn_faddr_v6; - } - - if (kssl_init_context(tcp->tcp_kssl_ent, - addr, is_v4, tcp->tcp_mss, - &(tcp->tcp_kssl_ctx)) != KSSL_STS_OK) { - tcp->tcp_kssl_pending = B_FALSE; - kssl_release_ent(tcp->tcp_kssl_ent, NULL, - KSSL_NO_PROXY); - tcp->tcp_kssl_ent = NULL; - goto no_can_do; - } - tcp->tcp_kssl_inhandshake = B_TRUE; - - /* we won't be needing this one after now */ - kssl_release_ent(tcp->tcp_kssl_ent, NULL, KSSL_NO_PROXY); - tcp->tcp_kssl_ent = NULL; - - } - - if (tcp->tcp_kssl_inhandshake) { - CONN_INC_REF(connp); - conn_held = B_TRUE; - } - - do { - kssl_cmd = kssl_input(tcp->tcp_kssl_ctx, mp, &outmp, - &more, tcp_kssl_input_callback, (void *)tcp); - - switch (kssl_cmd) { - case KSSL_CMD_SEND: - DTRACE_PROBE(kssl_cmd_send); - /* - * We need to increment tcp_squeue_bytes to account - * for the extra bytes internally injected to the - * outgoing flow. tcp_output() will decrement it - * as they are sent out. - */ - mutex_enter(&tcp->tcp_non_sq_lock); - tcp->tcp_squeue_bytes += msgdsize(outmp); - mutex_exit(&tcp->tcp_non_sq_lock); - tcp_output(connp, outmp, NULL, NULL); - - /* FALLTHROUGH */ - case KSSL_CMD_NONE: - DTRACE_PROBE(kssl_cmd_none); - if (tcp->tcp_kssl_pending) { - mblk_t *ctxmp; - - /* - * SSL handshake successfully started - - * pass up the T_CONN_IND - */ - - mp = NULL; - - listener = tcp->tcp_listener; - tcp->tcp_kssl_pending = B_FALSE; - - ind_mp = tcp->tcp_conn.tcp_eager_conn_ind; - ASSERT(ind_mp != NULL); - - ctxmp = allocb(sizeof (kssl_ctx_t), BPRI_MED); - - /* - * Give this session a chance to fall back to - * userland SSL - */ - if (ctxmp == NULL) - goto no_can_do; - - /* - * attach the kssl_ctx to the conn_ind and - * transform it to a T_SSL_PROXY_CONN_IND. - * Hold it so that it stays valid till it - * reaches the stream head. - */ - kssl_hold_ctx(tcp->tcp_kssl_ctx); - *((kssl_ctx_t *)ctxmp->b_rptr) = - tcp->tcp_kssl_ctx; - ctxmp->b_wptr = ctxmp->b_rptr + - sizeof (kssl_ctx_t); - - ind_mp->b_cont = ctxmp; - - tci = (struct T_conn_ind *)ind_mp->b_rptr; - tci->PRIM_type = T_SSL_PROXY_CONN_IND; - - /* - * The code below is copied from tcp_input_data - * delivering the T_CONN_IND on a TCPS_SYN_RCVD, - * and all conn ref cnt comments apply. - */ - tcp->tcp_conn.tcp_eager_conn_ind = NULL; - tcp->tcp_tconnind_started = B_TRUE; - - CONN_INC_REF(connp); - - CONN_INC_REF(listener->tcp_connp); - if (listener->tcp_connp->conn_sqp == - connp->conn_sqp) { - tcp_send_conn_ind(listener->tcp_connp, - ind_mp, - listener->tcp_connp->conn_sqp); - CONN_DEC_REF(listener->tcp_connp); - } else { - SQUEUE_ENTER_ONE( - listener->tcp_connp->conn_sqp, - ind_mp, tcp_send_conn_ind, - listener->tcp_connp, NULL, SQ_FILL, - SQTAG_TCP_CONN_IND); - } - } - break; - - case KSSL_CMD_QUEUED: - DTRACE_PROBE(kssl_cmd_queued); - /* - * We hold the conn_t here because an asynchronous - * request have been queued and - * tcp_kssl_input_callback() will be called later. - * It will release the conn_t - */ - CONN_INC_REF(connp); - break; - - case KSSL_CMD_DELIVER_PROXY: - case KSSL_CMD_DELIVER_SSL: - DTRACE_PROBE(kssl_cmd_proxy__ssl); - /* - * Keep accumulating if not yet accepted. - */ - if (tcp->tcp_listener != NULL) { - DTRACE_PROBE1(kssl_mblk__input_rcv_enqueue, - mblk_t *, outmp); - tcp_rcv_enqueue(tcp, outmp, msgdsize(outmp), - NULL); - } else { - DTRACE_PROBE1(kssl_mblk__input_putnext, - mblk_t *, outmp); - putnext(connp->conn_rq, outmp); - } - /* - * We're at a phase where records are sent upstreams, - * past the handshake - */ - tcp->tcp_kssl_inhandshake = B_FALSE; - break; - - case KSSL_CMD_NOT_SUPPORTED: - DTRACE_PROBE(kssl_cmd_not_supported); - /* - * Stop the SSL processing by the proxy, and - * switch to the userland SSL - */ - if (tcp->tcp_kssl_pending) { - - tcp->tcp_kssl_pending = B_FALSE; - -no_can_do: - DTRACE_PROBE1(kssl_no_can_do, tcp_t *, tcp); - listener = tcp->tcp_listener; - ind_mp = tcp->tcp_conn.tcp_eager_conn_ind; - ASSERT(ind_mp != NULL); - - if (tcp->tcp_kssl_ctx != NULL) { - kssl_release_ctx(tcp->tcp_kssl_ctx); - tcp->tcp_kssl_ctx = NULL; - } - - /* - * Make this a T_SSL_PROXY_CONN_IND, for the - * stream head to deliver it to the SSL - * fall-back listener - */ - tci = (struct T_conn_ind *)ind_mp->b_rptr; - tci->PRIM_type = T_SSL_PROXY_CONN_IND; - - /* - * The code below is copied from tcp_input_data - * delivering the T_CONN_IND on a TCPS_SYN_RCVD, - * and all conn ref cnt comments apply. - */ - tcp->tcp_conn.tcp_eager_conn_ind = NULL; - tcp->tcp_tconnind_started = B_TRUE; - - CONN_INC_REF(connp); - - CONN_INC_REF(listener->tcp_connp); - if (listener->tcp_connp->conn_sqp == - connp->conn_sqp) { - tcp_send_conn_ind(listener->tcp_connp, - ind_mp, - listener->tcp_connp->conn_sqp); - CONN_DEC_REF(listener->tcp_connp); - } else { - SQUEUE_ENTER_ONE( - listener->tcp_connp->conn_sqp, - ind_mp, tcp_send_conn_ind, - listener->tcp_connp, NULL, - SQ_FILL, SQTAG_TCP_CONN_IND); - } - } - if (mp != NULL) - tcp_rcv_enqueue(tcp, mp, msgdsize(mp), NULL); - break; - } - mp = NULL; - } while (more); - - if (conn_held) { - CONN_DEC_REF(connp); - } -} - -/* - * Callback function for the cases kssl_input() had to submit an asynchronous - * job and need to come back when done to carry on the input processing. - * This routine follows the conventions of timeout and interrupt handlers. - * (no blocking, ...) - */ -static void -tcp_kssl_input_callback(void *arg, mblk_t *mp, kssl_cmd_t kssl_cmd) -{ - tcp_t *tcp = (tcp_t *)arg; - conn_t *connp; - mblk_t *sqmp; - - ASSERT(tcp != NULL); - - connp = tcp->tcp_connp; - - ASSERT(connp != NULL); - - switch (kssl_cmd) { - case KSSL_CMD_SEND: - /* I'm coming from an outside perimeter */ - if (mp != NULL) { - /* - * See comment in tcp_kssl_input() call to tcp_output() - */ - mutex_enter(&tcp->tcp_non_sq_lock); - tcp->tcp_squeue_bytes += msgdsize(mp); - mutex_exit(&tcp->tcp_non_sq_lock); - } - CONN_INC_REF(connp); - SQUEUE_ENTER_ONE(connp->conn_sqp, mp, tcp_output, connp, - NULL, tcp_squeue_flag, SQTAG_TCP_OUTPUT); - - /* FALLTHROUGH */ - case KSSL_CMD_NONE: - break; - - case KSSL_CMD_DELIVER_PROXY: - case KSSL_CMD_DELIVER_SSL: - /* - * Keep accumulating if not yet accepted. - */ - if (tcp->tcp_listener != NULL) { - tcp_rcv_enqueue(tcp, mp, msgdsize(mp), NULL); - } else { - putnext(connp->conn_rq, mp); - } - break; - - case KSSL_CMD_NOT_SUPPORTED: - /* Stop the SSL processing */ - kssl_release_ctx(tcp->tcp_kssl_ctx); - tcp->tcp_kssl_ctx = NULL; - } - /* - * Process any input that may have accumulated while we're waiting for - * the call-back. - * We need to re-enter the squeue for this connp, and a new mp is - * necessary. - */ - if ((sqmp = allocb(1, BPRI_MED)) != NULL) { - CONN_INC_REF(connp); - SQUEUE_ENTER_ONE(connp->conn_sqp, sqmp, tcp_kssl_input_asynch, - connp, NULL, SQ_FILL, SQTAG_TCP_KSSL_INPUT); - } else { - DTRACE_PROBE(kssl_err__allocb_failed); - } - CONN_DEC_REF(connp); -} - -/* - * Needed by tcp_kssl_input_callback() to continue processing the incoming - * flow on a tcp_t after an asynchronous callback call. - */ -/* ARGSUSED */ -void -tcp_kssl_input_asynch(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *dummy) -{ - conn_t *connp = (conn_t *)arg; - tcp_t *tcp = connp->conn_tcp; - - ASSERT(connp != NULL); - freemsg(mp); - - /* - * NULL tcp_kssl_ctx means this connection is getting/was closed - * while we're away - */ - if (tcp->tcp_kssl_ctx != NULL) { - tcp_kssl_input(tcp, NULL, NULL); - } -} diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp/tcp_opt_data.c --- a/usr/src/uts/common/inet/tcp/tcp_opt_data.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/tcp/tcp_opt_data.c Thu Jun 17 17:23:59 2010 -0700 @@ -620,7 +620,6 @@ case SO_SND_COPYAVOID: if (!checkonly) { if (tcp->tcp_loopback || - (tcp->tcp_kssl_ctx != NULL) || (onoff != 1) || !tcp_zcopy_check(tcp)) { *outlenp = 0; return (EOPNOTSUPP); diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp/tcp_output.c --- a/usr/src/uts/common/inet/tcp/tcp_output.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/tcp/tcp_output.c Thu Jun 17 17:23:59 2010 -0700 @@ -933,28 +933,6 @@ non_urgent_data: switch ((int)tprim->type) { - case T_SSL_PROXY_BIND_REQ: /* an SSL proxy endpoint bind request */ - /* - * save the kssl_ent_t from the next block, and convert this - * back to a normal bind_req. - */ - if (mp->b_cont != NULL) { - ASSERT(MBLKL(mp->b_cont) >= sizeof (kssl_ent_t)); - - if (tcp->tcp_kssl_ent != NULL) { - kssl_release_ent(tcp->tcp_kssl_ent, NULL, - KSSL_NO_PROXY); - tcp->tcp_kssl_ent = NULL; - } - bcopy(mp->b_cont->b_rptr, &tcp->tcp_kssl_ent, - sizeof (kssl_ent_t)); - kssl_hold_ent(tcp->tcp_kssl_ent); - freemsg(mp->b_cont); - mp->b_cont = NULL; - } - tprim->type = T_BIND_REQ; - - /* FALLTHROUGH */ case O_T_BIND_REQ: /* bind request */ case T_BIND_REQ: /* new semantics bind request */ tcp_tpi_bind(tcp, mp); diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp/tcp_socket.c --- a/usr/src/uts/common/inet/tcp/tcp_socket.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/tcp/tcp_socket.c Thu Jun 17 17:23:59 2010 -0700 @@ -131,13 +131,19 @@ conn_t *lconnp, *econnp; tcp_t *listener, *eager; - lconnp = (conn_t *)lproto_handle; - listener = lconnp->conn_tcp; - ASSERT(listener->tcp_state == TCPS_LISTEN); + /* + * KSSL can move a socket from one listener to another, in which + * case `lproto_handle' points to the new listener. To ensure that + * the original listener is used the information is obtained from + * the eager. + */ econnp = (conn_t *)eproto_handle; eager = econnp->conn_tcp; + ASSERT(IPCL_IS_NONSTR(econnp)); ASSERT(eager->tcp_listener != NULL); - ASSERT(IPCL_IS_NONSTR(econnp)); + listener = eager->tcp_listener; + lconnp = (conn_t *)listener->tcp_connp; + ASSERT(listener->tcp_state == TCPS_LISTEN); ASSERT(lconnp->conn_upper_handle != NULL); /* diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/inet/tcp/tcp_tpi.c --- a/usr/src/uts/common/inet/tcp/tcp_tpi.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/inet/tcp/tcp_tpi.c Thu Jun 17 17:23:59 2010 -0700 @@ -1141,14 +1141,6 @@ stropt->so_wroff = sopp.sopp_wroff; stropt->so_maxblk = sopp.sopp_maxblk; - if (sopp.sopp_flags & SOCKOPT_TAIL) { - ASSERT(tcp->tcp_kssl_ctx != NULL); - - stropt->so_flags |= SO_TAIL | SO_COPYOPT; - stropt->so_tail = sopp.sopp_tail; - stropt->so_copyopt = sopp.sopp_zcopyflag; - } - /* Send the options up */ putnext(q, mp); @@ -1224,6 +1216,71 @@ (connp->conn_fanout == NULL && connp->conn_ref >= 3)); } +/* + * Pull a deferred connection indication off of the listener. The caller + * must verify that there is a deferred conn ind under eager_lock before + * calling this function. + */ +static mblk_t * +tcp_get_def_conn_ind(tcp_t *listener) +{ + tcp_t *tail; + tcp_t *tcp; + mblk_t *conn_ind; + + ASSERT(MUTEX_HELD(&listener->tcp_eager_lock)); + ASSERT(listener->tcp_eager_prev_q0->tcp_conn_def_q0); + + tcp = listener->tcp_eager_prev_q0; + /* + * listener->tcp_eager_prev_q0 points to the TAIL of the + * deferred T_conn_ind queue. We need to get to the head + * of the queue in order to send up T_conn_ind the same + * order as how the 3WHS is completed. + */ + while (tcp != listener) { + if (!tcp->tcp_eager_prev_q0->tcp_conn_def_q0) + break; + else + tcp = tcp->tcp_eager_prev_q0; + } + + conn_ind = tcp->tcp_conn.tcp_eager_conn_ind; + tcp->tcp_conn.tcp_eager_conn_ind = NULL; + /* Move from q0 to q */ + ASSERT(listener->tcp_conn_req_cnt_q0 > 0); + listener->tcp_conn_req_cnt_q0--; + listener->tcp_conn_req_cnt_q++; + tcp->tcp_eager_next_q0->tcp_eager_prev_q0 = + tcp->tcp_eager_prev_q0; + tcp->tcp_eager_prev_q0->tcp_eager_next_q0 = + tcp->tcp_eager_next_q0; + tcp->tcp_eager_prev_q0 = NULL; + tcp->tcp_eager_next_q0 = NULL; + tcp->tcp_conn_def_q0 = B_FALSE; + + /* Make sure the tcp isn't in the list of droppables */ + ASSERT(tcp->tcp_eager_next_drop_q0 == NULL && + tcp->tcp_eager_prev_drop_q0 == NULL); + + /* + * Insert at end of the queue because sockfs sends + * down T_CONN_RES in chronological order. Leaving + * the older conn indications at front of the queue + * helps reducing search time. + */ + tail = listener->tcp_eager_last_q; + if (tail != NULL) { + tail->tcp_eager_next_q = tcp; + } else { + listener->tcp_eager_next_q = tcp; + } + listener->tcp_eager_last_q = tcp; + tcp->tcp_eager_next_q = NULL; + + return (conn_ind); +} + /* * Reply to a clients T_CONN_RES TPI message. This function @@ -1236,7 +1293,6 @@ { tcp_t *acceptor; tcp_t *eager; - tcp_t *tcp; struct T_conn_res *tcr; t_uscalar_t acceptor_id; t_scalar_t seqnum; @@ -1564,7 +1620,6 @@ mutex_enter(&listener->tcp_eager_lock); if (listener->tcp_eager_prev_q0->tcp_conn_def_q0) { - tcp_t *tail; mblk_t *conn_ind; /* @@ -1572,56 +1627,9 @@ * acceptor streams are the same. */ ASSERT(listener != acceptor); - - tcp = listener->tcp_eager_prev_q0; - /* - * listener->tcp_eager_prev_q0 points to the TAIL of the - * deferred T_conn_ind queue. We need to get to the head of - * the queue in order to send up T_conn_ind the same order as - * how the 3WHS is completed. - */ - while (tcp != listener) { - if (!tcp->tcp_eager_prev_q0->tcp_conn_def_q0) - break; - else - tcp = tcp->tcp_eager_prev_q0; - } - ASSERT(tcp != listener); - conn_ind = tcp->tcp_conn.tcp_eager_conn_ind; - ASSERT(conn_ind != NULL); - tcp->tcp_conn.tcp_eager_conn_ind = NULL; - - /* Move from q0 to q */ - ASSERT(listener->tcp_conn_req_cnt_q0 > 0); - listener->tcp_conn_req_cnt_q0--; - listener->tcp_conn_req_cnt_q++; - tcp->tcp_eager_next_q0->tcp_eager_prev_q0 = - tcp->tcp_eager_prev_q0; - tcp->tcp_eager_prev_q0->tcp_eager_next_q0 = - tcp->tcp_eager_next_q0; - tcp->tcp_eager_prev_q0 = NULL; - tcp->tcp_eager_next_q0 = NULL; - tcp->tcp_conn_def_q0 = B_FALSE; - - /* Make sure the tcp isn't in the list of droppables */ - ASSERT(tcp->tcp_eager_next_drop_q0 == NULL && - tcp->tcp_eager_prev_drop_q0 == NULL); - - /* - * Insert at end of the queue because sockfs sends - * down T_CONN_RES in chronological order. Leaving - * the older conn indications at front of the queue - * helps reducing search time. - */ - tail = listener->tcp_eager_last_q; - if (tail != NULL) - tail->tcp_eager_next_q = tcp; - else - listener->tcp_eager_next_q = tcp; - listener->tcp_eager_last_q = tcp; - tcp->tcp_eager_next_q = NULL; + conn_ind = tcp_get_def_conn_ind(listener); mutex_exit(&listener->tcp_eager_lock); - putnext(tcp->tcp_connp->conn_rq, conn_ind); + putnext(listener->tcp_connp->conn_rq, conn_ind); } else { mutex_exit(&listener->tcp_eager_lock); } @@ -1783,69 +1791,14 @@ mutex_enter(&listener->tcp_eager_lock); if (listener->tcp_eager_prev_q0->tcp_conn_def_q0) { - - tcp_t *tail; - tcp_t *tcp; - mblk_t *mp1; - - tcp = listener->tcp_eager_prev_q0; - /* - * listener->tcp_eager_prev_q0 points to the TAIL of the - * deferred T_conn_ind queue. We need to get to the head - * of the queue in order to send up T_conn_ind the same - * order as how the 3WHS is completed. - */ - while (tcp != listener) { - if (!tcp->tcp_eager_prev_q0->tcp_conn_def_q0 && - !tcp->tcp_kssl_pending) - break; - else - tcp = tcp->tcp_eager_prev_q0; - } - /* None of the pending eagers can be sent up now */ - if (tcp == listener) - goto no_more_eagers; - - mp1 = tcp->tcp_conn.tcp_eager_conn_ind; - tcp->tcp_conn.tcp_eager_conn_ind = NULL; - /* Move from q0 to q */ - ASSERT(listener->tcp_conn_req_cnt_q0 > 0); - listener->tcp_conn_req_cnt_q0--; - listener->tcp_conn_req_cnt_q++; - tcp->tcp_eager_next_q0->tcp_eager_prev_q0 = - tcp->tcp_eager_prev_q0; - tcp->tcp_eager_prev_q0->tcp_eager_next_q0 = - tcp->tcp_eager_next_q0; - tcp->tcp_eager_prev_q0 = NULL; - tcp->tcp_eager_next_q0 = NULL; - tcp->tcp_conn_def_q0 = B_FALSE; - - /* Make sure the tcp isn't in the list of droppables */ - ASSERT(tcp->tcp_eager_next_drop_q0 == NULL && - tcp->tcp_eager_prev_drop_q0 == NULL); - - /* - * Insert at end of the queue because sockfs sends - * down T_CONN_RES in chronological order. Leaving - * the older conn indications at front of the queue - * helps reducing search time. - */ - tail = listener->tcp_eager_last_q; - if (tail != NULL) { - tail->tcp_eager_next_q = tcp; - } else { - listener->tcp_eager_next_q = tcp; - } - listener->tcp_eager_last_q = tcp; - tcp->tcp_eager_next_q = NULL; + mblk_t *conn_ind = tcp_get_def_conn_ind(listener); /* Need to get inside the listener perimeter */ CONN_INC_REF(listener->tcp_connp); - SQUEUE_ENTER_ONE(listener->tcp_connp->conn_sqp, mp1, - tcp_send_pending, listener->tcp_connp, NULL, - SQ_FILL, SQTAG_TCP_SEND_PENDING); + SQUEUE_ENTER_ONE(listener->tcp_connp->conn_sqp, + conn_ind, tcp_send_pending, listener->tcp_connp, + NULL, SQ_FILL, SQTAG_TCP_SEND_PENDING); } -no_more_eagers: tcp_eager_unlink(eager); mutex_exit(&listener->tcp_eager_lock); diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/sys/tihdr.h --- a/usr/src/uts/common/sys/tihdr.h Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/sys/tihdr.h Thu Jun 17 17:23:59 2010 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -24,15 +23,12 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _SYS_TIHDR_H #define _SYS_TIHDR_H -#pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 11.4 */ - #include /* * Include declarations implicit to TPI and shared with user level code @@ -171,8 +167,7 @@ #ifdef _KERNEL /* * Sun private TPI extensions. They are currently used for transparently - * passing options through the connection-oriented loopback transport, - * and for setting the kernel SSL proxy. + * passing options through the connection-oriented loopback transport. * Values assigned to them may change. * * T_EXTCONN_IND (extended T_CONN_IND) is used to return dst as well as @@ -182,11 +177,6 @@ #define T_OPTDATA_IND 0x1002 /* data (with options) indication */ #define T_EXTCONN_IND 0x1003 /* extended T_CONN_IND to return dst as well */ -#define T_SSL_PROXY_BIND_REQ 0x1004 /* extended T_BIND_REQ to carry a */ - /* kssl_entry_t to the transport. */ -#define T_SSL_PROXY_CONN_IND 0x1005 /* conn_ind from an SSL proxy */ - /* endpoint, carrying a kssl_ctx_t */ - #endif /* _KERNEL */ /* diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/common/syscall/sendfile.c --- a/usr/src/uts/common/syscall/sendfile.c Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/common/syscall/sendfile.c Thu Jun 17 17:23:59 2010 -0700 @@ -785,11 +785,8 @@ * size, so limit reads to maxblk if * there are filters present. */ - if ((!SOCK_IS_NONSTR(so) && - _SOTOTPI(so)->sti_kssl_ctx - != NULL) || - (so->so_filter_active > 0 && - maxblk != INFPSZ)) + if (so->so_filter_active > 0 && + maxblk != INFPSZ) iov_len = MIN(iov_len, maxblk); aiov.iov_len = iov_len; @@ -941,10 +938,8 @@ * so limit reads to maxblk if there are * filters present. */ - if ((!SOCK_IS_NONSTR(so) && - _SOTOTPI(so)->sti_kssl_ctx != NULL) || - (so->so_filter_active > 0 && - maxblk != INFPSZ)) + if (so->so_filter_active > 0 && + maxblk != INFPSZ) size = MIN(size, maxblk); if (vn_has_flocks(readvp) || diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/intel/Makefile.intel.shared --- a/usr/src/uts/intel/Makefile.intel.shared Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/intel/Makefile.intel.shared Thu Jun 17 17:23:59 2010 -0700 @@ -724,6 +724,7 @@ SOCKET_KMODS += socksctp SOCKET_KMODS += socksdp SOCKET_KMODS += sockrds +SOCKET_KMODS += ksslf # # kiconv modules (/kernel/kiconv): diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/intel/ia32/ml/modstubs.s --- a/usr/src/uts/intel/ia32/ml/modstubs.s Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/intel/ia32/ml/modstubs.s Thu Jun 17 17:23:59 2010 -0700 @@ -1295,24 +1295,6 @@ #endif /* - * Stubs for kssl, the kernel SSL proxy - */ -#ifndef KSSL_MODULE - MODULE(kssl,drv); - NO_UNLOAD_STUB(kssl, kssl_check_proxy, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_handle_mblk, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_input, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_build_record, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_hold_ent, nomod_void); - NO_UNLOAD_STUB(kssl, kssl_release_ent, nomod_void); - NO_UNLOAD_STUB(kssl, kssl_find_fallback, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_init_context, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_hold_ctx, nomod_void); - NO_UNLOAD_STUB(kssl, kssl_release_ctx, nomod_void); - END_MODULE(kssl); -#endif - -/* * Stubs for dcopy, for Intel IOAT KAPIs */ #ifndef DCOPY_MODULE diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/intel/ksslf/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/intel/ksslf/Makefile Thu Jun 17 17:23:59 2010 -0700 @@ -0,0 +1,94 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# +# This makefile drives the production of the kssl socket filter +# kernel module. +# +# intel architecture dependent +# + +# +# Path to the base of the uts directory tree (usually /usr/src/uts). +# +UTSBASE = ../.. + +# +# Define the module and object file sets. +# +MODULE = ksslf +OBJECTS = $(KSSL_SOCKFIL_MOD_OBJS:%=$(OBJS_DIR)/%) +LINTS = $(KSSL_SOCKFIL_MOD_OBJS:%.o=$(LINTS_DIR)/%.ln) +ROOTMODULE = $(ROOT_SOCK_DIR)/$(MODULE) + +# +# Include common rules. +# +include $(UTSBASE)/intel/Makefile.intel + +# +# Define targets +# +ALL_TARGET = $(BINARY) +LINT_TARGET = $(MODULE).lint +INSTALL_TARGET = $(BINARY) $(ROOTMODULE) + +# +# lint pass one enforcement and OS version +# +CFLAGS += $(CCVERBOSE) + +LDFLAGS += -dy -Nmisc/md5 -Nmisc/kcf -Ndrv/kssl -Nfs/sockfs + +# +# For now, disable these lint checks; maintainers should endeavor +# to investigate and remove these for maximum lint coverage. +# Please do not carry these forward to new Makefiles. +# +LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN +LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW + +# +# Default build targets. +# +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +lint: $(LINT_DEPS) + +modlintlib: $(MODLINTLIB_DEPS) + +clean.lint: $(CLEAN_LINT_DEPS) + +install: $(INSTALL_DEPS) + +# +# Include common targets. +# +include $(UTSBASE)/intel/Makefile.targ diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/sparc/Makefile.sparc.shared --- a/usr/src/uts/sparc/Makefile.sparc.shared Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/sparc/Makefile.sparc.shared Thu Jun 17 17:23:59 2010 -0700 @@ -504,6 +504,7 @@ SOCKET_KMODS += socksctp SOCKET_KMODS += socksdp SOCKET_KMODS += sockrds +SOCKET_KMODS += ksslf # # kiconv modules (/kernel/kiconv): diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/sparc/ksslf/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/sparc/ksslf/Makefile Thu Jun 17 17:23:59 2010 -0700 @@ -0,0 +1,94 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# +# This makefile drives the production of the kssl socket filter +# kernel module. +# +# sparc architecture dependent +# + +# +# Path to the base of the uts directory tree (usually /usr/src/uts). +# +UTSBASE = ../.. + +# +# Define the module and object file sets. +# +MODULE = ksslf +OBJECTS = $(KSSL_SOCKFIL_MOD_OBJS:%=$(OBJS_DIR)/%) +LINTS = $(KSSL_SOCKFIL_MOD_OBJS:%.o=$(LINTS_DIR)/%.ln) +ROOTMODULE = $(ROOT_SOCK_DIR)/$(MODULE) + +# +# Include common rules. +# +include $(UTSBASE)/sparc/Makefile.sparc + +# +# Define targets +# +ALL_TARGET = $(BINARY) +LINT_TARGET = $(MODULE).lint +INSTALL_TARGET = $(BINARY) $(ROOTMODULE) + +# +# lint pass one enforcement and OS version +# +CFLAGS += $(CCVERBOSE) + +LDFLAGS += -dy -Nmisc/md5 -Nmisc/kcf -Ndrv/kssl -Nfs/sockfs + +# +# For now, disable these lint checks; maintainers should endeavor +# to investigate and remove these for maximum lint coverage. +# Please do not carry these forward to new Makefiles. +# +LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN +LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW + +# +# Default build targets. +# +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +lint: $(LINT_DEPS) + +modlintlib: $(MODLINTLIB_DEPS) + +clean.lint: $(CLEAN_LINT_DEPS) + +install: $(INSTALL_DEPS) + +# +# Include common targets. +# +include $(UTSBASE)/sparc/Makefile.targ diff -r 044ff822d212 -r 4f9a0cd40c5f usr/src/uts/sparc/ml/modstubs.s --- a/usr/src/uts/sparc/ml/modstubs.s Thu Jun 17 17:22:09 2010 -0700 +++ b/usr/src/uts/sparc/ml/modstubs.s Thu Jun 17 17:23:59 2010 -0700 @@ -1219,24 +1219,6 @@ #endif /* - * Stubs for kssl, the kernel SSL proxy - */ -#ifndef KSSL_MODULE - MODULE(kssl,drv); - NO_UNLOAD_STUB(kssl, kssl_check_proxy, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_handle_mblk, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_input, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_build_record, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_hold_ent, nomod_void); - NO_UNLOAD_STUB(kssl, kssl_release_ent, nomod_void); - NO_UNLOAD_STUB(kssl, kssl_find_fallback, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_init_context, nomod_zero); - NO_UNLOAD_STUB(kssl, kssl_hold_ctx, nomod_void); - NO_UNLOAD_STUB(kssl, kssl_release_ctx, nomod_void); - END_MODULE(kssl); -#endif - -/* * Stubs for dcopy, for Intel IOAT KAPIs */ #ifndef DCOPY_MODULE