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 */ 25 26 #ifndef _SOCKFS_SOCKTPI_H 27 #define _SOCKFS_SOCKTPI_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /* 34 * Internal representation used for addresses. 35 */ 36 struct soaddr { 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 */ 40 }; 41 /* Maximum size address for transports that have ADDR_size == 1 */ 42 #define SOA_DEFSIZE 128 43 44 struct sonode; 45 46 /* 47 * TPI Sockets 48 * ====================== 49 * 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(). 57 * 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 * VOP_ACCESS checks before allowing an open of the transport 63 * provider. 64 * 65 * AF_UNIX Sockets 66 * ------------------------- 67 * 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. 74 * 75 * Out of Band Data Handling 76 * ------------------------- 77 * 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 81 * as follows. 82 * 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. 88 * 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.) 100 * 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. 106 * 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. 121 */ 122 123 #define SOTPI_INFO_MAGIC 0x12345678 124 125 /* 126 * Information used by TPI/STREAMS sockets 127 */ 128 typedef struct sotpi_info { 129 /* 130 * These fields are initialized once. 131 */ 132 uint32_t sti_magic; /* always set to SOTPI_INFO_MAGIC */ 133 dev_t sti_dev; /* device the sonode represents */ 134 135 struct sockparams *sti_orig_sp; /* in case of fallback; the orig sp */ 136 137 kmutex_t sti_plumb_lock; /* serializes plumbs, and the related */ 138 /* so_pushcnt */ 139 short sti_pushcnt; /* Number of modules above "sockmod" */ 140 141 kcondvar_t sti_ack_cv; /* wait for TPI acks */ 142 143 uint8_t 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 */ 147 148 sti_direct : 1, /* transport is directly below */ 149 150 sti_pad_to_bit7 : 4; 151 152 mblk_t *sti_ack_mp; /* TPI ack received from below */ 153 mblk_t *sti_unbind_mp; /* Preallocated T_UNBIND_REQ message */ 154 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 */ 158 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 */ 162 163 mblk_t *sti_conn_ind_head; /* b_next list of T_CONN_IND */ 164 mblk_t *sti_conn_ind_tail; 165 166 uint_t sti_oobsigcnt; /* Number of SIGURG generated */ 167 uint_t sti_oobcnt; /* Number of T_EXDATA_IND queued */ 168 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; 176 177 /* From T_capability_ack */ 178 t_uscalar_t sti_acceptor_id; 179 180 /* Internal provider information */ 181 struct tpi_provinfo *sti_provinfo; 182 183 /* 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. 191 * 192 * The other usage of sti_faddr is to keep the "connected to" 193 * address for datagram sockets. 194 * 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. 198 */ 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 207 208 /* 209 * For AF_UNIX sockets: 210 * 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. 215 */ 216 struct so_ux_addr sti_ux_laddr; /* laddr bound with the transport */ 217 struct so_ux_addr sti_ux_faddr; /* temporary peer address */ 218 struct vnode *sti_ux_bound_vp; /* bound AF_UNIX file system vnode */ 219 struct sonode *sti_next_so; /* next sonode on socklist */ 220 struct sonode *sti_prev_so; /* previous sonode on socklist */ 221 mblk_t *sti_discon_ind_mp; /* T_DISCON_IND received from below */ 222 223 /* 224 * For NL7C sockets: 225 * 226 * sti_nl7c_flags the NL7C state of URL processing. 227 * 228 * sti_nl7c_rcv_mp mblk_t chain of already received data to be 229 * passed up to the app after NL7C gives up on 230 * a socket. 231 * 232 * sti_nl7c_rcv_rval returned rval for last mblk_t from above. 233 * 234 * sti_nl7c_uri the URI currently being processed. 235 * 236 * sti_nl7c_rtime URI request gethrestime_sec(). 237 * 238 * sti_nl7c_addr pointer returned by nl7c_addr_lookup(). 239 */ 240 uint64_t sti_nl7c_flags; 241 mblk_t *sti_nl7c_rcv_mp; 242 int64_t sti_nl7c_rcv_rval; 243 void *sti_nl7c_uri; 244 time_t sti_nl7c_rtime; 245 void *sti_nl7c_addr; 246 } sotpi_info_t; 247 248 struct T_capability_ack; 249 250 extern sonodeops_t sotpi_sonodeops; 251 252 extern int socktpi_init(void); 253 extern int sotpi_convert_sonode(struct sonode *, struct sockparams *, 254 boolean_t *, queue_t **, struct cred *); 255 extern void sotpi_revert_sonode(struct sonode *, struct cred *); 256 extern void sotpi_update_state(struct sonode *, struct T_capability_ack *, 257 struct sockaddr *, socklen_t, struct sockaddr *, socklen_t, 258 short); 259 260 extern sotpi_info_t *sotpi_sototpi(struct sonode *); 261 #ifdef DEBUG 262 #define SOTOTPI(so) (sotpi_sototpi(so)) 263 #else 264 #define SOTOTPI(so) ((sotpi_info_t *)(so)->so_priv) 265 #endif 266 267 /* for consumers outside sockfs */ 268 #define _SOTOTPI(so) ((sotpi_info_t *)(so)->so_priv) 269 270 #ifdef __cplusplus 271 } 272 #endif 273 274 #endif /* _SOCKFS_SOCKTPI_H */ 275