xref: /minix/external/bsd/bind/dist/lib/isc/socket_api.c (revision fb9c64b2)
1 /*	$NetBSD: socket_api.c,v 1.10 2014/12/10 04:37:59 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2009, 2011-2014  Internet Systems Consortium, Inc. ("ISC")
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /* Id */
20 
21 #include <config.h>
22 
23 #include <isc/app.h>
24 #include <isc/magic.h>
25 #include <isc/mutex.h>
26 #include <isc/once.h>
27 #include <isc/socket.h>
28 #include <isc/util.h>
29 
30 static isc_mutex_t createlock;
31 static isc_once_t once = ISC_ONCE_INIT;
32 static isc_socketmgrcreatefunc_t socketmgr_createfunc = NULL;
33 
34 static void
35 initialize(void) {
36 	RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
37 }
38 
39 isc_result_t
40 isc_socket_register(isc_socketmgrcreatefunc_t createfunc) {
41 	isc_result_t result = ISC_R_SUCCESS;
42 
43 	RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
44 
45 	LOCK(&createlock);
46 	if (socketmgr_createfunc == NULL)
47 		socketmgr_createfunc = createfunc;
48 	else
49 		result = ISC_R_EXISTS;
50 	UNLOCK(&createlock);
51 
52 	return (result);
53 }
54 
55 isc_result_t
56 isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
57 			  isc_socketmgr_t **managerp)
58 {
59 	isc_result_t result;
60 
61 	LOCK(&createlock);
62 
63 	REQUIRE(socketmgr_createfunc != NULL);
64 	result = (*socketmgr_createfunc)(mctx, managerp);
65 
66 	UNLOCK(&createlock);
67 
68 	if (result == ISC_R_SUCCESS)
69 		isc_appctx_setsocketmgr(actx, *managerp);
70 
71 	return (result);
72 }
73 
74 isc_result_t
75 isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
76 	isc_result_t result;
77 
78 	if (isc_bind9)
79 		return (isc__socketmgr_create(mctx, managerp));
80 
81 	LOCK(&createlock);
82 
83 	REQUIRE(socketmgr_createfunc != NULL);
84 	result = (*socketmgr_createfunc)(mctx, managerp);
85 
86 	UNLOCK(&createlock);
87 
88 	return (result);
89 }
90 
91 void
92 isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
93 	REQUIRE(managerp != NULL && ISCAPI_SOCKETMGR_VALID(*managerp));
94 
95 	if (isc_bind9)
96 		isc__socketmgr_destroy(managerp);
97 	else
98 		(*managerp)->methods->destroy(managerp);
99 
100 	ENSURE(*managerp == NULL);
101 }
102 
103 isc_result_t
104 isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
105 		  isc_socket_t **socketp)
106 {
107 	REQUIRE(ISCAPI_SOCKETMGR_VALID(manager));
108 
109 	if (isc_bind9)
110 		return (isc__socket_create(manager, pf, type, socketp));
111 
112 	return (manager->methods->socketcreate(manager, pf, type, socketp));
113 }
114 
115 void
116 isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
117 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
118 	REQUIRE(socketp != NULL && *socketp == NULL);
119 
120 	if (isc_bind9)
121 		isc__socket_attach(sock, socketp);
122 	else
123 		sock->methods->attach(sock, socketp);
124 
125 	ENSURE(*socketp == sock);
126 }
127 
128 void
129 isc_socket_detach(isc_socket_t **socketp) {
130 	REQUIRE(socketp != NULL && ISCAPI_SOCKET_VALID(*socketp));
131 
132 	if (isc_bind9)
133 		isc__socket_detach(socketp);
134 	else
135 		(*socketp)->methods->detach(socketp);
136 
137 	ENSURE(*socketp == NULL);
138 }
139 
140 isc_result_t
141 isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
142 		unsigned int options)
143 {
144 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
145 
146 	if (isc_bind9)
147 		return (isc__socket_bind(sock, sockaddr, options));
148 
149 	return (sock->methods->bind(sock, sockaddr, options));
150 }
151 
152 isc_result_t
153 isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
154 		  isc_taskaction_t action, void *arg,
155 		  isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
156 {
157 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
158 
159 	if (isc_bind9)
160 		return (isc__socket_sendto(sock, region, task,
161 					   action, arg, address, pktinfo));
162 
163 	return (sock->methods->sendto(sock, region, task, action, arg, address,
164 				      pktinfo));
165 }
166 
167 isc_result_t
168 isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task,
169 		   isc_taskaction_t action, void *arg)
170 {
171 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
172 
173 	if (isc_bind9)
174 		return (isc__socket_connect(sock, addr, task, action, arg));
175 
176 	return (sock->methods->connect(sock, addr, task, action, arg));
177 }
178 
179 isc_result_t
180 isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
181 		isc_task_t *task, isc_taskaction_t action, void *arg)
182 {
183 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
184 
185 	if (isc_bind9)
186 		return (isc__socket_recv(sock, region, minimum,
187 					 task, action, arg));
188 
189 	return (sock->methods->recv(sock, region, minimum, task, action, arg));
190 }
191 
192 void
193 isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
194 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
195 
196 	if (isc_bind9)
197 		isc__socket_cancel(sock, task, how);
198 	else
199 		sock->methods->cancel(sock, task, how);
200 }
201 
202 isc_result_t
203 isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
204 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
205 
206 	if (isc_bind9)
207 		return (isc__socket_getsockname(sock, addressp));
208 
209 	return (sock->methods->getsockname(sock, addressp));
210 }
211 
212 void
213 isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
214 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
215 
216 	if (isc_bind9)
217 		isc__socket_ipv6only(sock, yes);
218 	else
219 		sock->methods->ipv6only(sock, yes);
220 }
221 
222 void
223 isc_socket_dscp(isc_socket_t *sock, isc_dscp_t dscp) {
224 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
225 
226 	sock->methods->dscp(sock, dscp);
227 }
228 
229 isc_sockettype_t
230 isc_socket_gettype(isc_socket_t *sock) {
231 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
232 
233 	if (isc_bind9)
234 		return (isc__socket_gettype(sock));
235 
236 	return (sock->methods->gettype(sock));
237 }
238 
239 void
240 isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
241 	REQUIRE(ISCAPI_SOCKET_VALID(socket));
242 
243 	UNUSED(socket);		/* in case REQUIRE() is empty */
244 	UNUSED(name);
245 	UNUSED(tag);
246 }
247 
248 isc_result_t
249 isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
250 			 isc_sockfdwatch_t callback, void *cbarg,
251 			 isc_task_t *task, isc_socket_t **socketp)
252 {
253 	REQUIRE(ISCAPI_SOCKETMGR_VALID(manager));
254 
255 	if (isc_bind9)
256 		return (isc__socket_fdwatchcreate(manager, fd, flags,
257 						  callback, cbarg,
258 						  task, socketp));
259 
260 	return (manager->methods->fdwatchcreate(manager, fd, flags,
261 						callback, cbarg, task,
262 						socketp));
263 }
264 
265 isc_result_t
266 isc_socket_fdwatchpoke(isc_socket_t *sock, int flags)
267 {
268 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
269 
270 	if (isc_bind9)
271 		return (isc__socket_fdwatchpoke(sock, flags));
272 
273 	return (sock->methods->fdwatchpoke(sock, flags));
274 }
275 
276 isc_result_t
277 isc_socket_dup(isc_socket_t *sock, isc_socket_t **socketp) {
278 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
279 	REQUIRE(socketp != NULL && *socketp == NULL);
280 
281 	if (isc_bind9)
282 		return (isc__socket_dup(sock, socketp));
283 
284 	return (sock->methods->dup(sock, socketp));
285 }
286 
287 int
288 isc_socket_getfd(isc_socket_t *sock) {
289 	REQUIRE(ISCAPI_SOCKET_VALID(sock));
290 
291 	if (isc_bind9)
292 		return (isc__socket_getfd(sock));
293 
294 	return (sock->methods->getfd(sock));
295 }
296 
297 isc_result_t
298 isc_socket_open(isc_socket_t *sock) {
299 	return (isc__socket_open(sock));
300 }
301 
302 isc_result_t
303 isc_socket_close(isc_socket_t *sock) {
304 	return (isc__socket_close(sock));
305 }
306 
307 isc_result_t
308 isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
309 		       unsigned int maxsocks)
310 {
311 	return (isc__socketmgr_create2(mctx, managerp, maxsocks));
312 }
313 
314 isc_result_t
315 isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
316 		 unsigned int minimum, isc_task_t *task,
317 		 isc_taskaction_t action, void *arg)
318 {
319 	return (isc__socket_recvv(sock, buflist, minimum, task, action, arg));
320 }
321 
322 isc_result_t
323 isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
324 		  unsigned int minimum, isc_task_t *task,
325 		  isc_socketevent_t *event, unsigned int flags)
326 {
327 	return (isc__socket_recv2(sock, region, minimum, task, event, flags));
328 }
329 
330 isc_result_t
331 isc_socket_send(isc_socket_t *sock, isc_region_t *region,
332 		 isc_task_t *task, isc_taskaction_t action, void *arg)
333 {
334 	return (isc__socket_send(sock, region, task, action, arg));
335 }
336 
337 isc_result_t
338 isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
339 		  isc_task_t *task, isc_taskaction_t action, void *arg)
340 {
341 	return (isc__socket_sendv(sock, buflist, task, action, arg));
342 }
343 
344 isc_result_t
345 isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
346 		    isc_task_t *task, isc_taskaction_t action, void *arg,
347 		    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
348 {
349 	return (isc__socket_sendtov(sock, buflist, task, action, arg,
350 				    address, pktinfo));
351 }
352 
353 isc_result_t
354 isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
355 		    isc_task_t *task, isc_taskaction_t action, void *arg,
356 		    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
357 		    unsigned int flags)
358 {
359 	return (isc__socket_sendtov2(sock, buflist, task, action, arg,
360 				     address, pktinfo, flags));
361 }
362 
363 isc_result_t
364 isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
365 		    isc_task_t *task,
366 		    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
367 		    isc_socketevent_t *event, unsigned int flags)
368 {
369 	return (isc__socket_sendto2(sock, region, task, address, pktinfo,
370 				    event, flags));
371 }
372 
373 void
374 isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
375 	isc__socket_cleanunix(sockaddr, active);
376 }
377 
378 isc_result_t
379 isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
380 		     isc_uint32_t owner, isc_uint32_t group)
381 {
382 	return (isc__socket_permunix(sockaddr, perm, owner, group));
383 }
384 
385 isc_result_t
386 isc_socket_filter(isc_socket_t *sock, const char *filter) {
387 	return (isc__socket_filter(sock, filter));
388 }
389 
390 isc_result_t
391 isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
392 	return (isc__socket_listen(sock, backlog));
393 }
394 
395 isc_result_t
396 isc_socket_accept(isc_socket_t *sock, isc_task_t *task,
397 		   isc_taskaction_t action, void *arg)
398 {
399 	return (isc__socket_accept(sock, task, action, arg));
400 }
401 
402 isc_result_t
403 isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
404 	return (isc__socket_getpeername(sock, addressp));
405 }
406