1 #ifndef MINIX_NET_UDS_UDS_H 2 #define MINIX_NET_UDS_UDS_H 3 4 #include <minix/drivers.h> 5 #include <minix/sockevent.h> 6 #include <minix/rmib.h> 7 #include <sys/un.h> 8 9 /* 10 * Maximum number of UNIX domain sockets. The control structures for all of 11 * these are allocated statically, although each socket's receive buffer is 12 * allocated only when the socket is in use. If this constant is increased 13 * beyond 65535, a few field sizes need to be changed. 14 */ 15 #define NR_UDSSOCK 256 16 17 /* Number of slots in the <dev,ino>-to-udssock hash table. */ 18 #define UDSHASH_SLOTS 64 19 20 /* UDS has no protocols, so we accept only an "any protocol" value. */ 21 #define UDSPROTO_UDS 0 22 23 /* 24 * The size of each socket's receive buffer. This size is currently a global 25 * setting which cannot be changed per socket at run time, and it would be 26 * rather tricky to change that. In order not to waste resources, this size 27 * should be a multiple of the page size. Due to the fact that data and 28 * metadata (such as lengths, source addresses and sender credentials) are 29 * intermixed in the same buffer, the actual amount of data that can be in 30 * transit at once is typically less than this value. If this constant is 31 * increased beyond 65535, several fields and field sizes need to be changed. 32 */ 33 #define UDS_BUF 32768 34 35 /* Maximum size of control data that can be sent or received at once. */ 36 #define UDS_CTL_MAX 4096 37 38 /* 39 * We allow longer path names than the size of struct sockaddr_un's sun_path 40 * field. The actual limit is determined by the maximum value of the sun_len 41 * field, which is 255 and includes the first two fields of the structure (one 42 * byte each) but not the null terminator of the path. Thus, the maximum 43 * length of the path minus null terminator is 253; with terminator it is 254. 44 */ 45 #define UDS_PATH_MAX (UINT8_MAX - sizeof(uint8_t) - sizeof(sa_family_t) + 1) 46 47 /* Output debugging information? */ 48 #define DEBUG 0 49 50 #if DEBUG 51 #define dprintf(x) printf x 52 #else 53 #define dprintf(x) 54 #endif 55 56 /* 57 * We declare this structure only for the static assert right below it. We 58 * have no need for the structure otherwise, as we use "struct sockaddr" 59 * directly instead. 60 */ 61 struct sockaddr_unx { 62 uint8_t sunx_len; 63 sa_family_t sunx_family; 64 char sunx_path[UDS_PATH_MAX]; 65 }; 66 STATIC_SOCKADDR_MAX_ASSERT(sockaddr_unx); 67 68 /* 69 * In-flight file descriptor object. Each in-use object is part of a socket's 70 * file descriptor queue, and the file descriptor is for a file open by this 71 * service. For each set of in-flight file descriptors associated with a 72 * particular segment, the first object's count field contains the number of 73 * file descriptors in that set. For all other objects in that set, the count 74 * field is zero. TODO: the count should be stored in the segment itself. 75 */ 76 struct uds_fd { 77 SIMPLEQ_ENTRY(uds_fd) ufd_next; /* next FD object for this socket */ 78 int ufd_fd; /* local file descriptor number */ 79 unsigned int ufd_count; /* number of FDs for this segment */ 80 }; 81 82 /* 83 * Connection-type sockets (SOCK_STREAM, SOCK_SEQPACKET) are always in one of 84 * the following five states, each with unique characteristics: 85 * 86 * - Unconnected: this socket is not in any of the other states, usually 87 * because it either has just been created, or because it has failed a 88 * connection attempt. This socket has no connected peer and does not have 89 * the SO_ACCEPTCONN socket option set. 90 * - Listening: this socket is in listening mode. It has a queue with sockets 91 * that are connecting or connected to it but have not yet been accepted on 92 * it. This socket has no connected peer. It has the SO_ACCEPTCONN socket 93 * option set. 94 * - Connecting: this socket is on a listening socket's queue. While in this 95 * state, the socket has the listening socket as its linked peer, and it has 96 * no connected peer. 97 * - Connected: this socket is connected to another socket, which is its 98 * connected peer socket. It has the UDSF_CONNECTED flag set. A socket may 99 * be connected and still be involved with a listening socket; see below. 100 * - Disconnected: this socket was connected to another socket, but that other 101 * socket has been closed. As a result, this socket has no peer. It does 102 * have the UDSF_CONNECTED flag set. 103 * 104 * The UDS service supports two different type of connect behaviors, depending 105 * on what the LOCAL_CONNWAIT option is set to on either the connecting or the 106 * listening socket. If LOCAL_CONNWAIT is not set on either (the default), the 107 * connecting socket socket (let's call it "A") enters the connected state 108 * right away, even if the connection is not immediately accepted through 109 * accept(2). In that case, a new limbo socket "B" is allocated as its 110 * connection peer. Limbo socket B is also in connected state, and either 111 * returned from accept(2) later, or freed when socket A leaves the connected 112 * state. Socket A can leave the connected state either by being closed or 113 * when the listening socket is closed. If LOCAL_CONNWAIT is set, socket A 114 * stays in the connecting state until it is accepted through accept(2). 115 * Importantly, in both cases, it is socket A, and (in the first case) *not* 116 * socket B, that is on the queue of the listening socket! 117 * 118 * Connected peers (uds_conn) are always symmetric: if one socket is connected 119 * to another socket, that other socket is connected to it. Any socket that is 120 * on the queue of another socket, is said to be "linked" to that other socket 121 * (uds_link). This is an asymmetric, one-to-many relationship: many sockets 122 * may be linked to one other socket, which keeps all those sockets on its 123 * queue. From the above story it should now be clear that for connection-type 124 * sockets, only listening sockets may have sockets on its queue, and while 125 * connecting sockets are always on a listening socket's queue, connected 126 * sockets may or may not be. Sockets in other states never are. 127 * 128 * UNIX domain sockets are generally reusable. This means that the listening 129 * state is the only final state; all other socket states allow the socket to 130 * enter another state, although not necessarily every other state. For 131 * example, a disconnected socket may be reconnected to another target; if that 132 * connection fails, the socket will enter the unconnected state. As a result, 133 * a socket in any state (even the listening state) may still have incoming 134 * data pending from a previous connection. However, EOF is currently produced 135 * only for disconnected sockets. To be sure: connecting and connected sockets 136 * must first enter the unconnected or disconnected state, respectively, before 137 * possibly being reconnected. 138 * 139 * For connectionless (i.e., SOCK_DGRAM) sockets, there are no separate states. 140 * However, a connectionless socket may have been connected to another socket. 141 * We maintain these links not with uds_conn but with uds_link, because such 142 * connections are not symmetric, and there is an interest in keeping track of 143 * which datagram sockets are connected to a particular socket (namely, to 144 * break the connection on close without doing an exhaustive search). For that 145 * reason, when a datagram socket connects to another socket, it is linked to 146 * that other socket, and the other socket has this socket on its queue. As a 147 * strange corner case, a connectionless socket may be connected to itself, in 148 * which case it is its own linked peer and it is also on its own queue. For 149 * datagram sockets, uds_conn is always NULL and UDSF_CONNECTED is never set. 150 * 151 * For the purposes of sending and receiving, we generally refer to the 152 * communication partner of a socket as its "peer". As should now be clear, 153 * for connection-type sockets, the socket's peer is identified with uds_conn; 154 * for connectionless sockets, the socket's peer is identified with uds_link. 155 */ 156 struct udssock { 157 struct sock uds_sock; /* sock object */ 158 struct udssock *uds_conn; /* connected socket, or NULL if none */ 159 struct udssock *uds_link; /* linked socket, or NULL if none */ 160 unsigned char *uds_buf; /* receive buffer (memory-mapped) */ 161 unsigned short uds_tail; /* tail of data in receive buffer */ 162 unsigned short uds_len; /* length of data in receive buffer */ 163 unsigned short uds_last; /* offset to last header in buffer */ 164 unsigned short uds_queued; /* current nr of sockets on queue */ 165 unsigned short uds_backlog; /* maximum nr of connecting sockets */ 166 unsigned char uds_flags; /* UDS-specific flags (UDSF_) */ 167 unsigned char uds_pathlen; /* socket file path length (w/o nul) */ 168 char uds_path[UDS_PATH_MAX - 1];/* socket file path (not terminated) */ 169 dev_t uds_dev; /* socket file device number */ 170 ino_t uds_ino; /* socket file inode number */ 171 struct unpcbid uds_cred; /* bind/connect-time credentials */ 172 SLIST_ENTRY(udssock) uds_hash; /* next in hash chain */ 173 TAILQ_ENTRY(udssock) uds_next; /* next in free list or queue */ 174 SIMPLEQ_HEAD(, uds_fd) uds_fds; /* in-flight file descriptors */ 175 TAILQ_HEAD(, udssock) uds_queue;/* queue of linked sockets */ 176 }; 177 178 #define UDSF_IN_USE 0x01 /* in use (for enumeration only) */ 179 #define UDSF_CONNECTED 0x02 /* connected or disconnected */ 180 #define UDSF_CONNWAIT 0x04 /* leave connecting until accept */ 181 #define UDSF_PASSCRED 0x08 /* pass credentials when receiving */ 182 183 /* Macros. */ 184 #define uds_get_type(uds) sockevent_get_type(&(uds)->uds_sock) 185 186 /* 187 * A socket that can be found through hash table lookups always has a non-empty 188 * path as well as a valid <dev,ino> pair identifying the socket file that is, 189 * or once was, identified by that path. However, a socket that is bound, even 190 * though it will still have an associated path, is not necessarily hashed. 191 * The reason for the difference is <dev,ino> pair reuse. This case is 192 * elaborated on in uds_bind(). 193 */ 194 #define uds_is_bound(uds) ((uds)->uds_pathlen != 0) 195 #define uds_is_hashed(uds) ((uds)->uds_dev != NO_DEV) 196 197 /* 198 * These macros may be used on all socket types. However, the uds_is_connected 199 * macro returns TRUE only for connection-oriented sockets. To see if a 200 * datagram socket is connected to a target, use uds_has_link instead. 201 */ 202 #define uds_has_conn(uds) ((uds)->uds_conn != NULL) 203 #define uds_has_link(uds) ((uds)->uds_link != NULL) 204 #define uds_get_peer(uds) \ 205 ((uds_get_type(uds) != SOCK_DGRAM) ? (uds)->uds_conn : (uds)->uds_link) 206 #define uds_is_listening(uds) sockevent_is_listening(&(uds)->uds_sock) 207 #define uds_is_connecting(uds) \ 208 (uds_has_link(uds) && !((uds)->uds_flags & UDSF_CONNECTED) && \ 209 uds_get_type(uds) != SOCK_DGRAM) 210 #define uds_is_connected(uds) \ 211 (((uds)->uds_flags & UDSF_CONNECTED) && uds_has_conn(uds)) 212 #define uds_is_disconnected(uds) \ 213 (((uds)->uds_flags & UDSF_CONNECTED) && !uds_has_conn(uds)) 214 215 #define uds_is_shutdown(uds, mask) \ 216 sockevent_is_shutdown(&(uds)->uds_sock, (mask)) 217 218 /* Function prototypes. */ 219 220 /* uds.c */ 221 sockid_t uds_get_id(struct udssock * uds); 222 struct udssock *uds_enum(struct udssock * prev, int type); 223 void uds_make_addr(const char * path, size_t len, struct sockaddr * addr, 224 socklen_t * addr_len); 225 int uds_lookup(struct udssock * uds, const struct sockaddr * addr, 226 socklen_t addr_len, endpoint_t user_endpt, struct udssock ** peerp); 227 228 /* io.c */ 229 void uds_io_init(void); 230 int uds_io_setup(struct udssock * uds); 231 void uds_io_cleanup(struct udssock * uds); 232 void uds_io_reset(struct udssock * uds); 233 size_t uds_io_buflen(void); 234 int uds_pre_send(struct sock * sock, size_t len, socklen_t ctl_len, 235 const struct sockaddr * addr, socklen_t addr_len, 236 endpoint_t user_endpt, int flags); 237 int uds_send(struct sock * sock, const struct sockdriver_data * data, 238 size_t len, size_t * off, const struct sockdriver_data * ctl, 239 socklen_t ctl_len, socklen_t * ctl_off, const struct sockaddr * addr, 240 socklen_t addr_len, endpoint_t user_endpt, int flags, size_t min); 241 int uds_test_send(struct sock * sock, size_t min); 242 int uds_pre_recv(struct sock * sock, endpoint_t user_endpt, int flags); 243 int uds_recv(struct sock * sock, const struct sockdriver_data * data, 244 size_t len, size_t * off, const struct sockdriver_data * ctl, 245 socklen_t ctl_len, socklen_t * ctl_off, struct sockaddr * addr, 246 socklen_t * addr_len, endpoint_t user_endpt, int flags, size_t min, 247 int * rflags); 248 int uds_test_recv(struct sock * sock, size_t min, size_t * size); 249 250 /* stat.c */ 251 void uds_stat_init(void); 252 void uds_stat_cleanup(void); 253 254 #endif /* !MINIX_NET_UDS_UDS_H */ 255