2 * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
28 #include <isc/socket.h>
30 #include "../task_p.h"
42 completion_init(completion_t *completion) {
43 completion->done = ISC_FALSE;
47 event_done(isc_task_t *task, isc_event_t *event) {
48 isc_socketevent_t *dev;
49 completion_t *completion = event->ev_arg;
53 dev = (isc_socketevent_t *) event;
54 completion->result = dev->result;
55 completion->done = ISC_TRUE;
56 isc_event_free(&event);
60 waitfor(completion_t *completion) {
62 while (!completion->done && i++ < 5000) {
63 #ifndef ISC_PLATFORM_USETHREADS
64 while (isc__taskmgr_ready(taskmgr))
65 isc__taskmgr_dispatch(taskmgr);
70 return (ISC_R_SUCCESS);
71 return (ISC_R_FAILURE);
75 * Individual unit tests
78 /* Test UDP sendto/recv (IPv4) */
80 ATF_TC_HEAD(udp_sendto, tc) {
81 atf_tc_set_md_var(tc, "descr", "UDP sendto/recv");
83 ATF_TC_BODY(udp_sendto, tc) {
85 isc_sockaddr_t addr1, addr2;
87 isc_socket_t *s1 = NULL, *s2 = NULL;
88 isc_task_t *task = NULL;
89 char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
90 completion_t completion;
95 result = isc_test_begin(NULL, ISC_TRUE);
96 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
99 * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to
102 in.s_addr = inet_addr("127.0.0.1");
103 isc_sockaddr_fromin(&addr1, &in, 5444);
104 isc_sockaddr_fromin(&addr2, &in, 5445);
106 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
107 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
108 result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
109 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
111 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
112 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
113 result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
114 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
116 result = isc_task_create(taskmgr, 0, &task);
117 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
119 strcpy(sendbuf, "Hello");
120 r.base = (void *) sendbuf;
121 r.length = strlen(sendbuf) + 1;
123 completion_init(&completion);
124 result = isc_socket_sendto(s1, &r, task, event_done, &completion,
126 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
127 waitfor(&completion);
128 ATF_CHECK(completion.done);
129 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
131 r.base = (void *) recvbuf;
133 completion_init(&completion);
134 result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
135 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
136 waitfor(&completion);
137 ATF_CHECK(completion.done);
138 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
139 ATF_CHECK_STREQ(recvbuf, "Hello");
141 isc_task_detach(&task);
143 isc_socket_detach(&s1);
144 isc_socket_detach(&s2);
149 /* Test UDP sendto/recv with duplicated socket */
151 ATF_TC_HEAD(udp_dup, tc) {
152 atf_tc_set_md_var(tc, "descr", "duplicated socket sendto/recv");
154 ATF_TC_BODY(udp_dup, tc) {
156 isc_sockaddr_t addr1, addr2;
158 isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
159 isc_task_t *task = NULL;
160 char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
161 completion_t completion;
166 result = isc_test_begin(NULL, ISC_TRUE);
167 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
170 * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to
173 in.s_addr = inet_addr("127.0.0.1");
174 isc_sockaddr_fromin(&addr1, &in, 5444);
175 isc_sockaddr_fromin(&addr2, &in, 5445);
177 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
178 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
179 result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
180 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
182 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
183 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
184 result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
185 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
187 result = isc_socket_dup(s2, &s3);
188 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
190 result = isc_task_create(taskmgr, 0, &task);
191 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
193 strcpy(sendbuf, "Hello");
194 r.base = (void *) sendbuf;
195 r.length = strlen(sendbuf) + 1;
197 completion_init(&completion);
198 result = isc_socket_sendto(s1, &r, task, event_done, &completion,
200 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
201 waitfor(&completion);
202 ATF_CHECK(completion.done);
203 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
205 strcpy(sendbuf, "World");
206 r.base = (void *) sendbuf;
207 r.length = strlen(sendbuf) + 1;
209 completion_init(&completion);
210 result = isc_socket_sendto(s1, &r, task, event_done, &completion,
212 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
213 waitfor(&completion);
214 ATF_CHECK(completion.done);
215 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
217 r.base = (void *) recvbuf;
219 completion_init(&completion);
220 result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
221 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
222 waitfor(&completion);
223 ATF_CHECK(completion.done);
224 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
225 ATF_CHECK_STREQ(recvbuf, "Hello");
227 r.base = (void *) recvbuf;
229 completion_init(&completion);
230 result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
231 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
232 waitfor(&completion);
233 ATF_CHECK(completion.done);
234 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
235 ATF_CHECK_STREQ(recvbuf, "World");
237 isc_task_detach(&task);
239 isc_socket_detach(&s1);
240 isc_socket_detach(&s2);
241 isc_socket_detach(&s3);
250 ATF_TP_ADD_TC(tp, udp_sendto);
251 ATF_TP_ADD_TC(tp, udp_dup);
253 return (atf_no_error());