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