xref: /illumos-gate/usr/src/lib/libnsl/nsl/t_look.c (revision 09b0d01c)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
2261961e0fSrobinson 
237c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
247c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
27e8031f0aSraf  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
287c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
29*09b0d01cSGary Mills  * Copyright 2014 Gary Mills
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include "mt.h"
337c478bd9Sstevel@tonic-gate #include <errno.h>
347c478bd9Sstevel@tonic-gate #include <unistd.h>
357c478bd9Sstevel@tonic-gate #include <sys/stream.h>
367c478bd9Sstevel@tonic-gate #include <stropts.h>
377c478bd9Sstevel@tonic-gate #define	_SUN_TPI_VERSION 2
387c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
397c478bd9Sstevel@tonic-gate #include <sys/timod.h>
407c478bd9Sstevel@tonic-gate #include <xti.h>
417c478bd9Sstevel@tonic-gate #include <assert.h>
427c478bd9Sstevel@tonic-gate #include "tx.h"
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate int
_tx_look(int fd,int api_semantics)457c478bd9Sstevel@tonic-gate _tx_look(int fd, int api_semantics)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate 	int state;
487c478bd9Sstevel@tonic-gate 	int sv_errno;
497c478bd9Sstevel@tonic-gate 	int do_expinline_peek;	 /* unusual XTI specific processing */
507c478bd9Sstevel@tonic-gate 	struct _ti_user *tiptr;
517c478bd9Sstevel@tonic-gate 
5261961e0fSrobinson 	if ((tiptr = _t_checkfd(fd, 0, api_semantics)) == NULL)
537c478bd9Sstevel@tonic-gate 		return (-1);
547c478bd9Sstevel@tonic-gate 	sig_mutex_lock(&tiptr->ti_lock);
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate 	if (_T_IS_XTI(api_semantics))
577c478bd9Sstevel@tonic-gate 		do_expinline_peek = 1;
587c478bd9Sstevel@tonic-gate 	else
597c478bd9Sstevel@tonic-gate 		do_expinline_peek = 0;
607c478bd9Sstevel@tonic-gate 	state = _t_look_locked(fd, tiptr, do_expinline_peek, api_semantics);
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	sv_errno = errno;
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	sig_mutex_unlock(&tiptr->ti_lock);
657c478bd9Sstevel@tonic-gate 	errno = sv_errno;
667c478bd9Sstevel@tonic-gate 	return (state);
677c478bd9Sstevel@tonic-gate }
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * _t_look_locked() assumes tiptr->ti_lock lock is already held and signals
717c478bd9Sstevel@tonic-gate  * already blocked in MT case.
727c478bd9Sstevel@tonic-gate  * Intended for use by other TLI routines only.
737c478bd9Sstevel@tonic-gate  */
747c478bd9Sstevel@tonic-gate int
_t_look_locked(int fd,struct _ti_user * tiptr,int do_expinline_peek,int api_semantics)757c478bd9Sstevel@tonic-gate _t_look_locked(
767c478bd9Sstevel@tonic-gate 	int fd,
777c478bd9Sstevel@tonic-gate 	struct _ti_user *tiptr,
787c478bd9Sstevel@tonic-gate 	int do_expinline_peek,
797c478bd9Sstevel@tonic-gate 	int api_semantics
807c478bd9Sstevel@tonic-gate )
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate 	struct strpeek strpeek;
8361961e0fSrobinson 	int retval;
847c478bd9Sstevel@tonic-gate 	union T_primitives *pptr;
857c478bd9Sstevel@tonic-gate 	t_scalar_t type;
867c478bd9Sstevel@tonic-gate 	t_scalar_t ctltype;
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 	assert(MUTEX_HELD(&tiptr->ti_lock));
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate #ifdef notyet
917c478bd9Sstevel@tonic-gate 	if (_T_IS_XTI(api_semantics)) {
927c478bd9Sstevel@tonic-gate 		/*
937c478bd9Sstevel@tonic-gate 		 * XTI requires the strange T_GODATA and T_GOEXDATA
947c478bd9Sstevel@tonic-gate 		 * events which are almost brain-damaged but thankfully
957c478bd9Sstevel@tonic-gate 		 * not tested. Anyone feeling the need for those should
967c478bd9Sstevel@tonic-gate 		 * consider the need for using non-blocking endpoint.
977c478bd9Sstevel@tonic-gate 		 * Probably introduced at the behest of some weird-os
987c478bd9Sstevel@tonic-gate 		 * vendor which did not understand the non-blocking endpoint
997c478bd9Sstevel@tonic-gate 		 * option.
1007c478bd9Sstevel@tonic-gate 		 * We choose not to implment these mis-features.
1017c478bd9Sstevel@tonic-gate 		 * Here is the plan-of-action (POA)if we are ever forced
1027c478bd9Sstevel@tonic-gate 		 * to implement these.
1037c478bd9Sstevel@tonic-gate 		 * - When returning TFLOW set state to indicate if it was
1047c478bd9Sstevel@tonic-gate 		 *   a normal or expedited data send attempt.
1057c478bd9Sstevel@tonic-gate 		 * - In routines that set TFLOW, clear the above set state
1067c478bd9Sstevel@tonic-gate 		 *   on each entry/reentry
1077c478bd9Sstevel@tonic-gate 		 * - In this routine, if that state flag is set,
1087c478bd9Sstevel@tonic-gate 		 * do a I_CANPUT on appropriate band to to see if it
1097c478bd9Sstevel@tonic-gate 		 * is writeable. If that indicates that the band is
1107c478bd9Sstevel@tonic-gate 		 * writeable, return T_GODATA or T_GOEXDATA event.
1117c478bd9Sstevel@tonic-gate 		 *
1127c478bd9Sstevel@tonic-gate 		 * Actions are also influenced by whether T_EXDATA_REQ stays
1137c478bd9Sstevel@tonic-gate 		 * band 1 or goes to band 0 if EXPINLINE is set
1147c478bd9Sstevel@tonic-gate 		 *
1157c478bd9Sstevel@tonic-gate 		 * We will also need to sort out if "write side" events
1167c478bd9Sstevel@tonic-gate 		 * (such as T_GODATA/T_GOEXDATA) take precedence over
1177c478bd9Sstevel@tonic-gate 		 * all other events (all read side) or not.
1187c478bd9Sstevel@tonic-gate 		 */
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate #endif /* notyet */
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	strpeek.ctlbuf.maxlen = (int)sizeof (ctltype);
1237c478bd9Sstevel@tonic-gate 	strpeek.ctlbuf.len = 0;
1247c478bd9Sstevel@tonic-gate 	strpeek.ctlbuf.buf = (char *)&ctltype;
1257c478bd9Sstevel@tonic-gate 	strpeek.databuf.maxlen = 0;
1267c478bd9Sstevel@tonic-gate 	strpeek.databuf.len = 0;
1277c478bd9Sstevel@tonic-gate 	strpeek.databuf.buf = NULL;
1287c478bd9Sstevel@tonic-gate 	strpeek.flags = 0;
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	do {
131e8031f0aSraf 		retval = ioctl(fd, I_PEEK, &strpeek);
1327c478bd9Sstevel@tonic-gate 	} while (retval < 0 && errno == EINTR);
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	if (retval < 0) {
13561961e0fSrobinson 		/*
136*09b0d01cSGary Mills 		 * XTI semantics (also identical to documented
137*09b0d01cSGary Mills 		 * TLI semantics).
13861961e0fSrobinson 		 */
13961961e0fSrobinson 		t_errno = TSYSERR;
14061961e0fSrobinson 		return (-1);
1417c478bd9Sstevel@tonic-gate 	}
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	/*
1447c478bd9Sstevel@tonic-gate 	 * if something there and cntl part also there
1457c478bd9Sstevel@tonic-gate 	 */
1467c478bd9Sstevel@tonic-gate 	if ((tiptr->ti_lookcnt > 0) ||
147*09b0d01cSGary Mills 	    ((retval > 0) && (strpeek.ctlbuf.len >=
148*09b0d01cSGary Mills 	    (int)sizeof (t_scalar_t)))) {
14961961e0fSrobinson 		/* LINTED pointer cast */
1507c478bd9Sstevel@tonic-gate 		pptr = (union T_primitives *)strpeek.ctlbuf.buf;
1517c478bd9Sstevel@tonic-gate 		if (tiptr->ti_lookcnt > 0) {
15261961e0fSrobinson 			/* LINTED pointer cast */
1537c478bd9Sstevel@tonic-gate 			type = *((t_scalar_t *)tiptr->ti_lookbufs.tl_lookcbuf);
1547c478bd9Sstevel@tonic-gate 			/*
1557c478bd9Sstevel@tonic-gate 			 * If message on stream head is a T_DISCON_IND, that
1567c478bd9Sstevel@tonic-gate 			 * has priority over a T_ORDREL_IND in the look
1577c478bd9Sstevel@tonic-gate 			 * buffer.
1587c478bd9Sstevel@tonic-gate 			 * (This assumes that T_ORDREL_IND can only be in the
1597c478bd9Sstevel@tonic-gate 			 * first look buffer in the list)
1607c478bd9Sstevel@tonic-gate 			 */
1617c478bd9Sstevel@tonic-gate 			if ((type == T_ORDREL_IND) && retval &&
1627c478bd9Sstevel@tonic-gate 			    (pptr->type == T_DISCON_IND)) {
1637c478bd9Sstevel@tonic-gate 				type = pptr->type;
1647c478bd9Sstevel@tonic-gate 				/*
1657c478bd9Sstevel@tonic-gate 				 * Blow away T_ORDREL_IND
1667c478bd9Sstevel@tonic-gate 				 */
1677c478bd9Sstevel@tonic-gate 				_t_free_looklist_head(tiptr);
1687c478bd9Sstevel@tonic-gate 			}
1697c478bd9Sstevel@tonic-gate 		} else
1707c478bd9Sstevel@tonic-gate 			type = pptr->type;
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 		switch (type) {
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 		case T_CONN_IND:
1757c478bd9Sstevel@tonic-gate 			return (T_LISTEN);
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 		case T_CONN_CON:
1787c478bd9Sstevel@tonic-gate 			return (T_CONNECT);
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 		case T_DISCON_IND:
1817c478bd9Sstevel@tonic-gate 			return (T_DISCONNECT);
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 		case T_DATA_IND: {
1847c478bd9Sstevel@tonic-gate 			int event = T_DATA;
1857c478bd9Sstevel@tonic-gate 			int retval, exp_on_q;
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 			if (do_expinline_peek &&
1887c478bd9Sstevel@tonic-gate 			    (tiptr->ti_prov_flag & EXPINLINE)) {
1897c478bd9Sstevel@tonic-gate 				assert(_T_IS_XTI(api_semantics));
1907c478bd9Sstevel@tonic-gate 				retval = _t_expinline_queued(fd, &exp_on_q);
1917c478bd9Sstevel@tonic-gate 				if (retval < 0) {
1927c478bd9Sstevel@tonic-gate 					t_errno = TSYSERR;
1937c478bd9Sstevel@tonic-gate 					return (-1);
1947c478bd9Sstevel@tonic-gate 				}
1957c478bd9Sstevel@tonic-gate 				if (exp_on_q)
1967c478bd9Sstevel@tonic-gate 					event = T_EXDATA;
1977c478bd9Sstevel@tonic-gate 			}
1987c478bd9Sstevel@tonic-gate 			return (event);
1997c478bd9Sstevel@tonic-gate 		}
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 		case T_UNITDATA_IND:
2027c478bd9Sstevel@tonic-gate 			return (T_DATA);
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 		case T_EXDATA_IND:
2057c478bd9Sstevel@tonic-gate 			return (T_EXDATA);
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 		case T_UDERROR_IND:
2087c478bd9Sstevel@tonic-gate 			return (T_UDERR);
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 		case T_ORDREL_IND:
2117c478bd9Sstevel@tonic-gate 			return (T_ORDREL);
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 		default:
2147c478bd9Sstevel@tonic-gate 			t_errno = TSYSERR;
2157c478bd9Sstevel@tonic-gate 			errno = EPROTO;
2167c478bd9Sstevel@tonic-gate 			return (-1);
2177c478bd9Sstevel@tonic-gate 		}
2187c478bd9Sstevel@tonic-gate 	}
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 	/*
2217c478bd9Sstevel@tonic-gate 	 * if something there put no control part
2227c478bd9Sstevel@tonic-gate 	 * it must be data on the stream head.
2237c478bd9Sstevel@tonic-gate 	 */
2247c478bd9Sstevel@tonic-gate 	if ((retval > 0) && (strpeek.ctlbuf.len <= 0)) {
2257c478bd9Sstevel@tonic-gate 		int event = T_DATA;
2267c478bd9Sstevel@tonic-gate 		int retval, exp_on_q;
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 		if (do_expinline_peek &&
2297c478bd9Sstevel@tonic-gate 		    (tiptr->ti_prov_flag & EXPINLINE)) {
2307c478bd9Sstevel@tonic-gate 			assert(_T_IS_XTI(api_semantics));
2317c478bd9Sstevel@tonic-gate 			retval = _t_expinline_queued(fd, &exp_on_q);
23261961e0fSrobinson 			if (retval < 0)
2337c478bd9Sstevel@tonic-gate 				return (-1);
2347c478bd9Sstevel@tonic-gate 			if (exp_on_q)
2357c478bd9Sstevel@tonic-gate 				event = T_EXDATA;
2367c478bd9Sstevel@tonic-gate 		}
2377c478bd9Sstevel@tonic-gate 		return (event);
2387c478bd9Sstevel@tonic-gate 	}
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	/*
2417c478bd9Sstevel@tonic-gate 	 * if msg there and control
2427c478bd9Sstevel@tonic-gate 	 * part not large enough to determine type?
2437c478bd9Sstevel@tonic-gate 	 * it must be illegal TLI message
2447c478bd9Sstevel@tonic-gate 	 */
2457c478bd9Sstevel@tonic-gate 	if ((retval > 0) && (strpeek.ctlbuf.len > 0)) {
2467c478bd9Sstevel@tonic-gate 		t_errno = TSYSERR;
2477c478bd9Sstevel@tonic-gate 		errno = EPROTO;
2487c478bd9Sstevel@tonic-gate 		return (-1);
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate 	return (0);
2517c478bd9Sstevel@tonic-gate }
252