From 3a480a4a216d7953f344ad665dbb79d246a78e2a Mon Sep 17 00:00:00 2001 From: fengdaolong Date: Tue, 12 Jan 2021 16:41:40 +0800 Subject: [PATCH] solved the problem that Windows cannot multicast (#576) * Solve the problem that Windows cannot multicast. * Better git judgment logic. --- CMakeLists.txt | 15 +++++----- include/edge_utils_win32.h | 10 ++++++- src/edge_utils.c | 9 ++++++ src/edge_utils_win32.c | 60 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bbe38a4..5b6da08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,14 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # N2n release information set(N2N_VERSION "2.9.0") -set(N2N_OSNAME ${CMAKE_SYSTEM}) +set(N2N_OSNAME ${CMAKE_SYSTEM_NAME}) execute_process( - COMMAND git --version + COMMAND git status WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - OUTPUT_VARIABLE GIT_EXIST + OUTPUT_VARIABLE GIT_OUTPUT + RESULT_VARIABLE GIT_ERROR_CODE ) -if (GIT_EXIST) +if (GIT_ERROR_CODE EQUAL 0) execute_process( COMMAND git rev-list --count HEAD WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} @@ -28,7 +29,7 @@ string(REGEX REPLACE "\n$" "" GIT_REV "${GIT_REV}") string(REGEX REPLACE "\n$" "" GIT_ID "${GIT_ID}") set(N2N_VERSION "${N2N_VERSION}.r${GIT_REV}.${GIT_ID}") MESSAGE(STATUS "Build from git rev: ${N2N_VERSION}") -endif (GIT_EXIST) +endif (GIT_ERROR_CODE EQUAL 0) add_definitions(-DCMAKE_BUILD) add_definitions(-DGIT_RELEASE="${N2N_VERSION}" -DPACKAGE_VERSION="${N2N_VERSION}" -DPACKAGE_OSNAME="${N2N_OSNAME}") @@ -142,7 +143,7 @@ endif(N2N_OPTION_USE_ZSTD) if(DEFINED WIN32) add_library(edge_utils_win32 src/edge_utils_win32.c) add_subdirectory(win32) - target_link_libraries(n2n edge_utils_win32 n2n_win32 ) + target_link_libraries(n2n edge_utils_win32 n2n_win32 iphlpapi) endif(DEFINED WIN32) add_executable(edge src/edge.c) @@ -164,7 +165,7 @@ if(N2N_OPTION_USE_PCAPLIB AND (NOT DEFINED WIN32)) # Linux Capabilities find_library(CAP_LIB cap) if(CAP_LIB) - target_link_libraries(edge cap) + target_link_libraries(edge cap.a) set(CMAKE_REQUIRED_LIBRARIES ${CAP_LIB}) ADD_DEFINITIONS("-DHAVE_LIBCAP") endif() diff --git a/include/edge_utils_win32.h b/include/edge_utils_win32.h index f9c81fe..ac1d95b 100644 --- a/include/edge_utils_win32.h +++ b/include/edge_utils_win32.h @@ -25,10 +25,17 @@ #include #include +#include +#include /* Multicast peers discovery disabled due to https://github.com/ntop/n2n/issues/65 */ -#define SKIP_MULTICAST_PEERS_DISCOVERY + +/* Currently, multicast is performed by specifying the default routing network adapter. + * If the solution is determined to be stable and effective, + * all macro definitions "SKIP_MULTICAST_PEERS_DISCOVERY" will be completely deleted in the future. + */ +//#define SKIP_MULTICAST_PEERS_DISCOVERY struct tunread_arg { n2n_edge_t *eee; @@ -36,6 +43,7 @@ struct tunread_arg { }; extern HANDLE startTunReadThread (struct tunread_arg *arg); +int get_best_interface_ip(n2n_edge_t * eee, dec_ip_str_t ip_addr); #endif /* WIN32 */ diff --git a/src/edge_utils.c b/src/edge_utils.c index 70bfba1..48d3607 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -718,6 +718,9 @@ static ssize_t sendto_sock (int fd, const void * buf, if(sent < 0) { char * c = strerror(errno); traceEvent(TRACE_ERROR, "sendto failed (%d) %s", errno, c); +#ifdef WIN32 + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); +#endif } else { traceEvent(TRACE_DEBUG, "sendto sent=%d to ", (signed int)sent); } @@ -734,7 +737,13 @@ static void check_join_multicast_group (n2n_edge_t *eee) { if(!eee->multicast_joined) { struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr(N2N_MULTICAST_GROUP); +#ifdef WIN32 + dec_ip_str_t ip_addr; + get_best_interface_ip(eee, ip_addr); + mreq.imr_interface.s_addr = inet_addr(ip_addr); +#else mreq.imr_interface.s_addr = htonl(INADDR_ANY); +#endif if(setsockopt(eee->udp_multicast_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) { traceEvent(TRACE_WARNING, "Failed to bind to local multicast group %s:%u [errno %u]", diff --git a/src/edge_utils_win32.c b/src/edge_utils_win32.c index 5cc0aae..10305d8 100644 --- a/src/edge_utils_win32.c +++ b/src/edge_utils_win32.c @@ -48,5 +48,65 @@ HANDLE startTunReadThread (struct tunread_arg *arg) { 0, /* thread creation flags */ &dwThreadId)); /* thread id out */ } + + + +int get_best_interface_ip(n2n_edge_t * eee, dec_ip_str_t ip_addr){ + DWORD interface_index = -1; + DWORD dwRetVal = 0; + PIP_ADAPTER_INFO pAdapterInfo = NULL, pAdapter = NULL; + macstr_t mac_buf; + ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); + + dwRetVal = GetBestInterface(*(IPAddr*)(&eee->curr_sn->sock.addr.v4), &interface_index); + if(dwRetVal != NO_ERROR) return -1; + + pAdapterInfo = (PIP_ADAPTER_INFO)malloc(ulOutBufLen); + if (pAdapterInfo == NULL) { + traceEvent(TRACE_INFO, "Error allocating memory needed to call GetAdaptersInfo\n"); + return -1; + } + + dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); + if(dwRetVal == ERROR_BUFFER_OVERFLOW){ + pAdapterInfo = (PIP_ADAPTER_INFO)realloc(pAdapterInfo, ulOutBufLen); + if (pAdapterInfo == NULL) { + traceEvent(TRACE_INFO, "Error allocating memory needed to call GetAdaptersInfo\n"); + return -1; + } + } + + dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); +// hexdump((uint8_t*)pAdapterInfo, ulOutBufLen); + if (dwRetVal == NO_ERROR) { + for(pAdapter = pAdapterInfo; pAdapter != NULL; pAdapter = pAdapter->Next){ + if (pAdapter->Index != interface_index) continue; + + traceEvent(TRACE_DEBUG, "Adapter Index: %ld\n", pAdapter->Index); + traceEvent(TRACE_DEBUG, "Combo Index: %ld\n", pAdapter->ComboIndex); + traceEvent(TRACE_DEBUG, "Adapter Name: %s\n", pAdapter->AdapterName); + traceEvent(TRACE_DEBUG, "Adapter Desc: %s\n", pAdapter->Description); + traceEvent(TRACE_DEBUG, "Adapter Type: %u\n", pAdapter->Type); + macaddr_str(mac_buf, pAdapter->Address); + traceEvent(TRACE_DEBUG, "Adapter Addr: %s\n", mac_buf); + traceEvent(TRACE_DEBUG, "DHCP Enabled: %u\n", pAdapter->DhcpEnabled); + traceEvent(TRACE_DEBUG, "DHCP Server: %s\n", pAdapter->DhcpServer.IpAddress.String); + traceEvent(TRACE_DEBUG, "IP Address: %s\n", pAdapter->IpAddressList.IpAddress.String); + traceEvent(TRACE_DEBUG, "IP Mask: %s\n", pAdapter->IpAddressList.IpMask.String); + traceEvent(TRACE_DEBUG, "Gateway: %s\n", pAdapter->GatewayList.IpAddress.String); + strncpy(ip_addr, pAdapter->IpAddressList.IpAddress.String, sizeof(dec_ip_str_t)-1); + } + } + else { + traceEvent(TRACE_WARNING, "GetAdaptersInfo failed with error: %d\n", dwRetVal); + } + if (pAdapterInfo != NULL){ + free(pAdapterInfo); + pAdapterInfo = NULL; + } + return 0; +} + + #endif