diff --git a/build.c b/build.c index 2258a76..358c9f1 100644 --- a/build.c +++ b/build.c @@ -9,7 +9,7 @@ int main(int argc, char **argv) { char *CXX = strcpy(calloc(1024, 1), or_else(getenv("CXX"), "g++")); char *EXEC_SUFFIX = strcpy(calloc(1024, 1), maybe(getenv("EXEC_SUFFIX"))); - char *EXAMPLE_FILES[] = {"Client", "Http3Server", "Broadcast", "HelloWorld", "Crc32", "ServerName", + char *EXAMPLE_FILES[] = {"Http3Server", "Broadcast", "HelloWorld", "Crc32", "ServerName", "EchoServer", "BroadcastingEchoServer", "UpgradeSync", "UpgradeAsync"}; strcat(CXXFLAGS, " -O3 -Wpedantic -Wall -Wextra -Wsign-conversion -Wconversion -std=c++20 -Isrc -IuSockets/src"); diff --git a/fuzzing/AsyncEpollHelloWorld.cpp b/fuzzing/AsyncEpollHelloWorld.cpp new file mode 100644 index 0000000..180bf73 --- /dev/null +++ b/fuzzing/AsyncEpollHelloWorld.cpp @@ -0,0 +1,60 @@ +/* We rely on wrapped syscalls */ +#include "libEpollFuzzer/epoll_fuzzer.h" + +#include "App.h" + +/* We keep this one for teardown later on */ +struct us_listen_socket_t *listen_socket; + +/* This test is run by libEpollFuzzer */ +void test() { + + { + /* Keep in mind that uWS::SSLApp({options}) is the same as uWS::App() when compiled without SSL support. + * You may swap to using uWS:App() if you don't need SSL */ + auto app = uWS::App({ + /* There are example certificates in uWebSockets.js repo */ + .key_file_name = "../misc/key.pem", + .cert_file_name = "../misc/cert.pem", + .passphrase = "1234" + }).get("/*", [](auto *res, auto *req) { + bool *aborted = new bool; + *aborted = false; + res->onAborted([aborted]() { + *aborted = true; + }); + + uWS::Loop::get()->defer([res, aborted]() { + if (!*aborted) { + res->cork([res, aborted]() { + // Todo: also test upgrade to websocket here + res->end("Hello async!"); + }); + } + delete aborted; + }); + }).listen(9001, [](auto *listenSocket) { + listen_socket = listenSocket; + }); + + app.run(); + } + uWS::Loop::get()->free(); +} + +/* Thus function should shutdown the event-loop and let the test fall through */ +void teardown() { + /* If we are called twice there's a bug (it potentially could if + * all open sockets cannot be error-closed in one epoll_wait call). + * But we only allow 1k FDs and we have a buffer of 1024 from epoll_wait */ + if (!listen_socket) { + exit(-1); + } + + /* We might have open sockets still, and these will be error-closed by epoll_wait */ + // us_socket_context_close - close all open sockets created with this socket context + if (listen_socket) { + us_listen_socket_close(0, listen_socket); + listen_socket = NULL; + } +} diff --git a/fuzzing/AsyncEpollHelloWorld.dict b/fuzzing/AsyncEpollHelloWorld.dict new file mode 100644 index 0000000..48b49eb --- /dev/null +++ b/fuzzing/AsyncEpollHelloWorld.dict @@ -0,0 +1,12 @@ +"get" +"post" +"get /" +"http/1.1" +"upgrade: websocket" +"\x0D\x0A" +"sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" +"sec-websocket-version: 13" +"get / http/1.1" +"sec-websocket-extensions: permessage-deflate" +"sec-websocket-protocol: " +" " \ No newline at end of file diff --git a/fuzzing/Makefile b/fuzzing/Makefile index 518334e..58f76bf 100644 --- a/fuzzing/Makefile +++ b/fuzzing/Makefile @@ -18,6 +18,8 @@ oss-fuzz: # Link against object files $(CXX) $(CXXFLAGS) $(WRAPPED_SYSCALLS) -std=c++17 -O3 -DUWS_MOCK_ZLIB -I../src -I../uSockets/src EpollHelloWorld.cpp -o $(OUT)/EpollHelloWorld $(LIB_FUZZING_ENGINE) *.o rm -f EpollHelloWorld.o + $(CXX) $(CXXFLAGS) $(WRAPPED_SYSCALLS) -std=c++17 -O3 -DUWS_MOCK_ZLIB -I../src -I../uSockets/src AsyncEpollHelloWorld.cpp -o $(OUT)/AsyncEpollHelloWorld $(LIB_FUZZING_ENGINE) *.o + rm -f AsyncEpollHelloWorld.o $(CXX) $(CXXFLAGS) $(WRAPPED_SYSCALLS) -std=c++17 -O3 -DUWS_MOCK_ZLIB -I../src -I../uSockets/src EpollEchoServer.cpp -o $(OUT)/EpollEchoServer $(LIB_FUZZING_ENGINE) *.o rm -f EpollEchoServer.o $(CXX) $(CXXFLAGS) $(WRAPPED_SYSCALLS) -std=c++17 -O3 -DUWS_MOCK_ZLIB -I../src -I../uSockets/src EpollEchoServerPubSub.cpp -o $(OUT)/EpollEchoServerPubSub $(LIB_FUZZING_ENGINE) *.o