1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sal.hxx"
30 
31 /**  test coder preface:
32 	1. the BSD socket function will meet "unresolved external symbol error" on Windows platform
33 	if you are not including ws2_32.lib in makefile.mk,  the including format will be like this:
34 
35 	.IF "$(GUI)" == "WNT"
36 	SHL1STDLIBS +=	$(SOLARLIBDIR)$/cppunit.lib
37 	SHL1STDLIBS +=  ws2_32.lib
38 	.ENDIF
39 
40 	likewise on Solaris platform.
41 	.IF "$(GUI)" == "UNX"
42 	SHL1STDLIBS+=$(SOLARLIBDIR)$/libcppunit$(DLLPOSTFIX).a
43 	SHL1STDLIBS += -lsocket -ldl -lnsl
44 	.ENDIF
45 
46 	2. since the Socket implementation of osl is only IPv4 oriented, our test are mainly focus on IPv4
47 	category.
48 
49 	3. some fragment of Socket source implementation are lack of comment so it is hard for testers
50 	guess what the exact functionality or usage of a member.  Hope the Socket section's comment
51 	will be added.
52 
53 	4. following functions are declared but not implemented:
54 	inline sal_Bool SAL_CALL operator== (const SocketAddr & Addr) const;
55  */
56 
57 //------------------------------------------------------------------------
58 // include files
59 //------------------------------------------------------------------------
60 
61 #include <testshl/simpleheader.hxx>
62 
63 #include "osl_Socket_Const.h"
64 #include "sockethelper.hxx"
65 
66 using namespace osl;
67 using namespace rtl;
68 
69 #define IP_PORT_FTP     21
70 #define IP_PORT_MYPORT9 8897
71 #define IP_PORT_MYPORT4 8885
72 #define IP_PORT_MYPORT3 8884
73 
74 //------------------------------------------------------------------------
75 // helper functions
76 //------------------------------------------------------------------------
77 
78 // just used to test socket::close() when accepting
79 class AcceptorThread : public Thread
80 {
81 	::osl::AcceptorSocket asAcceptorSocket;
82 	::rtl::OUString aHostIP;
83 	sal_Bool bOK;
84 protected:
85 	void SAL_CALL run( )
86 	{
87 		::osl::SocketAddr saLocalSocketAddr( aHostIP, IP_PORT_MYPORT9 );
88 		::osl::StreamSocket ssStreamConnection;
89 
90 		asAcceptorSocket.setOption( osl_Socket_OptionReuseAddr, 1 ); //integer not sal_Bool : sal_True);
91 		sal_Bool bOK1 = asAcceptorSocket.bind( saLocalSocketAddr );
92 		if  ( sal_True != bOK1 )
93 		{
94 			t_print("# AcceptorSocket bind address failed.\n" ) ;
95 			return;
96 		}
97 		sal_Bool bOK2 = asAcceptorSocket.listen( 1 );
98 		if  ( sal_True != bOK2 )
99 		{
100 			t_print("# AcceptorSocket listen address failed.\n" ) ;
101 			return;
102 		}
103 
104 		asAcceptorSocket.enableNonBlockingMode( sal_False );
105 
106 		oslSocketResult eResult = asAcceptorSocket.acceptConnection( ssStreamConnection );
107 		if (eResult != osl_Socket_Ok )
108 		{
109 			bOK = sal_True;
110 			t_print("AcceptorThread: acceptConnection failed! \n");
111 		}
112 	}
113 public:
114 	AcceptorThread(::osl::AcceptorSocket & asSocket, ::rtl::OUString const& aBindIP )
115 		: asAcceptorSocket( asSocket ), aHostIP( aBindIP )
116 	{
117 		bOK = sal_False;
118 	}
119 
120 	sal_Bool isOK() { return bOK; }
121 
122 	~AcceptorThread( )
123 	{
124 		if ( isRunning( ) )
125 		{
126 			asAcceptorSocket.shutdown();
127 			t_print("# error: Acceptor thread not terminated.\n" );
128 		}
129 	}
130 };
131 
132 namespace osl_AcceptorSocket
133 {
134 
135 	/** testing the methods:
136 		inline AcceptorSocket(oslAddrFamily Family = osl_Socket_FamilyInet,
137 							  oslProtocol	Protocol = osl_Socket_ProtocolIp,
138 							  oslSocketType	Type = osl_Socket_TypeStream);
139 	*/
140 
141 	class ctors : public CppUnit::TestFixture
142 	{
143 	public:
144 
145 		void ctors_001()
146 		{
147 			/// Socket constructor.
148 			::osl::AcceptorSocket asSocket( osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream );
149 
150 			CPPUNIT_ASSERT_MESSAGE( "test for ctors_001 constructor function: check if the acceptor socket was created successfully.",
151 									osl_Socket_TypeStream ==  asSocket.getType( ) );
152 		}
153 
154 		CPPUNIT_TEST_SUITE( ctors );
155 		CPPUNIT_TEST( ctors_001 );
156 		CPPUNIT_TEST_SUITE_END();
157 
158 	}; // class ctors
159 
160 #if 0  /* OBSOLETE */
161 	class operator_assign : public CppUnit::TestFixture
162 	{
163 	public:
164 
165 		void assign_001()
166 		{
167 #if defined(LINUX)
168 			::osl::AcceptorSocket asSocket( osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream );
169 			::osl::AcceptorSocket asSocketAssign( osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream );
170 			asSocket.setOption( osl_Socket_OptionReuseAddr, 1);
171 			::osl::SocketAddr saSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT4 );
172 			asSocket.bind( saSocketAddr );
173 
174 			AcceptorThread myAcceptorThread( asSocketAssign, rtl::OUString::createFromAscii("127.0.0.1") );
175 			myAcceptorThread.create();
176 
177 			thread_sleep( 1 );
178 			//when accepting, assign another socket to the socket, the thread will not be closed, so is blocking
179 			asSocketAssign = asSocket;
180 
181 			t_print("#asSocketAssign port number is %d\n", asSocketAssign.getLocalPort() );
182 
183 			asSocketAssign.shutdown();
184 			myAcceptorThread.join();
185 
186 			CPPUNIT_ASSERT_MESSAGE( "test for close when is accepting: the socket will quit accepting status.",
187 								myAcceptorThread.isOK()	== sal_True );
188 
189 
190 #endif /* LINUX */
191 		}
192 
193 
194 		CPPUNIT_TEST_SUITE( operator_assign  );
195 		CPPUNIT_TEST( assign_001 );
196 		CPPUNIT_TEST_SUITE_END();
197 
198 	}; // class operator_assign
199 #endif /* OBSOLETE */
200 
201 	/** testing the method:
202 		inline sal_Bool SAL_CALL listen(sal_Int32 MaxPendingConnections= -1);
203 		inline oslSocketResult SAL_CALL acceptConnection( StreamSocket& Connection);
204 		inline oslSocketResult SAL_CALL acceptConnection( StreamSocket&	Connection, SocketAddr & PeerAddr);
205 	*/
206 
207 	class listen_accept : public CppUnit::TestFixture
208 	{
209 	public:
210 		TimeValue *pTimeout;
211 		::osl::AcceptorSocket asAcceptorSocket;
212 		::osl::ConnectorSocket csConnectorSocket;
213 
214 
215 		// initialization
216 		void setUp( )
217 		{
218 			pTimeout  = ( TimeValue* )malloc( sizeof( TimeValue ) );
219 			pTimeout->Seconds = 3;
220 			pTimeout->Nanosec = 0;
221 			asAcceptorSocket.setOption( osl_Socket_OptionReuseAddr, 1);
222 		//	sHandle = osl_createSocket( osl_Socket_FamilyInet, osl_Socket_TypeStream, osl_Socket_ProtocolIp );
223 		}
224 
225 		void tearDown( )
226 		{
227 			free( pTimeout );
228 		//	sHandle = NULL;
229 			asAcceptorSocket.close( );
230 			csConnectorSocket.close( );
231 		}
232 
233 
234 		void listen_accept_001()
235 		{
236 			::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT3 );
237 			::osl::SocketAddr saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT3 );
238 			::osl::StreamSocket ssConnection;
239 
240 			/// launch server socket
241 			sal_Bool bOK1 = asAcceptorSocket.bind( saLocalSocketAddr );
242 			CPPUNIT_ASSERT_MESSAGE( "AcceptorSocket bind address failed.", sal_True == bOK1 );
243 			sal_Bool bOK2 = asAcceptorSocket.listen( 1 );
244 			CPPUNIT_ASSERT_MESSAGE( "AcceptorSocket listen failed.",  sal_True == bOK2 );
245 			asAcceptorSocket.enableNonBlockingMode( sal_True );
246 
247 			/// launch client socket
248 			csConnectorSocket.connect( saTargetSocketAddr, pTimeout );   /// connecting to server...
249 
250 			oslSocketResult eResult = asAcceptorSocket.acceptConnection(ssConnection); /// waiting for incoming connection...
251 
252 			CPPUNIT_ASSERT_MESSAGE( "test for listen_accept function: try to create a connection with remote host, using listen and accept.",
253 				( osl_Socket_Ok == eResult ) );
254 		}
255 
256 		void listen_accept_002()
257 		{
258 			::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT4 );
259 			::osl::SocketAddr saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT4 );
260 			::osl::SocketAddr saPeerSocketAddr( rtl::OUString::createFromAscii("129.158.217.202"), IP_PORT_FTP );
261 			::osl::StreamSocket ssConnection;
262 
263 			/// launch server socket
264 			sal_Bool bOK1 = asAcceptorSocket.bind( saLocalSocketAddr );
265 			CPPUNIT_ASSERT_MESSAGE( "AcceptorSocket bind address failed.", sal_True == bOK1 );
266 			sal_Bool bOK2 = asAcceptorSocket.listen( 1 );
267 			CPPUNIT_ASSERT_MESSAGE( "AcceptorSocket listen failed.",  sal_True == bOK2 );
268 			asAcceptorSocket.enableNonBlockingMode( sal_True );
269 
270 			/// launch client socket
271 			csConnectorSocket.connect( saTargetSocketAddr, pTimeout );   /// connecting to server...
272 
273 			oslSocketResult eResult = asAcceptorSocket.acceptConnection(ssConnection, saPeerSocketAddr); /// waiting for incoming connection...
274 
275 			CPPUNIT_ASSERT_MESSAGE( "test for listen_accept function: try to create a connection with remote host, using listen and accept, accept with peer address.",
276 									( sal_True == bOK2 ) &&
277 									( osl_Socket_Ok == eResult ) &&
278 									( sal_True == compareSocketAddr( saPeerSocketAddr, saLocalSocketAddr ) ) );
279 		}
280 
281 
282 		CPPUNIT_TEST_SUITE( listen_accept );
283 		CPPUNIT_TEST( listen_accept_001 );
284 		CPPUNIT_TEST( listen_accept_002 );
285 		CPPUNIT_TEST_SUITE_END();
286 
287 	}; // class listen_accept
288 
289 
290 // -----------------------------------------------------------------------------
291 
292 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_AcceptorSocket::ctors, "osl_AcceptorSocket");
293 //CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_AcceptorSocket::operator_assign, "osl_AcceptorSocket");
294 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_AcceptorSocket::listen_accept, "osl_AcceptorSocket");
295 
296 } // namespace osl_AcceptorSocket
297 
298 // -----------------------------------------------------------------------------
299 
300 // this macro creates an empty function, which will called by the RegisterAllFunctions()
301 // to let the user the possibility to also register some functions by hand.
302 NOADDITIONAL;
303