2 // *WARRANTY DISCLAIMER: LIMITATION OF LIABILITY. THE SOFTWARE AND
3 // CONTENT ARE PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED
4 // REPRESENTATIONS, GUARANTEES, OR WARRANTIES, INCLUDING BUT NOT LIMITED
5 // TO SUCH REPRESENTATION, GUARANTEES OR WARRANTIES REGARDING THE
6 // USABILITY, SUITABILITY, CONDITION, OPERATION OR ACCURACY THEREOF. *
8 // *ALL OTHER WARRANTIES AND CONDITIONS (EXPRESS, IMPLIED OR STATUTORY)
9 // ARE HEREBY DISCLAIMED, SUCH WARRANTIES AND CONDITIONS INCLUDING
10 // WITHOUT LIMITATION, ALL WARRANTIES AND CONDITIONS OF MERCHANTABILITY,
11 // TITLE, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT,
12 // COMPATIBILITY, AND SECURITY OR ACCURACY.*
14 // ============================================================================
20 // SOCK_SEQPACK_SCTP_Test.cpp
23 // Performs several tests on the ACE_SOCK_SEQPACK_Connector,
24 // ACE_SOCK_SEQPACK_Acceptor, and ACE_SOCK_SEQPACK_Association classes
25 // specifically for SCTP using the loopback interface. Attempts to
26 // replicate behavior of SOCK_Test.cpp, but integrating IPv6 tests
30 // Dave Craig <dwc@qualcomm.com>
33 #include "test_config.h"
34 #include "ace/OS_NS_unistd.h"
35 #include "ace/OS_NS_sys_select.h"
36 #include "ace/OS_NS_sys_wait.h"
37 #include "ace/SOCK_SEQPACK_Connector.h"
38 #include "ace/SOCK_SEQPACK_Acceptor.h"
39 #include "ace/Thread_Manager.h"
40 #include "ace/Handle_Set.h"
43 #define BYTE_MESG 0xcd
46 ACE_Thread_Semaphore
*tsemap
;
50 using tdesc_t
= struct tdesc
;
53 // This arg is ignored on Windows and causes pointer truncation
54 // warnings on 64-bit compiled.
55 #define SELECT_WIDTH(x) 0
57 #define SELECT_WIDTH(x) (x)
63 ACE_SOCK_SEQPACK_Acceptor
*AcceptorSocket
=
64 reinterpret_cast<ACE_SOCK_SEQPACK_Acceptor
*> (arg
);
66 ACE_SOCK_SEQPACK_Association Stream
;
68 ACE_Handle_Set handle_set
;
70 const ACE_Time_Value
def_timeout (ACE_DEFAULT_TIMEOUT
);
72 ACE_Time_Value
tv (def_timeout
);
79 // Make sure AcceptorSocket is in nonblocking mode so as not to
82 if (-1 == AcceptorSocket
->enable (ACE_NONBLOCK
))
84 ACE_TEXT ("(%P|%t) %p\n"),
85 ACE_TEXT ("AcceptorSocket.enable (ACE_NONBLOCK)")));
88 // Set up select to wait for I/O events.
91 handle_set
.set_bit (AcceptorSocket
->get_handle ());
93 select_width
= SELECT_WIDTH(int (AcceptorSocket
->get_handle ()) + 1);
95 result
= ACE_OS::select(select_width
,
102 ACE_ERROR_RETURN ((LM_ERROR
,
103 ACE_TEXT ("(%P|%t) %p\n"),
104 ACE_TEXT ("select")),
107 ACE_ERROR_RETURN ((LM_ERROR
,
108 ACE_TEXT("(%P|%t) select timed out, shutting down\n")),
111 ACE_DEBUG ((LM_DEBUG
,
112 ACE_TEXT ("(%P|%t) waiting for client to connect\n")));
114 while (-1 != AcceptorSocket
->accept (Stream
)) {
115 ACE_DEBUG ((LM_DEBUG
,
116 ACE_TEXT ("(%P|%t) client connected\n")));
119 // Enable non-blocking I/O.
121 if (Stream
.enable (ACE_NONBLOCK
))
122 ACE_ERROR_RETURN ((LM_ERROR
,
123 ACE_TEXT ("(%P|%t) %p\n"),
124 ACE_TEXT ("Stream.enable (ACE_NONBLOCK)")),
127 unsigned char byte
= BYTE_MESG
;
129 if (-1 == Stream
.send_n (&byte
, 1))
130 ACE_ERROR ((LM_ERROR
,
131 ACE_TEXT ("(%P|%t) %p\n"),
132 ACE_TEXT ("Stream.send_n")));
134 ACE_DEBUG ((LM_DEBUG
,
135 ACE_TEXT ("(%P|%t) byte sent\n")));
138 // Abruptly terminate the association.
140 if (-1 == Stream
.abort ())
141 ACE_ERROR ((LM_ERROR
,
142 ACE_TEXT ("(%P|%t) %p\n"),
143 ACE_TEXT ("Association.abort")));
146 // Negative test: make sure that we cannot send on a closed association.
148 if (-1 != Stream
.send_n (&byte
, 1))
149 //FUZZ: disable check_for_lack_ACE_OS
150 ACE_ERROR ((LM_ERROR
,
151 ACE_TEXT ("(%P|%t) Negative test fail: Association")
152 ACE_TEXT(".send_n succeeded after abort()\n")));
153 //FUZZ: enable check_for_lack_ACE_OS
158 // Close server socket.
160 if (-1 == AcceptorSocket
->close ())
161 ACE_ERROR ((LM_ERROR
,
162 ACE_TEXT ("(%P|%t) %p\n"),
163 ACE_TEXT ("AcceptorSocket.close")));
171 ACE_Multihomed_INET_Addr
*ServerAddr
=
172 reinterpret_cast<ACE_Multihomed_INET_Addr
*> (arg
);
174 ACE_SOCK_SEQPACK_Connector Connector
;
176 ACE_SOCK_SEQPACK_Association Stream
;
178 ACE_Time_Value
tv (ACE_DEFAULT_TIMEOUT
);
183 if (-1 == Connector
.connect (Stream
,
189 ACE_ERROR_RETURN ((LM_ERROR
,
190 ACE_TEXT ("(%P|%t) %p to %s:%d\n"),
191 ACE_TEXT ("Connector.connect"),
192 ServerAddr
->get_host_name (),
193 ServerAddr
->get_port_number ()),
197 if (-1 == Stream
.disable (ACE_NONBLOCK
))
199 ACE_ERROR ((LM_ERROR
,
200 ACE_TEXT ("(%P|%t) %p\n"),
201 ACE_TEXT ("Association.disable (ACE_NONBLOCK)")));
205 if (-1 == Stream
.recv_n (&b
, 1, &tv
, &bytes
))
207 ACE_ERROR ((LM_ERROR
,
208 ACE_TEXT ("(%P|%t) %p\n"),
209 ACE_TEXT ("Association.recv_n")));
213 ACE_DEBUG ((LM_DEBUG
,
214 ACE_TEXT ("(%P|%t) Client received %B bytes\n"),
217 ACE_ERROR ((LM_ERROR
,
218 ACE_TEXT ("(%P|%t) Client received %B bytes; expected 1\n"),
222 // Give server a little time to abort the association.
226 // abort closes the connection, so the recv should either see a closed
227 // socket or some failure other than a timeout.
228 ssize_t cnt
= Stream
.recv_n (&b
, 1, &tv
, &bytes
);
229 if (cnt
> 0 || (cnt
== -1 && errno
== ETIME
))
230 ACE_ERROR ((LM_ERROR
,
231 ACE_TEXT ("(%P|%t) Negative test failed; Association")
232 ACE_TEXT (".recv_n returned %b (w/ %m) after abort\n"),
239 // Spawn server and client threads and then wait until they complete the
240 // test. There must be a timeout on the wait, so executable does not hang the
241 // tests indefinitely.
244 spawn_test(bool ipv6_test
)
246 ACE_DEBUG ((LM_DEBUG
,
247 ACE_TEXT ("(%P|%t) spawn_test started ipv6 %d\n"),
250 ACE_SOCK_SEQPACK_Acceptor AcceptorSocket
;
252 const ACE_TCHAR
*addrstr
=
254 ipv6_test
? ACE_IPV6_LOCALHOST
: ACE_LOCALHOST
;
257 #endif /* ACE_HAS_IPV6 */
258 ACE_Multihomed_INET_Addr
ServerAddr (TTCPPORT
,
262 ipv6_test
? AF_INET6
: AF_INET
263 #endif /* ACE_HAS_IPV6 */
266 if (-1 == AcceptorSocket
.open (ServerAddr
, 1))
268 ACE_ERROR ((LM_ERROR
,
269 ACE_TEXT ("(%P|%t) %p\n"),
270 ACE_TEXT ("AcceptorSocket.open")));
273 if (-1 == AcceptorSocket
.get_local_addr (ServerAddr
))
275 ACE_ERROR ((LM_ERROR
,
276 ACE_TEXT ("(%P|%t) %p\n"),
277 ACE_TEXT ("AcceptorSocket.get_local_addr")));
280 #ifndef ACE_LACKS_FORK
281 switch (ACE_OS::fork (ACE_TEXT ("child")))
284 ACE_ERROR ((LM_ERROR
,
285 ACE_TEXT ("(%P|%t) %p"),
286 ACE_TEXT ("fork failed")));
289 ACE_LOG_MSG
->sync (ACE_TEXT ("SOCK_SEQPACK_SCTP_Test"));
290 Client (&ServerAddr
);
294 Server (reinterpret_cast<void *> (&AcceptorSocket
));
298 #elif defined (ACE_HAS_THREADS)
299 if (-1 == ACE_Thread_Manager::instance ()->spawn
301 reinterpret_cast<void *> (&AcceptorSocket
),
302 THR_NEW_LWP
| THR_DETACHED
))
304 ACE_ERROR ((LM_ERROR
,
305 ACE_TEXT ("(%P|%t) %p%a"),
306 ACE_TEXT ("thread create failed")));
309 if (-1 == ACE_Thread_Manager::instance ()->spawn
311 reinterpret_cast<void *> (&ServerAddr
),
312 THR_NEW_LWP
| THR_DETACHED
))
314 ACE_ERROR ((LM_ERROR
,
315 ACE_TEXT ("(%P|%t) %p%a"),
316 ACE_TEXT ("thread create failed")));
319 ACE_Thread_Manager::instance ()->wait ();
320 #else /* ACE_LACKS_FORK && ! ACE_HAS_THREADS */
321 ACE_ERROR ((LM_DEBUG
,
322 ACE_TEXT ("(%P|%t)\n"),
323 ACE_TEXT ("only one thread may be run ")
324 ACE_TEXT ("in a process on this platform\n")));
325 #endif /* ACE_LACKS_FORK && ! ACE_HAS_THREADS */
342 int run_main (int, ACE_TCHAR
*[])
344 ACE_START_TEST (ACE_TEXT ("SOCK_SEQPACK_SCTP_Test"));
347 // Check whether host OS has SCTP support before starting this test.
348 // If not, just pass because there is not a hope of testing
355 #else /* ! ACE_HAS_SCTP */
356 ACE_DEBUG ((LM_DEBUG
,
357 ACE_TEXT("SCTP not supported by ACE.\n")
358 ACE_TEXT("This test will not do anything.\n")));
359 #endif /* ! ACE_HAS_SCTP */