xref: /onnv-gate/usr/src/lib/libnsl/nsl/t_look.c (revision 1219:f89f56c2d9ac)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
22132Srobinson 
230Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
240Sstevel@tonic-gate /*	  All Rights Reserved  	*/
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
27*1219Sraf  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
280Sstevel@tonic-gate  * Use is subject to license terms.
290Sstevel@tonic-gate  */
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #include "mt.h"
340Sstevel@tonic-gate #include <errno.h>
350Sstevel@tonic-gate #include <unistd.h>
360Sstevel@tonic-gate #include <sys/stream.h>
370Sstevel@tonic-gate #include <stropts.h>
380Sstevel@tonic-gate #define	_SUN_TPI_VERSION 2
390Sstevel@tonic-gate #include <sys/tihdr.h>
400Sstevel@tonic-gate #include <sys/timod.h>
410Sstevel@tonic-gate #include <xti.h>
420Sstevel@tonic-gate #include <assert.h>
430Sstevel@tonic-gate #include "tx.h"
440Sstevel@tonic-gate 
450Sstevel@tonic-gate int
_tx_look(int fd,int api_semantics)460Sstevel@tonic-gate _tx_look(int fd, int api_semantics)
470Sstevel@tonic-gate {
480Sstevel@tonic-gate 	int state;
490Sstevel@tonic-gate 	int sv_errno;
500Sstevel@tonic-gate 	int do_expinline_peek;	 /* unusual XTI specific processing */
510Sstevel@tonic-gate 	struct _ti_user *tiptr;
520Sstevel@tonic-gate 
53132Srobinson 	if ((tiptr = _t_checkfd(fd, 0, api_semantics)) == NULL)
540Sstevel@tonic-gate 		return (-1);
550Sstevel@tonic-gate 	sig_mutex_lock(&tiptr->ti_lock);
560Sstevel@tonic-gate 
570Sstevel@tonic-gate 	if (_T_IS_XTI(api_semantics))
580Sstevel@tonic-gate 		do_expinline_peek = 1;
590Sstevel@tonic-gate 	else
600Sstevel@tonic-gate 		do_expinline_peek = 0;
610Sstevel@tonic-gate 	state = _t_look_locked(fd, tiptr, do_expinline_peek, api_semantics);
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	sv_errno = errno;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	sig_mutex_unlock(&tiptr->ti_lock);
660Sstevel@tonic-gate 	errno = sv_errno;
670Sstevel@tonic-gate 	return (state);
680Sstevel@tonic-gate }
690Sstevel@tonic-gate 
700Sstevel@tonic-gate /*
710Sstevel@tonic-gate  * _t_look_locked() assumes tiptr->ti_lock lock is already held and signals
720Sstevel@tonic-gate  * already blocked in MT case.
730Sstevel@tonic-gate  * Intended for use by other TLI routines only.
740Sstevel@tonic-gate  */
750Sstevel@tonic-gate int
_t_look_locked(int fd,struct _ti_user * tiptr,int do_expinline_peek,int api_semantics)760Sstevel@tonic-gate _t_look_locked(
770Sstevel@tonic-gate 	int fd,
780Sstevel@tonic-gate 	struct _ti_user *tiptr,
790Sstevel@tonic-gate 	int do_expinline_peek,
800Sstevel@tonic-gate 	int api_semantics
810Sstevel@tonic-gate )
820Sstevel@tonic-gate {
830Sstevel@tonic-gate 	struct strpeek strpeek;
84132Srobinson 	int retval;
850Sstevel@tonic-gate 	union T_primitives *pptr;
860Sstevel@tonic-gate 	t_scalar_t type;
870Sstevel@tonic-gate 	t_scalar_t ctltype;
880Sstevel@tonic-gate 
890Sstevel@tonic-gate 	assert(MUTEX_HELD(&tiptr->ti_lock));
900Sstevel@tonic-gate 
910Sstevel@tonic-gate #ifdef notyet
920Sstevel@tonic-gate 	if (_T_IS_XTI(api_semantics)) {
930Sstevel@tonic-gate 		/*
940Sstevel@tonic-gate 		 * XTI requires the strange T_GODATA and T_GOEXDATA
950Sstevel@tonic-gate 		 * events which are almost brain-damaged but thankfully
960Sstevel@tonic-gate 		 * not tested. Anyone feeling the need for those should
970Sstevel@tonic-gate 		 * consider the need for using non-blocking endpoint.
980Sstevel@tonic-gate 		 * Probably introduced at the behest of some weird-os
990Sstevel@tonic-gate 		 * vendor which did not understand the non-blocking endpoint
1000Sstevel@tonic-gate 		 * option.
1010Sstevel@tonic-gate 		 * We choose not to implment these mis-features.
1020Sstevel@tonic-gate 		 * Here is the plan-of-action (POA)if we are ever forced
1030Sstevel@tonic-gate 		 * to implement these.
1040Sstevel@tonic-gate 		 * - When returning TFLOW set state to indicate if it was
1050Sstevel@tonic-gate 		 *   a normal or expedited data send attempt.
1060Sstevel@tonic-gate 		 * - In routines that set TFLOW, clear the above set state
1070Sstevel@tonic-gate 		 *   on each entry/reentry
1080Sstevel@tonic-gate 		 * - In this routine, if that state flag is set,
1090Sstevel@tonic-gate 		 * do a I_CANPUT on appropriate band to to see if it
1100Sstevel@tonic-gate 		 * is writeable. If that indicates that the band is
1110Sstevel@tonic-gate 		 * writeable, return T_GODATA or T_GOEXDATA event.
1120Sstevel@tonic-gate 		 *
1130Sstevel@tonic-gate 		 * Actions are also influenced by whether T_EXDATA_REQ stays
1140Sstevel@tonic-gate 		 * band 1 or goes to band 0 if EXPINLINE is set
1150Sstevel@tonic-gate 		 *
1160Sstevel@tonic-gate 		 * We will also need to sort out if "write side" events
1170Sstevel@tonic-gate 		 * (such as T_GODATA/T_GOEXDATA) take precedence over
1180Sstevel@tonic-gate 		 * all other events (all read side) or not.
1190Sstevel@tonic-gate 		 */
1200Sstevel@tonic-gate 	}
1210Sstevel@tonic-gate #endif /* notyet */
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	strpeek.ctlbuf.maxlen = (int)sizeof (ctltype);
1240Sstevel@tonic-gate 	strpeek.ctlbuf.len = 0;
1250Sstevel@tonic-gate 	strpeek.ctlbuf.buf = (char *)&ctltype;
1260Sstevel@tonic-gate 	strpeek.databuf.maxlen = 0;
1270Sstevel@tonic-gate 	strpeek.databuf.len = 0;
1280Sstevel@tonic-gate 	strpeek.databuf.buf = NULL;
1290Sstevel@tonic-gate 	strpeek.flags = 0;
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	do {
132*1219Sraf 		retval = ioctl(fd, I_PEEK, &strpeek);
1330Sstevel@tonic-gate 	} while (retval < 0 && errno == EINTR);
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	if (retval < 0) {
1360Sstevel@tonic-gate 		if (_T_IS_TLI(api_semantics)) {
1370Sstevel@tonic-gate 			/*
1380Sstevel@tonic-gate 			 * This return of T_ERROR event is ancient
1390Sstevel@tonic-gate 			 * SVR3 TLI semantics and not documented for
1400Sstevel@tonic-gate 			 * current SVR4 TLI interface.
1410Sstevel@tonic-gate 			 * Fixing this will impact some apps
1420Sstevel@tonic-gate 			 * (e.g. nfsd,lockd) in ON consolidation
1430Sstevel@tonic-gate 			 * so they need to be fixed first before TLI
1440Sstevel@tonic-gate 			 * can be fixed.
1450Sstevel@tonic-gate 			 * XXX Should we never fix this because it might
1460Sstevel@tonic-gate 			 * break apps in field ?
1470Sstevel@tonic-gate 			 */
1480Sstevel@tonic-gate 			return (T_ERROR);
1490Sstevel@tonic-gate 		}
150132Srobinson 		/*
151132Srobinson 		 * XTI semantics (also identical to documented,
152132Srobinson 		 * but not implemented TLI semantics).
153132Srobinson 		 */
154132Srobinson 		t_errno = TSYSERR;
155132Srobinson 		return (-1);
1560Sstevel@tonic-gate 	}
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	/*
1590Sstevel@tonic-gate 	 * if something there and cntl part also there
1600Sstevel@tonic-gate 	 */
1610Sstevel@tonic-gate 	if ((tiptr->ti_lookcnt > 0) ||
1620Sstevel@tonic-gate 	((retval > 0) && (strpeek.ctlbuf.len >= (int)sizeof (t_scalar_t)))) {
163132Srobinson 		/* LINTED pointer cast */
1640Sstevel@tonic-gate 		pptr = (union T_primitives *)strpeek.ctlbuf.buf;
1650Sstevel@tonic-gate 		if (tiptr->ti_lookcnt > 0) {
166132Srobinson 			/* LINTED pointer cast */
1670Sstevel@tonic-gate 			type = *((t_scalar_t *)tiptr->ti_lookbufs.tl_lookcbuf);
1680Sstevel@tonic-gate 			/*
1690Sstevel@tonic-gate 			 * If message on stream head is a T_DISCON_IND, that
1700Sstevel@tonic-gate 			 * has priority over a T_ORDREL_IND in the look
1710Sstevel@tonic-gate 			 * buffer.
1720Sstevel@tonic-gate 			 * (This assumes that T_ORDREL_IND can only be in the
1730Sstevel@tonic-gate 			 * first look buffer in the list)
1740Sstevel@tonic-gate 			 */
1750Sstevel@tonic-gate 			if ((type == T_ORDREL_IND) && retval &&
1760Sstevel@tonic-gate 			    (pptr->type == T_DISCON_IND)) {
1770Sstevel@tonic-gate 				type = pptr->type;
1780Sstevel@tonic-gate 				/*
1790Sstevel@tonic-gate 				 * Blow away T_ORDREL_IND
1800Sstevel@tonic-gate 				 */
1810Sstevel@tonic-gate 				_t_free_looklist_head(tiptr);
1820Sstevel@tonic-gate 			}
1830Sstevel@tonic-gate 		} else
1840Sstevel@tonic-gate 			type = pptr->type;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 		switch (type) {
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 		case T_CONN_IND:
1890Sstevel@tonic-gate 			return (T_LISTEN);
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 		case T_CONN_CON:
1920Sstevel@tonic-gate 			return (T_CONNECT);
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 		case T_DISCON_IND:
1950Sstevel@tonic-gate 			return (T_DISCONNECT);
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 		case T_DATA_IND: {
1980Sstevel@tonic-gate 			int event = T_DATA;
1990Sstevel@tonic-gate 			int retval, exp_on_q;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 			if (do_expinline_peek &&
2020Sstevel@tonic-gate 			    (tiptr->ti_prov_flag & EXPINLINE)) {
2030Sstevel@tonic-gate 				assert(_T_IS_XTI(api_semantics));
2040Sstevel@tonic-gate 				retval = _t_expinline_queued(fd, &exp_on_q);
2050Sstevel@tonic-gate 				if (retval < 0) {
2060Sstevel@tonic-gate 					t_errno = TSYSERR;
2070Sstevel@tonic-gate 					return (-1);
2080Sstevel@tonic-gate 				}
2090Sstevel@tonic-gate 				if (exp_on_q)
2100Sstevel@tonic-gate 					event = T_EXDATA;
2110Sstevel@tonic-gate 			}
2120Sstevel@tonic-gate 			return (event);
2130Sstevel@tonic-gate 		}
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 		case T_UNITDATA_IND:
2160Sstevel@tonic-gate 			return (T_DATA);
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 		case T_EXDATA_IND:
2190Sstevel@tonic-gate 			return (T_EXDATA);
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate 		case T_UDERROR_IND:
2220Sstevel@tonic-gate 			return (T_UDERR);
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 		case T_ORDREL_IND:
2250Sstevel@tonic-gate 			return (T_ORDREL);
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 		default:
2280Sstevel@tonic-gate 			t_errno = TSYSERR;
2290Sstevel@tonic-gate 			errno = EPROTO;
2300Sstevel@tonic-gate 			return (-1);
2310Sstevel@tonic-gate 		}
2320Sstevel@tonic-gate 	}
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	/*
2350Sstevel@tonic-gate 	 * if something there put no control part
2360Sstevel@tonic-gate 	 * it must be data on the stream head.
2370Sstevel@tonic-gate 	 */
2380Sstevel@tonic-gate 	if ((retval > 0) && (strpeek.ctlbuf.len <= 0)) {
2390Sstevel@tonic-gate 		int event = T_DATA;
2400Sstevel@tonic-gate 		int retval, exp_on_q;
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 		if (do_expinline_peek &&
2430Sstevel@tonic-gate 		    (tiptr->ti_prov_flag & EXPINLINE)) {
2440Sstevel@tonic-gate 			assert(_T_IS_XTI(api_semantics));
2450Sstevel@tonic-gate 			retval = _t_expinline_queued(fd, &exp_on_q);
246132Srobinson 			if (retval < 0)
2470Sstevel@tonic-gate 				return (-1);
2480Sstevel@tonic-gate 			if (exp_on_q)
2490Sstevel@tonic-gate 				event = T_EXDATA;
2500Sstevel@tonic-gate 		}
2510Sstevel@tonic-gate 		return (event);
2520Sstevel@tonic-gate 	}
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	/*
2550Sstevel@tonic-gate 	 * if msg there and control
2560Sstevel@tonic-gate 	 * part not large enough to determine type?
2570Sstevel@tonic-gate 	 * it must be illegal TLI message
2580Sstevel@tonic-gate 	 */
2590Sstevel@tonic-gate 	if ((retval > 0) && (strpeek.ctlbuf.len > 0)) {
2600Sstevel@tonic-gate 		t_errno = TSYSERR;
2610Sstevel@tonic-gate 		errno = EPROTO;
2620Sstevel@tonic-gate 		return (-1);
2630Sstevel@tonic-gate 	}
2640Sstevel@tonic-gate 	return (0);
2650Sstevel@tonic-gate }
266