xref: /illumos-gate/usr/src/uts/common/fs/sockfs/socktpi.h (revision 77c0a660417a046bfab6c8ef58d00c181c0264b3)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright 2022 Garrett D'Amore
25  */
26 
27 #ifndef _SOCKFS_SOCKTPI_H
28 #define	_SOCKFS_SOCKTPI_H
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 /*
35  * Internal representation used for addresses.
36  */
37 struct soaddr {
38 	struct sockaddr	*soa_sa;	/* Actual address */
39 	t_uscalar_t	soa_len;	/* Length in bytes for kmem_free */
40 	t_uscalar_t	soa_maxlen;	/* Allocated length */
41 };
42 /* Maximum size address for transports that have ADDR_size == 1 */
43 #define	SOA_DEFSIZE	128
44 
45 struct sonode;
46 
47 /*
48  * TPI Sockets
49  * ======================
50  *
51  * A TPI socket can be created by the TPI socket module, or as a
52  * result of fallback. In either case, the TPI related information is
53  * stored in a sotpi_info_t. Sockets that are TPI based from the
54  * beginning will use a sotpi_sonode_t, but fallback case the
55  * sotpi_info_t will be allocated when needed. However, the so_priv
56  * field in the sonode will always point to the sotpi_info_t, and the
57  * structure should only be accessed via so_priv. Use SOTOTPI().
58  *
59  * A TPI socket always corresponds to a VCHR stream representing the
60  * transport provider (e.g. /dev/tcp). This information is retrieved
61  * from the kernel socket configuration table and accessible via
62  * so_sockparams->sp_sdev_info.  sockfs uses this to perform
63  * VOP_ACCESS checks before allowing an open of the transport
64  * provider.
65  *
66  * AF_UNIX Sockets
67  * -------------------------
68  *
69  * When an AF_UNIX socket is bound to a pathname the sockfs creates a
70  * VSOCK vnode in the underlying file system. However, the vnodeops
71  * etc in this VNODE remain those of the underlying file system.
72  * Sockfs uses the v_stream pointer in the underlying file system
73  * VSOCK node to find the sonode bound to the pathname. The bound
74  * pathname vnode is accessed through sti_ux_vp.
75  *
76  * Out of Band Data Handling
77  * -------------------------
78  *
79  * The counts (sti_oobcnt and sti_oobsigcnt) track the number of
80  * urgent indicates that are (logically) queued on the stream head
81  * read queue. The urgent data is queued on the stream head
82  * as follows.
83  *
84  * In the normal case the SIGURG is not generated until
85  * the T_EXDATA_IND arrives at the stream head. However, transports
86  * that have an early indication that urgent data is pending
87  * (e.g. TCP receiving a "new" urgent pointer value) can send up
88  * an M_PCPROTO/SIGURG message to generate the signal early.
89  *
90  * The mark is indicated by either:
91  *  - a T_EXDATA_IND (with no M_DATA b_cont) with MSGMARK set.
92  *    When this message is consumed by sorecvmsg the socket layer
93  *    sets SS_RCVATMARK until data has been consumed past the mark.
94  *  - a message with MSGMARKNEXT set (indicating that the
95  *    first byte of the next message constitutes the mark). When
96  *    the last byte of the MSGMARKNEXT message is consumed in
97  *    the stream head the stream head sets STRATMARK. This flag
98  *    is cleared when at least one byte is read. (Note that
99  *    the MSGMARKNEXT messages can be of zero length when there
100  *    is no previous data to which the marknext can be attached.)
101  *
102  * While the T_EXDATA_IND method is the common case which is used
103  * with all TPI transports, the MSGMARKNEXT method is needed to
104  * indicate the mark when e.g. the TCP urgent byte has not been
105  * received yet but the TCP urgent pointer has made TCP generate
106  * the M_PCSIG/SIGURG.
107  *
108  * The signal (the M_PCSIG carrying the SIGURG) and the mark
109  * indication can not be delivered as a single message, since
110  * the signal should be delivered as high priority and any mark
111  * indication must flow with the data. This implies that immediately
112  * when the SIGURG has been delivered if the stream head queue is
113  * empty it is impossible to determine if this will be the position
114  * of the mark. This race condition is resolved by using MSGNOTMARKNEXT
115  * messages and the STRNOTATMARK flag in the stream head. The
116  * SIOCATMARK code calls the stream head to wait for either a
117  * non-empty queue or one of the STR*ATMARK flags being set.
118  * This implies that any transport that is sending M_PCSIG(SIGURG)
119  * should send the appropriate MSGNOTMARKNEXT message (which can be
120  * zero length) after sending an M_PCSIG to prevent SIOCATMARK
121  * from sleeping unnecessarily.
122  */
123 
124 #define	SOTPI_INFO_MAGIC	0x12345678
125 
126 /*
127  * Information used by TPI/STREAMS sockets
128  */
129 typedef struct sotpi_info {
130 	/*
131 	 * These fields are initialized once.
132 	 */
133 	uint32_t	sti_magic;	/* always set to SOTPI_INFO_MAGIC */
134 	dev_t		sti_dev;	/* device the sonode represents */
135 
136 	struct sockparams *sti_orig_sp;	/* in case of fallback; the orig sp */
137 
138 	kmutex_t	sti_plumb_lock;	/* serializes plumbs, and the related */
139 					/* so_pushcnt */
140 	short		sti_pushcnt;	/* Number of modules above "sockmod" */
141 
142 	kcondvar_t	sti_ack_cv;	/* wait for TPI acks */
143 
144 	uint8_t
145 		sti_laddr_valid : 1,	/* sti_laddr valid for user */
146 		sti_faddr_valid : 1,	/* sti_faddr valid for user */
147 		sti_faddr_noxlate : 1,	/* No xlation of faddr for AF_UNIX */
148 
149 		sti_direct : 1,		/* transport is directly below */
150 
151 		sti_pad_to_bit7 : 4;
152 
153 	mblk_t	*sti_ack_mp;		/* TPI ack received from below */
154 	mblk_t	*sti_unbind_mp;		/* Preallocated T_UNBIND_REQ message */
155 
156 	time_t  sti_atime;		/* time of last access */
157 	time_t  sti_mtime;		/* time of last modification */
158 	time_t  sti_ctime;		/* time of last attributes change */
159 
160 	ushort_t sti_delayed_error;	/* From T_uderror_ind */
161 	mblk_t	*sti_eaddr_mp;		/* for so_delayed_error */
162 					/* put here for delayed processing  */
163 
164 	mblk_t	*sti_conn_ind_head;	/* b_next list of T_CONN_IND */
165 	mblk_t	*sti_conn_ind_tail;
166 
167 	uint_t	sti_oobsigcnt;		/* Number of SIGURG generated */
168 	uint_t	sti_oobcnt;		/* Number of T_EXDATA_IND queued */
169 
170 	/* From T_info_ack */
171 	t_uscalar_t	sti_tsdu_size;
172 	t_uscalar_t	sti_etsdu_size;
173 	t_scalar_t	sti_addr_size;
174 	t_uscalar_t	sti_opt_size;
175 	t_uscalar_t	sti_tidu_size;
176 	t_scalar_t	sti_serv_type;
177 
178 	/* From T_capability_ack */
179 	t_uscalar_t	sti_acceptor_id;
180 
181 	/* Internal provider information */
182 	struct tpi_provinfo	*sti_provinfo;
183 
184 	/*
185 	 * The local and remote addresses have multiple purposes
186 	 * but one of the key reasons for their existence and careful
187 	 * tracking in sockfs is to support getsockname and getpeername
188 	 * when the transport does not handle the TI_GET*NAME ioctls
189 	 * and caching when it does (signalled by valid bits in so_state).
190 	 * When all transports support the new TPI (with T_ADDR_REQ)
191 	 * we can revisit this code.
192 	 *
193 	 * The other usage of sti_faddr is to keep the "connected to"
194 	 * address for datagram sockets.
195 	 *
196 	 * Finally, for AF_UNIX both local and remote addresses are used
197 	 * to record the sockaddr_un since we use a separate namespace
198 	 * in the loopback transport.
199 	 */
200 	struct soaddr sti_laddr;	/* Local address */
201 	struct soaddr sti_faddr;	/* Peer address */
202 #define	sti_laddr_sa		sti_laddr.soa_sa
203 #define	sti_faddr_sa		sti_faddr.soa_sa
204 #define	sti_laddr_len		sti_laddr.soa_len
205 #define	sti_faddr_len		sti_faddr.soa_len
206 #define	sti_laddr_maxlen	sti_laddr.soa_maxlen
207 #define	sti_faddr_maxlen	sti_faddr.soa_maxlen
208 
209 	/*
210 	 * For AF_UNIX sockets:
211 	 *
212 	 * sti_ux_laddr/faddr records the internal addresses used with the
213 	 * transport. sti_ux_vp and v_stream->sd_vnode form the
214 	 * cross-linkage between the underlying fs vnode corresponding
215 	 * to the bound sockaddr_un and the socket node.
216 	 *
217 	 * sti_ux_taddr holds the result of translations done in
218 	 * so_ux_addr_xlate(), which may or may not be the same as
219 	 * sti_ux_faddr (which is our connected peer address).
220 	 */
221 	struct so_ux_addr sti_ux_laddr; /* laddr bound with the transport */
222 	struct so_ux_addr sti_ux_faddr; /* connected peer address */
223 	struct so_ux_addr sti_ux_taddr; /* temporary address for sendmsg */
224 	struct vnode	*sti_ux_bound_vp; /* bound AF_UNIX file system vnode */
225 	struct sonode	*sti_next_so;	/* next sonode on socklist	*/
226 	struct sonode	*sti_prev_so;	/* previous sonode on socklist	*/
227 	mblk_t	*sti_discon_ind_mp;	/* T_DISCON_IND received from below */
228 } sotpi_info_t;
229 
230 struct T_capability_ack;
231 
232 extern sonodeops_t sotpi_sonodeops;
233 
234 extern int	socktpi_init(void);
235 extern int	sotpi_convert_sonode(struct sonode *, struct sockparams *,
236 		    boolean_t *, queue_t **, struct cred *);
237 extern void	sotpi_revert_sonode(struct sonode *, struct cred *);
238 extern void	sotpi_update_state(struct sonode *, struct T_capability_ack *,
239 		    struct sockaddr *, socklen_t, struct sockaddr *, socklen_t,
240 		    short);
241 
242 extern sotpi_info_t	*sotpi_sototpi(struct sonode *);
243 #ifdef DEBUG
244 #define	SOTOTPI(so)	(sotpi_sototpi(so))
245 #else
246 #define	SOTOTPI(so)	((sotpi_info_t *)(so)->so_priv)
247 #endif
248 
249 /* for consumers outside sockfs */
250 #define	_SOTOTPI(so)	((sotpi_info_t *)(so)->so_priv)
251 
252 #ifdef	__cplusplus
253 }
254 #endif
255 
256 #endif /* _SOCKFS_SOCKTPI_H */
257