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