diff --git a/.gitignore b/.gitignore index 749b288b8..12910296e 100644 --- a/.gitignore +++ b/.gitignore @@ -117,7 +117,6 @@ cmake-build-debug builddir builddir-linux coverage.info -.vscode/settings.json .vscode/launch.json /vs .vscode/tasks.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..ccd8aa807 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "files.associations": { + "numbers": "cpp", + "cstring": "cpp" + }, + "C_Cpp.default.configurationProvider": "mesonbuild.mesonbuild", + "editor.inlayHints.enabled": "offUnlessPressed", + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/src/iptux-core/CoreThread.cpp b/src/iptux-core/CoreThread.cpp index 6a31946a7..536cc80ed 100644 --- a/src/iptux-core/CoreThread.cpp +++ b/src/iptux-core/CoreThread.cpp @@ -20,8 +20,7 @@ #include "iptux-core/internal/RecvFileData.h" #include "iptux-core/internal/SendFile.h" #include "iptux-core/internal/TcpData.h" -#include "iptux-core/internal/UdpData.h" -#include "iptux-core/internal/UdpDataService.h" +#include "iptux-core/internal/UdpServer.h" #include "iptux-core/internal/ipmsg.h" #include "iptux-core/internal/support.h" #include "iptux-utils/output.h" @@ -88,7 +87,7 @@ struct CoreThread::Impl { PPalInfo me; - UdpDataService_U udp_data_service; + UdpServer_U udp_server; GSList* blacklist{nullptr}; // 黑名单链表 bool debugDontBroadcast{false}; @@ -118,7 +117,7 @@ CoreThread::CoreThread(shared_ptr data) pImpl->debugDontBroadcast = true; } pImpl->port = programData->port(); - pImpl->udp_data_service = make_unique(*this); + pImpl->udp_server = make_unique(*this); pImpl->me = make_shared("127.0.0.1", port()); (*pImpl->me) .setUser(g_get_user_name()) @@ -151,6 +150,8 @@ void CoreThread::start() { pImpl->tcpFuture = async([](CoreThread* ct) { RecvTcpData(ct); }, this); pImpl->notifyToAllFuture = async([](CoreThread* ct) { SendNotifyToAll(ct); }, this); + + pImpl->udp_server->start(); } void CoreThread::bind_iptux_port() { @@ -230,7 +231,7 @@ void CoreThread::RecvUdpData(CoreThread* self) { if (size != MAX_UDPLEN) buf[size] = '\0'; auto port = ntohs(addr.sin_port); - self->pImpl->udp_data_service->process(addr.sin_addr, port, buf, size); + self->pImpl->udp_server->process(addr.sin_addr, port, buf, size); } } diff --git a/src/iptux-core/internal/UdpDataService.cpp b/src/iptux-core/internal/UdpServer.cpp similarity index 50% rename from src/iptux-core/internal/UdpDataService.cpp rename to src/iptux-core/internal/UdpServer.cpp index 50548a4ea..65a4c8a6b 100644 --- a/src/iptux-core/internal/UdpDataService.cpp +++ b/src/iptux-core/internal/UdpServer.cpp @@ -1,26 +1,31 @@ -#include "UdpDataService.h" +#include "UdpServer.h" +#include +#include +#include + +#include "iptux-core/Exception.h" +#include "iptux-core/internal/support.h" #include "iptux-utils/output.h" #include "iptux-utils/utils.h" using namespace std; namespace iptux { -UdpDataService::UdpDataService(CoreThread& coreThread) - : core_thread_(coreThread) {} +UdpServer::UdpServer(CoreThread& coreThread) : core_thread_(coreThread) {} -unique_ptr UdpDataService::process(in_addr ipv4, - int port, - const char buf[], - size_t size) { +unique_ptr UdpServer::process(in_addr ipv4, + int port, + const char buf[], + size_t size) { return process(ipv4, port, buf, size, true); } -unique_ptr UdpDataService::process(in_addr ipv4, - int port, - const char buf[], - size_t size, - bool run) { +unique_ptr UdpServer::process(in_addr ipv4, + int port, + const char buf[], + size_t size, + bool run) { if (Log::IsDebugEnabled()) { LOG_DEBUG("received udp message from %s:%d, size %zu\n%s", inAddrToString(ipv4).c_str(), port, size, @@ -37,7 +42,7 @@ unique_ptr UdpDataService::process(in_addr ipv4, return udata; } -void UdpDataService::process(UdpData& udata) { +void UdpServer::process(UdpData& udata) { /* 如果开启了黑名单处理功能,且此地址正好被列入了黑名单 */ if (core_thread_.IsBlocked(udata.getIpv4())) { LOG_INFO("address is blocked: %s", udata.getIpv4String().c_str()); @@ -85,4 +90,41 @@ void UdpDataService::process(UdpData& udata) { } } +bool UdpServer::start() { + if (status != UdpServerStatus::INITED) { + LOG_ERROR("udp server status is not inited"); + return false; + } + + int udpSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (udpSock < 0) { + LOG_ERROR("create udp socket failed: %s", strerror(errno)); + status = UdpServerStatus::START_FAILED; + return false; + } + + socket_enable_reuse(udpSock); + socket_enable_broadcast(udpSock); + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(bind_port); + addr.sin_addr = inAddrFromString(bind_ip); + + if (::bind(udpSock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + int ec = errno; + close(udpSock); + auto errmsg = + stringFormat(_("Fatal Error!! Failed to bind the UDP port(%s:%d)!\n%s"), + bind_ip.c_str(), bind_port, strerror(ec)); + LOG_ERROR("%s", errmsg.c_str()); + throw Exception(UDP_BIND_FAILED, errmsg); + } else { + LOG_INFO("bind UDP port(%s:%d) success.", bind_ip.c_str(), bind_port); + } + + status = UdpServerStatus::RUNNING; + return true; +} + } // namespace iptux diff --git a/src/iptux-core/internal/UdpDataService.h b/src/iptux-core/internal/UdpServer.h similarity index 69% rename from src/iptux-core/internal/UdpDataService.h rename to src/iptux-core/internal/UdpServer.h index ccc199466..619e3777c 100644 --- a/src/iptux-core/internal/UdpDataService.h +++ b/src/iptux-core/internal/UdpServer.h @@ -6,9 +6,16 @@ namespace iptux { -class UdpDataService { +enum class UdpServerStatus { + INITED, + RUNNING, + STOPPED, + START_FAILED, +}; + +class UdpServer { public: - explicit UdpDataService(CoreThread& coreThread); + explicit UdpServer(CoreThread& coreThread); std::unique_ptr process(in_addr ipv4, int port, @@ -23,11 +30,17 @@ class UdpDataService { void process(UdpData& udpData); + bool start(); + bool stop(); + private: CoreThread& core_thread_; + std::string bind_ip; + int bind_port; + UdpServerStatus status = UdpServerStatus::INITED; }; -using UdpDataService_U = std::unique_ptr; +using UdpServer_U = std::unique_ptr; } // namespace iptux diff --git a/src/iptux-core/internal/UdpDataServiceTest.cpp b/src/iptux-core/internal/UdpServerTest.cpp similarity index 88% rename from src/iptux-core/internal/UdpDataServiceTest.cpp rename to src/iptux-core/internal/UdpServerTest.cpp index 7f57739ae..307789a4b 100644 --- a/src/iptux-core/internal/UdpDataServiceTest.cpp +++ b/src/iptux-core/internal/UdpServerTest.cpp @@ -1,7 +1,7 @@ #include "gtest/gtest.h" #include "iptux-core/TestHelper.h" -#include "iptux-core/internal/UdpDataService.h" +#include "iptux-core/internal/UdpServer.h" #include "iptux-utils/utils.h" using namespace std; @@ -9,13 +9,13 @@ using namespace iptux; TEST(UdpDataService, process) { auto core = newCoreThread(); - auto service = new UdpDataService(*core.get()); + auto service = new UdpServer(*core.get()); service->process(inAddrFromString("127.0.0.1"), 1234, "", 0, true); } TEST(UdpDataService, SomeoneEntry) { auto core = newCoreThread(); - auto service = new UdpDataService(*core.get()); + auto service = new UdpServer(*core.get()); const char* data = "iptux 0.8.0:1:lidaobing:lidaobing.lan:257:lidaobing"; service->process(inAddrFromString("127.0.0.1"), 1234, data, strlen(data), true); @@ -28,7 +28,7 @@ TEST(UdpDataService, CreatePalInfo) { "1_iptux " "0.8.0-b1:6:lidaobing:LIs-MacBook-Pro.local:259:中\xe4\xb8\x00\x00icon-" "tux.png\x00utf-8\x00"; - auto service = new UdpDataService(*core.get()); + auto service = new UdpServer(*core.get()); auto udp = service->process(inAddrFromString("127.0.0.1"), 1234, data, strlen(data), false); auto pal = udp->CreatePalInfo(); @@ -43,7 +43,7 @@ TEST(UdpDataService, CreatePalInfo) { "1_iptux " "0.8.0-b1:6:中\xe4\xb8:LIs-MacBook-Pro.local:259:" "中\xe4\xb8\x00\x00icon-tux.png\x00utf-8\x00"; - auto service = new UdpDataService(*core.get()); + auto service = new UdpServer(*core.get()); auto udp = service->process(inAddrFromString("127.0.0.1"), 1234, data, strlen(data), false); auto pal = udp->CreatePalInfo(); diff --git a/src/iptux-core/meson.build b/src/iptux-core/meson.build index dfa21e4b1..91327a050 100644 --- a/src/iptux-core/meson.build +++ b/src/iptux-core/meson.build @@ -26,7 +26,7 @@ core_sources += files([ 'internal/TcpData.cpp', 'internal/TransAbstract.cpp', 'internal/UdpData.cpp', - 'internal/UdpDataService.cpp', + 'internal/UdpServer.cpp', ]) inc = include_directories('..', '../api') @@ -78,7 +78,7 @@ core_test_sources = files([ 'internal/CommandTest.cpp', 'internal/supportTest.cpp', 'internal/UdpDataTest.cpp', - 'internal/UdpDataServiceTest.cpp', + 'internal/UdpServerTest.cpp', 'IptuxConfigTest.cpp', 'ModelsTest.cpp', 'ProgramDataTest.cpp',