4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 //#include "TCPSocketHandle.test.hh"
26 //#include "TCPSocketHandle.test.ih"
29 #include <sys/types.h>
30 #include <sys/ioctl.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include "TCPSocketHandle.hh"
38 #include <boost/test/auto_unit_test.hpp>
39 #include <boost/test/test_tools.hpp>
42 ///////////////////////////////cc.p////////////////////////////////////////
46 void error(char const * fn, char const * proc="")
48 std::cerr << "\n" << proc << ((*proc)?": ":"") << fn << ": " << strerror(errno) << std::endl;
51 void fail(char const * proc, char const * fn)
59 void start(void (*fn)())
61 server_pid = ::fork();
62 if (server_pid < 0) BOOST_FAIL("fork()");
63 if (server_pid == 0) {
72 if (waitpid(server_pid,&status,0)<0)
73 BOOST_FAIL("waitpid()");
74 BOOST_CHECK_EQUAL( status , 0 );
88 ///////////////////////////////////////////////////////////////////////////
94 int serv = socket(PF_INET,SOCK_STREAM,0);
95 if (serv<0) fail("server_v4","socket()");
97 if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
98 fail("server_v4","setsockopt()");
99 struct sockaddr_in sin;
100 ::memset(&sin,0,sizeof(sin));
101 sin.sin_family = AF_INET;
102 sin.sin_port = htons(12345);
103 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
104 if (bind(serv,(struct sockaddr *)&sin,sizeof(sin))<0) fail("server_v4","bind()");
105 if (listen(serv,1)<0) fail("server_v4","listen()");
106 int sock = accept(serv,0,0);
107 if (sock < 0) fail("server_v4","accept()");
111 int n = read(sock,buffer,1024);
112 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
114 write(sock,buffer,n);
117 if (shutdown(sock, SHUT_RDWR) < 0) fail("server_v4","shutdown()");
118 if (close(sock) < 0) fail("server_v4","close()");
119 if (close(serv) < 0) fail("server_v4","close()");
124 int serv = socket(PF_INET6,SOCK_STREAM,0);
125 if (serv<0) fail("server_v6","socket()");
127 if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
128 fail("server_v6","setsockopt()");
129 struct sockaddr_in6 sin;
130 ::memset(&sin,0,sizeof(sin));
131 sin.sin6_family = AF_INET6;
132 sin.sin6_port = htons(12345);
133 sin.sin6_addr = in6addr_loopback;
134 if (bind(serv,(struct sockaddr *)&sin,sizeof(sin))<0) fail("server_v6","bind()");
135 if (listen(serv,1)<0) fail("server_v6","listen()");
136 int sock = accept(serv,0,0);
137 if (sock < 0) fail("server_v6","accept()");
141 int n = read(sock,buffer,1024);
142 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
144 write(sock,buffer,n);
147 if (shutdown(sock, SHUT_RDWR) < 0) fail("server_v6","shutdown()");
148 if (close(sock) < 0) fail("server_v6","close()");
149 if (close(serv) < 0) fail("server_v6","close()");
154 BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle)
157 senf::TCPv4ClientSocketHandle sock;
159 BOOST_CHECK_THROW( sock.connect(senf::INet4SocketAddress("127.0.0.1:12345")),
160 senf::SystemException );
161 BOOST_CHECK_THROW( sock.protocol().connect(senf::INet4SocketAddress("127.0.0.1:12345")),
162 senf::SystemException );
168 senf::TCPv4ClientSocketHandle sock;
169 BOOST_CHECK_NO_THROW( sock.bind(senf::INet4SocketAddress("127.0.0.1:23456")) );
170 BOOST_CHECK_NO_THROW( sock.connect(senf::INet4SocketAddress("127.0.0.1:12345")) );
171 BOOST_CHECK( sock.peer() == senf::INet4SocketAddress("127.0.0.1:12345") );
172 BOOST_CHECK( sock.local() == senf::INet4SocketAddress("127.0.0.1:23456") );
173 BOOST_CHECK( sock.blocking() );
174 BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
175 BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
176 BOOST_CHECK_NO_THROW( sock.sndbuf(2048) );
177 BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
178 BOOST_CHECK_NO_THROW( sock.write("TEST-WRITE") );
179 BOOST_CHECK_EQUAL( sock.read(), "TEST-WRITE" );
180 BOOST_CHECK( !sock.eof() );
185 BOOST_CHECK_EQUAL( sock.read(), "" );
186 BOOST_CHECK( sock.eof() );
187 BOOST_CHECK( !sock );
198 senf::TCPv4ClientSocketHandle sock;
200 // Since this is a TCP socket, most of the calls will fail or
201 // are at least not sensible ...
202 // I'll have to move those to a UDPSocket test ... they should
203 // realy only be in the UDP Protocol implementation
204 // BOOST_CHECK_NO_THROW( sock.protocol().mcTTL() );
205 // BOOST_CHECK_THROW( sock.protocol().mcTTL(1), senf::SystemException );
206 // BOOST_CHECK_NO_THROW( sock.protocol().mcLoop() );
207 // BOOST_CHECK_NO_THROW( sock.protocol().mcLoop(false) );
208 // BOOST_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0") );
209 // BOOST_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0","127.0.0.1:0") );
210 // BOOST_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0","127.0.0.1:0") );
211 // BOOST_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0") );
212 // BOOST_CHECK_THROW( sock.protocol().mcIface("lo"), senf::SystemException );
214 // The following setsockopts are hard to REALLY test ...
215 BOOST_CHECK_NO_THROW( sock.protocol().nodelay(true) );
216 BOOST_CHECK( sock.protocol().nodelay() );
217 BOOST_CHECK_EQUAL( sock.protocol().siocinq(), 0u );
218 BOOST_CHECK_EQUAL( sock.protocol().siocoutq(), 0u );
220 BOOST_CHECK_NO_THROW( sock.protocol().reuseaddr(true) );
221 BOOST_CHECK( sock.protocol().reuseaddr() );
222 BOOST_CHECK_NO_THROW( sock.protocol().linger(true,0) );
223 BOOST_CHECK( sock.protocol().linger() == std::make_pair(true, 0u) );
227 BOOST_AUTO_UNIT_TEST(tcpv6ClientSocketHandle)
230 senf::TCPv6ClientSocketHandle sock;
232 BOOST_CHECK_THROW( sock.connect(senf::INet6SocketAddress("[::1]:12345")),
233 senf::SystemException );
239 senf::TCPv6ClientSocketHandle sock;
240 BOOST_CHECK_NO_THROW( sock.bind(senf::INet6SocketAddress("[::1]:23456")) );
241 BOOST_CHECK_NO_THROW( sock.connect(senf::INet6SocketAddress("[::1]:12345")) );
242 BOOST_CHECK( sock.peer() == senf::INet6SocketAddress("[::1]:12345") );
243 BOOST_CHECK( sock.local() == senf::INet6SocketAddress("[::1]:23456") );
244 BOOST_CHECK( sock.blocking() );
245 BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
246 BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
247 BOOST_CHECK_NO_THROW( sock.sndbuf(2048) );
248 BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
249 BOOST_CHECK_NO_THROW( sock.write("TEST-WRITE") );
250 BOOST_CHECK_EQUAL( sock.read(), "TEST-WRITE" );
251 // this fails with ENOFILE ... why ????
252 // BOOST_CHECK_NO_THROW( sock.protocol().timestamp() );
253 BOOST_CHECK( !sock.eof() );
258 BOOST_CHECK_EQUAL( sock.read(), "" );
259 BOOST_CHECK( sock.eof() );
260 BOOST_CHECK( !sock );
271 senf::TCPv6ClientSocketHandle sock;
273 // The following setsockopts are hard to REALLY test ...
274 BOOST_CHECK_NO_THROW( sock.protocol().nodelay(true) );
275 BOOST_CHECK( sock.protocol().nodelay() );
276 BOOST_CHECK_EQUAL( sock.protocol().siocinq(), 0u );
277 BOOST_CHECK_EQUAL( sock.protocol().siocoutq(), 0u );
279 BOOST_CHECK_NO_THROW( sock.protocol().reuseaddr(true) );
280 BOOST_CHECK( sock.protocol().reuseaddr() );
281 BOOST_CHECK_NO_THROW( sock.protocol().linger(true,0) );
282 BOOST_CHECK( sock.protocol().linger() == std::make_pair(true, 0u) );
286 ///////////////////////////////////////////////////////////////////////////
292 int sock = socket(PF_INET,SOCK_STREAM,0);
293 if (sock<0) fail("client_v4","socket()");
294 struct sockaddr_in sin;
295 ::memset(&sin,0,sizeof(sin));
296 sin.sin_family = AF_INET;
297 sin.sin_port = htons(12346);
298 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
299 if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
300 fail("client_v4","connect()");
304 int n = read(sock,buffer,1024);
305 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
307 write(sock,buffer,n);
310 if (shutdown(sock, SHUT_RDWR) < 0) fail("client_v4","shutdown()");
311 if (close(sock) < 0) fail("client_v4","close()");
316 int sock = socket(PF_INET6,SOCK_STREAM,0);
317 if (sock<0) fail("client_v6","socket()");
318 struct sockaddr_in6 sin;
319 ::memset(&sin,0,sizeof(sin));
320 sin.sin6_family = AF_INET6;
321 sin.sin6_port = htons(12347);
322 sin.sin6_addr = in6addr_loopback;
323 if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
324 fail("client_v6","connect()");
328 int n = read(sock,buffer,1024);
329 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
331 write(sock,buffer,n);
334 if (shutdown(sock, SHUT_RDWR) < 0) fail("client_v6","shutdown()");
335 if (close(sock) < 0) fail("client_v6","close()");
340 BOOST_AUTO_UNIT_TEST(tcpv4ServerSocketHandle)
344 BOOST_CHECKPOINT("Opening server socket");
345 senf::TCPv4ServerSocketHandle server (senf::INet4SocketAddress("127.0.0.1:12346"));
346 BOOST_CHECKPOINT("Starting client");
349 BOOST_CHECKPOINT("Accepting connection");
350 senf::TCPv4ClientSocketHandle client = server.accept();
351 BOOST_CHECK_NO_THROW(client.write("QUIT"));
353 BOOST_CHECKPOINT("Stopping client");
366 BOOST_AUTO_UNIT_TEST(tcpv6ServerSocketHandle)
370 BOOST_CHECKPOINT("Opening server socket");
371 senf::TCPv6ServerSocketHandle server (senf::INet6SocketAddress("[::1]:12347"));
372 BOOST_CHECKPOINT("Starting client");
375 BOOST_CHECKPOINT("Accepting connection");
376 senf::TCPv6ClientSocketHandle client = server.accept();
377 BOOST_CHECK_NO_THROW(client.write("QUIT"));
379 BOOST_CHECKPOINT("Stopping client");
392 ///////////////////////////////cc.e////////////////////////////////////////
399 // c-file-style: "senf"
400 // indent-tabs-mode: nil
401 // ispell-local-dictionary: "american"
402 // compile-command: "scons -u test"
403 // comment-column: 40