1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
#include "apr_arch_networkio.h"
18
#include "apr_arch_inherit.h"
19
#include "apr_network_io.h"
20
#include "apr_general.h"
21
#include "apr_portable.h"
23
#include "apr_strings.h"
26
#include <sys/socket.h>
27
#include <netinet/tcp.h>
28
#include <netinet/in.h>
29
#include <arpa/inet.h>
31
#include "apr_arch_os2calls.h"
33
static apr_status_t socket_cleanup(void *sock)
35
apr_socket_t *thesocket = sock;
37
if (thesocket->socketdes < 0) {
38
return APR_EINVALSOCK;
41
if (soclose(thesocket->socketdes) == 0) {
42
thesocket->socketdes = -1;
46
return APR_OS2_STATUS(sock_errno());
50
static void set_socket_vars(apr_socket_t *sock, int family, int type, int protocol)
53
sock->protocol = protocol;
54
apr_sockaddr_vars_set(sock->local_addr, family, 0);
55
apr_sockaddr_vars_set(sock->remote_addr, family, 0);
58
static void alloc_socket(apr_socket_t **new, apr_pool_t *p)
60
*new = (apr_socket_t *)apr_pcalloc(p, sizeof(apr_socket_t));
62
(*new)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->pool,
63
sizeof(apr_sockaddr_t));
64
(*new)->local_addr->pool = p;
65
(*new)->remote_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->pool,
66
sizeof(apr_sockaddr_t));
67
(*new)->remote_addr->pool = p;
69
/* Create a pollset with room for one descriptor. */
70
/* ### check return codes */
71
(void) apr_pollset_create(&(*new)->pollset, 1, p, 0);
74
APR_DECLARE(apr_status_t) apr_socket_protocol_get(apr_socket_t *sock, int *protocol)
76
*protocol = sock->protocol;
80
APR_DECLARE(apr_status_t) apr_socket_create(apr_socket_t **new, int family, int type,
81
int protocol, apr_pool_t *cont)
83
int downgrade = (family == AF_UNSPEC);
86
if (family == AF_UNSPEC) {
94
alloc_socket(new, cont);
96
(*new)->socketdes = socket(family, type, protocol);
98
if ((*new)->socketdes < 0 && downgrade) {
100
(*new)->socketdes = socket(family, type, protocol);
104
if ((*new)->socketdes < 0) {
105
return APR_OS2_STATUS(sock_errno());
107
set_socket_vars(*new, family, type, protocol);
109
(*new)->timeout = -1;
110
(*new)->nonblock = FALSE;
111
apr_pool_cleanup_register((*new)->pool, (void *)(*new),
112
socket_cleanup, apr_pool_cleanup_null);
117
APR_DECLARE(apr_status_t) apr_socket_shutdown(apr_socket_t *thesocket,
118
apr_shutdown_how_e how)
120
if (shutdown(thesocket->socketdes, how) == 0) {
124
return APR_OS2_STATUS(sock_errno());
128
APR_DECLARE(apr_status_t) apr_socket_close(apr_socket_t *thesocket)
130
apr_pool_cleanup_kill(thesocket->pool, thesocket, socket_cleanup);
131
return socket_cleanup(thesocket);
134
APR_DECLARE(apr_status_t) apr_socket_bind(apr_socket_t *sock,
137
if (bind(sock->socketdes,
138
(struct sockaddr *)&sa->sa,
140
return APR_OS2_STATUS(sock_errno());
142
sock->local_addr = sa;
147
APR_DECLARE(apr_status_t) apr_socket_listen(apr_socket_t *sock,
150
if (listen(sock->socketdes, backlog) == -1)
151
return APR_OS2_STATUS(sock_errno());
156
APR_DECLARE(apr_status_t) apr_socket_accept(apr_socket_t **new,
158
apr_pool_t *connection_context)
160
alloc_socket(new, connection_context);
161
set_socket_vars(*new, sock->local_addr->sa.sin.sin_family, SOCK_STREAM, sock->protocol);
163
(*new)->timeout = -1;
164
(*new)->nonblock = FALSE;
166
(*new)->socketdes = accept(sock->socketdes,
167
(struct sockaddr *)&(*new)->remote_addr->sa,
168
&(*new)->remote_addr->salen);
170
if ((*new)->socketdes < 0) {
171
return APR_OS2_STATUS(sock_errno());
174
*(*new)->local_addr = *sock->local_addr;
175
(*new)->local_addr->pool = connection_context;
176
(*new)->remote_addr->port = ntohs((*new)->remote_addr->sa.sin.sin_port);
178
/* fix up any pointers which are no longer valid */
179
if (sock->local_addr->sa.sin.sin_family == AF_INET) {
180
(*new)->local_addr->ipaddr_ptr = &(*new)->local_addr->sa.sin.sin_addr;
183
apr_pool_cleanup_register((*new)->pool, (void *)(*new),
184
socket_cleanup, apr_pool_cleanup_null);
188
APR_DECLARE(apr_status_t) apr_socket_connect(apr_socket_t *sock,
191
if ((connect(sock->socketdes, (struct sockaddr *)&sa->sa.sin,
193
(sock_errno() != SOCEINPROGRESS)) {
194
return APR_OS2_STATUS(sock_errno());
197
int namelen = sizeof(sock->local_addr->sa.sin);
198
getsockname(sock->socketdes, (struct sockaddr *)&sock->local_addr->sa.sin,
200
sock->remote_addr = sa;
205
APR_DECLARE(apr_status_t) apr_socket_type_get(apr_socket_t *sock, int *type)
211
APR_DECLARE(apr_status_t) apr_socket_data_get(void **data, const char *key,
214
sock_userdata_t *cur = sock->userdata;
219
if (!strcmp(cur->key, key)) {
231
APR_DECLARE(apr_status_t) apr_socket_data_set(apr_socket_t *sock, void *data, const char *key,
232
apr_status_t (*cleanup) (void *))
234
sock_userdata_t *new = apr_palloc(sock->pool, sizeof(sock_userdata_t));
236
new->key = apr_pstrdup(sock->pool, key);
238
new->next = sock->userdata;
239
sock->userdata = new;
242
apr_pool_cleanup_register(sock->pool, data, cleanup, cleanup);
248
APR_DECLARE(apr_status_t) apr_os_sock_get(apr_os_sock_t *thesock, apr_socket_t *sock)
250
*thesock = sock->socketdes;
254
APR_DECLARE(apr_status_t) apr_os_sock_make(apr_socket_t **apr_sock,
255
apr_os_sock_info_t *os_sock_info,
258
alloc_socket(apr_sock, cont);
259
set_socket_vars(*apr_sock, os_sock_info->family, os_sock_info->type, os_sock_info->protocol);
260
(*apr_sock)->timeout = -1;
261
(*apr_sock)->socketdes = *os_sock_info->os_sock;
262
if (os_sock_info->local) {
263
memcpy(&(*apr_sock)->local_addr->sa.sin,
265
(*apr_sock)->local_addr->salen);
266
/* XXX IPv6 - this assumes sin_port and sin6_port at same offset */
267
(*apr_sock)->local_addr->port = ntohs((*apr_sock)->local_addr->sa.sin.sin_port);
270
(*apr_sock)->local_port_unknown = (*apr_sock)->local_interface_unknown = 1;
272
if (os_sock_info->remote) {
273
memcpy(&(*apr_sock)->remote_addr->sa.sin,
274
os_sock_info->remote,
275
(*apr_sock)->remote_addr->salen);
276
/* XXX IPv6 - this assumes sin_port and sin6_port at same offset */
277
(*apr_sock)->remote_addr->port = ntohs((*apr_sock)->remote_addr->sa.sin.sin_port);
280
(*apr_sock)->remote_addr_unknown = 1;
283
apr_pool_cleanup_register((*apr_sock)->pool, (void *)(*apr_sock),
284
socket_cleanup, apr_pool_cleanup_null);
289
APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock, apr_os_sock_t *thesock, apr_pool_t *cont)
294
if ((*sock) == NULL) {
295
alloc_socket(sock, cont);
296
set_socket_vars(*sock, AF_INET, SOCK_STREAM, 0);
297
(*sock)->timeout = -1;
300
(*sock)->local_port_unknown = (*sock)->local_interface_unknown = 1;
301
(*sock)->remote_addr_unknown = 1;
302
(*sock)->socketdes = *thesock;
306
APR_POOL_IMPLEMENT_ACCESSOR(socket);
308
APR_IMPLEMENT_INHERIT_SET(socket, inherit, pool, socket_cleanup)
310
APR_IMPLEMENT_INHERIT_UNSET(socket, inherit, pool, socket_cleanup)