TCPServerTest.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. //
  2. // TCPServerTest.cpp
  3. //
  4. // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
  5. // and Contributors.
  6. //
  7. // SPDX-License-Identifier: BSL-1.0
  8. //
  9. #include "TCPServerTest.h"
  10. #include "CppUnit/TestCaller.h"
  11. #include "CppUnit/TestSuite.h"
  12. #include "Poco/Net/TCPServer.h"
  13. #include "Poco/Net/TCPServerConnection.h"
  14. #include "Poco/Net/TCPServerConnectionFactory.h"
  15. #include "Poco/Net/TCPServerParams.h"
  16. #include "Poco/Net/SecureStreamSocket.h"
  17. #include "Poco/Net/SecureServerSocket.h"
  18. #include "Poco/Net/Context.h"
  19. #include "Poco/Net/RejectCertificateHandler.h"
  20. #include "Poco/Net/AcceptCertificateHandler.h"
  21. #include "Poco/Net/Session.h"
  22. #include "Poco/Net/SSLManager.h"
  23. #include "Poco/Util/Application.h"
  24. #include "Poco/Util/AbstractConfiguration.h"
  25. #include "Poco/Thread.h"
  26. #include "Poco/Mutex.h"
  27. #include <iostream>
  28. using Poco::Net::TCPServer;
  29. using Poco::Net::TCPServerConnection;
  30. using Poco::Net::TCPServerConnectionFactory;
  31. using Poco::Net::TCPServerConnectionFactoryImpl;
  32. using Poco::Net::TCPServerParams;
  33. using Poco::Net::StreamSocket;
  34. using Poco::Net::SecureStreamSocket;
  35. using Poco::Net::SecureServerSocket;
  36. using Poco::Net::SocketAddress;
  37. using Poco::Net::Context;
  38. using Poco::Net::Session;
  39. using Poco::Net::SSLManager;
  40. using Poco::Thread;
  41. using Poco::Util::Application;
  42. namespace
  43. {
  44. static Poco::FastMutex cerrMutex;
  45. class EchoConnection: public TCPServerConnection
  46. {
  47. public:
  48. EchoConnection(const StreamSocket& s): TCPServerConnection(s)
  49. {
  50. }
  51. void run()
  52. {
  53. StreamSocket& ss = socket();
  54. try
  55. {
  56. char buffer[256];
  57. int n = ss.receiveBytes(buffer, sizeof(buffer));
  58. while (n > 0)
  59. {
  60. ss.sendBytes(buffer, n);
  61. n = ss.receiveBytes(buffer, sizeof(buffer));
  62. }
  63. }
  64. catch (const Poco::Exception& exc)
  65. {
  66. Poco::FastMutex::ScopedLock l(cerrMutex);
  67. std::cerr << "EchoConnection: " << exc.displayText() << std::endl;
  68. }
  69. }
  70. };
  71. class NullConnection: public TCPServerConnection
  72. {
  73. public:
  74. NullConnection(const StreamSocket& s): TCPServerConnection(s)
  75. {
  76. }
  77. void run()
  78. {
  79. SecureStreamSocket ss = socket();
  80. try
  81. {
  82. ss.completeHandshake();
  83. }
  84. catch (...)
  85. {
  86. }
  87. }
  88. };
  89. }
  90. TCPServerTest::TCPServerTest(const std::string& name): CppUnit::TestCase(name)
  91. {
  92. }
  93. TCPServerTest::~TCPServerTest()
  94. {
  95. }
  96. void TCPServerTest::testOneConnection()
  97. {
  98. SecureServerSocket svs(0);
  99. TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
  100. srv.start();
  101. assertTrue (srv.currentConnections() == 0);
  102. assertTrue (srv.currentThreads() == 0);
  103. assertTrue (srv.queuedConnections() == 0);
  104. assertTrue (srv.totalConnections() == 0);
  105. SocketAddress sa("127.0.0.1", svs.address().port());
  106. SecureStreamSocket ss1(sa);
  107. std::string data("hello, world");
  108. ss1.sendBytes(data.data(), (int) data.size());
  109. char buffer[256];
  110. int n = ss1.receiveBytes(buffer, sizeof(buffer));
  111. assertTrue (n > 0);
  112. assertTrue (std::string(buffer, n) == data);
  113. assertTrue (srv.currentConnections() == 1);
  114. assertTrue (srv.currentThreads() == 1);
  115. assertTrue (srv.queuedConnections() == 0);
  116. assertTrue (srv.totalConnections() == 1);
  117. ss1.close();
  118. Thread::sleep(300);
  119. assertTrue (srv.currentConnections() == 0);
  120. }
  121. void TCPServerTest::testTwoConnections()
  122. {
  123. SecureServerSocket svs(0);
  124. TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
  125. srv.start();
  126. assertTrue (srv.currentConnections() == 0);
  127. assertTrue (srv.currentThreads() == 0);
  128. assertTrue (srv.queuedConnections() == 0);
  129. assertTrue (srv.totalConnections() == 0);
  130. SocketAddress sa("127.0.0.1", svs.address().port());
  131. SecureStreamSocket ss1(sa);
  132. SecureStreamSocket ss2(sa);
  133. std::string data("hello, world");
  134. ss1.sendBytes(data.data(), (int) data.size());
  135. ss2.sendBytes(data.data(), (int) data.size());
  136. char buffer[256];
  137. int n = ss1.receiveBytes(buffer, sizeof(buffer));
  138. assertTrue (n > 0);
  139. assertTrue (std::string(buffer, n) == data);
  140. n = ss2.receiveBytes(buffer, sizeof(buffer));
  141. assertTrue (n > 0);
  142. assertTrue (std::string(buffer, n) == data);
  143. assertTrue (srv.currentConnections() == 2);
  144. assertTrue (srv.currentThreads() == 2);
  145. assertTrue (srv.queuedConnections() == 0);
  146. assertTrue (srv.totalConnections() == 2);
  147. ss1.close();
  148. Thread::sleep(300);
  149. assertTrue (srv.currentConnections() == 1);
  150. assertTrue (srv.currentThreads() == 1);
  151. assertTrue (srv.queuedConnections() == 0);
  152. assertTrue (srv.totalConnections() == 2);
  153. ss2.close();
  154. Thread::sleep(300);
  155. assertTrue (srv.currentConnections() == 0);
  156. }
  157. void TCPServerTest::testMultiConnections()
  158. {
  159. SecureServerSocket svs(0);
  160. TCPServerParams* pParams = new TCPServerParams;
  161. pParams->setMaxThreads(4);
  162. pParams->setMaxQueued(4);
  163. pParams->setThreadIdleTime(100);
  164. TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs, pParams);
  165. srv.start();
  166. assertTrue (srv.currentConnections() == 0);
  167. assertTrue (srv.currentThreads() == 0);
  168. assertTrue (srv.queuedConnections() == 0);
  169. assertTrue (srv.totalConnections() == 0);
  170. SocketAddress sa("127.0.0.1", svs.address().port());
  171. SecureStreamSocket ss1(sa);
  172. SecureStreamSocket ss2(sa);
  173. SecureStreamSocket ss3(sa);
  174. SecureStreamSocket ss4(sa);
  175. std::string data("hello, world");
  176. ss1.sendBytes(data.data(), (int) data.size());
  177. ss2.sendBytes(data.data(), (int) data.size());
  178. ss3.sendBytes(data.data(), (int) data.size());
  179. ss4.sendBytes(data.data(), (int) data.size());
  180. char buffer[256];
  181. int n = ss1.receiveBytes(buffer, sizeof(buffer));
  182. assertTrue (n > 0);
  183. assertTrue (std::string(buffer, n) == data);
  184. n = ss2.receiveBytes(buffer, sizeof(buffer));
  185. assertTrue (n > 0);
  186. assertTrue (std::string(buffer, n) == data);
  187. n = ss3.receiveBytes(buffer, sizeof(buffer));
  188. assertTrue (n > 0);
  189. assertTrue (std::string(buffer, n) == data);
  190. n = ss4.receiveBytes(buffer, sizeof(buffer));
  191. assertTrue (n > 0);
  192. assertTrue (std::string(buffer, n) == data);
  193. assertTrue (srv.currentConnections() == 4);
  194. assertTrue (srv.currentThreads() == 4);
  195. assertTrue (srv.queuedConnections() == 0);
  196. assertTrue (srv.totalConnections() == 4);
  197. SecureStreamSocket ss5;
  198. ss5.setLazyHandshake();
  199. ss5.connect(sa);
  200. Thread::sleep(200);
  201. assertTrue (srv.queuedConnections() == 1);
  202. SecureStreamSocket ss6;
  203. ss6.setLazyHandshake();
  204. ss6.connect(sa);
  205. Thread::sleep(200);
  206. assertTrue (srv.queuedConnections() == 2);
  207. ss1.close();
  208. Thread::sleep(300);
  209. assertTrue (srv.currentConnections() == 4);
  210. assertTrue (srv.currentThreads() == 4);
  211. assertTrue (srv.queuedConnections() == 1);
  212. assertTrue (srv.totalConnections() == 5);
  213. ss2.close();
  214. Thread::sleep(300);
  215. assertTrue (srv.currentConnections() == 4);
  216. assertTrue (srv.currentThreads() == 4);
  217. assertTrue (srv.queuedConnections() == 0);
  218. assertTrue (srv.totalConnections() == 6);
  219. ss3.close();
  220. Thread::sleep(300);
  221. assertTrue (srv.currentConnections() == 3);
  222. assertTrue (srv.currentThreads() == 3);
  223. assertTrue (srv.queuedConnections() == 0);
  224. assertTrue (srv.totalConnections() == 6);
  225. ss4.close();
  226. Thread::sleep(300);
  227. assertTrue (srv.currentConnections() == 2);
  228. assertTrue (srv.currentThreads() == 2);
  229. assertTrue (srv.queuedConnections() == 0);
  230. assertTrue (srv.totalConnections() == 6);
  231. ss5.close();
  232. ss6.close();
  233. Thread::sleep(300);
  234. assertTrue (srv.currentConnections() == 0);
  235. }
  236. void TCPServerTest::testReuseSocket()
  237. {
  238. SecureServerSocket svs(0);
  239. TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
  240. srv.start();
  241. assertTrue (srv.currentConnections() == 0);
  242. assertTrue (srv.currentThreads() == 0);
  243. assertTrue (srv.queuedConnections() == 0);
  244. assertTrue (srv.totalConnections() == 0);
  245. SocketAddress sa("127.0.0.1", svs.address().port());
  246. SecureStreamSocket ss1(sa);
  247. std::string data("hello, world");
  248. ss1.sendBytes(data.data(), (int) data.size());
  249. char buffer[256];
  250. int n = ss1.receiveBytes(buffer, sizeof(buffer));
  251. assertTrue (n > 0);
  252. assertTrue (std::string(buffer, n) == data);
  253. assertTrue (srv.currentConnections() == 1);
  254. assertTrue (srv.currentThreads() == 1);
  255. assertTrue (srv.queuedConnections() == 0);
  256. assertTrue (srv.totalConnections() == 1);
  257. ss1.close();
  258. Thread::sleep(300);
  259. assertTrue (srv.currentConnections() == 0);
  260. ss1.connect(sa);
  261. ss1.sendBytes(data.data(), (int) data.size());
  262. n = ss1.receiveBytes(buffer, sizeof(buffer));
  263. assertTrue (n > 0);
  264. assertTrue (std::string(buffer, n) == data);
  265. assertTrue (srv.currentConnections() == 1);
  266. assertTrue (srv.queuedConnections() == 0);
  267. assertTrue (srv.totalConnections() == 2);
  268. ss1.close();
  269. Thread::sleep(300);
  270. assertTrue (srv.currentConnections() == 0);
  271. }
  272. void TCPServerTest::testReuseSession()
  273. {
  274. // ensure OpenSSL machinery is fully setup
  275. Context::Ptr pDefaultServerContext = SSLManager::instance().defaultServerContext();
  276. Context::Ptr pDefaultClientContext = SSLManager::instance().defaultClientContext();
  277. Context::Ptr pServerContext = new Context(
  278. Context::SERVER_USE,
  279. Application::instance().config().getString("openSSL.server.privateKeyFile"),
  280. Application::instance().config().getString("openSSL.server.privateKeyFile"),
  281. Application::instance().config().getString("openSSL.server.caConfig"),
  282. Context::VERIFY_NONE,
  283. 9,
  284. true,
  285. "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
  286. pServerContext->disableProtocols(Context::PROTO_TLSV1_3);
  287. pServerContext->enableSessionCache(true, "TestSuite");
  288. pServerContext->setSessionTimeout(10);
  289. pServerContext->setSessionCacheSize(1000);
  290. pServerContext->disableStatelessSessionResumption();
  291. SecureServerSocket svs(0, 64, pServerContext);
  292. TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
  293. srv.start();
  294. assertTrue (srv.currentConnections() == 0);
  295. assertTrue (srv.currentThreads() == 0);
  296. assertTrue (srv.queuedConnections() == 0);
  297. assertTrue (srv.totalConnections() == 0);
  298. Context::Ptr pClientContext = new Context(
  299. Context::CLIENT_USE,
  300. Application::instance().config().getString("openSSL.client.privateKeyFile"),
  301. Application::instance().config().getString("openSSL.client.privateKeyFile"),
  302. Application::instance().config().getString("openSSL.client.caConfig"),
  303. Context::VERIFY_RELAXED,
  304. 9,
  305. true,
  306. "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
  307. pClientContext->enableSessionCache(true);
  308. SocketAddress sa("127.0.0.1", svs.address().port());
  309. SecureStreamSocket ss1(sa, pClientContext);
  310. assertTrue (!ss1.sessionWasReused());
  311. std::string data("hello, world");
  312. ss1.sendBytes(data.data(), (int) data.size());
  313. char buffer[256];
  314. int n = ss1.receiveBytes(buffer, sizeof(buffer));
  315. assertTrue (n > 0);
  316. assertTrue (std::string(buffer, n) == data);
  317. assertTrue (srv.currentConnections() == 1);
  318. assertTrue (srv.currentThreads() == 1);
  319. assertTrue (srv.queuedConnections() == 0);
  320. assertTrue (srv.totalConnections() == 1);
  321. Session::Ptr pSession = ss1.currentSession();
  322. if (!pSession || !pSession->isResumable())
  323. {
  324. std::cerr << "WARNING: Server did not return a session or session is not resumable. Aborting test." << std::endl;
  325. return;
  326. }
  327. ss1.close();
  328. Thread::sleep(300);
  329. assertTrue (srv.currentConnections() == 0);
  330. ss1.useSession(pSession);
  331. ss1.connect(sa);
  332. ss1.sendBytes(data.data(), (int) data.size());
  333. n = ss1.receiveBytes(buffer, sizeof(buffer));
  334. assertTrue (ss1.sessionWasReused());
  335. assertTrue (n > 0);
  336. assertTrue (std::string(buffer, n) == data);
  337. assertTrue (srv.currentConnections() == 1);
  338. assertTrue (srv.queuedConnections() == 0);
  339. assertTrue (srv.totalConnections() == 2);
  340. pSession = ss1.currentSession();
  341. ss1.close();
  342. Thread::sleep(300);
  343. assertTrue (srv.currentConnections() == 0);
  344. Thread::sleep(15000); // wait for session to expire
  345. pServerContext->flushSessionCache();
  346. ss1.useSession(pSession);
  347. ss1.connect(sa);
  348. ss1.sendBytes(data.data(), (int) data.size());
  349. n = ss1.receiveBytes(buffer, sizeof(buffer));
  350. assertTrue (!ss1.sessionWasReused());
  351. assertTrue (n > 0);
  352. assertTrue (std::string(buffer, n) == data);
  353. assertTrue (srv.currentConnections() == 1);
  354. assertTrue (srv.queuedConnections() == 0);
  355. assertTrue (srv.totalConnections() == 3);
  356. ss1.close();
  357. Thread::sleep(300);
  358. assertTrue (srv.currentConnections() == 0);
  359. }
  360. void TCPServerTest::testContextInvalidCertificateHandler()
  361. {
  362. SecureServerSocket svs(0);
  363. TCPServer srv(new TCPServerConnectionFactoryImpl<NullConnection>(), svs);
  364. srv.start();
  365. Context::Ptr pClientContext = new Context(
  366. Context::CLIENT_USE,
  367. "",
  368. "",
  369. "",
  370. Context::VERIFY_RELAXED,
  371. 9,
  372. true,
  373. "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
  374. pClientContext->setInvalidCertificateHandler(new Poco::Net::RejectCertificateHandler(false));
  375. SocketAddress sa("127.0.0.1", svs.address().port());
  376. try
  377. {
  378. SecureStreamSocket ss1(sa, pClientContext);
  379. fail("must throw with RejectCertificateHandler");
  380. }
  381. catch (...)
  382. {
  383. }
  384. pClientContext->setInvalidCertificateHandler(new Poco::Net::AcceptCertificateHandler(false));
  385. try
  386. {
  387. SecureStreamSocket ss1(sa, pClientContext);
  388. }
  389. catch (...)
  390. {
  391. fail("must not throw with AcceptCertificateHandler");
  392. }
  393. srv.stop();
  394. }
  395. void TCPServerTest::setUp()
  396. {
  397. }
  398. void TCPServerTest::tearDown()
  399. {
  400. }
  401. CppUnit::Test* TCPServerTest::suite()
  402. {
  403. CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("TCPServerTest");
  404. CppUnit_addTest(pSuite, TCPServerTest, testOneConnection);
  405. CppUnit_addTest(pSuite, TCPServerTest, testTwoConnections);
  406. CppUnit_addTest(pSuite, TCPServerTest, testMultiConnections);
  407. CppUnit_addTest(pSuite, TCPServerTest, testReuseSocket);
  408. CppUnit_addTest(pSuite, TCPServerTest, testReuseSession);
  409. CppUnit_addTest(pSuite, TCPServerTest, testContextInvalidCertificateHandler);
  410. return pSuite;
  411. }