4 * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
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.
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.
19 /* Id: socket_api.c,v 1.5 2009/10/01 01:30:01 sar Exp */
24 #include <isc/magic.h>
25 #include <isc/mutex.h>
27 #include <isc/socket.h>
30 static isc_mutex_t createlock
;
31 static isc_once_t once
= ISC_ONCE_INIT
;
32 static isc_socketmgrcreatefunc_t socketmgr_createfunc
= NULL
;
36 RUNTIME_CHECK(isc_mutex_init(&createlock
) == ISC_R_SUCCESS
);
40 isc_socket_register(isc_socketmgrcreatefunc_t createfunc
) {
41 isc_result_t result
= ISC_R_SUCCESS
;
43 RUNTIME_CHECK(isc_once_do(&once
, initialize
) == ISC_R_SUCCESS
);
46 if (socketmgr_createfunc
== NULL
)
47 socketmgr_createfunc
= createfunc
;
49 result
= ISC_R_EXISTS
;
56 isc_socketmgr_createinctx(isc_mem_t
*mctx
, isc_appctx_t
*actx
,
57 isc_socketmgr_t
**managerp
)
63 REQUIRE(socketmgr_createfunc
!= NULL
);
64 result
= (*socketmgr_createfunc
)(mctx
, managerp
);
68 if (result
== ISC_R_SUCCESS
)
69 isc_appctx_setsocketmgr(actx
, *managerp
);
75 isc_socketmgr_create(isc_mem_t
*mctx
, isc_socketmgr_t
**managerp
) {
80 REQUIRE(socketmgr_createfunc
!= NULL
);
81 result
= (*socketmgr_createfunc
)(mctx
, managerp
);
89 isc_socketmgr_destroy(isc_socketmgr_t
**managerp
) {
90 REQUIRE(managerp
!= NULL
&& ISCAPI_SOCKETMGR_VALID(*managerp
));
92 (*managerp
)->methods
->destroy(managerp
);
94 ENSURE(*managerp
== NULL
);
98 isc_socket_create(isc_socketmgr_t
*manager
, int pf
, isc_sockettype_t type
,
99 isc_socket_t
**socketp
)
101 REQUIRE(ISCAPI_SOCKETMGR_VALID(manager
));
103 return (manager
->methods
->socketcreate(manager
, pf
, type
, socketp
));
107 isc_socket_attach(isc_socket_t
*sock
, isc_socket_t
**socketp
) {
108 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
109 REQUIRE(socketp
!= NULL
&& *socketp
== NULL
);
111 sock
->methods
->attach(sock
, socketp
);
113 ENSURE(*socketp
== sock
);
117 isc_socket_detach(isc_socket_t
**socketp
) {
118 REQUIRE(socketp
!= NULL
&& ISCAPI_SOCKET_VALID(*socketp
));
120 (*socketp
)->methods
->detach(socketp
);
122 ENSURE(*socketp
== NULL
);
126 isc_socket_bind(isc_socket_t
*sock
, isc_sockaddr_t
*sockaddr
,
127 unsigned int options
)
129 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
131 return (sock
->methods
->bind(sock
, sockaddr
, options
));
135 isc_socket_sendto(isc_socket_t
*sock
, isc_region_t
*region
, isc_task_t
*task
,
136 isc_taskaction_t action
, const void *arg
,
137 isc_sockaddr_t
*address
, struct in6_pktinfo
*pktinfo
)
139 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
141 return (sock
->methods
->sendto(sock
, region
, task
, action
, arg
, address
,
146 isc_socket_connect(isc_socket_t
*sock
, isc_sockaddr_t
*addr
, isc_task_t
*task
,
147 isc_taskaction_t action
, const void *arg
)
149 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
151 return (sock
->methods
->connect(sock
, addr
, task
, action
, arg
));
155 isc_socket_recv(isc_socket_t
*sock
, isc_region_t
*region
, unsigned int minimum
,
156 isc_task_t
*task
, isc_taskaction_t action
, const void *arg
)
158 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
160 return (sock
->methods
->recv(sock
, region
, minimum
, task
, action
, arg
));
164 isc_socket_cancel(isc_socket_t
*sock
, isc_task_t
*task
, unsigned int how
) {
165 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
167 sock
->methods
->cancel(sock
, task
, how
);
171 isc_socket_getsockname(isc_socket_t
*sock
, isc_sockaddr_t
*addressp
) {
172 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
174 return (sock
->methods
->getsockname(sock
, addressp
));
178 isc_socket_ipv6only(isc_socket_t
*sock
, isc_boolean_t yes
) {
179 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
181 sock
->methods
->ipv6only(sock
, yes
);
185 isc_socket_gettype(isc_socket_t
*sock
) {
186 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
188 return (sock
->methods
->gettype(sock
));
192 isc_socket_setname(isc_socket_t
*socket
, const char *name
, void *tag
) {
193 REQUIRE(ISCAPI_SOCKET_VALID(socket
));
195 UNUSED(socket
); /* in case REQUIRE() is empty */
201 isc_socket_fdwatchcreate(isc_socketmgr_t
*manager
, int fd
, int flags
,
202 isc_sockfdwatch_t callback
, void *cbarg
,
203 isc_task_t
*task
, isc_socket_t
**socketp
)
205 REQUIRE(ISCAPI_SOCKETMGR_VALID(manager
));
207 return (manager
->methods
->fdwatchcreate(manager
, fd
, flags
,
208 callback
, cbarg
, task
,
213 isc_socket_fdwatchpoke(isc_socket_t
*sock
, int flags
)
215 REQUIRE(ISCAPI_SOCKET_VALID(sock
));
217 return(sock
->methods
->fdwatchpoke(sock
, flags
));