/src/uWebSockets/fuzzing/EpollEchoServerPubSub.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* We rely on wrapped syscalls */ |
2 | | #include "libEpollFuzzer/epoll_fuzzer.h" |
3 | | |
4 | | #include "App.h" |
5 | | #include <vector> |
6 | | |
7 | | /* We keep this one for teardown later on */ |
8 | | struct us_listen_socket_t *listen_socket; |
9 | | |
10 | | /* This test is run by libEpollFuzzer */ |
11 | 5.79k | void test() { |
12 | | |
13 | | /* ws->getUserData returns one of these */ |
14 | 5.79k | struct PerSocketData { |
15 | | /* Fill with user data */ |
16 | 5.79k | std::vector<std::string> topics; |
17 | 5.79k | int nr = 0; |
18 | 5.79k | }; |
19 | | |
20 | | /* Keep in mind that uWS::SSLApp({options}) is the same as uWS::App() when compiled without SSL support. |
21 | | * You may swap to using uWS:App() if you don't need SSL */ |
22 | 5.79k | uWS::SSLApp *app = new uWS::SSLApp({ |
23 | | /* There are example certificates in uWebSockets.js repo */ |
24 | 5.79k | .key_file_name = "../misc/key.pem", |
25 | 5.79k | .cert_file_name = "../misc/cert.pem", |
26 | 5.79k | .passphrase = "1234" |
27 | 5.79k | }); |
28 | | |
29 | 5.79k | app->ws<PerSocketData>("/*", { |
30 | | /* Settings */ |
31 | 5.79k | .compression = uWS::DISABLED, |
32 | 5.79k | .maxPayloadLength = 512, // also have a low value here for fuzzing |
33 | 5.79k | .idleTimeout = 60, |
34 | 5.79k | .maxBackpressure = 128, // we want a low number so that we can reach this in fuzzing |
35 | 5.79k | .closeOnBackpressureLimit = false, // this one could be tested as well |
36 | 5.79k | .resetIdleTimeoutOnSend = true, // and this |
37 | 5.79k | .sendPingsAutomatically = false, // and this |
38 | | /* Handlers */ |
39 | 5.79k | .upgrade = nullptr, |
40 | 64.9k | .open = [](auto *ws) { |
41 | | /* Open event here, you may access ws->getUserData() which points to a PerSocketData struct */ |
42 | | |
43 | 64.9k | PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); |
44 | | |
45 | 6.56M | for (int i = 0; i < 100; i++) { |
46 | 6.49M | std::string topic = std::to_string((uintptr_t)ws) + "-" + std::to_string(i); |
47 | 6.49M | perSocketData->topics.push_back(topic); |
48 | 6.49M | ws->subscribe(topic); |
49 | 6.49M | } |
50 | 64.9k | }, |
51 | 167k | .message = [&app](auto *ws, std::string_view message, uWS::OpCode opCode) { |
52 | 167k | PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); |
53 | | |
54 | 167k | app->publish(perSocketData->topics[++perSocketData->nr % 100], message, opCode); |
55 | 167k | }, |
56 | 10.4k | .drain = [](auto */*ws*/) { |
57 | | /* Check ws->getBufferedAmount() here */ |
58 | | //std::cout << "drain" << std::endl; |
59 | 10.4k | }, |
60 | 6.69k | .ping = [](auto */*ws*/, std::string_view ) { |
61 | | /* Not implemented yet */ |
62 | 6.69k | }, |
63 | 5.79k | .pong = [](auto */*ws*/, std::string_view ) { |
64 | | /* Not implemented yet */ |
65 | 789 | }, |
66 | 64.9k | .close = [](auto */*ws*/, int /*code*/, std::string_view /*message*/) { |
67 | | /* You may access ws->getUserData() here */ |
68 | 64.9k | } |
69 | 5.79k | }).listen(9001, [](auto *listen_s) { |
70 | 4.13k | if (listen_s) { |
71 | | //std::cout << "Listening on port " << 9001 << std::endl; |
72 | 4.12k | listen_socket = listen_s; |
73 | 4.12k | } |
74 | 4.13k | }); |
75 | | |
76 | 5.79k | app->run(); |
77 | | |
78 | 5.79k | delete app; |
79 | | |
80 | 5.79k | uWS::Loop::get()->free(); |
81 | 5.79k | } |
82 | | |
83 | | /* Thus function should shutdown the event-loop and let the test fall through */ |
84 | 11.2k | void teardown() { |
85 | | /* If we are called twice there's a bug (it potentially could if |
86 | | * all open sockets cannot be error-closed in one epoll_wait call). |
87 | | * But we only allow 1k FDs and we have a buffer of 1024 from epoll_wait */ |
88 | 11.2k | if (!listen_socket) { |
89 | 0 | exit(-1); |
90 | 0 | } |
91 | | |
92 | | /* We might have open sockets still, and these will be error-closed by epoll_wait */ |
93 | | // us_socket_context_close - close all open sockets created with this socket context |
94 | 11.2k | if (listen_socket) { |
95 | 11.2k | us_listen_socket_close(0, listen_socket); |
96 | 11.2k | listen_socket = NULL; |
97 | 11.2k | } |
98 | 11.2k | } |