~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr/test/testsock.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
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
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
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.
 
15
 */
 
16
 
 
17
#include "testutil.h"
 
18
#include "testsock.h"
 
19
#include "apr_thread_proc.h"
 
20
#include "apr_network_io.h"
 
21
#include "apr_errno.h"
 
22
#include "apr_general.h"
 
23
#include "apr_lib.h"
 
24
#include "apr_strings.h"
 
25
#include "apr_poll.h"
 
26
 
 
27
static void launch_child(abts_case *tc, apr_proc_t *proc, const char *arg1, apr_pool_t *p)
 
28
{
 
29
    apr_procattr_t *procattr;
 
30
    const char *args[3];
 
31
    apr_status_t rv;
 
32
 
 
33
    rv = apr_procattr_create(&procattr, p);
 
34
    APR_ASSERT_SUCCESS(tc, "Couldn't create procattr", rv);
 
35
 
 
36
    rv = apr_procattr_io_set(procattr, APR_NO_PIPE, APR_NO_PIPE,
 
37
            APR_NO_PIPE);
 
38
    APR_ASSERT_SUCCESS(tc, "Couldn't set io in procattr", rv);
 
39
 
 
40
    rv = apr_procattr_error_check_set(procattr, 1);
 
41
    APR_ASSERT_SUCCESS(tc, "Couldn't set error check in procattr", rv);
 
42
 
 
43
    args[0] = "sockchild" EXTENSION;
 
44
    args[1] = arg1;
 
45
    args[2] = NULL;
 
46
    rv = apr_proc_create(proc, "./sockchild" EXTENSION, args, NULL,
 
47
                         procattr, p);
 
48
    APR_ASSERT_SUCCESS(tc, "Couldn't launch program", rv);
 
49
}
 
50
 
 
51
static int wait_child(abts_case *tc, apr_proc_t *proc) 
 
52
{
 
53
    int exitcode;
 
54
    apr_exit_why_e why;
 
55
 
 
56
    ABTS_ASSERT(tc, "Error waiting for child process",
 
57
            apr_proc_wait(proc, &exitcode, &why, APR_WAIT) == APR_CHILD_DONE);
 
58
 
 
59
    ABTS_ASSERT(tc, "child terminated normally", why == APR_PROC_EXIT);
 
60
    return exitcode;
 
61
}
 
62
 
 
63
static void test_addr_info(abts_case *tc, void *data)
 
64
{
 
65
    apr_status_t rv;
 
66
    apr_sockaddr_t *sa;
 
67
 
 
68
    rv = apr_sockaddr_info_get(&sa, NULL, APR_UNSPEC, 80, 0, p);
 
69
    APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
 
70
 
 
71
    rv = apr_sockaddr_info_get(&sa, "127.0.0.1", APR_UNSPEC, 80, 0, p);
 
72
    APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
 
73
    ABTS_STR_EQUAL(tc, "127.0.0.1", sa->hostname);
 
74
}
 
75
 
 
76
static apr_socket_t *setup_socket(abts_case *tc)
 
77
{
 
78
    apr_status_t rv;
 
79
    apr_sockaddr_t *sa;
 
80
    apr_socket_t *sock;
 
81
 
 
82
    rv = apr_sockaddr_info_get(&sa, NULL, APR_INET, 8021, 0, p);
 
83
    APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
 
84
 
 
85
    rv = apr_socket_create(&sock, sa->family, SOCK_STREAM, APR_PROTO_TCP, p);
 
86
    APR_ASSERT_SUCCESS(tc, "Problem creating socket", rv);
 
87
 
 
88
    rv = apr_socket_opt_set(sock, APR_SO_REUSEADDR, 1);
 
89
    APR_ASSERT_SUCCESS(tc, "Could not set REUSEADDR on socket", rv);
 
90
    
 
91
    rv = apr_socket_bind(sock, sa);
 
92
    APR_ASSERT_SUCCESS(tc, "Problem binding to port", rv);
 
93
    if (rv) return NULL;
 
94
                
 
95
    rv = apr_socket_listen(sock, 5);
 
96
    APR_ASSERT_SUCCESS(tc, "Problem listening on socket", rv);
 
97
 
 
98
    return sock;
 
99
}
 
100
 
 
101
static void test_create_bind_listen(abts_case *tc, void *data)
 
102
{
 
103
    apr_status_t rv;
 
104
    apr_socket_t *sock = setup_socket(tc);
 
105
    
 
106
    if (!sock) return;
 
107
    
 
108
    rv = apr_socket_close(sock);
 
109
    APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
 
110
}
 
111
 
 
112
static void test_send(abts_case *tc, void *data)
 
113
{
 
114
    apr_status_t rv;
 
115
    apr_socket_t *sock;
 
116
    apr_socket_t *sock2;
 
117
    apr_proc_t proc;
 
118
    int protocol;
 
119
    apr_size_t length;
 
120
 
 
121
    sock = setup_socket(tc);
 
122
    if (!sock) return;
 
123
 
 
124
    launch_child(tc, &proc, "read", p);
 
125
    
 
126
    rv = apr_socket_accept(&sock2, sock, p);
 
127
    APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
 
128
 
 
129
    apr_socket_protocol_get(sock2, &protocol);
 
130
    ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
 
131
    
 
132
    length = strlen(DATASTR);
 
133
    apr_socket_send(sock2, DATASTR, &length);
 
134
 
 
135
    /* Make sure that the client received the data we sent */
 
136
    ABTS_INT_EQUAL(tc, strlen(DATASTR), wait_child(tc, &proc));
 
137
 
 
138
    rv = apr_socket_close(sock2);
 
139
    APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
 
140
    rv = apr_socket_close(sock);
 
141
    APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
 
142
}
 
143
 
 
144
static void test_recv(abts_case *tc, void *data)
 
145
{
 
146
    apr_status_t rv;
 
147
    apr_socket_t *sock;
 
148
    apr_socket_t *sock2;
 
149
    apr_proc_t proc;
 
150
    int protocol;
 
151
    apr_size_t length = STRLEN;
 
152
    char datastr[STRLEN];
 
153
    
 
154
    sock = setup_socket(tc);
 
155
    if (!sock) return;
 
156
 
 
157
    launch_child(tc, &proc, "write", p);
 
158
    
 
159
    rv = apr_socket_accept(&sock2, sock, p);
 
160
    APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
 
161
 
 
162
    apr_socket_protocol_get(sock2, &protocol);
 
163
    ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
 
164
    
 
165
    memset(datastr, 0, STRLEN);
 
166
    apr_socket_recv(sock2, datastr, &length);
 
167
 
 
168
    /* Make sure that the server received the data we sent */
 
169
    ABTS_STR_EQUAL(tc, DATASTR, datastr);
 
170
    ABTS_INT_EQUAL(tc, strlen(datastr), wait_child(tc, &proc));
 
171
 
 
172
    rv = apr_socket_close(sock2);
 
173
    APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
 
174
    rv = apr_socket_close(sock);
 
175
    APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
 
176
}
 
177
 
 
178
static void test_timeout(abts_case *tc, void *data)
 
179
{
 
180
    apr_status_t rv;
 
181
    apr_socket_t *sock;
 
182
    apr_socket_t *sock2;
 
183
    apr_proc_t proc;
 
184
    int protocol;
 
185
    int exit;
 
186
    
 
187
    sock = setup_socket(tc);
 
188
    if (!sock) return;
 
189
 
 
190
    launch_child(tc, &proc, "read", p);
 
191
    
 
192
    rv = apr_socket_accept(&sock2, sock, p);
 
193
    APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
 
194
 
 
195
    apr_socket_protocol_get(sock2, &protocol);
 
196
    ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
 
197
    
 
198
    exit = wait_child(tc, &proc);    
 
199
    ABTS_INT_EQUAL(tc, SOCKET_TIMEOUT, exit);
 
200
 
 
201
    /* We didn't write any data, so make sure the child program returns
 
202
     * an error.
 
203
     */
 
204
    rv = apr_socket_close(sock2);
 
205
    APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
 
206
    rv = apr_socket_close(sock);
 
207
    APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
 
208
}
 
209
 
 
210
static void test_get_addr(abts_case *tc, void *data)
 
211
{
 
212
    apr_status_t rv;
 
213
    apr_socket_t *ld, *sd, *cd;
 
214
    apr_sockaddr_t *sa, *ca;
 
215
    char a[128], b[128];
 
216
 
 
217
    ld = setup_socket(tc);
 
218
 
 
219
    APR_ASSERT_SUCCESS(tc,
 
220
                       "get local address of bound socket",
 
221
                       apr_socket_addr_get(&sa, APR_LOCAL, ld));
 
222
 
 
223
    rv = apr_socket_create(&cd, sa->family, SOCK_STREAM,
 
224
                           APR_PROTO_TCP, p);
 
225
    APR_ASSERT_SUCCESS(tc, "create client socket", rv);
 
226
 
 
227
    APR_ASSERT_SUCCESS(tc, "enable non-block mode",
 
228
                       apr_socket_opt_set(cd, APR_SO_NONBLOCK, 1));
 
229
 
 
230
    /* It is valid for a connect() on a socket with NONBLOCK set to
 
231
     * succeed (if the connection can be established synchronously),
 
232
     * but if it does, this test cannot proceed.  */
 
233
    rv = apr_socket_connect(cd, sa);
 
234
    if (!APR_STATUS_IS_EINPROGRESS(rv)) {
 
235
        apr_socket_close(ld);
 
236
        apr_socket_close(cd);
 
237
        APR_ASSERT_SUCCESS(tc, "connect to listener", rv);
 
238
        ABTS_NOT_IMPL(tc, "Cannot test if connect completes "
 
239
                      "synchronously");
 
240
        return;
 
241
    }
 
242
 
 
243
    APR_ASSERT_SUCCESS(tc, "accept connection",
 
244
                       apr_socket_accept(&sd, ld, p));
 
245
    
 
246
    {
 
247
        /* wait for writability */
 
248
        apr_pollfd_t pfd;
 
249
        int n;
 
250
 
 
251
        pfd.p = p;
 
252
        pfd.desc_type = APR_POLL_SOCKET;
 
253
        pfd.reqevents = APR_POLLOUT|APR_POLLHUP;
 
254
        pfd.desc.s = cd;
 
255
        pfd.client_data = NULL;
 
256
 
 
257
        APR_ASSERT_SUCCESS(tc, "poll for connect completion",
 
258
                           apr_poll(&pfd, 1, &n, 5 * APR_USEC_PER_SEC));
 
259
 
 
260
    }
 
261
 
 
262
    APR_ASSERT_SUCCESS(tc, "get local address of server socket",
 
263
                       apr_socket_addr_get(&sa, APR_LOCAL, sd));
 
264
 
 
265
    APR_ASSERT_SUCCESS(tc, "get remote address of client socket",
 
266
                       apr_socket_addr_get(&ca, APR_REMOTE, cd));
 
267
    
 
268
    apr_snprintf(a, sizeof(a), "%pI", sa);
 
269
    apr_snprintf(b, sizeof(b), "%pI", ca);
 
270
 
 
271
    ABTS_STR_EQUAL(tc, a, b);
 
272
                       
 
273
    apr_socket_close(cd);
 
274
    apr_socket_close(sd);
 
275
    apr_socket_close(ld);
 
276
}
 
277
 
 
278
abts_suite *testsock(abts_suite *suite)
 
279
{
 
280
    suite = ADD_SUITE(suite)
 
281
 
 
282
    abts_run_test(suite, test_addr_info, NULL);
 
283
    abts_run_test(suite, test_create_bind_listen, NULL);
 
284
    abts_run_test(suite, test_send, NULL);
 
285
    abts_run_test(suite, test_recv, NULL);
 
286
    abts_run_test(suite, test_timeout, NULL);
 
287
    abts_run_test(suite, test_get_addr, NULL);
 
288
 
 
289
    return suite;
 
290
}
 
291