4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 #ifndef _SOCKFS_SOCKTPI_H
27 #define _SOCKFS_SOCKTPI_H
34 * Internal representation used for addresses.
37 struct sockaddr
*soa_sa
; /* Actual address */
38 t_uscalar_t soa_len
; /* Length in bytes for kmem_free */
39 t_uscalar_t soa_maxlen
; /* Allocated length */
41 /* Maximum size address for transports that have ADDR_size == 1 */
42 #define SOA_DEFSIZE 128
48 * ======================
50 * A TPI socket can be created by the TPI socket module, or as a
51 * result of fallback. In either case, the TPI related information is
52 * stored in a sotpi_info_t. Sockets that are TPI based from the
53 * beginning will use a sotpi_sonode_t, but fallback case the
54 * sotpi_info_t will be allocated when needed. However, the so_priv
55 * field in the sonode will always point to the sotpi_info_t, and the
56 * structure should only be accessed via so_priv. Use SOTOTPI().
58 * A TPI socket always corresponds to a VCHR stream representing the
59 * transport provider (e.g. /dev/tcp). This information is retrieved
60 * from the kernel socket configuration table and accessible via
61 * so_sockparams->sp_sdev_info. sockfs uses this to perform
62 * fop_access checks before allowing an open of the transport
66 * -------------------------
68 * When an AF_UNIX socket is bound to a pathname the sockfs creates a
69 * VSOCK vnode in the underlying file system. However, the vnodeops
70 * etc in this VNODE remain those of the underlying file system.
71 * Sockfs uses the v_stream pointer in the underlying file system
72 * VSOCK node to find the sonode bound to the pathname. The bound
73 * pathname vnode is accessed through sti_ux_vp.
75 * Out of Band Data Handling
76 * -------------------------
78 * The counts (sti_oobcnt and sti_oobsigcnt) track the number of
79 * urgent indicates that are (logically) queued on the stream head
80 * read queue. The urgent data is queued on the stream head
83 * In the normal case the SIGURG is not generated until
84 * the T_EXDATA_IND arrives at the stream head. However, transports
85 * that have an early indication that urgent data is pending
86 * (e.g. TCP receiving a "new" urgent pointer value) can send up
87 * an M_PCPROTO/SIGURG message to generate the signal early.
89 * The mark is indicated by either:
90 * - a T_EXDATA_IND (with no M_DATA b_cont) with MSGMARK set.
91 * When this message is consumed by sorecvmsg the socket layer
92 * sets SS_RCVATMARK until data has been consumed past the mark.
93 * - a message with MSGMARKNEXT set (indicating that the
94 * first byte of the next message constitutes the mark). When
95 * the last byte of the MSGMARKNEXT message is consumed in
96 * the stream head the stream head sets STRATMARK. This flag
97 * is cleared when at least one byte is read. (Note that
98 * the MSGMARKNEXT messages can be of zero length when there
99 * is no previous data to which the marknext can be attached.)
101 * While the T_EXDATA_IND method is the common case which is used
102 * with all TPI transports, the MSGMARKNEXT method is needed to
103 * indicate the mark when e.g. the TCP urgent byte has not been
104 * received yet but the TCP urgent pointer has made TCP generate
105 * the M_PCSIG/SIGURG.
107 * The signal (the M_PCSIG carrying the SIGURG) and the mark
108 * indication can not be delivered as a single message, since
109 * the signal should be delivered as high priority and any mark
110 * indication must flow with the data. This implies that immediately
111 * when the SIGURG has been delivered if the stream head queue is
112 * empty it is impossible to determine if this will be the position
113 * of the mark. This race condition is resolved by using MSGNOTMARKNEXT
114 * messages and the STRNOTATMARK flag in the stream head. The
115 * SIOCATMARK code calls the stream head to wait for either a
116 * non-empty queue or one of the STR*ATMARK flags being set.
117 * This implies that any transport that is sending M_PCSIG(SIGURG)
118 * should send the appropriate MSGNOTMARKNEXT message (which can be
119 * zero length) after sending an M_PCSIG to prevent SIOCATMARK
120 * from sleeping unnecessarily.
123 #define SOTPI_INFO_MAGIC 0x12345678
126 * Information used by TPI/STREAMS sockets
128 typedef struct sotpi_info
{
130 * These fields are initialized once.
132 uint32_t sti_magic
; /* always set to SOTPI_INFO_MAGIC */
133 dev_t sti_dev
; /* device the sonode represents */
135 struct sockparams
*sti_orig_sp
; /* in case of fallback; the orig sp */
137 kmutex_t sti_plumb_lock
; /* serializes plumbs, and the related */
139 short sti_pushcnt
; /* Number of modules above "sockmod" */
141 kcondvar_t sti_ack_cv
; /* wait for TPI acks */
144 sti_laddr_valid
: 1, /* sti_laddr valid for user */
145 sti_faddr_valid
: 1, /* sti_faddr valid for user */
146 sti_faddr_noxlate
: 1, /* No xlation of faddr for AF_UNIX */
148 sti_direct
: 1, /* transport is directly below */
152 mblk_t
*sti_ack_mp
; /* TPI ack received from below */
153 mblk_t
*sti_unbind_mp
; /* Preallocated T_UNBIND_REQ message */
155 time_t sti_atime
; /* time of last access */
156 time_t sti_mtime
; /* time of last modification */
157 time_t sti_ctime
; /* time of last attributes change */
159 ushort_t sti_delayed_error
; /* From T_uderror_ind */
160 mblk_t
*sti_eaddr_mp
; /* for so_delayed_error */
161 /* put here for delayed processing */
163 mblk_t
*sti_conn_ind_head
; /* b_next list of T_CONN_IND */
164 mblk_t
*sti_conn_ind_tail
;
166 uint_t sti_oobsigcnt
; /* Number of SIGURG generated */
167 uint_t sti_oobcnt
; /* Number of T_EXDATA_IND queued */
169 /* From T_info_ack */
170 t_uscalar_t sti_tsdu_size
;
171 t_uscalar_t sti_etsdu_size
;
172 t_scalar_t sti_addr_size
;
173 t_uscalar_t sti_opt_size
;
174 t_uscalar_t sti_tidu_size
;
175 t_scalar_t sti_serv_type
;
177 /* From T_capability_ack */
178 t_uscalar_t sti_acceptor_id
;
180 /* Internal provider information */
181 struct tpi_provinfo
*sti_provinfo
;
184 * The local and remote addresses have multiple purposes
185 * but one of the key reasons for their existence and careful
186 * tracking in sockfs is to support getsockname and getpeername
187 * when the transport does not handle the TI_GET*NAME ioctls
188 * and caching when it does (signalled by valid bits in so_state).
189 * When all transports support the new TPI (with T_ADDR_REQ)
190 * we can revisit this code.
192 * The other usage of sti_faddr is to keep the "connected to"
193 * address for datagram sockets.
195 * Finally, for AF_UNIX both local and remote addresses are used
196 * to record the sockaddr_un since we use a separate namespace
197 * in the loopback transport.
199 struct soaddr sti_laddr
; /* Local address */
200 struct soaddr sti_faddr
; /* Peer address */
201 #define sti_laddr_sa sti_laddr.soa_sa
202 #define sti_faddr_sa sti_faddr.soa_sa
203 #define sti_laddr_len sti_laddr.soa_len
204 #define sti_faddr_len sti_faddr.soa_len
205 #define sti_laddr_maxlen sti_laddr.soa_maxlen
206 #define sti_faddr_maxlen sti_faddr.soa_maxlen
209 * For AF_UNIX sockets:
211 * sti_ux_laddr/faddr records the internal addresses used with the
212 * transport. sti_ux_vp and v_stream->sd_vnode form the
213 * cross-linkage between the underlying fs vnode corresponding
214 * to the bound sockaddr_un and the socket node.
216 * sti_ux_taddr holds the result of translations done in
217 * so_ux_addr_xlate(), which may or may not be the same as
218 * sti_ux_faddr (which is our connected peer address).
220 struct so_ux_addr sti_ux_laddr
; /* laddr bound with the transport */
221 struct so_ux_addr sti_ux_faddr
; /* connected peer address */
222 struct so_ux_addr sti_ux_taddr
; /* temporary address for sendmsg */
223 struct vnode
*sti_ux_bound_vp
; /* bound AF_UNIX file system vnode */
224 struct sonode
*sti_next_so
; /* next sonode on socklist */
225 struct sonode
*sti_prev_so
; /* previous sonode on socklist */
226 mblk_t
*sti_discon_ind_mp
; /* T_DISCON_IND received from below */
229 struct T_capability_ack
;
231 extern sonodeops_t sotpi_sonodeops
;
233 extern int socktpi_init(void);
234 extern int sotpi_convert_sonode(struct sonode
*, struct sockparams
*,
235 boolean_t
*, queue_t
**, struct cred
*);
236 extern void sotpi_revert_sonode(struct sonode
*, struct cred
*);
237 extern void sotpi_update_state(struct sonode
*, struct T_capability_ack
*,
238 struct sockaddr
*, socklen_t
, struct sockaddr
*, socklen_t
,
241 extern sotpi_info_t
*sotpi_sototpi(struct sonode
*);
243 #define SOTOTPI(so) (sotpi_sototpi(so))
245 #define SOTOTPI(so) ((sotpi_info_t *)(so)->so_priv)
248 /* for consumers outside sockfs */
249 #define _SOTOTPI(so) ((sotpi_info_t *)(so)->so_priv)
255 #endif /* _SOCKFS_SOCKTPI_H */