18348SEric.Yu@Sun.COM /* 28348SEric.Yu@Sun.COM * CDDL HEADER START 38348SEric.Yu@Sun.COM * 48348SEric.Yu@Sun.COM * The contents of this file are subject to the terms of the 58348SEric.Yu@Sun.COM * Common Development and Distribution License (the "License"). 68348SEric.Yu@Sun.COM * You may not use this file except in compliance with the License. 78348SEric.Yu@Sun.COM * 88348SEric.Yu@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 98348SEric.Yu@Sun.COM * or http://www.opensolaris.org/os/licensing. 108348SEric.Yu@Sun.COM * See the License for the specific language governing permissions 118348SEric.Yu@Sun.COM * and limitations under the License. 128348SEric.Yu@Sun.COM * 138348SEric.Yu@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 148348SEric.Yu@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 158348SEric.Yu@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 168348SEric.Yu@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 178348SEric.Yu@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 188348SEric.Yu@Sun.COM * 198348SEric.Yu@Sun.COM * CDDL HEADER END 208348SEric.Yu@Sun.COM */ 218348SEric.Yu@Sun.COM 228348SEric.Yu@Sun.COM /* 23*12643SAnders.Persson@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 248348SEric.Yu@Sun.COM */ 258348SEric.Yu@Sun.COM 268348SEric.Yu@Sun.COM #ifndef _SOCKFS_SOCKTPI_H 278348SEric.Yu@Sun.COM #define _SOCKFS_SOCKTPI_H 288348SEric.Yu@Sun.COM 298348SEric.Yu@Sun.COM #ifdef __cplusplus 308348SEric.Yu@Sun.COM extern "C" { 318348SEric.Yu@Sun.COM #endif 328348SEric.Yu@Sun.COM 338348SEric.Yu@Sun.COM /* 348348SEric.Yu@Sun.COM * Internal representation used for addresses. 358348SEric.Yu@Sun.COM */ 368348SEric.Yu@Sun.COM struct soaddr { 378348SEric.Yu@Sun.COM struct sockaddr *soa_sa; /* Actual address */ 388348SEric.Yu@Sun.COM t_uscalar_t soa_len; /* Length in bytes for kmem_free */ 398348SEric.Yu@Sun.COM t_uscalar_t soa_maxlen; /* Allocated length */ 408348SEric.Yu@Sun.COM }; 418348SEric.Yu@Sun.COM /* Maximum size address for transports that have ADDR_size == 1 */ 428348SEric.Yu@Sun.COM #define SOA_DEFSIZE 128 438348SEric.Yu@Sun.COM 448348SEric.Yu@Sun.COM struct sonode; 458348SEric.Yu@Sun.COM 468348SEric.Yu@Sun.COM /* 478348SEric.Yu@Sun.COM * TPI Sockets 488348SEric.Yu@Sun.COM * ====================== 498348SEric.Yu@Sun.COM * 508348SEric.Yu@Sun.COM * A TPI socket can be created by the TPI socket module, or as a 518348SEric.Yu@Sun.COM * result of fallback. In either case, the TPI related information is 528348SEric.Yu@Sun.COM * stored in a sotpi_info_t. Sockets that are TPI based from the 538348SEric.Yu@Sun.COM * beginning will use a sotpi_sonode_t, but fallback case the 548348SEric.Yu@Sun.COM * sotpi_info_t will be allocated when needed. However, the so_priv 558348SEric.Yu@Sun.COM * field in the sonode will always point to the sotpi_info_t, and the 568348SEric.Yu@Sun.COM * structure should only be accessed via so_priv. Use SOTOTPI(). 578348SEric.Yu@Sun.COM * 588348SEric.Yu@Sun.COM * A TPI socket always corresponds to a VCHR stream representing the 598348SEric.Yu@Sun.COM * transport provider (e.g. /dev/tcp). This information is retrieved 608348SEric.Yu@Sun.COM * from the kernel socket configuration table and accessible via 618348SEric.Yu@Sun.COM * so_sockparams->sp_sdev_info. sockfs uses this to perform 628348SEric.Yu@Sun.COM * VOP_ACCESS checks before allowing an open of the transport 638348SEric.Yu@Sun.COM * provider. 648348SEric.Yu@Sun.COM * 658348SEric.Yu@Sun.COM * AF_UNIX Sockets 668348SEric.Yu@Sun.COM * ------------------------- 678348SEric.Yu@Sun.COM * 688348SEric.Yu@Sun.COM * When an AF_UNIX socket is bound to a pathname the sockfs creates a 698348SEric.Yu@Sun.COM * VSOCK vnode in the underlying file system. However, the vnodeops 708348SEric.Yu@Sun.COM * etc in this VNODE remain those of the underlying file system. 718348SEric.Yu@Sun.COM * Sockfs uses the v_stream pointer in the underlying file system 728348SEric.Yu@Sun.COM * VSOCK node to find the sonode bound to the pathname. The bound 738348SEric.Yu@Sun.COM * pathname vnode is accessed through sti_ux_vp. 748348SEric.Yu@Sun.COM * 758348SEric.Yu@Sun.COM * Out of Band Data Handling 768348SEric.Yu@Sun.COM * ------------------------- 778348SEric.Yu@Sun.COM * 788348SEric.Yu@Sun.COM * The counts (sti_oobcnt and sti_oobsigcnt) track the number of 798348SEric.Yu@Sun.COM * urgent indicates that are (logically) queued on the stream head 808348SEric.Yu@Sun.COM * read queue. The urgent data is queued on the stream head 818348SEric.Yu@Sun.COM * as follows. 828348SEric.Yu@Sun.COM * 838348SEric.Yu@Sun.COM * In the normal case the SIGURG is not generated until 848348SEric.Yu@Sun.COM * the T_EXDATA_IND arrives at the stream head. However, transports 858348SEric.Yu@Sun.COM * that have an early indication that urgent data is pending 868348SEric.Yu@Sun.COM * (e.g. TCP receiving a "new" urgent pointer value) can send up 878348SEric.Yu@Sun.COM * an M_PCPROTO/SIGURG message to generate the signal early. 888348SEric.Yu@Sun.COM * 898348SEric.Yu@Sun.COM * The mark is indicated by either: 908348SEric.Yu@Sun.COM * - a T_EXDATA_IND (with no M_DATA b_cont) with MSGMARK set. 918348SEric.Yu@Sun.COM * When this message is consumed by sorecvmsg the socket layer 928348SEric.Yu@Sun.COM * sets SS_RCVATMARK until data has been consumed past the mark. 938348SEric.Yu@Sun.COM * - a message with MSGMARKNEXT set (indicating that the 948348SEric.Yu@Sun.COM * first byte of the next message constitutes the mark). When 958348SEric.Yu@Sun.COM * the last byte of the MSGMARKNEXT message is consumed in 968348SEric.Yu@Sun.COM * the stream head the stream head sets STRATMARK. This flag 978348SEric.Yu@Sun.COM * is cleared when at least one byte is read. (Note that 988348SEric.Yu@Sun.COM * the MSGMARKNEXT messages can be of zero length when there 998348SEric.Yu@Sun.COM * is no previous data to which the marknext can be attached.) 1008348SEric.Yu@Sun.COM * 1018348SEric.Yu@Sun.COM * While the T_EXDATA_IND method is the common case which is used 1028348SEric.Yu@Sun.COM * with all TPI transports, the MSGMARKNEXT method is needed to 1038348SEric.Yu@Sun.COM * indicate the mark when e.g. the TCP urgent byte has not been 1048348SEric.Yu@Sun.COM * received yet but the TCP urgent pointer has made TCP generate 1058348SEric.Yu@Sun.COM * the M_PCSIG/SIGURG. 1068348SEric.Yu@Sun.COM * 1078348SEric.Yu@Sun.COM * The signal (the M_PCSIG carrying the SIGURG) and the mark 1088348SEric.Yu@Sun.COM * indication can not be delivered as a single message, since 1098348SEric.Yu@Sun.COM * the signal should be delivered as high priority and any mark 1108348SEric.Yu@Sun.COM * indication must flow with the data. This implies that immediately 1118348SEric.Yu@Sun.COM * when the SIGURG has been delivered if the stream head queue is 1128348SEric.Yu@Sun.COM * empty it is impossible to determine if this will be the position 1138348SEric.Yu@Sun.COM * of the mark. This race condition is resolved by using MSGNOTMARKNEXT 1148348SEric.Yu@Sun.COM * messages and the STRNOTATMARK flag in the stream head. The 1158348SEric.Yu@Sun.COM * SIOCATMARK code calls the stream head to wait for either a 1168348SEric.Yu@Sun.COM * non-empty queue or one of the STR*ATMARK flags being set. 1178348SEric.Yu@Sun.COM * This implies that any transport that is sending M_PCSIG(SIGURG) 1188348SEric.Yu@Sun.COM * should send the appropriate MSGNOTMARKNEXT message (which can be 1198348SEric.Yu@Sun.COM * zero length) after sending an M_PCSIG to prevent SIOCATMARK 1208348SEric.Yu@Sun.COM * from sleeping unnecessarily. 1218348SEric.Yu@Sun.COM */ 1228348SEric.Yu@Sun.COM 1238348SEric.Yu@Sun.COM #define SOTPI_INFO_MAGIC 0x12345678 1248348SEric.Yu@Sun.COM 1258348SEric.Yu@Sun.COM /* 1268348SEric.Yu@Sun.COM * Information used by TPI/STREAMS sockets 1278348SEric.Yu@Sun.COM */ 1288348SEric.Yu@Sun.COM typedef struct sotpi_info { 1298348SEric.Yu@Sun.COM /* 1308348SEric.Yu@Sun.COM * These fields are initialized once. 1318348SEric.Yu@Sun.COM */ 1328348SEric.Yu@Sun.COM uint32_t sti_magic; /* always set to SOTPI_INFO_MAGIC */ 1338348SEric.Yu@Sun.COM dev_t sti_dev; /* device the sonode represents */ 1348348SEric.Yu@Sun.COM 1358348SEric.Yu@Sun.COM struct sockparams *sti_orig_sp; /* in case of fallback; the orig sp */ 1368348SEric.Yu@Sun.COM 1378348SEric.Yu@Sun.COM kmutex_t sti_plumb_lock; /* serializes plumbs, and the related */ 1388348SEric.Yu@Sun.COM /* so_pushcnt */ 1398348SEric.Yu@Sun.COM short sti_pushcnt; /* Number of modules above "sockmod" */ 1408348SEric.Yu@Sun.COM 1418348SEric.Yu@Sun.COM kcondvar_t sti_ack_cv; /* wait for TPI acks */ 1428348SEric.Yu@Sun.COM 1438348SEric.Yu@Sun.COM uint8_t 1448348SEric.Yu@Sun.COM sti_laddr_valid : 1, /* sti_laddr valid for user */ 1458348SEric.Yu@Sun.COM sti_faddr_valid : 1, /* sti_faddr valid for user */ 1468348SEric.Yu@Sun.COM sti_faddr_noxlate : 1, /* No xlation of faddr for AF_UNIX */ 1478348SEric.Yu@Sun.COM 1488348SEric.Yu@Sun.COM sti_direct : 1, /* transport is directly below */ 1498348SEric.Yu@Sun.COM 1508348SEric.Yu@Sun.COM sti_pad_to_bit7 : 4; 1518348SEric.Yu@Sun.COM 1528348SEric.Yu@Sun.COM mblk_t *sti_ack_mp; /* TPI ack received from below */ 1538348SEric.Yu@Sun.COM mblk_t *sti_unbind_mp; /* Preallocated T_UNBIND_REQ message */ 1548348SEric.Yu@Sun.COM 1558348SEric.Yu@Sun.COM time_t sti_atime; /* time of last access */ 1568348SEric.Yu@Sun.COM time_t sti_mtime; /* time of last modification */ 1578348SEric.Yu@Sun.COM time_t sti_ctime; /* time of last attributes change */ 1588348SEric.Yu@Sun.COM 1598348SEric.Yu@Sun.COM ushort_t sti_delayed_error; /* From T_uderror_ind */ 1608348SEric.Yu@Sun.COM mblk_t *sti_eaddr_mp; /* for so_delayed_error */ 1618348SEric.Yu@Sun.COM /* put here for delayed processing */ 1628348SEric.Yu@Sun.COM 1638348SEric.Yu@Sun.COM mblk_t *sti_conn_ind_head; /* b_next list of T_CONN_IND */ 1648348SEric.Yu@Sun.COM mblk_t *sti_conn_ind_tail; 1658348SEric.Yu@Sun.COM 1668348SEric.Yu@Sun.COM uint_t sti_oobsigcnt; /* Number of SIGURG generated */ 1678348SEric.Yu@Sun.COM uint_t sti_oobcnt; /* Number of T_EXDATA_IND queued */ 1688348SEric.Yu@Sun.COM 1698348SEric.Yu@Sun.COM /* From T_info_ack */ 1708348SEric.Yu@Sun.COM t_uscalar_t sti_tsdu_size; 1718348SEric.Yu@Sun.COM t_uscalar_t sti_etsdu_size; 1728348SEric.Yu@Sun.COM t_scalar_t sti_addr_size; 1738348SEric.Yu@Sun.COM t_uscalar_t sti_opt_size; 1748348SEric.Yu@Sun.COM t_uscalar_t sti_tidu_size; 1758348SEric.Yu@Sun.COM t_scalar_t sti_serv_type; 1768348SEric.Yu@Sun.COM 1778348SEric.Yu@Sun.COM /* From T_capability_ack */ 1788348SEric.Yu@Sun.COM t_uscalar_t sti_acceptor_id; 1798348SEric.Yu@Sun.COM 1808348SEric.Yu@Sun.COM /* Internal provider information */ 1818348SEric.Yu@Sun.COM struct tpi_provinfo *sti_provinfo; 1828348SEric.Yu@Sun.COM 1838348SEric.Yu@Sun.COM /* 1848348SEric.Yu@Sun.COM * The local and remote addresses have multiple purposes 1858348SEric.Yu@Sun.COM * but one of the key reasons for their existence and careful 1868348SEric.Yu@Sun.COM * tracking in sockfs is to support getsockname and getpeername 1878348SEric.Yu@Sun.COM * when the transport does not handle the TI_GET*NAME ioctls 1888348SEric.Yu@Sun.COM * and caching when it does (signalled by valid bits in so_state). 1898348SEric.Yu@Sun.COM * When all transports support the new TPI (with T_ADDR_REQ) 1908348SEric.Yu@Sun.COM * we can revisit this code. 1918348SEric.Yu@Sun.COM * 1928348SEric.Yu@Sun.COM * The other usage of sti_faddr is to keep the "connected to" 1938348SEric.Yu@Sun.COM * address for datagram sockets. 1948348SEric.Yu@Sun.COM * 1958348SEric.Yu@Sun.COM * Finally, for AF_UNIX both local and remote addresses are used 1968348SEric.Yu@Sun.COM * to record the sockaddr_un since we use a separate namespace 1978348SEric.Yu@Sun.COM * in the loopback transport. 1988348SEric.Yu@Sun.COM */ 1998348SEric.Yu@Sun.COM struct soaddr sti_laddr; /* Local address */ 2008348SEric.Yu@Sun.COM struct soaddr sti_faddr; /* Peer address */ 2018348SEric.Yu@Sun.COM #define sti_laddr_sa sti_laddr.soa_sa 2028348SEric.Yu@Sun.COM #define sti_faddr_sa sti_faddr.soa_sa 2038348SEric.Yu@Sun.COM #define sti_laddr_len sti_laddr.soa_len 2048348SEric.Yu@Sun.COM #define sti_faddr_len sti_faddr.soa_len 2058348SEric.Yu@Sun.COM #define sti_laddr_maxlen sti_laddr.soa_maxlen 2068348SEric.Yu@Sun.COM #define sti_faddr_maxlen sti_faddr.soa_maxlen 2078348SEric.Yu@Sun.COM 2088348SEric.Yu@Sun.COM /* 2098348SEric.Yu@Sun.COM * For AF_UNIX sockets: 2108348SEric.Yu@Sun.COM * 2118348SEric.Yu@Sun.COM * sti_ux_laddr/faddr records the internal addresses used with the 2128348SEric.Yu@Sun.COM * transport. sti_ux_vp and v_stream->sd_vnode form the 2138348SEric.Yu@Sun.COM * cross-linkage between the underlying fs vnode corresponding 2148348SEric.Yu@Sun.COM * to the bound sockaddr_un and the socket node. 2158348SEric.Yu@Sun.COM */ 2168348SEric.Yu@Sun.COM struct so_ux_addr sti_ux_laddr; /* laddr bound with the transport */ 2178348SEric.Yu@Sun.COM struct so_ux_addr sti_ux_faddr; /* temporary peer address */ 2188348SEric.Yu@Sun.COM struct vnode *sti_ux_bound_vp; /* bound AF_UNIX file system vnode */ 2198348SEric.Yu@Sun.COM struct sonode *sti_next_so; /* next sonode on socklist */ 2208348SEric.Yu@Sun.COM struct sonode *sti_prev_so; /* previous sonode on socklist */ 2218348SEric.Yu@Sun.COM mblk_t *sti_discon_ind_mp; /* T_DISCON_IND received from below */ 2228348SEric.Yu@Sun.COM 2238348SEric.Yu@Sun.COM /* 2248348SEric.Yu@Sun.COM * For NL7C sockets: 2258348SEric.Yu@Sun.COM * 2268348SEric.Yu@Sun.COM * sti_nl7c_flags the NL7C state of URL processing. 2278348SEric.Yu@Sun.COM * 2288348SEric.Yu@Sun.COM * sti_nl7c_rcv_mp mblk_t chain of already received data to be 2298348SEric.Yu@Sun.COM * passed up to the app after NL7C gives up on 2308348SEric.Yu@Sun.COM * a socket. 2318348SEric.Yu@Sun.COM * 2328348SEric.Yu@Sun.COM * sti_nl7c_rcv_rval returned rval for last mblk_t from above. 2338348SEric.Yu@Sun.COM * 2348348SEric.Yu@Sun.COM * sti_nl7c_uri the URI currently being processed. 2358348SEric.Yu@Sun.COM * 2368348SEric.Yu@Sun.COM * sti_nl7c_rtime URI request gethrestime_sec(). 2378348SEric.Yu@Sun.COM * 2388348SEric.Yu@Sun.COM * sti_nl7c_addr pointer returned by nl7c_addr_lookup(). 2398348SEric.Yu@Sun.COM */ 2408348SEric.Yu@Sun.COM uint64_t sti_nl7c_flags; 2418348SEric.Yu@Sun.COM mblk_t *sti_nl7c_rcv_mp; 2428348SEric.Yu@Sun.COM int64_t sti_nl7c_rcv_rval; 2438348SEric.Yu@Sun.COM void *sti_nl7c_uri; 2448348SEric.Yu@Sun.COM time_t sti_nl7c_rtime; 2458348SEric.Yu@Sun.COM void *sti_nl7c_addr; 2468348SEric.Yu@Sun.COM } sotpi_info_t; 2478348SEric.Yu@Sun.COM 2488348SEric.Yu@Sun.COM struct T_capability_ack; 2498348SEric.Yu@Sun.COM 2508348SEric.Yu@Sun.COM extern sonodeops_t sotpi_sonodeops; 2518348SEric.Yu@Sun.COM 2528348SEric.Yu@Sun.COM extern int socktpi_init(void); 2538963SAnders.Persson@Sun.COM extern int sotpi_convert_sonode(struct sonode *, struct sockparams *, 2548963SAnders.Persson@Sun.COM boolean_t *, queue_t **, struct cred *); 2558963SAnders.Persson@Sun.COM extern void sotpi_revert_sonode(struct sonode *, struct cred *); 2568348SEric.Yu@Sun.COM extern void sotpi_update_state(struct sonode *, struct T_capability_ack *, 2578348SEric.Yu@Sun.COM struct sockaddr *, socklen_t, struct sockaddr *, socklen_t, 2588348SEric.Yu@Sun.COM short); 2598348SEric.Yu@Sun.COM 2608348SEric.Yu@Sun.COM extern sotpi_info_t *sotpi_sototpi(struct sonode *); 2618348SEric.Yu@Sun.COM #ifdef DEBUG 2628348SEric.Yu@Sun.COM #define SOTOTPI(so) (sotpi_sototpi(so)) 2638348SEric.Yu@Sun.COM #else 2648348SEric.Yu@Sun.COM #define SOTOTPI(so) ((sotpi_info_t *)(so)->so_priv) 2658348SEric.Yu@Sun.COM #endif 2668348SEric.Yu@Sun.COM 2678348SEric.Yu@Sun.COM /* for consumers outside sockfs */ 2688348SEric.Yu@Sun.COM #define _SOTOTPI(so) ((sotpi_info_t *)(so)->so_priv) 2698348SEric.Yu@Sun.COM 2708348SEric.Yu@Sun.COM #ifdef __cplusplus 2718348SEric.Yu@Sun.COM } 2728348SEric.Yu@Sun.COM #endif 2738348SEric.Yu@Sun.COM 2748348SEric.Yu@Sun.COM #endif /* _SOCKFS_SOCKTPI_H */ 275