xref: /minix/minix/include/minix/sockdriver.h (revision 27852ebe)
1 #ifndef _MINIX_SOCKDRIVER_H
2 #define _MINIX_SOCKDRIVER_H
3 
4 #include <sys/socket.h>
5 
6 /*
7  * The maximum sockaddr structure size.  All provided address buffers are of
8  * this size.  The socket driver writer must ensure that all the driver's
9  * sockaddr structures fit in this size, increasing this variable as necessary.
10  */
11 #define SOCKADDR_MAX	(UINT8_MAX + 1)
12 
13 /*
14  * Convenience macro to perform static testing of the above assumption.  Usage:
15  *   STATIC_SOCKADDR_MAX_ASSERT(sockaddr_un);
16  */
17 #define STATIC_SOCKADDR_MAX_ASSERT(t) \
18 	typedef int _STATIC_SOCKADDR_MAX_ASSERT_##t[/* CONSTCOND */ \
19 		(sizeof(struct t) <= SOCKADDR_MAX) ? 1 : -1]
20 
21 /*
22  * The maximum number of I/O vector elements that can be passed to the
23  * sockdriver_vcopy functions.
24  */
25 #define SOCKDRIVER_IOV_MAX	SCPVEC_NR
26 
27 /* Socket identifier.  May also be a negative error code upon call return. */
28 typedef int32_t sockid_t;
29 
30 /* Socket request identifier.  To be used in struct sockdriver_call only. */
31 typedef int32_t sockreq_t;
32 
33 /*
34  * The following structures are all identity transfer (ixfer) safe, meaning
35  * that they are guaranteed not to contain pointers.
36  */
37 
38 /*
39  * Data structure with call information for later call resumption.  The socket
40  * driver may use the sc_endpt and sc_req fields to index and find suspended
41  * calls for the purpose of cancellation.  A provided sc_endpt value will never
42  * be NONE, so this value may be used to mark the structure as unused, if
43  * needed.  Otherwise, the structure should be copied around as is.  Upon
44  * cancellation, the original call structure must be used to resume the call,
45  * and not the call structure passed to sdr_cancel.
46  */
47 struct sockdriver_call {
48 	endpoint_t	sc_endpt;	/* endpoint of caller */
49 	sockreq_t	sc_req;		/* request identifier */
50 	cp_grant_id_t	_sc_grant;	/* address storage grant (private) */
51 	size_t		_sc_len;	/* size of address storage (private) */
52 };
53 
54 /*
55  * Data structure for the requesting party of select requests.  The socket
56  * driver may use the ss_endpt field to index and find suspended select calls.
57  * A provided ss_endpt value will never be NONE, so this value may be used to
58  * mark the structure as unused, if needed.  For future compatibility, the
59  * structure should be copied around in its entirety.
60  */
61 struct sockdriver_select {
62 	endpoint_t	ss_endpt;	/* endpoint of caller */
63 };
64 
65 /* Opaque data structure for copying in and out data. */
66 struct sockdriver_data {
67 	endpoint_t	_sd_endpt;	/* endpoint of grant owner (private) */
68 	cp_grant_id_t	_sd_grant;	/* safecopy grant (private) */
69 	size_t		_sd_len;	/* size of granted area (private) */
70 };
71 
72 /*
73  * Opaque data structure that may store the contents of sockdriver_data more
74  * compactly in cases where some of its fields are available through other
75  * means.  Practically, this can save memory when storing suspended calls.
76  */
77 struct sockdriver_packed_data {
78 	cp_grant_id_t	_spd_grant;	/* safecopy grant (private) */
79 };
80 
81 /* Function call table for socket drivers. */
82 struct sockdriver {
83 	sockid_t (* sdr_socket)(int domain, int type, int protocol,
84 	    endpoint_t user_endpt);
85 	int (* sdr_socketpair)(int domain, int type, int protocol,
86 	    endpoint_t user_endpt, sockid_t id[2]);
87 	int (* sdr_bind)(sockid_t id, const struct sockaddr * __restrict addr,
88 	    socklen_t addr_len, endpoint_t user_endpt,
89 	    const struct sockdriver_call * __restrict call);
90 	int (* sdr_connect)(sockid_t id,
91 	    const struct sockaddr * __restrict addr, socklen_t addr_len,
92 	    endpoint_t user_endpt,
93 	    const struct sockdriver_call * __restrict call);
94 	int (* sdr_listen)(sockid_t id, int backlog);
95 	sockid_t (* sdr_accept)(sockid_t id, struct sockaddr * __restrict addr,
96 	    socklen_t * __restrict addr_len, endpoint_t user_endpt,
97 	    const struct sockdriver_call * __restrict call);
98 	int (* sdr_send)(sockid_t id,
99 	    const struct sockdriver_data * __restrict data, size_t len,
100 	    const struct sockdriver_data * __restrict ctl_data,
101 	    socklen_t ctl_len, const struct sockaddr * __restrict addr,
102 	    socklen_t addr_len, endpoint_t user_endpt, int flags,
103 	    const struct sockdriver_call * __restrict call);
104 	int (* sdr_recv)(sockid_t id,
105 	    const struct sockdriver_data * __restrict data, size_t len,
106 	    const struct sockdriver_data * __restrict ctl_data,
107 	    socklen_t * __restrict ctl_len, struct sockaddr * __restrict addr,
108 	    socklen_t * __restrict addr_len, endpoint_t user_endpt,
109 	    int * __restrict flags,
110 	    const struct sockdriver_call * __restrict call);
111 	int (* sdr_ioctl)(sockid_t id, unsigned long request,
112 	    const struct sockdriver_data * __restrict data,
113 	    endpoint_t user_endpt,
114 	    const struct sockdriver_call * __restrict call);
115 	int (* sdr_setsockopt)(sockid_t id, int level, int name,
116 	    const struct sockdriver_data * data, socklen_t len);
117 	int (* sdr_getsockopt)(sockid_t id, int level, int name,
118 	    const struct sockdriver_data * __restrict data,
119 	    socklen_t * __restrict len);
120 	int (* sdr_getsockname)(sockid_t id, struct sockaddr * __restrict addr,
121 	    socklen_t * __restrict addr_len);
122 	int (* sdr_getpeername)(sockid_t id, struct sockaddr * __restrict addr,
123 	    socklen_t * __restrict addr_len);
124 	int (* sdr_shutdown)(sockid_t id, int how);
125 	int (* sdr_close)(sockid_t id, const struct sockdriver_call * call);
126 	void (* sdr_cancel)(sockid_t id, const struct sockdriver_call * call);
127 	int (* sdr_select)(sockid_t id, unsigned int ops,
128 	    const struct sockdriver_select * sel);
129 	void (* sdr_alarm)(clock_t stamp);
130 	void (* sdr_other)(const message * m_ptr, int ipc_status);
131 };
132 
133 /* Functions defined by libsockdriver. */
134 void sockdriver_announce(void);
135 void sockdriver_process(const struct sockdriver * __restrict sdp,
136 	const message * __restrict m_ptr, int ipc_status);
137 void sockdriver_terminate(void);
138 void sockdriver_task(const struct sockdriver * sdp);
139 
140 void sockdriver_reply_generic(const struct sockdriver_call * call, int reply);
141 void sockdriver_reply_accept(const struct sockdriver_call * __restrict call,
142 	sockid_t reply, struct sockaddr * __restrict addr, socklen_t addr_len);
143 void sockdriver_reply_recv(const struct sockdriver_call * __restrict call,
144 	int reply, socklen_t ctl_len, struct sockaddr * __restrict addr,
145 	socklen_t addr_len, int flags);
146 void sockdriver_reply_select(const struct sockdriver_select * sel, sockid_t id,
147 	int ops);
148 
149 int sockdriver_copyin(const struct sockdriver_data * __restrict data,
150 	size_t off, void * __restrict ptr, size_t len);
151 int sockdriver_copyout(const struct sockdriver_data * __restrict data,
152 	size_t off, const void * __restrict ptr, size_t len);
153 
154 int sockdriver_vcopyin(const struct sockdriver_data * __restrict data,
155 	size_t off, const iovec_t * iov, unsigned int iovcnt);
156 int sockdriver_vcopyout(const struct sockdriver_data * __restrict data,
157 	size_t off, const iovec_t * iov, unsigned int iovcnt);
158 
159 int sockdriver_copyin_opt(const struct sockdriver_data * __restrict data,
160 	void * __restrict ptr, size_t len, socklen_t optlen);
161 int sockdriver_copyout_opt(const struct sockdriver_data * __restrict data,
162 	const void * __restrict ptr, size_t len,
163 	socklen_t * __restrict optlen);
164 
165 int sockdriver_pack_data(struct sockdriver_packed_data * pack,
166 	const struct sockdriver_call * call,
167 	const struct sockdriver_data * data, size_t len);
168 void sockdriver_unpack_data(struct sockdriver_data * data,
169 	const struct sockdriver_call * call,
170 	const struct sockdriver_packed_data * pack, size_t len);
171 
172 #endif /* !_MINIX_SOCKDRIVER_H */
173