1224090Sdougb/* 2254897Serwin * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") 3224090Sdougb * 4224090Sdougb * Permission to use, copy, modify, and/or distribute this software for any 5224090Sdougb * purpose with or without fee is hereby granted, provided that the above 6224090Sdougb * copyright notice and this permission notice appear in all copies. 7224090Sdougb * 8224090Sdougb * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9224090Sdougb * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10224090Sdougb * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11224090Sdougb * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12224090Sdougb * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13224090Sdougb * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14224090Sdougb * PERFORMANCE OF THIS SOFTWARE. 15224090Sdougb */ 16224090Sdougb 17234010Sdougb/* $Id$ */ 18224090Sdougb 19224090Sdougb#include <config.h> 20224090Sdougb 21224090Sdougb#include <isc/app.h> 22224090Sdougb#include <isc/magic.h> 23224090Sdougb#include <isc/mutex.h> 24224090Sdougb#include <isc/once.h> 25224090Sdougb#include <isc/socket.h> 26224090Sdougb#include <isc/util.h> 27224090Sdougb 28224090Sdougbstatic isc_mutex_t createlock; 29224090Sdougbstatic isc_once_t once = ISC_ONCE_INIT; 30224090Sdougbstatic isc_socketmgrcreatefunc_t socketmgr_createfunc = NULL; 31224090Sdougb 32224090Sdougbstatic void 33224090Sdougbinitialize(void) { 34224090Sdougb RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); 35224090Sdougb} 36224090Sdougb 37224090Sdougbisc_result_t 38224090Sdougbisc_socket_register(isc_socketmgrcreatefunc_t createfunc) { 39224090Sdougb isc_result_t result = ISC_R_SUCCESS; 40224090Sdougb 41224090Sdougb RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); 42224090Sdougb 43224090Sdougb LOCK(&createlock); 44224090Sdougb if (socketmgr_createfunc == NULL) 45224090Sdougb socketmgr_createfunc = createfunc; 46224090Sdougb else 47224090Sdougb result = ISC_R_EXISTS; 48224090Sdougb UNLOCK(&createlock); 49224090Sdougb 50224090Sdougb return (result); 51224090Sdougb} 52224090Sdougb 53224090Sdougbisc_result_t 54224090Sdougbisc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, 55224090Sdougb isc_socketmgr_t **managerp) 56224090Sdougb{ 57224090Sdougb isc_result_t result; 58224090Sdougb 59224090Sdougb LOCK(&createlock); 60224090Sdougb 61224090Sdougb REQUIRE(socketmgr_createfunc != NULL); 62224090Sdougb result = (*socketmgr_createfunc)(mctx, managerp); 63224090Sdougb 64224090Sdougb UNLOCK(&createlock); 65224090Sdougb 66224090Sdougb if (result == ISC_R_SUCCESS) 67224090Sdougb isc_appctx_setsocketmgr(actx, *managerp); 68224090Sdougb 69224090Sdougb return (result); 70224090Sdougb} 71224090Sdougb 72224090Sdougbisc_result_t 73224090Sdougbisc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { 74224090Sdougb isc_result_t result; 75224090Sdougb 76224090Sdougb LOCK(&createlock); 77224090Sdougb 78224090Sdougb REQUIRE(socketmgr_createfunc != NULL); 79224090Sdougb result = (*socketmgr_createfunc)(mctx, managerp); 80224090Sdougb 81224090Sdougb UNLOCK(&createlock); 82224090Sdougb 83224090Sdougb return (result); 84224090Sdougb} 85224090Sdougb 86224090Sdougbvoid 87224090Sdougbisc_socketmgr_destroy(isc_socketmgr_t **managerp) { 88224090Sdougb REQUIRE(managerp != NULL && ISCAPI_SOCKETMGR_VALID(*managerp)); 89224090Sdougb 90224090Sdougb (*managerp)->methods->destroy(managerp); 91224090Sdougb 92224090Sdougb ENSURE(*managerp == NULL); 93224090Sdougb} 94224090Sdougb 95224090Sdougbisc_result_t 96224090Sdougbisc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, 97224090Sdougb isc_socket_t **socketp) 98224090Sdougb{ 99224090Sdougb REQUIRE(ISCAPI_SOCKETMGR_VALID(manager)); 100224090Sdougb 101224090Sdougb return (manager->methods->socketcreate(manager, pf, type, socketp)); 102224090Sdougb} 103224090Sdougb 104224090Sdougbvoid 105224090Sdougbisc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) { 106224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 107224090Sdougb REQUIRE(socketp != NULL && *socketp == NULL); 108224090Sdougb 109224090Sdougb sock->methods->attach(sock, socketp); 110224090Sdougb 111224090Sdougb ENSURE(*socketp == sock); 112224090Sdougb} 113224090Sdougb 114224090Sdougbvoid 115224090Sdougbisc_socket_detach(isc_socket_t **socketp) { 116224090Sdougb REQUIRE(socketp != NULL && ISCAPI_SOCKET_VALID(*socketp)); 117224090Sdougb 118224090Sdougb (*socketp)->methods->detach(socketp); 119224090Sdougb 120224090Sdougb ENSURE(*socketp == NULL); 121224090Sdougb} 122224090Sdougb 123224090Sdougbisc_result_t 124224090Sdougbisc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, 125224090Sdougb unsigned int options) 126224090Sdougb{ 127224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 128224090Sdougb 129224090Sdougb return (sock->methods->bind(sock, sockaddr, options)); 130224090Sdougb} 131224090Sdougb 132224090Sdougbisc_result_t 133224090Sdougbisc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, 134224090Sdougb isc_taskaction_t action, const void *arg, 135224090Sdougb isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) 136224090Sdougb{ 137224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 138224090Sdougb 139224090Sdougb return (sock->methods->sendto(sock, region, task, action, arg, address, 140224090Sdougb pktinfo)); 141224090Sdougb} 142224090Sdougb 143224090Sdougbisc_result_t 144254897Serwinisc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, 145254897Serwin isc_task_t *task, isc_sockaddr_t *address, 146254897Serwin struct in6_pktinfo *pktinfo, isc_socketevent_t *event, 147254897Serwin unsigned int flags) 148254897Serwin{ 149254897Serwin REQUIRE(ISCAPI_SOCKET_VALID(sock)); 150254897Serwin 151254897Serwin return (sock->methods->sendto2(sock, region, task, address, 152254897Serwin pktinfo, event, flags)); 153254897Serwin} 154254897Serwin 155254897Serwinisc_result_t 156224090Sdougbisc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, 157224090Sdougb isc_taskaction_t action, const void *arg) 158224090Sdougb{ 159224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 160224090Sdougb 161224090Sdougb return (sock->methods->connect(sock, addr, task, action, arg)); 162224090Sdougb} 163224090Sdougb 164224090Sdougbisc_result_t 165224090Sdougbisc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, 166224090Sdougb isc_task_t *task, isc_taskaction_t action, const void *arg) 167224090Sdougb{ 168224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 169224090Sdougb 170224090Sdougb return (sock->methods->recv(sock, region, minimum, task, action, arg)); 171224090Sdougb} 172224090Sdougb 173254897Serwinisc_result_t 174254897Serwinisc_socket_recv2(isc_socket_t *sock, isc_region_t *region, 175254897Serwin unsigned int minimum, isc_task_t *task, 176254897Serwin isc_socketevent_t *event, unsigned int flags) 177254897Serwin{ 178254897Serwin REQUIRE(ISCAPI_SOCKET_VALID(sock)); 179254897Serwin 180254897Serwin return (sock->methods->recv2(sock, region, minimum, task, 181254897Serwin event, flags)); 182254897Serwin} 183254897Serwin 184224090Sdougbvoid 185224090Sdougbisc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { 186224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 187224090Sdougb 188224090Sdougb sock->methods->cancel(sock, task, how); 189224090Sdougb} 190224090Sdougb 191224090Sdougbisc_result_t 192224090Sdougbisc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) { 193224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 194224090Sdougb 195224090Sdougb return (sock->methods->getsockname(sock, addressp)); 196224090Sdougb} 197224090Sdougb 198224090Sdougbvoid 199224090Sdougbisc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) { 200224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 201224090Sdougb 202224090Sdougb sock->methods->ipv6only(sock, yes); 203224090Sdougb} 204224090Sdougb 205224090Sdougbisc_sockettype_t 206224090Sdougbisc_socket_gettype(isc_socket_t *sock) { 207224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 208224090Sdougb 209224090Sdougb return (sock->methods->gettype(sock)); 210224090Sdougb} 211224090Sdougb 212224090Sdougbvoid 213224090Sdougbisc_socket_setname(isc_socket_t *socket, const char *name, void *tag) { 214224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(socket)); 215224090Sdougb 216224090Sdougb UNUSED(socket); /* in case REQUIRE() is empty */ 217224090Sdougb UNUSED(name); 218224090Sdougb UNUSED(tag); 219224090Sdougb} 220224090Sdougb 221224090Sdougbisc_result_t 222224090Sdougbisc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, 223224090Sdougb isc_sockfdwatch_t callback, void *cbarg, 224224090Sdougb isc_task_t *task, isc_socket_t **socketp) 225224090Sdougb{ 226224090Sdougb REQUIRE(ISCAPI_SOCKETMGR_VALID(manager)); 227224090Sdougb 228224090Sdougb return (manager->methods->fdwatchcreate(manager, fd, flags, 229224090Sdougb callback, cbarg, task, 230224090Sdougb socketp)); 231224090Sdougb} 232224090Sdougb 233224090Sdougbisc_result_t 234224090Sdougbisc_socket_fdwatchpoke(isc_socket_t *sock, int flags) 235224090Sdougb{ 236224090Sdougb REQUIRE(ISCAPI_SOCKET_VALID(sock)); 237224090Sdougb 238224090Sdougb return(sock->methods->fdwatchpoke(sock, flags)); 239224090Sdougb} 240254897Serwin 241254897Serwinisc_result_t 242254897Serwinisc_socket_dup(isc_socket_t *sock, isc_socket_t **socketp) { 243254897Serwin REQUIRE(ISCAPI_SOCKET_VALID(sock)); 244254897Serwin REQUIRE(socketp != NULL && *socketp == NULL); 245254897Serwin 246254897Serwin return(sock->methods->dup(sock, socketp)); 247254897Serwin} 248254897Serwin 249254897Serwinint 250254897Serwinisc_socket_getfd(isc_socket_t *sock) { 251254897Serwin REQUIRE(ISCAPI_SOCKET_VALID(sock)); 252254897Serwin 253254897Serwin return(sock->methods->getfd(sock)); 254254897Serwin} 255