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