diff --git a/wish/cpp/CMakeLists.txt b/wish/cpp/CMakeLists.txt index 9b1847e..e39066d 100644 --- a/wish/cpp/CMakeLists.txt +++ b/wish/cpp/CMakeLists.txt @@ -82,13 +82,6 @@ add_library(wish_handler # BoringSSL targets: ssl and crypto target_link_libraries(wish_handler wslay event ssl crypto) -add_executable(echo_server examples/echo_server.cc) -target_link_libraries(echo_server wish_handler) - -add_executable(hello_client examples/hello_client.cc) -target_link_libraries(hello_client wish_handler) - -add_executable(benchmark_client examples/benchmark_client.cc) -target_link_libraries(benchmark_client wish_handler) +add_subdirectory(examples) add_subdirectory(benchmark) diff --git a/wish/cpp/benchmark/CMakeLists.txt b/wish/cpp/benchmark/CMakeLists.txt index a9000d0..9e352f4 100644 --- a/wish/cpp/benchmark/CMakeLists.txt +++ b/wish/cpp/benchmark/CMakeLists.txt @@ -1,24 +1,19 @@ -add_executable(wish_echo_server - server.cc +add_executable(benchmark_client + client.cc ) -target_link_libraries(wish_echo_server +target_link_libraries(benchmark_client wish_handler absl::flags absl::flags_parse absl::log absl::log_initialize "$" + benchmark::benchmark ) -add_executable(wish_bench_client - client.cc +add_executable(tls_benchmark_client + tls_client.cc ) -target_link_libraries(wish_bench_client +target_link_libraries(tls_benchmark_client wish_handler - absl::flags - absl::flags_parse - absl::log - absl::log_initialize - "$" - benchmark::benchmark -) +) \ No newline at end of file diff --git a/wish/cpp/benchmark/benchmark.py b/wish/cpp/benchmark/benchmark.py index 4e479b7..5eb7927 100644 --- a/wish/cpp/benchmark/benchmark.py +++ b/wish/cpp/benchmark/benchmark.py @@ -6,8 +6,8 @@ import signal BUILD_DIR = "./build" -SERVER_BINARY_NAME = "benchmark/wish_echo_server" -CLIENT_BINARY_NAME = "benchmark/wish_bench_client" +SERVER_BINARY_NAME = "examples/echo_server" +CLIENT_BINARY_NAME = "benchmark/benchmark_client" SERVER_BINARY_PATH = os.path.join(BUILD_DIR, SERVER_BINARY_NAME) CLIENT_BINARY_PATH = os.path.join(BUILD_DIR, CLIENT_BINARY_NAME) diff --git a/wish/cpp/benchmark/server.cc b/wish/cpp/benchmark/server.cc deleted file mode 100644 index 51885a9..0000000 --- a/wish/cpp/benchmark/server.cc +++ /dev/null @@ -1,128 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "../src/wish_handler.h" -#include "absl/flags/flag.h" -#include "absl/flags/parse.h" -#include "absl/log/initialize.h" -#include "absl/log/log.h" - -ABSL_FLAG(int, port, 8080, "Port to listen on"); - -namespace { - -void accept_conn_cb(struct evconnlistener* listener, evutil_socket_t fd, - struct sockaddr* address, int socklen, void* ctx) { - (void)address; - (void)socklen; - (void)ctx; - - struct event_base* base = evconnlistener_get_base(listener); - - int nodelay = 1; - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)) != - 0) { - LOG(ERROR) << "setsockopt(TCP_NODELAY) failed"; - } - - struct bufferevent* bev = - bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); - if (!bev) { - LOG(ERROR) << "Failed to create bufferevent for accepted socket"; - evutil_closesocket(fd); - return; - } - - auto* handler = new WishHandler(bev, true); - handler->SetOnMessage([handler](uint8_t opcode, const std::string& msg) { - std::string type; - switch (opcode) { - case WISH_OPCODE_TEXT: - type = "TEXT"; - break; - case WISH_OPCODE_BINARY: - type = "BINARY"; - break; - case WISH_OPCODE_TEXT_METADATA: - type = "TEXT_METADATA"; - break; - case WISH_OPCODE_BINARY_METADATA: - type = "BINARY_METADATA"; - break; - default: - type = "UNKNOWN(" + std::to_string(opcode) + ")"; - break; - } - LOG(INFO) << "Received [" << type << "]: " << msg; - - // Echo back - if (opcode == WISH_OPCODE_TEXT) - handler->SendText(msg); - else if (opcode == WISH_OPCODE_BINARY) - handler->SendBinary(msg); - else if (opcode == WISH_OPCODE_TEXT_METADATA) - handler->SendTextMetadata(msg); - else if (opcode == WISH_OPCODE_BINARY_METADATA) - handler->SendBinaryMetadata(msg); - else { - LOG(WARNING) << "Unknown opcode, cannot echo."; - } - }); - - handler->Start(); -} - -void accept_error_cb(struct evconnlistener* listener, void* ctx) { - (void)ctx; - struct event_base* base = evconnlistener_get_base(listener); - const int err = EVUTIL_SOCKET_ERROR(); - LOG(ERROR) << "Listener error " << err << " (" - << evutil_socket_error_to_string(err) << ")"; - event_base_loopexit(base, nullptr); -} - -} // namespace - -int main(int argc, char** argv) { - absl::ParseCommandLine(argc, argv); - absl::InitializeLog(); - const int port = absl::GetFlag(FLAGS_port); - - struct event_base* base = event_base_new(); - if (!base) { - LOG(ERROR) << "Could not initialize libevent"; - return 1; - } - - struct sockaddr_in sin; - std::memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_ANY); - sin.sin_port = htons(port); - - struct evconnlistener* listener = evconnlistener_new_bind( - base, accept_conn_cb, nullptr, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, - -1, reinterpret_cast(&sin), sizeof(sin)); - - if (!listener) { - LOG(ERROR) << "Could not create listener on port " << port; - event_base_free(base); - return 1; - } - - evconnlistener_set_error_cb(listener, accept_error_cb); - LOG(INFO) << "WiSH benchmark server listening on port " << port << "..."; - event_base_dispatch(base); - - evconnlistener_free(listener); - event_base_free(base); - return 0; -} diff --git a/wish/cpp/examples/benchmark_client.cc b/wish/cpp/benchmark/tls_client.cc similarity index 100% rename from wish/cpp/examples/benchmark_client.cc rename to wish/cpp/benchmark/tls_client.cc diff --git a/wish/cpp/examples/CMakeLists.txt b/wish/cpp/examples/CMakeLists.txt new file mode 100644 index 0000000..8f3760f --- /dev/null +++ b/wish/cpp/examples/CMakeLists.txt @@ -0,0 +1,25 @@ +add_executable(echo_server + echo_server.cc +) +target_link_libraries(echo_server + wish_handler + absl::flags + absl::flags_parse + absl::log + absl::log_initialize + "$" +) + +add_executable(tls_echo_server + tls_echo_server.cc +) +target_link_libraries(tls_echo_server + wish_handler +) + +add_executable(tls_hello_client + tls_hello_client.cc +) +target_link_libraries(tls_hello_client + wish_handler +) diff --git a/wish/cpp/examples/echo_server.cc b/wish/cpp/examples/echo_server.cc index 2d645eb..51885a9 100644 --- a/wish/cpp/examples/echo_server.cc +++ b/wish/cpp/examples/echo_server.cc @@ -1,64 +1,128 @@ -#include -#include - -#include "../src/tls_server.h" -#include "../src/wish_handler.h" - -int main(int argc, char** argv) { - int port = 8080; - - TlsServer server("../certs/ca.crt", "../certs/server.crt", - "../certs/server.key", port); - - if (!server.Init()) { - std::cerr << "Failed to initialize server" << std::endl; - return 1; - } - - server.SetOnConnection([](struct bufferevent* bev) { - std::cout << "Client connected." << std::endl; - - WishHandler* handler = new WishHandler(bev, true); - - handler->SetOnMessage([handler](uint8_t opcode, const std::string& msg) { - std::string type; - switch (opcode) { - case WISH_OPCODE_TEXT: - type = "TEXT"; - break; - case WISH_OPCODE_BINARY: - type = "BINARY"; - break; - case WISH_OPCODE_TEXT_METADATA: - type = "TEXT_METADATA"; - break; - case WISH_OPCODE_BINARY_METADATA: - type = "BINARY_METADATA"; - break; - default: - type = "UNKNOWN(" + std::to_string(opcode) + ")"; - break; - } - std::cout << "Received [" << type << "]: " << msg << std::endl; - - // Echo back - if (opcode == WISH_OPCODE_TEXT) - handler->SendText(msg); - else if (opcode == WISH_OPCODE_BINARY) - handler->SendBinary(msg); - else if (opcode == WISH_OPCODE_TEXT_METADATA) - handler->SendTextMetadata(msg); - else if (opcode == WISH_OPCODE_BINARY_METADATA) - handler->SendBinaryMetadata(msg); - else { - std::cerr << "Unknown opcode, cannot echo." << std::endl; - } - }); - - handler->Start(); - }); - - server.Run(); - - return 0; -} +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../src/wish_handler.h" +#include "absl/flags/flag.h" +#include "absl/flags/parse.h" +#include "absl/log/initialize.h" +#include "absl/log/log.h" + +ABSL_FLAG(int, port, 8080, "Port to listen on"); + +namespace { + +void accept_conn_cb(struct evconnlistener* listener, evutil_socket_t fd, + struct sockaddr* address, int socklen, void* ctx) { + (void)address; + (void)socklen; + (void)ctx; + + struct event_base* base = evconnlistener_get_base(listener); + + int nodelay = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)) != + 0) { + LOG(ERROR) << "setsockopt(TCP_NODELAY) failed"; + } + + struct bufferevent* bev = + bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); + if (!bev) { + LOG(ERROR) << "Failed to create bufferevent for accepted socket"; + evutil_closesocket(fd); + return; + } + + auto* handler = new WishHandler(bev, true); + handler->SetOnMessage([handler](uint8_t opcode, const std::string& msg) { + std::string type; + switch (opcode) { + case WISH_OPCODE_TEXT: + type = "TEXT"; + break; + case WISH_OPCODE_BINARY: + type = "BINARY"; + break; + case WISH_OPCODE_TEXT_METADATA: + type = "TEXT_METADATA"; + break; + case WISH_OPCODE_BINARY_METADATA: + type = "BINARY_METADATA"; + break; + default: + type = "UNKNOWN(" + std::to_string(opcode) + ")"; + break; + } + LOG(INFO) << "Received [" << type << "]: " << msg; + + // Echo back + if (opcode == WISH_OPCODE_TEXT) + handler->SendText(msg); + else if (opcode == WISH_OPCODE_BINARY) + handler->SendBinary(msg); + else if (opcode == WISH_OPCODE_TEXT_METADATA) + handler->SendTextMetadata(msg); + else if (opcode == WISH_OPCODE_BINARY_METADATA) + handler->SendBinaryMetadata(msg); + else { + LOG(WARNING) << "Unknown opcode, cannot echo."; + } + }); + + handler->Start(); +} + +void accept_error_cb(struct evconnlistener* listener, void* ctx) { + (void)ctx; + struct event_base* base = evconnlistener_get_base(listener); + const int err = EVUTIL_SOCKET_ERROR(); + LOG(ERROR) << "Listener error " << err << " (" + << evutil_socket_error_to_string(err) << ")"; + event_base_loopexit(base, nullptr); +} + +} // namespace + +int main(int argc, char** argv) { + absl::ParseCommandLine(argc, argv); + absl::InitializeLog(); + const int port = absl::GetFlag(FLAGS_port); + + struct event_base* base = event_base_new(); + if (!base) { + LOG(ERROR) << "Could not initialize libevent"; + return 1; + } + + struct sockaddr_in sin; + std::memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(port); + + struct evconnlistener* listener = evconnlistener_new_bind( + base, accept_conn_cb, nullptr, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, + -1, reinterpret_cast(&sin), sizeof(sin)); + + if (!listener) { + LOG(ERROR) << "Could not create listener on port " << port; + event_base_free(base); + return 1; + } + + evconnlistener_set_error_cb(listener, accept_error_cb); + LOG(INFO) << "WiSH benchmark server listening on port " << port << "..."; + event_base_dispatch(base); + + evconnlistener_free(listener); + event_base_free(base); + return 0; +} diff --git a/wish/cpp/examples/tls_echo_server.cc b/wish/cpp/examples/tls_echo_server.cc new file mode 100644 index 0000000..2d645eb --- /dev/null +++ b/wish/cpp/examples/tls_echo_server.cc @@ -0,0 +1,64 @@ +#include +#include + +#include "../src/tls_server.h" +#include "../src/wish_handler.h" + +int main(int argc, char** argv) { + int port = 8080; + + TlsServer server("../certs/ca.crt", "../certs/server.crt", + "../certs/server.key", port); + + if (!server.Init()) { + std::cerr << "Failed to initialize server" << std::endl; + return 1; + } + + server.SetOnConnection([](struct bufferevent* bev) { + std::cout << "Client connected." << std::endl; + + WishHandler* handler = new WishHandler(bev, true); + + handler->SetOnMessage([handler](uint8_t opcode, const std::string& msg) { + std::string type; + switch (opcode) { + case WISH_OPCODE_TEXT: + type = "TEXT"; + break; + case WISH_OPCODE_BINARY: + type = "BINARY"; + break; + case WISH_OPCODE_TEXT_METADATA: + type = "TEXT_METADATA"; + break; + case WISH_OPCODE_BINARY_METADATA: + type = "BINARY_METADATA"; + break; + default: + type = "UNKNOWN(" + std::to_string(opcode) + ")"; + break; + } + std::cout << "Received [" << type << "]: " << msg << std::endl; + + // Echo back + if (opcode == WISH_OPCODE_TEXT) + handler->SendText(msg); + else if (opcode == WISH_OPCODE_BINARY) + handler->SendBinary(msg); + else if (opcode == WISH_OPCODE_TEXT_METADATA) + handler->SendTextMetadata(msg); + else if (opcode == WISH_OPCODE_BINARY_METADATA) + handler->SendBinaryMetadata(msg); + else { + std::cerr << "Unknown opcode, cannot echo." << std::endl; + } + }); + + handler->Start(); + }); + + server.Run(); + + return 0; +} diff --git a/wish/cpp/examples/hello_client.cc b/wish/cpp/examples/tls_hello_client.cc similarity index 100% rename from wish/cpp/examples/hello_client.cc rename to wish/cpp/examples/tls_hello_client.cc