4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
24 /* All Rights Reserved */
27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.3.4.1 */
38 #include <sys/stream.h>
39 #define _SUN_TPI_VERSION 2
40 #include <sys/tihdr.h>
41 #include <sys/timod.h>
50 const struct t_bind
*req
,
55 struct T_bind_req
*bind_reqp
;
56 struct T_bind_ack
*bind_ackp
;
57 int size
, sv_errno
, retlen
;
58 struct _ti_user
*tiptr
;
65 if ((tiptr
= _t_checkfd(fd
, 0, api_semantics
)) == NULL
)
69 * We block all signals since TI_BIND, which sends a TPI message
70 * O_T_BIND_REQ down, is not an idempotetent operation
71 * Note that sig_mutex_lock() only defers signals, it does not
72 * block them, so interruptible syscalls could still get EINTR.
74 (void) thr_sigsetmask(SIG_SETMASK
, &fillset
, &mask
);
75 sig_mutex_lock(&tiptr
->ti_lock
);
76 if (_T_IS_XTI(api_semantics
)) {
78 * User level state verification only done for XTI
79 * because doing for TLI may break existing applications
81 if (tiptr
->ti_state
!= T_UNBND
) {
83 sig_mutex_unlock(&tiptr
->ti_lock
);
84 (void) thr_sigsetmask(SIG_SETMASK
, &mask
, NULL
);
89 * Acquire buffer for use in sending/receiving the message.
90 * Note: assumes (correctly) that ti_ctlsize is large enough
91 * to hold sizeof (struct T_bind_req/ack)
93 if (_t_acquire_ctlbuf(tiptr
, &ctlbuf
, &didalloc
) < 0) {
95 sig_mutex_unlock(&tiptr
->ti_lock
);
96 (void) thr_sigsetmask(SIG_SETMASK
, &mask
, NULL
);
101 /* LINTED pointer cast */
102 bind_reqp
= (struct T_bind_req
*)ctlbuf
.buf
;
103 size
= (int)sizeof (struct T_bind_req
);
105 use_xpg41tpi
= (_T_IS_XTI(api_semantics
)) &&
106 ((tiptr
->ti_prov_flag
& XPG4_1
) != 0);
108 /* XTI call and provider knows the XTI inspired TPI */
109 bind_reqp
->PRIM_type
= T_BIND_REQ
;
111 /* TLI caller old TPI provider */
112 bind_reqp
->PRIM_type
= O_T_BIND_REQ
;
114 bind_reqp
->ADDR_length
= (req
== NULL
? 0: req
->addr
.len
);
115 bind_reqp
->ADDR_offset
= 0;
116 bind_reqp
->CONIND_number
= (req
== NULL
? 0: req
->qlen
);
119 if (bind_reqp
->ADDR_length
) {
120 if (_t_aligned_copy(&ctlbuf
, (int)bind_reqp
->ADDR_length
, size
,
121 req
->addr
.buf
, &bind_reqp
->ADDR_offset
) < 0) {
123 * Aligned copy will overflow buffer allocated based
124 * on transport maximum address length.
130 size
= bind_reqp
->ADDR_offset
+ bind_reqp
->ADDR_length
;
133 if (_t_do_ioctl(fd
, ctlbuf
.buf
, size
, TI_BIND
, &retlen
) < 0) {
137 if (retlen
< (int)sizeof (struct T_bind_ack
)) {
143 /* LINTED pointer cast */
144 bind_ackp
= (struct T_bind_ack
*)ctlbuf
.buf
;
146 if ((req
!= NULL
) && req
->addr
.len
!= 0 &&
147 (use_xpg41tpi
== 0) && (_T_IS_XTI(api_semantics
))) {
149 * Best effort to do XTI on old TPI.
151 * Match address requested or unbind and fail with
154 * XXX - Hack alert ! Should we do this at all ?
155 * Not "supported" as may not work if encoding of
156 * address is different in the returned address. This
157 * will also have trouble with TCP/UDP wildcard port
160 if ((req
->addr
.len
!= bind_ackp
->ADDR_length
) ||
161 (memcmp(req
->addr
.buf
, ctlbuf
.buf
+
162 bind_ackp
->ADDR_offset
, req
->addr
.len
) != 0)) {
163 (void) _tx_unbind_locked(fd
, tiptr
, &ctlbuf
);
170 tiptr
->ti_flags
&= ~TX_TQFULL_NOTIFIED
;
172 _T_TX_NEXTSTATE(T_BIND
, tiptr
, "t_bind: invalid state event T_BIND");
175 if (_T_IS_TLI(api_semantics
) || ret
->addr
.maxlen
> 0) {
176 if (TLEN_GT_NLEN(bind_reqp
->ADDR_length
,
181 (void) memcpy(ret
->addr
.buf
,
182 ctlbuf
.buf
+ bind_ackp
->ADDR_offset
,
183 (size_t)bind_ackp
->ADDR_length
);
184 ret
->addr
.len
= bind_ackp
->ADDR_length
;
186 ret
->qlen
= bind_ackp
->CONIND_number
;
189 tiptr
->ti_qlen
= (uint_t
)bind_ackp
->CONIND_number
;
194 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
195 sig_mutex_unlock(&tiptr
->ti_lock
);
196 (void) thr_sigsetmask(SIG_SETMASK
, &mask
, NULL
);
204 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
205 sig_mutex_unlock(&tiptr
->ti_lock
);
206 (void) thr_sigsetmask(SIG_SETMASK
, &mask
, NULL
);