From 45b7f48bc9acee8e81767ab5507b88d9ab86c4f0 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 10:27:24 -0700 Subject: [PATCH 001/167] Move files to reactor-c/network/ --- {include/core/federated/network => network/api}/net_common.h | 0 {include/core/federated/network => network/api}/net_util.h | 0 {include/core/federated/network => network/api}/socket_common.h | 0 {core/federated/network => network/impl}/CMakeLists.txt | 0 {core/federated/network => network/impl/src}/net_util.c | 0 {core/federated/network => network/impl/src}/socket_common.c | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename {include/core/federated/network => network/api}/net_common.h (100%) rename {include/core/federated/network => network/api}/net_util.h (100%) rename {include/core/federated/network => network/api}/socket_common.h (100%) rename {core/federated/network => network/impl}/CMakeLists.txt (100%) rename {core/federated/network => network/impl/src}/net_util.c (100%) rename {core/federated/network => network/impl/src}/socket_common.c (100%) diff --git a/include/core/federated/network/net_common.h b/network/api/net_common.h similarity index 100% rename from include/core/federated/network/net_common.h rename to network/api/net_common.h diff --git a/include/core/federated/network/net_util.h b/network/api/net_util.h similarity index 100% rename from include/core/federated/network/net_util.h rename to network/api/net_util.h diff --git a/include/core/federated/network/socket_common.h b/network/api/socket_common.h similarity index 100% rename from include/core/federated/network/socket_common.h rename to network/api/socket_common.h diff --git a/core/federated/network/CMakeLists.txt b/network/impl/CMakeLists.txt similarity index 100% rename from core/federated/network/CMakeLists.txt rename to network/impl/CMakeLists.txt diff --git a/core/federated/network/net_util.c b/network/impl/src/net_util.c similarity index 100% rename from core/federated/network/net_util.c rename to network/impl/src/net_util.c diff --git a/core/federated/network/socket_common.c b/network/impl/src/socket_common.c similarity index 100% rename from core/federated/network/socket_common.c rename to network/impl/src/socket_common.c From 536cdc769f2aa79b9bc441afe7e3eb90c7d3b5b1 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 10:28:30 -0700 Subject: [PATCH 002/167] Remove unnecessary #include on socket_common.h --- network/api/net_util.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/network/api/net_util.h b/network/api/net_util.h index 1e9008816..7cd5faf65 100644 --- a/network/api/net_util.h +++ b/network/api/net_util.h @@ -51,9 +51,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "low_level_platform.h" #include "tag.h" -#ifdef FEDERATED -#include "socket_common.h" -#endif #define HOST_LITTLE_ENDIAN 1 #define HOST_BIG_ENDIAN 2 From 684ab06644db0eebe308f577b35659831ad2a770 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 10:30:28 -0700 Subject: [PATCH 003/167] Add net_driver. --- core/federated/RTI/rti_remote.h | 7 ++++++- core/federated/federate.c | 1 + network/api/net_driver.h | 13 +++++++++++++ network/api/socket_common.h | 1 + network/impl/src/lf_socket_support.c | 0 network/impl/src/net_driver.c | 1 + 6 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 network/api/net_driver.h create mode 100644 network/impl/src/lf_socket_support.c create mode 100644 network/impl/src/net_driver.c diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index de6b144aa..3dc56c180 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -31,7 +31,7 @@ #include "lf_types.h" #include "pqueue_tag.h" -#include "socket_common.h" +#include "net_driver.h" /** Time allowed for federates to reply to stop request. */ #define MAX_TIME_FOR_REPLY_TO_STOP_REQUEST SEC(30) @@ -129,6 +129,11 @@ typedef struct rti_remote_t { /** The UDP socket descriptor for the socket server. */ int socket_descriptor_UDP; + /** + * The rti's netdriver. + */ + netdrv_t* rti_netdrv; + /************* Clock synchronization information *************/ /* Thread performing PTP clock sync sessions periodically. */ lf_thread_t clock_thread; diff --git a/core/federated/federate.c b/core/federated/federate.c index 51b9c2602..a689ae090 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -30,6 +30,7 @@ #include "federate.h" #include "net_common.h" #include "net_util.h" +#include "net_driver.h" #include "reactor.h" #include "reactor_common.h" #include "reactor_threaded.h" diff --git a/network/api/net_driver.h b/network/api/net_driver.h new file mode 100644 index 000000000..993d22853 --- /dev/null +++ b/network/api/net_driver.h @@ -0,0 +1,13 @@ +#ifndef NET_DRIVER_H +#define NET_DRIVER_H + +#include "socket_common.h" + +typedef struct netdrv_t { + void* priv; + // unsigned int read_remaining_bytes; + // int my_federate_id; // The RTI is -1, and unitialized is -2. This must be int not uint16_t + // const char* federation_id; +} netdrv_t; + +#endif /* NET_DRIVER_H */ diff --git a/network/api/socket_common.h b/network/api/socket_common.h index c273b4b74..878f0b107 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -2,6 +2,7 @@ #define SOCKET_COMMON_H #include "low_level_platform.h" +#include /** * The amount of time to wait after a failed socket read or write before trying again. This defaults to 100 ms. diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c new file mode 100644 index 000000000..e69de29bb diff --git a/network/impl/src/net_driver.c b/network/impl/src/net_driver.c new file mode 100644 index 000000000..4b6232348 --- /dev/null +++ b/network/impl/src/net_driver.c @@ -0,0 +1 @@ +#include "net_driver.h" \ No newline at end of file From 43960cfad2ac5652d5648e7ef786e13151d69d36 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 10:31:23 -0700 Subject: [PATCH 004/167] Create CMake files to make the network related c files as a library. --- core/CMakeLists.txt | 11 +++++++- core/federated/RTI/CMakeLists.txt | 17 +++++++++-- network/api/CMakeLists.txt | 14 +++++++++ network/impl/CMakeLists.txt | 47 +++++++++++++++++++++++++++++-- 4 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 network/api/CMakeLists.txt diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 6d938ae0c..6f5f021c8 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -18,7 +18,6 @@ list(APPEND REACTORC_SOURCES ${GENERAL_SOURCES}) # Add sources for either threaded or single-threaded runtime if(DEFINED FEDERATED) include(federated/CMakeLists.txt) - include(federated/network/CMakeLists.txt) endif() # Add sources for either threaded or single-threaded runtime @@ -96,6 +95,16 @@ include(${LF_ROOT}/platform/impl/CMakeLists.txt) target_link_libraries(reactor-c PUBLIC lf::platform-api) target_link_libraries(reactor-c PRIVATE lf::platform-impl) +option(COMM_TYPE "Communication type between RTI and federate(s)." ON) +IF(COMM_TYPE MATCHES ON) + set(COMM_TYPE TCP) +ENDIF() + +include(${LF_ROOT}/network/api/CMakeLists.txt) +include(${LF_ROOT}/network/impl/CMakeLists.txt) +target_link_libraries(reactor-c PUBLIC lf::network-api) +target_link_libraries(reactor-c PRIVATE lf::network-impl) + target_include_directories(reactor-c PUBLIC ../include) target_include_directories(reactor-c PUBLIC ../include/core) target_include_directories(reactor-c PUBLIC ../include/core/federated) diff --git a/core/federated/RTI/CMakeLists.txt b/core/federated/RTI/CMakeLists.txt index d9a93c246..fce1517a5 100644 --- a/core/federated/RTI/CMakeLists.txt +++ b/core/federated/RTI/CMakeLists.txt @@ -16,8 +16,6 @@ add_library(${RTI_LIB} STATIC ${CoreLib}/utils/util.c ${CoreLib}/tag.c ${CoreLib}/clock.c - ${CoreLib}/federated/network/net_util.c - ${CoreLib}/federated/network/socket_common.c ${CoreLib}/utils/pqueue_base.c ${CoreLib}/utils/pqueue_tag.c ${CoreLib}/utils/pqueue.c @@ -29,7 +27,6 @@ add_executable(${RTI_MAIN} main.c) target_include_directories(${RTI_LIB} PUBLIC ../../../include) target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}) target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}/federated) -target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}/federated/network) target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}/modal_models) target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}/utils) @@ -37,6 +34,11 @@ if (NOT DEFINED LOG_LEVEL) set(LOG_LEVEL 0) ENDIF(NOT DEFINED LOG_LEVEL) +# option(COMM_TYPE "Communication type between RTI and federate(s)." ON) +# IF(COMM_TYPE MATCHES ON) +set(COMM_TYPE TCP) +# ENDIF() + IF(CMAKE_BUILD_TYPE MATCHES DEBUG) # Set the LOG_LEVEL to 4 to get DEBUG messages message("-- Building RTI with DEBUG messages enabled") @@ -71,6 +73,12 @@ target_link_libraries(${RTI_LIB} PUBLIC lf::low-level-platform-impl) include(${LF_ROOT}/low_level_platform/api/CMakeLists.txt) target_link_libraries(${RTI_LIB} PUBLIC lf::low-level-platform-api) +include(${LF_ROOT}/network/impl/CMakeLists.txt) +target_link_libraries(${RTI_LIB} PUBLIC lf::network-impl) + +include(${LF_ROOT}/network/api/CMakeLists.txt) +target_link_libraries(${RTI_LIB} PUBLIC lf::network-api) + # Set the STANDALONE_RTI flag to include the rti_remote and rti_common. target_compile_definitions(${RTI_LIB} PUBLIC STANDALONE_RTI=1) @@ -78,6 +86,9 @@ target_compile_definitions(${RTI_LIB} PUBLIC STANDALONE_RTI=1) target_compile_definitions(${RTI_LIB} PUBLIC FEDERATED=1) target_compile_definitions(${RTI_LIB} PUBLIC PLATFORM_${CMAKE_SYSTEM_NAME}) +# Set communication type. +target_compile_definitions(${RTI_LIB} PUBLIC COMM_TYPE_${COMM_TYPE}) + # Set RTI Tracing target_compile_definitions(${RTI_LIB} PUBLIC RTI_TRACE) diff --git a/network/api/CMakeLists.txt b/network/api/CMakeLists.txt new file mode 100644 index 000000000..6f724fe1a --- /dev/null +++ b/network/api/CMakeLists.txt @@ -0,0 +1,14 @@ +add_library(lf-network-api INTERFACE) +target_include_directories(lf-network-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}) +add_library(lf::network-api ALIAS lf-network-api) + +#Link necessary libraries. +target_link_libraries(lf-network-api INTERFACE lf::tag-api) +target_link_libraries(lf-network-api INTERFACE lf::low-level-platform-api) + + +# #TODO:CHECK. +# target_include_directories(lf-network-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}/type) +target_include_directories(lf-network-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}/../../include/core/utils) + +target_compile_definitions(lf-network-api INTERFACE COMM_TYPE_${COMM_TYPE}) \ No newline at end of file diff --git a/network/impl/CMakeLists.txt b/network/impl/CMakeLists.txt index f61d69897..e54a9631a 100644 --- a/network/impl/CMakeLists.txt +++ b/network/impl/CMakeLists.txt @@ -1,4 +1,45 @@ -set(LF_NETWORK_FILES net_util.c socket_common.c) +set(LF_ROOT ${CMAKE_CURRENT_LIST_DIR}/../..) +include(${LF_ROOT}/core/lf_utils.cmake) -list(TRANSFORM LF_NETWORK_FILES PREPEND federated/network/) -list(APPEND REACTORC_SOURCES ${LF_NETWORK_FILES}) +add_library(lf-network-impl STATIC ${LF_NETWORK_FILES}) +add_library(lf::network-impl ALIAS lf-network-impl) +target_sources(lf-network-impl PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/src/net_util.c + ${CMAKE_CURRENT_LIST_DIR}/src/net_driver.c + ${CMAKE_CURRENT_LIST_DIR}/src/socket_common.c +) + +if(COMM_TYPE MATCHES TCP) + target_sources(lf-network-impl PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lf_socket_support.c) +elseif(COMM_TYPE MATCHES MQTT) +# # $ git clone https://github.com/eclipse/paho.mqtt.c.git +# # $ cd paho.mqtt.c.git +# # $ mkdir build.paho; cd build.paho +# # $ cmake ../ +# # $ make +# # $ sudo make install +# # It will be installed in /usr/local/lib +# find_package(eclipse-paho-mqtt-c REQUIRED) +# target_link_libraries(lf-network-impl PRIVATE eclipse-paho-mqtt-c::paho-mqtt3a eclipse-paho-mqtt-c::paho-mqtt3c) +# # $ apt-get install libssl-dev +# # find_package(OpenSSL REQUIRED) + +# # target_link_libraries(lf-network-impl PUBLIC OpenSSL::SSL) +# # target_sources(lf-network-impl PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lf_mqtt_support.c) +elseif(COMM_TYPE MATCHES SST) +# target_link_libraries(lf-network-impl PUBLIC SSTLIB) +# target_sources(lf-network-impl PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lf_sst_support.c) +# # add_compile_definitions(OPENSSL_REQUIRED) +else() + message(FATAL_ERROR "Your communication type is not supported! The C target supports TCP, MQTT and SST.") +endif() + +# Link necessary libraries +target_link_libraries(lf-network-impl PUBLIC lf-logging-api) +target_link_libraries(lf-network-impl PUBLIC lf-low-level-platform-api) +target_link_libraries(lf-network-impl PUBLIC lf::tag-api) +target_link_libraries(lf-network-impl PRIVATE lf-network-api) + +lf_enable_compiler_warnings(lf-network-impl) + +target_compile_definitions(lf-network-impl PUBLIC COMM_TYPE_${COMM_TYPE}) From 6b00c237d51e3c52062f8e565205c08861379f04 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 11:58:49 -0700 Subject: [PATCH 005/167] Remove parameter from create_server() --- core/federated/RTI/main.c | 6 +++++- core/federated/RTI/rti_remote.c | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/core/federated/RTI/main.c b/core/federated/RTI/main.c index 17d73e93e..7a5d418cb 100644 --- a/core/federated/RTI/main.c +++ b/core/federated/RTI/main.c @@ -233,6 +233,7 @@ int process_args(int argc, const char* argv[]) { rti.base.number_of_scheduling_nodes = (int32_t)num_federates; // FIXME: Loses numbers on 64-bit machines lf_print("RTI: Number of federates: %d", rti.base.number_of_scheduling_nodes); } else if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--port") == 0) { +#ifdef COMM_TYPE_TCP if (argc < i + 2) { lf_print_error("--port needs a short unsigned integer argument ( > 0 and < %d).", UINT16_MAX); usage(argc, argv); @@ -246,6 +247,9 @@ int process_args(int argc, const char* argv[]) { return 0; } rti.user_specified_port = (uint16_t)RTI_port; +#else + lf_print_error("--port is only available for TCP."); +#endif } else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--clock_sync") == 0) { if (argc < i + 2) { lf_print_error("--clock-sync needs off|init|on."); @@ -324,7 +328,7 @@ int main(int argc, const char* argv[]) { rti.base.scheduling_nodes[i] = (scheduling_node_t*)fed_info; } - int socket_descriptor = start_rti_server(rti.user_specified_port); + int socket_descriptor = start_rti_server(); if (socket_descriptor >= 0) { wait_for_federates(socket_descriptor); normal_termination = true; diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index d800dcaac..755912994 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1477,10 +1477,10 @@ void initialize_federate(federate_info_t* fed, uint16_t id) { fed->server_port = -1; } -int32_t start_rti_server(uint16_t port) { +int32_t start_rti_server() { _lf_initialize_clock(); // Create the TCP socket server - if (create_server(port, &rti_remote->socket_descriptor_TCP, &rti_remote->final_port_TCP, TCP, true)) { + if (create_server(rti_remote->user_specified_port, &rti_remote->socket_descriptor_TCP, &rti_remote->final_port_TCP, TCP, true)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); }; lf_print("RTI: Listening for federates."); @@ -1548,8 +1548,10 @@ void initialize_RTI(rti_remote_t* rti) { rti_remote->all_federates_exited = false; rti_remote->federation_id = "Unidentified Federation"; rti_remote->user_specified_port = 0; + // TODO: Erase rti_remote->final_port_TCP = 0; rti_remote->socket_descriptor_TCP = -1; + rti_remote->final_port_UDP = UINT16_MAX; rti_remote->socket_descriptor_UDP = -1; rti_remote->clock_sync_global_status = clock_sync_init; From d62bf0cf5a5ee0d8152ea60b8e4f6ebe573c4151 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 13:30:51 -0700 Subject: [PATCH 006/167] Fix create_server to use netdriver. First only fix RTI. Separate the create_clock_server, because there are no plans using other network stacks rather than UDP. --- core/federated/RTI/rti_remote.c | 6 ++-- core/federated/RTI/rti_remote.h | 11 ++++--- network/api/net_driver.h | 3 ++ network/api/socket_common.h | 22 ++++++++++++++ network/impl/src/socket_common.c | 49 +++++++++++++++++++++++++++++++- 5 files changed, 81 insertions(+), 10 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 755912994..4eee736b2 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1480,15 +1480,15 @@ void initialize_federate(federate_info_t* fed, uint16_t id) { int32_t start_rti_server() { _lf_initialize_clock(); // Create the TCP socket server - if (create_server(rti_remote->user_specified_port, &rti_remote->socket_descriptor_TCP, &rti_remote->final_port_TCP, TCP, true)) { + if (create_server_(rti_remote->rti_netdrv, RTI)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); }; lf_print("RTI: Listening for federates."); // Create the UDP socket server // Try to get the rti_remote->final_port_TCP + 1 port if (rti_remote->clock_sync_global_status >= clock_sync_on) { - if (create_server(rti_remote->final_port_TCP + 1, &rti_remote->socket_descriptor_UDP, &rti_remote->final_port_UDP, - UDP, true)) { + if (create_clock_server(rti_remote->final_port_TCP + 1, &rti_remote->socket_descriptor_UDP, + &rti_remote->final_port_UDP)) { lf_print_error_system_failure("RTI failed to create UDP server: %s.", strerror(errno)); } } diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 3dc56c180..bb3000cfe 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -113,7 +113,9 @@ typedef struct rti_remote_t { const char* federation_id; /************* TCP server information *************/ - /** The desired port specified by the user on the command line. */ + /** The desired port specified by the user on the command line. + * This should be not moved to the net_driver, because the user can configure this as -p or --port. + */ uint16_t user_specified_port; /** The final port number that the TCP socket server ends up using. */ @@ -130,7 +132,7 @@ typedef struct rti_remote_t { int socket_descriptor_UDP; /** - * The rti's netdriver. + * The rti's network driver. */ netdrv_t* rti_netdrv; @@ -375,11 +377,8 @@ void initialize_federate(federate_info_t* fed, uint16_t id); /** * Start the socket server for the runtime infrastructure (RTI) and * return the socket descriptor. - * @param num_feds Number of federates. - * @param port The port on which to listen for socket connections, or - * 0 to use the default port range. */ -int32_t start_rti_server(uint16_t port); +int32_t start_rti_server(); /** * Start the runtime infrastructure (RTI) interaction with the federates diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 993d22853..ce4d0b49d 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -3,6 +3,7 @@ #include "socket_common.h" +typedef enum server_type_t { RTI, FED} server_type_t; typedef struct netdrv_t { void* priv; // unsigned int read_remaining_bytes; @@ -10,4 +11,6 @@ typedef struct netdrv_t { // const char* federation_id; } netdrv_t; +int create_server_(netdrv_t* drv, server_type_t serv_type); + #endif /* NET_DRIVER_H */ diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 878f0b107..7fd6c0f06 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -3,6 +3,7 @@ #include "low_level_platform.h" #include +#include /** * The amount of time to wait after a failed socket read or write before trying again. This defaults to 100 ms. @@ -74,6 +75,23 @@ typedef enum socket_type_t { TCP, UDP } socket_type_t; */ extern lf_mutex_t socket_mutex; +typedef struct socket_priv_t { + int socket_descriptor; + uint16_t port; // my port number // TODO: Only used in federate.c to send federate's port. + uint16_t user_specified_port; + + // The connected other side's info. + char server_hostname[INET_ADDRSTRLEN]; // Human-readable IP address and + int32_t server_port; // port number of the socket server of the federate + // if it has any incoming direct connections from other federates. + // The port number will be -1 if there is no server or if the + // RTI has not been informed of the port number. + struct in_addr server_ip_addr; // Information about the IP address of the socket + // server of the federate. + + struct sockaddr_in UDP_addr; // The UDP address for the federate. +} socket_priv_t; + /** * @brief Create an IPv4 TCP socket with Nagle's algorithm disabled * (TCP_NODELAY) and Delayed ACKs disabled (TCP_QUICKACK). Exits application @@ -106,6 +124,10 @@ int create_real_time_tcp_socket_errexit(); int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, bool increment_port_on_retry); + + +int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port); + /** * Wait for an incoming connection request on the specified server socket. * This blocks until a connection is successfully accepted. If an error occurs that is not diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 587318a2f..47db27f93 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -11,7 +11,7 @@ #include // strerror #include "util.h" -#include "socket_common.h" +#include "net_driver.h" #ifndef NUMBER_OF_FEDERATES #define NUMBER_OF_FEDERATES 1 @@ -133,6 +133,7 @@ static int set_socket_bind_option(int socket_descriptor, uint16_t specified_port return used_port; } +//TODO: Fix on federate. int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, bool increment_port_on_retry) { int socket_descriptor; @@ -170,6 +171,52 @@ int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket return 0; } +int create_server_(netdrv_t* drv, server_type_t serv_type) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + int socket_descriptor; + struct timeval timeout_time; + // Create an IPv4 socket for TCP. + socket_descriptor = create_real_time_tcp_socket_errexit(); + // Set the timeout time for the communications of the server + timeout_time = (struct timeval){.tv_sec = TCP_TIMEOUT_TIME / BILLION, .tv_usec = (TCP_TIMEOUT_TIME % BILLION) / 1000}; + if (socket_descriptor < 0) { + lf_print_error("Failed to create TCP socket."); + return -1; + } + set_socket_timeout_option(socket_descriptor, &timeout_time); + bool increment_port_on_retry = (serv_type == RTI) ? true : false; + + int used_port = set_socket_bind_option(socket_descriptor, priv->user_specified_port, increment_port_on_retry); + // Enable listening for socket connections. + // The second argument is the maximum number of queued socket requests, + // which according to the Mac man page is limited to 128. + if (listen(socket_descriptor, 128)) { + lf_print_error("Failed to listen on %d socket: %s.", socket_descriptor, strerror(errno)); + return -1; + } + priv->socket_descriptor = socket_descriptor; + priv->port = used_port; + return 0; +} + +int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) { + int socket_descriptor; + struct timeval timeout_time; + // Create a UDP socket. + socket_descriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + timeout_time = (struct timeval){.tv_sec = UDP_TIMEOUT_TIME / BILLION, .tv_usec = (UDP_TIMEOUT_TIME % BILLION) / 1000}; + + if (socket_descriptor < 0) { + lf_print_error("Failed to create UDP socket."); + return -1; + } + set_socket_timeout_option(socket_descriptor, &timeout_time); + int used_port = set_socket_bind_option(socket_descriptor, port, true); + *final_socket = socket_descriptor; + *final_port = used_port; + return 0; +} + /** * Return true if either the socket to the RTI is broken or the socket is * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. From fdf009cb0c2cf8717aff0272c24265574c1d44c2 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 14:23:21 -0700 Subject: [PATCH 007/167] Add initialize_netdrv() --- core/federated/RTI/rti_remote.c | 4 +++- network/api/net_driver.h | 15 ++++++++++++- network/impl/src/lf_socket_support.c | 33 ++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 4eee736b2..c900fcb90 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1479,7 +1479,9 @@ void initialize_federate(federate_info_t* fed, uint16_t id) { int32_t start_rti_server() { _lf_initialize_clock(); - // Create the TCP socket server + // Initialize RTI's network driver. + rti_remote->rti_netdrv = initialize_netdrv(); + // Create the server if (create_server_(rti_remote->rti_netdrv, RTI)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); }; diff --git a/network/api/net_driver.h b/network/api/net_driver.h index ce4d0b49d..85880173d 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -3,7 +3,7 @@ #include "socket_common.h" -typedef enum server_type_t { RTI, FED} server_type_t; +typedef enum server_type_t { RTI, FED } server_type_t; typedef struct netdrv_t { void* priv; // unsigned int read_remaining_bytes; @@ -11,6 +11,19 @@ typedef struct netdrv_t { // const char* federation_id; } netdrv_t; +/** + * Allocate memory for the netdriver. + * @return netdrv_t* + */ +netdrv_t* initialize_netdrv(); + +/** + * Create a netdriver server. This is such as a server socket which accepts connections. However this is only the creation of the server netdriver. + * + * @param drv Server's network driver. + * @param serv_type Type of server, RTI or FED. + * @return int 0 for success, -1 for failure. + */ int create_server_(netdrv_t* drv, server_type_t serv_type); #endif /* NET_DRIVER_H */ diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index e69de29bb..144a2524b 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -0,0 +1,33 @@ +#include +#include + +#include "net_driver.h" +#include "socket_common.h" +#include "util.h" +// #include "lf_socket_support.h" + +netdrv_t* initialize_netdrv() { + netdrv_t* drv = malloc(sizeof(netdrv_t)); + if (drv == NULL) { + lf_print_error_and_exit("Falied to malloc netdrv_t."); + } + // Initialize priv. + socket_priv_t* priv = malloc(sizeof(socket_priv_t)); + if (priv == NULL) { + lf_print_error_and_exit("Falied to malloc socket_priv_t."); + } + // Initialize to zero. + // memset(priv, 0, sizeof(socket_priv_t)); + + // Server initialization. + priv->port = 0; + priv->socket_descriptor = -1; + + // Federate initialization + strncpy(priv->server_hostname, "localhost", INET_ADDRSTRLEN); + priv->server_port = -1; + + // Set drv->priv pointer to point the malloc'd priv. + drv->priv = (void*)priv; + return drv; +} From 83d92bd1411b593f85595c02371edb399c72f9b5 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 16:49:21 -0700 Subject: [PATCH 008/167] Move create_server to lf_socket_support.c --- network/impl/src/lf_socket_support.c | 28 +++++++++++++ network/impl/src/socket_common.c | 59 +++++++++++++++------------- 2 files changed, 60 insertions(+), 27 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 144a2524b..ed00d51b9 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -31,3 +31,31 @@ netdrv_t* initialize_netdrv() { drv->priv = (void*)priv; return drv; } + +int create_server_(netdrv_t* drv, server_type_t serv_type) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + int socket_descriptor; + struct timeval timeout_time; + // Create an IPv4 socket for TCP. + socket_descriptor = create_real_time_tcp_socket_errexit(); + // Set the timeout time for the communications of the server + timeout_time = (struct timeval){.tv_sec = TCP_TIMEOUT_TIME / BILLION, .tv_usec = (TCP_TIMEOUT_TIME % BILLION) / 1000}; + if (socket_descriptor < 0) { + lf_print_error("Failed to create TCP socket."); + return -1; + } + set_socket_timeout_option(socket_descriptor, &timeout_time); + bool increment_port_on_retry = (serv_type == RTI) ? true : false; + + int used_port = set_socket_bind_option(socket_descriptor, priv->user_specified_port, increment_port_on_retry); + // Enable listening for socket connections. + // The second argument is the maximum number of queued socket requests, + // which according to the Mac man page is limited to 128. + if (listen(socket_descriptor, 128)) { + lf_print_error("Failed to listen on %d socket: %s.", socket_descriptor, strerror(errno)); + return -1; + } + priv->socket_descriptor = socket_descriptor; + priv->port = used_port; + return 0; +} \ No newline at end of file diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 47db27f93..f9b6311c9 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -171,33 +171,6 @@ int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket return 0; } -int create_server_(netdrv_t* drv, server_type_t serv_type) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; - int socket_descriptor; - struct timeval timeout_time; - // Create an IPv4 socket for TCP. - socket_descriptor = create_real_time_tcp_socket_errexit(); - // Set the timeout time for the communications of the server - timeout_time = (struct timeval){.tv_sec = TCP_TIMEOUT_TIME / BILLION, .tv_usec = (TCP_TIMEOUT_TIME % BILLION) / 1000}; - if (socket_descriptor < 0) { - lf_print_error("Failed to create TCP socket."); - return -1; - } - set_socket_timeout_option(socket_descriptor, &timeout_time); - bool increment_port_on_retry = (serv_type == RTI) ? true : false; - - int used_port = set_socket_bind_option(socket_descriptor, priv->user_specified_port, increment_port_on_retry); - // Enable listening for socket connections. - // The second argument is the maximum number of queued socket requests, - // which according to the Mac man page is limited to 128. - if (listen(socket_descriptor, 128)) { - lf_print_error("Failed to listen on %d socket: %s.", socket_descriptor, strerror(errno)); - return -1; - } - priv->socket_descriptor = socket_descriptor; - priv->port = used_port; - return 0; -} int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) { int socket_descriptor; @@ -263,6 +236,38 @@ int accept_socket(int socket, int rti_socket) { return socket_id; } +int accept_netdrv(netdrv_t server_drv, int rti_socket) { + struct sockaddr client_fd; + // Wait for an incoming connection request. + uint32_t client_length = sizeof(client_fd); + // The following blocks until a federate connects. + int socket_id = -1; + while (true) { + // When close(socket) is called, the accept() will return -1. + socket_id = accept(socket, &client_fd, &client_length); + if (socket_id >= 0) { + // Got a socket + break; + } else if (socket_id < 0 && (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR)) { + lf_print_warning("Failed to accept the socket. %s.", strerror(errno)); + break; + } else if (errno == EPERM) { + lf_print_error_system_failure("Firewall permissions prohibit connection."); + } else { + // For the federates, it should check if the rti_socket is still open, before retrying accept(). + if (rti_socket == -1) { + if (check_socket_closed(rti_socket)) { + break; + } + } + // Try again + lf_print_warning("Failed to accept the socket. %s. Trying again.", strerror(errno)); + continue; + } + } + return socket_id; +} + int connect_to_socket(int sock, const char* hostname, int port) { struct addrinfo hints; struct addrinfo* result; From ce9ee880d28d3b5dafad9a65025275f4b5273700 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 16:51:17 -0700 Subject: [PATCH 009/167] Fix start_rti_server() and wait_for_federates() parameters. --- core/federated/RTI/main.c | 5 ++--- core/federated/RTI/rti_remote.c | 8 +++++--- core/federated/RTI/rti_remote.h | 9 ++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/federated/RTI/main.c b/core/federated/RTI/main.c index 7a5d418cb..c2be579c9 100644 --- a/core/federated/RTI/main.c +++ b/core/federated/RTI/main.c @@ -328,9 +328,8 @@ int main(int argc, const char* argv[]) { rti.base.scheduling_nodes[i] = (scheduling_node_t*)fed_info; } - int socket_descriptor = start_rti_server(); - if (socket_descriptor >= 0) { - wait_for_federates(socket_descriptor); + if (!start_rti_server()) { + wait_for_federates(); normal_termination = true; if (rti.base.tracing_enabled) { // No need for a mutex lock because all threads have exited. diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index c900fcb90..9964cc3a1 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1477,13 +1477,14 @@ void initialize_federate(federate_info_t* fed, uint16_t id) { fed->server_port = -1; } -int32_t start_rti_server() { +int start_rti_server() { _lf_initialize_clock(); // Initialize RTI's network driver. rti_remote->rti_netdrv = initialize_netdrv(); // Create the server if (create_server_(rti_remote->rti_netdrv, RTI)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); + return -1; }; lf_print("RTI: Listening for federates."); // Create the UDP socket server @@ -1492,12 +1493,13 @@ int32_t start_rti_server() { if (create_clock_server(rti_remote->final_port_TCP + 1, &rti_remote->socket_descriptor_UDP, &rti_remote->final_port_UDP)) { lf_print_error_system_failure("RTI failed to create UDP server: %s.", strerror(errno)); + return -1; } } - return rti_remote->socket_descriptor_TCP; + return 0; } -void wait_for_federates(int socket_descriptor) { +void wait_for_federates() { // Wait for connections from federates and create a thread for each. lf_connect_to_federates(socket_descriptor); diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index bb3000cfe..2ec9b042a 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -375,17 +375,16 @@ void* respond_to_erroneous_connections(void* nothing); void initialize_federate(federate_info_t* fed, uint16_t id); /** - * Start the socket server for the runtime infrastructure (RTI) and - * return the socket descriptor. + * Start the socket server for the runtime infrastructure (RTI). + * @return 0 for success, -1 for failure. */ -int32_t start_rti_server(); +int start_rti_server(); /** * Start the runtime infrastructure (RTI) interaction with the federates * and wait for the federates to exit. - * @param socket_descriptor The socket descriptor returned by start_rti_server(). */ -void wait_for_federates(int socket_descriptor); +void wait_for_federates(); /** * Print a usage message. From f02fa2a415b887101b5fad6f7c1631038540364c Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 17:19:58 -0700 Subject: [PATCH 010/167] Start fixing lf_connect_to_federates() && add accept_netdrv() --- core/federated/RTI/rti_remote.c | 8 ++-- core/federated/RTI/rti_remote.h | 4 +- network/api/net_driver.h | 6 ++- network/api/socket_common.h | 27 +++++++++++++- network/impl/src/lf_socket_support.c | 43 ++++++++++++++++++++- network/impl/src/socket_common.c | 56 ++-------------------------- 6 files changed, 79 insertions(+), 65 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 9964cc3a1..05fb95cea 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1384,9 +1384,9 @@ static bool authenticate_federate(int* socket) { } #endif -void lf_connect_to_federates(int socket_descriptor) { +void lf_connect_to_federates(netdrv_t* rti_netdrv) { for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { - int socket_id = accept_socket(rti_remote->socket_descriptor_TCP, -1); + int socket_id = accept_netdrv(rti_remote->socket_descriptor_TCP, -1); // Wait for the first message from the federate when RTI -a option is on. #ifdef __RTI_AUTH__ if (rti_remote->authentication_enabled) { @@ -1444,7 +1444,7 @@ void* respond_to_erroneous_connections(void* nothing) { // Wait for an incoming connection request. // The following will block until either a federate attempts to connect // or shutdown_socket(rti->socket_descriptor_TCP) is called. - int socket_id = accept_socket(rti_remote->socket_descriptor_TCP, -1); + int socket_id = accept_netdrv(rti_remote->socket_descriptor_TCP, -1); if (socket_id < 0) { return NULL; } @@ -1501,7 +1501,7 @@ int start_rti_server() { void wait_for_federates() { // Wait for connections from federates and create a thread for each. - lf_connect_to_federates(socket_descriptor); + lf_connect_to_federates(rti_remote->rti_netdrv); // All federates have connected. lf_print("RTI: All expected federates have connected. Starting execution."); diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 2ec9b042a..359ce2a91 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -357,9 +357,9 @@ void send_reject(int* socket_id, unsigned char error_code); * Wait for one incoming connection request from each federate, * and upon receiving it, create a thread to communicate with * that federate. Return when all federates have connected. - * @param socket_descriptor The socket on which to accept connections. + * @param rti_netdrv The rti's network driver on which to accept connections. */ -void lf_connect_to_federates(int socket_descriptor); +void lf_connect_to_federates(netdrv_t* rti_netdrv); /** * Thread to respond to new connections, which could be federates of other diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 85880173d..833819785 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -12,8 +12,8 @@ typedef struct netdrv_t { } netdrv_t; /** - * Allocate memory for the netdriver. - * @return netdrv_t* + * Allocate memory for the network driver. + * @return netdrv_t* Initialized network driver. */ netdrv_t* initialize_netdrv(); @@ -26,4 +26,6 @@ netdrv_t* initialize_netdrv(); */ int create_server_(netdrv_t* drv, server_type_t serv_type); +netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); + #endif /* NET_DRIVER_H */ diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 7fd6c0f06..08c4770de 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -101,6 +101,24 @@ typedef struct socket_priv_t { */ int create_real_time_tcp_socket_errexit(); +/** + * Set the socket timeout options. + * @param socket_descriptor The file descriptor of the socket on which to set options. + * @param timeout_time A pointer to a `struct timeval` that specifies the timeout duration + * for socket operations (receive and send). + */ +void set_socket_timeout_option(int socket_descriptor, struct timeval* timeout_time); + +/** + * Assign a port to the socket, and bind the socket. + * + * @param socket_descriptor The file descriptor of the socket to be bound to an address and port. + * @param specified_port The port number to bind the socket to. + * @param increment_port_on_retry Boolean to retry port increment. + * @return The final port number used. + */ +int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool increment_port_on_retry); + /** * @brief Create a TCP server that listens for socket connections. * @@ -124,10 +142,15 @@ int create_real_time_tcp_socket_errexit(); int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, bool increment_port_on_retry); - - int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port); +/** + * Return true if either the socket to the RTI is broken or the socket is + * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. + * @param socket Socket to check. + */ +bool check_socket_closed(int socket); + /** * Wait for an incoming connection request on the specified server socket. * This blocks until a connection is successfully accepted. If an error occurs that is not diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index ed00d51b9..3f1cea0e4 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -1,5 +1,6 @@ -#include -#include +#include // malloc +#include // strerror +#include // errno #include "net_driver.h" #include "socket_common.h" @@ -58,4 +59,42 @@ int create_server_(netdrv_t* drv, server_type_t serv_type) { priv->socket_descriptor = socket_descriptor; priv->port = used_port; return 0; +} + +netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { + socket_priv_t* serv_priv = (socket_priv_t*)server_drv->priv; + netdrv_t* fed_netdrv = initialize_netdrv(); + socket_priv_t* fed_priv = (socket_priv_t*)fed_netdrv->priv; + + struct sockaddr client_fd; + // Wait for an incoming connection request. + uint32_t client_length = sizeof(client_fd); + // The following blocks until a federate connects. + int socket_id = -1; + while (true) { + // When close(socket) is called, the accept() will return -1. + socket_id = accept(serv_priv->socket_descriptor, &client_fd, &client_length); + if (socket_id >= 0) { + // Got a socket + break; + } else if (socket_id < 0 && (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR)) { + lf_print_warning("Failed to accept the socket. %s.", strerror(errno)); + break; + } else if (errno == EPERM) { + lf_print_error_system_failure("Firewall permissions prohibit connection."); + } else { + // For the federates, it should check if the rti_socket is still open, before retrying accept(). + socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; + if (rti_priv->socket_descriptor != -1) { + if (check_socket_closed(rti_priv->socket_descriptor)) { + break; + } + } + // Try again + lf_print_warning("Failed to accept the socket. %s. Trying again.", strerror(errno)); + continue; + } + } + fed_priv->socket_descriptor = socket_id; + return fed_netdrv; } \ No newline at end of file diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index f9b6311c9..e43181738 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -52,13 +52,7 @@ int create_real_time_tcp_socket_errexit() { return sock; } -/** - * Set the socket timeout options. - * @param socket_descriptor The file descriptor of the socket on which to set options. - * @param timeout_time A pointer to a `struct timeval` that specifies the timeout duration - * for socket operations (receive and send). - */ -static void set_socket_timeout_option(int socket_descriptor, struct timeval* timeout_time) { +void set_socket_timeout_option(int socket_descriptor, struct timeval* timeout_time) { // Set the option for this socket to reuse the same address int true_variable = 1; // setsockopt() requires a reference to the value assigned to an option if (setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &true_variable, sizeof(int32_t)) < 0) { @@ -73,15 +67,7 @@ static void set_socket_timeout_option(int socket_descriptor, struct timeval* tim } } -/** - * Assign a port to the socket, and bind the socket. - * - * @param socket_descriptor The file descriptor of the socket to be bound to an address and port. - * @param specified_port The port number to bind the socket to. - * @param increment_port_on_retry Boolean to retry port increment. - * @return The final port number used. - */ -static int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool increment_port_on_retry) { +int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool increment_port_on_retry) { // Server file descriptor. struct sockaddr_in server_fd; // Zero out the server address structure. @@ -190,11 +176,7 @@ int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) return 0; } -/** - * Return true if either the socket to the RTI is broken or the socket is - * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. - */ -static bool check_socket_closed(int socket) { +bool check_socket_closed(int socket) { unsigned char first_byte; ssize_t bytes = peek_from_socket(socket, &first_byte); if (bytes < 0 || (bytes == 1 && first_byte == MSG_TYPE_FAILED)) { @@ -236,38 +218,6 @@ int accept_socket(int socket, int rti_socket) { return socket_id; } -int accept_netdrv(netdrv_t server_drv, int rti_socket) { - struct sockaddr client_fd; - // Wait for an incoming connection request. - uint32_t client_length = sizeof(client_fd); - // The following blocks until a federate connects. - int socket_id = -1; - while (true) { - // When close(socket) is called, the accept() will return -1. - socket_id = accept(socket, &client_fd, &client_length); - if (socket_id >= 0) { - // Got a socket - break; - } else if (socket_id < 0 && (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR)) { - lf_print_warning("Failed to accept the socket. %s.", strerror(errno)); - break; - } else if (errno == EPERM) { - lf_print_error_system_failure("Firewall permissions prohibit connection."); - } else { - // For the federates, it should check if the rti_socket is still open, before retrying accept(). - if (rti_socket == -1) { - if (check_socket_closed(rti_socket)) { - break; - } - } - // Try again - lf_print_warning("Failed to accept the socket. %s. Trying again.", strerror(errno)); - continue; - } - } - return socket_id; -} - int connect_to_socket(int sock, const char* hostname, int port) { struct addrinfo hints; struct addrinfo* result; From 839f58bb5b032f20aedc7243cd20ee3d32060aa5 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 17:35:05 -0700 Subject: [PATCH 011/167] Fix lf_connect_to_federates() to use network drivers. --- core/federated/RTI/rti_remote.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 05fb95cea..172a931bd 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1016,11 +1016,12 @@ void send_reject(int* socket_id, unsigned char error_code) { * a federate ID and a federation ID. If the federation ID * matches this federation, send an MSG_TYPE_ACK and otherwise send * a MSG_TYPE_REJECT message. - * @param socket_id Pointer to the socket on which to listen. + * @param fed_netdrv Pointer to the network driver on which to listen. * @param client_fd The socket address. * @return The federate ID for success or -1 for failure. */ -static int32_t receive_and_check_fed_id_message(int* socket_id) { +// TODO: Check. +static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { // Buffer for message ID, federate ID, and federation ID length. size_t length = 1 + sizeof(uint16_t) + 1; // Message ID, federate ID, length of fedration ID. unsigned char buffer[length]; @@ -1159,7 +1160,8 @@ static int32_t receive_and_check_fed_id_message(int* socket_id) { * out the relevant information in the federate's struct. * @return 1 on success and 0 on failure. */ -static int receive_connection_information(int* socket_id, uint16_t fed_id) { +//TODO: Check. +static int receive_connection_information(netdrv_t* fed_netdrv, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; read_from_socket_fail_on_error(socket_id, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, NULL, @@ -1238,11 +1240,11 @@ static int receive_connection_information(int* socket_id, uint16_t fed_id) { * up to perform runtime clock synchronization using the UDP port number * specified in the payload to communicate with the federate's clock * synchronization logic. - * @param socket_id The socket on which to listen. + * @param fed_netdrv The network driver on which to listen. * @param fed_id The federate ID. * @return 1 for success, 0 for failure. */ -static int receive_udp_message_and_set_up_clock_sync(int* socket_id, uint16_t fed_id) { +static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint16_t fed_id) { // Read the MSG_TYPE_UDP_PORT message from the federate regardless of the status of // clock synchronization. This message will tell the RTI whether the federate // is doing clock synchronization, and if it is, what port to use for UDP. @@ -1318,10 +1320,11 @@ static int receive_udp_message_and_set_up_clock_sync(int* socket_id, uint16_t fe /** * Authenticate incoming federate by performing HMAC-based authentication. * - * @param socket Socket for the incoming federate tryting to authenticate. + * @param fed_netdrv Network driver for the incoming federate tryting to authenticate. * @return True if authentication is successful and false otherwise. */ -static bool authenticate_federate(int* socket) { +//TODO: Fix. +static bool authenticate_federate(netdrv_t* fed_netdrv) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); unsigned char buffer[1 + fed_id_length + NONCE_LENGTH]; @@ -1386,13 +1389,14 @@ static bool authenticate_federate(int* socket) { void lf_connect_to_federates(netdrv_t* rti_netdrv) { for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { - int socket_id = accept_netdrv(rti_remote->socket_descriptor_TCP, -1); + netdrv_t* fed_netdrv = accept_netdrv(rti_netdrv, NULL); // Wait for the first message from the federate when RTI -a option is on. #ifdef __RTI_AUTH__ if (rti_remote->authentication_enabled) { - if (!authenticate_federate(&socket_id)) { + if (!authenticate_federate(fed_netdrv)) { lf_print_warning("RTI failed to authenticate the incoming federate."); // Close the socket without reading until EOF. + //TODO: Check. shutdown_socket(&socket_id, false); // Ignore the federate that failed authentication. i--; @@ -1402,9 +1406,9 @@ void lf_connect_to_federates(netdrv_t* rti_netdrv) { #endif // The first message from the federate should contain its ID and the federation ID. - int32_t fed_id = receive_and_check_fed_id_message(&socket_id); - if (fed_id >= 0 && socket_id >= 0 && receive_connection_information(&socket_id, (uint16_t)fed_id) && - receive_udp_message_and_set_up_clock_sync(&socket_id, (uint16_t)fed_id)) { + int32_t fed_id = receive_and_check_fed_id_message(fed_netdrv); + if (fed_id >= 0 && receive_connection_information(fed_netdrv, (uint16_t)fed_id) && + receive_udp_message_and_set_up_clock_sync(fed_netdrv, (uint16_t)fed_id)) { // Create a thread to communicate with the federate. // This has to be done after clock synchronization is finished @@ -1444,10 +1448,7 @@ void* respond_to_erroneous_connections(void* nothing) { // Wait for an incoming connection request. // The following will block until either a federate attempts to connect // or shutdown_socket(rti->socket_descriptor_TCP) is called. - int socket_id = accept_netdrv(rti_remote->socket_descriptor_TCP, -1); - if (socket_id < 0) { - return NULL; - } + netdrv_t* fed_netdrv = accept_netdrv(rti_remote->rti_netdrv, NULL); if (rti_remote->all_federates_exited) { return NULL; } From 6d03173dffec508202d570dc1fcb9500dfa5c406 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 17:58:43 -0700 Subject: [PATCH 012/167] Add read() write() shutdown() functions using netdrver --- network/api/net_driver.h | 107 ++++++++++++++++- network/impl/src/lf_socket_support.c | 164 ++++++++++++++++++++++++++- 2 files changed, 266 insertions(+), 5 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 833819785..fe04dbefd 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -18,8 +18,9 @@ typedef struct netdrv_t { netdrv_t* initialize_netdrv(); /** - * Create a netdriver server. This is such as a server socket which accepts connections. However this is only the creation of the server netdriver. - * + * Create a netdriver server. This is such as a server socket which accepts connections. However this is only the + * creation of the server netdriver. + * * @param drv Server's network driver. * @param serv_type Type of server, RTI or FED. * @return int 0 for success, -1 for failure. @@ -28,4 +29,106 @@ int create_server_(netdrv_t* drv, server_type_t serv_type); netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); +/** + * Read the specified number of bytes from the specified socket into the specified buffer. + * If an error occurs during this reading, return -1 and set errno to indicate + * the cause of the error. If the read succeeds in reading the specified number of bytes, + * return 0. If an EOF occurs before reading the specified number of bytes, return 1. + * This function repeats the read attempt until the specified number of bytes + * have been read, an EOF is read, or an error occurs. Specifically, errors EAGAIN, + * EWOULDBLOCK, and EINTR are not considered errors and instead trigger + * another attempt. A delay between attempts is given by DELAY_BETWEEN_SOCKET_RETRIES. + * @param drv The socket ID. + * @param num_bytes The number of bytes to read. + * @param buffer The buffer into which to put the bytes. + * @return 0 for success, 1 for EOF, and -1 for an error. + */ +int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); + +/** + * Read the specified number of bytes to the specified socket using read_from_socket + * and close the socket if an error occurs. If an error occurs, this will change the + * socket ID pointed to by the first argument to -1 and will return -1. + * @param socket Pointer to the socket ID. + * @param num_bytes The number of bytes to write. + * @param buffer The buffer from which to get the bytes. + * @return 0 for success, -1 for failure. + */ +int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); + +/** + * Read the specified number of bytes from the specified socket into the + * specified buffer. If a disconnect or an EOF occurs during this + * reading, then if format is non-null, report an error and exit. + * If the mutex argument is non-NULL, release the mutex before exiting. + * If format is null, then report the error, but do not exit. + * This function takes a formatted string and additional optional arguments + * similar to printf(format, ...) that is appended to the error messages. + * @param drv The socket ID. + * @param num_bytes The number of bytes to read. + * @param buffer The buffer into which to put the bytes. + * @param format A printf-style format string, followed by arguments to + * fill the string, or NULL to not exit with an error message. + * @return The number of bytes read, or 0 if an EOF is received, or + * a negative number for an error. + */ +void read_from_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, + char* format, ...); + +/** + * Write the specified number of bytes to the specified socket from the + * specified buffer. If an error occurs, return -1 and set errno to indicate + * the cause of the error. If the write succeeds, return 0. + * This function repeats the attempt until the specified number of bytes + * have been written or an error occurs. Specifically, errors EAGAIN, + * EWOULDBLOCK, and EINTR are not considered errors and instead trigger + * another attempt. A delay between attempts is given by + * DELAY_BETWEEN_SOCKET_RETRIES. + * @param drv The socket ID. + * @param num_bytes The number of bytes to write. + * @param buffer The buffer from which to get the bytes. + * @return 0 for success, -1 for failure. + */ +int write_to_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); + +/** + * Write the specified number of bytes to the specified socket using write_to_socket + * and close the socket if an error occurs. If an error occurs, this will change the + * socket ID pointed to by the first argument to -1 and will return -1. + * @param drv Pointer to the socket ID. + * @param num_bytes The number of bytes to write. + * @param buffer The buffer from which to get the bytes. + * @return 0 for success, -1 for failure. + */ +int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); + +/** + * Write the specified number of bytes to the specified socket using + * write_to_socket_close_on_error and exit with an error code if an error occurs. + * If the mutex argument is non-NULL, release the mutex before exiting. If the + * format argument is non-null, then use it an any additional arguments to form + * the error message using printf conventions. Otherwise, print a generic error + * message. + * @param drv Pointer to the socket ID. + * @param num_bytes The number of bytes to write. + * @param buffer The buffer from which to get the bytes. + * @param mutex If non-NULL, the mutex to unlock before exiting. + * @param format A format string for error messages, followed by any number of + * fields that will be used to fill the format string as in printf, or NULL + * to print a generic error message. + */ +void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, + char* format, ...); + +/** + * @brief Gracefully shuts down and closes a socket, optionally reading until EOF. + * Shutdown and close the socket. If read_before_closing is false, it just immediately calls shutdown() with SHUT_RDWR + * and close(). If read_before_closing is true, it calls shutdown with SHUT_WR, only disallowing further writing. Then, + * it calls read() until EOF is received, and discards all received bytes. + * @param drv Pointer to the socket descriptor to shutdown and close. + * @param read_before_closing If true, read until EOF before closing the socket. + * @return int Returns 0 on success, -1 on failure (errno will indicate the error). + */ +int shutdown_netdrv(netdrv_t* drv, bool read_before_closing); + #endif /* NET_DRIVER_H */ diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 3f1cea0e4..10ec1ba59 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -1,6 +1,7 @@ -#include // malloc -#include // strerror +#include // malloc() +#include // strerror() #include // errno +#include // read() write() #include "net_driver.h" #include "socket_common.h" @@ -97,4 +98,161 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { } fed_priv->socket_descriptor = socket_id; return fed_netdrv; -} \ No newline at end of file +} + +int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + int socket = priv->socket_descriptor; + if (socket < 0) { + // Socket is not open. + errno = EBADF; + return -1; + } + ssize_t bytes_read = 0; + while (bytes_read < (ssize_t)num_bytes) { + ssize_t more = read(socket, buffer + bytes_read, num_bytes - (size_t)bytes_read); + if (more < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) { + // Those error codes set by the socket indicates + // that we should try again (@see man errno). + LF_PRINT_DEBUG("Reading from socket %d failed with error: `%s`. Will try again.", socket, strerror(errno)); + lf_sleep(DELAY_BETWEEN_SOCKET_RETRIES); + continue; + } else if (more < 0) { + // A more serious error occurred. + lf_print_error("Reading from socket %d failed. With error: `%s`", socket, strerror(errno)); + return -1; + } else if (more == 0) { + // EOF received. + return 1; + } + bytes_read += more; + } + return 0; +} + +int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { + int read_failed = read_from_netdrv(drv, num_bytes, buffer); + if (read_failed) { + // Read failed. + // Socket has probably been closed from the other side. + // Shut down and close the socket from this side. + shutdown_netdrv(drv, false); + return -1; + } + return 0; +} + +void read_from_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, + char* format, ...) { + va_list args; + int read_failed = read_from_netdrv_close_on_error(drv, num_bytes, buffer); + if (read_failed) { + // Read failed. + if (mutex != NULL) { + LF_MUTEX_UNLOCK(mutex); + } + if (format != NULL) { + va_start(args, format); + lf_print_error_system_failure(format, args); + va_end(args); + } else { + lf_print_error_system_failure("Failed to read from socket."); + } + } +} + +int write_to_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + int socket = priv->socket_descriptor; + if (socket < 0) { + // Socket is not open. + errno = EBADF; + return -1; + } + ssize_t bytes_written = 0; + while (bytes_written < (ssize_t)num_bytes) { + ssize_t more = write(socket, buffer + bytes_written, num_bytes - (size_t)bytes_written); + if (more <= 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) { + // The error codes EAGAIN or EWOULDBLOCK indicate + // that we should try again (@see man errno). + // The error code EINTR means the system call was interrupted before completing. + LF_PRINT_DEBUG("Writing to socket %d was blocked. Will try again.", socket); + lf_sleep(DELAY_BETWEEN_SOCKET_RETRIES); + continue; + } else if (more < 0) { + // A more serious error occurred. + lf_print_error("Writing to socket %d failed. With error: `%s`", socket, strerror(errno)); + return -1; + } + bytes_written += more; + } + return 0; +} + +int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { + int result = write_to_netdrv(drv, num_bytes, buffer); + if (result) { + // Write failed. + // Socket has probably been closed from the other side. + // Shut down and close the socket from this side. + shutdown_netdrv(drv, false); + } + return result; +} + +void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, + char* format, ...) { + va_list args; + int result = write_to_netdrv_close_on_error(drv, num_bytes, buffer); + if (result) { + // Write failed. + if (mutex != NULL) { + LF_MUTEX_UNLOCK(mutex); + } + if (format != NULL) { + va_start(args, format); + lf_print_error_system_failure(format, args); + va_end(args); + } else { + lf_print_error("Failed to write to socket. Closing it."); + } + } +} + +int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + if (!read_before_closing) { + if (shutdown(priv->socket_descriptor, SHUT_RDWR)) { + lf_print_log("On shutdown socket, received reply: %s", strerror(errno)); + return -1; + } + } else { + // Signal the other side that no further writes are expected by sending a FIN packet. + // This indicates the write direction is closed. For more details, refer to: + // https://stackoverflow.com/questions/4160347/close-vs-shutdown-socket + if (shutdown(priv->socket_descriptor, SHUT_WR)) { + lf_print_log("Failed to shutdown socket: %s", strerror(errno)); + return -1; + } + + // Wait for the other side to send an EOF or encounter a socket error. + // Discard any incoming bytes. Normally, this read should return 0, indicating the peer has also closed the + // connection. + // This compensates for delayed ACKs and scenarios where Nagle's algorithm is disabled, ensuring the shutdown + // completes gracefully. + unsigned char buffer[10]; + while (read(priv->socket_descriptor, buffer, 10) > 0) + ; + } + // NOTE: In all common TCP/IP stacks, there is a time period, + // typically between 30 and 120 seconds, called the TIME_WAIT period, + // before the port is released after this close. This is because + // the OS is preventing another program from accidentally receiving + // duplicated packets intended for this program. + if (close(priv->socket_descriptor)) { + lf_print_log("Error while closing socket: %s\n", strerror(errno)); + return -1; + } + priv->socket_descriptor = -1; + return 0; +} From 9726b8602c9b4204d48486d765b87847ea4a8489 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 21:09:58 -0700 Subject: [PATCH 013/167] Fix send_reject() read() write() shutdown() functions on remote.c && Formatting. --- core/federated/RTI/rti_remote.c | 73 +++++++++++++-------------------- core/federated/RTI/rti_remote.h | 22 ++++------ network/api/socket_common.h | 6 +-- 3 files changed, 41 insertions(+), 60 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 172a931bd..c9736e7eb 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -996,18 +996,18 @@ void* federate_info_thread_TCP(void* fed) { return NULL; } -void send_reject(int* socket_id, unsigned char error_code) { +void send_reject(netdrv_t* drv, unsigned char error_code) { LF_PRINT_DEBUG("RTI sending MSG_TYPE_REJECT."); unsigned char response[2]; response[0] = MSG_TYPE_REJECT; response[1] = error_code; LF_MUTEX_LOCK(&rti_mutex); // NOTE: Ignore errors on this response. - if (write_to_socket(*socket_id, 2, response)) { + if (write_to_netdrv(drv, 2, response)) { lf_print_warning("RTI failed to write MSG_TYPE_REJECT message on the socket."); } // Close the socket without reading until EOF. - shutdown_socket(socket_id, false); + shutdown_netdrv(drv, false); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -1020,14 +1020,13 @@ void send_reject(int* socket_id, unsigned char error_code) { * @param client_fd The socket address. * @return The federate ID for success or -1 for failure. */ -// TODO: Check. static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { // Buffer for message ID, federate ID, and federation ID length. size_t length = 1 + sizeof(uint16_t) + 1; // Message ID, federate ID, length of fedration ID. unsigned char buffer[length]; // Read bytes from the socket. We need 4 bytes. - if (read_from_socket_close_on_error(socket_id, length, buffer)) { + if (read_from_netdrv_close_on_error(fed_netdrv, length, buffer)) { lf_print_error("RTI failed to read from accepted socket."); return -1; } @@ -1047,12 +1046,12 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { // of the peer they want to connect to from the RTI. // If the connection is a peer-to-peer connection between two // federates, reject the connection with the WRONG_SERVER error. - send_reject(socket_id, WRONG_SERVER); + send_reject(fed_netdrv, WRONG_SERVER); } else if (buffer[0] == MSG_TYPE_FED_NONCE) { - send_reject(socket_id, RTI_NOT_EXECUTED_WITH_AUTH); + send_reject(fed_netdrv, RTI_NOT_EXECUTED_WITH_AUTH); lf_print_error("RTI not executed with HMAC authentication option using -a or --auth."); } else { - send_reject(socket_id, UNEXPECTED_MESSAGE); + send_reject(fed_netdrv, UNEXPECTED_MESSAGE); } lf_print_error("RTI expected a MSG_TYPE_FED_IDS message. Got %u (see net_common.h).", buffer[0]); return -1; @@ -1065,7 +1064,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { size_t federation_id_length = (size_t)buffer[sizeof(uint16_t) + 1]; char federation_id_received[federation_id_length + 1]; // One extra for null terminator. // Next read the actual federation ID. - if (read_from_socket_close_on_error(socket_id, federation_id_length, (unsigned char*)federation_id_received)) { + if (read_from_netdrv_close_on_error(fed_netdrv, federation_id_length, (unsigned char*)federation_id_received)) { lf_print_error("RTI failed to read federation id from federate %d.", fed_id); return -1; } @@ -1086,7 +1085,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(socket_id, FEDERATION_ID_DOES_NOT_MATCH); + send_reject(fed_netdrv, FEDERATION_ID_DOES_NOT_MATCH); return -1; } else { if (fed_id >= rti_remote->base.number_of_scheduling_nodes) { @@ -1095,7 +1094,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(socket_id, FEDERATE_ID_OUT_OF_RANGE); + send_reject(fed_netdrv, FEDERATE_ID_OUT_OF_RANGE); return -1; } else { if ((rti_remote->base.scheduling_nodes[fed_id])->state != NOT_CONNECTED) { @@ -1103,7 +1102,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(socket_id, FEDERATE_ID_IN_USE); + send_reject(fed_netdrv, FEDERATE_ID_IN_USE); return -1; } } @@ -1113,23 +1112,10 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { // The MSG_TYPE_FED_IDS message has the right federation ID. // Get the peer address from the connected socket_id. Then assign it as the federate's socket server. - struct sockaddr_in peer_addr; - socklen_t addr_len = sizeof(peer_addr); - if (getpeername(*socket_id, (struct sockaddr*)&peer_addr, &addr_len) != 0) { + if(get_peer_address(fed_netdrv) != 0) { lf_print_error("RTI failed to get peer address."); - } - fed->server_ip_addr = peer_addr.sin_addr; - -#if LOG_LEVEL >= LOG_LEVEL_DEBUG - // Create the human readable format and copy that into - // the .server_hostname field of the federate. - char str[INET_ADDRSTRLEN + 1]; - inet_ntop(AF_INET, &fed->server_ip_addr, str, INET_ADDRSTRLEN); - strncpy(fed->server_hostname, str, INET_ADDRSTRLEN); - - LF_PRINT_DEBUG("RTI got address %s from federate %d.", fed->server_hostname, fed_id); -#endif - fed->socket = *socket_id; + }; + fed->fed_netdrv = fed_netdrv; // Set the federate's state as pending // because it is waiting for the start time to be @@ -1164,7 +1150,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { static int receive_connection_information(netdrv_t* fed_netdrv, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; - read_from_socket_fail_on_error(socket_id, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, NULL, + read_from_netdrv_fail_on_error(fed_netdrv, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, NULL, "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message header from federate %d.", fed_id); @@ -1172,7 +1158,7 @@ static int receive_connection_information(netdrv_t* fed_netdrv, uint16_t fed_id) lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", fed_id, connection_info_header[0]); - send_reject(socket_id, UNEXPECTED_MESSAGE); + send_reject(fed_netdrv, UNEXPECTED_MESSAGE); return 0; } else { federate_info_t* fed = GET_FED_INFO(fed_id); @@ -1206,7 +1192,7 @@ static int receive_connection_information(netdrv_t* fed_netdrv, uint16_t fed_id) if (connections_info_body_size > 0) { connections_info_body = (unsigned char*)malloc(connections_info_body_size); LF_ASSERT_NON_NULL(connections_info_body); - read_from_socket_fail_on_error(socket_id, connections_info_body_size, connections_info_body, NULL, + read_from_netdrv_fail_on_error(fed_netdrv, connections_info_body_size, connections_info_body, NULL, "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message body from federate %d.", fed_id); // Keep track of where we are in the buffer @@ -1250,13 +1236,13 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 // is doing clock synchronization, and if it is, what port to use for UDP. LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_UDP_PORT from federate %d.", fed_id); unsigned char response[1 + sizeof(uint16_t)]; - read_from_socket_fail_on_error(socket_id, 1 + sizeof(uint16_t), response, NULL, + read_from_netdrv_fail_on_error(fed_netdrv, 1 + sizeof(uint16_t), response, NULL, "RTI failed to read MSG_TYPE_UDP_PORT message from federate %d.", fed_id); if (response[0] != MSG_TYPE_UDP_PORT) { lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", fed_id, response[0]); - send_reject(socket_id, UNEXPECTED_MESSAGE); + send_reject(fed_netdrv, UNEXPECTED_MESSAGE); return 0; } else { federate_info_t* fed = GET_FED_INFO(fed_id); @@ -1277,7 +1263,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); unsigned char buffer[message_size]; - read_from_socket_fail_on_error(socket_id, message_size, buffer, NULL, + read_from_netdrv_fail_on_error(fed_netdrv, message_size, buffer, NULL, "Socket to federate %d unexpectedly closed.", fed_id); if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); @@ -1285,7 +1271,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 handle_physical_clock_sync_message(fed, TCP); } else { lf_print_error("Unexpected message %u from federate %d.", buffer[0], fed_id); - send_reject(socket_id, UNEXPECTED_MESSAGE); + send_reject(fed_netdrv, UNEXPECTED_MESSAGE); return 0; } } @@ -1328,7 +1314,7 @@ static bool authenticate_federate(netdrv_t* fed_netdrv) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); unsigned char buffer[1 + fed_id_length + NONCE_LENGTH]; - read_from_socket_fail_on_error(socket, 1 + fed_id_length + NONCE_LENGTH, buffer, NULL, + read_from_netdrv_fail_on_error(fed_netdrv, 1 + fed_id_length + NONCE_LENGTH, buffer, NULL, "Failed to read MSG_TYPE_FED_NONCE"); if (buffer[0] != MSG_TYPE_FED_NONCE) { lf_print_error_and_exit("Received unexpected response %u from the FED (see net_common.h).", buffer[0]); @@ -1353,13 +1339,13 @@ static bool authenticate_federate(netdrv_t* fed_netdrv) { RAND_bytes(rti_nonce, NONCE_LENGTH); memcpy(&sender[1], rti_nonce, NONCE_LENGTH); memcpy(&sender[1 + NONCE_LENGTH], hmac_tag, hmac_length); - if (write_to_socket(*socket, 1 + NONCE_LENGTH + hmac_length, sender)) { + if (write_to_netdrv(fed_netdrv, 1 + NONCE_LENGTH + hmac_length, sender)) { lf_print_error("Failed to send nonce to federate."); } // Wait for MSG_TYPE_FED_RESPONSE unsigned char received[1 + hmac_length]; - read_from_socket_fail_on_error(socket, 1 + hmac_length, received, NULL, "Failed to read federate response."); + read_from_netdrv_fail_on_error(fed_netdrv, 1 + hmac_length, received, NULL, "Failed to read federate response."); if (received[0] != MSG_TYPE_FED_RESPONSE) { lf_print_error_and_exit("Received unexpected response %u from the federate (see net_common.h).", received[0]); return false; @@ -1378,7 +1364,7 @@ static bool authenticate_federate(netdrv_t* fed_netdrv) { if (memcmp(&received[1], rti_tag, hmac_length) != 0) { // Federation IDs do not match. Send back a HMAC_DOES_NOT_MATCH message. lf_print_warning("HMAC authentication failed. Rejecting the federate."); - send_reject(socket, HMAC_DOES_NOT_MATCH); + send_reject(fed_netdrv, HMAC_DOES_NOT_MATCH); return false; } else { LF_PRINT_LOG("Federate's HMAC verified."); @@ -1396,8 +1382,7 @@ void lf_connect_to_federates(netdrv_t* rti_netdrv) { if (!authenticate_federate(fed_netdrv)) { lf_print_warning("RTI failed to authenticate the incoming federate."); // Close the socket without reading until EOF. - //TODO: Check. - shutdown_socket(&socket_id, false); + shutdown_netdrv(fed_netdrv, false); // Ignore the federate that failed authentication. i--; continue; @@ -1458,11 +1443,11 @@ void* respond_to_erroneous_connections(void* nothing) { response[0] = MSG_TYPE_REJECT; response[1] = FEDERATION_ID_DOES_NOT_MATCH; // Ignore errors on this response. - if (write_to_socket(socket_id, 2, response)) { + if (write_to_netdrv(fed_netdrv, 2, response)) { lf_print_warning("RTI failed to write FEDERATION_ID_DOES_NOT_MATCH to erroneous incoming connection."); } // Close the socket without reading until EOF. - shutdown_socket(&socket_id, false); + shutdown_netdrv(fed_netdrv, false); } return NULL; } @@ -1529,7 +1514,7 @@ void wait_for_federates() { // Shutdown and close the socket that is listening for incoming connections // so that the accept() call in respond_to_erroneous_connections returns. // That thread should then check rti->all_federates_exited and it should exit. - shutdown_socket(&socket_descriptor, false); + shutdown_netdrv(rti_remote->rti_netdrv, false); if (rti_remote->socket_descriptor_UDP > 0) { shutdown_socket(&rti_remote->socket_descriptor_UDP, false); diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 359ce2a91..c29d0d53b 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -49,10 +49,13 @@ */ typedef struct federate_info_t { scheduling_node_t enclave; - bool requested_stop; // Indicates that the federate has requested stop or has replied - // to a request for stop from the RTI. Used to prevent double-counting - // a federate when handling lf_request_stop(). - lf_thread_t thread_id; // The ID of the thread handling communication with this federate. + bool requested_stop; // Indicates that the federate has requested stop or has replied + // to a request for stop from the RTI. Used to prevent double-counting + // a federate when handling lf_request_stop(). + lf_thread_t thread_id; // The ID of the thread handling communication with this federate. + + netdrv_t* fed_netdrv; // The netdriver that the RTI handling each federate. + int socket; // The TCP socket descriptor for communicating with this federate. struct sockaddr_in UDP_addr; // The UDP address for the federate. bool clock_synchronization_enabled; // Indicates the status of clock synchronization @@ -60,13 +63,6 @@ typedef struct federate_info_t { pqueue_tag_t* in_transit_message_tags; // Record of in-transit messages to this federate that are not // yet processed. This record is ordered based on the time // value of each message for a more efficient access. - char server_hostname[INET_ADDRSTRLEN]; // Human-readable IP address and - int32_t server_port; // port number of the socket server of the federate - // if it has any incoming direct connections from other federates. - // The port number will be -1 if there is no server or if the - // RTI has not been informed of the port number. - struct in_addr server_ip_addr; // Information about the IP address of the socket - // server of the federate. } federate_info_t; /** @@ -348,10 +344,10 @@ void* federate_info_thread_TCP(void* fed); /** * Send a MSG_TYPE_REJECT message to the specified socket and close the socket. - * @param socket_id Pointer to the socket ID. + * @param drv Pointer to the network driver. * @param error_code An error code. */ -void send_reject(int* socket_id, unsigned char error_code); +void send_reject(netdrv_t* drv, unsigned char error_code); /** * Wait for one incoming connection request from each federate, diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 08c4770de..7e52c06a1 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -77,10 +77,10 @@ extern lf_mutex_t socket_mutex; typedef struct socket_priv_t { int socket_descriptor; - uint16_t port; // my port number // TODO: Only used in federate.c to send federate's port. - uint16_t user_specified_port; + uint16_t port; // The port number. // TODO: Only used in federate.c to send federate's port. + uint16_t user_specified_port; // Default as 0 for both RTI and federate. - // The connected other side's info. + // The connected other side's info. The char server_hostname[INET_ADDRSTRLEN]; // Human-readable IP address and int32_t server_port; // port number of the socket server of the federate // if it has any incoming direct connections from other federates. From 418d2c9e5e08994236aca1746d43a1d077fb966e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 21:21:28 -0700 Subject: [PATCH 014/167] Add get_peer_address() --- core/federated/RTI/rti_remote.c | 6 +++--- network/impl/src/lf_socket_support.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index c9736e7eb..d9e6e7840 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1112,7 +1112,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { // The MSG_TYPE_FED_IDS message has the right federation ID. // Get the peer address from the connected socket_id. Then assign it as the federate's socket server. - if(get_peer_address(fed_netdrv) != 0) { + if (get_peer_address(fed_netdrv) != 0) { lf_print_error("RTI failed to get peer address."); }; fed->fed_netdrv = fed_netdrv; @@ -1146,7 +1146,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { * out the relevant information in the federate's struct. * @return 1 on success and 0 on failure. */ -//TODO: Check. +// TODO: Check. static int receive_connection_information(netdrv_t* fed_netdrv, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; @@ -1309,7 +1309,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 * @param fed_netdrv Network driver for the incoming federate tryting to authenticate. * @return True if authentication is successful and false otherwise. */ -//TODO: Fix. +// TODO: Fix. static bool authenticate_federate(netdrv_t* fed_netdrv) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 10ec1ba59..31c95859b 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -100,6 +100,26 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { return fed_netdrv; } +int get_peer_address(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + struct sockaddr_in peer_addr; + socklen_t addr_len = sizeof(peer_addr); + if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { + lf_print_error("RTI failed to get peer address."); + } + priv->server_ip_addr = peer_addr.sin_addr; + +#if LOG_LEVEL >= LOG_LEVEL_DEBUG + // Create the human readable format and copy that into + // the .server_hostname field of the federate. + char str[INET_ADDRSTRLEN + 1]; + inet_ntop(AF_INET, priv->server_ip_addr, str, INET_ADDRSTRLEN); + strncpy(priv->server_hostname, str, INET_ADDRSTRLEN); + + LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); +#endif +} + int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = (socket_priv_t*)drv->priv; int socket = priv->socket_descriptor; From 32975a635c78bfba796c9c714cd4dba26989e684 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 21:33:21 -0700 Subject: [PATCH 015/167] Minor fix on not using server_ip_addr --- network/impl/src/lf_socket_support.c | 1 + 1 file changed, 1 insertion(+) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 31c95859b..4d286df26 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -27,6 +27,7 @@ netdrv_t* initialize_netdrv() { // Federate initialization strncpy(priv->server_hostname, "localhost", INET_ADDRSTRLEN); + priv->server_ip_addr.s_addr = 0; priv->server_port = -1; // Set drv->priv pointer to point the malloc'd priv. From 7922ae128d85ef26ab62fade48eb83565baef30b Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 21:33:21 -0700 Subject: [PATCH 016/167] Minor fix on not using server_ip_addr --- core/federated/RTI/rti_remote.c | 12 +++++------- network/api/net_driver.h | 2 ++ network/impl/src/lf_socket_support.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index d9e6e7840..bd222c9c6 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1146,7 +1146,6 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { * out the relevant information in the federate's struct. * @return 1 on success and 0 on failure. */ -// TODO: Check. static int receive_connection_information(netdrv_t* fed_netdrv, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; @@ -1283,7 +1282,11 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 // Initialize the UDP_addr field of the federate struct fed->UDP_addr.sin_family = AF_INET; fed->UDP_addr.sin_port = htons(federate_UDP_port_number); - fed->UDP_addr.sin_addr = fed->server_ip_addr; + #ifdef COMM_TYPE_TCP + fed->UDP_addr.sin_addr = ((socket_priv_t*)fed_netdrv->priv)->server_ip_addr; + // fed->UDP_addr.sin_addr = fed->server_ip_addr; + #elif + #endif } } else { // Disable clock sync after initial round. @@ -1309,7 +1312,6 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 * @param fed_netdrv Network driver for the incoming federate tryting to authenticate. * @return True if authentication is successful and false otherwise. */ -// TODO: Fix. static bool authenticate_federate(netdrv_t* fed_netdrv) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); @@ -1455,12 +1457,8 @@ void* respond_to_erroneous_connections(void* nothing) { void initialize_federate(federate_info_t* fed, uint16_t id) { initialize_scheduling_node(&(fed->enclave), id); fed->requested_stop = false; - fed->socket = -1; // No socket. fed->clock_synchronization_enabled = true; fed->in_transit_message_tags = pqueue_tag_init(10); - strncpy(fed->server_hostname, "localhost", INET_ADDRSTRLEN); - fed->server_ip_addr.s_addr = 0; - fed->server_port = -1; } int start_rti_server() { diff --git a/network/api/net_driver.h b/network/api/net_driver.h index fe04dbefd..362efd3f0 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -29,6 +29,8 @@ int create_server_(netdrv_t* drv, server_type_t serv_type); netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); +int get_peer_address(netdrv_t* drv); + /** * Read the specified number of bytes from the specified socket into the specified buffer. * If an error occurs during this reading, return -1 and set errno to indicate diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 31c95859b..4d286df26 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -27,6 +27,7 @@ netdrv_t* initialize_netdrv() { // Federate initialization strncpy(priv->server_hostname, "localhost", INET_ADDRSTRLEN); + priv->server_ip_addr.s_addr = 0; priv->server_port = -1; // Set drv->priv pointer to point the malloc'd priv. From 170f923809108363fe0d4d5034746bdeeeb72751 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 21:36:19 -0700 Subject: [PATCH 017/167] Formatting on ifdefs. --- core/federated/RTI/rti_remote.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index bd222c9c6..87630141c 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1282,11 +1282,11 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 // Initialize the UDP_addr field of the federate struct fed->UDP_addr.sin_family = AF_INET; fed->UDP_addr.sin_port = htons(federate_UDP_port_number); - #ifdef COMM_TYPE_TCP +#ifdef COMM_TYPE_TCP fed->UDP_addr.sin_addr = ((socket_priv_t*)fed_netdrv->priv)->server_ip_addr; - // fed->UDP_addr.sin_addr = fed->server_ip_addr; - #elif - #endif +// fed->UDP_addr.sin_addr = fed->server_ip_addr; +#elif +#endif } } else { // Disable clock sync after initial round. From 5f3d831ee20e438325945bfdfff345028e4c2ca4 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 22:51:17 -0700 Subject: [PATCH 018/167] Fix handle_address_query to combine the message and write() it in once. && Change all read() write(), and shutdown() to use netdrv --- core/federated/RTI/rti_remote.c | 87 ++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 87630141c..5d2693a96 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -73,9 +73,10 @@ void notify_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_TAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the socket might close, causing the following write_to_socket + // function. During this call, the socket might close, causing the following write_to_netdrv // to fail. Consider a failure here a soft failure and update the federate's status. - if (write_to_socket(((federate_info_t*)e)->socket, message_length, buffer)) { + // TODO: Check if works well. + if (write_to_netdrv(((federate_info_t*)e)->fed_netdrv, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -106,9 +107,9 @@ void notify_provisional_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_PTAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the socket might close, causing the following write_to_socket + // function. During this call, the socket might close, causing the following write_to_netdrv // to fail. Consider a failure here a soft failure and update the federate's status. - if (write_to_socket(((federate_info_t*)e)->socket, message_length, buffer)) { + if (write_to_netdrv(((federate_info_t*)e)->fed_netdrv, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -158,7 +159,7 @@ void update_federate_next_event_tag_locked(uint16_t federate_id, tag_t next_even void handle_port_absent_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t message_size = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(int64_t) + sizeof(uint32_t); - read_from_socket_fail_on_error(&sending_federate->socket, message_size, &(buffer[1]), NULL, + read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, message_size, &(buffer[1]), NULL, " RTI failed to read port absent message from federate %u.", sending_federate->enclave.id); @@ -207,7 +208,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char } // Forward the message. - write_to_socket_fail_on_error(&fed->socket, message_size + 1, buffer, &rti_mutex, + write_to_netdrv_fail_on_error(fed->fed_netdrv, message_size + 1, buffer, &rti_mutex, "RTI failed to forward message to federate %d.", federate_id); LF_MUTEX_UNLOCK(&rti_mutex); @@ -216,7 +217,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char void handle_timed_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t header_size = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(int64_t) + sizeof(uint32_t); // Read the header, minus the first byte which has already been read. - read_from_socket_fail_on_error(&sending_federate->socket, header_size - 1, &(buffer[1]), NULL, + read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, header_size - 1, &(buffer[1]), NULL, "RTI failed to read the timed message header from remote federate."); // Extract the header information. of the sender uint16_t reactor_port_id; @@ -245,7 +246,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff sending_federate->enclave.id, federate_id, reactor_port_id, intended_tag.time - lf_time_start(), intended_tag.microstep); - read_from_socket_fail_on_error(&sending_federate->socket, bytes_to_read, &(buffer[header_size]), NULL, + read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, bytes_to_read, &(buffer[header_size]), NULL, "RTI failed to read timed message from federate %d.", federate_id); size_t bytes_read = bytes_to_read + header_size; // Following only works for string messages. @@ -281,7 +282,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_socket_fail_on_error(&sending_federate->socket, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, bytes_to_read, buffer, NULL, "RTI failed to clear message chunks."); total_bytes_read += bytes_to_read; } @@ -303,7 +304,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff tracepoint_rti_to_federate(send_TAGGED_MSG, federate_id, &intended_tag); } - write_to_socket_fail_on_error(&fed->socket, bytes_read, buffer, &rti_mutex, + write_to_netdrv_fail_on_error(fed->fed_netdrv, bytes_read, buffer, &rti_mutex, "RTI failed to forward message to federate %d.", federate_id); // The message length may be longer than the buffer, @@ -315,7 +316,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_socket_fail_on_error(&sending_federate->socket, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, bytes_to_read, buffer, NULL, "RTI failed to read message chunks."); total_bytes_read += bytes_to_read; @@ -323,7 +324,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff // do not write to destination_socket and cause interleaving. However, // holding the rti_mutex might be very expensive. Instead, each outgoing // socket should probably have its own mutex. - write_to_socket_fail_on_error(&fed->socket, bytes_to_read, buffer, &rti_mutex, + write_to_netdrv_fail_on_error(fed->fed_netdrv, bytes_to_read, buffer, &rti_mutex, "RTI failed to send message chunks."); } @@ -353,7 +354,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff void handle_latest_tag_confirmed(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_socket_fail_on_error(&fed->socket, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, + read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, "RTI failed to read the content of the logical tag complete from federate %d.", fed->enclave.id); tag_t completed = extract_tag(buffer); @@ -371,7 +372,7 @@ void handle_latest_tag_confirmed(federate_info_t* fed) { void handle_next_event_tag(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_socket_fail_on_error(&fed->socket, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, + read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, "RTI failed to read the content of the next event tag from federate %d.", fed->enclave.id); @@ -429,7 +430,7 @@ static void broadcast_stop_time_to_federates_locked() { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_STOP_GRN, fed->enclave.id, &rti_remote->base.max_stop_tag); } - write_to_socket_fail_on_error(&fed->socket, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, + write_to_netdrv_fail_on_error(fed->fed_netdrv, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, "RTI failed to send MSG_TYPE_STOP_GRANTED message to federate %d.", fed->enclave.id); } @@ -482,7 +483,7 @@ void handle_stop_request_message(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_socket_fail_on_error(&fed->socket, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(fed->fed_netdrv, bytes_to_read, buffer, NULL, "RTI failed to read the MSG_TYPE_STOP_REQUEST payload from federate %d.", fed->enclave.id); @@ -549,7 +550,7 @@ void handle_stop_request_message(federate_info_t* fed) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_STOP_REQ, f->enclave.id, &rti_remote->base.max_stop_tag); } - write_to_socket_fail_on_error(&f->socket, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, + write_to_netdrv_fail_on_error(f->fed_netdrv, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, "RTI failed to forward MSG_TYPE_STOP_REQUEST message to federate %d.", f->enclave.id); } @@ -562,7 +563,7 @@ void handle_stop_request_message(federate_info_t* fed) { void handle_stop_request_reply(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_REPLY_LENGTH - 1; unsigned char buffer_stop_time[bytes_to_read]; - read_from_socket_fail_on_error(&fed->socket, bytes_to_read, buffer_stop_time, NULL, + read_from_netdrv_fail_on_error(fed->fed_netdrv, bytes_to_read, buffer_stop_time, NULL, "RTI failed to read the reply to MSG_TYPE_STOP_REQUEST message from federate %d.", fed->enclave.id); @@ -591,8 +592,8 @@ void handle_address_query(uint16_t fed_id) { federate_info_t* fed = GET_FED_INFO(fed_id); // Use buffer both for reading and constructing the reply. // The length is what is needed for the reply. - unsigned char buffer[1 + sizeof(int32_t)]; - read_from_socket_fail_on_error(&fed->socket, sizeof(uint16_t), (unsigned char*)buffer, NULL, + unsigned char buffer[1 + sizeof(int32_t) + sizeof(uint32_t)]; + read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(uint16_t), (unsigned char*)buffer, NULL, "Failed to read address query."); uint16_t remote_fed_id = extract_uint16(buffer); @@ -614,18 +615,23 @@ void handle_address_query(uint16_t fed_id) { // Send the port number (which could be -1). LF_MUTEX_LOCK(&rti_mutex); - encode_int32(remote_fed->server_port, (unsigned char*)&buffer[1]); - write_to_socket_fail_on_error(&fed->socket, sizeof(int32_t) + 1, (unsigned char*)buffer, &rti_mutex, - "Failed to write port number to socket of federate %d.", fed_id); - - // Send the server IP address to federate. - write_to_socket_fail_on_error(&fed->socket, sizeof(remote_fed->server_ip_addr), - (unsigned char*)&remote_fed->server_ip_addr, &rti_mutex, - "Failed to write ip address to socket of federate %d.", fed_id); + int32_t server_port = get_server_port(remote_fed->fed_netdrv); + + encode_int32(server_port, (unsigned char*)&buffer[1]); + encode_uint32(get_server_ip_addr(remote_fed->fed_netdrv), buffer + 1 + sizeof(int32_t)); + + // Send the port number (which could be -1) and the server IP address to federate. + write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int32_t) + sizeof(uint32_t), (unsigned char*)buffer, + &rti_mutex, "Failed to write port number and ip address to socket of federate %d.", + fed_id); + + // write_to_netdrv_fail_on_error(fed->fed_netdrv, sizeof(remote_fed->server_ip_addr), + // (unsigned char*)&remote_fed->server_ip_addr, &rti_mutex, + // "Failed to write ip address to socket of federate %d.", fed_id); LF_MUTEX_UNLOCK(&rti_mutex); - LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, remote_fed->server_hostname, - remote_fed->server_port); + LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, + get_server_hostname(remote_fed->fed_netdrv), server_port); } void handle_address_ad(uint16_t federate_id) { @@ -634,7 +640,7 @@ void handle_address_ad(uint16_t federate_id) { // connections to other federates int32_t server_port = -1; unsigned char buffer[sizeof(int32_t)]; - read_from_socket_fail_on_error(&fed->socket, sizeof(int32_t), (unsigned char*)buffer, NULL, + read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(int32_t), (unsigned char*)buffer, NULL, "Error reading port data from federate %d.", federate_id); server_port = extract_int32(buffer); @@ -642,7 +648,7 @@ void handle_address_ad(uint16_t federate_id) { assert(server_port < 65536); LF_MUTEX_LOCK(&rti_mutex); - fed->server_port = server_port; + set_port(fed->fed_netdrv, server_port); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_LOG("Received address advertisement with port %d from federate %d.", server_port, federate_id); @@ -654,7 +660,7 @@ void handle_address_ad(uint16_t federate_id) { void handle_timestamp(federate_info_t* my_fed) { unsigned char buffer[sizeof(int64_t)]; // Read bytes from the socket. We need 8 bytes. - read_from_socket_fail_on_error(&my_fed->socket, sizeof(int64_t), (unsigned char*)&buffer, NULL, + read_from_netdrv_fail_on_error(my_fed->fed_netdrv, sizeof(int64_t), (unsigned char*)&buffer, NULL, "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); int64_t timestamp = swap_bytes_if_big_endian_int64(*((int64_t*)(&buffer))); @@ -696,7 +702,7 @@ void handle_timestamp(federate_info_t* my_fed) { tag_t tag = {.time = start_time, .microstep = 0}; tracepoint_rti_to_federate(send_TIMESTAMP, my_fed->enclave.id, &tag); } - if (write_to_socket(my_fed->socket, MSG_TYPE_TIMESTAMP_LENGTH, start_time_buffer)) { + if (write_to_netdrv(my_fed->fed_netdrv, MSG_TYPE_TIMESTAMP_LENGTH, start_time_buffer)) { lf_print_error("Failed to send the starting time to federate %d.", my_fed->enclave.id); } @@ -735,7 +741,7 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, socke } else if (socket_type == TCP) { LF_PRINT_DEBUG("Clock sync: RTI sending TCP message type %u.", buffer[0]); LF_MUTEX_LOCK(&rti_mutex); - write_to_socket_fail_on_error(&fed->socket, 1 + sizeof(int64_t), buffer, &rti_mutex, + write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int64_t), buffer, &rti_mutex, "Clock sync: RTI failed to send physical time to federate %d.", fed->enclave.id); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -871,7 +877,7 @@ static void handle_federate_failed(federate_info_t* my_fed) { // Indicate that there will no further events from this federate. my_fed->enclave.next_event = FOREVER_TAG; - shutdown_socket(&my_fed->socket, false); + shutdown_netdrv(my_fed->fed_netdrv, false); // Check downstream federates to see whether they should now be granted a TAG. // To handle cycles, need to create a boolean array to keep @@ -910,7 +916,7 @@ static void handle_federate_resign(federate_info_t* my_fed) { // Indicate that there will no further events from this federate. my_fed->enclave.next_event = FOREVER_TAG; - shutdown_socket(&my_fed->socket, true); + shutdown_netdrv(my_fed->fed_netdrv, true); // Check downstream federates to see whether they should now be granted a TAG. // To handle cycles, need to create a boolean array to keep @@ -934,7 +940,7 @@ void* federate_info_thread_TCP(void* fed) { // Listen for messages from the federate. while (my_fed->enclave.state != NOT_CONNECTED) { // Read no more than one byte to get the message type. - int read_failed = read_from_socket(my_fed->socket, 1, buffer); + int read_failed = read_from_netdrv(my_fed->fed_netdrv, 1, buffer); if (read_failed) { // Socket is closed lf_print_error("RTI: Socket to federate %d is closed. Exiting the thread.", my_fed->enclave.id); @@ -942,7 +948,7 @@ void* federate_info_thread_TCP(void* fed) { // Nothing more to do. Close the socket and exit. // Prevent multiple threads from closing the same socket at the same time. LF_MUTEX_LOCK(&rti_mutex); - shutdown_socket(&my_fed->socket, false); // from unistd.h + shutdown_netdrv(my_fed->fed_netdrv, false); // from unistd.h LF_MUTEX_UNLOCK(&rti_mutex); // FIXME: We need better error handling here, but do not stop execution here. break; @@ -1129,7 +1135,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { tracepoint_rti_to_federate(send_ACK, fed_id, NULL); } LF_MUTEX_LOCK(&rti_mutex); - if (write_to_socket_close_on_error(&fed->socket, 1, &ack_message)) { + if (write_to_netdrv_close_on_error(fed->fed_netdrv, 1, &ack_message)) { LF_MUTEX_UNLOCK(&rti_mutex); lf_print_error("RTI failed to write MSG_TYPE_ACK message to federate %d.", fed_id); return -1; @@ -1515,6 +1521,7 @@ void wait_for_federates() { shutdown_netdrv(rti_remote->rti_netdrv, false); if (rti_remote->socket_descriptor_UDP > 0) { + // UDP only uses sockets. shutdown_socket(&rti_remote->socket_descriptor_UDP, false); } } From 373a623d877839b146d58637f5ce8a3a036dba97 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 22:51:41 -0700 Subject: [PATCH 019/167] Add get and set functions to be used in rti_remote.c --- network/api/net_driver.h | 8 ++++ network/impl/src/lf_socket_support.c | 66 ++++++++++++---------------- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 362efd3f0..fec967843 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -133,4 +133,12 @@ void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha */ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing); +int32_t get_server_port(netdrv_t* drv); + +uint32_t get_server_ip_addr(netdrv_t* drv); + +char* get_server_hostname(netdrv_t* drv); + +void set_port(netdrv_t* drv, int32_t port); + #endif /* NET_DRIVER_H */ diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 4d286df26..a6d8e0261 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -1,7 +1,8 @@ -#include // malloc() -#include // strerror() -#include // errno -#include // read() write() +#include // malloc() +#include // strerror() +#include // errno +#include // read() write() +#include // inet_ntop #include "net_driver.h" #include "socket_common.h" @@ -107,6 +108,7 @@ int get_peer_address(netdrv_t* drv) { socklen_t addr_len = sizeof(peer_addr); if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { lf_print_error("RTI failed to get peer address."); + return -1; } priv->server_ip_addr = peer_addr.sin_addr; @@ -114,11 +116,12 @@ int get_peer_address(netdrv_t* drv) { // Create the human readable format and copy that into // the .server_hostname field of the federate. char str[INET_ADDRSTRLEN + 1]; - inet_ntop(AF_INET, priv->server_ip_addr, str, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); strncpy(priv->server_hostname, str, INET_ADDRSTRLEN); LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); #endif + return 0; } int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { @@ -242,38 +245,25 @@ void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { socket_priv_t* priv = (socket_priv_t*)drv->priv; - if (!read_before_closing) { - if (shutdown(priv->socket_descriptor, SHUT_RDWR)) { - lf_print_log("On shutdown socket, received reply: %s", strerror(errno)); - return -1; - } - } else { - // Signal the other side that no further writes are expected by sending a FIN packet. - // This indicates the write direction is closed. For more details, refer to: - // https://stackoverflow.com/questions/4160347/close-vs-shutdown-socket - if (shutdown(priv->socket_descriptor, SHUT_WR)) { - lf_print_log("Failed to shutdown socket: %s", strerror(errno)); - return -1; - } + return shutdown_socket(&priv->socket_descriptor, read_before_closing); +} - // Wait for the other side to send an EOF or encounter a socket error. - // Discard any incoming bytes. Normally, this read should return 0, indicating the peer has also closed the - // connection. - // This compensates for delayed ACKs and scenarios where Nagle's algorithm is disabled, ensuring the shutdown - // completes gracefully. - unsigned char buffer[10]; - while (read(priv->socket_descriptor, buffer, 10) > 0) - ; - } - // NOTE: In all common TCP/IP stacks, there is a time period, - // typically between 30 and 120 seconds, called the TIME_WAIT period, - // before the port is released after this close. This is because - // the OS is preventing another program from accidentally receiving - // duplicated packets intended for this program. - if (close(priv->socket_descriptor)) { - lf_print_log("Error while closing socket: %s\n", strerror(errno)); - return -1; - } - priv->socket_descriptor = -1; - return 0; +int32_t get_server_port(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + return priv->server_port; +} + +uint32_t get_server_ip_addr(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + return priv->server_ip_addr.s_addr; +} + +char* get_server_hostname(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + return priv->server_hostname; +} + +void set_port(netdrv_t* drv, int32_t port) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + priv->server_port = port; } From d2d982b9d6166b8ecf8e7e36b2b149493559f2c2 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 22:51:58 -0700 Subject: [PATCH 020/167] Minor fix. --- network/api/socket_common.h | 1 + network/impl/src/socket_common.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 7e52c06a1..fd91640ac 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -4,6 +4,7 @@ #include "low_level_platform.h" #include #include +#include /** * The amount of time to wait after a failed socket read or write before trying again. This defaults to 100 ms. diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index e43181738..202ad1125 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -119,7 +119,7 @@ int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool return used_port; } -//TODO: Fix on federate. +// TODO: Fix on federate. int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, bool increment_port_on_retry) { int socket_descriptor; @@ -157,7 +157,6 @@ int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket return 0; } - int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) { int socket_descriptor; struct timeval timeout_time; From d6471208f3fc8c72504aa172994a4c0ab1d00274 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 15 Jan 2025 23:57:01 -0700 Subject: [PATCH 021/167] Revert to sending two write()s in handle_address_query() --- core/federated/RTI/rti_remote.c | 19 +++++++++---------- network/api/net_driver.h | 2 +- network/impl/src/lf_socket_support.c | 7 +++++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 5d2693a96..35794371d 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -592,7 +592,7 @@ void handle_address_query(uint16_t fed_id) { federate_info_t* fed = GET_FED_INFO(fed_id); // Use buffer both for reading and constructing the reply. // The length is what is needed for the reply. - unsigned char buffer[1 + sizeof(int32_t) + sizeof(uint32_t)]; + unsigned char buffer[1 + sizeof(int32_t)]; read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(uint16_t), (unsigned char*)buffer, NULL, "Failed to read address query."); uint16_t remote_fed_id = extract_uint16(buffer); @@ -613,21 +613,21 @@ void handle_address_query(uint16_t fed_id) { // Encode the port number. federate_info_t* remote_fed = GET_FED_INFO(remote_fed_id); + // The fed_netdrv is NULL yet, which means, the RTI does not know the port number because it has not yet received an MSG_TYPE_ADDRESS_ADVERTISEMENT message from this federate. In that case, it will respond by sending -1. + if (remote_fed->fed_netdrv == NULL) { + } // Send the port number (which could be -1). LF_MUTEX_LOCK(&rti_mutex); int32_t server_port = get_server_port(remote_fed->fed_netdrv); encode_int32(server_port, (unsigned char*)&buffer[1]); - encode_uint32(get_server_ip_addr(remote_fed->fed_netdrv), buffer + 1 + sizeof(int32_t)); // Send the port number (which could be -1) and the server IP address to federate. - write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int32_t) + sizeof(uint32_t), (unsigned char*)buffer, - &rti_mutex, "Failed to write port number and ip address to socket of federate %d.", - fed_id); + write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int32_t), (unsigned char*)buffer, &rti_mutex, + "Failed to write port number to socket of federate %d.", fed_id); - // write_to_netdrv_fail_on_error(fed->fed_netdrv, sizeof(remote_fed->server_ip_addr), - // (unsigned char*)&remote_fed->server_ip_addr, &rti_mutex, - // "Failed to write ip address to socket of federate %d.", fed_id); + write_to_netdrv_fail_on_error(fed->fed_netdrv, sizeof(uint32_t), (unsigned char*)get_ip_addr(remote_fed->fed_netdrv), + &rti_mutex, "Failed to write ip address to socket of federate %d.", fed_id); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, @@ -1289,8 +1289,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 fed->UDP_addr.sin_family = AF_INET; fed->UDP_addr.sin_port = htons(federate_UDP_port_number); #ifdef COMM_TYPE_TCP - fed->UDP_addr.sin_addr = ((socket_priv_t*)fed_netdrv->priv)->server_ip_addr; -// fed->UDP_addr.sin_addr = fed->server_ip_addr; + fed->UDP_addr.sin_addr = *get_ip_addr(fed_netdrv); #elif #endif } diff --git a/network/api/net_driver.h b/network/api/net_driver.h index fec967843..a70abca7e 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -135,7 +135,7 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing); int32_t get_server_port(netdrv_t* drv); -uint32_t get_server_ip_addr(netdrv_t* drv); +struct in_addr* get_ip_addr(netdrv_t* drv); char* get_server_hostname(netdrv_t* drv); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index a6d8e0261..34844e8de 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -249,13 +249,16 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { } int32_t get_server_port(netdrv_t* drv) { + // if (drv == NULL) { + // lf_print_warning("Netdriver is closed, returning -1."); + // } socket_priv_t* priv = (socket_priv_t*)drv->priv; return priv->server_port; } -uint32_t get_server_ip_addr(netdrv_t* drv) { +struct in_addr* get_ip_addr(netdrv_t* drv) { socket_priv_t* priv = (socket_priv_t*)drv->priv; - return priv->server_ip_addr.s_addr; + return &priv->server_ip_addr; } char* get_server_hostname(netdrv_t* drv) { From 225e0b5ff0b3fda793a91b7465c105094ec8bff3 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Thu, 16 Jan 2025 10:21:08 -0700 Subject: [PATCH 022/167] Add logic in handle_address_query(), to check if the remote_fed's network driver is initialized, and send default values when not initialized. --- core/federated/RTI/rti_remote.c | 34 +++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 35794371d..d6d8f0c47 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -613,12 +613,26 @@ void handle_address_query(uint16_t fed_id) { // Encode the port number. federate_info_t* remote_fed = GET_FED_INFO(remote_fed_id); - // The fed_netdrv is NULL yet, which means, the RTI does not know the port number because it has not yet received an MSG_TYPE_ADDRESS_ADVERTISEMENT message from this federate. In that case, it will respond by sending -1. + int32_t server_port; + uint32_t* ip_address; + char* server_host_name; + + LF_MUTEX_LOCK(&rti_mutex); + // Check if the RTI has initialized the remote federate's network driver. if (remote_fed->fed_netdrv == NULL) { + // RTI has not set up the remote federate. Respond with -1 to indicate an unknown port number. + server_port = -1; + uint32_t temp = 0; + ip_address = &temp; + server_host_name = "localhost"; + } else { + // The network driver is initialized, but the RTI might still not know the port number. This can happen if the RTI + // has not yet received a MSG_TYPE_ADDRESS_ADVERTISEMENT message from the remote federate. In such cases, the + // returned port number might still be -1. + server_port = get_server_port(remote_fed->fed_netdrv); + ip_address = (uint32_t*)get_ip_addr(remote_fed->fed_netdrv); + server_host_name = get_server_hostname(remote_fed->fed_netdrv); } - // Send the port number (which could be -1). - LF_MUTEX_LOCK(&rti_mutex); - int32_t server_port = get_server_port(remote_fed->fed_netdrv); encode_int32(server_port, (unsigned char*)&buffer[1]); @@ -626,12 +640,12 @@ void handle_address_query(uint16_t fed_id) { write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int32_t), (unsigned char*)buffer, &rti_mutex, "Failed to write port number to socket of federate %d.", fed_id); - write_to_netdrv_fail_on_error(fed->fed_netdrv, sizeof(uint32_t), (unsigned char*)get_ip_addr(remote_fed->fed_netdrv), - &rti_mutex, "Failed to write ip address to socket of federate %d.", fed_id); + write_to_netdrv_fail_on_error(fed->fed_netdrv, sizeof(uint32_t), (unsigned char*)ip_address, &rti_mutex, + "Failed to write ip address to socket of federate %d.", fed_id); LF_MUTEX_UNLOCK(&rti_mutex); - LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, - get_server_hostname(remote_fed->fed_netdrv), server_port); + LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, server_host_name, + server_port); } void handle_address_ad(uint16_t federate_id) { @@ -1381,6 +1395,10 @@ static bool authenticate_federate(netdrv_t* fed_netdrv) { #endif void lf_connect_to_federates(netdrv_t* rti_netdrv) { + // netdrv_t* netdrv_array[rti_remote->base.number_of_scheduling_nodes]; + // for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { + // netdrv_array[i] = establish_communication_session(rti_netdrv); + // } for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { netdrv_t* fed_netdrv = accept_netdrv(rti_netdrv, NULL); // Wait for the first message from the federate when RTI -a option is on. From 0de95842565a623b657dd2470a157e88d40f8597 Mon Sep 17 00:00:00 2001 From: Dongha Kim <74869052+Jakio815@users.noreply.github.com> Date: Fri, 17 Jan 2025 09:55:04 -0700 Subject: [PATCH 023/167] Update CMakeLists.txt --- network/api/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/api/CMakeLists.txt b/network/api/CMakeLists.txt index 6f724fe1a..75a3c2814 100644 --- a/network/api/CMakeLists.txt +++ b/network/api/CMakeLists.txt @@ -11,4 +11,4 @@ target_link_libraries(lf-network-api INTERFACE lf::low-level-platform-api) # target_include_directories(lf-network-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}/type) target_include_directories(lf-network-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}/../../include/core/utils) -target_compile_definitions(lf-network-api INTERFACE COMM_TYPE_${COMM_TYPE}) \ No newline at end of file +target_compile_definitions(lf-network-api INTERFACE COMM_TYPE_${COMM_TYPE}) From de834545aa310a82d15caf2e4d64a026bb58b639 Mon Sep 17 00:00:00 2001 From: Dongha Kim <74869052+Jakio815@users.noreply.github.com> Date: Fri, 17 Jan 2025 09:56:05 -0700 Subject: [PATCH 024/167] Update CMakeLists.txt --- network/api/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/network/api/CMakeLists.txt b/network/api/CMakeLists.txt index 75a3c2814..08aaf8105 100644 --- a/network/api/CMakeLists.txt +++ b/network/api/CMakeLists.txt @@ -6,9 +6,6 @@ add_library(lf::network-api ALIAS lf-network-api) target_link_libraries(lf-network-api INTERFACE lf::tag-api) target_link_libraries(lf-network-api INTERFACE lf::low-level-platform-api) - -# #TODO:CHECK. -# target_include_directories(lf-network-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}/type) target_include_directories(lf-network-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}/../../include/core/utils) target_compile_definitions(lf-network-api INTERFACE COMM_TYPE_${COMM_TYPE}) From 5cf0a470e172ac0600741a01862a3ad30f4cb037 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 17:31:39 -0700 Subject: [PATCH 025/167] Fixing data types to netdriver. --- core/federated/federate.c | 54 +++++++++++++++---------------- include/core/federated/federate.h | 39 +++++++++++----------- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index a689ae090..52dac1281 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -78,7 +78,7 @@ int max_level_allowed_to_advance; */ federate_instance_t _fed = {.socket_TCP_RTI = -1, .number_of_inbound_p2p_connections = 0, - .inbound_socket_listeners = NULL, + .inbound_netdriv_listeners = NULL, .number_of_outbound_p2p_connections = 0, .inbound_p2p_handling_thread_id = 0, .server_socket = -1, @@ -411,8 +411,8 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen */ static void close_inbound_socket(int fed_id) { LF_MUTEX_LOCK(&socket_mutex); - if (_fed.sockets_for_inbound_p2p_connections[fed_id] >= 0) { - shutdown_socket(&_fed.sockets_for_inbound_p2p_connections[fed_id], false); + if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] >= 0) { + shutdown_socket(&_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); } LF_MUTEX_UNLOCK(&socket_mutex); } @@ -726,7 +726,7 @@ static int handle_port_absent_message(int* socket, int fed_id) { * peer federate and calls the appropriate handling function for * each message type. If an error occurs or an EOF is received * from the peer, then this procedure sets the corresponding - * socket in _fed.sockets_for_inbound_p2p_connections + * socket in _fed.netdrvs_for_inbound_p2p_connections * to -1 and returns, terminating the thread. * @param _args The remote federate ID (cast to void*). * @param fed_id_ptr A pointer to a uint16_t containing federate ID being listened to. @@ -738,7 +738,7 @@ static void* listen_to_federates(void* _args) { LF_PRINT_LOG("Listening to federate %d.", fed_id); - int* socket_id = &_fed.sockets_for_inbound_p2p_connections[fed_id]; + int* socket_id = &_fed.netdrvs_for_inbound_p2p_connections[fed_id]; // Buffer for incoming messages. // This does not constrain the message size @@ -823,14 +823,14 @@ static void close_outbound_socket(int fed_id) { // abnormal termination, in which case it will just close the socket. if (_lf_normal_termination) { LF_MUTEX_LOCK(&lf_outbound_socket_mutex); - if (_fed.sockets_for_outbound_p2p_connections[fed_id] >= 0) { + if (_fed.netdrvs_for_outbound_p2p_connections[fed_id] >= 0) { // Close the socket by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. - shutdown_socket(&_fed.sockets_for_outbound_p2p_connections[fed_id], true); + shutdown_socket(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); } LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); } else { - shutdown_socket(&_fed.sockets_for_outbound_p2p_connections[fed_id], false); + shutdown_socket(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); } } @@ -1632,11 +1632,11 @@ void lf_terminate_execution(environment_t* env) { for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { close_inbound_socket(i); // Ignore errors. Mark the socket closed. - _fed.sockets_for_inbound_p2p_connections[i] = -1; + _fed.netdrvs_for_inbound_p2p_connections[i] = -1; } // Check for all outgoing physical connections in - // _fed.sockets_for_outbound_p2p_connections and + // _fed.netdrvs_for_outbound_p2p_connections and // if the socket ID is not -1, the connection is still open. // Send an EOF by closing the socket here. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { @@ -1649,23 +1649,23 @@ void lf_terminate_execution(environment_t* env) { LF_PRINT_DEBUG("Waiting for inbound p2p socket listener threads."); // Wait for each inbound socket listener thread to close. - if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_socket_listeners != NULL) { + if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_netdriv_listeners != NULL) { LF_PRINT_LOG("Waiting for %zu threads listening for incoming messages to exit.", _fed.number_of_inbound_p2p_connections); for (size_t i = 0; i < _fed.number_of_inbound_p2p_connections; i++) { // Ignoring errors here. - lf_thread_join(_fed.inbound_socket_listeners[i], NULL); + lf_thread_join(_fed.inbound_netdriv_listeners[i], NULL); } } - LF_PRINT_DEBUG("Waiting for RTI's socket listener threads."); + LF_PRINT_DEBUG("Waiting for RTI's network driver listener threads."); // Wait for the thread listening for messages from the RTI to close. - lf_thread_join(_fed.RTI_socket_listener, NULL); + lf_thread_join(_fed.RTI_netdrv_listener, NULL); // For abnormal termination, there is no need to free memory. if (_lf_normal_termination) { LF_PRINT_DEBUG("Freeing memory occupied by the federate."); - free(_fed.inbound_socket_listeners); + free(_fed.inbound_netdriv_listeners); free(federation_metadata.rti_host); free(federation_metadata.rti_user); } @@ -1801,7 +1801,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } // Once we set this variable, then all future calls to close() on this // socket ID should reset it to -1 within a critical section. - _fed.sockets_for_outbound_p2p_connections[remote_federate_id] = socket_id; + _fed.netdrvs_for_outbound_p2p_connections[remote_federate_id] = socket_id; } void lf_connect_to_rti(const char* hostname, int port) { @@ -1967,7 +1967,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { LF_ASSERT_NON_NULL(env_arg); size_t received_federates = 0; // Allocate memory to store thread IDs. - _fed.inbound_socket_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); + _fed.inbound_netdriv_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); while (received_federates < _fed.number_of_inbound_p2p_connections && !_lf_termination_executed) { // Wait for an incoming connection request. int socket_id = accept_socket(_fed.server_socket, _fed.socket_TCP_RTI); @@ -2028,7 +2028,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // element should be reset to -1 during that critical section. // Otherwise, there can be race condition where, during termination, // two threads attempt to simultaneously close the socket. - _fed.sockets_for_inbound_p2p_connections[remote_fed_id] = socket_id; + _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = socket_id; // Send an MSG_TYPE_ACK message. unsigned char response = MSG_TYPE_ACK; @@ -2037,7 +2037,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); LF_MUTEX_LOCK(&lf_outbound_socket_mutex); - write_to_socket_fail_on_error(&_fed.sockets_for_inbound_p2p_connections[remote_fed_id], 1, + write_to_socket_fail_on_error(&_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, &lf_outbound_socket_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); @@ -2045,13 +2045,13 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Start a thread to listen for incoming messages from other federates. // The fed_id is a uint16_t, which we assume can be safely cast to and from void*. void* fed_id_arg = (void*)(uintptr_t)remote_fed_id; - int result = lf_thread_create(&_fed.inbound_socket_listeners[received_federates], listen_to_federates, fed_id_arg); + int result = lf_thread_create(&_fed.inbound_netdriv_listeners[received_federates], listen_to_federates, fed_id_arg); if (result != 0) { // Failed to create a listening thread. LF_MUTEX_LOCK(&socket_mutex); - if (_fed.sockets_for_inbound_p2p_connections[remote_fed_id] != -1) { + if (_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] != -1) { shutdown_socket(&socket_id, false); - _fed.sockets_for_inbound_p2p_connections[remote_fed_id] = -1; + _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = -1; } LF_MUTEX_UNLOCK(&socket_mutex); lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", @@ -2160,7 +2160,7 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa // Use a mutex lock to prevent multiple threads from simultaneously sending. LF_MUTEX_LOCK(&lf_outbound_socket_mutex); - int* socket = &_fed.sockets_for_outbound_p2p_connections[federate]; + int* socket = &_fed.netdrvs_for_outbound_p2p_connections[federate]; // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_P2P_MSG, _lf_my_fed_id, federate, NULL); @@ -2340,7 +2340,7 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d int* socket = &_fed.socket_TCP_RTI; #else // Send the absent message directly to the federate - int* socket = &_fed.sockets_for_outbound_p2p_connections[fed_ID]; + int* socket = &_fed.netdrvs_for_outbound_p2p_connections[fed_ID]; #endif if (socket == &_fed.socket_TCP_RTI) { @@ -2453,7 +2453,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int int* socket; if (message_type == MSG_TYPE_P2P_TAGGED_MESSAGE) { - socket = &_fed.sockets_for_outbound_p2p_connections[federate]; + socket = &_fed.netdrvs_for_outbound_p2p_connections[federate]; tracepoint_federate_to_federate(send_P2P_TAGGED_MSG, _lf_my_fed_id, federate, ¤t_message_intended_tag); } else { socket = &_fed.socket_TCP_RTI; @@ -2508,11 +2508,11 @@ void lf_synchronize_with_other_federates(void) { start_time = get_start_time_from_rti(lf_time_physical()); lf_tracing_set_start_time(start_time); - // Start a thread to listen for incoming TCP messages from the RTI. + // Start a thread to listen for incoming messages from the RTI. // @note Up until this point, the federate has been listening for messages // from the RTI in a sequential manner in the main thread. From now on, a // separate thread is created to allow for asynchronous communication. - lf_thread_create(&_fed.RTI_socket_listener, listen_to_rti_TCP, NULL); + lf_thread_create(&_fed.RTI_netdrv_listener, listen_to_rti_TCP, NULL); lf_thread_t thread_id; if (create_clock_sync_thread(&thread_id)) { lf_print_warning("Failed to create thread to handle clock synchronization."); diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index 50c59daa1..a8cb325d0 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -18,6 +18,7 @@ #include "lf_types.h" #include "environment.h" #include "low_level_platform.h" +#include "net_driver.h" #ifndef ADVANCE_MESSAGE_INTERVAL #define ADVANCE_MESSAGE_INTERVAL MSEC(10) @@ -31,16 +32,16 @@ */ typedef struct federate_instance_t { /** - * The TCP socket descriptor for this federate to communicate with the RTI. + * The network driver for this federate to communicate with the RTI. * This is set by lf_connect_to_rti(), which must be called before other * functions that communicate with the rti are called. */ - int socket_TCP_RTI; + netdrv_t* netdrv_to_RTI; /** - * Thread listening for incoming TCP messages from the RTI. + * Thread listening for incoming messages from the RTI. */ - lf_thread_t RTI_socket_listener; + lf_thread_t RTI_netdrv_listener; /** * Number of inbound physical connections to the federate. @@ -54,7 +55,7 @@ typedef struct federate_instance_t { * This is NULL if there are none and otherwise has size given by * number_of_inbound_p2p_connections. */ - lf_thread_t* inbound_socket_listeners; + lf_thread_t* inbound_netdriv_listeners; /** * Number of outbound peer-to-peer connections from the federate. @@ -64,34 +65,34 @@ typedef struct federate_instance_t { size_t number_of_outbound_p2p_connections; /** - * An array that holds the socket descriptors for inbound + * An array that holds the network drivers for inbound * connections from each federate. The index will be the federate * ID of the remote sending federate. This is initialized at startup - * to -1 and is set to a socket ID by lf_handle_p2p_connections_from_federates() - * when the socket is opened. + * to -1 and is set to a socket ID by lf_handle_p2p_connections_from_federates() //TODO: Check here. + * when the network drivers is opened. * - * @note There will not be an inbound socket unless a physical connection + * @note There will not be an inbound network driver unless a physical connection * or a p2p logical connection (by setting the coordination target property * to "distributed") is specified in the Lingua Franca program where this * federate is the destination. Multiple incoming p2p connections from the - * same remote federate will use the same socket. + * same remote federate will use the same network driver. */ - int sockets_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; + netdrv_t* netdrvs_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; /** - * An array that holds the socket descriptors for outbound direct + * An array that holds the network drivers for outbound direct * connections to each remote federate. The index will be the federate * ID of the remote receiving federate. This is initialized at startup - * to -1 and is set to a socket ID by lf_connect_to_federate() - * when the socket is opened. + * to -1 and is set to a socket ID by lf_connect_to_federate() //TODO: Check here. + * when the network drivers is opened. * - * @note This federate will not open an outbound socket unless a physical + * @note This federate will not open an outbound network drivers unless a physical * connection or a p2p logical connection (by setting the coordination target * property to "distributed") is specified in the Lingua Franca * program where this federate acts as the source. Multiple outgoing p2p - * connections to the same remote federate will use the same socket. + * connections to the same remote federate will use the same network drivers. */ - int sockets_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; + netdrv_t* netdrvs_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; /** * Thread ID for a thread that accepts sockets and then supervises @@ -105,7 +106,7 @@ typedef struct federate_instance_t { * This socket is used to listen to incoming physical connections from * remote federates. Once an incoming connection is accepted, the * opened socket will be stored in - * federate_sockets_for_inbound_p2p_connections. + * federate_netdrvs_for_inbound_p2p_connections. */ int server_socket; @@ -227,7 +228,7 @@ extern lf_cond_t lf_port_status_changed; * the IP address and port number of the specified federate. It then attempts * to establish a socket connection to the specified federate. * If this fails, the program exits. If it succeeds, it sets element [id] of - * the _fed.sockets_for_outbound_p2p_connections global array to + * the _fed.netdrvs_for_outbound_p2p_connections global array to * refer to the socket for communicating directly with the federate. * @param remote_federate_id The ID of the remote federate. */ From 9c7c4ab429fe3d368c57e61382b51a96b73cb3f0 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 18:07:44 -0700 Subject: [PATCH 026/167] Fix names to netdriver. --- core/federated/federate.c | 76 +++++++++++++++---------------- include/core/federated/federate.h | 51 +++++++++------------ 2 files changed, 60 insertions(+), 67 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 52dac1281..e7f3143cc 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -50,7 +50,7 @@ extern instant_t start_time; extern bool _lf_termination_executed; // Global variables references in federate.h -lf_mutex_t lf_outbound_socket_mutex; +lf_mutex_t lf_outbound_netdrv_mutex; lf_cond_t lf_port_status_changed; /** @@ -100,7 +100,7 @@ federation_metadata_t federation_metadata = { // Static functions (used only internally) /** - * Send a time to the RTI. This acquires the lf_outbound_socket_mutex. + * Send a time to the RTI. This acquires the lf_outbound_netdrv_mutex. * @param type The message type (MSG_TYPE_TIMESTAMP). * @param time The time. */ @@ -115,15 +115,15 @@ static void send_time(unsigned char type, instant_t time) { tag_t tag = {.time = time, .microstep = 0}; tracepoint_federate_to_rti(send_TIMESTAMP, _lf_my_fed_id, &tag); - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_socket_mutex, + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); + write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } /** * Send a tag to the RTI. - * This function acquires the lf_outbound_socket_mutex. + * This function acquires the lf_outbound_netdrv_mutex. * @param type The message type (MSG_TYPE_NEXT_EVENT_TAG or MSG_TYPE_LATEST_TAG_CONFIRMED). * @param tag The tag. */ @@ -134,18 +134,18 @@ static void send_tag(unsigned char type, tag_t tag) { buffer[0] = type; encode_tag(&(buffer[1]), tag); - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); if (_fed.socket_TCP_RTI < 0) { lf_print_warning("Socket is no longer connected. Dropping message."); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return; } trace_event_t event_type = (type == MSG_TYPE_NEXT_EVENT_TAG) ? send_NET : send_LTC; // Trace the event when tracing is enabled tracepoint_federate_to_rti(event_type, _lf_my_fed_id, &tag); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_socket_mutex, + write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } /** @@ -811,7 +811,7 @@ static void* listen_to_federates(void* _args) { /** * Close the socket that sends outgoing messages to the - * specified federate ID. This function acquires the lf_outbound_socket_mutex mutex lock + * specified federate ID. This function acquires the lf_outbound_netdrv_mutex mutex lock * if _lf_normal_termination is true and otherwise proceeds without the lock. * @param fed_id The ID of the peer federate receiving messages from this * federate, or -1 if the RTI (centralized coordination). @@ -822,13 +822,13 @@ static void close_outbound_socket(int fed_id) { // This will result in EOF being sent to the remote federate, except for // abnormal termination, in which case it will just close the socket. if (_lf_normal_termination) { - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); if (_fed.netdrvs_for_outbound_p2p_connections[fed_id] >= 0) { // Close the socket by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. shutdown_socket(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); } - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } else { shutdown_socket(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); } @@ -1379,7 +1379,7 @@ static void handle_stop_request_message() { // is guarded by the outbound socket mutex. // The second is guarded by the global mutex. // Note that the RTI should not send stop requests more than once to federates. - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); if (_fed.received_stop_request_from_rti) { LF_PRINT_LOG("Redundant MSG_TYPE_STOP_REQUEST from RTI. Ignoring it."); already_blocked = true; @@ -1388,7 +1388,7 @@ static void handle_stop_request_message() { // prevent lf_request_stop from sending. _fed.received_stop_request_from_rti = true; } - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); if (already_blocked) { // Either we have sent a stop request to the RTI ourselves, @@ -1422,11 +1422,11 @@ static void handle_stop_request_message() { tracepoint_federate_to_rti(send_STOP_REQ_REP, _lf_my_fed_id, &tag_to_stop); // Send the current logical time to the RTI. - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, - &lf_outbound_socket_mutex, + &lf_outbound_netdrv_mutex, "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); LF_PRINT_DEBUG("Sent MSG_TYPE_STOP_REQUEST_REPLY to RTI with tag " PRINTF_TAG, tag_to_stop.time, tag_to_stop.microstep); @@ -1439,10 +1439,10 @@ static void send_resign_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_RESIGN; - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_socket_mutex, + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); + write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netdrv_mutex, "Failed to send MSG_TYPE_RESIGN."); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); LF_PRINT_LOG("Resigned."); } @@ -1694,10 +1694,10 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_QR, _lf_my_fed_id, NULL); - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_socket_mutex, + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); + write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netdrv_mutex, "Failed to send address query for federate %d to RTI.", remote_federate_id); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); // Read RTI's response. read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, sizeof(int32_t) + 1, buffer, NULL, @@ -2036,11 +2036,11 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); write_to_socket_fail_on_error(&_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, - (unsigned char*)&response, &lf_outbound_socket_mutex, + (unsigned char*)&response, &lf_outbound_netdrv_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); // Start a thread to listen for incoming messages from other federates. // The fed_id is a uint16_t, which we assume can be safely cast to and from void*. @@ -2158,7 +2158,7 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa const int header_length = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); // Use a mutex lock to prevent multiple threads from simultaneously sending. - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); int* socket = &_fed.netdrvs_for_outbound_p2p_connections[federate]; @@ -2174,7 +2174,7 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa // Message did not send. Since this is used for physical connections, this is not critical. lf_print_warning("Failed to send message to %s. Dropping the message.", next_destination_str); } - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return result; } @@ -2349,9 +2349,9 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d tracepoint_federate_to_federate(send_PORT_ABS, _lf_my_fed_id, fed_ID, ¤t_message_intended_tag); } - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); int result = write_to_socket_close_on_error(socket, message_length, buffer); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); if (result != 0) { // Write failed. Response depends on whether coordination is centralized. @@ -2374,7 +2374,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { stop_tag.microstep++; ENCODE_STOP_REQUEST(buffer, stop_tag.time, stop_tag.microstep); - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); // Do not send a stop request if a stop request has been previously received from the RTI. if (!_fed.received_stop_request_from_rti) { LF_PRINT_LOG("Sending to RTI a MSG_TYPE_STOP_REQUEST message with tag " PRINTF_TAG ".", stop_tag.time - start_time, @@ -2382,21 +2382,21 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { if (_fed.socket_TCP_RTI < 0) { lf_print_warning("Socket is no longer connected. Dropping message."); - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return -1; } // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_STOP_REQ, _lf_my_fed_id, &stop_tag); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_socket_mutex, + write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_netdrv_mutex, "Failed to send stop time " PRINTF_TIME " to the RTI.", stop_tag.time - start_time); // Treat this sending as equivalent to having received a stop request from the RTI. _fed.received_stop_request_from_rti = true; - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return 0; } else { - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return 1; } } @@ -2449,7 +2449,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int current_message_intended_tag.microstep, next_destination_str); // Use a mutex lock to prevent multiple threads from simultaneously sending. - LF_MUTEX_LOCK(&lf_outbound_socket_mutex); + LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); int* socket; if (message_type == MSG_TYPE_P2P_TAGGED_MESSAGE) { @@ -2474,7 +2474,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int next_destination_str, errno, strerror(errno)); } } - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return result; } diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index a8cb325d0..0a62dba43 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -95,27 +95,20 @@ typedef struct federate_instance_t { netdrv_t* netdrvs_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; /** - * Thread ID for a thread that accepts sockets and then supervises - * listening to those sockets for incoming P2P (physical) connections. + * Thread ID for a thread that accepts network drivers and then supervises + * listening to those network drivers for incoming P2P (physical) connections. */ lf_thread_t inbound_p2p_handling_thread_id; /** - * A socket descriptor for the socket server of the federate. + * A network driver for the server of the federate. * This is assigned in lf_create_server(). - * This socket is used to listen to incoming physical connections from + * This network driver is used to listen to incoming physical connections from * remote federates. Once an incoming connection is accepted, the - * opened socket will be stored in + * opened network driver will be stored in * federate_netdrvs_for_inbound_p2p_connections. */ - int server_socket; - - /** - * The port used for the server socket to listen for messages from other federates. - * The federate informs the RTI of this port once it has created its socket server by - * sending an ADDRESS_AD message (@see rti.h). - */ - int server_port; + netdrv_t* server_netdrv; /** * Most recent tag advance grant (TAG) received from the RTI, or NEVER if none @@ -207,9 +200,9 @@ typedef enum parse_rti_code_t { SUCCESS, INVALID_PORT, INVALID_HOST, INVALID_USE // Global variables /** - * Mutex lock held while performing socket write and close operations. + * Mutex lock held while performing network driver write and close operations. */ -extern lf_mutex_t lf_outbound_socket_mutex; +extern lf_mutex_t lf_outbound_netdrv_mutex; /** * Condition variable for blocking on unkonwn federate input ports. @@ -226,10 +219,10 @@ extern lf_cond_t lf_port_status_changed; * to send messages directly to the specified federate. * This function first sends an MSG_TYPE_ADDRESS_QUERY message to the RTI to obtain * the IP address and port number of the specified federate. It then attempts - * to establish a socket connection to the specified federate. + * to establish a network driver connection to the specified federate. * If this fails, the program exits. If it succeeds, it sets element [id] of * the _fed.netdrvs_for_outbound_p2p_connections global array to - * refer to the socket for communicating directly with the federate. + * refer to the network driver for communicating directly with the federate. * @param remote_federate_id The ID of the remote federate. */ void lf_connect_to_federate(uint16_t); @@ -237,12 +230,12 @@ void lf_connect_to_federate(uint16_t); /** * @brief Connect to the RTI at the specified host and port. * - * This will return the socket descriptor for the connection. + * This will return the network driver for the connection. * If port_number is 0, then start at DEFAULT_PORT and increment * the port number on each attempt. If an attempt fails, wait CONNECT_RETRY_INTERVAL * and try again. If it fails after CONNECT_TIMEOUT, the program exits. - * If it succeeds, it sets the _fed.socket_TCP_RTI global variable to refer to - * the socket for communicating with the RTI. + * If it succeeds, it sets the _fed.netdrv_to_RTI global variable to refer to + * the network driver for communicating with the RTI. * @param hostname A hostname, such as "localhost". * @param port_number A port number or 0 to start with the default. */ @@ -252,8 +245,8 @@ void lf_connect_to_rti(const char* hostname, int port_number); * @brief Create a server to listen to incoming P2P connections. * * Such connections are used for physical connections or any connection if using - * decentralized coordination. This function only handles the creation of the server socket. - * The bound port for the server socket is then sent to the RTI by sending an + * decentralized coordination. This function only handles the creation of the server network driver. + * The bound port for the server network driver is then sent to the RTI by sending an * MSG_TYPE_ADDRESS_ADVERTISEMENT message (@see net_common.h). * This function expects no response from the RTI. * @@ -280,8 +273,8 @@ void lf_enqueue_port_absent_reactions(environment_t* env); * * This thread accepts connections from federates that send messages directly * to this one (not through the RTI). This thread starts a thread for - * each accepted socket connection to read messages and, once it has opened all expected - * sockets, exits. + * each accepted network driver connection to read messages and, once it has opened all expected + * network drivers, exits. * @param ignored No argument needed for this thread. */ void* lf_handle_p2p_connections_from_federates(void*); @@ -323,7 +316,7 @@ void lf_reset_status_fields_on_input_port_triggers(); * between federates. If the socket connection to the remote federate or the RTI has been broken, * then this returns -1 without sending. Otherwise, it returns 0. * - * This method assumes that the caller does not hold the lf_outbound_socket_mutex lock, + * This method assumes that the caller does not hold the lf_outbound_netdrv_mutex lock, * which it acquires to perform the send. * * @param message_type The type of the message being sent (currently only MSG_TYPE_P2P_MESSAGE). @@ -425,7 +418,7 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d * * The payload is the specified tag plus one microstep. If this federate has previously * received a stop request from the RTI, then do not send the message and - * return 1. Return -1 if the socket is disconnected. Otherwise, return 0. + * return 1. Return -1 if the network driver is disconnected. Otherwise, return 0. * @return 0 if the message is sent. */ int lf_send_stop_request_to_rti(tag_t stop_tag); @@ -437,7 +430,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag); * If the delayed tag falls after the timeout time, then the message is not sent and -1 is returned. * The caller can reuse or free the memory storing the message after this returns. * - * If the message fails to send (e.g. the socket connection is broken), then the + * If the message fails to send (e.g. the network driver connection is broken), then the * response depends on the message_type. For MSG_TYPE_TAGGED_MESSAGE, the message is * supposed to go via the RTI, and failure to communicate with the RTI is a critical failure. * In this case, the program will exit with an error message. If the message type is @@ -446,7 +439,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag); * to believe that there were no messages forthcoming. In this case, on failure to send * the message, this function returns -11. * - * This method assumes that the caller does not hold the lf_outbound_socket_mutex lock, + * This method assumes that the caller does not hold the lf_outbound_netdrv_mutex lock, * which it acquires to perform the send. * * @param env The environment from which to get the current tag. @@ -502,7 +495,7 @@ void lf_stall_advance_level_federation_locked(size_t level); * @brief Synchronize the start with other federates via the RTI. * * This assumes that a connection to the RTI is already made - * and _lf_rti_socket_TCP is valid. It then sends the current logical + * and _lf_rti_socket_TCP is valid. It then sends the current logical //TODO: Check. * time to the RTI and waits for the RTI to respond with a specified * time. It starts a thread to listen for messages from the RTI. */ From aa3237e3858d84f1d9acc2de96b4cc84625be28e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 18:44:08 -0700 Subject: [PATCH 027/167] Remove old TCP related parameters. --- core/federated/RTI/rti_remote.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index d6d8f0c47..634a99b06 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1560,10 +1560,6 @@ void initialize_RTI(rti_remote_t* rti) { rti_remote->all_federates_exited = false; rti_remote->federation_id = "Unidentified Federation"; rti_remote->user_specified_port = 0; - // TODO: Erase - rti_remote->final_port_TCP = 0; - rti_remote->socket_descriptor_TCP = -1; - rti_remote->final_port_UDP = UINT16_MAX; rti_remote->socket_descriptor_UDP = -1; rti_remote->clock_sync_global_status = clock_sync_init; From bfea77a2cfe2157692a718305178499703d6631a Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 18:44:08 -0700 Subject: [PATCH 028/167] Remove old TCP related parameters. --- core/federated/RTI/rti_remote.c | 4 ---- core/federated/RTI/rti_remote.h | 6 ------ 2 files changed, 10 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index d6d8f0c47..634a99b06 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1560,10 +1560,6 @@ void initialize_RTI(rti_remote_t* rti) { rti_remote->all_federates_exited = false; rti_remote->federation_id = "Unidentified Federation"; rti_remote->user_specified_port = 0; - // TODO: Erase - rti_remote->final_port_TCP = 0; - rti_remote->socket_descriptor_TCP = -1; - rti_remote->final_port_UDP = UINT16_MAX; rti_remote->socket_descriptor_UDP = -1; rti_remote->clock_sync_global_status = clock_sync_init; diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index c29d0d53b..abf7cb20e 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -114,12 +114,6 @@ typedef struct rti_remote_t { */ uint16_t user_specified_port; - /** The final port number that the TCP socket server ends up using. */ - uint16_t final_port_TCP; - - /** The TCP socket descriptor for the socket server. */ - int socket_descriptor_TCP; - /************* UDP server information *************/ /** The final port number that the UDP socket server ends up using. */ uint16_t final_port_UDP; From f8f45e2857d84f690a56e4b7f4e6508a5c1f3405 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 18:48:47 -0700 Subject: [PATCH 029/167] Minor fix. --- network/impl/src/lf_socket_support.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 34844e8de..90ab3d84c 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -19,8 +19,6 @@ netdrv_t* initialize_netdrv() { if (priv == NULL) { lf_print_error_and_exit("Falied to malloc socket_priv_t."); } - // Initialize to zero. - // memset(priv, 0, sizeof(socket_priv_t)); // Server initialization. priv->port = 0; From dc79adf739a36aa76f4ec8968481a13cf4b15bf9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 22:28:09 -0700 Subject: [PATCH 030/167] Set hostname and port for federate. Also move get_peer_address to bottom of code. --- core/federated/federate.c | 8 ++++- network/impl/src/lf_socket_support.c | 49 +++++++++++++++------------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index e7f3143cc..cd188c5fe 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1811,7 +1811,13 @@ void lf_connect_to_rti(const char* hostname, int port) { hostname = federation_metadata.rti_host ? federation_metadata.rti_host : hostname; port = federation_metadata.rti_port >= 0 ? federation_metadata.rti_port : port; - // Create a socket + + + // Create a network driver. + _fed.netdrv_to_RTI = initialize_netdrv(); + set_host_name(_fed.netdrv_to_RTI, hostname); + set_port(_fed.netdrv_to_RTI, port); + _fed.socket_TCP_RTI = create_real_time_tcp_socket_errexit(); if (connect_to_socket(_fed.socket_TCP_RTI, hostname, port) < 0) { lf_print_error_and_exit("Failed to connect() to RTI."); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 90ab3d84c..e6a753d77 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -100,28 +100,6 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { return fed_netdrv; } -int get_peer_address(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; - struct sockaddr_in peer_addr; - socklen_t addr_len = sizeof(peer_addr); - if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { - lf_print_error("RTI failed to get peer address."); - return -1; - } - priv->server_ip_addr = peer_addr.sin_addr; - -#if LOG_LEVEL >= LOG_LEVEL_DEBUG - // Create the human readable format and copy that into - // the .server_hostname field of the federate. - char str[INET_ADDRSTRLEN + 1]; - inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); - strncpy(priv->server_hostname, str, INET_ADDRSTRLEN); - - LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); -#endif - return 0; -} - int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = (socket_priv_t*)drv->priv; int socket = priv->socket_descriptor; @@ -246,6 +224,28 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { return shutdown_socket(&priv->socket_descriptor, read_before_closing); } +int get_peer_address(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + struct sockaddr_in peer_addr; + socklen_t addr_len = sizeof(peer_addr); + if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { + lf_print_error("RTI failed to get peer address."); + return -1; + } + priv->server_ip_addr = peer_addr.sin_addr; + +#if LOG_LEVEL >= LOG_LEVEL_DEBUG + // Create the human readable format and copy that into + // the .server_hostname field of the federate. + char str[INET_ADDRSTRLEN + 1]; + inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); + strncpy(priv->server_hostname, str, INET_ADDRSTRLEN); + + LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); +#endif + return 0; +} + int32_t get_server_port(netdrv_t* drv) { // if (drv == NULL) { // lf_print_warning("Netdriver is closed, returning -1."); @@ -268,3 +268,8 @@ void set_port(netdrv_t* drv, int32_t port) { socket_priv_t* priv = (socket_priv_t*)drv->priv; priv->server_port = port; } + +void set_host_name(netdrv_t* drv, const char* hostname) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + memcpy(priv->server_hostname, hostname, INET_ADDRSTRLEN); +} \ No newline at end of file From 56ff3be892c019c8b2f83e342354ec9f04f5d8c6 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 22:31:14 -0700 Subject: [PATCH 031/167] Add create client. --- core/federated/federate.c | 4 +++- network/impl/src/lf_socket_support.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index cd188c5fe..ad0bf3b2d 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1817,7 +1817,9 @@ void lf_connect_to_rti(const char* hostname, int port) { _fed.netdrv_to_RTI = initialize_netdrv(); set_host_name(_fed.netdrv_to_RTI, hostname); set_port(_fed.netdrv_to_RTI, port); - + + create_client(); + _fed.socket_TCP_RTI = create_real_time_tcp_socket_errexit(); if (connect_to_socket(_fed.socket_TCP_RTI, hostname, port) < 0) { lf_print_error_and_exit("Failed to connect() to RTI."); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index e6a753d77..03cd18223 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -246,6 +246,10 @@ int get_peer_address(netdrv_t* drv) { return 0; } +void create_client(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + priv->socket_descriptor = create_real_time_tcp_socket_errexit(); +} int32_t get_server_port(netdrv_t* drv) { // if (drv == NULL) { // lf_print_warning("Netdriver is closed, returning -1."); From 7001175a310ca4e3ffa2b309d9aba38a124f42b9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 22:47:48 -0700 Subject: [PATCH 032/167] Minor fix setting server port and host name. --- core/federated/RTI/rti_remote.c | 2 +- core/federated/federate.c | 8 ++++---- network/api/net_driver.h | 4 +++- network/impl/src/lf_socket_support.c | 19 +++++++++++++------ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 634a99b06..39847ce31 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -662,7 +662,7 @@ void handle_address_ad(uint16_t federate_id) { assert(server_port < 65536); LF_MUTEX_LOCK(&rti_mutex); - set_port(fed->fed_netdrv, server_port); + set_server_port(fed->fed_netdrv, server_port); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_LOG("Received address advertisement with port %d from federate %d.", server_port, federate_id); diff --git a/core/federated/federate.c b/core/federated/federate.c index ad0bf3b2d..f2efe4edf 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1815,12 +1815,12 @@ void lf_connect_to_rti(const char* hostname, int port) { // Create a network driver. _fed.netdrv_to_RTI = initialize_netdrv(); - set_host_name(_fed.netdrv_to_RTI, hostname); - set_port(_fed.netdrv_to_RTI, port); + // Set the user specified host name and port to the network driver. + set_server_port(_fed.netdrv_to_RTI, hostname); + set_server_host_name(_fed.netdrv_to_RTI, port); + // create_client(); - - _fed.socket_TCP_RTI = create_real_time_tcp_socket_errexit(); if (connect_to_socket(_fed.socket_TCP_RTI, hostname, port) < 0) { lf_print_error_and_exit("Failed to connect() to RTI."); } diff --git a/network/api/net_driver.h b/network/api/net_driver.h index a70abca7e..c6410a0c1 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -139,6 +139,8 @@ struct in_addr* get_ip_addr(netdrv_t* drv); char* get_server_hostname(netdrv_t* drv); -void set_port(netdrv_t* drv, int32_t port); +void set_server_port(netdrv_t* drv, int32_t port); + +void set_server_host_name(netdrv_t* drv, const char* hostname); #endif /* NET_DRIVER_H */ diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 03cd18223..5b5375f15 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -100,6 +100,17 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { return fed_netdrv; } +void create_client(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + priv->socket_descriptor = create_real_time_tcp_socket_errexit(); +} + +int connect_to_netdrv(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + + return connect_to_socket(priv->socket_descriptor, priv->server_hostname, priv->server_port); +} + int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = (socket_priv_t*)drv->priv; int socket = priv->socket_descriptor; @@ -246,10 +257,6 @@ int get_peer_address(netdrv_t* drv) { return 0; } -void create_client(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; - priv->socket_descriptor = create_real_time_tcp_socket_errexit(); -} int32_t get_server_port(netdrv_t* drv) { // if (drv == NULL) { // lf_print_warning("Netdriver is closed, returning -1."); @@ -268,12 +275,12 @@ char* get_server_hostname(netdrv_t* drv) { return priv->server_hostname; } -void set_port(netdrv_t* drv, int32_t port) { +void set_server_port(netdrv_t* drv, int32_t port) { socket_priv_t* priv = (socket_priv_t*)drv->priv; priv->server_port = port; } -void set_host_name(netdrv_t* drv, const char* hostname) { +void set_server_host_name(netdrv_t* drv, const char* hostname) { socket_priv_t* priv = (socket_priv_t*)drv->priv; memcpy(priv->server_hostname, hostname, INET_ADDRSTRLEN); } \ No newline at end of file From caebf9b1e7aa8236e010502f16a555cffd59eeb6 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 22:48:46 -0700 Subject: [PATCH 033/167] Add connect to network driver. --- core/federated/federate.c | 2 +- network/impl/src/lf_socket_support.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index f2efe4edf..f4a07218c 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1819,7 +1819,7 @@ void lf_connect_to_rti(const char* hostname, int port) { set_server_port(_fed.netdrv_to_RTI, hostname); set_server_host_name(_fed.netdrv_to_RTI, port); - // + // Create the client network driver. create_client(); if (connect_to_socket(_fed.socket_TCP_RTI, hostname, port) < 0) { lf_print_error_and_exit("Failed to connect() to RTI."); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 5b5375f15..1001f7a27 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -107,7 +107,6 @@ void create_client(netdrv_t* drv) { int connect_to_netdrv(netdrv_t* drv) { socket_priv_t* priv = (socket_priv_t*)drv->priv; - return connect_to_socket(priv->socket_descriptor, priv->server_hostname, priv->server_port); } From 12a88f0f71ccf323d7574212d517b8915153698c Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 22:49:09 -0700 Subject: [PATCH 034/167] Minor fix. --- core/federated/federate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index f4a07218c..6063b6db2 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1821,7 +1821,7 @@ void lf_connect_to_rti(const char* hostname, int port) { // Create the client network driver. create_client(); - if (connect_to_socket(_fed.socket_TCP_RTI, hostname, port) < 0) { + if (connect_to_netdrv(__fed.netdrv_to_RTI) < 0) { lf_print_error_and_exit("Failed to connect() to RTI."); } From 83cd10e2e45755e679c1fad55f815fa61a82f50e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 22:55:28 -0700 Subject: [PATCH 035/167] Fix all read and write namings. --- core/federated/federate.c | 92 +++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 6063b6db2..13bc08f67 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -116,7 +116,7 @@ static void send_time(unsigned char type, instant_t time) { tracepoint_federate_to_rti(send_TIMESTAMP, _lf_my_fed_id, &tag); LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } @@ -143,7 +143,7 @@ static void send_tag(unsigned char type, tag_t tag) { trace_event_t event_type = (type == MSG_TYPE_NEXT_EVENT_TAG) ? send_NET : send_LTC; // Trace the event when tracing is enabled tracepoint_federate_to_rti(event_type, _lf_my_fed_id, &tag); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } @@ -473,7 +473,7 @@ static int handle_message(int* socket, int fed_id) { // Read the header. size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); unsigned char buffer[bytes_to_read]; - if (read_from_socket_close_on_error(socket, bytes_to_read, buffer)) { + if (read_from_netdrv_close_on_error(socket, bytes_to_read, buffer)) { // Read failed, which means the socket has been closed between reading the // message ID byte and here. return -1; @@ -494,7 +494,7 @@ static int handle_message(int* socket, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_socket_close_on_error(socket, length, message_contents)) { + if (read_from_netdrv_close_on_error(socket, length, message_contents)) { return -1; } // Trace the event when tracing is enabled @@ -531,7 +531,7 @@ static int handle_tagged_message(int* socket, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_socket_close_on_error(socket, bytes_to_read, buffer)) { + if (read_from_netdrv_close_on_error(socket, bytes_to_read, buffer)) { return -1; // Read failed. } @@ -580,7 +580,7 @@ static int handle_tagged_message(int* socket, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_socket_close_on_error(socket, length, message_contents)) { + if (read_from_netdrv_close_on_error(socket, length, message_contents)) { #ifdef FEDERATED_DECENTRALIZED _lf_decrement_tag_barrier_locked(env); #endif @@ -689,7 +689,7 @@ static int handle_tagged_message(int* socket, int fed_id) { static int handle_port_absent_message(int* socket, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_socket_close_on_error(socket, bytes_to_read, buffer)) { + if (read_from_netdrv_close_on_error(socket, bytes_to_read, buffer)) { return -1; } @@ -751,7 +751,7 @@ static void* listen_to_federates(void* _args) { // Read one byte to get the message type. LF_PRINT_DEBUG("Waiting for a P2P message on socket %d.", *socket_id); bool bad_message = false; - if (read_from_socket_close_on_error(socket_id, 1, buffer)) { + if (read_from_netdrv_close_on_error(socket_id, 1, buffer)) { // Socket has been closed. lf_print("Socket from federate %d is closed.", fed_id); // Stop listening to this federate. @@ -852,14 +852,14 @@ static int perform_hmac_authentication() { RAND_bytes(fed_nonce, NONCE_LENGTH); memcpy(&fed_hello_buf[1 + fed_id_length], fed_nonce, NONCE_LENGTH); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, message_length, fed_hello_buf, NULL, "Failed to write nonce."); + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, message_length, fed_hello_buf, NULL, "Failed to write nonce."); // Check HMAC of received FED_RESPONSE message. unsigned int hmac_length = SHA256_HMAC_LENGTH; size_t federation_id_length = strnlen(federation_metadata.federation_id, 255); unsigned char received[1 + NONCE_LENGTH + hmac_length]; - if (read_from_socket_close_on_error(&_fed.socket_TCP_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { + if (read_from_netdrv_close_on_error(&_fed.socket_TCP_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { lf_print_warning("Failed to read RTI response."); return -1; } @@ -893,7 +893,7 @@ static int perform_hmac_authentication() { response[1] = HMAC_DOES_NOT_MATCH; // Ignore errors on writing back. - write_to_socket(_fed.socket_TCP_RTI, 2, response); + write_to_netdrv(_fed.socket_TCP_RTI, 2, response); return -1; } else { LF_PRINT_LOG("HMAC verified."); @@ -907,7 +907,7 @@ static int perform_hmac_authentication() { HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH, &sender[1], &hmac_length); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, 1 + hmac_length, sender, NULL, "Failed to write fed response."); + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, 1 + hmac_length, sender, NULL, "Failed to write fed response."); } return 0; } @@ -931,7 +931,7 @@ static instant_t get_start_time_from_rti(instant_t my_physical_time) { size_t buffer_length = 1 + sizeof(instant_t); unsigned char buffer[buffer_length]; - read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, buffer_length, buffer, NULL, + read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, buffer_length, buffer, NULL, "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); LF_PRINT_DEBUG("Read 9 bytes."); @@ -975,7 +975,7 @@ static void handle_tag_advance_grant(void) { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, "Failed to read tag advance grant from RTI."); tag_t TAG = extract_tag(buffer); @@ -1216,7 +1216,7 @@ static void handle_provisional_tag_advance_grant() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, "Failed to read provisional tag advance grant from RTI."); tag_t PTAG = extract_tag(buffer); @@ -1306,7 +1306,7 @@ static void handle_stop_granted_message() { size_t bytes_to_read = MSG_TYPE_STOP_GRANTED_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, "Failed to read stop granted from RTI."); tag_t received_stop_tag = extract_tag(buffer); @@ -1350,7 +1350,7 @@ static void handle_stop_granted_message() { static void handle_stop_request_message() { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, "Failed to read stop request from RTI."); tag_t tag_to_stop = extract_tag(buffer); @@ -1423,7 +1423,7 @@ static void handle_stop_request_message() { // Send the current logical time to the RTI. LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, &lf_outbound_netdrv_mutex, "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); @@ -1440,7 +1440,7 @@ static void send_resign_signal() { unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_RESIGN; LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netdrv_mutex, "Failed to send MSG_TYPE_RESIGN."); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); LF_PRINT_LOG("Resigned."); @@ -1453,7 +1453,7 @@ static void send_failed_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_FAILED; - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, &(buffer[0]), NULL, + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, &(buffer[0]), NULL, "Failed to send MSG_TYPE_FAILED."); LF_PRINT_LOG("Failed."); } @@ -1488,7 +1488,7 @@ static void* listen_to_rti_TCP(void* args) { } // Read one byte to get the message type. // This will exit if the read fails. - int read_failed = read_from_socket(_fed.socket_TCP_RTI, 1, buffer); + int read_failed = read_from_netdrv(_fed.socket_TCP_RTI, 1, buffer); if (read_failed < 0) { if (errno == ECONNRESET) { lf_print_error("Socket connection to the RTI was closed by the RTI without" @@ -1695,12 +1695,12 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { tracepoint_federate_to_rti(send_ADR_QR, _lf_my_fed_id, NULL); LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netdrv_mutex, "Failed to send address query for federate %d to RTI.", remote_federate_id); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); // Read RTI's response. - read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, sizeof(int32_t) + 1, buffer, NULL, + read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, sizeof(int32_t) + 1, buffer, NULL, "Failed to read the requested port number for federate %d from RTI.", remote_federate_id); @@ -1714,7 +1714,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } port = extract_int32(&buffer[1]); - read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, NULL, + read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, NULL, "Failed to read the IP address for federate %d from RTI.", remote_federate_id); // A reply of -1 for the port means that the RTI does not know @@ -1772,17 +1772,17 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { tracepoint_federate_to_federate(send_FED_ID, _lf_my_fed_id, remote_federate_id, NULL); // No need for a mutex because we have the only handle on the socket. - write_to_socket_fail_on_error(&socket_id, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", + write_to_netdrv_fail_on_error(&socket_id, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", remote_federate_id); - write_to_socket_fail_on_error(&socket_id, federation_id_length, (unsigned char*)federation_metadata.federation_id, + write_to_netdrv_fail_on_error(&socket_id, federation_id_length, (unsigned char*)federation_metadata.federation_id, NULL, "Failed to send federation id to federate %d.", remote_federate_id); - read_from_socket_fail_on_error(&socket_id, 1, (unsigned char*)buffer, NULL, + read_from_netdrv_fail_on_error(&socket_id, 1, (unsigned char*)buffer, NULL, "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", remote_federate_id); if (buffer[0] != MSG_TYPE_ACK) { // Get the error code. - read_from_socket_fail_on_error(&socket_id, 1, (unsigned char*)buffer, NULL, + read_from_netdrv_fail_on_error(&socket_id, 1, (unsigned char*)buffer, NULL, "Failed to read error code from federate %d in response to sending fed_id.", remote_federate_id); lf_print_error("Received MSG_TYPE_REJECT message from remote federate (%d).", buffer[0]); @@ -1863,12 +1863,12 @@ void lf_connect_to_rti(const char* hostname, int port) { tracepoint_federate_to_rti(send_FED_ID, _lf_my_fed_id, NULL); // No need for a mutex here because no other threads are writing to this socket. - if (write_to_socket(_fed.socket_TCP_RTI, 2 + sizeof(uint16_t), buffer)) { + if (write_to_netdrv(_fed.netdrv_to_RTI, 2 + sizeof(uint16_t), buffer)) { continue; // Try again, possibly on a new port. } // Next send the federation ID itself. - if (write_to_socket(_fed.socket_TCP_RTI, federation_id_length, (unsigned char*)federation_metadata.federation_id)) { + if (write_to_netdrv(_fed.netdrv_to_RTI, federation_id_length, (unsigned char*)federation_metadata.federation_id)) { continue; // Try again. } @@ -1880,7 +1880,7 @@ void lf_connect_to_rti(const char* hostname, int port) { LF_PRINT_DEBUG("Waiting for response to federation ID from the RTI."); - if (read_from_socket(_fed.socket_TCP_RTI, 1, &response)) { + if (read_from_netdrv(_fed.netdrv_to_RTI, 1, &response)) { continue; // Try again. } if (response == MSG_TYPE_REJECT) { @@ -1888,7 +1888,7 @@ void lf_connect_to_rti(const char* hostname, int port) { tracepoint_federate_from_rti(receive_REJECT, _lf_my_fed_id, NULL); // Read one more byte to determine the cause of rejection. unsigned char cause; - read_from_socket_fail_on_error(&_fed.socket_TCP_RTI, 1, &cause, NULL, + read_from_netdrv_fail_on_error(&_fed.netdrv_to_RTI, 1, &cause, NULL, "Failed to read the cause of rejection by the RTI."); if (cause == FEDERATION_ID_DOES_NOT_MATCH || cause == WRONG_SERVER) { lf_print_warning("Connected to the wrong RTI. Will try again"); @@ -1912,7 +1912,7 @@ void lf_connect_to_rti(const char* hostname, int port) { // about connections between this federate and other federates // where messages are routed through the RTI. // @see MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h - lf_send_neighbor_structure_to_RTI(_fed.socket_TCP_RTI); + lf_send_neighbor_structure_to_RTI(_fed.netdrv_to_RTI); uint16_t udp_port = setup_clock_synchronization_with_rti(); @@ -1920,7 +1920,7 @@ void lf_connect_to_rti(const char* hostname, int port) { unsigned char UDP_port_number[1 + sizeof(uint16_t)]; UDP_port_number[0] = MSG_TYPE_UDP_PORT; encode_uint16(udp_port, &(UDP_port_number[1])); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, + write_to_netdrv_fail_on_error(&_fed.netdrv_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, "Failed to send the UDP port number to the RTI."); } @@ -1941,7 +1941,7 @@ void lf_create_server(int specified_port) { tracepoint_federate_to_rti(send_ADR_AD, _lf_my_fed_id, NULL); // No need for a mutex because we have the only handle on this socket. - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, "Failed to send address advertisement."); LF_PRINT_DEBUG("Sent port %d to the RTI.", _fed.server_port); @@ -1987,7 +1987,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { size_t header_length = 1 + sizeof(uint16_t) + 1; unsigned char buffer[header_length]; - int read_failed = read_from_socket(socket_id, header_length, (unsigned char*)&buffer); + int read_failed = read_from_netdrv(socket_id, header_length, (unsigned char*)&buffer); if (read_failed || buffer[0] != MSG_TYPE_P2P_SENDING_FED_ID) { lf_print_warning("Federate received invalid first message on P2P socket. Closing socket."); if (read_failed == 0) { @@ -1998,7 +1998,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_socket(socket_id, 2, response); + write_to_netdrv(socket_id, 2, response); } shutdown_socket(&socket_id, false); continue; @@ -2007,7 +2007,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Get the federation ID and check it. unsigned char federation_id_length = buffer[header_length - 1]; char remote_federation_id[federation_id_length]; - read_failed = read_from_socket(socket_id, federation_id_length, (unsigned char*)remote_federation_id); + read_failed = read_from_netdrv(socket_id, federation_id_length, (unsigned char*)remote_federation_id); if (read_failed || (strncmp(federation_metadata.federation_id, remote_federation_id, strnlen(federation_metadata.federation_id, 255)) != 0)) { lf_print_warning("Received invalid federation ID. Closing socket."); @@ -2018,7 +2018,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_socket(socket_id, 2, response); + write_to_netdrv(socket_id, 2, response); } shutdown_socket(&socket_id, false); continue; @@ -2045,7 +2045,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_socket_fail_on_error(&_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, + write_to_netdrv_fail_on_error(&_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, &lf_outbound_netdrv_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); @@ -2173,10 +2173,10 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_P2P_MSG, _lf_my_fed_id, federate, NULL); - int result = write_to_socket_close_on_error(socket, header_length, header_buffer); + int result = write_to_netdrv_close_on_error(socket, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_socket_close_on_error(socket, length, message); + result = write_to_netdrv_close_on_error(socket, length, message); } if (result != 0) { // Message did not send. Since this is used for physical connections, this is not critical. @@ -2358,7 +2358,7 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d } LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - int result = write_to_socket_close_on_error(socket, message_length, buffer); + int result = write_to_netdrv_close_on_error(socket, message_length, buffer); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); if (result != 0) { @@ -2396,7 +2396,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_STOP_REQ, _lf_my_fed_id, &stop_tag); - write_to_socket_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_netdrv_mutex, "Failed to send stop time " PRINTF_TIME " to the RTI.", stop_tag.time - start_time); // Treat this sending as equivalent to having received a stop request from the RTI. @@ -2468,10 +2468,10 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int tracepoint_federate_to_rti(send_TAGGED_MSG, _lf_my_fed_id, ¤t_message_intended_tag); } - int result = write_to_socket_close_on_error(socket, header_length, header_buffer); + int result = write_to_netdrv_close_on_error(socket, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_socket_close_on_error(socket, length, message); + result = write_to_netdrv_close_on_error(socket, length, message); } if (result != 0) { // Message did not send. Handling depends on message type. From 9d47c70cbefeb924994bb7295defba3be7dbac82 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 22:55:43 -0700 Subject: [PATCH 036/167] Fix parameter on lf_send_neighbor_structure_to_RTI --- include/core/federated/federate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index 0a62dba43..b2432e6f2 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -339,7 +339,7 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa * information is needed for the RTI to perform the centralized coordination. * @see MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h */ -void lf_send_neighbor_structure_to_RTI(int); +void lf_send_neighbor_structure_to_RTI(netdrv_t*); /** * @brief Send a next event tag (NET) signal. From 4b172d15e044ddeab49fc5a0ea8ede483e088bfd Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 23:02:04 -0700 Subject: [PATCH 037/167] Change socket_mutex to netdrv_mutex --- core/federated/clock-sync.c | 2 +- core/federated/federate.c | 10 +++++----- include/core/federated/clock-sync.h | 2 +- network/api/socket_common.h | 2 +- network/impl/src/socket_common.c | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index 60a7bd16f..f4b578cf5 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -304,7 +304,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, int socket, instant_t t2 * the T4 and the coded probe message is not as expected, then reject * this clock synchronization round. If it is not rejected, then make * an adjustment to the clock offset based on the estimated error. - * This function does not acquire the socket_mutex lock. + * This function does not acquire the netdrv_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. * @param socket The socket (either _lf_rti_socket_TCP or _lf_rti_socket_UDP). diff --git a/core/federated/federate.c b/core/federated/federate.c index 13bc08f67..a8d35eb2e 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -410,11 +410,11 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen * federate. */ static void close_inbound_socket(int fed_id) { - LF_MUTEX_LOCK(&socket_mutex); + LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] >= 0) { shutdown_socket(&_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); } - LF_MUTEX_UNLOCK(&socket_mutex); + LF_MUTEX_UNLOCK(&netdrv_mutex); } /** @@ -2032,7 +2032,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { tracepoint_federate_to_federate(receive_FED_ID, _lf_my_fed_id, remote_fed_id, NULL); // Once we record the socket_id here, all future calls to close() on - // the socket should be done while holding the socket_mutex, and this array + // the socket should be done while holding the netdrv_mutex, and this array // element should be reset to -1 during that critical section. // Otherwise, there can be race condition where, during termination, // two threads attempt to simultaneously close the socket. @@ -2056,12 +2056,12 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { int result = lf_thread_create(&_fed.inbound_netdriv_listeners[received_federates], listen_to_federates, fed_id_arg); if (result != 0) { // Failed to create a listening thread. - LF_MUTEX_LOCK(&socket_mutex); + LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] != -1) { shutdown_socket(&socket_id, false); _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = -1; } - LF_MUTEX_UNLOCK(&socket_mutex); + LF_MUTEX_UNLOCK(&netdrv_mutex); lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", result); } diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index b003a3150..1b0cacd3e 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -190,7 +190,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, int socket, instant_t t2 * the T4 and the coded probe message is not as expected, then reject * this clock synchronization round. If it is not rejected, then make * an adjustment to the clock offset based on the estimated error. - * This function does not acquire the socket_mutex lock. + * This function does not acquire the netdrv_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. * @param socket The socket (either _lf_rti_socket_TCP or _lf_rti_socket_UDP). diff --git a/network/api/socket_common.h b/network/api/socket_common.h index fd91640ac..63665942b 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -74,7 +74,7 @@ typedef enum socket_type_t { TCP, UDP } socket_type_t; /** * Mutex protecting socket close operations. */ -extern lf_mutex_t socket_mutex; +extern lf_mutex_t netdrv_mutex; typedef struct socket_priv_t { int socket_descriptor; diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 202ad1125..279cb51ef 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -20,9 +20,9 @@ /** Number of nanoseconds to sleep before retrying a socket read. */ #define SOCKET_READ_RETRY_INTERVAL 1000000 -// Mutex lock held while performing socket close operations. -// A deadlock can occur if two threads simulataneously attempt to close the same socket. -lf_mutex_t socket_mutex; +// Mutex lock held while performing networ driver close operations. +// A deadlock can occur if two threads simulataneously attempt to close the same network driver. +lf_mutex_t netdrv_mutex; int create_real_time_tcp_socket_errexit() { int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); From 9dbf5be93511129af5cce2fefd89cc20cbf34272 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 23:11:14 -0700 Subject: [PATCH 038/167] Remove server_type. just leave it as true false for increment on retry. --- core/federated/RTI/rti_remote.c | 2 +- core/federated/clock-sync.c | 1 + core/federated/federate.c | 7 ++++--- network/api/net_driver.h | 3 +-- network/impl/src/lf_socket_support.c | 3 +-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 39847ce31..38de11ef5 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1489,7 +1489,7 @@ int start_rti_server() { // Initialize RTI's network driver. rti_remote->rti_netdrv = initialize_netdrv(); // Create the server - if (create_server_(rti_remote->rti_netdrv, RTI)) { + if (create_server_(rti_remote->rti_netdrv, true)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); return -1; }; diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index f4b578cf5..cd95aa0b2 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -208,6 +208,7 @@ uint16_t setup_clock_synchronization_with_rti() { return port_to_return; } +//TODO: Fix clocks. void synchronize_initial_physical_clock_with_rti(int* rti_socket_TCP) { LF_PRINT_DEBUG("Waiting for initial clock synchronization messages from the RTI."); diff --git a/core/federated/federate.c b/core/federated/federate.c index a8d35eb2e..74443c0d5 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1811,8 +1811,6 @@ void lf_connect_to_rti(const char* hostname, int port) { hostname = federation_metadata.rti_host ? federation_metadata.rti_host : hostname; port = federation_metadata.rti_port >= 0 ? federation_metadata.rti_port : port; - - // Create a network driver. _fed.netdrv_to_RTI = initialize_netdrv(); // Set the user specified host name and port to the network driver. @@ -1926,7 +1924,10 @@ void lf_connect_to_rti(const char* hostname, int port) { void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); - if (create_server(specified_port, &_fed.server_socket, (uint16_t*)&_fed.server_port, TCP, false)) { + + netdrv_t* server_netdrv = initialize_netdrv(); + + if (create_server_(server_netdrv, false)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); }; LF_PRINT_LOG("Server for communicating with other federates started using port %d.", _fed.server_port); diff --git a/network/api/net_driver.h b/network/api/net_driver.h index c6410a0c1..e2a0a9606 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -3,7 +3,6 @@ #include "socket_common.h" -typedef enum server_type_t { RTI, FED } server_type_t; typedef struct netdrv_t { void* priv; // unsigned int read_remaining_bytes; @@ -25,7 +24,7 @@ netdrv_t* initialize_netdrv(); * @param serv_type Type of server, RTI or FED. * @return int 0 for success, -1 for failure. */ -int create_server_(netdrv_t* drv, server_type_t serv_type); +int create_server_(netdrv_t* drv, bool increment_port_on_retry); netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 1001f7a27..c71f5763e 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -34,7 +34,7 @@ netdrv_t* initialize_netdrv() { return drv; } -int create_server_(netdrv_t* drv, server_type_t serv_type) { +int create_server_(netdrv_t* drv, bool increment_port_on_retry) { socket_priv_t* priv = (socket_priv_t*)drv->priv; int socket_descriptor; struct timeval timeout_time; @@ -47,7 +47,6 @@ int create_server_(netdrv_t* drv, server_type_t serv_type) { return -1; } set_socket_timeout_option(socket_descriptor, &timeout_time); - bool increment_port_on_retry = (serv_type == RTI) ? true : false; int used_port = set_socket_bind_option(socket_descriptor, priv->user_specified_port, increment_port_on_retry); // Enable listening for socket connections. From df0c3ef920032a9bace21617f6f06b2ec9e71f48 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 23:30:58 -0700 Subject: [PATCH 039/167] Fix lf_create_server. --- core/federated/federate.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 74443c0d5..f316ee41c 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1926,26 +1926,30 @@ void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); netdrv_t* server_netdrv = initialize_netdrv(); + set_server_port(server_netdrv, specified_port); if (create_server_(server_netdrv, false)) { - lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); + lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); }; - LF_PRINT_LOG("Server for communicating with other federates started using port %d.", _fed.server_port); + // Get the final server port set. + int32_t server_port = get_server_port(server_netdrv); + + LF_PRINT_LOG("Server for communicating with other federates started using port %d.", server_port); // Send the server port number to the RTI // on an MSG_TYPE_ADDRESS_ADVERTISEMENT message (@see net_common.h). unsigned char buffer[sizeof(int32_t) + 1]; buffer[0] = MSG_TYPE_ADDRESS_ADVERTISEMENT; - encode_int32(_fed.server_port, &(buffer[1])); + encode_int32(server_port, &(buffer[1])); // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_AD, _lf_my_fed_id, NULL); // No need for a mutex because we have the only handle on this socket. - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, + write_to_netdrv_fail_on_error(server_netdrv, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, "Failed to send address advertisement."); - LF_PRINT_DEBUG("Sent port %d to the RTI.", _fed.server_port); + LF_PRINT_DEBUG("Sent port %d to the RTI.", server_port); } void lf_enqueue_port_absent_reactions(environment_t* env) { From df2bcd587c40c5fa644c8a294fadd8d28c836623 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 23:33:21 -0700 Subject: [PATCH 040/167] Add setting server netdriver to federate. --- core/federated/federate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/federated/federate.c b/core/federated/federate.c index f316ee41c..67617af0f 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1931,6 +1931,7 @@ void lf_create_server(int specified_port) { if (create_server_(server_netdrv, false)) { lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); }; + _fed.server_netdrv = server_netdrv; // Get the final server port set. int32_t server_port = get_server_port(server_netdrv); From 6cc28d55893b70598e254e0b44aa4a1763b2c212 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 23:43:37 -0700 Subject: [PATCH 041/167] Fix on accept netdriver, to return NULL, when failed to accept. --- core/federated/federate.c | 25 +++++++++++++------------ network/impl/src/lf_socket_support.c | 6 ++++-- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 67617af0f..4510b5548 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1984,8 +1984,9 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { _fed.inbound_netdriv_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); while (received_federates < _fed.number_of_inbound_p2p_connections && !_lf_termination_executed) { // Wait for an incoming connection request. - int socket_id = accept_socket(_fed.server_socket, _fed.socket_TCP_RTI); - if (socket_id < 0) { + netdrv_t* netdrv = accept_netdrv(_fed.server_netdrv, _fed.netdrv_to_RTI); + // int socket_id = accept_socket(_fed.server_socket, _fed.socket_TCP_RTI); + if (netdrv == NULL) { lf_print_warning("Federate failed to accept the socket."); return NULL; } @@ -1993,7 +1994,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { size_t header_length = 1 + sizeof(uint16_t) + 1; unsigned char buffer[header_length]; - int read_failed = read_from_netdrv(socket_id, header_length, (unsigned char*)&buffer); + int read_failed = read_from_netdrv(netdrv, header_length, (unsigned char*)&buffer); if (read_failed || buffer[0] != MSG_TYPE_P2P_SENDING_FED_ID) { lf_print_warning("Federate received invalid first message on P2P socket. Closing socket."); if (read_failed == 0) { @@ -2004,7 +2005,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_netdrv(socket_id, 2, response); + write_to_netdrv(netdrv, 2, response); } shutdown_socket(&socket_id, false); continue; @@ -2013,7 +2014,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Get the federation ID and check it. unsigned char federation_id_length = buffer[header_length - 1]; char remote_federation_id[federation_id_length]; - read_failed = read_from_netdrv(socket_id, federation_id_length, (unsigned char*)remote_federation_id); + read_failed = read_from_netdrv(netdrv, federation_id_length, (unsigned char*)remote_federation_id); if (read_failed || (strncmp(federation_metadata.federation_id, remote_federation_id, strnlen(federation_metadata.federation_id, 255)) != 0)) { lf_print_warning("Received invalid federation ID. Closing socket."); @@ -2024,7 +2025,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_netdrv(socket_id, 2, response); + write_to_netdrv(netdrv, 2, response); } shutdown_socket(&socket_id, false); continue; @@ -2037,12 +2038,12 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(receive_FED_ID, _lf_my_fed_id, remote_fed_id, NULL); - // Once we record the socket_id here, all future calls to close() on - // the socket should be done while holding the netdrv_mutex, and this array + // Once we record the network driver here, all future calls to close() on + // the network driver should be done while holding the netdrv_mutex, and this array // element should be reset to -1 during that critical section. // Otherwise, there can be race condition where, during termination, - // two threads attempt to simultaneously close the socket. - _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = socket_id; + // two threads attempt to simultaneously close the network driver. + _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = netdrv; // Send an MSG_TYPE_ACK message. unsigned char response = MSG_TYPE_ACK; @@ -2063,9 +2064,9 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { if (result != 0) { // Failed to create a listening thread. LF_MUTEX_LOCK(&netdrv_mutex); - if (_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] != -1) { + if (_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] != NULL) { shutdown_socket(&socket_id, false); - _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = -1; + _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = NULL; } LF_MUTEX_UNLOCK(&netdrv_mutex); lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index c71f5763e..185cdead6 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -79,15 +79,17 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { break; } else if (socket_id < 0 && (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR)) { lf_print_warning("Failed to accept the socket. %s.", strerror(errno)); - break; + //TODO: Must free memory. + return NULL; } else if (errno == EPERM) { lf_print_error_system_failure("Firewall permissions prohibit connection."); + return NULL; } else { // For the federates, it should check if the rti_socket is still open, before retrying accept(). socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; if (rti_priv->socket_descriptor != -1) { if (check_socket_closed(rti_priv->socket_descriptor)) { - break; + return NULL; } } // Try again From bde87c4494e5695a35a6cb2a8b18c052e645164a Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 18 Jan 2025 23:55:33 -0700 Subject: [PATCH 042/167] Add free_netdrv() --- core/federated/federate.c | 18 +++++++++--------- network/impl/src/lf_socket_support.c | 19 ++++++++++++++++--- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 4510b5548..35f1bea80 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -412,7 +412,7 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen static void close_inbound_socket(int fed_id) { LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] >= 0) { - shutdown_socket(&_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); + shutdown_netdrv(&_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); } LF_MUTEX_UNLOCK(&netdrv_mutex); } @@ -826,11 +826,11 @@ static void close_outbound_socket(int fed_id) { if (_fed.netdrvs_for_outbound_p2p_connections[fed_id] >= 0) { // Close the socket by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. - shutdown_socket(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); + shutdown_netdrv(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); } LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } else { - shutdown_socket(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); + shutdown_netdrv(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); } } @@ -1494,7 +1494,7 @@ static void* listen_to_rti_TCP(void* args) { lf_print_error("Socket connection to the RTI was closed by the RTI without" " properly sending an EOF first. Considering this a soft error."); // FIXME: If this happens, possibly a new RTI must be elected. - shutdown_socket(&_fed.socket_TCP_RTI, false); + shutdown_netdrv(&_fed.socket_TCP_RTI, false); return NULL; } else { lf_print_error("Socket connection to the RTI has been broken with error %d: %s." @@ -1502,13 +1502,13 @@ static void* listen_to_rti_TCP(void* args) { " Considering this a soft error.", errno, strerror(errno)); // FIXME: If this happens, possibly a new RTI must be elected. - shutdown_socket(&_fed.socket_TCP_RTI, false); + shutdown_netdrv(&_fed.socket_TCP_RTI, false); return NULL; } } else if (read_failed > 0) { // EOF received. lf_print("Connection to the RTI closed with an EOF."); - shutdown_socket(&_fed.socket_TCP_RTI, false); + shutdown_netdrv(&_fed.socket_TCP_RTI, false); return NULL; } switch (buffer[0]) { @@ -2007,7 +2007,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Ignore errors on this response. write_to_netdrv(netdrv, 2, response); } - shutdown_socket(&socket_id, false); + shutdown_netdrv(netdrv, false); continue; } @@ -2027,7 +2027,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Ignore errors on this response. write_to_netdrv(netdrv, 2, response); } - shutdown_socket(&socket_id, false); + shutdown_netdrv(netdrv, false); continue; } @@ -2065,7 +2065,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Failed to create a listening thread. LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] != NULL) { - shutdown_socket(&socket_id, false); + shutdown_netdrv(&socket_id, false); _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = NULL; } LF_MUTEX_UNLOCK(&netdrv_mutex); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 185cdead6..97fbfd9d5 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -34,6 +34,12 @@ netdrv_t* initialize_netdrv() { return drv; } +void free_netdrv(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + free(priv); + free(drv); +} + int create_server_(netdrv_t* drv, bool increment_port_on_retry) { socket_priv_t* priv = (socket_priv_t*)drv->priv; int socket_descriptor; @@ -79,16 +85,18 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { break; } else if (socket_id < 0 && (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR)) { lf_print_warning("Failed to accept the socket. %s.", strerror(errno)); - //TODO: Must free memory. + free_netdrv(fed_netdrv); return NULL; } else if (errno == EPERM) { lf_print_error_system_failure("Firewall permissions prohibit connection."); + free_netdrv(fed_netdrv); return NULL; } else { // For the federates, it should check if the rti_socket is still open, before retrying accept(). socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; if (rti_priv->socket_descriptor != -1) { if (check_socket_closed(rti_priv->socket_descriptor)) { + free_netdrv(fed_netdrv); return NULL; } } @@ -232,7 +240,12 @@ void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { socket_priv_t* priv = (socket_priv_t*)drv->priv; - return shutdown_socket(&priv->socket_descriptor, read_before_closing); + int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); + if (ret != 0) { + lf_print_error("Failed to shutdown socket."); + } + free_netdrv(drv); + return ret; } int get_peer_address(netdrv_t* drv) { @@ -283,4 +296,4 @@ void set_server_port(netdrv_t* drv, int32_t port) { void set_server_host_name(netdrv_t* drv, const char* hostname) { socket_priv_t* priv = (socket_priv_t*)drv->priv; memcpy(priv->server_hostname, hostname, INET_ADDRSTRLEN); -} \ No newline at end of file +} From 96567d6261177076f5b320b05ca6a9b7344b7bd0 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 00:37:39 -0700 Subject: [PATCH 043/167] Add get_socket_id() --- network/api/net_driver.h | 2 ++ network/impl/src/lf_socket_support.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index e2a0a9606..44a95cf25 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -138,6 +138,8 @@ struct in_addr* get_ip_addr(netdrv_t* drv); char* get_server_hostname(netdrv_t* drv); +int get_socket_id(netdrv_t* drv); + void set_server_port(netdrv_t* drv, int32_t port); void set_server_host_name(netdrv_t* drv, const char* hostname); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 97fbfd9d5..9b29a64ef 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -288,6 +288,11 @@ char* get_server_hostname(netdrv_t* drv) { return priv->server_hostname; } +int get_socket_id(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + return priv->socket_descriptor; +} + void set_server_port(netdrv_t* drv, int32_t port) { socket_priv_t* priv = (socket_priv_t*)drv->priv; priv->server_port = port; From 21d2f2334440857f55afd3e1f425c8a962dd1049 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 00:38:45 -0700 Subject: [PATCH 044/167] Fix on listen_to_federates and lf_connect_to_federate --- core/federated/federate.c | 118 +++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 54 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 35f1bea80..c8e553339 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -409,10 +409,10 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen * @param fed_id The ID of the peer federate sending messages to this * federate. */ -static void close_inbound_socket(int fed_id) { +static void close_inbound_netdrv(int fed_id) { LF_MUTEX_LOCK(&netdrv_mutex); - if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] >= 0) { - shutdown_netdrv(&_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); + if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] != NULL) { + shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); } LF_MUTEX_UNLOCK(&netdrv_mutex); } @@ -464,17 +464,17 @@ static bool handle_message_now(environment_t* env, trigger_t* trigger, tag_t int * Handle a message being received from a remote federate. * * This function assumes the caller does not hold the mutex lock. - * @param socket Pointer to the socket to read the message from. + * @param netdrv Pointer to the network driver to read the message from. * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure. */ -static int handle_message(int* socket, int fed_id) { +static int handle_message(netdrv_t* netdrv, int fed_id) { (void)fed_id; // Read the header. size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); unsigned char buffer[bytes_to_read]; - if (read_from_netdrv_close_on_error(socket, bytes_to_read, buffer)) { - // Read failed, which means the socket has been closed between reading the + if (read_from_netdrv_close_on_error(netdrv, bytes_to_read, buffer)) { + // Read failed, which means the network driver has been closed between reading the // message ID byte and here. return -1; } @@ -494,7 +494,7 @@ static int handle_message(int* socket, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_netdrv_close_on_error(socket, length, message_contents)) { + if (read_from_netdrv_close_on_error(netdrv, length, message_contents)) { return -1; } // Trace the event when tracing is enabled @@ -518,11 +518,11 @@ static int handle_message(int* socket, int fed_id) { * will not advance to the tag of the message if it is in the future, or * the tag will not advance at all if the tag of the message is * now or in the past. - * @param socket Pointer to the socket to read the message from. + * @param netdrv Pointer to the network driver to read the message from. * @param fed_id The sending federate ID or -1 if the centralized coordination. - * @return 0 on successfully reading the message, -1 on failure (e.g. due to socket closed). + * @return 0 on successfully reading the message, -1 on failure (e.g. due to network driver closed). */ -static int handle_tagged_message(int* socket, int fed_id) { +static int handle_tagged_message(netdrv_t* netdrv, int fed_id) { // Environment is always the one corresponding to the top-level scheduling enclave. environment_t* env; _lf_get_environments(&env); @@ -531,7 +531,7 @@ static int handle_tagged_message(int* socket, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_netdrv_close_on_error(socket, bytes_to_read, buffer)) { + if (read_from_netdrv_close_on_error(netdrv, bytes_to_read, buffer)) { return -1; // Read failed. } @@ -580,7 +580,7 @@ static int handle_tagged_message(int* socket, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_netdrv_close_on_error(socket, length, message_contents)) { + if (read_from_netdrv_close_on_error(netdrv, length, message_contents)) { #ifdef FEDERATED_DECENTRALIZED _lf_decrement_tag_barrier_locked(env); #endif @@ -649,11 +649,11 @@ static int handle_tagged_message(int* socket, int fed_id) { if (lf_tag_compare(env->current_tag, env->stop_tag) >= 0 && env->execution_started) { lf_print_error("Received message too late. Already at stop tag.\n" " Current tag is " PRINTF_TAG " and intended tag is " PRINTF_TAG ".\n" - " Discarding message and closing the socket.", + " Discarding message and closing the network driver.", env->current_tag.time - start_time, env->current_tag.microstep, intended_tag.time - start_time, intended_tag.microstep); - // Close socket, reading any incoming data and discarding it. - close_inbound_socket(fed_id); + // Close network driver, reading any incoming data and discarding it. + close_inbound_netdrv(fed_id); } else { // Need to use intended_tag here, not actual_tag, so that STP violations are detected. // It will become actual_tag (that is when the reactions will be invoked). @@ -682,14 +682,14 @@ static int handle_tagged_message(int* socket, int fed_id) { * This just sets the last known status tag of the port specified * in the message. * - * @param socket Pointer to the socket to read the message from + * @param netdrv Pointer to the network driver to read the message from * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure to complete the read. */ -static int handle_port_absent_message(int* socket, int fed_id) { +static int handle_port_absent_message(netdrv_t* netdrv, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_netdrv_close_on_error(socket, bytes_to_read, buffer)) { + if (read_from_netdrv_close_on_error(netdrv, bytes_to_read, buffer)) { return -1; } @@ -726,7 +726,7 @@ static int handle_port_absent_message(int* socket, int fed_id) { * peer federate and calls the appropriate handling function for * each message type. If an error occurs or an EOF is received * from the peer, then this procedure sets the corresponding - * socket in _fed.netdrvs_for_inbound_p2p_connections + * network driver in _fed.netdrvs_for_inbound_p2p_connections * to -1 and returns, terminating the thread. * @param _args The remote federate ID (cast to void*). * @param fed_id_ptr A pointer to a uint16_t containing federate ID being listened to. @@ -738,53 +738,55 @@ static void* listen_to_federates(void* _args) { LF_PRINT_LOG("Listening to federate %d.", fed_id); - int* socket_id = &_fed.netdrvs_for_inbound_p2p_connections[fed_id]; + netdrv_t* netdrv = _fed.netdrvs_for_inbound_p2p_connections[fed_id]; // Buffer for incoming messages. // This does not constrain the message size // because the message will be put into malloc'd memory. unsigned char buffer[FED_COM_BUFFER_SIZE]; + int socket_id = get_socket_id(netdrv); + // Listen for messages from the federate. while (1) { - bool socket_closed = false; + bool netdrv_closed = false; // Read one byte to get the message type. - LF_PRINT_DEBUG("Waiting for a P2P message on socket %d.", *socket_id); + LF_PRINT_DEBUG("Waiting for a P2P message on socket %d.", socket_id); bool bad_message = false; - if (read_from_netdrv_close_on_error(socket_id, 1, buffer)) { - // Socket has been closed. - lf_print("Socket from federate %d is closed.", fed_id); + if (read_from_netdrv_close_on_error(netdrv, 1, buffer)) { + // Network driver has been closed. + lf_print("Network driver from federate %d is closed.", fed_id); // Stop listening to this federate. - socket_closed = true; + netdrv_closed = true; } else { - LF_PRINT_DEBUG("Received a P2P message on socket %d of type %d.", *socket_id, buffer[0]); + LF_PRINT_DEBUG("Received a P2P message on socket %d of type %d.", socket_id, buffer[0]); switch (buffer[0]) { case MSG_TYPE_P2P_MESSAGE: LF_PRINT_LOG("Received untimed message from federate %d.", fed_id); - if (handle_message(socket_id, fed_id)) { + if (handle_message(netdrv, fed_id)) { // Failed to complete the reading of a message on a physical connection. lf_print_warning("Failed to complete reading of message on physical connection."); - socket_closed = true; + netdrv_closed = true; } break; case MSG_TYPE_P2P_TAGGED_MESSAGE: LF_PRINT_LOG("Received tagged message from federate %d.", fed_id); - if (handle_tagged_message(socket_id, fed_id)) { + if (handle_tagged_message(netdrv, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and // it is not a fatal error if the socket is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); - socket_closed = true; + netdrv_closed = true; } break; case MSG_TYPE_PORT_ABSENT: LF_PRINT_LOG("Received port absent message from federate %d.", fed_id); - if (handle_port_absent_message(socket_id, fed_id)) { + if (handle_port_absent_message(netdrv, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and // it is not a fatal error if the socket is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); - socket_closed = true; + netdrv_closed = true; } break; default: @@ -797,7 +799,7 @@ static void* listen_to_federates(void* _args) { tracepoint_federate_from_federate(receive_UNIDENTIFIED, _lf_my_fed_id, fed_id, NULL); break; // while loop } - if (socket_closed) { + if (netdrv_closed) { // For decentralized execution, once this socket is closed, we // update last known tags of all ports connected to the specified federate to FOREVER_TAG, // which would eliminate the need to wait for STAA to assume an input is absent. @@ -1695,12 +1697,12 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { tracepoint_federate_to_rti(send_ADR_QR, _lf_my_fed_id, NULL); LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netdrv_mutex, "Failed to send address query for federate %d to RTI.", remote_federate_id); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); // Read RTI's response. - read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, sizeof(int32_t) + 1, buffer, NULL, + read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, sizeof(int32_t) + 1, buffer, NULL, "Failed to read the requested port number for federate %d from RTI.", remote_federate_id); @@ -1714,7 +1716,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } port = extract_int32(&buffer[1]); - read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, NULL, + read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, NULL, "Failed to read the IP address for federate %d from RTI.", remote_federate_id); // A reply of -1 for the port means that the RTI does not know @@ -1735,10 +1737,18 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { char hostname[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &host_ip_addr, hostname, INET_ADDRSTRLEN); - int socket_id = create_real_time_tcp_socket_errexit(); - if (connect_to_socket(socket_id, (const char*)hostname, uport) < 0) { + + // Create a network driver. + netdrv_t* netdrv = initialize_netdrv(); + // Set the received host name and port to the network driver. + set_server_port(netdrv, uport); + set_server_host_name(netdrv, hostname); + // Create the client network driver. + create_client(netdrv); + if (connect_to_netdrv(netdrv) < 0) { lf_print_error_and_exit("Failed to connect() to RTI."); } + // Iterate until we either successfully connect or we exceed the CONNECT_TIMEOUT start_connect = lf_time_physical(); while (result < 0 && !_lf_termination_executed) { @@ -1755,6 +1765,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } // Check whether the RTI is still there. + // TODO: Fix. if (rti_failed()) { break; } @@ -1772,17 +1783,17 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { tracepoint_federate_to_federate(send_FED_ID, _lf_my_fed_id, remote_federate_id, NULL); // No need for a mutex because we have the only handle on the socket. - write_to_netdrv_fail_on_error(&socket_id, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", + write_to_netdrv_fail_on_error(netdrv, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", remote_federate_id); - write_to_netdrv_fail_on_error(&socket_id, federation_id_length, (unsigned char*)federation_metadata.federation_id, - NULL, "Failed to send federation id to federate %d.", remote_federate_id); + write_to_netdrv_fail_on_error(netdrv, federation_id_length, (unsigned char*)federation_metadata.federation_id, NULL, + "Failed to send federation id to federate %d.", remote_federate_id); - read_from_netdrv_fail_on_error(&socket_id, 1, (unsigned char*)buffer, NULL, + read_from_netdrv_fail_on_error(netdrv, 1, (unsigned char*)buffer, NULL, "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", remote_federate_id); if (buffer[0] != MSG_TYPE_ACK) { // Get the error code. - read_from_netdrv_fail_on_error(&socket_id, 1, (unsigned char*)buffer, NULL, + read_from_netdrv_fail_on_error(netdrv, 1, (unsigned char*)buffer, NULL, "Failed to read error code from federate %d in response to sending fed_id.", remote_federate_id); lf_print_error("Received MSG_TYPE_REJECT message from remote federate (%d).", buffer[0]); @@ -1800,8 +1811,8 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } } // Once we set this variable, then all future calls to close() on this - // socket ID should reset it to -1 within a critical section. - _fed.netdrvs_for_outbound_p2p_connections[remote_federate_id] = socket_id; + // network driver should reset it to NULL within a critical section. + _fed.netdrvs_for_outbound_p2p_connections[remote_federate_id] = netdrv; } void lf_connect_to_rti(const char* hostname, int port) { @@ -1814,11 +1825,11 @@ void lf_connect_to_rti(const char* hostname, int port) { // Create a network driver. _fed.netdrv_to_RTI = initialize_netdrv(); // Set the user specified host name and port to the network driver. - set_server_port(_fed.netdrv_to_RTI, hostname); - set_server_host_name(_fed.netdrv_to_RTI, port); + set_server_port(_fed.netdrv_to_RTI, port); + set_server_host_name(_fed.netdrv_to_RTI, hostname); // Create the client network driver. - create_client(); + create_client(_fed.netdrv_to_RTI); if (connect_to_netdrv(__fed.netdrv_to_RTI) < 0) { lf_print_error_and_exit("Failed to connect() to RTI."); } @@ -1860,7 +1871,7 @@ void lf_connect_to_rti(const char* hostname, int port) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_FED_ID, _lf_my_fed_id, NULL); - // No need for a mutex here because no other threads are writing to this socket. + // No need for a mutex here because no other threads are writing to this network driver. if (write_to_netdrv(_fed.netdrv_to_RTI, 2 + sizeof(uint16_t), buffer)) { continue; // Try again, possibly on a new port. } @@ -1985,7 +1996,6 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { while (received_federates < _fed.number_of_inbound_p2p_connections && !_lf_termination_executed) { // Wait for an incoming connection request. netdrv_t* netdrv = accept_netdrv(_fed.server_netdrv, _fed.netdrv_to_RTI); - // int socket_id = accept_socket(_fed.server_socket, _fed.socket_TCP_RTI); if (netdrv == NULL) { lf_print_warning("Federate failed to accept the socket."); return NULL; @@ -2040,7 +2050,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Once we record the network driver here, all future calls to close() on // the network driver should be done while holding the netdrv_mutex, and this array - // element should be reset to -1 during that critical section. + // element should be reset to NULL during that critical section. // Otherwise, there can be race condition where, during termination, // two threads attempt to simultaneously close the network driver. _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = netdrv; @@ -2065,7 +2075,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Failed to create a listening thread. LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] != NULL) { - shutdown_netdrv(&socket_id, false); + shutdown_netdrv(netdrv, false); _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = NULL; } LF_MUTEX_UNLOCK(&netdrv_mutex); From 255ddb396da8d3fabdebf0816198b57c54cb9265 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 00:56:48 -0700 Subject: [PATCH 045/167] Fix listen_to_rti_TCP to use netdriver. --- core/federated/federate.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index c8e553339..cfc7fdb4d 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1484,38 +1484,26 @@ static void* listen_to_rti_TCP(void* args) { // Listen for messages from the federate. while (1) { // Check whether the RTI socket is still valid - if (_fed.socket_TCP_RTI < 0) { - lf_print_warning("Socket to the RTI unexpectedly closed."); + if (_fed.netdrv_to_RTI == NULL) { + lf_print_warning("Network driver to the RTI unexpectedly closed."); return NULL; } // Read one byte to get the message type. // This will exit if the read fails. - int read_failed = read_from_netdrv(_fed.socket_TCP_RTI, 1, buffer); + int read_failed = read_from_netdrv(_fed.netdrv_to_RTI, 1, buffer); if (read_failed < 0) { - if (errno == ECONNRESET) { - lf_print_error("Socket connection to the RTI was closed by the RTI without" - " properly sending an EOF first. Considering this a soft error."); - // FIXME: If this happens, possibly a new RTI must be elected. - shutdown_netdrv(&_fed.socket_TCP_RTI, false); - return NULL; - } else { - lf_print_error("Socket connection to the RTI has been broken with error %d: %s." - " The RTI should close connections with an EOF first." - " Considering this a soft error.", - errno, strerror(errno)); - // FIXME: If this happens, possibly a new RTI must be elected. - shutdown_netdrv(&_fed.socket_TCP_RTI, false); - return NULL; - } + lf_print_error("Connection to the RTI was closed by the RTI with an error. Considering this a soft error."); + shutdown_netdrv(_fed.netdrv_to_RTI, false); + return NULL; } else if (read_failed > 0) { // EOF received. lf_print("Connection to the RTI closed with an EOF."); - shutdown_netdrv(&_fed.socket_TCP_RTI, false); + shutdown_netdrv(_fed.netdrv_to_RTI, false); return NULL; } switch (buffer[0]) { case MSG_TYPE_TAGGED_MESSAGE: - if (handle_tagged_message(&_fed.socket_TCP_RTI, -1)) { + if (handle_tagged_message(_fed.netdrv_to_RTI, -1)) { // Failures to complete the read of messages from the RTI are fatal. lf_print_error_and_exit("Failed to complete the reading of a message from the RTI."); } @@ -1533,7 +1521,7 @@ static void* listen_to_rti_TCP(void* args) { handle_stop_granted_message(); break; case MSG_TYPE_PORT_ABSENT: - if (handle_port_absent_message(&_fed.socket_TCP_RTI, -1)) { + if (handle_port_absent_message(_fed.netdrv_to_RTI, -1)) { // Failures to complete the read of absent messages from the RTI are fatal. lf_print_error_and_exit("Failed to complete the reading of an absent message from the RTI."); } From a64adfcae0a610be553dbb5df386d3ca246a855b Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 00:57:20 -0700 Subject: [PATCH 046/167] Fix read to handle ECONNRESET errors. --- network/impl/src/lf_socket_support.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 9b29a64ef..561bce69b 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -136,6 +136,10 @@ int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { LF_PRINT_DEBUG("Reading from socket %d failed with error: `%s`. Will try again.", socket, strerror(errno)); lf_sleep(DELAY_BETWEEN_SOCKET_RETRIES); continue; + } else if (more < 0 && errno == ECONNRESET) { + lf_print_error( + "Connection was closed by the peer without properly sending an EOF first. Considering this a soft error."); + return -1; } else if (more < 0) { // A more serious error occurred. lf_print_error("Reading from socket %d failed. With error: `%s`", socket, strerror(errno)); @@ -242,7 +246,7 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { socket_priv_t* priv = (socket_priv_t*)drv->priv; int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); if (ret != 0) { - lf_print_error("Failed to shutdown socket."); + lf_print_error("Failed to shutdown socket."); } free_netdrv(drv); return ret; From 89c8b077586e0df700e6b0c829ecabcd3e0db17c Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 00:58:55 -0700 Subject: [PATCH 047/167] Fix perform_hmac_authentication() to use network driver. --- core/federated/federate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index cfc7fdb4d..7d87ae481 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -854,14 +854,14 @@ static int perform_hmac_authentication() { RAND_bytes(fed_nonce, NONCE_LENGTH); memcpy(&fed_hello_buf[1 + fed_id_length], fed_nonce, NONCE_LENGTH); - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, message_length, fed_hello_buf, NULL, "Failed to write nonce."); + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, message_length, fed_hello_buf, NULL, "Failed to write nonce."); // Check HMAC of received FED_RESPONSE message. unsigned int hmac_length = SHA256_HMAC_LENGTH; size_t federation_id_length = strnlen(federation_metadata.federation_id, 255); unsigned char received[1 + NONCE_LENGTH + hmac_length]; - if (read_from_netdrv_close_on_error(&_fed.socket_TCP_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { + if (read_from_netdrv_close_on_error(_fed.netdrv_to_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { lf_print_warning("Failed to read RTI response."); return -1; } @@ -895,7 +895,7 @@ static int perform_hmac_authentication() { response[1] = HMAC_DOES_NOT_MATCH; // Ignore errors on writing back. - write_to_netdrv(_fed.socket_TCP_RTI, 2, response); + write_to_netdrv(_fed.netdrv_to_RTI, 2, response); return -1; } else { LF_PRINT_LOG("HMAC verified."); @@ -909,7 +909,7 @@ static int perform_hmac_authentication() { HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH, &sender[1], &hmac_length); - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, 1 + hmac_length, sender, NULL, "Failed to write fed response."); + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, 1 + hmac_length, sender, NULL, "Failed to write fed response."); } return 0; } From 0e73e792bc3e2de955e174f2d35b92ff2076a583 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:03:38 -0700 Subject: [PATCH 048/167] Fix all RTI sockets to network drivers. --- core/federated/federate.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 7d87ae481..9c6cfa12b 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -116,7 +116,7 @@ static void send_time(unsigned char type, instant_t time) { tracepoint_federate_to_rti(send_TIMESTAMP, _lf_my_fed_id, &tag); LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } @@ -135,7 +135,7 @@ static void send_tag(unsigned char type, tag_t tag) { encode_tag(&(buffer[1]), tag); LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - if (_fed.socket_TCP_RTI < 0) { + if (_fed.netdrv_to_RTI == NULL) { lf_print_warning("Socket is no longer connected. Dropping message."); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return; @@ -143,7 +143,7 @@ static void send_tag(unsigned char type, tag_t tag) { trace_event_t event_type = (type == MSG_TYPE_NEXT_EVENT_TAG) ? send_NET : send_LTC; // Trace the event when tracing is enabled tracepoint_federate_to_rti(event_type, _lf_my_fed_id, &tag); - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } @@ -933,7 +933,7 @@ static instant_t get_start_time_from_rti(instant_t my_physical_time) { size_t buffer_length = 1 + sizeof(instant_t); unsigned char buffer[buffer_length]; - read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, buffer_length, buffer, NULL, + read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, buffer_length, buffer, NULL, "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); LF_PRINT_DEBUG("Read 9 bytes."); @@ -977,7 +977,7 @@ static void handle_tag_advance_grant(void) { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, "Failed to read tag advance grant from RTI."); tag_t TAG = extract_tag(buffer); @@ -1218,7 +1218,7 @@ static void handle_provisional_tag_advance_grant() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, "Failed to read provisional tag advance grant from RTI."); tag_t PTAG = extract_tag(buffer); @@ -1308,7 +1308,7 @@ static void handle_stop_granted_message() { size_t bytes_to_read = MSG_TYPE_STOP_GRANTED_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, "Failed to read stop granted from RTI."); tag_t received_stop_tag = extract_tag(buffer); @@ -1352,7 +1352,7 @@ static void handle_stop_granted_message() { static void handle_stop_request_message() { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_read, buffer, NULL, + read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, "Failed to read stop request from RTI."); tag_t tag_to_stop = extract_tag(buffer); @@ -1425,7 +1425,7 @@ static void handle_stop_request_message() { // Send the current logical time to the RTI. LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, &lf_outbound_netdrv_mutex, "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); @@ -1442,7 +1442,7 @@ static void send_resign_signal() { unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_RESIGN; LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netdrv_mutex, "Failed to send MSG_TYPE_RESIGN."); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); LF_PRINT_LOG("Resigned."); @@ -1455,7 +1455,7 @@ static void send_failed_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_FAILED; - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, bytes_to_write, &(buffer[0]), NULL, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_write, &(buffer[0]), NULL, "Failed to send MSG_TYPE_FAILED."); LF_PRINT_LOG("Failed."); } @@ -1607,7 +1607,7 @@ void lf_terminate_execution(environment_t* env) { // For an abnormal termination (e.g. a SIGINT), we need to send a // MSG_TYPE_FAILED message to the RTI, but we should not acquire a mutex. - if (_fed.socket_TCP_RTI >= 0) { + if (_fed.netdrv_to_RTI != NULL) { if (_lf_normal_termination) { tracepoint_federate_to_rti(send_RESIGN, _lf_my_fed_id, &env->current_tag); send_resign_signal(); @@ -2350,13 +2350,13 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d #ifdef FEDERATED_CENTRALIZED // Send the absent message through the RTI - int* socket = &_fed.socket_TCP_RTI; + int* socket = _fed.netdrv_to_RTI; #else // Send the absent message directly to the federate int* socket = &_fed.netdrvs_for_outbound_p2p_connections[fed_ID]; #endif - if (socket == &_fed.socket_TCP_RTI) { + if (socket == _fed.netdrv_to_RTI) { tracepoint_federate_to_rti(send_PORT_ABS, _lf_my_fed_id, ¤t_message_intended_tag); } else { tracepoint_federate_to_federate(send_PORT_ABS, _lf_my_fed_id, fed_ID, ¤t_message_intended_tag); @@ -2368,7 +2368,7 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d if (result != 0) { // Write failed. Response depends on whether coordination is centralized. - if (socket == &_fed.socket_TCP_RTI) { + if (socket == _fed.netdrv_to_RTI) { // Centralized coordination. This is a critical error. lf_print_error_system_failure("Failed to send port absent message for port %hu to federate %hu.", port_ID, fed_ID); @@ -2393,7 +2393,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { LF_PRINT_LOG("Sending to RTI a MSG_TYPE_STOP_REQUEST message with tag " PRINTF_TAG ".", stop_tag.time - start_time, stop_tag.microstep); - if (_fed.socket_TCP_RTI < 0) { + if (_fed.netdrv_to_RTI == NULL) { lf_print_warning("Socket is no longer connected. Dropping message."); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return -1; @@ -2401,7 +2401,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_STOP_REQ, _lf_my_fed_id, &stop_tag); - write_to_netdrv_fail_on_error(&_fed.socket_TCP_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_netdrv_mutex, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_netdrv_mutex, "Failed to send stop time " PRINTF_TIME " to the RTI.", stop_tag.time - start_time); // Treat this sending as equivalent to having received a stop request from the RTI. @@ -2469,7 +2469,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int socket = &_fed.netdrvs_for_outbound_p2p_connections[federate]; tracepoint_federate_to_federate(send_P2P_TAGGED_MSG, _lf_my_fed_id, federate, ¤t_message_intended_tag); } else { - socket = &_fed.socket_TCP_RTI; + socket = _fed.netdrv_to_RTI; tracepoint_federate_to_rti(send_TAGGED_MSG, _lf_my_fed_id, ¤t_message_intended_tag); } From 04e71e3b55720addaf27676b28e44fa4ce8267a7 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:05:05 -0700 Subject: [PATCH 049/167] Remove server socket and port from federate instance. --- core/federated/federate.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 9c6cfa12b..94dac8648 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -81,8 +81,6 @@ federate_instance_t _fed = {.socket_TCP_RTI = -1, .inbound_netdriv_listeners = NULL, .number_of_outbound_p2p_connections = 0, .inbound_p2p_handling_thread_id = 0, - .server_socket = -1, - .server_port = -1, .last_TAG = {.time = NEVER, .microstep = 0u}, .is_last_TAG_provisional = false, .has_upstream = false, From 6a851e3cd5594b16a8983d1d4b4639bfc7476da9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:10:05 -0700 Subject: [PATCH 050/167] Fix peek_from_netdrv(). --- core/federated/federate.c | 2 +- network/api/net_driver.h | 2 ++ network/impl/src/lf_socket_support.c | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 94dac8648..d014137a5 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -152,7 +152,7 @@ static void send_tag(unsigned char type, tag_t tag) { */ static bool rti_failed() { unsigned char first_byte; - ssize_t bytes = peek_from_socket(_fed.socket_TCP_RTI, &first_byte); + ssize_t bytes = peek_from_netdrv(_fed.netdrv_to_RTI, &first_byte); if (bytes < 0 || (bytes == 1 && first_byte == MSG_TYPE_FAILED)) return true; else diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 44a95cf25..221e6fb3f 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -121,6 +121,8 @@ int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...); +ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result); + /** * @brief Gracefully shuts down and closes a socket, optionally reading until EOF. * Shutdown and close the socket. If read_before_closing is false, it just immediately calls shutdown() with SHUT_RDWR diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 561bce69b..81a2bb302 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -242,6 +242,11 @@ void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha } } +ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + return peek_from_socket(priv->socket_descriptor, result); +} + int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { socket_priv_t* priv = (socket_priv_t*)drv->priv; int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); From 31496157e1fb8041d84d2a60bd7bbad55b2f4f39 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:10:39 -0700 Subject: [PATCH 051/167] Remove socket_TCP_RTI --- core/federated/federate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index d014137a5..20e7d9b19 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -76,8 +76,7 @@ int max_level_allowed_to_advance; * The state of this federate instance. Each executable has exactly one federate instance, * and the _fed global variable refers to that instance. */ -federate_instance_t _fed = {.socket_TCP_RTI = -1, - .number_of_inbound_p2p_connections = 0, +federate_instance_t _fed = {.number_of_inbound_p2p_connections = 0, .inbound_netdriv_listeners = NULL, .number_of_outbound_p2p_connections = 0, .inbound_p2p_handling_thread_id = 0, From 18caa30bb149af6c368ca9b2b64f607d5b091bd0 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:20:06 -0700 Subject: [PATCH 052/167] Fix all socket to netdrivers. --- core/federated/federate.c | 99 +++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 20e7d9b19..e06dfc50a 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -133,7 +133,7 @@ static void send_tag(unsigned char type, tag_t tag) { LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); if (_fed.netdrv_to_RTI == NULL) { - lf_print_warning("Socket is no longer connected. Dropping message."); + lf_print_warning("RTI is no longer connected. Dropping message."); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return; } @@ -146,8 +146,8 @@ static void send_tag(unsigned char type, tag_t tag) { } /** - * Return true if either the socket to the RTI is broken or the socket is - * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. + * Return true if either the network driver to the RTI is broken or the network driver is + * alive and the first unread byte on the network driver's queue is MSG_TYPE_FAILED. */ static bool rti_failed() { unsigned char first_byte; @@ -400,7 +400,7 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen } /** - * Close the socket that receives incoming messages from the + * Close the network driver that receives incoming messages from the * specified federate ID. * * @param fed_id The ID of the peer federate sending messages to this @@ -770,7 +770,7 @@ static void* listen_to_federates(void* _args) { LF_PRINT_LOG("Received tagged message from federate %d.", fed_id); if (handle_tagged_message(netdrv, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and - // it is not a fatal error if the socket is closed before the whole message is read. + // it is not a fatal error if the network driver is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); netdrv_closed = true; @@ -780,7 +780,7 @@ static void* listen_to_federates(void* _args) { LF_PRINT_LOG("Received port absent message from federate %d.", fed_id); if (handle_port_absent_message(netdrv, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and - // it is not a fatal error if the socket is closed before the whole message is read. + // it is not a fatal error if the network driver is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); netdrv_closed = true; @@ -791,13 +791,13 @@ static void* listen_to_federates(void* _args) { } } if (bad_message) { - lf_print_error("Received erroneous message type: %d. Closing the socket.", buffer[0]); + lf_print_error("Received erroneous message type: %d. Closing the network driver.", buffer[0]); // Trace the event when tracing is enabled tracepoint_federate_from_federate(receive_UNIDENTIFIED, _lf_my_fed_id, fed_id, NULL); break; // while loop } if (netdrv_closed) { - // For decentralized execution, once this socket is closed, we + // For decentralized execution, once this network driver is closed, we // update last known tags of all ports connected to the specified federate to FOREVER_TAG, // which would eliminate the need to wait for STAA to assume an input is absent. mark_inputs_known_absent(fed_id); @@ -809,21 +809,21 @@ static void* listen_to_federates(void* _args) { } /** - * Close the socket that sends outgoing messages to the + * Close the network driver that sends outgoing messages to the * specified federate ID. This function acquires the lf_outbound_netdrv_mutex mutex lock * if _lf_normal_termination is true and otherwise proceeds without the lock. * @param fed_id The ID of the peer federate receiving messages from this * federate, or -1 if the RTI (centralized coordination). */ -static void close_outbound_socket(int fed_id) { +static void close_outbound_netdrv(int fed_id) { assert(fed_id >= 0 && fed_id < NUMBER_OF_FEDERATES); // Close outbound connections, in case they have not closed themselves. // This will result in EOF being sent to the remote federate, except for - // abnormal termination, in which case it will just close the socket. + // abnormal termination, in which case it will just close the network driver. if (_lf_normal_termination) { LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); if (_fed.netdrvs_for_outbound_p2p_connections[fed_id] >= 0) { - // Close the socket by sending a FIN packet indicating that no further writes + // Close the network driver by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. shutdown_netdrv(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); } @@ -925,7 +925,7 @@ static instant_t get_start_time_from_rti(instant_t my_physical_time) { // Send the timestamp marker first. send_time(MSG_TYPE_TIMESTAMP, my_physical_time); - // Read bytes from the socket. We need 9 bytes. + // Read bytes from the network driver. We need 9 bytes. // Buffer for message ID plus timestamp. size_t buffer_length = 1 + sizeof(instant_t); unsigned char buffer[buffer_length]; @@ -1375,7 +1375,7 @@ static void handle_stop_request_message() { // or we have previously sent a stop request to the RTI, // then we have already blocked tag advance in enclaves. // Do not do this twice. The record of whether the first has occurred - // is guarded by the outbound socket mutex. + // is guarded by the outbound network driver mutex. // The second is guarded by the global mutex. // Note that the RTI should not send stop requests more than once to federates. LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); @@ -1480,7 +1480,7 @@ static void* listen_to_rti_TCP(void* args) { // Listen for messages from the federate. while (1) { - // Check whether the RTI socket is still valid + // Check whether the RTI network driver is still valid if (_fed.netdrv_to_RTI == NULL) { lf_print_warning("Network driver to the RTI unexpectedly closed."); return NULL; @@ -1528,7 +1528,7 @@ static void* listen_to_rti_TCP(void* args) { break; case MSG_TYPE_CLOCK_SYNC_T1: case MSG_TYPE_CLOCK_SYNC_T4: - lf_print_error("Federate %d received unexpected clock sync message from RTI on TCP socket.", _lf_my_fed_id); + lf_print_error("Federate %d received unexpected clock sync message from RTI.", _lf_my_fed_id); break; default: lf_print_error_and_exit("Received from RTI an unrecognized TCP message type: %hhx.", buffer[0]); @@ -1593,7 +1593,7 @@ static bool bounded_NET(tag_t* tag) { // An empty version of this function is code generated for unfederated execution. /** - * Close sockets used to communicate with other federates, if they are open, + * Close network drivers used to communicate with other federates, if they are open, * and send a MSG_TYPE_RESIGN message to the RTI. This implements the function * defined in reactor.h. For unfederated execution, the code generator * generates an empty implementation. @@ -1614,28 +1614,28 @@ void lf_terminate_execution(environment_t* env) { } } - LF_PRINT_DEBUG("Closing incoming P2P sockets."); - // Close any incoming P2P sockets that are still open. + LF_PRINT_DEBUG("Closing incoming P2P network drivers."); + // Close any incoming P2P network drivers that are still open. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { - close_inbound_socket(i); - // Ignore errors. Mark the socket closed. - _fed.netdrvs_for_inbound_p2p_connections[i] = -1; + close_inbound_netdrv(i); + // Ignore errors. Mark the network driver closed. + _fed.netdrvs_for_inbound_p2p_connections[i] = NULL; } // Check for all outgoing physical connections in // _fed.netdrvs_for_outbound_p2p_connections and - // if the socket ID is not -1, the connection is still open. - // Send an EOF by closing the socket here. + // if the network driver ID is not NULL, the connection is still open. + // Send an EOF by closing the network driver here. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { // Close outbound connections, in case they have not closed themselves. // This will result in EOF being sent to the remote federate, except for - // abnormal termination, in which case it will just close the socket. - close_outbound_socket(i); + // abnormal termination, in which case it will just close the network driver. + close_outbound_netdrv(i); } - LF_PRINT_DEBUG("Waiting for inbound p2p socket listener threads."); - // Wait for each inbound socket listener thread to close. + LF_PRINT_DEBUG("Waiting for inbound p2p network driver listener threads."); + // Wait for each inbound network driver listener thread to close. if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_netdriv_listeners != NULL) { LF_PRINT_LOG("Waiting for %zu threads listening for incoming messages to exit.", _fed.number_of_inbound_p2p_connections); @@ -1739,8 +1739,8 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { while (result < 0 && !_lf_termination_executed) { // Try again after some time if the connection failed. // Note that this should not really happen since the remote federate should be - // accepting socket connections. But possibly it will be busy (in process of accepting - // another socket connection?). Hence, we retry. + // accepting connections. But possibly it will be busy (in process of accepting + // another connection?). Hence, we retry. if (CHECK_TIMEOUT(start_connect, CONNECT_TIMEOUT)) { // If the remote federate is not accepting the connection after CONNECT_TIMEOUT // treat it as a soft error condition and return. @@ -1750,7 +1750,6 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } // Check whether the RTI is still there. - // TODO: Fix. if (rti_failed()) { break; } @@ -1767,7 +1766,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_FED_ID, _lf_my_fed_id, remote_federate_id, NULL); - // No need for a mutex because we have the only handle on the socket. + // No need for a mutex because we have the only handle on the network driver. write_to_netdrv_fail_on_error(netdrv, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", remote_federate_id); write_to_netdrv_fail_on_error(netdrv, federation_id_length, (unsigned char*)federation_metadata.federation_id, NULL, @@ -1942,7 +1941,7 @@ void lf_create_server(int specified_port) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_AD, _lf_my_fed_id, NULL); - // No need for a mutex because we have the only handle on this socket. + // No need for a mutex because we have the only handle on this network driver. write_to_netdrv_fail_on_error(server_netdrv, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, "Failed to send address advertisement."); @@ -1982,7 +1981,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Wait for an incoming connection request. netdrv_t* netdrv = accept_netdrv(_fed.server_netdrv, _fed.netdrv_to_RTI); if (netdrv == NULL) { - lf_print_warning("Federate failed to accept the socket."); + lf_print_warning("Federate failed to accept the network driver."); return NULL; } LF_PRINT_LOG("Accepted new connection from remote federate."); @@ -1991,7 +1990,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { unsigned char buffer[header_length]; int read_failed = read_from_netdrv(netdrv, header_length, (unsigned char*)&buffer); if (read_failed || buffer[0] != MSG_TYPE_P2P_SENDING_FED_ID) { - lf_print_warning("Federate received invalid first message on P2P socket. Closing socket."); + lf_print_warning("Federate received invalid first message on P2P network driver. Closing network driver."); if (read_failed == 0) { // Wrong message received. unsigned char response[2]; @@ -2012,7 +2011,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { read_failed = read_from_netdrv(netdrv, federation_id_length, (unsigned char*)remote_federation_id); if (read_failed || (strncmp(federation_metadata.federation_id, remote_federation_id, strnlen(federation_metadata.federation_id, 255)) != 0)) { - lf_print_warning("Received invalid federation ID. Closing socket."); + lf_print_warning("Received invalid federation ID. Closing network driver."); if (read_failed == 0) { unsigned char response[2]; response[0] = MSG_TYPE_REJECT; @@ -2170,15 +2169,15 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa // Use a mutex lock to prevent multiple threads from simultaneously sending. LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - int* socket = &_fed.netdrvs_for_outbound_p2p_connections[federate]; + netdrv_t* netdrv = _fed.netdrvs_for_outbound_p2p_connections[federate]; // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_P2P_MSG, _lf_my_fed_id, federate, NULL); - int result = write_to_netdrv_close_on_error(socket, header_length, header_buffer); + int result = write_to_netdrv_close_on_error(netdrv, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_netdrv_close_on_error(socket, length, message); + result = write_to_netdrv_close_on_error(netdrv, length, message); } if (result != 0) { // Message did not send. Since this is used for physical connections, this is not critical. @@ -2347,25 +2346,25 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d #ifdef FEDERATED_CENTRALIZED // Send the absent message through the RTI - int* socket = _fed.netdrv_to_RTI; + netdrv_t* netdrv = _fed.netdrv_to_RTI; #else // Send the absent message directly to the federate - int* socket = &_fed.netdrvs_for_outbound_p2p_connections[fed_ID]; + netdrv_t* netdrv = &_fed.netdrvs_for_outbound_p2p_connections[fed_ID]; #endif - if (socket == _fed.netdrv_to_RTI) { + if (netdrv == _fed.netdrv_to_RTI) { tracepoint_federate_to_rti(send_PORT_ABS, _lf_my_fed_id, ¤t_message_intended_tag); } else { tracepoint_federate_to_federate(send_PORT_ABS, _lf_my_fed_id, fed_ID, ¤t_message_intended_tag); } LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - int result = write_to_netdrv_close_on_error(socket, message_length, buffer); + int result = write_to_netdrv_close_on_error(netdrv, message_length, buffer); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); if (result != 0) { // Write failed. Response depends on whether coordination is centralized. - if (socket == _fed.netdrv_to_RTI) { + if (netdrv == _fed.netdrv_to_RTI) { // Centralized coordination. This is a critical error. lf_print_error_system_failure("Failed to send port absent message for port %hu to federate %hu.", port_ID, fed_ID); @@ -2391,7 +2390,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { stop_tag.microstep); if (_fed.netdrv_to_RTI == NULL) { - lf_print_warning("Socket is no longer connected. Dropping message."); + lf_print_warning("RTI is no longer connected. Dropping message."); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); return -1; } @@ -2461,19 +2460,19 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int // Use a mutex lock to prevent multiple threads from simultaneously sending. LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - int* socket; + netdrv_t* netdrv ; if (message_type == MSG_TYPE_P2P_TAGGED_MESSAGE) { - socket = &_fed.netdrvs_for_outbound_p2p_connections[federate]; + netdrv = _fed.netdrvs_for_outbound_p2p_connections[federate]; tracepoint_federate_to_federate(send_P2P_TAGGED_MSG, _lf_my_fed_id, federate, ¤t_message_intended_tag); } else { - socket = _fed.netdrv_to_RTI; + netdrv = _fed.netdrv_to_RTI; tracepoint_federate_to_rti(send_TAGGED_MSG, _lf_my_fed_id, ¤t_message_intended_tag); } - int result = write_to_netdrv_close_on_error(socket, header_length, header_buffer); + int result = write_to_netdrv_close_on_error(netdrv, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_netdrv_close_on_error(socket, length, message); + result = write_to_netdrv_close_on_error(netdrv, length, message); } if (result != 0) { // Message did not send. Handling depends on message type. From ce8be1482bdffe47adb873d4ee59b02675ea2fc3 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:34:09 -0700 Subject: [PATCH 053/167] Remove socket.h header from federate.c --- core/federated/federate.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index e06dfc50a..f56877018 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -17,7 +17,6 @@ #include // inet_ntop & inet_pton #include // Defines getaddrinfo(), freeaddrinfo() and struct addrinfo. #include // Defines struct sockaddr_in -#include #include // Defines read(), write(), and close() #include // Defines memset(), strnlen(), strncmp(), strncpy() #include // Defines strerror() @@ -825,11 +824,11 @@ static void close_outbound_netdrv(int fed_id) { if (_fed.netdrvs_for_outbound_p2p_connections[fed_id] >= 0) { // Close the network driver by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. - shutdown_netdrv(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); + shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); } LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } else { - shutdown_netdrv(&_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); + shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); } } @@ -1814,7 +1813,7 @@ void lf_connect_to_rti(const char* hostname, int port) { // Create the client network driver. create_client(_fed.netdrv_to_RTI); - if (connect_to_netdrv(__fed.netdrv_to_RTI) < 0) { + if (connect_to_netdrv(_fed.netdrv_to_RTI) < 0) { lf_print_error_and_exit("Failed to connect() to RTI."); } @@ -1881,7 +1880,7 @@ void lf_connect_to_rti(const char* hostname, int port) { tracepoint_federate_from_rti(receive_REJECT, _lf_my_fed_id, NULL); // Read one more byte to determine the cause of rejection. unsigned char cause; - read_from_netdrv_fail_on_error(&_fed.netdrv_to_RTI, 1, &cause, NULL, + read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, 1, &cause, NULL, "Failed to read the cause of rejection by the RTI."); if (cause == FEDERATION_ID_DOES_NOT_MATCH || cause == WRONG_SERVER) { lf_print_warning("Connected to the wrong RTI. Will try again"); @@ -1913,7 +1912,7 @@ void lf_connect_to_rti(const char* hostname, int port) { unsigned char UDP_port_number[1 + sizeof(uint16_t)]; UDP_port_number[0] = MSG_TYPE_UDP_PORT; encode_uint16(udp_port, &(UDP_port_number[1])); - write_to_netdrv_fail_on_error(&_fed.netdrv_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, "Failed to send the UDP port number to the RTI."); } @@ -2046,7 +2045,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(&_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, + write_to_netdrv_fail_on_error(_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, &lf_outbound_netdrv_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); @@ -2349,7 +2348,7 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d netdrv_t* netdrv = _fed.netdrv_to_RTI; #else // Send the absent message directly to the federate - netdrv_t* netdrv = &_fed.netdrvs_for_outbound_p2p_connections[fed_ID]; + netdrv_t* netdrv = _fed.netdrvs_for_outbound_p2p_connections[fed_ID]; #endif if (netdrv == _fed.netdrv_to_RTI) { From 2e53546ea298dd4010bf6bc2e52230e41bc1295d Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:34:32 -0700 Subject: [PATCH 054/167] Add create_client() and connect_to_netdrv() in net_driver.h header file. --- network/api/net_driver.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 221e6fb3f..8feb706cd 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -28,6 +28,10 @@ int create_server_(netdrv_t* drv, bool increment_port_on_retry); netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); +void create_client(netdrv_t* drv); + +int connect_to_netdrv(netdrv_t* drv); + int get_peer_address(netdrv_t* drv); /** From 1c44f2e6c3f7e7910384067280e6aa141a194186 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:35:07 -0700 Subject: [PATCH 055/167] Fix accept_netdrv to use accept_socket. --- network/impl/src/lf_socket_support.c | 40 +++++----------------------- network/impl/src/socket_common.c | 5 ++-- 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 81a2bb302..1793b0db0 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -69,43 +69,17 @@ int create_server_(netdrv_t* drv, bool increment_port_on_retry) { netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { socket_priv_t* serv_priv = (socket_priv_t*)server_drv->priv; + socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; + netdrv_t* fed_netdrv = initialize_netdrv(); socket_priv_t* fed_priv = (socket_priv_t*)fed_netdrv->priv; - struct sockaddr client_fd; - // Wait for an incoming connection request. - uint32_t client_length = sizeof(client_fd); - // The following blocks until a federate connects. - int socket_id = -1; - while (true) { - // When close(socket) is called, the accept() will return -1. - socket_id = accept(serv_priv->socket_descriptor, &client_fd, &client_length); - if (socket_id >= 0) { - // Got a socket - break; - } else if (socket_id < 0 && (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR)) { - lf_print_warning("Failed to accept the socket. %s.", strerror(errno)); - free_netdrv(fed_netdrv); - return NULL; - } else if (errno == EPERM) { - lf_print_error_system_failure("Firewall permissions prohibit connection."); - free_netdrv(fed_netdrv); - return NULL; - } else { - // For the federates, it should check if the rti_socket is still open, before retrying accept(). - socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; - if (rti_priv->socket_descriptor != -1) { - if (check_socket_closed(rti_priv->socket_descriptor)) { - free_netdrv(fed_netdrv); - return NULL; - } - } - // Try again - lf_print_warning("Failed to accept the socket. %s. Trying again.", strerror(errno)); - continue; - } + int sock = accept_socket(serv_priv->socket_descriptor, rti_priv->socket_descriptor); + if (sock == -1) { + free_netdrv(fed_netdrv); + return NULL; } - fed_priv->socket_descriptor = socket_id; + fed_priv->socket_descriptor = sock; return fed_netdrv; } diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 279cb51ef..d6e393e12 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -199,14 +199,15 @@ int accept_socket(int socket, int rti_socket) { break; } else if (socket_id < 0 && (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR)) { lf_print_warning("Failed to accept the socket. %s.", strerror(errno)); - break; + return -1; } else if (errno == EPERM) { lf_print_error_system_failure("Firewall permissions prohibit connection."); + return -1; } else { // For the federates, it should check if the rti_socket is still open, before retrying accept(). if (rti_socket == -1) { if (check_socket_closed(rti_socket)) { - break; + return -1; } } // Try again From 9e45794665e0122c845cf2aa8bca1f2afe0e54df Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:42:39 -0700 Subject: [PATCH 056/167] Fix create_server() to call create_socket_server() --- core/federated/RTI/rti_remote.c | 2 +- core/federated/federate.c | 2 +- network/api/net_driver.h | 2 +- network/api/socket_common.h | 4 +-- network/impl/src/lf_socket_support.c | 29 +++------------------ network/impl/src/socket_common.c | 39 ++++++++++------------------ 6 files changed, 22 insertions(+), 56 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 38de11ef5..14d1da2f1 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1489,7 +1489,7 @@ int start_rti_server() { // Initialize RTI's network driver. rti_remote->rti_netdrv = initialize_netdrv(); // Create the server - if (create_server_(rti_remote->rti_netdrv, true)) { + if (create_server(rti_remote->rti_netdrv, true)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); return -1; }; diff --git a/core/federated/federate.c b/core/federated/federate.c index f56877018..95465219e 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1922,7 +1922,7 @@ void lf_create_server(int specified_port) { netdrv_t* server_netdrv = initialize_netdrv(); set_server_port(server_netdrv, specified_port); - if (create_server_(server_netdrv, false)) { + if (create_server(server_netdrv, false)) { lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); }; _fed.server_netdrv = server_netdrv; diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 8feb706cd..8faf031c0 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -24,7 +24,7 @@ netdrv_t* initialize_netdrv(); * @param serv_type Type of server, RTI or FED. * @return int 0 for success, -1 for failure. */ -int create_server_(netdrv_t* drv, bool increment_port_on_retry); +int create_server(netdrv_t* drv, bool increment_port_on_retry); netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 63665942b..b46e759a3 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -136,12 +136,10 @@ int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool * @param port The port number to use or 0 to let the OS pick or 1 to start trying at DEFAULT_PORT. * @param final_socket Pointer to the returned socket descriptor on which accepting connections will occur. * @param final_port Pointer to the final port the server will use. - * @param sock_type Type of the socket, TCP or UDP. * @param increment_port_on_retry Boolean to retry port increment. * @return 0 for success, -1 for failure. */ -int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, - bool increment_port_on_retry); +int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, bool increment_port_on_retry); int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 1793b0db0..8cb017f0b 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -40,37 +40,16 @@ void free_netdrv(netdrv_t* drv) { free(drv); } -int create_server_(netdrv_t* drv, bool increment_port_on_retry) { +int create_server(netdrv_t* drv, bool increment_port_on_retry) { socket_priv_t* priv = (socket_priv_t*)drv->priv; - int socket_descriptor; - struct timeval timeout_time; - // Create an IPv4 socket for TCP. - socket_descriptor = create_real_time_tcp_socket_errexit(); - // Set the timeout time for the communications of the server - timeout_time = (struct timeval){.tv_sec = TCP_TIMEOUT_TIME / BILLION, .tv_usec = (TCP_TIMEOUT_TIME % BILLION) / 1000}; - if (socket_descriptor < 0) { - lf_print_error("Failed to create TCP socket."); - return -1; - } - set_socket_timeout_option(socket_descriptor, &timeout_time); - - int used_port = set_socket_bind_option(socket_descriptor, priv->user_specified_port, increment_port_on_retry); - // Enable listening for socket connections. - // The second argument is the maximum number of queued socket requests, - // which according to the Mac man page is limited to 128. - if (listen(socket_descriptor, 128)) { - lf_print_error("Failed to listen on %d socket: %s.", socket_descriptor, strerror(errno)); - return -1; - } - priv->socket_descriptor = socket_descriptor; - priv->port = used_port; - return 0; + return create_socket_server(priv->user_specified_port, &priv->socket_descriptor, &priv->port, + increment_port_on_retry); } netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { socket_priv_t* serv_priv = (socket_priv_t*)server_drv->priv; socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; - + netdrv_t* fed_netdrv = initialize_netdrv(); socket_priv_t* fed_priv = (socket_priv_t*)fed_netdrv->priv; diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index d6e393e12..9884d9f18 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -119,38 +119,27 @@ int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool return used_port; } -// TODO: Fix on federate. -int create_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, - bool increment_port_on_retry) { +int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, bool increment_port_on_retry) { int socket_descriptor; struct timeval timeout_time; - if (sock_type == TCP) { - // Create an IPv4 socket for TCP. - socket_descriptor = create_real_time_tcp_socket_errexit(); - // Set the timeout time for the communications of the server - timeout_time = - (struct timeval){.tv_sec = TCP_TIMEOUT_TIME / BILLION, .tv_usec = (TCP_TIMEOUT_TIME % BILLION) / 1000}; - } else { - // Create a UDP socket. - socket_descriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - timeout_time = - (struct timeval){.tv_sec = UDP_TIMEOUT_TIME / BILLION, .tv_usec = (UDP_TIMEOUT_TIME % BILLION) / 1000}; - } - char* type = (sock_type == TCP) ? "TCP" : "UDP"; + + // Create an IPv4 socket for TCP. + socket_descriptor = create_real_time_tcp_socket_errexit(); + // Set the timeout time for the communications of the server + timeout_time = (struct timeval){.tv_sec = TCP_TIMEOUT_TIME / BILLION, .tv_usec = (TCP_TIMEOUT_TIME % BILLION) / 1000}; + if (socket_descriptor < 0) { - lf_print_error("Failed to create %s socket.", type); + lf_print_error("Failed to create TCP socket."); return -1; } set_socket_timeout_option(socket_descriptor, &timeout_time); int used_port = set_socket_bind_option(socket_descriptor, port, increment_port_on_retry); - if (sock_type == TCP) { - // Enable listening for socket connections. - // The second argument is the maximum number of queued socket requests, - // which according to the Mac man page is limited to 128. - if (listen(socket_descriptor, 128)) { - lf_print_error("Failed to listen on %d socket: %s.", socket_descriptor, strerror(errno)); - return -1; - } + // Enable listening for socket connections. + // The second argument is the maximum number of queued socket requests, + // which according to the Mac man page is limited to 128. + if (listen(socket_descriptor, 128)) { + lf_print_error("Failed to listen on %d socket: %s.", socket_descriptor, strerror(errno)); + return -1; } *final_socket = socket_descriptor; *final_port = used_port; From 02f041bf2b604b67ae3361210b66307f4c4312a8 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 01:45:51 -0700 Subject: [PATCH 057/167] Create UDP default port, because there can be situations not using TCP for RTI. --- core/federated/RTI/rti_remote.c | 3 +-- network/api/socket_common.h | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 14d1da2f1..0ab6880ea 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1495,9 +1495,8 @@ int start_rti_server() { }; lf_print("RTI: Listening for federates."); // Create the UDP socket server - // Try to get the rti_remote->final_port_TCP + 1 port if (rti_remote->clock_sync_global_status >= clock_sync_on) { - if (create_clock_server(rti_remote->final_port_TCP + 1, &rti_remote->socket_descriptor_UDP, + if (create_clock_server(DEFAULT_UDP_PORT, &rti_remote->socket_descriptor_UDP, &rti_remote->final_port_UDP)) { lf_print_error_system_failure("RTI failed to create UDP server: %s.", strerror(errno)); return -1; diff --git a/network/api/socket_common.h b/network/api/socket_common.h index b46e759a3..bae6a5b3f 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -64,6 +64,8 @@ */ #define DEFAULT_PORT 15045u +#define DEFAULT_UDP_PORT 15061u + /** * Byte identifying that the federate or the RTI has failed. */ From aacd379ca46c6ec9a097ddbae66d60ff8a0ed75c Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 19 Jan 2025 02:24:32 -0700 Subject: [PATCH 058/167] Add logic to check the netdriver is null, when the rti_drv is not available. --- core/federated/federate.c | 6 +++--- network/api/net_driver.h | 2 ++ network/impl/src/lf_socket_support.c | 23 +++++++++++++++++------ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 95465219e..66617c2b3 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1783,7 +1783,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { result = -1; // Wait ADDRESS_QUERY_RETRY_INTERVAL nanoseconds. lf_sleep(ADDRESS_QUERY_RETRY_INTERVAL); - lf_print_warning("Could not connect to federate %d. Will try again every" PRINTF_TIME "nanoseconds.\n", + lf_print_warning("Could not connect to federate %d. Will try again every " PRINTF_TIME "nanoseconds.\n", remote_federate_id, ADDRESS_QUERY_RETRY_INTERVAL); continue; } else { @@ -1927,7 +1927,7 @@ void lf_create_server(int specified_port) { }; _fed.server_netdrv = server_netdrv; // Get the final server port set. - int32_t server_port = get_server_port(server_netdrv); + int32_t server_port = get_my_port(server_netdrv); LF_PRINT_LOG("Server for communicating with other federates started using port %d.", server_port); @@ -1941,7 +1941,7 @@ void lf_create_server(int specified_port) { tracepoint_federate_to_rti(send_ADR_AD, _lf_my_fed_id, NULL); // No need for a mutex because we have the only handle on this network driver. - write_to_netdrv_fail_on_error(server_netdrv, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, + write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, "Failed to send address advertisement."); LF_PRINT_DEBUG("Sent port %d to the RTI.", server_port); diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 8faf031c0..6006a9230 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -138,6 +138,8 @@ ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result); */ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing); +int32_t get_my_port(netdrv_t* drv); + int32_t get_server_port(netdrv_t* drv); struct in_addr* get_ip_addr(netdrv_t* drv); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 8cb017f0b..cbd8f4035 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -48,12 +48,17 @@ int create_server(netdrv_t* drv, bool increment_port_on_retry) { netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { socket_priv_t* serv_priv = (socket_priv_t*)server_drv->priv; - socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; - + int rti_socket; + if (rti_drv == NULL) { + rti_socket = -1; + } else { + socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; + rti_socket = rti_priv->socket_descriptor; + } netdrv_t* fed_netdrv = initialize_netdrv(); socket_priv_t* fed_priv = (socket_priv_t*)fed_netdrv->priv; - int sock = accept_socket(serv_priv->socket_descriptor, rti_priv->socket_descriptor); + int sock = accept_socket(serv_priv->socket_descriptor, rti_socket); if (sock == -1) { free_netdrv(fed_netdrv); return NULL; @@ -201,6 +206,10 @@ ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result) { } int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { + if (drv == NULL) { + lf_print("Socket already closed."); + return 0; + } socket_priv_t* priv = (socket_priv_t*)drv->priv; int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); if (ret != 0) { @@ -232,10 +241,12 @@ int get_peer_address(netdrv_t* drv) { return 0; } +int32_t get_my_port(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + return priv->port; +} + int32_t get_server_port(netdrv_t* drv) { - // if (drv == NULL) { - // lf_print_warning("Netdriver is closed, returning -1."); - // } socket_priv_t* priv = (socket_priv_t*)drv->priv; return priv->server_port; } From 0406a0270aa0c02cfffe53ff0ac7ad922a0ef161 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 10:21:01 -0700 Subject: [PATCH 059/167] Fis to not shutdown the netdrv, but the socket. --- network/impl/src/lf_socket_support.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index cbd8f4035..10c003a68 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -112,12 +112,13 @@ int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { } int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; int read_failed = read_from_netdrv(drv, num_bytes, buffer); if (read_failed) { // Read failed. // Socket has probably been closed from the other side. // Shut down and close the socket from this side. - shutdown_netdrv(drv, false); + shutdown_socket(&priv->socket_descriptor, false); return -1; } return 0; @@ -171,12 +172,13 @@ int write_to_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { } int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; int result = write_to_netdrv(drv, num_bytes, buffer); if (result) { // Write failed. // Socket has probably been closed from the other side. // Shut down and close the socket from this side. - shutdown_netdrv(drv, false); + shutdown_socket(&priv->socket_descriptor, false); } return result; } From 8f589ea44298aa0a8f8b01db5025d2331005470f Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 10:34:19 -0700 Subject: [PATCH 060/167] Remove comments. --- core/federated/RTI/rti_remote.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 0ab6880ea..9fd6a3b8d 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1395,10 +1395,6 @@ static bool authenticate_federate(netdrv_t* fed_netdrv) { #endif void lf_connect_to_federates(netdrv_t* rti_netdrv) { - // netdrv_t* netdrv_array[rti_remote->base.number_of_scheduling_nodes]; - // for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { - // netdrv_array[i] = establish_communication_session(rti_netdrv); - // } for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { netdrv_t* fed_netdrv = accept_netdrv(rti_netdrv, NULL); // Wait for the first message from the federate when RTI -a option is on. From 36b29eea9de19ee6204d346b7fef263b4ddebc49 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 14:49:15 -0700 Subject: [PATCH 061/167] Fix clock sync to split down network drivers with UDP. --- core/federated/RTI/rti_remote.c | 62 +++++++++++++++------- core/federated/RTI/rti_remote.h | 18 +++++-- core/federated/clock-sync.c | 80 +++++++++++++++++++---------- include/core/federated/clock-sync.h | 47 +++++++++++------ 4 files changed, 142 insertions(+), 65 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 9fd6a3b8d..a611c67f2 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -730,7 +730,14 @@ void handle_timestamp(federate_info_t* my_fed) { LF_MUTEX_UNLOCK(&rti_mutex); } -void send_physical_clock(unsigned char message_type, federate_info_t* fed, socket_type_t socket_type) { +/** + * Helper function to send the current physical clock time to a federate. + * This supports both TCP and UDP sockets. + * @param message_type The type of message being sent. + * @param fed Information about the federate receiving the message. + * @param is_udp Flag indicating whether to use UDP (true) or TCP (false). + */ +static void send_physical_clock_helper(unsigned char message_type, federate_info_t* fed, bool is_udp) { if (fed->enclave.state == NOT_CONNECTED) { lf_print_warning("Clock sync: RTI failed to send physical time to federate %d. Socket not connected.\n", fed->enclave.id); @@ -741,9 +748,8 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, socke int64_t current_physical_time = lf_time_physical(); encode_int64(current_physical_time, &(buffer[1])); - // Send the message - if (socket_type == UDP) { - // FIXME: UDP_addr is never initialized. + if (is_udp) { + // Send using UDP LF_PRINT_DEBUG("Clock sync: RTI sending UDP message type %u.", buffer[0]); ssize_t bytes_written = sendto(rti_remote->socket_descriptor_UDP, buffer, 1 + sizeof(int64_t), 0, (struct sockaddr*)&fed->UDP_addr, sizeof(fed->UDP_addr)); @@ -752,8 +758,9 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, socke strerror(errno)); return; } - } else if (socket_type == TCP) { - LF_PRINT_DEBUG("Clock sync: RTI sending TCP message type %u.", buffer[0]); + } else { + // Send using TCP + LF_PRINT_DEBUG("Clock sync: RTI sending TCP message type %u.", buffer[0]); LF_MUTEX_LOCK(&rti_mutex); write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int64_t), buffer, &rti_mutex, "Clock sync: RTI failed to send physical time to federate %d.", fed->enclave.id); @@ -763,20 +770,40 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, socke current_physical_time, fed->enclave.id); } -void handle_physical_clock_sync_message(federate_info_t* my_fed, socket_type_t socket_type) { - // Lock the mutex to prevent interference between sending the two - // coded probe messages. +void send_physical_clock(unsigned char message_type, federate_info_t* fed) { + send_physical_clock_helper(message_type, fed, false); +} + +void send_physical_clock_UDP(unsigned char message_type, federate_info_t* fed) { + send_physical_clock_helper(message_type, fed, true); +} + +/** + * Handle a physical clock synchronization message, sending the required messages. + * UDP sends a coded probe message. + * @param my_fed The federate information. + * @param send_coded_probe Boolean to send a coded probe message (for UDP only). + */ +static void handle_physical_clock_sync_message_helper(federate_info_t* my_fed, bool send_coded_probe) { LF_MUTEX_LOCK(&rti_mutex); // Reply with a T4 type message - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed, socket_type); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed); // Send the corresponding coded probe immediately after, // but only if this is a UDP channel. - if (socket_type == UDP) { - send_physical_clock(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed, socket_type); + if (send_coded_probe) { + send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed); } LF_MUTEX_UNLOCK(&rti_mutex); } +void handle_physical_clock_sync_message(federate_info_t* my_fed) { + handle_physical_clock_sync_message_helper(my_fed, false); +} + +void handle_physical_clock_sync_message_UDP(federate_info_t* my_fed) { + handle_physical_clock_sync_message_helper(my_fed, true); +} + void* clock_synchronization_thread(void* noargs) { initialize_lf_thread_id(); // Wait until all federates have been notified of the start time. @@ -814,7 +841,7 @@ void* clock_synchronization_thread(void* noargs) { // Send the RTI's current physical time to the federate // Send on UDP. LF_PRINT_DEBUG("RTI sending T1 message to initiate clock sync round."); - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, UDP); + send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_T1, fed); // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); @@ -839,7 +866,7 @@ void* clock_synchronization_thread(void* noargs) { continue; } LF_PRINT_DEBUG("Clock sync: RTI received T3 message from federate %d.", fed_id_2); - handle_physical_clock_sync_message(GET_FED_INFO(fed_id_2), UDP); + handle_physical_clock_sync_message_UDP(GET_FED_INFO(fed_id_2)); break; } else { // The message is not a T3 message. Discard the message and @@ -1277,7 +1304,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 // Send the required number of messages for clock synchronization for (int i = 0; i < rti_remote->clock_sync_exchanges_per_interval; i++) { // Send the RTI's current physical time T1 to the federate. - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, TCP); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed); // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); @@ -1287,7 +1314,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); LF_PRINT_DEBUG("RTI received T3 clock sync message from federate %d.", fed_id); - handle_physical_clock_sync_message(fed, TCP); + handle_physical_clock_sync_message(fed); } else { lf_print_error("Unexpected message %u from federate %d.", buffer[0], fed_id); send_reject(fed_netdrv, UNEXPECTED_MESSAGE); @@ -1492,8 +1519,7 @@ int start_rti_server() { lf_print("RTI: Listening for federates."); // Create the UDP socket server if (rti_remote->clock_sync_global_status >= clock_sync_on) { - if (create_clock_server(DEFAULT_UDP_PORT, &rti_remote->socket_descriptor_UDP, - &rti_remote->final_port_UDP)) { + if (create_clock_server(DEFAULT_UDP_PORT, &rti_remote->socket_descriptor_UDP, &rti_remote->final_port_UDP)) { lf_print_error_system_failure("RTI failed to create UDP server: %s.", strerror(errno)); return -1; } diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index abf7cb20e..900ee39b9 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -291,15 +291,22 @@ void handle_timestamp(federate_info_t* my_fed); /** * Take a snapshot of the physical clock time and send - * it to federate fed_id. + * it to federate fed_id using the network driver. * * This version assumes the caller holds the mutex lock. * * @param message_type The type of the clock sync message (see net_common.h). * @param fed The federate to send the physical time to. - * @param socket_type The socket type (TCP or UDP). */ -void send_physical_clock(unsigned char message_type, federate_info_t* fed, socket_type_t socket_type); +void send_physical_clock(unsigned char message_type, federate_info_t* fed); + +/** + * This does the same function with send_physical_clock(), but uses UDP. + * + * @param message_type The type of the clock sync message (see net_common.h). + * @param fed The federate to send the physical time to. + */ +void send_physical_clock_UDP(unsigned char message_type, federate_info_t* fed); /** * Handle clock synchronization T3 messages from federates. @@ -312,9 +319,10 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, socke * clock synchronization round. * * @param my_fed The sending federate. - * @param socket_type The RTI's socket type used for the communication (TCP or UDP) */ -void handle_physical_clock_sync_message(federate_info_t* my_fed, socket_type_t socket_type); +void handle_physical_clock_sync_message(federate_info_t* my_fed); + +void handle_physical_clock_sync_message_UDP(federate_info_t* my_fed); /** * A (quasi-)periodic thread that performs clock synchronization with each diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index cd95aa0b2..d2b1e14e8 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -208,8 +208,7 @@ uint16_t setup_clock_synchronization_with_rti() { return port_to_return; } -//TODO: Fix clocks. -void synchronize_initial_physical_clock_with_rti(int* rti_socket_TCP) { +void synchronize_initial_physical_clock_with_rti(netdrv_t* rti_netdrv) { LF_PRINT_DEBUG("Waiting for initial clock synchronization messages from the RTI."); size_t message_size = 1 + sizeof(instant_t); @@ -217,7 +216,7 @@ void synchronize_initial_physical_clock_with_rti(int* rti_socket_TCP) { for (int i = 0; i < _LF_CLOCK_SYNC_EXCHANGES_PER_INTERVAL; i++) { // The first message expected from the RTI is MSG_TYPE_CLOCK_SYNC_T1 - read_from_socket_fail_on_error(rti_socket_TCP, message_size, buffer, NULL, + read_from_netdrv_fail_on_error(rti_netdrv, message_size, buffer, NULL, "Federate %d did not get the initial clock synchronization message T1 from the RTI.", _lf_my_fed_id); @@ -231,12 +230,12 @@ void synchronize_initial_physical_clock_with_rti(int* rti_socket_TCP) { // Handle the message and send a reply T3 message. // NOTE: No need to acquire the mutex lock during initialization because only // one thread is running. - if (handle_T1_clock_sync_message(buffer, *rti_socket_TCP, receive_time) != 0) { + if (handle_T1_clock_sync_message(buffer, rti_netdrv, receive_time) != 0) { lf_print_error_and_exit("Initial clock sync: Failed to send T3 reply to RTI."); } // Next message from the RTI is required to be MSG_TYPE_CLOCK_SYNC_T4 - read_from_socket_fail_on_error(rti_socket_TCP, message_size, buffer, NULL, + read_from_netdrv_fail_on_error(rti_netdrv, message_size, buffer, NULL, "Federate %d did not get the clock synchronization message T4 from the RTI.", _lf_my_fed_id); @@ -246,7 +245,7 @@ void synchronize_initial_physical_clock_with_rti(int* rti_socket_TCP) { } // Handle the message. - handle_T4_clock_sync_message(buffer, *rti_socket_TCP, receive_time); + handle_T4_clock_sync_message(buffer, rti_netdrv, receive_time); } LF_PRINT_LOG("Finished initial clock synchronization with the RTI."); @@ -259,11 +258,12 @@ void synchronize_initial_physical_clock_with_rti(int* rti_socket_TCP) { * It also measures the time it takes between when the method is * called and the reply has been sent. * @param buffer The buffer containing the message, including the message type. - * @param socket The socket (either _lf_rti_socket_TCP or _lf_rti_socket_UDP). + * @param socket_or_netdrv The pointer of either UDP socket or the network driver. * @param t2 The physical time at which the T1 message was received. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, int socket, instant_t t2) { +static int handle_T1_clock_sync_message_common(unsigned char* buffer, void* socket_or_netdrv, instant_t t2, + bool use_udp) { // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); @@ -283,7 +283,10 @@ int handle_T1_clock_sync_message(unsigned char* buffer, int socket, instant_t t2 // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); - if (write_to_socket(socket, 1 + sizeof(uint16_t), reply_buffer)) { + int result = use_udp ? write_to_socket(*(int*)socket_or_netdrv, sizeof(reply_buffer), reply_buffer) + : write_to_netdrv((netdrv_t*)socket_or_netdrv, sizeof(reply_buffer), reply_buffer); + + if (result) { lf_print_error("Clock sync: Failed to send T3 message to RTI."); return -1; } @@ -295,12 +298,22 @@ int handle_T1_clock_sync_message(unsigned char* buffer, int socket, instant_t t2 return 0; } +// Wrapper for handling clock synchronization over netdrv (e.g., TCP) +int handle_T1_clock_sync_message(unsigned char* buffer, netdrv_t* netdrv, instant_t t2) { + return handle_T1_clock_sync_message_common(buffer, (void*)netdrv, t2, false); +} + +// Wrapper for handling clock synchronization over UDP +int handle_T1_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, instant_t t2) { + return handle_T1_clock_sync_message_common(buffer, (void*)UDP_socket, t2, true); +} + /** * Handle a clock synchronization message T4 coming from the RTI. - * If the socket is _lf_rti_socket_TCP, then assume we are in the + * If using the network driver, then assume we are in the * initial clock synchronization phase and set the clock offset * based on the estimated clock synchronization error. - * Otherwise, if the socket is _lf_rti_socket_UDP, then this looks also for a + * Otherwise, if using the UDP socket, then this looks also for a * subsequent "coded probe" message on the socket. If the delay between * the T4 and the coded probe message is not as expected, then reject * this clock synchronization round. If it is not rejected, then make @@ -308,10 +321,11 @@ int handle_T1_clock_sync_message(unsigned char* buffer, int socket, instant_t t2 * This function does not acquire the netdrv_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. - * @param socket The socket (either _lf_rti_socket_TCP or _lf_rti_socket_UDP). + * @param socket_or_netdrv The pointer of either UDP socket or the network driver. * @param r4 The physical time at which this T4 message was received. */ -void handle_T4_clock_sync_message(unsigned char* buffer, int socket, instant_t r4) { +static void handle_T4_clock_sync_message_common(unsigned char* buffer, void* socket_or_netdrv, instant_t r4, + int use_udp) { // Increment the number of received T4 messages _lf_rti_socket_stat.received_T4_messages_in_current_sync_window++; @@ -343,10 +357,10 @@ void handle_T4_clock_sync_message(unsigned char* buffer, int socket, instant_t r // If the socket is _lf_rti_socket_UDP, then // after sending T4, the RTI sends a "coded probe" message, // which can be used to filter out noise. - if (socket == _lf_rti_socket_UDP) { + if (use_udp) { // Read the coded probe message. // We can reuse the same buffer. - int read_failed = read_from_socket(socket, 1 + sizeof(instant_t), buffer); + int read_failed = read_from_socket(*(int*)socket_or_netdrv, 1 + sizeof(instant_t), buffer); instant_t r5 = lf_time_physical(); @@ -377,17 +391,15 @@ void handle_T4_clock_sync_message(unsigned char* buffer, int socket, instant_t r _lf_rti_socket_stat.received_T4_messages_in_current_sync_window--; return; } - // Apply a jitter attenuator to the estimated clock error to prevent - // large jumps in the underlying clock. - // Note that estimated_clock_error is calculated using lf_time_physical() which includes - // the clock sync adjustment. - adjustment = estimated_clock_error / _LF_CLOCK_SYNC_ATTENUATION; - } else { - // Use of TCP socket means we are in the startup phase, so - // rather than adjust the clock offset, we simply set it to the - // estimated error. - adjustment = estimated_clock_error; } + // If use UDP, apply a jitter attenuator to the estimated clock error to prevent + // large jumps in the underlying clock. + // Note that estimated_clock_error is calculated using lf_time_physical() which includes + // the clock sync adjustment. + // Use of TCP socket means we are in the startup phase, so + // rather than adjust the clock offset, we simply set it to the + // estimated error. + adjustment = use_udp ? estimated_clock_error / _LF_CLOCK_SYNC_ATTENUATION : estimated_clock_error; #ifdef _LF_CLOCK_SYNC_COLLECT_STATS // Enabled by default // Update RTI's socket stats @@ -437,6 +449,20 @@ void handle_T4_clock_sync_message(unsigned char* buffer, int socket, instant_t r } } +/** + * Wrapper for handling clock synchronization messages via TCP. + */ +void handle_T4_clock_sync_message(unsigned char* buffer, netdrv_t* netdrv, instant_t r4) { + handle_T4_clock_sync_message_common(buffer, (void*)netdrv, r4, 0); +} + +/** + * Wrapper for handling clock synchronization messages via UDP. + */ +void handle_T4_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, instant_t r4) { + handle_T4_clock_sync_message_common(buffer, (void*)UDP_socket, r4, 1); +} + /** * Thread that listens for UDP inputs from the RTI. */ @@ -502,7 +528,7 @@ void* listen_to_rti_UDP_thread(void* args) { break; } connected = true; - if (handle_T1_clock_sync_message(buffer, _lf_rti_socket_UDP, receive_time) != 0) { + if (handle_T1_clock_sync_message_UDP(buffer, &_lf_rti_socket_UDP, receive_time) != 0) { // Failed to send T3 reply. Wait for the next T1. waiting_for_T1 = true; continue; @@ -515,7 +541,7 @@ void* listen_to_rti_UDP_thread(void* args) { continue; } } else if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T4) { - handle_T4_clock_sync_message(buffer, _lf_rti_socket_UDP, receive_time); + handle_T4_clock_sync_message_UDP(buffer, &_lf_rti_socket_UDP, receive_time); waiting_for_T1 = true; } else { lf_print_warning("Clock sync: Received from RTI an unexpected UDP message type: %u. " diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index 1b0cacd3e..18fe33848 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -34,6 +34,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define CLOCK_SYNC_H #include "low_level_platform.h" +#include "net_driver.h" // Clock synchronization defaults to performing clock synchronization only at initialization. #define LF_CLOCK_SYNC_OFF 1 @@ -157,15 +158,15 @@ uint16_t setup_clock_synchronization_with_rti(void); * is required. * * This is a blocking function that expects - * to read a MSG_TYPE_CLOCK_SYNC_T1 from the RTI TCP socket. + * to read a MSG_TYPE_CLOCK_SYNC_T1 from the RTI network driver. * It will then follow the PTP protocol to synchronize the local * physical clock with the RTI. * Failing to complete this protocol is treated as a catastrophic * error that causes the federate to exit. * - * @param rti_socket_TCP Pointer to the RTI's socket + * @param rti_netdrv Pointer to the RTI's network driver. */ -void synchronize_initial_physical_clock_with_rti(int* rti_socket_TCP); +void synchronize_initial_physical_clock_with_rti(netdrv_t* rti_netdrv); /** * Handle a clock synchroninzation message T1 coming from the RTI. @@ -174,29 +175,45 @@ void synchronize_initial_physical_clock_with_rti(int* rti_socket_TCP); * It also measures the time it takes between when the method is * called and the reply has been sent. * @param buffer The buffer containing the message, including the message type. - * @param socket The socket (either _lf_rti_socket_TCP or _lf_rti_socket_UDP). + * @param netdrv_t The pointer to the network driver. * @param t2 The physical time at which the T1 message was received. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, int socket, instant_t t2); +int handle_T1_clock_sync_message(unsigned char* buffer, netdrv_t* netdrv, instant_t t2); /** - * Handle a clock synchronization message T4 coming from the RTI. - * If the socket is _lf_rti_socket_TCP, then assume we are in the - * initial clock synchronization phase and set the clock offset + * This does the same function as handle_T1_clock_sync_message(), only using a UDP socket. + * @param buffer The buffer containing the message, including the message type. + * @param socket The pointer to the UDP socket. + * @param t2 The physical time at which the T1 message was received. + * @return 0 if T3 reply is successfully sent, -1 otherwise. + */ +int handle_T1_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, instant_t t2); + +/** + * Handle a clock synchronization message T4 coming from the RTI using the network driver. + * Assume this is the initial clock synchronization phase and set the clock offset * based on the estimated clock synchronization error. - * Otherwise, if the socket is _lf_rti_socket_UDP, then this looks also for a - * subsequent "coded probe" message on the socket. If the delay between - * the T4 and the coded probe message is not as expected, then reject - * this clock synchronization round. If it is not rejected, then make - * an adjustment to the clock offset based on the estimated error. * This function does not acquire the netdrv_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. - * @param socket The socket (either _lf_rti_socket_TCP or _lf_rti_socket_UDP). + * @param netdrv_t The pointer to the network driver. + * @param r4 The physical time at which this T4 message was received. + */ +void handle_T4_clock_sync_message(unsigned char* buffer, netdrv_t* netdrv, instant_t r4); + +/** + * Handle a clock synchronization message T4 coming from the RTI using a UDP socket. + * Look for a subsequent "coded probe" message on the socket. + * If the delay between the T4 and the coded probe message is not as expected, reject the clock synchronization round. + * If it is not rejected, then make an adjustment to the clock offset based on the estimated error. + * This function does not acquire the netdrv_mutex lock. + * The caller should acquire it unless it is sure there is only one thread running. + * @param buffer The buffer containing the message, including the message type. + * @param socket The pointer to the UDP socket. * @param r4 The physical time at which this T4 message was received. */ -void handle_T4_clock_sync_message(unsigned char* buffer, int socket, instant_t r4); +void handle_T4_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, instant_t r4); /** * Thread that listens for UDP inputs from the RTI. From fb46c59e77eb51c2c1b2816540850d5b3369ca60 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 15:22:41 -0700 Subject: [PATCH 062/167] Code cleanup. --- network/api/net_driver.h | 2 +- network/api/socket_common.h | 7 ---- network/impl/src/socket_common.c | 72 +++----------------------------- 3 files changed, 7 insertions(+), 74 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 6006a9230..a604bc481 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -109,7 +109,7 @@ int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha /** * Write the specified number of bytes to the specified socket using - * write_to_socket_close_on_error and exit with an error code if an error occurs. + * write_to_netdrv_close_on_error and exit with an error code if an error occurs. * If the mutex argument is non-NULL, release the mutex before exiting. If the * format argument is non-null, then use it an any additional arguments to form * the error message using printf conventions. Otherwise, print a generic error diff --git a/network/api/socket_common.h b/network/api/socket_common.h index bae6a5b3f..debcdfe8e 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -145,13 +145,6 @@ int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port); -/** - * Return true if either the socket to the RTI is broken or the socket is - * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. - * @param socket Socket to check. - */ -bool check_socket_closed(int socket); - /** * Wait for an incoming connection request on the specified server socket. * This blocks until a connection is successfully accepted. If an error occurs that is not diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 9884d9f18..2f5890815 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -164,7 +164,12 @@ int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) return 0; } -bool check_socket_closed(int socket) { +/** + * Return true if either the socket to the RTI is broken or the socket is + * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. + * @param socket Socket to check. + */ +static bool check_socket_closed(int socket) { unsigned char first_byte; ssize_t bytes = peek_from_socket(socket, &first_byte); if (bytes < 0 || (bytes == 1 && first_byte == MSG_TYPE_FAILED)) { @@ -289,39 +294,6 @@ int read_from_socket(int socket, size_t num_bytes, unsigned char* buffer) { return 0; } -int read_from_socket_close_on_error(int* socket, size_t num_bytes, unsigned char* buffer) { - assert(socket); - int read_failed = read_from_socket(*socket, num_bytes, buffer); - if (read_failed) { - // Read failed. - // Socket has probably been closed from the other side. - // Shut down and close the socket from this side. - shutdown_socket(socket, false); - return -1; - } - return 0; -} - -void read_from_socket_fail_on_error(int* socket, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...) { - va_list args; - assert(socket); - int read_failed = read_from_socket_close_on_error(socket, num_bytes, buffer); - if (read_failed) { - // Read failed. - if (mutex != NULL) { - LF_MUTEX_UNLOCK(mutex); - } - if (format != NULL) { - va_start(args, format); - lf_print_error_system_failure(format, args); - va_end(args); - } else { - lf_print_error_system_failure("Failed to read from socket."); - } - } -} - ssize_t peek_from_socket(int socket, unsigned char* result) { ssize_t bytes_read = recv(socket, result, 1, MSG_DONTWAIT | MSG_PEEK); if (bytes_read < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) @@ -356,38 +328,6 @@ int write_to_socket(int socket, size_t num_bytes, unsigned char* buffer) { return 0; } -int write_to_socket_close_on_error(int* socket, size_t num_bytes, unsigned char* buffer) { - assert(socket); - int result = write_to_socket(*socket, num_bytes, buffer); - if (result) { - // Write failed. - // Socket has probably been closed from the other side. - // Shut down and close the socket from this side. - shutdown_socket(socket, false); - } - return result; -} - -void write_to_socket_fail_on_error(int* socket, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...) { - va_list args; - assert(socket); - int result = write_to_socket_close_on_error(socket, num_bytes, buffer); - if (result) { - // Write failed. - if (mutex != NULL) { - LF_MUTEX_UNLOCK(mutex); - } - if (format != NULL) { - va_start(args, format); - lf_print_error_system_failure(format, args); - va_end(args); - } else { - lf_print_error("Failed to write to socket. Closing it."); - } - } -} - int shutdown_socket(int* socket, bool read_before_closing) { if (!read_before_closing) { if (shutdown(*socket, SHUT_RDWR)) { From 4464284ac64f3a775dafae54bbbeb8f20645ab2c Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 15:25:36 -0700 Subject: [PATCH 063/167] Cleanup read and write functions. --- network/impl/src/lf_socket_support.c | 56 +--------------------------- 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 10c003a68..4c31efc2b 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -79,36 +79,7 @@ int connect_to_netdrv(netdrv_t* drv) { int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = (socket_priv_t*)drv->priv; - int socket = priv->socket_descriptor; - if (socket < 0) { - // Socket is not open. - errno = EBADF; - return -1; - } - ssize_t bytes_read = 0; - while (bytes_read < (ssize_t)num_bytes) { - ssize_t more = read(socket, buffer + bytes_read, num_bytes - (size_t)bytes_read); - if (more < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) { - // Those error codes set by the socket indicates - // that we should try again (@see man errno). - LF_PRINT_DEBUG("Reading from socket %d failed with error: `%s`. Will try again.", socket, strerror(errno)); - lf_sleep(DELAY_BETWEEN_SOCKET_RETRIES); - continue; - } else if (more < 0 && errno == ECONNRESET) { - lf_print_error( - "Connection was closed by the peer without properly sending an EOF first. Considering this a soft error."); - return -1; - } else if (more < 0) { - // A more serious error occurred. - lf_print_error("Reading from socket %d failed. With error: `%s`", socket, strerror(errno)); - return -1; - } else if (more == 0) { - // EOF received. - return 1; - } - bytes_read += more; - } - return 0; + return read_from_socket(priv->socket_descriptor, num_bytes, buffer); } int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { @@ -145,30 +116,7 @@ void read_from_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned ch int write_to_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = (socket_priv_t*)drv->priv; - int socket = priv->socket_descriptor; - if (socket < 0) { - // Socket is not open. - errno = EBADF; - return -1; - } - ssize_t bytes_written = 0; - while (bytes_written < (ssize_t)num_bytes) { - ssize_t more = write(socket, buffer + bytes_written, num_bytes - (size_t)bytes_written); - if (more <= 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) { - // The error codes EAGAIN or EWOULDBLOCK indicate - // that we should try again (@see man errno). - // The error code EINTR means the system call was interrupted before completing. - LF_PRINT_DEBUG("Writing to socket %d was blocked. Will try again.", socket); - lf_sleep(DELAY_BETWEEN_SOCKET_RETRIES); - continue; - } else if (more < 0) { - // A more serious error occurred. - lf_print_error("Writing to socket %d failed. With error: `%s`", socket, strerror(errno)); - return -1; - } - bytes_written += more; - } - return 0; + return write_to_socket(priv->socket_descriptor, num_bytes, buffer); } int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { From d4d78a92acd6947080f9af869310de60b18b2aa9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 18:22:56 -0700 Subject: [PATCH 064/167] Rollback create socket server to one function. --- network/api/socket_common.h | 3 +- network/impl/src/lf_socket_support.c | 2 +- network/impl/src/socket_common.c | 54 +++++++++++++--------------- 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/network/api/socket_common.h b/network/api/socket_common.h index debcdfe8e..6653a813d 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -141,7 +141,8 @@ int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool * @param increment_port_on_retry Boolean to retry port increment. * @return 0 for success, -1 for failure. */ -int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, bool increment_port_on_retry); +int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, + bool increment_port_on_retry); int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 4c31efc2b..f8f7504ee 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -42,7 +42,7 @@ void free_netdrv(netdrv_t* drv) { int create_server(netdrv_t* drv, bool increment_port_on_retry) { socket_priv_t* priv = (socket_priv_t*)drv->priv; - return create_socket_server(priv->user_specified_port, &priv->socket_descriptor, &priv->port, + return create_socket_server(priv->user_specified_port, &priv->socket_descriptor, &priv->port, TCP, increment_port_on_retry); } diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 2f5890815..b68152680 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -119,27 +119,37 @@ int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool return used_port; } -int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, bool increment_port_on_retry) { +int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, + bool increment_port_on_retry) { int socket_descriptor; struct timeval timeout_time; - - // Create an IPv4 socket for TCP. - socket_descriptor = create_real_time_tcp_socket_errexit(); - // Set the timeout time for the communications of the server - timeout_time = (struct timeval){.tv_sec = TCP_TIMEOUT_TIME / BILLION, .tv_usec = (TCP_TIMEOUT_TIME % BILLION) / 1000}; - + if (sock_type == TCP) { + // Create an IPv4 socket for TCP. + socket_descriptor = create_real_time_tcp_socket_errexit(); + // Set the timeout time for the communications of the server + timeout_time = + (struct timeval){.tv_sec = TCP_TIMEOUT_TIME / BILLION, .tv_usec = (TCP_TIMEOUT_TIME % BILLION) / 1000}; + } else { + // Create a UDP socket. + socket_descriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + timeout_time = + (struct timeval){.tv_sec = UDP_TIMEOUT_TIME / BILLION, .tv_usec = (UDP_TIMEOUT_TIME % BILLION) / 1000}; + } + char* type = (sock_type == TCP) ? "TCP" : "UDP"; if (socket_descriptor < 0) { - lf_print_error("Failed to create TCP socket."); + lf_print_error("Failed to create %s socket.", type); return -1; } set_socket_timeout_option(socket_descriptor, &timeout_time); int used_port = set_socket_bind_option(socket_descriptor, port, increment_port_on_retry); - // Enable listening for socket connections. - // The second argument is the maximum number of queued socket requests, - // which according to the Mac man page is limited to 128. - if (listen(socket_descriptor, 128)) { - lf_print_error("Failed to listen on %d socket: %s.", socket_descriptor, strerror(errno)); - return -1; + if (sock_type == TCP) { + // Enable listening for socket connections. + // The second argument is the maximum number of queued socket requests, + // which according to the Mac man page is limited to 128. + if (listen(socket_descriptor, 128)) { + lf_print_error("Failed to listen on %d socket: %s.", socket_descriptor, strerror(errno)); + return -1; + } } *final_socket = socket_descriptor; *final_port = used_port; @@ -147,21 +157,7 @@ int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, } int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) { - int socket_descriptor; - struct timeval timeout_time; - // Create a UDP socket. - socket_descriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - timeout_time = (struct timeval){.tv_sec = UDP_TIMEOUT_TIME / BILLION, .tv_usec = (UDP_TIMEOUT_TIME % BILLION) / 1000}; - - if (socket_descriptor < 0) { - lf_print_error("Failed to create UDP socket."); - return -1; - } - set_socket_timeout_option(socket_descriptor, &timeout_time); - int used_port = set_socket_bind_option(socket_descriptor, port, true); - *final_socket = socket_descriptor; - *final_port = used_port; - return 0; + return create_socket_server(port, final_socket, final_port, UDP, true); } /** From 5d1bf720f17a3a92041c7386c0583f6184324e08 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 19:16:11 -0700 Subject: [PATCH 065/167] Minor fix and formatting. --- core/federated/RTI/rti_remote.c | 2 +- core/federated/federate.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index a611c67f2..b5c53d80e 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -989,7 +989,7 @@ void* federate_info_thread_TCP(void* fed) { // Nothing more to do. Close the socket and exit. // Prevent multiple threads from closing the same socket at the same time. LF_MUTEX_LOCK(&rti_mutex); - shutdown_netdrv(my_fed->fed_netdrv, false); // from unistd.h + shutdown_netdrv(my_fed->fed_netdrv, false); LF_MUTEX_UNLOCK(&rti_mutex); // FIXME: We need better error handling here, but do not stop execution here. break; diff --git a/core/federated/federate.c b/core/federated/federate.c index 66617c2b3..7690d8cad 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -17,9 +17,9 @@ #include // inet_ntop & inet_pton #include // Defines getaddrinfo(), freeaddrinfo() and struct addrinfo. #include // Defines struct sockaddr_in -#include // Defines read(), write(), and close() -#include // Defines memset(), strnlen(), strncmp(), strncpy() -#include // Defines strerror() +#include // Defines read(), write(), and close() +#include // Defines memset(), strnlen(), strncmp(), strncpy() +#include // Defines strerror() #include #include // Defined perror(), errno @@ -2045,9 +2045,9 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, - (unsigned char*)&response, &lf_outbound_netdrv_mutex, - "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); + write_to_netdrv_fail_on_error(_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, + &lf_outbound_netdrv_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", + remote_fed_id); LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); // Start a thread to listen for incoming messages from other federates. @@ -2058,7 +2058,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Failed to create a listening thread. LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] != NULL) { - shutdown_netdrv(netdrv, false); + shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], false); _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = NULL; } LF_MUTEX_UNLOCK(&netdrv_mutex); @@ -2348,7 +2348,7 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d netdrv_t* netdrv = _fed.netdrv_to_RTI; #else // Send the absent message directly to the federate - netdrv_t* netdrv = _fed.netdrvs_for_outbound_p2p_connections[fed_ID]; + netdrv_t* netdrv = _fed.netdrvs_for_outbound_p2p_connections[fed_ID]; #endif if (netdrv == _fed.netdrv_to_RTI) { @@ -2459,7 +2459,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int // Use a mutex lock to prevent multiple threads from simultaneously sending. LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - netdrv_t* netdrv ; + netdrv_t* netdrv; if (message_type == MSG_TYPE_P2P_TAGGED_MESSAGE) { netdrv = _fed.netdrvs_for_outbound_p2p_connections[federate]; tracepoint_federate_to_federate(send_P2P_TAGGED_MSG, _lf_my_fed_id, federate, ¤t_message_intended_tag); From 4c6e5e71525157bf0cd813e40565cb216d9508b5 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 19:42:35 -0700 Subject: [PATCH 066/167] Minor fix on clock-sync. --- core/federated/clock-sync.c | 4 ++-- network/impl/src/socket_common.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index d2b1e14e8..273af494b 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -283,8 +283,8 @@ static int handle_T1_clock_sync_message_common(unsigned char* buffer, void* sock // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); - int result = use_udp ? write_to_socket(*(int*)socket_or_netdrv, sizeof(reply_buffer), reply_buffer) - : write_to_netdrv((netdrv_t*)socket_or_netdrv, sizeof(reply_buffer), reply_buffer); + int result = use_udp ? write_to_socket(*(int*)socket_or_netdrv, 1 + sizeof(uint16_t), reply_buffer) + : write_to_netdrv((netdrv_t*)socket_or_netdrv, 1 + sizeof(uint16_t), reply_buffer); if (result) { lf_print_error("Clock sync: Failed to send T3 message to RTI."); diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index b68152680..963145338 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -157,7 +157,7 @@ int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, } int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) { - return create_socket_server(port, final_socket, final_port, UDP, true); + return create_socket_server(port, final_socket, final_port, UDP, false); } /** From e0d7fd1ef25b654440f65a191fe03fb70dd0401e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 20:34:11 -0700 Subject: [PATCH 067/167] Fix sending clocks. --- core/federated/RTI/rti_remote.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index b5c53d80e..e54f45e33 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -786,16 +786,17 @@ void send_physical_clock_UDP(unsigned char message_type, federate_info_t* fed) { */ static void handle_physical_clock_sync_message_helper(federate_info_t* my_fed, bool send_coded_probe) { LF_MUTEX_LOCK(&rti_mutex); + if (!send_coded_probe) { // Reply with a T4 type message send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed); // Send the corresponding coded probe immediately after, // but only if this is a UDP channel. - if (send_coded_probe) { + else { + send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_T4, my_fed); send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed); } LF_MUTEX_UNLOCK(&rti_mutex); } - void handle_physical_clock_sync_message(federate_info_t* my_fed) { handle_physical_clock_sync_message_helper(my_fed, false); } From 30ecc8b757ad32901d8e361a4361c70c837e220d Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 20 Jan 2025 20:34:11 -0700 Subject: [PATCH 068/167] Fix sending clocks. --- core/federated/RTI/rti_remote.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index b5c53d80e..ec577de07 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -786,16 +786,17 @@ void send_physical_clock_UDP(unsigned char message_type, federate_info_t* fed) { */ static void handle_physical_clock_sync_message_helper(federate_info_t* my_fed, bool send_coded_probe) { LF_MUTEX_LOCK(&rti_mutex); + if (!send_coded_probe) { // Reply with a T4 type message send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed); // Send the corresponding coded probe immediately after, // but only if this is a UDP channel. - if (send_coded_probe) { + } else { + send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_T4, my_fed); send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed); } LF_MUTEX_UNLOCK(&rti_mutex); } - void handle_physical_clock_sync_message(federate_info_t* my_fed) { handle_physical_clock_sync_message_helper(my_fed, false); } From 087b9e2af2b7b1e709cf19570a3adb04e34a1e9b Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 21 Jan 2025 12:01:35 -0700 Subject: [PATCH 069/167] Fix netdrv pointer check. --- core/federated/federate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 7690d8cad..919732b4e 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -821,7 +821,7 @@ static void close_outbound_netdrv(int fed_id) { // abnormal termination, in which case it will just close the network driver. if (_lf_normal_termination) { LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - if (_fed.netdrvs_for_outbound_p2p_connections[fed_id] >= 0) { + if (_fed.netdrvs_for_outbound_p2p_connections[fed_id] != NULL) { // Close the network driver by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); From 6dfabf56c102c50281826231a3d68c79ef1b3e9b Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 21 Jan 2025 12:24:49 -0700 Subject: [PATCH 070/167] Fix memory uninitialized error. --- network/impl/src/lf_socket_support.c | 1 + 1 file changed, 1 insertion(+) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index f8f7504ee..a73def181 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -22,6 +22,7 @@ netdrv_t* initialize_netdrv() { // Server initialization. priv->port = 0; + priv->user_specified_port = 0; priv->socket_descriptor = -1; // Federate initialization From 6147df62685fa0aaa07d3db6fea9fd14a89c0ee6 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 21 Jan 2025 12:36:29 -0700 Subject: [PATCH 071/167] Fix get getaddrinfo memory error. --- network/impl/src/socket_common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 963145338..56670ddb8 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -120,7 +120,7 @@ int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool } int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, - bool increment_port_on_retry) { + bool increment_port_on_retry) { int socket_descriptor; struct timeval timeout_time; if (sock_type == TCP) { @@ -252,8 +252,10 @@ int connect_to_socket(int sock, const char* hostname, int port) { } lf_print_warning("Could not connect. Will try again every " PRINTF_TIME " nanoseconds. Connecting to port %d.\n", CONNECT_RETRY_INTERVAL, used_port); + freeaddrinfo(result); continue; } else { + freeaddrinfo(result); break; } freeaddrinfo(result); From 70e9e579bcec7c9f64ec848b69f12f55642adfd0 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 11:48:25 -0700 Subject: [PATCH 072/167] Add NULL setting after freed pointer. --- core/federated/federate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/federated/federate.c b/core/federated/federate.c index 919732b4e..5dbdbfc00 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -409,6 +409,7 @@ static void close_inbound_netdrv(int fed_id) { LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] != NULL) { shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); + _fed.netdrvs_for_inbound_p2p_connections[fed_id] = NULL; } LF_MUTEX_UNLOCK(&netdrv_mutex); } @@ -825,10 +826,12 @@ static void close_outbound_netdrv(int fed_id) { // Close the network driver by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); + _fed.netdrvs_for_outbound_p2p_connections[fed_id] = NULL; } LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } else { shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); + _fed.netdrvs_for_outbound_p2p_connections[fed_id] = NULL; } } From dd4eb91c78b5a5ef42e6a507487dfb65f46d1dcb Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 12:23:11 -0700 Subject: [PATCH 073/167] Fix for docker tests. --- network/impl/src/lf_socket_support.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index a73def181..f126b8bf3 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -185,7 +185,8 @@ int get_peer_address(netdrv_t* drv) { // the .server_hostname field of the federate. char str[INET_ADDRSTRLEN + 1]; inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); - strncpy(priv->server_hostname, str, INET_ADDRSTRLEN); + strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters +priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); #endif From 11b8088cd9506894783662e5fea1c5f3c587abfb Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 12:37:03 -0700 Subject: [PATCH 074/167] Revert "Add NULL setting after freed pointer." This reverts commit 70e9e579bcec7c9f64ec848b69f12f55642adfd0. --- core/federated/federate.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 5dbdbfc00..919732b4e 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -409,7 +409,6 @@ static void close_inbound_netdrv(int fed_id) { LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] != NULL) { shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); - _fed.netdrvs_for_inbound_p2p_connections[fed_id] = NULL; } LF_MUTEX_UNLOCK(&netdrv_mutex); } @@ -826,12 +825,10 @@ static void close_outbound_netdrv(int fed_id) { // Close the network driver by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); - _fed.netdrvs_for_outbound_p2p_connections[fed_id] = NULL; } LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } else { shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); - _fed.netdrvs_for_outbound_p2p_connections[fed_id] = NULL; } } From 51a4257c01df14e102f4d411de7151a10bcb6957 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 12:37:31 -0700 Subject: [PATCH 075/167] Fix ref. --- lingua-franca-ref.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lingua-franca-ref.txt b/lingua-franca-ref.txt index 8b25206ff..1b2aba1c3 100644 --- a/lingua-franca-ref.txt +++ b/lingua-franca-ref.txt @@ -1 +1 @@ -master \ No newline at end of file +networkdriver \ No newline at end of file From a75fefcb7e4d091ed6ab4c736989a51414d3613e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 13:15:20 -0700 Subject: [PATCH 076/167] Remove shutdown socket on close on error. --- network/impl/src/lf_socket_support.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index f126b8bf3..f79188dc9 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -84,13 +84,13 @@ int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { } int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + // socket_priv_t* priv = (socket_priv_t*)drv->priv; int read_failed = read_from_netdrv(drv, num_bytes, buffer); if (read_failed) { // Read failed. // Socket has probably been closed from the other side. // Shut down and close the socket from this side. - shutdown_socket(&priv->socket_descriptor, false); + // shutdown_socket(&priv->socket_descriptor, false); return -1; } return 0; From b703ab0c35d5c00064d09e676b93cd6f01fdbad1 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 13:39:05 -0700 Subject: [PATCH 077/167] Fix comments. --- include/core/federated/federate.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index b2432e6f2..1cdd79c51 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -68,7 +68,7 @@ typedef struct federate_instance_t { * An array that holds the network drivers for inbound * connections from each federate. The index will be the federate * ID of the remote sending federate. This is initialized at startup - * to -1 and is set to a socket ID by lf_handle_p2p_connections_from_federates() //TODO: Check here. + * to NULL and is set to the pointer of the network driver by lf_connect_to_federate() * when the network drivers is opened. * * @note There will not be an inbound network driver unless a physical connection @@ -83,7 +83,7 @@ typedef struct federate_instance_t { * An array that holds the network drivers for outbound direct * connections to each remote federate. The index will be the federate * ID of the remote receiving federate. This is initialized at startup - * to -1 and is set to a socket ID by lf_connect_to_federate() //TODO: Check here. + * to NULL and is set to the pointer of the network driver by lf_connect_to_federate() * when the network drivers is opened. * * @note This federate will not open an outbound network drivers unless a physical @@ -313,7 +313,7 @@ void lf_reset_status_fields_on_input_port_triggers(); * @brief Send a message to another federate. * * This function is used for physical connections - * between federates. If the socket connection to the remote federate or the RTI has been broken, + * between federates. If the connection to the remote federate or the RTI has been broken, * then this returns -1 without sending. Otherwise, it returns 0. * * This method assumes that the caller does not hold the lf_outbound_netdrv_mutex lock, @@ -495,7 +495,7 @@ void lf_stall_advance_level_federation_locked(size_t level); * @brief Synchronize the start with other federates via the RTI. * * This assumes that a connection to the RTI is already made - * and _lf_rti_socket_TCP is valid. It then sends the current logical //TODO: Check. + * and netdrv_to_RTI is valid. It then sends the current logical * time to the RTI and waits for the RTI to respond with a specified * time. It starts a thread to listen for messages from the RTI. */ From e95f6e578cf1ce2c141cdd4bfc23b0542e5cbe1f Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 13:43:46 -0700 Subject: [PATCH 078/167] Add socket = -1 check, to check if already closed. --- network/impl/src/lf_socket_support.c | 4 ++-- network/impl/src/socket_common.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index f79188dc9..f126b8bf3 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -84,13 +84,13 @@ int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { } int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { - // socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = (socket_priv_t*)drv->priv; int read_failed = read_from_netdrv(drv, num_bytes, buffer); if (read_failed) { // Read failed. // Socket has probably been closed from the other side. // Shut down and close the socket from this side. - // shutdown_socket(&priv->socket_descriptor, false); + shutdown_socket(&priv->socket_descriptor, false); return -1; } return 0; diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 56670ddb8..5c501dec6 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -327,6 +327,10 @@ int write_to_socket(int socket, size_t num_bytes, unsigned char* buffer) { } int shutdown_socket(int* socket, bool read_before_closing) { + if (*socket == -1) { + lf_print_log("Socket is already closed."); + return 0; + } if (!read_before_closing) { if (shutdown(*socket, SHUT_RDWR)) { lf_print_log("On shutdown socket, received reply: %s", strerror(errno)); From dccd81ae82db3143cdb4ffd0499201e644e9afb2 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 13:47:42 -0700 Subject: [PATCH 079/167] Revert "Revert "Add NULL setting after freed pointer."" This reverts commit 11b8088cd9506894783662e5fea1c5f3c587abfb. --- core/federated/federate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/federated/federate.c b/core/federated/federate.c index 919732b4e..5dbdbfc00 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -409,6 +409,7 @@ static void close_inbound_netdrv(int fed_id) { LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] != NULL) { shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); + _fed.netdrvs_for_inbound_p2p_connections[fed_id] = NULL; } LF_MUTEX_UNLOCK(&netdrv_mutex); } @@ -825,10 +826,12 @@ static void close_outbound_netdrv(int fed_id) { // Close the network driver by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); + _fed.netdrvs_for_outbound_p2p_connections[fed_id] = NULL; } LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); } else { shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); + _fed.netdrvs_for_outbound_p2p_connections[fed_id] = NULL; } } From 82033883b8f46214f8b677321908d4911c3016a9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 13:48:18 -0700 Subject: [PATCH 080/167] Revert "Fix for docker tests." This reverts commit dd4eb91c78b5a5ef42e6a507487dfb65f46d1dcb. --- network/impl/src/lf_socket_support.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index f126b8bf3..a73def181 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -185,8 +185,7 @@ int get_peer_address(netdrv_t* drv) { // the .server_hostname field of the federate. char str[INET_ADDRSTRLEN + 1]; inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); - strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters -priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly + strncpy(priv->server_hostname, str, INET_ADDRSTRLEN); LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); #endif From 561e07e179ac9607b15175cce27e6ba6a9dee5cf Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 13:52:20 -0700 Subject: [PATCH 081/167] Fix formatting. --- core/federated/RTI/rti_remote.c | 8 ++++---- network/api/net_util.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index ec577de07..a91f6ee5b 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -787,10 +787,10 @@ void send_physical_clock_UDP(unsigned char message_type, federate_info_t* fed) { static void handle_physical_clock_sync_message_helper(federate_info_t* my_fed, bool send_coded_probe) { LF_MUTEX_LOCK(&rti_mutex); if (!send_coded_probe) { - // Reply with a T4 type message - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed); - // Send the corresponding coded probe immediately after, - // but only if this is a UDP channel. + // Reply with a T4 type message + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed); + // Send the corresponding coded probe immediately after, + // but only if this is a UDP channel. } else { send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_T4, my_fed); send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed); diff --git a/network/api/net_util.h b/network/api/net_util.h index 7cd5faf65..b945659c7 100644 --- a/network/api/net_util.h +++ b/network/api/net_util.h @@ -51,7 +51,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "low_level_platform.h" #include "tag.h" - #define HOST_LITTLE_ENDIAN 1 #define HOST_BIG_ENDIAN 2 From 16ff0c09c3dd3b5becca59e18b472af94317cf05 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 13:58:13 -0700 Subject: [PATCH 082/167] Revert "Revert "Fix for docker tests."" This reverts commit 82033883b8f46214f8b677321908d4911c3016a9. --- network/impl/src/lf_socket_support.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index a73def181..f126b8bf3 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -185,7 +185,8 @@ int get_peer_address(netdrv_t* drv) { // the .server_hostname field of the federate. char str[INET_ADDRSTRLEN + 1]; inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); - strncpy(priv->server_hostname, str, INET_ADDRSTRLEN); + strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters +priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); #endif From 6b8758f8de8b099b93c067444b136c90d8c02191 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 13:58:34 -0700 Subject: [PATCH 083/167] Formatting. --- network/impl/src/lf_socket_support.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index f126b8bf3..fccf9b67e 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -185,8 +185,8 @@ int get_peer_address(netdrv_t* drv) { // the .server_hostname field of the federate. char str[INET_ADDRSTRLEN + 1]; inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); - strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters -priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly + strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters + priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); #endif From 4ca416526d35e256de442f7c3f0f62cccb572d18 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 15:10:16 -0700 Subject: [PATCH 084/167] Add null check for accept() --- core/federated/RTI/rti_remote.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index a91f6ee5b..9a73c6288 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1425,6 +1425,10 @@ static bool authenticate_federate(netdrv_t* fed_netdrv) { void lf_connect_to_federates(netdrv_t* rti_netdrv) { for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { netdrv_t* fed_netdrv = accept_netdrv(rti_netdrv, NULL); + if (fed_netdrv == NULL) { + lf_print_warning("RTI failed to accept the federate."); + return NULL; + } // Wait for the first message from the federate when RTI -a option is on. #ifdef __RTI_AUTH__ if (rti_remote->authentication_enabled) { @@ -1483,6 +1487,9 @@ void* respond_to_erroneous_connections(void* nothing) { // The following will block until either a federate attempts to connect // or shutdown_socket(rti->socket_descriptor_TCP) is called. netdrv_t* fed_netdrv = accept_netdrv(rti_remote->rti_netdrv, NULL); + if (fed_netdrv == NULL) { + return NULL; + } if (rti_remote->all_federates_exited) { return NULL; } From 18e47ef3eb6994e8685290674666eefe1e52e567 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 15:11:28 -0700 Subject: [PATCH 085/167] Minor fix on void return. --- core/federated/RTI/rti_remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 9a73c6288..0b531bbbd 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1427,7 +1427,7 @@ void lf_connect_to_federates(netdrv_t* rti_netdrv) { netdrv_t* fed_netdrv = accept_netdrv(rti_netdrv, NULL); if (fed_netdrv == NULL) { lf_print_warning("RTI failed to accept the federate."); - return NULL; + return; } // Wait for the first message from the federate when RTI -a option is on. #ifdef __RTI_AUTH__ From 3ea4614b0ef1b87151a89114d883175518bed7a2 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 15:43:32 -0700 Subject: [PATCH 086/167] Formatting. --- core/federated/RTI/rti_remote.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 900ee39b9..725ca6ae7 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -49,12 +49,12 @@ */ typedef struct federate_info_t { scheduling_node_t enclave; - bool requested_stop; // Indicates that the federate has requested stop or has replied - // to a request for stop from the RTI. Used to prevent double-counting - // a federate when handling lf_request_stop(). - lf_thread_t thread_id; // The ID of the thread handling communication with this federate. + bool requested_stop; // Indicates that the federate has requested stop or has replied + // to a request for stop from the RTI. Used to prevent double-counting + // a federate when handling lf_request_stop(). + lf_thread_t thread_id; // The ID of the thread handling communication with this federate. - netdrv_t* fed_netdrv; // The netdriver that the RTI handling each federate. + netdrv_t* fed_netdrv; // The netdriver that the RTI handling each federate. int socket; // The TCP socket descriptor for communicating with this federate. struct sockaddr_in UDP_addr; // The UDP address for the federate. From b176d0a40304ba02de0fe4247a176da8e118789a Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 15:50:33 -0700 Subject: [PATCH 087/167] Move get_peer_address to accept_socket --- core/federated/RTI/rti_remote.c | 5 ----- network/api/net_driver.h | 2 -- network/impl/src/lf_socket_support.c | 10 +++++++--- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 0b531bbbd..1602de633 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -75,7 +75,6 @@ void notify_tag_advance_grant(scheduling_node_t* e, tag_t tag) { // This function is called in notify_advance_grant_if_safe(), which is a long // function. During this call, the socket might close, causing the following write_to_netdrv // to fail. Consider a failure here a soft failure and update the federate's status. - // TODO: Check if works well. if (write_to_netdrv(((federate_info_t*)e)->fed_netdrv, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; @@ -1159,10 +1158,6 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { federate_info_t* fed = GET_FED_INFO(fed_id); // The MSG_TYPE_FED_IDS message has the right federation ID. - // Get the peer address from the connected socket_id. Then assign it as the federate's socket server. - if (get_peer_address(fed_netdrv) != 0) { - lf_print_error("RTI failed to get peer address."); - }; fed->fed_netdrv = fed_netdrv; // Set the federate's state as pending diff --git a/network/api/net_driver.h b/network/api/net_driver.h index a604bc481..805a10f14 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -32,8 +32,6 @@ void create_client(netdrv_t* drv); int connect_to_netdrv(netdrv_t* drv); -int get_peer_address(netdrv_t* drv); - /** * Read the specified number of bytes from the specified socket into the specified buffer. * If an error occurs during this reading, return -1 and set errno to indicate diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index fccf9b67e..0a4d0ec13 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -65,6 +65,10 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { return NULL; } fed_priv->socket_descriptor = sock; + // Get the peer address from the connected socket_id. + if (get_peer_address(fed_netdrv) != 0) { + lf_print_error("RTI failed to get peer address."); + }; return fed_netdrv; } @@ -170,12 +174,12 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { return ret; } -int get_peer_address(netdrv_t* drv) { +static int get_peer_address(netdrv_t* drv) { socket_priv_t* priv = (socket_priv_t*)drv->priv; struct sockaddr_in peer_addr; socklen_t addr_len = sizeof(peer_addr); if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { - lf_print_error("RTI failed to get peer address."); + lf_print_error("Failed to get peer address."); return -1; } priv->server_ip_addr = peer_addr.sin_addr; @@ -188,7 +192,7 @@ int get_peer_address(netdrv_t* drv) { strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly - LF_PRINT_DEBUG("RTI got address %s", priv->server_hostname); + LF_PRINT_DEBUG("Got address %s", priv->server_hostname); #endif return 0; } From 7d2f11d5e59561f5cfd00ffe853cd82ccbd302b9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 15:50:52 -0700 Subject: [PATCH 088/167] Cleanup CMake. --- core/federated/RTI/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/federated/RTI/CMakeLists.txt b/core/federated/RTI/CMakeLists.txt index fce1517a5..a7d26f553 100644 --- a/core/federated/RTI/CMakeLists.txt +++ b/core/federated/RTI/CMakeLists.txt @@ -34,10 +34,7 @@ if (NOT DEFINED LOG_LEVEL) set(LOG_LEVEL 0) ENDIF(NOT DEFINED LOG_LEVEL) -# option(COMM_TYPE "Communication type between RTI and federate(s)." ON) -# IF(COMM_TYPE MATCHES ON) set(COMM_TYPE TCP) -# ENDIF() IF(CMAKE_BUILD_TYPE MATCHES DEBUG) # Set the LOG_LEVEL to 4 to get DEBUG messages From d54c9ad313a505ffc45fe769a37a90d6ff898ae8 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 15:54:33 -0700 Subject: [PATCH 089/167] Move static function to top. --- network/impl/src/lf_socket_support.c | 46 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 0a4d0ec13..43261ddea 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -9,6 +9,29 @@ #include "util.h" // #include "lf_socket_support.h" +static int get_peer_address(netdrv_t* drv) { + socket_priv_t* priv = (socket_priv_t*)drv->priv; + struct sockaddr_in peer_addr; + socklen_t addr_len = sizeof(peer_addr); + if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { + lf_print_error("Failed to get peer address."); + return -1; + } + priv->server_ip_addr = peer_addr.sin_addr; + +#if LOG_LEVEL >= LOG_LEVEL_DEBUG + // Create the human readable format and copy that into + // the .server_hostname field of the federate. + char str[INET_ADDRSTRLEN + 1]; + inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); + strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters + priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly + + LF_PRINT_DEBUG("Got address %s", priv->server_hostname); +#endif + return 0; +} + netdrv_t* initialize_netdrv() { netdrv_t* drv = malloc(sizeof(netdrv_t)); if (drv == NULL) { @@ -174,29 +197,6 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { return ret; } -static int get_peer_address(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; - struct sockaddr_in peer_addr; - socklen_t addr_len = sizeof(peer_addr); - if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { - lf_print_error("Failed to get peer address."); - return -1; - } - priv->server_ip_addr = peer_addr.sin_addr; - -#if LOG_LEVEL >= LOG_LEVEL_DEBUG - // Create the human readable format and copy that into - // the .server_hostname field of the federate. - char str[INET_ADDRSTRLEN + 1]; - inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); - strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters - priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly - - LF_PRINT_DEBUG("Got address %s", priv->server_hostname); -#endif - return 0; -} - int32_t get_my_port(netdrv_t* drv) { socket_priv_t* priv = (socket_priv_t*)drv->priv; return priv->port; From 860520fee780e24f97371949e7d4db8a52aced58 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 16:54:49 -0700 Subject: [PATCH 090/167] Merge separated functions to one, without wrappers on clock related functions. --- core/federated/RTI/rti_remote.c | 52 ++++++++--------------------- core/federated/RTI/rti_remote.h | 16 +++------ core/federated/clock-sync.c | 40 +++++----------------- include/core/federated/clock-sync.h | 40 ++++++++-------------- 4 files changed, 38 insertions(+), 110 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 1602de633..acae93398 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -729,14 +729,7 @@ void handle_timestamp(federate_info_t* my_fed) { LF_MUTEX_UNLOCK(&rti_mutex); } -/** - * Helper function to send the current physical clock time to a federate. - * This supports both TCP and UDP sockets. - * @param message_type The type of message being sent. - * @param fed Information about the federate receiving the message. - * @param is_udp Flag indicating whether to use UDP (true) or TCP (false). - */ -static void send_physical_clock_helper(unsigned char message_type, federate_info_t* fed, bool is_udp) { +void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP) { if (fed->enclave.state == NOT_CONNECTED) { lf_print_warning("Clock sync: RTI failed to send physical time to federate %d. Socket not connected.\n", fed->enclave.id); @@ -747,7 +740,7 @@ static void send_physical_clock_helper(unsigned char message_type, federate_info int64_t current_physical_time = lf_time_physical(); encode_int64(current_physical_time, &(buffer[1])); - if (is_udp) { + if (use_UDP) { // Send using UDP LF_PRINT_DEBUG("Clock sync: RTI sending UDP message type %u.", buffer[0]); ssize_t bytes_written = sendto(rti_remote->socket_descriptor_UDP, buffer, 1 + sizeof(int64_t), 0, @@ -769,40 +762,21 @@ static void send_physical_clock_helper(unsigned char message_type, federate_info current_physical_time, fed->enclave.id); } -void send_physical_clock(unsigned char message_type, federate_info_t* fed) { - send_physical_clock_helper(message_type, fed, false); -} - -void send_physical_clock_UDP(unsigned char message_type, federate_info_t* fed) { - send_physical_clock_helper(message_type, fed, true); -} - -/** - * Handle a physical clock synchronization message, sending the required messages. - * UDP sends a coded probe message. - * @param my_fed The federate information. - * @param send_coded_probe Boolean to send a coded probe message (for UDP only). - */ -static void handle_physical_clock_sync_message_helper(federate_info_t* my_fed, bool send_coded_probe) { +void handle_physical_clock_sync_message(federate_info_t* my_fed, bool use_UDP) { + // Lock the mutex to prevent interference between sending the two + // coded probe messages. LF_MUTEX_LOCK(&rti_mutex); - if (!send_coded_probe) { + if (!use_UDP) { // Reply with a T4 type message - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed, false); // Send the corresponding coded probe immediately after, // but only if this is a UDP channel. } else { - send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_T4, my_fed); - send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed, true); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed, true); } LF_MUTEX_UNLOCK(&rti_mutex); } -void handle_physical_clock_sync_message(federate_info_t* my_fed) { - handle_physical_clock_sync_message_helper(my_fed, false); -} - -void handle_physical_clock_sync_message_UDP(federate_info_t* my_fed) { - handle_physical_clock_sync_message_helper(my_fed, true); -} void* clock_synchronization_thread(void* noargs) { initialize_lf_thread_id(); @@ -841,7 +815,7 @@ void* clock_synchronization_thread(void* noargs) { // Send the RTI's current physical time to the federate // Send on UDP. LF_PRINT_DEBUG("RTI sending T1 message to initiate clock sync round."); - send_physical_clock_UDP(MSG_TYPE_CLOCK_SYNC_T1, fed); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, true); // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); @@ -866,7 +840,7 @@ void* clock_synchronization_thread(void* noargs) { continue; } LF_PRINT_DEBUG("Clock sync: RTI received T3 message from federate %d.", fed_id_2); - handle_physical_clock_sync_message_UDP(GET_FED_INFO(fed_id_2)); + handle_physical_clock_sync_message(GET_FED_INFO(fed_id_2), true); break; } else { // The message is not a T3 message. Discard the message and @@ -1300,7 +1274,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 // Send the required number of messages for clock synchronization for (int i = 0; i < rti_remote->clock_sync_exchanges_per_interval; i++) { // Send the RTI's current physical time T1 to the federate. - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, false); // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); @@ -1310,7 +1284,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); LF_PRINT_DEBUG("RTI received T3 clock sync message from federate %d.", fed_id); - handle_physical_clock_sync_message(fed); + handle_physical_clock_sync_message(fed, false); } else { lf_print_error("Unexpected message %u from federate %d.", buffer[0], fed_id); send_reject(fed_netdrv, UNEXPECTED_MESSAGE); diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 725ca6ae7..bc0f6c7aa 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -297,16 +297,9 @@ void handle_timestamp(federate_info_t* my_fed); * * @param message_type The type of the clock sync message (see net_common.h). * @param fed The federate to send the physical time to. + * @param use_UDP Boolean to use UDP or the network driver. */ -void send_physical_clock(unsigned char message_type, federate_info_t* fed); - -/** - * This does the same function with send_physical_clock(), but uses UDP. - * - * @param message_type The type of the clock sync message (see net_common.h). - * @param fed The federate to send the physical time to. - */ -void send_physical_clock_UDP(unsigned char message_type, federate_info_t* fed); +void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP); /** * Handle clock synchronization T3 messages from federates. @@ -319,10 +312,9 @@ void send_physical_clock_UDP(unsigned char message_type, federate_info_t* fed); * clock synchronization round. * * @param my_fed The sending federate. + * @param use_UDP Boolean to send a coded probe message (for UDP only). */ -void handle_physical_clock_sync_message(federate_info_t* my_fed); - -void handle_physical_clock_sync_message_UDP(federate_info_t* my_fed); +void handle_physical_clock_sync_message(federate_info_t* my_fed, bool use_UDP); /** * A (quasi-)periodic thread that performs clock synchronization with each diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index 273af494b..5fd29d4d5 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -230,7 +230,7 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t* rti_netdrv) { // Handle the message and send a reply T3 message. // NOTE: No need to acquire the mutex lock during initialization because only // one thread is running. - if (handle_T1_clock_sync_message(buffer, rti_netdrv, receive_time) != 0) { + if (handle_T1_clock_sync_message(buffer, (void*)rti_netdrv, receive_time, false) != 0) { lf_print_error_and_exit("Initial clock sync: Failed to send T3 reply to RTI."); } @@ -245,7 +245,7 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t* rti_netdrv) { } // Handle the message. - handle_T4_clock_sync_message(buffer, rti_netdrv, receive_time); + handle_T4_clock_sync_message(buffer, (void*)rti_netdrv, receive_time, false); } LF_PRINT_LOG("Finished initial clock synchronization with the RTI."); @@ -260,10 +260,10 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t* rti_netdrv) { * @param buffer The buffer containing the message, including the message type. * @param socket_or_netdrv The pointer of either UDP socket or the network driver. * @param t2 The physical time at which the T1 message was received. + * @param use_UDP Boolean to use UDP or the network driver. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -static int handle_T1_clock_sync_message_common(unsigned char* buffer, void* socket_or_netdrv, instant_t t2, - bool use_udp) { +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, instant_t t2, bool use_udp) { // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); @@ -298,16 +298,6 @@ static int handle_T1_clock_sync_message_common(unsigned char* buffer, void* sock return 0; } -// Wrapper for handling clock synchronization over netdrv (e.g., TCP) -int handle_T1_clock_sync_message(unsigned char* buffer, netdrv_t* netdrv, instant_t t2) { - return handle_T1_clock_sync_message_common(buffer, (void*)netdrv, t2, false); -} - -// Wrapper for handling clock synchronization over UDP -int handle_T1_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, instant_t t2) { - return handle_T1_clock_sync_message_common(buffer, (void*)UDP_socket, t2, true); -} - /** * Handle a clock synchronization message T4 coming from the RTI. * If using the network driver, then assume we are in the @@ -323,9 +313,9 @@ int handle_T1_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, ins * @param buffer The buffer containing the message, including the message type. * @param socket_or_netdrv The pointer of either UDP socket or the network driver. * @param r4 The physical time at which this T4 message was received. + * @param use_UDP Boolean to use UDP or the network driver. */ -static void handle_T4_clock_sync_message_common(unsigned char* buffer, void* socket_or_netdrv, instant_t r4, - int use_udp) { +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, instant_t r4, bool use_udp) { // Increment the number of received T4 messages _lf_rti_socket_stat.received_T4_messages_in_current_sync_window++; @@ -449,20 +439,6 @@ static void handle_T4_clock_sync_message_common(unsigned char* buffer, void* soc } } -/** - * Wrapper for handling clock synchronization messages via TCP. - */ -void handle_T4_clock_sync_message(unsigned char* buffer, netdrv_t* netdrv, instant_t r4) { - handle_T4_clock_sync_message_common(buffer, (void*)netdrv, r4, 0); -} - -/** - * Wrapper for handling clock synchronization messages via UDP. - */ -void handle_T4_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, instant_t r4) { - handle_T4_clock_sync_message_common(buffer, (void*)UDP_socket, r4, 1); -} - /** * Thread that listens for UDP inputs from the RTI. */ @@ -528,7 +504,7 @@ void* listen_to_rti_UDP_thread(void* args) { break; } connected = true; - if (handle_T1_clock_sync_message_UDP(buffer, &_lf_rti_socket_UDP, receive_time) != 0) { + if (handle_T1_clock_sync_message(buffer, (void*)&_lf_rti_socket_UDP, receive_time, true) != 0) { // Failed to send T3 reply. Wait for the next T1. waiting_for_T1 = true; continue; @@ -541,7 +517,7 @@ void* listen_to_rti_UDP_thread(void* args) { continue; } } else if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T4) { - handle_T4_clock_sync_message_UDP(buffer, &_lf_rti_socket_UDP, receive_time); + handle_T4_clock_sync_message(buffer, (void*)&_lf_rti_socket_UDP, receive_time, true); waiting_for_T1 = true; } else { lf_print_warning("Clock sync: Received from RTI an unexpected UDP message type: %u. " diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index 18fe33848..478be1912 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -177,43 +177,29 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t* rti_netdrv); * @param buffer The buffer containing the message, including the message type. * @param netdrv_t The pointer to the network driver. * @param t2 The physical time at which the T1 message was received. + * @param use_UDP Boolean to use UDP or the network driver. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, netdrv_t* netdrv, instant_t t2); +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, instant_t t2, bool use_udp); /** - * This does the same function as handle_T1_clock_sync_message(), only using a UDP socket. - * @param buffer The buffer containing the message, including the message type. - * @param socket The pointer to the UDP socket. - * @param t2 The physical time at which the T1 message was received. - * @return 0 if T3 reply is successfully sent, -1 otherwise. - */ -int handle_T1_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, instant_t t2); - -/** - * Handle a clock synchronization message T4 coming from the RTI using the network driver. - * Assume this is the initial clock synchronization phase and set the clock offset + * Handle a clock synchronization message T4 coming from the RTI. + * If the socket_or_netdrv is a network driver, then assume we are in the + * initial clock synchronization phase and set the clock offset * based on the estimated clock synchronization error. + * Otherwise, if the socket_or_netdrv is UDP socket, then this looks also for a + * subsequent "coded probe" message on the socket. If the delay between + * the T4 and the coded probe message is not as expected, then reject + * this clock synchronization round. If it is not rejected, then make + * an adjustment to the clock offset based on the estimated error. * This function does not acquire the netdrv_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. * @param netdrv_t The pointer to the network driver. - * @param r4 The physical time at which this T4 message was received. - */ -void handle_T4_clock_sync_message(unsigned char* buffer, netdrv_t* netdrv, instant_t r4); - -/** - * Handle a clock synchronization message T4 coming from the RTI using a UDP socket. - * Look for a subsequent "coded probe" message on the socket. - * If the delay between the T4 and the coded probe message is not as expected, reject the clock synchronization round. - * If it is not rejected, then make an adjustment to the clock offset based on the estimated error. - * This function does not acquire the netdrv_mutex lock. - * The caller should acquire it unless it is sure there is only one thread running. - * @param buffer The buffer containing the message, including the message type. - * @param socket The pointer to the UDP socket. - * @param r4 The physical time at which this T4 message was received. + * @param r4 The physical time at which this T4 message was received.\ + * @param use_UDP Boolean to use UDP or the network driver. */ -void handle_T4_clock_sync_message_UDP(unsigned char* buffer, int* UDP_socket, instant_t r4); +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, instant_t r4, bool use_udp); /** * Thread that listens for UDP inputs from the RTI. From fcf63cee48e51ec3bc75356590dde829c993f7ce Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 17:31:03 -0700 Subject: [PATCH 091/167] Code cleanup --- core/federated/RTI/rti_remote.c | 3 --- core/federated/RTI/rti_remote.h | 3 --- core/federated/federate.c | 3 ++- network/api/socket_common.h | 18 ------------------ network/impl/src/socket_common.c | 18 ++++++++++++++++-- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index acae93398..b05fd2afc 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1299,10 +1299,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 // Initialize the UDP_addr field of the federate struct fed->UDP_addr.sin_family = AF_INET; fed->UDP_addr.sin_port = htons(federate_UDP_port_number); -#ifdef COMM_TYPE_TCP fed->UDP_addr.sin_addr = *get_ip_addr(fed_netdrv); -#elif -#endif } } else { // Disable clock sync after initial round. diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index bc0f6c7aa..d2315287e 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -53,10 +53,7 @@ typedef struct federate_info_t { // to a request for stop from the RTI. Used to prevent double-counting // a federate when handling lf_request_stop(). lf_thread_t thread_id; // The ID of the thread handling communication with this federate. - netdrv_t* fed_netdrv; // The netdriver that the RTI handling each federate. - - int socket; // The TCP socket descriptor for communicating with this federate. struct sockaddr_in UDP_addr; // The UDP address for the federate. bool clock_synchronization_enabled; // Indicates the status of clock synchronization // for this federate. Enabled by default. diff --git a/core/federated/federate.c b/core/federated/federate.c index 5dbdbfc00..c27adb9dc 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1923,13 +1923,14 @@ void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); netdrv_t* server_netdrv = initialize_netdrv(); + //TODO: Check. set_server_port(server_netdrv, specified_port); if (create_server(server_netdrv, false)) { lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); }; _fed.server_netdrv = server_netdrv; - // Get the final server port set. + // Get the final server port to send to the RTI on an MSG_TYPE_ADDRESS_ADVERTISEMENT message. int32_t server_port = get_my_port(server_netdrv); LF_PRINT_LOG("Server for communicating with other federates started using port %d.", server_port); diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 6653a813d..8386df36e 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -104,24 +104,6 @@ typedef struct socket_priv_t { */ int create_real_time_tcp_socket_errexit(); -/** - * Set the socket timeout options. - * @param socket_descriptor The file descriptor of the socket on which to set options. - * @param timeout_time A pointer to a `struct timeval` that specifies the timeout duration - * for socket operations (receive and send). - */ -void set_socket_timeout_option(int socket_descriptor, struct timeval* timeout_time); - -/** - * Assign a port to the socket, and bind the socket. - * - * @param socket_descriptor The file descriptor of the socket to be bound to an address and port. - * @param specified_port The port number to bind the socket to. - * @param increment_port_on_retry Boolean to retry port increment. - * @return The final port number used. - */ -int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool increment_port_on_retry); - /** * @brief Create a TCP server that listens for socket connections. * diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 5c501dec6..24723d56d 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -52,7 +52,13 @@ int create_real_time_tcp_socket_errexit() { return sock; } -void set_socket_timeout_option(int socket_descriptor, struct timeval* timeout_time) { +/** + * Set the socket timeout options. + * @param socket_descriptor The file descriptor of the socket on which to set options. + * @param timeout_time A pointer to a `struct timeval` that specifies the timeout duration + * for socket operations (receive and send). + */ +static void set_socket_timeout_option(int socket_descriptor, struct timeval* timeout_time) { // Set the option for this socket to reuse the same address int true_variable = 1; // setsockopt() requires a reference to the value assigned to an option if (setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &true_variable, sizeof(int32_t)) < 0) { @@ -67,7 +73,15 @@ void set_socket_timeout_option(int socket_descriptor, struct timeval* timeout_ti } } -int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool increment_port_on_retry) { +/** + * Assign a port to the socket, and bind the socket. + * + * @param socket_descriptor The file descriptor of the socket to be bound to an address and port. + * @param specified_port The port number to bind the socket to. + * @param increment_port_on_retry Boolean to retry port increment. + * @return The final port number used. + */ +static int set_socket_bind_option(int socket_descriptor, uint16_t specified_port, bool increment_port_on_retry) { // Server file descriptor. struct sockaddr_in server_fd; // Zero out the server address structure. From f707321c18d73a6f48bdf7025f8fe4f2af808b7e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 22 Jan 2025 17:35:00 -0700 Subject: [PATCH 092/167] Minor fix. --- core/federated/RTI/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/federated/RTI/main.c b/core/federated/RTI/main.c index c2be579c9..5251b509f 100644 --- a/core/federated/RTI/main.c +++ b/core/federated/RTI/main.c @@ -80,11 +80,11 @@ static void send_failed_signal(federate_info_t* fed) { if (rti.base.tracing_enabled) { tracepoint_rti_to_federate(send_FAILED, fed->enclave.id, NULL); } - int failed = write_to_socket(fed->socket, bytes_to_write, &(buffer[0])); + int failed = write_to_netdrv(fed->fed_netdrv, bytes_to_write, &(buffer[0])); if (failed == 0) { LF_PRINT_LOG("RTI has sent failed signal to federate %d due to abnormal termination.", fed->enclave.id); } else { - lf_print_error("RTI failed to send failed signal to federate %d on socket ID %d.", fed->enclave.id, fed->socket); + lf_print_error("RTI failed to send failed signal to federate %d.", fed->enclave.id); } } From 743ab6e172b2466ea6b899351973e6a3ce784c40 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Thu, 23 Jan 2025 18:24:30 -0700 Subject: [PATCH 093/167] Formatting. --- network/impl/src/socket_common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index b5b1fca3f..9fb6def25 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -348,7 +348,7 @@ int shutdown_socket(int* socket, bool read_before_closing) { if (!read_before_closing) { if (shutdown(*socket, SHUT_RDWR)) { lf_print_log("On shutdown socket, received reply: %s", strerror(errno)); - goto close_socket; // Try closing socket. + goto close_socket; // Try closing socket. } } else { // Signal the other side that no further writes are expected by sending a FIN packet. @@ -356,7 +356,7 @@ int shutdown_socket(int* socket, bool read_before_closing) { // https://stackoverflow.com/questions/4160347/close-vs-shutdown-socket if (shutdown(*socket, SHUT_WR)) { lf_print_log("Failed to shutdown socket: %s", strerror(errno)); - goto close_socket; // Try closing socket. + goto close_socket; // Try closing socket. } // Wait for the other side to send an EOF or encounter a socket error. @@ -369,7 +369,7 @@ int shutdown_socket(int* socket, bool read_before_closing) { ; } -close_socket: // Label to jump to the closing part of the function +close_socket: // Label to jump to the closing part of the function // NOTE: In all common TCP/IP stacks, there is a time period, // typically between 30 and 120 seconds, called the TIME_WAIT period, // before the port is released after this close. This is because From df90300daa94d9618cce354d50c82088ba8e48d9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 10:09:15 -0700 Subject: [PATCH 094/167] Add get_socket_priv_t --- network/impl/src/lf_socket_support.c | 45 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 43261ddea..96bf4a487 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -7,10 +7,11 @@ #include "net_driver.h" #include "socket_common.h" #include "util.h" -// #include "lf_socket_support.h" + +static socket_priv_t* get_socket_priv_t(netdrv_t* drv) { return (socket_priv_t*)drv->priv; } static int get_peer_address(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); struct sockaddr_in peer_addr; socklen_t addr_len = sizeof(peer_addr); if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { @@ -59,28 +60,28 @@ netdrv_t* initialize_netdrv() { } void free_netdrv(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); free(priv); free(drv); } int create_server(netdrv_t* drv, bool increment_port_on_retry) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return create_socket_server(priv->user_specified_port, &priv->socket_descriptor, &priv->port, TCP, increment_port_on_retry); } netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { - socket_priv_t* serv_priv = (socket_priv_t*)server_drv->priv; + socket_priv_t* serv_priv = get_socket_priv_t(server_drv); int rti_socket; if (rti_drv == NULL) { rti_socket = -1; } else { - socket_priv_t* rti_priv = (socket_priv_t*)rti_drv->priv; + socket_priv_t* rti_priv = get_socket_priv_t(rti_drv); rti_socket = rti_priv->socket_descriptor; } netdrv_t* fed_netdrv = initialize_netdrv(); - socket_priv_t* fed_priv = (socket_priv_t*)fed_netdrv->priv; + socket_priv_t* fed_priv = get_socket_priv_t(fed_netdrv); int sock = accept_socket(serv_priv->socket_descriptor, rti_socket); if (sock == -1) { @@ -96,22 +97,22 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { } void create_client(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); priv->socket_descriptor = create_real_time_tcp_socket_errexit(); } int connect_to_netdrv(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return connect_to_socket(priv->socket_descriptor, priv->server_hostname, priv->server_port); } int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return read_from_socket(priv->socket_descriptor, num_bytes, buffer); } int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); int read_failed = read_from_netdrv(drv, num_bytes, buffer); if (read_failed) { // Read failed. @@ -143,12 +144,12 @@ void read_from_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned ch } int write_to_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return write_to_socket(priv->socket_descriptor, num_bytes, buffer); } int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); int result = write_to_netdrv(drv, num_bytes, buffer); if (result) { // Write failed. @@ -179,7 +180,7 @@ void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha } ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return peek_from_socket(priv->socket_descriptor, result); } @@ -188,7 +189,7 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { lf_print("Socket already closed."); return 0; } - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); if (ret != 0) { lf_print_error("Failed to shutdown socket."); @@ -198,36 +199,36 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { } int32_t get_my_port(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return priv->port; } int32_t get_server_port(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return priv->server_port; } struct in_addr* get_ip_addr(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return &priv->server_ip_addr; } char* get_server_hostname(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return priv->server_hostname; } int get_socket_id(netdrv_t* drv) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); return priv->socket_descriptor; } void set_server_port(netdrv_t* drv, int32_t port) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); priv->server_port = port; } void set_server_host_name(netdrv_t* drv, const char* hostname) { - socket_priv_t* priv = (socket_priv_t*)drv->priv; + socket_priv_t* priv = get_socket_priv_t(drv); memcpy(priv->server_hostname, hostname, INET_ADDRSTRLEN); } From beea2a28b50ab19507a93ff66a51841bc23546a5 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 11:41:34 -0700 Subject: [PATCH 095/167] Remove unimplemented communication policies yet. --- network/impl/CMakeLists.txt | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/network/impl/CMakeLists.txt b/network/impl/CMakeLists.txt index e54a9631a..ff944a112 100644 --- a/network/impl/CMakeLists.txt +++ b/network/impl/CMakeLists.txt @@ -11,25 +11,6 @@ target_sources(lf-network-impl PUBLIC if(COMM_TYPE MATCHES TCP) target_sources(lf-network-impl PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lf_socket_support.c) -elseif(COMM_TYPE MATCHES MQTT) -# # $ git clone https://github.com/eclipse/paho.mqtt.c.git -# # $ cd paho.mqtt.c.git -# # $ mkdir build.paho; cd build.paho -# # $ cmake ../ -# # $ make -# # $ sudo make install -# # It will be installed in /usr/local/lib -# find_package(eclipse-paho-mqtt-c REQUIRED) -# target_link_libraries(lf-network-impl PRIVATE eclipse-paho-mqtt-c::paho-mqtt3a eclipse-paho-mqtt-c::paho-mqtt3c) -# # $ apt-get install libssl-dev -# # find_package(OpenSSL REQUIRED) - -# # target_link_libraries(lf-network-impl PUBLIC OpenSSL::SSL) -# # target_sources(lf-network-impl PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lf_mqtt_support.c) -elseif(COMM_TYPE MATCHES SST) -# target_link_libraries(lf-network-impl PUBLIC SSTLIB) -# target_sources(lf-network-impl PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lf_sst_support.c) -# # add_compile_definitions(OPENSSL_REQUIRED) else() message(FATAL_ERROR "Your communication type is not supported! The C target supports TCP, MQTT and SST.") endif() From 71c83f84692f1e51309a48d5636aac3c0c00d24d Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 12:35:00 -0700 Subject: [PATCH 096/167] Remove unnecessary info. --- network/api/net_driver.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 805a10f14..65b90dd12 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -5,9 +5,6 @@ typedef struct netdrv_t { void* priv; - // unsigned int read_remaining_bytes; - // int my_federate_id; // The RTI is -1, and unitialized is -2. This must be int not uint16_t - // const char* federation_id; } netdrv_t; /** From 08ff7655efaefb46199ed703745f594dca574bb2 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 14:33:30 -0700 Subject: [PATCH 097/167] Fix to not use socket_id. --- core/federated/federate.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index c27adb9dc..531985b33 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -742,13 +742,11 @@ static void* listen_to_federates(void* _args) { // because the message will be put into malloc'd memory. unsigned char buffer[FED_COM_BUFFER_SIZE]; - int socket_id = get_socket_id(netdrv); - // Listen for messages from the federate. while (1) { bool netdrv_closed = false; // Read one byte to get the message type. - LF_PRINT_DEBUG("Waiting for a P2P message on socket %d.", socket_id); + LF_PRINT_DEBUG("Waiting for a P2P message."); bool bad_message = false; if (read_from_netdrv_close_on_error(netdrv, 1, buffer)) { // Network driver has been closed. @@ -756,7 +754,7 @@ static void* listen_to_federates(void* _args) { // Stop listening to this federate. netdrv_closed = true; } else { - LF_PRINT_DEBUG("Received a P2P message on socket %d of type %d.", socket_id, buffer[0]); + LF_PRINT_DEBUG("Received a P2P message of type %d.", buffer[0]); switch (buffer[0]) { case MSG_TYPE_P2P_MESSAGE: LF_PRINT_LOG("Received untimed message from federate %d.", fed_id); From 1d98c85f46162d226af6feed640c21ebcf558002 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 14:34:13 -0700 Subject: [PATCH 098/167] Add set my port for specified ports. --- core/federated/RTI/rti_remote.c | 2 ++ core/federated/federate.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index b05fd2afc..fbb24f6a9 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1485,6 +1485,8 @@ int start_rti_server() { _lf_initialize_clock(); // Initialize RTI's network driver. rti_remote->rti_netdrv = initialize_netdrv(); + // Set the user specified port to the network driver. + set_my_port(rti_remote->rti_netdrv, rti_remote->user_specified_port); // Create the server if (create_server(rti_remote->rti_netdrv, true)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); diff --git a/core/federated/federate.c b/core/federated/federate.c index 531985b33..618f620aa 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1922,7 +1922,7 @@ void lf_create_server(int specified_port) { netdrv_t* server_netdrv = initialize_netdrv(); //TODO: Check. - set_server_port(server_netdrv, specified_port); + set_my_port(server_netdrv, specified_port); if (create_server(server_netdrv, false)) { lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); From d8ab5bec8d80eaeb4ae982f32067471f55fb5e19 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 14:38:21 -0700 Subject: [PATCH 099/167] Fix name to set_server_hostname --- core/federated/federate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 618f620aa..cb0fa179b 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1727,7 +1727,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { netdrv_t* netdrv = initialize_netdrv(); // Set the received host name and port to the network driver. set_server_port(netdrv, uport); - set_server_host_name(netdrv, hostname); + set_server_hostname(netdrv, hostname); // Create the client network driver. create_client(netdrv); if (connect_to_netdrv(netdrv) < 0) { @@ -1810,7 +1810,7 @@ void lf_connect_to_rti(const char* hostname, int port) { _fed.netdrv_to_RTI = initialize_netdrv(); // Set the user specified host name and port to the network driver. set_server_port(_fed.netdrv_to_RTI, port); - set_server_host_name(_fed.netdrv_to_RTI, hostname); + set_server_hostname(_fed.netdrv_to_RTI, hostname); // Create the client network driver. create_client(_fed.netdrv_to_RTI); From e045b1ef6c1db8e7bd5f95460b4ad14cfb31c689 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 14:38:51 -0700 Subject: [PATCH 100/167] Add comments and function descriptions. --- network/api/net_driver.h | 70 +++++++++++++++++++++++++++- network/api/socket_common.h | 3 ++ network/impl/src/lf_socket_support.c | 8 ++-- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 65b90dd12..12c3b8def 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -23,10 +23,32 @@ netdrv_t* initialize_netdrv(); */ int create_server(netdrv_t* drv, bool increment_port_on_retry); +/** + * Wait for an incoming connection request on the specified server network driver. + * The implementation should include three steps. + * 1. Initialize the network driver of the connected federate. + * 2. Wait for the incoming connection request. This should block until the connection is successfully accepted. + * 3. Save the information in the connected network driver, such as the address of the connected peer, for future querying address. + * + * @param server_drv The server network driver that is listening for incoming connections. + * @param rti_drv The rti's network driver to check if it is still open. + * @return netdrv_t* The network driver for the newly accepted connection on success, or NULL on failure + */ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); +/** + * Using the initialized network driver, create a client network driver ready to connect to a server. + * + * @param drv The initialized network driver. + */ void create_client(netdrv_t* drv); +/** + * Connect to the server network driver. The server's connection information, such as the port and address should be set before calling this function. + * + * @param drv Network driver to connect. + * @return int 0 on success, -1 on failure, and `errno` is set to indicate the specific error. + */ int connect_to_netdrv(netdrv_t* drv); /** @@ -133,18 +155,62 @@ ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result); */ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing); +/** + * Get the open port number from the network driver. + * This is used when the federate sends a MSG_TYPE_ADDRESS_ADVERTISEMENT to the RTI, informing its port number. The RTI will save this port number, and send it to the other federate in a MSG_TYPE_ADDRESS_QUERY_REPLY message. + * + * @param drv Network driver instance + * @return The port number of a server network driver. + */ int32_t get_my_port(netdrv_t* drv); +/** + * Get the port number of the connected peer. + * This is used by the RTI, when there is a request from the federate to the RTI, for the MSG_TYPE_ADDRESS_QUERY message. + * + * @param drv Network driver instance + * @return Port number of the connected peer. + */ int32_t get_server_port(netdrv_t* drv); +/** + * Get the IP address of the connected peer. + * + * @param drv Network driver instance + * @return Pointer to the server IP address + */ struct in_addr* get_ip_addr(netdrv_t* drv); +/** + * Get the hostname of the connected peer. + * + * @param drv Network driver instance + * @return Pointer to the server hostname + */ char* get_server_hostname(netdrv_t* drv); -int get_socket_id(netdrv_t* drv); +/** + * Set the user specified port to the created network driver. + * + * @param drv Network driver instance + * @param port The user specified port + */ +void set_my_port(netdrv_t* drv, int32_t port); +/** + * Set server port number to the target network driver. The federate and RTI receives the port number fr on aom another federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. This function is used to set the network driver's target server port number. The + * + * @param drv Network driver instance + * @param port + */ void set_server_port(netdrv_t* drv, int32_t port); -void set_server_host_name(netdrv_t* drv, const char* hostname); +/** + * Set the target server's hostname to the network driver. + * + * @param drv Network driver instance + * @param hostname The target server's hos + */ +void set_server_hostname(netdrv_t* drv, const char* hostname); #endif /* NET_DRIVER_H */ diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 8386df36e..f7f826547 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -64,6 +64,9 @@ */ #define DEFAULT_PORT 15045u +/** + * Default port number for the RTI's clock server. + */ #define DEFAULT_UDP_PORT 15061u /** diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 96bf4a487..2ad91c110 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -89,7 +89,7 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { return NULL; } fed_priv->socket_descriptor = sock; - // Get the peer address from the connected socket_id. + // Get the peer address from the connected socket_id. Saving this for the address query. if (get_peer_address(fed_netdrv) != 0) { lf_print_error("RTI failed to get peer address."); }; @@ -218,9 +218,9 @@ char* get_server_hostname(netdrv_t* drv) { return priv->server_hostname; } -int get_socket_id(netdrv_t* drv) { +void set_my_port(netdrv_t* drv, int32_t port) { socket_priv_t* priv = get_socket_priv_t(drv); - return priv->socket_descriptor; + priv->port = port; } void set_server_port(netdrv_t* drv, int32_t port) { @@ -228,7 +228,7 @@ void set_server_port(netdrv_t* drv, int32_t port) { priv->server_port = port; } -void set_server_host_name(netdrv_t* drv, const char* hostname) { +void set_server_hostname(netdrv_t* drv, const char* hostname) { socket_priv_t* priv = get_socket_priv_t(drv); memcpy(priv->server_hostname, hostname, INET_ADDRSTRLEN); } From 31e4af09f83a8c2515d2d4549a3fa748ca2170a9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 15:09:51 -0700 Subject: [PATCH 101/167] Formatting --- core/federated/federate.c | 1 - network/api/net_driver.h | 38 ++++++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index cb0fa179b..94d5e362a 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1921,7 +1921,6 @@ void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); netdrv_t* server_netdrv = initialize_netdrv(); - //TODO: Check. set_my_port(server_netdrv, specified_port); if (create_server(server_netdrv, false)) { diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 12c3b8def..095b9885e 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -28,8 +28,9 @@ int create_server(netdrv_t* drv, bool increment_port_on_retry); * The implementation should include three steps. * 1. Initialize the network driver of the connected federate. * 2. Wait for the incoming connection request. This should block until the connection is successfully accepted. - * 3. Save the information in the connected network driver, such as the address of the connected peer, for future querying address. - * + * 3. Save the information in the connected network driver, such as the address of the connected peer, for future + * querying address. + * * @param server_drv The server network driver that is listening for incoming connections. * @param rti_drv The rti's network driver to check if it is still open. * @return netdrv_t* The network driver for the newly accepted connection on success, or NULL on failure @@ -38,14 +39,15 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); /** * Using the initialized network driver, create a client network driver ready to connect to a server. - * + * * @param drv The initialized network driver. */ void create_client(netdrv_t* drv); /** - * Connect to the server network driver. The server's connection information, such as the port and address should be set before calling this function. - * + * Connect to the server network driver. The server's connection information, such as the port and address should be set + * before calling this function. + * * @param drv Network driver to connect. * @return int 0 on success, -1 on failure, and `errno` is set to indicate the specific error. */ @@ -157,8 +159,9 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing); /** * Get the open port number from the network driver. - * This is used when the federate sends a MSG_TYPE_ADDRESS_ADVERTISEMENT to the RTI, informing its port number. The RTI will save this port number, and send it to the other federate in a MSG_TYPE_ADDRESS_QUERY_REPLY message. - * + * This is used when the federate sends a MSG_TYPE_ADDRESS_ADVERTISEMENT to the RTI, informing its port number. The RTI + * will save this port number, and send it to the other federate in a MSG_TYPE_ADDRESS_QUERY_REPLY message. + * * @param drv Network driver instance * @return The port number of a server network driver. */ @@ -166,8 +169,9 @@ int32_t get_my_port(netdrv_t* drv); /** * Get the port number of the connected peer. - * This is used by the RTI, when there is a request from the federate to the RTI, for the MSG_TYPE_ADDRESS_QUERY message. - * + * This is used by the RTI, when there is a request from the federate to the RTI, for the MSG_TYPE_ADDRESS_QUERY + * message. + * * @param drv Network driver instance * @return Port number of the connected peer. */ @@ -175,7 +179,7 @@ int32_t get_server_port(netdrv_t* drv); /** * Get the IP address of the connected peer. - * + * * @param drv Network driver instance * @return Pointer to the server IP address */ @@ -183,7 +187,7 @@ struct in_addr* get_ip_addr(netdrv_t* drv); /** * Get the hostname of the connected peer. - * + * * @param drv Network driver instance * @return Pointer to the server hostname */ @@ -191,23 +195,25 @@ char* get_server_hostname(netdrv_t* drv); /** * Set the user specified port to the created network driver. - * + * * @param drv Network driver instance * @param port The user specified port */ void set_my_port(netdrv_t* drv, int32_t port); /** - * Set server port number to the target network driver. The federate and RTI receives the port number fr on aom another federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. This function is used to set the network driver's target server port number. The - * + * Set server port number to the target network driver. The federate and RTI receives the port number fr on aom another + * federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. This function is used to set the network driver's target server port + * number. The + * * @param drv Network driver instance - * @param port + * @param port */ void set_server_port(netdrv_t* drv, int32_t port); /** * Set the target server's hostname to the network driver. - * + * * @param drv Network driver instance * @param hostname The target server's hos */ From 786b6ccb1f6ae7e54d41a74777dfffeea4fe984a Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 15:32:59 -0700 Subject: [PATCH 102/167] Add comments. --- network/api/net_driver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 095b9885e..4b0272725 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -207,7 +207,7 @@ void set_my_port(netdrv_t* drv, int32_t port); * number. The * * @param drv Network driver instance - * @param port + * @param port The target server's port */ void set_server_port(netdrv_t* drv, int32_t port); @@ -215,7 +215,7 @@ void set_server_port(netdrv_t* drv, int32_t port); * Set the target server's hostname to the network driver. * * @param drv Network driver instance - * @param hostname The target server's hos + * @param hostname The target server's hostname */ void set_server_hostname(netdrv_t* drv, const char* hostname); From 4d31c940e2eef6730c569bf477f70af61abd3e29 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 19:46:22 -0700 Subject: [PATCH 103/167] Fix netdrv_t to a typdef of void* --- core/federated/RTI/rti_remote.c | 16 +++---- core/federated/RTI/rti_remote.h | 8 ++-- core/federated/clock-sync.c | 4 +- core/federated/federate.c | 22 +++++----- include/core/federated/clock-sync.h | 2 +- include/core/federated/federate.h | 10 ++--- network/api/net_driver.h | 48 ++++++++++----------- network/impl/src/lf_socket_support.c | 63 ++++++++++++++-------------- 8 files changed, 85 insertions(+), 88 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index fbb24f6a9..5cf5283e2 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1017,7 +1017,7 @@ void* federate_info_thread_TCP(void* fed) { return NULL; } -void send_reject(netdrv_t* drv, unsigned char error_code) { +void send_reject(netdrv_t drv, unsigned char error_code) { LF_PRINT_DEBUG("RTI sending MSG_TYPE_REJECT."); unsigned char response[2]; response[0] = MSG_TYPE_REJECT; @@ -1041,7 +1041,7 @@ void send_reject(netdrv_t* drv, unsigned char error_code) { * @param client_fd The socket address. * @return The federate ID for success or -1 for failure. */ -static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { +static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { // Buffer for message ID, federate ID, and federation ID length. size_t length = 1 + sizeof(uint16_t) + 1; // Message ID, federate ID, length of fedration ID. unsigned char buffer[length]; @@ -1163,7 +1163,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t* fed_netdrv) { * out the relevant information in the federate's struct. * @return 1 on success and 0 on failure. */ -static int receive_connection_information(netdrv_t* fed_netdrv, uint16_t fed_id) { +static int receive_connection_information(netdrv_t fed_netdrv, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; read_from_netdrv_fail_on_error(fed_netdrv, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, NULL, @@ -1246,7 +1246,7 @@ static int receive_connection_information(netdrv_t* fed_netdrv, uint16_t fed_id) * @param fed_id The federate ID. * @return 1 for success, 0 for failure. */ -static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint16_t fed_id) { +static int receive_udp_message_and_set_up_clock_sync(netdrv_t fed_netdrv, uint16_t fed_id) { // Read the MSG_TYPE_UDP_PORT message from the federate regardless of the status of // clock synchronization. This message will tell the RTI whether the federate // is doing clock synchronization, and if it is, what port to use for UDP. @@ -1325,7 +1325,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t* fed_netdrv, uint1 * @param fed_netdrv Network driver for the incoming federate tryting to authenticate. * @return True if authentication is successful and false otherwise. */ -static bool authenticate_federate(netdrv_t* fed_netdrv) { +static bool authenticate_federate(netdrv_t fed_netdrv) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); unsigned char buffer[1 + fed_id_length + NONCE_LENGTH]; @@ -1388,9 +1388,9 @@ static bool authenticate_federate(netdrv_t* fed_netdrv) { } #endif -void lf_connect_to_federates(netdrv_t* rti_netdrv) { +void lf_connect_to_federates(netdrv_t rti_netdrv) { for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { - netdrv_t* fed_netdrv = accept_netdrv(rti_netdrv, NULL); + netdrv_t fed_netdrv = accept_netdrv(rti_netdrv, NULL); if (fed_netdrv == NULL) { lf_print_warning("RTI failed to accept the federate."); return; @@ -1452,7 +1452,7 @@ void* respond_to_erroneous_connections(void* nothing) { // Wait for an incoming connection request. // The following will block until either a federate attempts to connect // or shutdown_socket(rti->socket_descriptor_TCP) is called. - netdrv_t* fed_netdrv = accept_netdrv(rti_remote->rti_netdrv, NULL); + netdrv_t fed_netdrv = accept_netdrv(rti_remote->rti_netdrv, NULL); if (fed_netdrv == NULL) { return NULL; } diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index d2315287e..78054d339 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -53,7 +53,7 @@ typedef struct federate_info_t { // to a request for stop from the RTI. Used to prevent double-counting // a federate when handling lf_request_stop(). lf_thread_t thread_id; // The ID of the thread handling communication with this federate. - netdrv_t* fed_netdrv; // The netdriver that the RTI handling each federate. + netdrv_t fed_netdrv; // The netdriver that the RTI handling each federate. struct sockaddr_in UDP_addr; // The UDP address for the federate. bool clock_synchronization_enabled; // Indicates the status of clock synchronization // for this federate. Enabled by default. @@ -121,7 +121,7 @@ typedef struct rti_remote_t { /** * The rti's network driver. */ - netdrv_t* rti_netdrv; + netdrv_t rti_netdrv; /************* Clock synchronization information *************/ /* Thread performing PTP clock sync sessions periodically. */ @@ -338,7 +338,7 @@ void* federate_info_thread_TCP(void* fed); * @param drv Pointer to the network driver. * @param error_code An error code. */ -void send_reject(netdrv_t* drv, unsigned char error_code); +void send_reject(netdrv_t drv, unsigned char error_code); /** * Wait for one incoming connection request from each federate, @@ -346,7 +346,7 @@ void send_reject(netdrv_t* drv, unsigned char error_code); * that federate. Return when all federates have connected. * @param rti_netdrv The rti's network driver on which to accept connections. */ -void lf_connect_to_federates(netdrv_t* rti_netdrv); +void lf_connect_to_federates(netdrv_t rti_netdrv); /** * Thread to respond to new connections, which could be federates of other diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index 5fd29d4d5..5f1e18946 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -208,7 +208,7 @@ uint16_t setup_clock_synchronization_with_rti() { return port_to_return; } -void synchronize_initial_physical_clock_with_rti(netdrv_t* rti_netdrv) { +void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv) { LF_PRINT_DEBUG("Waiting for initial clock synchronization messages from the RTI."); size_t message_size = 1 + sizeof(instant_t); @@ -284,7 +284,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); int result = use_udp ? write_to_socket(*(int*)socket_or_netdrv, 1 + sizeof(uint16_t), reply_buffer) - : write_to_netdrv((netdrv_t*)socket_or_netdrv, 1 + sizeof(uint16_t), reply_buffer); + : write_to_netdrv((netdrv_t)socket_or_netdrv, 1 + sizeof(uint16_t), reply_buffer); if (result) { lf_print_error("Clock sync: Failed to send T3 message to RTI."); diff --git a/core/federated/federate.c b/core/federated/federate.c index 94d5e362a..9c3019183 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -465,7 +465,7 @@ static bool handle_message_now(environment_t* env, trigger_t* trigger, tag_t int * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure. */ -static int handle_message(netdrv_t* netdrv, int fed_id) { +static int handle_message(netdrv_t netdrv, int fed_id) { (void)fed_id; // Read the header. size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); @@ -519,7 +519,7 @@ static int handle_message(netdrv_t* netdrv, int fed_id) { * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 on successfully reading the message, -1 on failure (e.g. due to network driver closed). */ -static int handle_tagged_message(netdrv_t* netdrv, int fed_id) { +static int handle_tagged_message(netdrv_t netdrv, int fed_id) { // Environment is always the one corresponding to the top-level scheduling enclave. environment_t* env; _lf_get_environments(&env); @@ -683,7 +683,7 @@ static int handle_tagged_message(netdrv_t* netdrv, int fed_id) { * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure to complete the read. */ -static int handle_port_absent_message(netdrv_t* netdrv, int fed_id) { +static int handle_port_absent_message(netdrv_t netdrv, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; if (read_from_netdrv_close_on_error(netdrv, bytes_to_read, buffer)) { @@ -735,7 +735,7 @@ static void* listen_to_federates(void* _args) { LF_PRINT_LOG("Listening to federate %d.", fed_id); - netdrv_t* netdrv = _fed.netdrvs_for_inbound_p2p_connections[fed_id]; + netdrv_t netdrv = _fed.netdrvs_for_inbound_p2p_connections[fed_id]; // Buffer for incoming messages. // This does not constrain the message size @@ -1724,7 +1724,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { inet_ntop(AF_INET, &host_ip_addr, hostname, INET_ADDRSTRLEN); // Create a network driver. - netdrv_t* netdrv = initialize_netdrv(); + netdrv_t netdrv = initialize_netdrv(); // Set the received host name and port to the network driver. set_server_port(netdrv, uport); set_server_hostname(netdrv, hostname); @@ -1920,7 +1920,7 @@ void lf_connect_to_rti(const char* hostname, int port) { void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); - netdrv_t* server_netdrv = initialize_netdrv(); + netdrv_t server_netdrv = initialize_netdrv(); set_my_port(server_netdrv, specified_port); if (create_server(server_netdrv, false)) { @@ -1979,7 +1979,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { _fed.inbound_netdriv_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); while (received_federates < _fed.number_of_inbound_p2p_connections && !_lf_termination_executed) { // Wait for an incoming connection request. - netdrv_t* netdrv = accept_netdrv(_fed.server_netdrv, _fed.netdrv_to_RTI); + netdrv_t netdrv = accept_netdrv(_fed.server_netdrv, _fed.netdrv_to_RTI); if (netdrv == NULL) { lf_print_warning("Federate failed to accept the network driver."); return NULL; @@ -2169,7 +2169,7 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa // Use a mutex lock to prevent multiple threads from simultaneously sending. LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - netdrv_t* netdrv = _fed.netdrvs_for_outbound_p2p_connections[federate]; + netdrv_t netdrv = _fed.netdrvs_for_outbound_p2p_connections[federate]; // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_P2P_MSG, _lf_my_fed_id, federate, NULL); @@ -2346,10 +2346,10 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d #ifdef FEDERATED_CENTRALIZED // Send the absent message through the RTI - netdrv_t* netdrv = _fed.netdrv_to_RTI; + netdrv_t netdrv = _fed.netdrv_to_RTI; #else // Send the absent message directly to the federate - netdrv_t* netdrv = _fed.netdrvs_for_outbound_p2p_connections[fed_ID]; + netdrv_t netdrv = _fed.netdrvs_for_outbound_p2p_connections[fed_ID]; #endif if (netdrv == _fed.netdrv_to_RTI) { @@ -2460,7 +2460,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int // Use a mutex lock to prevent multiple threads from simultaneously sending. LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - netdrv_t* netdrv; + netdrv_t netdrv; if (message_type == MSG_TYPE_P2P_TAGGED_MESSAGE) { netdrv = _fed.netdrvs_for_outbound_p2p_connections[federate]; tracepoint_federate_to_federate(send_P2P_TAGGED_MSG, _lf_my_fed_id, federate, ¤t_message_intended_tag); diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index 478be1912..8f0f0e5ca 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -166,7 +166,7 @@ uint16_t setup_clock_synchronization_with_rti(void); * * @param rti_netdrv Pointer to the RTI's network driver. */ -void synchronize_initial_physical_clock_with_rti(netdrv_t* rti_netdrv); +void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv); /** * Handle a clock synchroninzation message T1 coming from the RTI. diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index 1cdd79c51..3e7009aa4 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -36,7 +36,7 @@ typedef struct federate_instance_t { * This is set by lf_connect_to_rti(), which must be called before other * functions that communicate with the rti are called. */ - netdrv_t* netdrv_to_RTI; + netdrv_t netdrv_to_RTI; /** * Thread listening for incoming messages from the RTI. @@ -77,7 +77,7 @@ typedef struct federate_instance_t { * federate is the destination. Multiple incoming p2p connections from the * same remote federate will use the same network driver. */ - netdrv_t* netdrvs_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; + netdrv_t netdrvs_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; /** * An array that holds the network drivers for outbound direct @@ -92,7 +92,7 @@ typedef struct federate_instance_t { * program where this federate acts as the source. Multiple outgoing p2p * connections to the same remote federate will use the same network drivers. */ - netdrv_t* netdrvs_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; + netdrv_t netdrvs_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; /** * Thread ID for a thread that accepts network drivers and then supervises @@ -108,7 +108,7 @@ typedef struct federate_instance_t { * opened network driver will be stored in * federate_netdrvs_for_inbound_p2p_connections. */ - netdrv_t* server_netdrv; + netdrv_t server_netdrv; /** * Most recent tag advance grant (TAG) received from the RTI, or NEVER if none @@ -339,7 +339,7 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa * information is needed for the RTI to perform the centralized coordination. * @see MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h */ -void lf_send_neighbor_structure_to_RTI(netdrv_t*); +void lf_send_neighbor_structure_to_RTI(netdrv_t); /** * @brief Send a next event tag (NET) signal. diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 4b0272725..a00385db0 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -3,15 +3,13 @@ #include "socket_common.h" -typedef struct netdrv_t { - void* priv; -} netdrv_t; +typedef void* netdrv_t; /** * Allocate memory for the network driver. - * @return netdrv_t* Initialized network driver. + * @return netdrv_t Initialized network driver. */ -netdrv_t* initialize_netdrv(); +netdrv_t initialize_netdrv(); /** * Create a netdriver server. This is such as a server socket which accepts connections. However this is only the @@ -21,7 +19,7 @@ netdrv_t* initialize_netdrv(); * @param serv_type Type of server, RTI or FED. * @return int 0 for success, -1 for failure. */ -int create_server(netdrv_t* drv, bool increment_port_on_retry); +int create_server(netdrv_t drv, bool increment_port_on_retry); /** * Wait for an incoming connection request on the specified server network driver. @@ -33,16 +31,16 @@ int create_server(netdrv_t* drv, bool increment_port_on_retry); * * @param server_drv The server network driver that is listening for incoming connections. * @param rti_drv The rti's network driver to check if it is still open. - * @return netdrv_t* The network driver for the newly accepted connection on success, or NULL on failure + * @return netdrv_t The network driver for the newly accepted connection on success, or NULL on failure */ -netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv); +netdrv_t accept_netdrv(netdrv_t server_drv, netdrv_t rti_drv); /** * Using the initialized network driver, create a client network driver ready to connect to a server. * * @param drv The initialized network driver. */ -void create_client(netdrv_t* drv); +void create_client(netdrv_t drv); /** * Connect to the server network driver. The server's connection information, such as the port and address should be set @@ -51,7 +49,7 @@ void create_client(netdrv_t* drv); * @param drv Network driver to connect. * @return int 0 on success, -1 on failure, and `errno` is set to indicate the specific error. */ -int connect_to_netdrv(netdrv_t* drv); +int connect_to_netdrv(netdrv_t drv); /** * Read the specified number of bytes from the specified socket into the specified buffer. @@ -67,7 +65,7 @@ int connect_to_netdrv(netdrv_t* drv); * @param buffer The buffer into which to put the bytes. * @return 0 for success, 1 for EOF, and -1 for an error. */ -int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); +int read_from_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** * Read the specified number of bytes to the specified socket using read_from_socket @@ -78,7 +76,7 @@ int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. */ -int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); +int read_from_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** * Read the specified number of bytes from the specified socket into the @@ -96,7 +94,7 @@ int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned ch * @return The number of bytes read, or 0 if an EOF is received, or * a negative number for an error. */ -void read_from_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, +void read_from_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...); /** @@ -113,7 +111,7 @@ void read_from_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned ch * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. */ -int write_to_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); +int write_to_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** * Write the specified number of bytes to the specified socket using write_to_socket @@ -124,7 +122,7 @@ int write_to_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. */ -int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer); +int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** * Write the specified number of bytes to the specified socket using @@ -141,10 +139,10 @@ int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha * fields that will be used to fill the format string as in printf, or NULL * to print a generic error message. */ -void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, +void write_to_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...); -ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result); +ssize_t peek_from_netdrv(netdrv_t drv, unsigned char* result); /** * @brief Gracefully shuts down and closes a socket, optionally reading until EOF. @@ -155,7 +153,7 @@ ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result); * @param read_before_closing If true, read until EOF before closing the socket. * @return int Returns 0 on success, -1 on failure (errno will indicate the error). */ -int shutdown_netdrv(netdrv_t* drv, bool read_before_closing); +int shutdown_netdrv(netdrv_t drv, bool read_before_closing); /** * Get the open port number from the network driver. @@ -165,7 +163,7 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing); * @param drv Network driver instance * @return The port number of a server network driver. */ -int32_t get_my_port(netdrv_t* drv); +int32_t get_my_port(netdrv_t drv); /** * Get the port number of the connected peer. @@ -175,7 +173,7 @@ int32_t get_my_port(netdrv_t* drv); * @param drv Network driver instance * @return Port number of the connected peer. */ -int32_t get_server_port(netdrv_t* drv); +int32_t get_server_port(netdrv_t drv); /** * Get the IP address of the connected peer. @@ -183,7 +181,7 @@ int32_t get_server_port(netdrv_t* drv); * @param drv Network driver instance * @return Pointer to the server IP address */ -struct in_addr* get_ip_addr(netdrv_t* drv); +struct in_addr* get_ip_addr(netdrv_t drv); /** * Get the hostname of the connected peer. @@ -191,7 +189,7 @@ struct in_addr* get_ip_addr(netdrv_t* drv); * @param drv Network driver instance * @return Pointer to the server hostname */ -char* get_server_hostname(netdrv_t* drv); +char* get_server_hostname(netdrv_t drv); /** * Set the user specified port to the created network driver. @@ -199,7 +197,7 @@ char* get_server_hostname(netdrv_t* drv); * @param drv Network driver instance * @param port The user specified port */ -void set_my_port(netdrv_t* drv, int32_t port); +void set_my_port(netdrv_t drv, int32_t port); /** * Set server port number to the target network driver. The federate and RTI receives the port number fr on aom another @@ -209,7 +207,7 @@ void set_my_port(netdrv_t* drv, int32_t port); * @param drv Network driver instance * @param port The target server's port */ -void set_server_port(netdrv_t* drv, int32_t port); +void set_server_port(netdrv_t drv, int32_t port); /** * Set the target server's hostname to the network driver. @@ -217,6 +215,6 @@ void set_server_port(netdrv_t* drv, int32_t port); * @param drv Network driver instance * @param hostname The target server's hostname */ -void set_server_hostname(netdrv_t* drv, const char* hostname); +void set_server_hostname(netdrv_t drv, const char* hostname); #endif /* NET_DRIVER_H */ diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 2ad91c110..4f7930ff8 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -8,9 +8,15 @@ #include "socket_common.h" #include "util.h" -static socket_priv_t* get_socket_priv_t(netdrv_t* drv) { return (socket_priv_t*)drv->priv; } +static socket_priv_t* get_socket_priv_t(netdrv_t drv) { + if (drv == NULL) { + lf_print_error("Network driver is already closed."); + return NULL; + } + return (socket_priv_t*)drv; +} -static int get_peer_address(netdrv_t* drv) { +static int get_peer_address(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); struct sockaddr_in peer_addr; socklen_t addr_len = sizeof(peer_addr); @@ -33,11 +39,7 @@ static int get_peer_address(netdrv_t* drv) { return 0; } -netdrv_t* initialize_netdrv() { - netdrv_t* drv = malloc(sizeof(netdrv_t)); - if (drv == NULL) { - lf_print_error_and_exit("Falied to malloc netdrv_t."); - } +netdrv_t initialize_netdrv() { // Initialize priv. socket_priv_t* priv = malloc(sizeof(socket_priv_t)); if (priv == NULL) { @@ -54,24 +56,21 @@ netdrv_t* initialize_netdrv() { priv->server_ip_addr.s_addr = 0; priv->server_port = -1; - // Set drv->priv pointer to point the malloc'd priv. - drv->priv = (void*)priv; - return drv; + return (netdrv_t)priv; } -void free_netdrv(netdrv_t* drv) { +void free_netdrv(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); free(priv); - free(drv); } -int create_server(netdrv_t* drv, bool increment_port_on_retry) { +int create_server(netdrv_t drv, bool increment_port_on_retry) { socket_priv_t* priv = get_socket_priv_t(drv); return create_socket_server(priv->user_specified_port, &priv->socket_descriptor, &priv->port, TCP, increment_port_on_retry); } -netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { +netdrv_t accept_netdrv(netdrv_t server_drv, netdrv_t rti_drv) { socket_priv_t* serv_priv = get_socket_priv_t(server_drv); int rti_socket; if (rti_drv == NULL) { @@ -80,7 +79,7 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { socket_priv_t* rti_priv = get_socket_priv_t(rti_drv); rti_socket = rti_priv->socket_descriptor; } - netdrv_t* fed_netdrv = initialize_netdrv(); + netdrv_t fed_netdrv = initialize_netdrv(); socket_priv_t* fed_priv = get_socket_priv_t(fed_netdrv); int sock = accept_socket(serv_priv->socket_descriptor, rti_socket); @@ -96,22 +95,22 @@ netdrv_t* accept_netdrv(netdrv_t* server_drv, netdrv_t* rti_drv) { return fed_netdrv; } -void create_client(netdrv_t* drv) { +void create_client(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); priv->socket_descriptor = create_real_time_tcp_socket_errexit(); } -int connect_to_netdrv(netdrv_t* drv) { +int connect_to_netdrv(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); return connect_to_socket(priv->socket_descriptor, priv->server_hostname, priv->server_port); } -int read_from_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { +int read_from_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = get_socket_priv_t(drv); return read_from_socket(priv->socket_descriptor, num_bytes, buffer); } -int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { +int read_from_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = get_socket_priv_t(drv); int read_failed = read_from_netdrv(drv, num_bytes, buffer); if (read_failed) { @@ -124,7 +123,7 @@ int read_from_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned ch return 0; } -void read_from_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, +void read_from_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...) { va_list args; int read_failed = read_from_netdrv_close_on_error(drv, num_bytes, buffer); @@ -143,12 +142,12 @@ void read_from_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned ch } } -int write_to_netdrv(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { +int write_to_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = get_socket_priv_t(drv); return write_to_socket(priv->socket_descriptor, num_bytes, buffer); } -int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer) { +int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = get_socket_priv_t(drv); int result = write_to_netdrv(drv, num_bytes, buffer); if (result) { @@ -160,7 +159,7 @@ int write_to_netdrv_close_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha return result; } -void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, +void write_to_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...) { va_list args; int result = write_to_netdrv_close_on_error(drv, num_bytes, buffer); @@ -179,12 +178,12 @@ void write_to_netdrv_fail_on_error(netdrv_t* drv, size_t num_bytes, unsigned cha } } -ssize_t peek_from_netdrv(netdrv_t* drv, unsigned char* result) { +ssize_t peek_from_netdrv(netdrv_t drv, unsigned char* result) { socket_priv_t* priv = get_socket_priv_t(drv); return peek_from_socket(priv->socket_descriptor, result); } -int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { +int shutdown_netdrv(netdrv_t drv, bool read_before_closing) { if (drv == NULL) { lf_print("Socket already closed."); return 0; @@ -198,37 +197,37 @@ int shutdown_netdrv(netdrv_t* drv, bool read_before_closing) { return ret; } -int32_t get_my_port(netdrv_t* drv) { +int32_t get_my_port(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); return priv->port; } -int32_t get_server_port(netdrv_t* drv) { +int32_t get_server_port(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); return priv->server_port; } -struct in_addr* get_ip_addr(netdrv_t* drv) { +struct in_addr* get_ip_addr(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); return &priv->server_ip_addr; } -char* get_server_hostname(netdrv_t* drv) { +char* get_server_hostname(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); return priv->server_hostname; } -void set_my_port(netdrv_t* drv, int32_t port) { +void set_my_port(netdrv_t drv, int32_t port) { socket_priv_t* priv = get_socket_priv_t(drv); priv->port = port; } -void set_server_port(netdrv_t* drv, int32_t port) { +void set_server_port(netdrv_t drv, int32_t port) { socket_priv_t* priv = get_socket_priv_t(drv); priv->server_port = port; } -void set_server_hostname(netdrv_t* drv, const char* hostname) { +void set_server_hostname(netdrv_t drv, const char* hostname) { socket_priv_t* priv = get_socket_priv_t(drv); memcpy(priv->server_hostname, hostname, INET_ADDRSTRLEN); } From ad751796681e0acc4385c018d21518cea3351d80 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 20:07:00 -0700 Subject: [PATCH 104/167] Minor fix. --- network/api/socket_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 0c4ec9261..9e66061c8 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -83,7 +83,7 @@ extern lf_mutex_t netdrv_mutex; typedef struct socket_priv_t { int socket_descriptor; - uint16_t port; // The port number. // TODO: Only used in federate.c to send federate's port. + uint16_t port; // The port number. // uint16_t user_specified_port; // Default as 0 for both RTI and federate. // The connected other side's info. The From d4a2bcd6f002ee0d478d3d5786278c1d5226142f Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 24 Jan 2025 22:14:44 -0700 Subject: [PATCH 105/167] Revert inbound socket closes to false. --- core/federated/federate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 117d3bfd6..42484b88e 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -408,7 +408,7 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen static void close_inbound_netdrv(int fed_id) { LF_MUTEX_LOCK(&netdrv_mutex); if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] != NULL) { - shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[fed_id], true); + shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); _fed.netdrvs_for_inbound_p2p_connections[fed_id] = NULL; } LF_MUTEX_UNLOCK(&netdrv_mutex); From eb5378acca2cf2436078f1def92b326aad881a0f Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 25 Jan 2025 01:01:02 -0700 Subject: [PATCH 106/167] retrigger checks From aca13882a4da7003f17224f014e4363e3977ece7 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 25 Jan 2025 01:32:46 -0700 Subject: [PATCH 107/167] Formatting. --- core/federated/RTI/rti_remote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 8d781dfa4..4df4c6cb1 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -53,7 +53,7 @@ typedef struct federate_info_t { // to a request for stop from the RTI. Used to prevent double-counting // a federate when handling lf_request_stop(). lf_thread_t thread_id; // The ID of the thread handling communication with this federate. - netdrv_t fed_netdrv; // The netdriver that the RTI handling each federate. + netdrv_t fed_netdrv; // The netdriver that the RTI handling each federate. struct sockaddr_in UDP_addr; // The UDP address for the federate. bool clock_synchronization_enabled; // Indicates the status of clock synchronization // for this federate. Enabled by default. From 7370d8ad622e37c15dc9890d8a6f9524fb0d7667 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 28 Jan 2025 10:15:40 -0700 Subject: [PATCH 108/167] Remove redundant code. --- CMakeLists.txt | 1 - network/impl/src/net_driver.c | 1 - network/impl/src/net_util.c | 2 -- 3 files changed, 4 deletions(-) delete mode 100644 network/impl/src/net_driver.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 186e5b670..674c1c158 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,6 @@ set(PlatformLib platform) include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_SOURCE_DIR}/include/core) include_directories(${CMAKE_SOURCE_DIR}/include/core/federated) -include_directories(${CMAKE_SOURCE_DIR}/include/core/federated/network) include_directories(${CMAKE_SOURCE_DIR}/include/core/modal_models) include_directories(${CMAKE_SOURCE_DIR}/include/core/platform) include_directories(${CMAKE_SOURCE_DIR}/include/core/threaded) diff --git a/network/impl/src/net_driver.c b/network/impl/src/net_driver.c deleted file mode 100644 index 4b6232348..000000000 --- a/network/impl/src/net_driver.c +++ /dev/null @@ -1 +0,0 @@ -#include "net_driver.h" \ No newline at end of file diff --git a/network/impl/src/net_util.c b/network/impl/src/net_util.c index bcea05495..6a2c518de 100644 --- a/network/impl/src/net_util.c +++ b/network/impl/src/net_util.c @@ -39,8 +39,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include // Defines memcpy() #include // Defines nanosleep() -#include // IPPROTO_TCP, IPPROTO_UDP -#include // TCP_NODELAY #include "net_util.h" #include "util.h" From bf557efa223db529be85b8f5d1bd9bde145b5a37 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 28 Jan 2025 10:16:04 -0700 Subject: [PATCH 109/167] Add guards to add Federated for network files. --- core/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 6f5f021c8..e619218c9 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -95,6 +95,7 @@ include(${LF_ROOT}/platform/impl/CMakeLists.txt) target_link_libraries(reactor-c PUBLIC lf::platform-api) target_link_libraries(reactor-c PRIVATE lf::platform-impl) +if(DEFINED FEDERATED) option(COMM_TYPE "Communication type between RTI and federate(s)." ON) IF(COMM_TYPE MATCHES ON) set(COMM_TYPE TCP) @@ -104,11 +105,11 @@ include(${LF_ROOT}/network/api/CMakeLists.txt) include(${LF_ROOT}/network/impl/CMakeLists.txt) target_link_libraries(reactor-c PUBLIC lf::network-api) target_link_libraries(reactor-c PRIVATE lf::network-impl) +endif() target_include_directories(reactor-c PUBLIC ../include) target_include_directories(reactor-c PUBLIC ../include/core) target_include_directories(reactor-c PUBLIC ../include/core/federated) -target_include_directories(reactor-c PUBLIC ../include/core/federated/network) target_include_directories(reactor-c PUBLIC ../include/core/platform) target_include_directories(reactor-c PUBLIC ../include/core/modal_models) target_include_directories(reactor-c PUBLIC ../include/core/threaded) From b4720bb0ce367c673d39fe0b4dd516406c6e8d18 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 28 Jan 2025 10:45:02 -0700 Subject: [PATCH 110/167] Minor fix. --- network/impl/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/network/impl/CMakeLists.txt b/network/impl/CMakeLists.txt index ff944a112..e9863d980 100644 --- a/network/impl/CMakeLists.txt +++ b/network/impl/CMakeLists.txt @@ -5,7 +5,6 @@ add_library(lf-network-impl STATIC ${LF_NETWORK_FILES}) add_library(lf::network-impl ALIAS lf-network-impl) target_sources(lf-network-impl PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/net_util.c - ${CMAKE_CURRENT_LIST_DIR}/src/net_driver.c ${CMAKE_CURRENT_LIST_DIR}/src/socket_common.c ) From 8a4c690a02508dd558bd02c37b2614ec63cbbcee Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 28 Jan 2025 12:08:36 -0700 Subject: [PATCH 111/167] Formatting. --- network/impl/src/net_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network/impl/src/net_util.c b/network/impl/src/net_util.c index 6a2c518de..79849aa4d 100644 --- a/network/impl/src/net_util.c +++ b/network/impl/src/net_util.c @@ -37,8 +37,8 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include // Defines va_list #include #include -#include // Defines memcpy() -#include // Defines nanosleep() +#include // Defines memcpy() +#include // Defines nanosleep() #include "net_util.h" #include "util.h" From 6665157a9f9116db936fadffc723235b28b51cae Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 13:46:37 -0700 Subject: [PATCH 112/167] Add reference. --- network/api/socket_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 9e66061c8..3d4db81d7 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -1,7 +1,7 @@ #ifndef SOCKET_COMMON_H #define SOCKET_COMMON_H -#include "low_level_platform.h" +#include "low_level_platform.h" // lf_mutex_t #include #include #include From 0df7bfbeaf9fd3e056dc7d4de583cb7035822798 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 13:46:51 -0700 Subject: [PATCH 113/167] Remove unused libraries. --- core/federated/federate.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index c31c66688..25faa77fb 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -14,10 +14,7 @@ #error No support for federated execution on this platform. #endif -#include // inet_ntop & inet_pton -#include // Defines getaddrinfo(), freeaddrinfo() and struct addrinfo. -#include // Defines struct sockaddr_in -#include // Defines read(), write(), and close() +#include // inet_ntop #include // Defines memset(), strnlen(), strncmp(), strncpy() #include // Defines strerror() From 421c4f2fb54dc1d1a984eb81109e290d847dab69 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 13:47:09 -0700 Subject: [PATCH 114/167] Fix CMake to use user input, and default value as TCP. --- core/federated/RTI/CMakeLists.txt | 4 +++- network/impl/CMakeLists.txt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/federated/RTI/CMakeLists.txt b/core/federated/RTI/CMakeLists.txt index a7d26f553..c3b5f28b1 100644 --- a/core/federated/RTI/CMakeLists.txt +++ b/core/federated/RTI/CMakeLists.txt @@ -34,7 +34,9 @@ if (NOT DEFINED LOG_LEVEL) set(LOG_LEVEL 0) ENDIF(NOT DEFINED LOG_LEVEL) -set(COMM_TYPE TCP) +if(NOT DEFINED COMM_TYPE) + set(COMM_TYPE "TCP") +endif() IF(CMAKE_BUILD_TYPE MATCHES DEBUG) # Set the LOG_LEVEL to 4 to get DEBUG messages diff --git a/network/impl/CMakeLists.txt b/network/impl/CMakeLists.txt index e9863d980..225edf3d5 100644 --- a/network/impl/CMakeLists.txt +++ b/network/impl/CMakeLists.txt @@ -11,7 +11,7 @@ target_sources(lf-network-impl PUBLIC if(COMM_TYPE MATCHES TCP) target_sources(lf-network-impl PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lf_socket_support.c) else() - message(FATAL_ERROR "Your communication type is not supported! The C target supports TCP, MQTT and SST.") + message(FATAL_ERROR "Your communication type is not supported! The C target supports TCP.") endif() # Link necessary libraries From 34cd096b708d8192b2334c03da004c3a43aebea3 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 14:02:51 -0700 Subject: [PATCH 115/167] Try fixing comm_type options. --- core/CMakeLists.txt | 16 +++++++--------- core/federated/RTI/CMakeLists.txt | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index e619218c9..2d572b4d5 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -96,15 +96,13 @@ target_link_libraries(reactor-c PUBLIC lf::platform-api) target_link_libraries(reactor-c PRIVATE lf::platform-impl) if(DEFINED FEDERATED) -option(COMM_TYPE "Communication type between RTI and federate(s)." ON) -IF(COMM_TYPE MATCHES ON) - set(COMM_TYPE TCP) -ENDIF() - -include(${LF_ROOT}/network/api/CMakeLists.txt) -include(${LF_ROOT}/network/impl/CMakeLists.txt) -target_link_libraries(reactor-c PUBLIC lf::network-api) -target_link_libraries(reactor-c PRIVATE lf::network-impl) + if(NOT DEFINED COMM_TYPE) + set(COMM_TYPE TCP) + endif() + include(${LF_ROOT}/network/api/CMakeLists.txt) + include(${LF_ROOT}/network/impl/CMakeLists.txt) + target_link_libraries(reactor-c PUBLIC lf::network-api) + target_link_libraries(reactor-c PRIVATE lf::network-impl) endif() target_include_directories(reactor-c PUBLIC ../include) diff --git a/core/federated/RTI/CMakeLists.txt b/core/federated/RTI/CMakeLists.txt index c3b5f28b1..8c12ffd6e 100644 --- a/core/federated/RTI/CMakeLists.txt +++ b/core/federated/RTI/CMakeLists.txt @@ -35,7 +35,7 @@ if (NOT DEFINED LOG_LEVEL) ENDIF(NOT DEFINED LOG_LEVEL) if(NOT DEFINED COMM_TYPE) - set(COMM_TYPE "TCP") + set(COMM_TYPE TCP) endif() IF(CMAKE_BUILD_TYPE MATCHES DEBUG) From c8788865c39c1045d1113a54c9949e7a1310941c Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 14:26:34 -0700 Subject: [PATCH 116/167] Formatting. --- core/federated/federate.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 25faa77fb..e2610532c 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -14,10 +14,9 @@ #error No support for federated execution on this platform. #endif -#include // inet_ntop -#include // Defines memset(), strnlen(), strncmp(), strncpy() -#include // Defines strerror() - +#include // inet_ntop +#include // Defines memset(), strnlen(), strncmp(), strncpy() +#include // Defines strerror() #include #include // Defined perror(), errno #include // Defines bzero(). From e432043f20c6dfa792c724435f73871b50fba99d Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 14:44:13 -0700 Subject: [PATCH 117/167] Add check_netdrv_closed. --- core/federated/federate.c | 9 +-------- network/api/net_driver.h | 10 ++++++++-- network/api/socket_common.h | 7 +++++++ network/impl/src/lf_socket_support.c | 4 ++-- network/impl/src/socket_common.c | 7 +------ 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index e2610532c..730df27d2 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -147,14 +147,7 @@ static void send_tag(unsigned char type, tag_t tag) { * Return true if either the network driver to the RTI is broken or the network driver is * alive and the first unread byte on the network driver's queue is MSG_TYPE_FAILED. */ -static bool rti_failed() { - unsigned char first_byte; - ssize_t bytes = peek_from_netdrv(_fed.netdrv_to_RTI, &first_byte); - if (bytes < 0 || (bytes == 1 && first_byte == MSG_TYPE_FAILED)) - return true; - else - return false; -} +static bool rti_failed() { return check_netdrv_closed(_fed.netdrv_to_RTI); } //////////////////////////////// Port Status Handling /////////////////////////////////////// diff --git a/network/api/net_driver.h b/network/api/net_driver.h index a00385db0..df4ec0577 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -131,7 +131,7 @@ int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char * format argument is non-null, then use it an any additional arguments to form * the error message using printf conventions. Otherwise, print a generic error * message. - * @param drv Pointer to the socket ID. + * @param drv The network driver. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @param mutex If non-NULL, the mutex to unlock before exiting. @@ -142,7 +142,13 @@ int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char void write_to_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...); -ssize_t peek_from_netdrv(netdrv_t drv, unsigned char* result); +/** + * Checks if the network driver is still connected to the peer. + * + * @param drv The network driver. + * @return true if closed, false if still open. + */ +bool check_netdrv_closed(netdrv_t drv); /** * @brief Gracefully shuts down and closes a socket, optionally reading until EOF. diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 3d4db81d7..fb1899b02 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -221,6 +221,13 @@ void read_from_socket_fail_on_error(int* socket, size_t num_bytes, unsigned char */ ssize_t peek_from_socket(int socket, unsigned char* result); +/** + * Return true if either the socket to the RTI is broken or the socket is + * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. + * @param socket Socket to check. + */ +bool check_socket_closed(int socket); + /** * Write the specified number of bytes to the specified socket from the * specified buffer. If an error occurs, return -1 and set errno to indicate diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 4f7930ff8..df8a10670 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -178,9 +178,9 @@ void write_to_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char } } -ssize_t peek_from_netdrv(netdrv_t drv, unsigned char* result) { +bool check_netdrv_closed(netdrv_t drv) { socket_priv_t* priv = get_socket_priv_t(drv); - return peek_from_socket(priv->socket_descriptor, result); + return check_socket_closed(priv->socket_descriptor); } int shutdown_netdrv(netdrv_t drv, bool read_before_closing) { diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 9fb6def25..4ccebb02e 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -174,12 +174,7 @@ int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) return create_socket_server(port, final_socket, final_port, UDP, false); } -/** - * Return true if either the socket to the RTI is broken or the socket is - * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. - * @param socket Socket to check. - */ -static bool check_socket_closed(int socket) { +bool check_socket_closed(int socket) { unsigned char first_byte; ssize_t bytes = peek_from_socket(socket, &first_byte); if (bytes < 0 || (bytes == 1 && first_byte == MSG_TYPE_FAILED)) { From e07c0cf74853332c013620170c93b6923f81f02f Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 14:51:06 -0700 Subject: [PATCH 118/167] Fix comments. --- network/api/net_driver.h | 57 ++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index df4ec0577..32f867ea4 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -52,15 +52,11 @@ void create_client(netdrv_t drv); int connect_to_netdrv(netdrv_t drv); /** - * Read the specified number of bytes from the specified socket into the specified buffer. + * Read the specified number of bytes from the specified network driver into the specified buffer. * If an error occurs during this reading, return -1 and set errno to indicate * the cause of the error. If the read succeeds in reading the specified number of bytes, * return 0. If an EOF occurs before reading the specified number of bytes, return 1. - * This function repeats the read attempt until the specified number of bytes - * have been read, an EOF is read, or an error occurs. Specifically, errors EAGAIN, - * EWOULDBLOCK, and EINTR are not considered errors and instead trigger - * another attempt. A delay between attempts is given by DELAY_BETWEEN_SOCKET_RETRIES. - * @param drv The socket ID. + * @param drv The network driver. * @param num_bytes The number of bytes to read. * @param buffer The buffer into which to put the bytes. * @return 0 for success, 1 for EOF, and -1 for an error. @@ -68,10 +64,10 @@ int connect_to_netdrv(netdrv_t drv); int read_from_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** - * Read the specified number of bytes to the specified socket using read_from_socket - * and close the socket if an error occurs. If an error occurs, this will change the + * Read the specified number of bytes to the specified network driver using read_from_netdrv + * and close the network driver if an error occurs. If an error occurs, this will change the * socket ID pointed to by the first argument to -1 and will return -1. - * @param socket Pointer to the socket ID. + * @param drv The network driver. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. @@ -79,14 +75,14 @@ int read_from_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); int read_from_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** - * Read the specified number of bytes from the specified socket into the + * Read the specified number of bytes from the specified network driver into the * specified buffer. If a disconnect or an EOF occurs during this * reading, then if format is non-null, report an error and exit. * If the mutex argument is non-NULL, release the mutex before exiting. * If format is null, then report the error, but do not exit. * This function takes a formatted string and additional optional arguments * similar to printf(format, ...) that is appended to the error messages. - * @param drv The socket ID. + * @param drv The network driver. * @param num_bytes The number of bytes to read. * @param buffer The buffer into which to put the bytes. * @param format A printf-style format string, followed by arguments to @@ -98,15 +94,12 @@ void read_from_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned cha char* format, ...); /** - * Write the specified number of bytes to the specified socket from the + * Write the specified number of bytes to the specified network driver from the * specified buffer. If an error occurs, return -1 and set errno to indicate * the cause of the error. If the write succeeds, return 0. * This function repeats the attempt until the specified number of bytes - * have been written or an error occurs. Specifically, errors EAGAIN, - * EWOULDBLOCK, and EINTR are not considered errors and instead trigger - * another attempt. A delay between attempts is given by - * DELAY_BETWEEN_SOCKET_RETRIES. - * @param drv The socket ID. + * have been written or an error occurs. + * @param drv The network driver. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. @@ -114,10 +107,10 @@ void read_from_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned cha int write_to_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** - * Write the specified number of bytes to the specified socket using write_to_socket - * and close the socket if an error occurs. If an error occurs, this will change the + * Write the specified number of bytes to the specified network driver using write_to_netfdrv + * and close the network driver if an error occurs. If an error occurs, this will change the * socket ID pointed to by the first argument to -1 and will return -1. - * @param drv Pointer to the socket ID. + * @param drv The network driver. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. @@ -125,7 +118,7 @@ int write_to_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** - * Write the specified number of bytes to the specified socket using + * Write the specified number of bytes to the specified network driver using * write_to_netdrv_close_on_error and exit with an error code if an error occurs. * If the mutex argument is non-NULL, release the mutex before exiting. If the * format argument is non-null, then use it an any additional arguments to form @@ -151,12 +144,12 @@ void write_to_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char bool check_netdrv_closed(netdrv_t drv); /** - * @brief Gracefully shuts down and closes a socket, optionally reading until EOF. - * Shutdown and close the socket. If read_before_closing is false, it just immediately calls shutdown() with SHUT_RDWR + * @brief Gracefully shuts down and closes the network driver, optionally reading until EOF. + * Shutdown and close the network driver. If read_before_closing is false, it just immediately calls shutdown() with SHUT_RDWR * and close(). If read_before_closing is true, it calls shutdown with SHUT_WR, only disallowing further writing. Then, * it calls read() until EOF is received, and discards all received bytes. - * @param drv Pointer to the socket descriptor to shutdown and close. - * @param read_before_closing If true, read until EOF before closing the socket. + * @param drv The network driver to shutdown and close. + * @param read_before_closing If true, read until EOF before closing the network driver. * @return int Returns 0 on success, -1 on failure (errno will indicate the error). */ int shutdown_netdrv(netdrv_t drv, bool read_before_closing); @@ -166,7 +159,7 @@ int shutdown_netdrv(netdrv_t drv, bool read_before_closing); * This is used when the federate sends a MSG_TYPE_ADDRESS_ADVERTISEMENT to the RTI, informing its port number. The RTI * will save this port number, and send it to the other federate in a MSG_TYPE_ADDRESS_QUERY_REPLY message. * - * @param drv Network driver instance + * @param drv The network driver. * @return The port number of a server network driver. */ int32_t get_my_port(netdrv_t drv); @@ -176,7 +169,7 @@ int32_t get_my_port(netdrv_t drv); * This is used by the RTI, when there is a request from the federate to the RTI, for the MSG_TYPE_ADDRESS_QUERY * message. * - * @param drv Network driver instance + * @param drv The network driver. * @return Port number of the connected peer. */ int32_t get_server_port(netdrv_t drv); @@ -184,7 +177,7 @@ int32_t get_server_port(netdrv_t drv); /** * Get the IP address of the connected peer. * - * @param drv Network driver instance + * @param drv The network driver. * @return Pointer to the server IP address */ struct in_addr* get_ip_addr(netdrv_t drv); @@ -192,7 +185,7 @@ struct in_addr* get_ip_addr(netdrv_t drv); /** * Get the hostname of the connected peer. * - * @param drv Network driver instance + * @param drv The network driver. * @return Pointer to the server hostname */ char* get_server_hostname(netdrv_t drv); @@ -200,7 +193,7 @@ char* get_server_hostname(netdrv_t drv); /** * Set the user specified port to the created network driver. * - * @param drv Network driver instance + * @param drv The network driver. * @param port The user specified port */ void set_my_port(netdrv_t drv, int32_t port); @@ -210,7 +203,7 @@ void set_my_port(netdrv_t drv, int32_t port); * federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. This function is used to set the network driver's target server port * number. The * - * @param drv Network driver instance + * @param drv The network driver. * @param port The target server's port */ void set_server_port(netdrv_t drv, int32_t port); @@ -218,7 +211,7 @@ void set_server_port(netdrv_t drv, int32_t port); /** * Set the target server's hostname to the network driver. * - * @param drv Network driver instance + * @param drv The network driver. * @param hostname The target server's hostname */ void set_server_hostname(netdrv_t drv, const char* hostname); From d21419033d9f68f211061787e5fec81494abce79 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 15:38:14 -0700 Subject: [PATCH 119/167] Change comments. --- network/api/net_driver.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 32f867ea4..52f437e2b 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -65,8 +65,7 @@ int read_from_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** * Read the specified number of bytes to the specified network driver using read_from_netdrv - * and close the network driver if an error occurs. If an error occurs, this will change the - * socket ID pointed to by the first argument to -1 and will return -1. + * and close the network driver if an error occurs. * @param drv The network driver. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. @@ -107,9 +106,8 @@ void read_from_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned cha int write_to_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); /** - * Write the specified number of bytes to the specified network driver using write_to_netfdrv - * and close the network driver if an error occurs. If an error occurs, this will change the - * socket ID pointed to by the first argument to -1 and will return -1. + * Write the specified number of bytes to the specified network driver using write_to_netdrv + * and close the network driver if an error occurs. * @param drv The network driver. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. @@ -145,9 +143,9 @@ bool check_netdrv_closed(netdrv_t drv); /** * @brief Gracefully shuts down and closes the network driver, optionally reading until EOF. - * Shutdown and close the network driver. If read_before_closing is false, it just immediately calls shutdown() with SHUT_RDWR - * and close(). If read_before_closing is true, it calls shutdown with SHUT_WR, only disallowing further writing. Then, - * it calls read() until EOF is received, and discards all received bytes. + * Shutdown and close the network driver. If read_before_closing is false, it just immediately calls shutdown() with + * SHUT_RDWR and close(). If read_before_closing is true, it calls shutdown with SHUT_WR, only disallowing further + * writing. Then, it calls read() until EOF is received, and discards all received bytes. * @param drv The network driver to shutdown and close. * @param read_before_closing If true, read until EOF before closing the network driver. * @return int Returns 0 on success, -1 on failure (errno will indicate the error). @@ -199,9 +197,10 @@ char* get_server_hostname(netdrv_t drv); void set_my_port(netdrv_t drv, int32_t port); /** - * Set server port number to the target network driver. The federate and RTI receives the port number fr on aom another - * federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. This function is used to set the network driver's target server port - * number. The + * Set server port number to the target network driver. + * The federate and RTI receives the port number from another + * federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. + * This function is used to set the network driver's target server port number. * * @param drv The network driver. * @param port The target server's port From 72791c083af05d431ce574f4ec1c433405edd515 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Thu, 30 Jan 2025 09:52:09 -0700 Subject: [PATCH 120/167] Fix comments. --- network/api/net_driver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 52f437e2b..f9c74bde9 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -43,8 +43,8 @@ netdrv_t accept_netdrv(netdrv_t server_drv, netdrv_t rti_drv); void create_client(netdrv_t drv); /** - * Connect to the server network driver. The server's connection information, such as the port and address should be set - * before calling this function. + * Connect to the server network driver. The server's connection information, + * such as the port and address should be set before calling this function. * * @param drv Network driver to connect. * @return int 0 on success, -1 on failure, and `errno` is set to indicate the specific error. From 1f2290e5881ef8ecf03a455ba413e2a794cf92ed Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Thu, 30 Jan 2025 10:59:31 -0700 Subject: [PATCH 121/167] Minor fix. Remove create_clock_server, directly using create_socket_server for clock servers. --- core/federated/RTI/rti_remote.c | 48 ++++++++++++++++---------------- network/api/net_driver.h | 4 +-- network/api/socket_common.h | 4 +-- network/impl/src/socket_common.c | 4 --- 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index c89e1044a..682b48e69 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -73,7 +73,7 @@ void notify_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_TAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the socket might close, causing the following write_to_netdrv + // function. During this call, the network driver might close, causing the following write_to_netdrv // to fail. Consider a failure here a soft failure and update the federate's status. if (write_to_netdrv(((federate_info_t*)e)->fed_netdrv, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); @@ -106,7 +106,7 @@ void notify_provisional_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_PTAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the socket might close, causing the following write_to_netdrv + // function. During this call, the network driver might close, causing the following write_to_netdrv // to fail. Consider a failure here a soft failure and update the federate's status. if (write_to_netdrv(((federate_info_t*)e)->fed_netdrv, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); @@ -200,7 +200,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char } // Need to acquire the mutex lock to ensure that the thread handling - // messages coming from the socket connected to the destination does not + // messages coming from the network driver connected to the destination does not // issue a TAG before this message has been forwarded. LF_MUTEX_LOCK(&rti_mutex); @@ -285,12 +285,12 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff } // Need to acquire the mutex lock to ensure that the thread handling - // messages coming from the socket connected to the destination does not + // messages coming from the network driver connected to the destination does not // issue a TAG before this message has been forwarded. LF_MUTEX_LOCK(&rti_mutex); // If the destination federate is no longer connected, issue a warning, - // remove the message from the socket and return. + // remove the message from the network driver and return. federate_info_t* fed = GET_FED_INFO(federate_id); if (fed->enclave.state == NOT_CONNECTED) { lf_print_warning("RTI: Destination federate %d is no longer connected. Dropping message.", federate_id); @@ -351,7 +351,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff // FIXME: a mutex needs to be held for this so that other threads // do not write to destination_socket and cause interleaving. However, // holding the rti_mutex might be very expensive. Instead, each outgoing - // socket should probably have its own mutex. + // network driver should probably have its own mutex. write_to_netdrv_fail_on_error(fed->fed_netdrv, bytes_to_read, buffer, &rti_mutex, "RTI failed to send message chunks."); } @@ -701,7 +701,7 @@ void handle_address_ad(uint16_t federate_id) { void handle_timestamp(federate_info_t* my_fed) { unsigned char buffer[sizeof(int64_t)]; - // Read bytes from the socket. We need 8 bytes. + // Read bytes from the network driver. We need 8 bytes. read_from_netdrv_fail_on_error(my_fed->fed_netdrv, sizeof(int64_t), (unsigned char*)&buffer, NULL, "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); @@ -905,7 +905,7 @@ void* clock_synchronization_thread(void* noargs) { * @param my_fed The federate sending a MSG_TYPE_FAILED message. */ static void handle_federate_failed(federate_info_t* my_fed) { - // Nothing more to do. Close the socket and exit. + // Nothing more to do. Close the network driver and exit. LF_MUTEX_LOCK(&rti_mutex); if (rti_remote->base.tracing_enabled) { @@ -940,13 +940,13 @@ static void handle_federate_failed(federate_info_t* my_fed) { * This function assumes the caller does not hold the mutex. * * @note At this point, the RTI might have outgoing messages to the federate. This - * function thus first performs a shutdown on the socket, which sends an EOF. It then - * waits for the remote socket to be closed before closing the socket itself. + * function thus first performs a shutdown on the network driver, which sends an EOF. It then + * waits for the remote network driver to be closed before closing the network driver itself. * * @param my_fed The federate sending a MSG_TYPE_RESIGN message. */ static void handle_federate_resign(federate_info_t* my_fed) { - // Nothing more to do. Close the socket and exit. + // Nothing more to do. Close the network driver and exit. LF_MUTEX_LOCK(&rti_mutex); if (rti_remote->base.tracing_enabled) { @@ -986,11 +986,11 @@ void* federate_info_thread_TCP(void* fed) { // Read no more than one byte to get the message type. int read_failed = read_from_netdrv(my_fed->fed_netdrv, 1, buffer); if (read_failed) { - // Socket is closed + // ã…œetwork driver is closed lf_print_error("RTI: Socket to federate %d is closed. Exiting the thread.", my_fed->enclave.id); my_fed->enclave.state = NOT_CONNECTED; - // Nothing more to do. Close the socket and exit. - // Prevent multiple threads from closing the same socket at the same time. + // Nothing more to do. Close the network driver and exit. + // Prevent multiple threads from closing the same network driver at the same time. LF_MUTEX_LOCK(&rti_mutex); shutdown_netdrv(my_fed->fed_netdrv, false); LF_MUTEX_UNLOCK(&rti_mutex); @@ -1054,9 +1054,9 @@ void send_reject(netdrv_t drv, unsigned char error_code) { LF_MUTEX_LOCK(&rti_mutex); // NOTE: Ignore errors on this response. if (write_to_netdrv(drv, 2, response)) { - lf_print_warning("RTI failed to write MSG_TYPE_REJECT message on the socket."); + lf_print_warning("RTI failed to write MSG_TYPE_REJECT message on the network driver."); } - // Close the socket without reading until EOF. + // Close the network driver without reading until EOF. shutdown_netdrv(drv, false); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -1067,7 +1067,6 @@ void send_reject(netdrv_t drv, unsigned char error_code) { * matches this federation, send an MSG_TYPE_ACK and otherwise send * a MSG_TYPE_REJECT message. * @param fed_netdrv Pointer to the network driver on which to listen. - * @param client_fd The socket address. * @return The federate ID for success or -1 for failure. */ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { @@ -1077,7 +1076,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { // Read bytes from the socket. We need 4 bytes. if (read_from_netdrv_close_on_error(fed_netdrv, length, buffer)) { - lf_print_error("RTI failed to read from accepted socket."); + lf_print_error("RTI failed to read from accepted network driver."); return -1; } @@ -1307,7 +1306,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t fed_netdrv, uint16 size_t message_size = 1 + sizeof(uint16_t); unsigned char buffer[message_size]; read_from_netdrv_fail_on_error(fed_netdrv, message_size, buffer, NULL, - "Socket to federate %d unexpectedly closed.", fed_id); + "Network driver to federate %d unexpectedly closed.", fed_id); if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); LF_PRINT_DEBUG("RTI received T3 clock sync message from federate %d.", fed_id); @@ -1427,7 +1426,7 @@ void lf_connect_to_federates(netdrv_t rti_netdrv) { if (rti_remote->authentication_enabled) { if (!authenticate_federate(fed_netdrv)) { lf_print_warning("RTI failed to authenticate the incoming federate."); - // Close the socket without reading until EOF. + // Close the network driver without reading until EOF. shutdown_netdrv(fed_netdrv, false); // Ignore the federate that failed authentication. i--; @@ -1495,7 +1494,7 @@ void* respond_to_erroneous_connections(void* nothing) { if (write_to_netdrv(fed_netdrv, 2, response)) { lf_print_warning("RTI failed to write FEDERATION_ID_DOES_NOT_MATCH to erroneous incoming connection."); } - // Close the socket without reading until EOF. + // Close the network driver without reading until EOF. shutdown_netdrv(fed_netdrv, false); } return NULL; @@ -1522,7 +1521,8 @@ int start_rti_server() { lf_print("RTI: Listening for federates."); // Create the UDP socket server if (rti_remote->clock_sync_global_status >= clock_sync_on) { - if (create_clock_server(DEFAULT_UDP_PORT, &rti_remote->socket_descriptor_UDP, &rti_remote->final_port_UDP)) { + if (create_socket_server(DEFAULT_UDP_PORT, &rti_remote->socket_descriptor_UDP, &rti_remote->final_port_UDP, UDP, + false)) { lf_print_error_system_failure("RTI failed to create UDP server: %s.", strerror(errno)); return -1; } @@ -1537,7 +1537,7 @@ void wait_for_federates() { // All federates have connected. lf_print("RTI: All expected federates have connected. Starting execution."); - // The socket server will not continue to accept connections after all the federates + // The network driver server will not continue to accept connections after all the federates // have joined. // In case some other federation's federates are trying to join the wrong // federation, need to respond. Start a separate thread to do that. @@ -1556,7 +1556,7 @@ void wait_for_federates() { rti_remote->all_federates_exited = true; - // Shutdown and close the socket that is listening for incoming connections + // Shutdown and close the network driver that is listening for incoming connections // so that the accept() call in respond_to_erroneous_connections returns. // That thread should then check rti->all_federates_exited and it should exit. shutdown_netdrv(rti_remote->rti_netdrv, false); diff --git a/network/api/net_driver.h b/network/api/net_driver.h index f9c74bde9..b29e8b108 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -12,8 +12,8 @@ typedef void* netdrv_t; netdrv_t initialize_netdrv(); /** - * Create a netdriver server. This is such as a server socket which accepts connections. However this is only the - * creation of the server netdriver. + * Create a netdriver server. This is such as a server socket which accepts connections. + * However this is only the creation of the server netdriver. * * @param drv Server's network driver. * @param serv_type Type of server, RTI or FED. diff --git a/network/api/socket_common.h b/network/api/socket_common.h index fb1899b02..87d6237e0 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -129,8 +129,6 @@ int create_real_time_tcp_socket_errexit(); int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, socket_type_t sock_type, bool increment_port_on_retry); -int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port); - /** * Wait for an incoming connection request on the specified server socket. * This blocks until a connection is successfully accepted. If an error occurs that is not @@ -147,7 +145,6 @@ int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port); * @return The file descriptor for the newly accepted socket on success, or -1 on failure * (with an appropriate error message printed). */ - int accept_socket(int socket, int rti_socket); /** @@ -225,6 +222,7 @@ ssize_t peek_from_socket(int socket, unsigned char* result); * Return true if either the socket to the RTI is broken or the socket is * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. * @param socket Socket to check. + * @return True if closed, false if still connected. */ bool check_socket_closed(int socket); diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 4ccebb02e..cf8ca017d 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -170,10 +170,6 @@ int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, return 0; } -int create_clock_server(uint16_t port, int* final_socket, uint16_t* final_port) { - return create_socket_server(port, final_socket, final_port, UDP, false); -} - bool check_socket_closed(int socket) { unsigned char first_byte; ssize_t bytes = peek_from_socket(socket, &first_byte); From 6e57f4be1c524139c35f83d807573d62c6d89c51 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Thu, 30 Jan 2025 12:22:50 -0700 Subject: [PATCH 122/167] Remove unnecessary headers. --- core/federated/RTI/rti_remote.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 4df4c6cb1..800b696d9 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -15,13 +15,6 @@ #ifndef RTI_REMOTE_H #define RTI_REMOTE_H -#include -#include // Provides select() function to read from multiple sockets. -#include // Defines struct sockaddr_in -#include // inet_ntop & inet_pton -#include // Defines read(), write(), and close() -#include // Defines bzero(). - #include "rti_common.h" #ifdef __RTI_AUTH__ From 9358e76b2a767c52324c0b293e09042a3096092c Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Thu, 30 Jan 2025 12:23:44 -0700 Subject: [PATCH 123/167] Fix comments and logs. --- core/federated/RTI/rti_remote.c | 16 ++++++++-------- core/federated/federate.c | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 682b48e69..296774338 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -666,10 +666,10 @@ void handle_address_query(uint16_t fed_id) { // Send the port number (which could be -1) and the server IP address to federate. write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int32_t), (unsigned char*)buffer, &rti_mutex, - "Failed to write port number to socket of federate %d.", fed_id); + "Failed to write port number to network driver of federate %d.", fed_id); write_to_netdrv_fail_on_error(fed->fed_netdrv, sizeof(uint32_t), (unsigned char*)ip_address, &rti_mutex, - "Failed to write ip address to socket of federate %d.", fed_id); + "Failed to write ip address to network driver of federate %d.", fed_id); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, server_host_name, @@ -760,7 +760,7 @@ void handle_timestamp(federate_info_t* my_fed) { void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP) { if (fed->enclave.state == NOT_CONNECTED) { - lf_print_warning("Clock sync: RTI failed to send physical time to federate %d. Socket not connected.\n", + lf_print_warning("Clock sync: RTI failed to send physical time to federate %d. Network driver not connected.\n", fed->enclave.id); return; } @@ -780,8 +780,8 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool return; } } else { - // Send using TCP - LF_PRINT_DEBUG("Clock sync: RTI sending TCP message type %u.", buffer[0]); + // Send using network driver. + LF_PRINT_DEBUG("Clock sync: RTI sending message type %u.", buffer[0]); LF_MUTEX_LOCK(&rti_mutex); write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int64_t), buffer, &rti_mutex, "Clock sync: RTI failed to send physical time to federate %d.", fed->enclave.id); @@ -987,7 +987,7 @@ void* federate_info_thread_TCP(void* fed) { int read_failed = read_from_netdrv(my_fed->fed_netdrv, 1, buffer); if (read_failed) { // ã…œetwork driver is closed - lf_print_error("RTI: Socket to federate %d is closed. Exiting the thread.", my_fed->enclave.id); + lf_print_error("RTI: Network driver to federate %d is closed. Exiting the thread.", my_fed->enclave.id); my_fed->enclave.state = NOT_CONNECTED; // Nothing more to do. Close the network driver and exit. // Prevent multiple threads from closing the same network driver at the same time. @@ -1074,7 +1074,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { size_t length = 1 + sizeof(uint16_t) + 1; // Message ID, federate ID, length of fedration ID. unsigned char buffer[length]; - // Read bytes from the socket. We need 4 bytes. + // Read bytes from the network driver. We need 4 bytes. if (read_from_netdrv_close_on_error(fed_netdrv, length, buffer)) { lf_print_error("RTI failed to read from accepted network driver."); return -1; @@ -1477,7 +1477,7 @@ void* respond_to_erroneous_connections(void* nothing) { while (true) { // Wait for an incoming connection request. // The following will block until either a federate attempts to connect - // or shutdown_socket(rti->socket_descriptor_TCP) is called. + // or shutdown_netdrv(rti->rti_netdrv) is called. netdrv_t fed_netdrv = accept_netdrv(rti_remote->rti_netdrv, NULL); if (fed_netdrv == NULL) { return NULL; diff --git a/core/federated/federate.c b/core/federated/federate.c index 730df27d2..abd920a73 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1492,11 +1492,11 @@ static void send_failed_signal() { static void handle_rti_failed_message(void) { exit(1); } /** - * Thread that listens for TCP inputs from the RTI. + * Thread that listens for network driver inputs from the RTI. * When messages arrive, this calls the appropriate handler. * @param args Ignored */ -static void* listen_to_rti_TCP(void* args) { +static void* listen_to_rti_netdrv(void* args) { (void)args; initialize_lf_thread_id(); // Buffer for incoming messages. @@ -1560,7 +1560,7 @@ static void* listen_to_rti_TCP(void* args) { lf_print_error("Federate %d received unexpected clock sync message from RTI.", _lf_my_fed_id); break; default: - lf_print_error_and_exit("Received from RTI an unrecognized TCP message type: %hhx.", buffer[0]); + lf_print_error_and_exit("Received from RTI an unrecognized message type: %hhx.", buffer[0]); // Trace the event when tracing is enabled tracepoint_federate_from_rti(receive_UNIDENTIFIED, _lf_my_fed_id, NULL); } @@ -2577,7 +2577,7 @@ void lf_synchronize_with_other_federates(void) { // @note Up until this point, the federate has been listening for messages // from the RTI in a sequential manner in the main thread. From now on, a // separate thread is created to allow for asynchronous communication. - lf_thread_create(&_fed.RTI_netdrv_listener, listen_to_rti_TCP, NULL); + lf_thread_create(&_fed.RTI_netdrv_listener, listen_to_rti_netdrv, NULL); lf_thread_t thread_id; if (create_clock_sync_thread(&thread_id)) { lf_print_warning("Failed to create thread to handle clock synchronization."); From 9f79d09d91927abe617d2916b5358b20fc301983 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 31 Jan 2025 15:28:22 -0700 Subject: [PATCH 124/167] Move get_peer_addr to socket_common.c for reuse. --- network/api/socket_common.h | 8 ++++++++ network/impl/src/lf_socket_support.c | 23 ----------------------- network/impl/src/socket_common.c | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 87d6237e0..89fca99a5 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -225,6 +225,14 @@ ssize_t peek_from_socket(int socket, unsigned char* result); * @return True if closed, false if still connected. */ bool check_socket_closed(int socket); +/** + * Get the connected peer name from the connected socket. + * Set it to the server_ip_addr. Also, set server_hostname if LOG_LEVEL is higher than LOG_LEVEL_DEBUG. + * + * @param priv The socket_priv struct. + * @return 0 for success, -1 for failure. + */ +int get_peer_address(socket_priv_t* priv); /** * Write the specified number of bytes to the specified socket from the diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index df8a10670..ec257ea52 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -16,29 +16,6 @@ static socket_priv_t* get_socket_priv_t(netdrv_t drv) { return (socket_priv_t*)drv; } -static int get_peer_address(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); - struct sockaddr_in peer_addr; - socklen_t addr_len = sizeof(peer_addr); - if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { - lf_print_error("Failed to get peer address."); - return -1; - } - priv->server_ip_addr = peer_addr.sin_addr; - -#if LOG_LEVEL >= LOG_LEVEL_DEBUG - // Create the human readable format and copy that into - // the .server_hostname field of the federate. - char str[INET_ADDRSTRLEN + 1]; - inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); - strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters - priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly - - LF_PRINT_DEBUG("Got address %s", priv->server_hostname); -#endif - return 0; -} - netdrv_t initialize_netdrv() { // Initialize priv. socket_priv_t* priv = malloc(sizeof(socket_priv_t)); diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index cf8ca017d..338aa9b3f 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -1,6 +1,7 @@ #include // Defines read(), write(), and close() #include // IPPROTO_TCP, IPPROTO_UDP #include // TCP_NODELAY +#include // inet_ntop #include #include #include @@ -180,6 +181,28 @@ bool check_socket_closed(int socket) { } } +int get_peer_address(socket_priv_t* priv) { + struct sockaddr_in peer_addr; + socklen_t addr_len = sizeof(peer_addr); + if (getpeername(priv->socket_descriptor, (struct sockaddr*)&peer_addr, &addr_len) != 0) { + lf_print_error("Failed to get peer address."); + return -1; + } + priv->server_ip_addr = peer_addr.sin_addr; + +#if LOG_LEVEL >= LOG_LEVEL_DEBUG + // Create the human readable format and copy that into + // the .server_hostname field of the federate. + char str[INET_ADDRSTRLEN + 1]; + inet_ntop(AF_INET, &priv->server_ip_addr, str, INET_ADDRSTRLEN); + strncpy(priv->server_hostname, str, INET_ADDRSTRLEN - 1); // Copy up to INET_ADDRSTRLEN - 1 characters + priv->server_hostname[INET_ADDRSTRLEN - 1] = '\0'; // Null-terminate explicitly + + LF_PRINT_DEBUG("Got address %s", priv->server_hostname); +#endif + return 0; +} + int accept_socket(int socket, int rti_socket) { struct sockaddr client_fd; // Wait for an incoming connection request. From c3ca18f09df63be736a64c5c834ee86a7e8d91bb Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 31 Jan 2025 15:30:06 -0700 Subject: [PATCH 125/167] Add comments. --- network/impl/src/lf_socket_support.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index ec257ea52..417979aa2 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -51,6 +51,8 @@ netdrv_t accept_netdrv(netdrv_t server_drv, netdrv_t rti_drv) { socket_priv_t* serv_priv = get_socket_priv_t(server_drv); int rti_socket; if (rti_drv == NULL) { + // Set to -1, to indicate that this accept_netdrv() call is not trying to check if the rti_drv is available, inside + // the accept_socket() function. rti_socket = -1; } else { socket_priv_t* rti_priv = get_socket_priv_t(rti_drv); From 22f6bb85a610d3aba2e63fb7063884cdcfc45eb0 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 31 Jan 2025 15:31:29 -0700 Subject: [PATCH 126/167] Minor fix. --- network/impl/src/lf_socket_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 417979aa2..f82d5b456 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -68,7 +68,7 @@ netdrv_t accept_netdrv(netdrv_t server_drv, netdrv_t rti_drv) { } fed_priv->socket_descriptor = sock; // Get the peer address from the connected socket_id. Saving this for the address query. - if (get_peer_address(fed_netdrv) != 0) { + if (get_peer_address(fed_priv) != 0) { lf_print_error("RTI failed to get peer address."); }; return fed_netdrv; From f5960ffa55a0124267bb3ef65ce08d86f9c3790d Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 31 Jan 2025 16:10:29 -0700 Subject: [PATCH 127/167] Minor fix on comments. --- core/federated/federate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index abd920a73..460f72255 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1760,7 +1760,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // Create the client network driver. create_client(netdrv); if (connect_to_netdrv(netdrv) < 0) { - lf_print_error_and_exit("Failed to connect() to RTI."); + lf_print_error_and_exit("Failed to connect to federate."); } // Iterate until we either successfully connect or we exceed the CONNECT_TIMEOUT @@ -1844,7 +1844,7 @@ void lf_connect_to_rti(const char* hostname, int port) { // Create the client network driver. create_client(_fed.netdrv_to_RTI); if (connect_to_netdrv(_fed.netdrv_to_RTI) < 0) { - lf_print_error_and_exit("Failed to connect() to RTI."); + lf_print_error_and_exit("Failed to connect to RTI."); } instant_t start_connect = lf_time_physical(); From 93379ce75bd33dea62a503ec97152eb2596bdb48 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 15:38:59 -0700 Subject: [PATCH 128/167] Add `void` to functions with no parameters. --- network/api/socket_common.h | 2 +- network/impl/src/net_util.c | 2 +- network/impl/src/socket_common.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 89fca99a5..4841a91f2 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -105,7 +105,7 @@ typedef struct socket_priv_t { * * @return The socket ID (a file descriptor). */ -int create_real_time_tcp_socket_errexit(); +int create_real_time_tcp_socket_errexit(void); /** * @brief Create a TCP server that listens for socket connections. diff --git a/network/impl/src/net_util.c b/network/impl/src/net_util.c index 79849aa4d..3565fcb4e 100644 --- a/network/impl/src/net_util.c +++ b/network/impl/src/net_util.c @@ -80,7 +80,7 @@ void encode_uint16(uint16_t data, unsigned char* buffer) { buffer[1] = (unsigned char)((data & 0xff00) >> 8); } -int host_is_big_endian() { +int host_is_big_endian(void) { static int host = 0; union { uint32_t uint; diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 338aa9b3f..159de1d66 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -25,7 +25,7 @@ // A deadlock can occur if two threads simulataneously attempt to close the same network driver. lf_mutex_t netdrv_mutex; -int create_real_time_tcp_socket_errexit() { +int create_real_time_tcp_socket_errexit(void) { int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) { lf_print_error_system_failure("Could not open TCP socket."); From aa66b629e23c0695c79e130d1cbc5f0ea4030ce7 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 24 Feb 2025 12:53:40 -0700 Subject: [PATCH 129/167] Change clock-sync.c name to netchan --- core/federated/clock-sync.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index 5f1e18946..f26c43718 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -208,7 +208,7 @@ uint16_t setup_clock_synchronization_with_rti() { return port_to_return; } -void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv) { +void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan) { LF_PRINT_DEBUG("Waiting for initial clock synchronization messages from the RTI."); size_t message_size = 1 + sizeof(instant_t); @@ -216,7 +216,7 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv) { for (int i = 0; i < _LF_CLOCK_SYNC_EXCHANGES_PER_INTERVAL; i++) { // The first message expected from the RTI is MSG_TYPE_CLOCK_SYNC_T1 - read_from_netdrv_fail_on_error(rti_netdrv, message_size, buffer, NULL, + read_from_netchan_fail_on_error(rti_netchan, message_size, buffer, NULL, "Federate %d did not get the initial clock synchronization message T1 from the RTI.", _lf_my_fed_id); @@ -230,12 +230,12 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv) { // Handle the message and send a reply T3 message. // NOTE: No need to acquire the mutex lock during initialization because only // one thread is running. - if (handle_T1_clock_sync_message(buffer, (void*)rti_netdrv, receive_time, false) != 0) { + if (handle_T1_clock_sync_message(buffer, (void*)rti_netchan, receive_time, false) != 0) { lf_print_error_and_exit("Initial clock sync: Failed to send T3 reply to RTI."); } // Next message from the RTI is required to be MSG_TYPE_CLOCK_SYNC_T4 - read_from_netdrv_fail_on_error(rti_netdrv, message_size, buffer, NULL, + read_from_netchan_fail_on_error(rti_netchan, message_size, buffer, NULL, "Federate %d did not get the clock synchronization message T4 from the RTI.", _lf_my_fed_id); @@ -245,7 +245,7 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv) { } // Handle the message. - handle_T4_clock_sync_message(buffer, (void*)rti_netdrv, receive_time, false); + handle_T4_clock_sync_message(buffer, (void*)rti_netchan, receive_time, false); } LF_PRINT_LOG("Finished initial clock synchronization with the RTI."); @@ -258,12 +258,12 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv) { * It also measures the time it takes between when the method is * called and the reply has been sent. * @param buffer The buffer containing the message, including the message type. - * @param socket_or_netdrv The pointer of either UDP socket or the network driver. + * @param socket_or_netchan The pointer of either UDP socket or the network channel. * @param t2 The physical time at which the T1 message was received. - * @param use_UDP Boolean to use UDP or the network driver. + * @param use_UDP Boolean to use UDP or the network channel. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, instant_t t2, bool use_udp) { +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t t2, bool use_udp) { // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); @@ -283,8 +283,8 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); - int result = use_udp ? write_to_socket(*(int*)socket_or_netdrv, 1 + sizeof(uint16_t), reply_buffer) - : write_to_netdrv((netdrv_t)socket_or_netdrv, 1 + sizeof(uint16_t), reply_buffer); + int result = use_udp ? write_to_socket(*(int*)socket_or_netchan, 1 + sizeof(uint16_t), reply_buffer) + : write_to_netchan((netchan_t)socket_or_netchan, 1 + sizeof(uint16_t), reply_buffer); if (result) { lf_print_error("Clock sync: Failed to send T3 message to RTI."); @@ -300,7 +300,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, /** * Handle a clock synchronization message T4 coming from the RTI. - * If using the network driver, then assume we are in the + * If using the network channel, then assume we are in the * initial clock synchronization phase and set the clock offset * based on the estimated clock synchronization error. * Otherwise, if using the UDP socket, then this looks also for a @@ -308,14 +308,14 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, * the T4 and the coded probe message is not as expected, then reject * this clock synchronization round. If it is not rejected, then make * an adjustment to the clock offset based on the estimated error. - * This function does not acquire the netdrv_mutex lock. + * This function does not acquire the netchan_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. - * @param socket_or_netdrv The pointer of either UDP socket or the network driver. + * @param socket_or_netchan The pointer of either UDP socket or the network channel. * @param r4 The physical time at which this T4 message was received. - * @param use_UDP Boolean to use UDP or the network driver. + * @param use_UDP Boolean to use UDP or the network channel. */ -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, instant_t r4, bool use_udp) { +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t r4, bool use_udp) { // Increment the number of received T4 messages _lf_rti_socket_stat.received_T4_messages_in_current_sync_window++; @@ -350,7 +350,7 @@ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, if (use_udp) { // Read the coded probe message. // We can reuse the same buffer. - int read_failed = read_from_socket(*(int*)socket_or_netdrv, 1 + sizeof(instant_t), buffer); + int read_failed = read_from_socket(*(int*)socket_or_netchan, 1 + sizeof(instant_t), buffer); instant_t r5 = lf_time_physical(); From b50ba2f4b115a72d528a5d0328f6d172a22640ef Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 24 Feb 2025 13:10:08 -0700 Subject: [PATCH 130/167] Change federate.c name to netchan --- core/federated/federate.c | 416 +++++++++++++++++++------------------- 1 file changed, 208 insertions(+), 208 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 460f72255..14b9e4784 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -45,7 +45,7 @@ extern instant_t start_time; extern bool _lf_termination_executed; // Global variables references in federate.h -lf_mutex_t lf_outbound_netdrv_mutex; +lf_mutex_t lf_outbound_netchan_mutex; lf_cond_t lf_port_status_changed; /** @@ -95,7 +95,7 @@ federation_metadata_t federation_metadata = { // Static functions (used only internally) /** - * Send a time to the RTI. This acquires the lf_outbound_netdrv_mutex. + * Send a time to the RTI. This acquires the lf_outbound_netchan_mutex. * @param type The message type (MSG_TYPE_TIMESTAMP). * @param time The time. */ @@ -110,15 +110,15 @@ static void send_time(unsigned char type, instant_t time) { tag_t tag = {.time = time, .microstep = 0}; tracepoint_federate_to_rti(send_TIMESTAMP, _lf_my_fed_id, &tag); - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, buffer, &lf_outbound_netchan_mutex, "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); } /** * Send a tag to the RTI. - * This function acquires the lf_outbound_netdrv_mutex. + * This function acquires the lf_outbound_netchan_mutex. * @param type The message type (MSG_TYPE_NEXT_EVENT_TAG or MSG_TYPE_LATEST_TAG_CONFIRMED). * @param tag The tag. */ @@ -129,25 +129,25 @@ static void send_tag(unsigned char type, tag_t tag) { buffer[0] = type; encode_tag(&(buffer[1]), tag); - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - if (_fed.netdrv_to_RTI == NULL) { + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + if (_fed.netchan_to_RTI == NULL) { lf_print_warning("RTI is no longer connected. Dropping message."); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); return; } trace_event_t event_type = (type == MSG_TYPE_NEXT_EVENT_TAG) ? send_NET : send_LTC; // Trace the event when tracing is enabled tracepoint_federate_to_rti(event_type, _lf_my_fed_id, &tag); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_write, buffer, &lf_outbound_netdrv_mutex, + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, buffer, &lf_outbound_netchan_mutex, "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); } /** - * Return true if either the network driver to the RTI is broken or the network driver is - * alive and the first unread byte on the network driver's queue is MSG_TYPE_FAILED. + * Return true if either the network channel to the RTI is broken or the network channel is + * alive and the first unread byte on the network channel's queue is MSG_TYPE_FAILED. */ -static bool rti_failed() { return check_netdrv_closed(_fed.netdrv_to_RTI); } +static bool rti_failed() { return check_netchan_closed(_fed.netchan_to_RTI); } //////////////////////////////// Port Status Handling /////////////////////////////////////// @@ -391,21 +391,21 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen } /** - * Close the network driver that receives incoming messages from the + * Close the network channel that receives incoming messages from the * specified federate ID. This function should be called when a read - * of incoming network driver fails or when an EOF is received. + * of incoming network channel fails or when an EOF is received. * It can also be called when the receiving end wants to stop communication. * * @param fed_id The ID of the peer federate sending messages to this * federate. */ -static void close_inbound_netdrv(int fed_id) { - LF_MUTEX_LOCK(&netdrv_mutex); - if (_fed.netdrvs_for_inbound_p2p_connections[fed_id] != NULL) { - shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[fed_id], false); - _fed.netdrvs_for_inbound_p2p_connections[fed_id] = NULL; +static void close_inbound_netchan(int fed_id) { + LF_MUTEX_LOCK(&netchan_mutex); + if (_fed.netchans_for_inbound_p2p_connections[fed_id] != NULL) { + shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[fed_id], false); + _fed.netchans_for_inbound_p2p_connections[fed_id] = NULL; } - LF_MUTEX_UNLOCK(&netdrv_mutex); + LF_MUTEX_UNLOCK(&netchan_mutex); } /** @@ -455,17 +455,17 @@ static bool handle_message_now(environment_t* env, trigger_t* trigger, tag_t int * Handle a message being received from a remote federate. * * This function assumes the caller does not hold the mutex lock. - * @param netdrv Pointer to the network driver to read the message from. + * @param netchan Pointer to the network channel to read the message from. * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure. */ -static int handle_message(netdrv_t netdrv, int fed_id) { +static int handle_message(netchan_t netchan, int fed_id) { (void)fed_id; // Read the header. size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); unsigned char buffer[bytes_to_read]; - if (read_from_netdrv_close_on_error(netdrv, bytes_to_read, buffer)) { - // Read failed, which means the network driver has been closed between reading the + if (read_from_netchan_close_on_error(netchan, bytes_to_read, buffer)) { + // Read failed, which means the network channel has been closed between reading the // message ID byte and here. return -1; } @@ -485,7 +485,7 @@ static int handle_message(netdrv_t netdrv, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_netdrv_close_on_error(netdrv, length, message_contents)) { + if (read_from_netchan_close_on_error(netchan, length, message_contents)) { return -1; } // Trace the event when tracing is enabled @@ -509,11 +509,11 @@ static int handle_message(netdrv_t netdrv, int fed_id) { * will not advance to the tag of the message if it is in the future, or * the tag will not advance at all if the tag of the message is * now or in the past. - * @param netdrv Pointer to the network driver to read the message from. + * @param netchan Pointer to the network channel to read the message from. * @param fed_id The sending federate ID or -1 if the centralized coordination. - * @return 0 on successfully reading the message, -1 on failure (e.g. due to network driver closed). + * @return 0 on successfully reading the message, -1 on failure (e.g. due to network channel closed). */ -static int handle_tagged_message(netdrv_t netdrv, int fed_id) { +static int handle_tagged_message(netchan_t netchan, int fed_id) { // Environment is always the one corresponding to the top-level scheduling enclave. environment_t* env; _lf_get_environments(&env); @@ -522,7 +522,7 @@ static int handle_tagged_message(netdrv_t netdrv, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_netdrv_close_on_error(netdrv, bytes_to_read, buffer)) { + if (read_from_netchan_close_on_error(netchan, bytes_to_read, buffer)) { return -1; // Read failed. } @@ -571,7 +571,7 @@ static int handle_tagged_message(netdrv_t netdrv, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_netdrv_close_on_error(netdrv, length, message_contents)) { + if (read_from_netchan_close_on_error(netchan, length, message_contents)) { #ifdef FEDERATED_DECENTRALIZED _lf_decrement_tag_barrier_locked(env); #endif @@ -640,11 +640,11 @@ static int handle_tagged_message(netdrv_t netdrv, int fed_id) { if (lf_tag_compare(env->current_tag, env->stop_tag) >= 0 && env->execution_started) { lf_print_error("Received message too late. Already at stop tag.\n" " Current tag is " PRINTF_TAG " and intended tag is " PRINTF_TAG ".\n" - " Discarding message and closing the network driver.", + " Discarding message and closing the network channel.", env->current_tag.time - start_time, env->current_tag.microstep, intended_tag.time - start_time, intended_tag.microstep); - // Close network driver, reading any incoming data and discarding it. - close_inbound_netdrv(fed_id); + // Close network channel, reading any incoming data and discarding it. + close_inbound_netchan(fed_id); LF_MUTEX_UNLOCK(&env->mutex); return -1; } else { @@ -675,14 +675,14 @@ static int handle_tagged_message(netdrv_t netdrv, int fed_id) { * This just sets the last known status tag of the port specified * in the message. * - * @param netdrv Pointer to the network driver to read the message from + * @param netchan Pointer to the network channel to read the message from * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure to complete the read. */ -static int handle_port_absent_message(netdrv_t netdrv, int fed_id) { +static int handle_port_absent_message(netchan_t netchan, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_netdrv_close_on_error(netdrv, bytes_to_read, buffer)) { + if (read_from_netchan_close_on_error(netchan, bytes_to_read, buffer)) { return -1; } @@ -719,7 +719,7 @@ static int handle_port_absent_message(netdrv_t netdrv, int fed_id) { * peer federate and calls the appropriate handling function for * each message type. If an error occurs or an EOF is received * from the peer, then this procedure sets the corresponding - * network driver in _fed.netdrvs_for_inbound_p2p_connections + * network channel in _fed.netchans_for_inbound_p2p_connections * to -1 and returns, terminating the thread. * @param _args The remote federate ID (cast to void*). * @param fed_id_ptr A pointer to a uint16_t containing federate ID being listened to. @@ -731,7 +731,7 @@ static void* listen_to_federates(void* _args) { LF_PRINT_LOG("Listening to federate %d.", fed_id); - netdrv_t netdrv = _fed.netdrvs_for_inbound_p2p_connections[fed_id]; + netchan_t netchan = _fed.netchans_for_inbound_p2p_connections[fed_id]; // Buffer for incoming messages. // This does not constrain the message size @@ -740,44 +740,44 @@ static void* listen_to_federates(void* _args) { // Listen for messages from the federate. while (1) { - bool netdrv_closed = false; + bool netchan_closed = false; // Read one byte to get the message type. LF_PRINT_DEBUG("Waiting for a P2P message."); bool bad_message = false; - if (read_from_netdrv_close_on_error(netdrv, 1, buffer)) { - // Network driver has been closed. - lf_print("Network driver from federate %d is closed.", fed_id); + if (read_from_netchan_close_on_error(netchan, 1, buffer)) { + // network channel has been closed. + lf_print("network channel from federate %d is closed.", fed_id); // Stop listening to this federate. - netdrv_closed = true; + netchan_closed = true; } else { LF_PRINT_DEBUG("Received a P2P message of type %d.", buffer[0]); switch (buffer[0]) { case MSG_TYPE_P2P_MESSAGE: LF_PRINT_LOG("Received untimed message from federate %d.", fed_id); - if (handle_message(netdrv, fed_id)) { + if (handle_message(netchan, fed_id)) { // Failed to complete the reading of a message on a physical connection. lf_print_warning("Failed to complete reading of message on physical connection."); - netdrv_closed = true; + netchan_closed = true; } break; case MSG_TYPE_P2P_TAGGED_MESSAGE: LF_PRINT_LOG("Received tagged message from federate %d.", fed_id); - if (handle_tagged_message(netdrv, fed_id)) { + if (handle_tagged_message(netchan, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and - // it is not a fatal error if the network driver is closed before the whole message is read. + // it is not a fatal error if the network channel is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); - netdrv_closed = true; + netchan_closed = true; } break; case MSG_TYPE_PORT_ABSENT: LF_PRINT_LOG("Received port absent message from federate %d.", fed_id); - if (handle_port_absent_message(netdrv, fed_id)) { + if (handle_port_absent_message(netchan, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and - // it is not a fatal error if the network driver is closed before the whole message is read. + // it is not a fatal error if the network channel is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); - netdrv_closed = true; + netchan_closed = true; } break; default: @@ -785,13 +785,13 @@ static void* listen_to_federates(void* _args) { } } if (bad_message) { - lf_print_error("Received erroneous message type: %d. Closing the network driver.", buffer[0]); + lf_print_error("Received erroneous message type: %d. Closing the network channel.", buffer[0]); // Trace the event when tracing is enabled tracepoint_federate_from_federate(receive_UNIDENTIFIED, _lf_my_fed_id, fed_id, NULL); break; // while loop } - if (netdrv_closed) { - // For decentralized execution, once this network driver is closed, we + if (netchan_closed) { + // For decentralized execution, once this network channel is closed, we // update last known tags of all ports connected to the specified federate to FOREVER_TAG, // which would eliminate the need to wait for STAA to assume an input is absent. mark_inputs_known_absent(fed_id); @@ -803,29 +803,29 @@ static void* listen_to_federates(void* _args) { } /** - * Close the network driver that sends outgoing messages to the - * specified federate ID. This function acquires the lf_outbound_netdrv_mutex mutex lock + * Close the network channel that sends outgoing messages to the + * specified federate ID. This function acquires the lf_outbound_netchan_mutex mutex lock * if _lf_normal_termination is true and otherwise proceeds without the lock. * @param fed_id The ID of the peer federate receiving messages from this * federate, or -1 if the RTI (centralized coordination). */ -static void close_outbound_netdrv(int fed_id) { +static void close_outbound_netchan(int fed_id) { assert(fed_id >= 0 && fed_id < NUMBER_OF_FEDERATES); // Close outbound connections, in case they have not closed themselves. // This will result in EOF being sent to the remote federate, except for - // abnormal termination, in which case it will just close the network driver. + // abnormal termination, in which case it will just close the network channel. if (_lf_normal_termination) { - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - if (_fed.netdrvs_for_outbound_p2p_connections[fed_id] != NULL) { - // Close the network driver by sending a FIN packet indicating that no further writes + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + if (_fed.netchans_for_outbound_p2p_connections[fed_id] != NULL) { + // Close the network channel by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. - shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], true); - _fed.netdrvs_for_outbound_p2p_connections[fed_id] = NULL; + shutdown_netchan(_fed.netchans_for_outbound_p2p_connections[fed_id], true); + _fed.netchans_for_outbound_p2p_connections[fed_id] = NULL; } - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); } else { - shutdown_netdrv(_fed.netdrvs_for_outbound_p2p_connections[fed_id], false); - _fed.netdrvs_for_outbound_p2p_connections[fed_id] = NULL; + shutdown_netchan(_fed.netchans_for_outbound_p2p_connections[fed_id], false); + _fed.netchans_for_outbound_p2p_connections[fed_id] = NULL; } } @@ -847,14 +847,14 @@ static int perform_hmac_authentication() { RAND_bytes(fed_nonce, NONCE_LENGTH); memcpy(&fed_hello_buf[1 + fed_id_length], fed_nonce, NONCE_LENGTH); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, message_length, fed_hello_buf, NULL, "Failed to write nonce."); + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, message_length, fed_hello_buf, NULL, "Failed to write nonce."); // Check HMAC of received FED_RESPONSE message. unsigned int hmac_length = SHA256_HMAC_LENGTH; size_t federation_id_length = strnlen(federation_metadata.federation_id, 255); unsigned char received[1 + NONCE_LENGTH + hmac_length]; - if (read_from_netdrv_close_on_error(_fed.netdrv_to_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { + if (read_from_netchan_close_on_error(_fed.netchan_to_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { lf_print_warning("Failed to read RTI response."); return -1; } @@ -888,7 +888,7 @@ static int perform_hmac_authentication() { response[1] = HMAC_DOES_NOT_MATCH; // Ignore errors on writing back. - write_to_netdrv(_fed.netdrv_to_RTI, 2, response); + write_to_netchan(_fed.netchan_to_RTI, 2, response); return -1; } else { LF_PRINT_LOG("HMAC verified."); @@ -902,7 +902,7 @@ static int perform_hmac_authentication() { HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH, &sender[1], &hmac_length); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, 1 + hmac_length, sender, NULL, "Failed to write fed response."); + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, 1 + hmac_length, sender, NULL, "Failed to write fed response."); } return 0; } @@ -921,12 +921,12 @@ static instant_t get_start_time_from_rti(instant_t my_physical_time) { // Send the timestamp marker first. send_time(MSG_TYPE_TIMESTAMP, my_physical_time); - // Read bytes from the network driver. We need 9 bytes. + // Read bytes from the network channel. We need 9 bytes. // Buffer for message ID plus timestamp. size_t buffer_length = 1 + sizeof(instant_t); unsigned char buffer[buffer_length]; - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, buffer_length, buffer, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, buffer_length, buffer, NULL, "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); LF_PRINT_DEBUG("Read 9 bytes."); @@ -970,7 +970,7 @@ static void handle_tag_advance_grant(void) { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, "Failed to read tag advance grant from RTI."); tag_t TAG = extract_tag(buffer); @@ -1211,7 +1211,7 @@ static void handle_provisional_tag_advance_grant() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, "Failed to read provisional tag advance grant from RTI."); tag_t PTAG = extract_tag(buffer); @@ -1301,7 +1301,7 @@ static void handle_stop_granted_message() { size_t bytes_to_read = MSG_TYPE_STOP_GRANTED_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, "Failed to read stop granted from RTI."); tag_t received_stop_tag = extract_tag(buffer); @@ -1345,7 +1345,7 @@ static void handle_stop_granted_message() { static void handle_stop_request_message() { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, "Failed to read stop request from RTI."); tag_t tag_to_stop = extract_tag(buffer); @@ -1371,10 +1371,10 @@ static void handle_stop_request_message() { // or we have previously sent a stop request to the RTI, // then we have already blocked tag advance in enclaves. // Do not do this twice. The record of whether the first has occurred - // is guarded by the outbound network driver mutex. + // is guarded by the outbound network channel mutex. // The second is guarded by the global mutex. // Note that the RTI should not send stop requests more than once to federates. - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); if (_fed.received_stop_request_from_rti) { LF_PRINT_LOG("Redundant MSG_TYPE_STOP_REQUEST from RTI. Ignoring it."); already_blocked = true; @@ -1383,7 +1383,7 @@ static void handle_stop_request_message() { // prevent lf_request_stop from sending. _fed.received_stop_request_from_rti = true; } - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); if (already_blocked) { // Either we have sent a stop request to the RTI ourselves, @@ -1417,11 +1417,11 @@ static void handle_stop_request_message() { tracepoint_federate_to_rti(send_STOP_REQ_REP, _lf_my_fed_id, &tag_to_stop); // Send the current logical time to the RTI. - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, - &lf_outbound_netdrv_mutex, + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, + &lf_outbound_netchan_mutex, "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); LF_PRINT_DEBUG("Sent MSG_TYPE_STOP_REQUEST_REPLY to RTI with tag " PRINTF_TAG, tag_to_stop.time, tag_to_stop.microstep); @@ -1433,7 +1433,7 @@ static void handle_stop_request_message() { static void handle_downstream_next_event_tag() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_read, buffer, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, "Failed to read downstream next event tag from RTI."); tag_t DNET = extract_tag(buffer); @@ -1464,10 +1464,10 @@ static void send_resign_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_RESIGN; - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netdrv_mutex, + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netchan_mutex, "Failed to send MSG_TYPE_RESIGN."); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); LF_PRINT_LOG("Resigned."); } @@ -1478,7 +1478,7 @@ static void send_failed_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_FAILED; - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, bytes_to_write, &(buffer[0]), NULL, + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, &(buffer[0]), NULL, "Failed to send MSG_TYPE_FAILED."); LF_PRINT_LOG("Failed."); } @@ -1492,11 +1492,11 @@ static void send_failed_signal() { static void handle_rti_failed_message(void) { exit(1); } /** - * Thread that listens for network driver inputs from the RTI. + * Thread that listens for network channel inputs from the RTI. * When messages arrive, this calls the appropriate handler. * @param args Ignored */ -static void* listen_to_rti_netdrv(void* args) { +static void* listen_to_rti_netchan(void* args) { (void)args; initialize_lf_thread_id(); // Buffer for incoming messages. @@ -1506,27 +1506,27 @@ static void* listen_to_rti_netdrv(void* args) { // Listen for messages from the federate. while (1) { - // Check whether the RTI network driver is still valid - if (_fed.netdrv_to_RTI == NULL) { - lf_print_warning("Network driver to the RTI unexpectedly closed."); + // Check whether the RTI network channel is still valid + if (_fed.netchan_to_RTI == NULL) { + lf_print_warning("network channel to the RTI unexpectedly closed."); return NULL; } // Read one byte to get the message type. // This will exit if the read fails. - int read_failed = read_from_netdrv(_fed.netdrv_to_RTI, 1, buffer); + int read_failed = read_from_netchan(_fed.netchan_to_RTI, 1, buffer); if (read_failed < 0) { lf_print_error("Connection to the RTI was closed by the RTI with an error. Considering this a soft error."); - shutdown_netdrv(_fed.netdrv_to_RTI, false); + shutdown_netchan(_fed.netchan_to_RTI, false); return NULL; } else if (read_failed > 0) { // EOF received. lf_print("Connection to the RTI closed with an EOF."); - shutdown_netdrv(_fed.netdrv_to_RTI, false); + shutdown_netchan(_fed.netchan_to_RTI, false); return NULL; } switch (buffer[0]) { case MSG_TYPE_TAGGED_MESSAGE: - if (handle_tagged_message(_fed.netdrv_to_RTI, -1)) { + if (handle_tagged_message(_fed.netchan_to_RTI, -1)) { // Failures to complete the read of messages from the RTI are fatal. lf_print_error_and_exit("Failed to complete the reading of a message from the RTI."); } @@ -1544,7 +1544,7 @@ static void* listen_to_rti_netdrv(void* args) { handle_stop_granted_message(); break; case MSG_TYPE_PORT_ABSENT: - if (handle_port_absent_message(_fed.netdrv_to_RTI, -1)) { + if (handle_port_absent_message(_fed.netchan_to_RTI, -1)) { // Failures to complete the read of absent messages from the RTI are fatal. lf_print_error_and_exit("Failed to complete the reading of an absent message from the RTI."); } @@ -1622,7 +1622,7 @@ static bool bounded_NET(tag_t* tag) { // An empty version of this function is code generated for unfederated execution. /** - * Close network drivers used to communicate with other federates, if they are open, + * Close network channels used to communicate with other federates, if they are open, * and send a MSG_TYPE_RESIGN message to the RTI. This implements the function * defined in reactor.h. For unfederated execution, the code generator * generates an empty implementation. @@ -1633,7 +1633,7 @@ void lf_terminate_execution(environment_t* env) { // For an abnormal termination (e.g. a SIGINT), we need to send a // MSG_TYPE_FAILED message to the RTI, but we should not acquire a mutex. - if (_fed.netdrv_to_RTI != NULL) { + if (_fed.netchan_to_RTI != NULL) { if (_lf_normal_termination) { tracepoint_federate_to_rti(send_RESIGN, _lf_my_fed_id, &env->current_tag); send_resign_signal(); @@ -1643,28 +1643,28 @@ void lf_terminate_execution(environment_t* env) { } } - LF_PRINT_DEBUG("Closing incoming P2P network drivers."); - // Close any incoming P2P network drivers that are still open. + LF_PRINT_DEBUG("Closing incoming P2P network channels."); + // Close any incoming P2P network channels that are still open. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { - close_inbound_netdrv(i); - // Ignore errors. Mark the network driver closed. - _fed.netdrvs_for_inbound_p2p_connections[i] = NULL; + close_inbound_netchan(i); + // Ignore errors. Mark the network channel closed. + _fed.netchans_for_inbound_p2p_connections[i] = NULL; } // Check for all outgoing physical connections in - // _fed.netdrvs_for_outbound_p2p_connections and - // if the network driver ID is not NULL, the connection is still open. - // Send an EOF by closing the network driver here. + // _fed.netchans_for_outbound_p2p_connections and + // if the network channel ID is not NULL, the connection is still open. + // Send an EOF by closing the network channel here. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { // Close outbound connections, in case they have not closed themselves. // This will result in EOF being sent to the remote federate, except for - // abnormal termination, in which case it will just close the network driver. - close_outbound_netdrv(i); + // abnormal termination, in which case it will just close the network channel. + close_outbound_netchan(i); } - LF_PRINT_DEBUG("Waiting for inbound p2p network driver listener threads."); - // Wait for each inbound network driver listener thread to close. + LF_PRINT_DEBUG("Waiting for inbound p2p network channel listener threads."); + // Wait for each inbound network channel listener thread to close. if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_netdriv_listeners != NULL) { LF_PRINT_LOG("Waiting for %zu threads listening for incoming messages to exit.", _fed.number_of_inbound_p2p_connections); @@ -1674,9 +1674,9 @@ void lf_terminate_execution(environment_t* env) { } } - LF_PRINT_DEBUG("Waiting for RTI's network driver listener threads."); + LF_PRINT_DEBUG("Waiting for RTI's network channel listener threads."); // Wait for the thread listening for messages from the RTI to close. - lf_thread_join(_fed.RTI_netdrv_listener, NULL); + lf_thread_join(_fed.RTI_netchan_listener, NULL); // For abnormal termination, there is no need to free memory. if (_lf_normal_termination) { @@ -1710,13 +1710,13 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_QR, _lf_my_fed_id, NULL); - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netdrv_mutex, + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netchan_mutex, "Failed to send address query for federate %d to RTI.", remote_federate_id); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); // Read RTI's response. - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, sizeof(int32_t) + 1, buffer, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(int32_t) + 1, buffer, NULL, "Failed to read the requested port number for federate %d from RTI.", remote_federate_id); @@ -1730,7 +1730,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } port = extract_int32(&buffer[1]); - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, NULL, "Failed to read the IP address for federate %d from RTI.", remote_federate_id); // A reply of -1 for the port means that the RTI does not know @@ -1752,14 +1752,14 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { char hostname[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &host_ip_addr, hostname, INET_ADDRSTRLEN); - // Create a network driver. - netdrv_t netdrv = initialize_netdrv(); - // Set the received host name and port to the network driver. - set_server_port(netdrv, uport); - set_server_hostname(netdrv, hostname); - // Create the client network driver. - create_client(netdrv); - if (connect_to_netdrv(netdrv) < 0) { + // Create a network channel. + netchan_t netchan = initialize_netchan(); + // Set the received host name and port to the network channel. + set_server_port(netchan, uport); + set_server_hostname(netchan, hostname); + // Create the client network channel. + create_client(netchan); + if (connect_to_netchan(netchan) < 0) { lf_print_error_and_exit("Failed to connect to federate."); } @@ -1795,18 +1795,18 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_FED_ID, _lf_my_fed_id, remote_federate_id, NULL); - // No need for a mutex because we have the only handle on the network driver. - write_to_netdrv_fail_on_error(netdrv, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", + // No need for a mutex because we have the only handle on the network channel. + write_to_netchan_fail_on_error(netchan, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", remote_federate_id); - write_to_netdrv_fail_on_error(netdrv, federation_id_length, (unsigned char*)federation_metadata.federation_id, NULL, + write_to_netchan_fail_on_error(netchan, federation_id_length, (unsigned char*)federation_metadata.federation_id, NULL, "Failed to send federation id to federate %d.", remote_federate_id); - read_from_netdrv_fail_on_error(netdrv, 1, (unsigned char*)buffer, NULL, + read_from_netchan_fail_on_error(netchan, 1, (unsigned char*)buffer, NULL, "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", remote_federate_id); if (buffer[0] != MSG_TYPE_ACK) { // Get the error code. - read_from_netdrv_fail_on_error(netdrv, 1, (unsigned char*)buffer, NULL, + read_from_netchan_fail_on_error(netchan, 1, (unsigned char*)buffer, NULL, "Failed to read error code from federate %d in response to sending fed_id.", remote_federate_id); lf_print_error("Received MSG_TYPE_REJECT message from remote federate (%d).", buffer[0]); @@ -1824,8 +1824,8 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } } // Once we set this variable, then all future calls to close() on this - // network driver should reset it to NULL within a critical section. - _fed.netdrvs_for_outbound_p2p_connections[remote_federate_id] = netdrv; + // network channel should reset it to NULL within a critical section. + _fed.netchans_for_outbound_p2p_connections[remote_federate_id] = netchan; } void lf_connect_to_rti(const char* hostname, int port) { @@ -1835,15 +1835,15 @@ void lf_connect_to_rti(const char* hostname, int port) { hostname = federation_metadata.rti_host ? federation_metadata.rti_host : hostname; port = federation_metadata.rti_port >= 0 ? federation_metadata.rti_port : port; - // Create a network driver. - _fed.netdrv_to_RTI = initialize_netdrv(); - // Set the user specified host name and port to the network driver. - set_server_port(_fed.netdrv_to_RTI, port); - set_server_hostname(_fed.netdrv_to_RTI, hostname); + // Create a network channel. + _fed.netchan_to_RTI = initialize_netchan(); + // Set the user specified host name and port to the network channel. + set_server_port(_fed.netchan_to_RTI, port); + set_server_hostname(_fed.netchan_to_RTI, hostname); - // Create the client network driver. - create_client(_fed.netdrv_to_RTI); - if (connect_to_netdrv(_fed.netdrv_to_RTI) < 0) { + // Create the client network channel. + create_client(_fed.netchan_to_RTI); + if (connect_to_netchan(_fed.netchan_to_RTI) < 0) { lf_print_error_and_exit("Failed to connect to RTI."); } @@ -1884,13 +1884,13 @@ void lf_connect_to_rti(const char* hostname, int port) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_FED_ID, _lf_my_fed_id, NULL); - // No need for a mutex here because no other threads are writing to this network driver. - if (write_to_netdrv(_fed.netdrv_to_RTI, 2 + sizeof(uint16_t), buffer)) { + // No need for a mutex here because no other threads are writing to this network channel. + if (write_to_netchan(_fed.netchan_to_RTI, 2 + sizeof(uint16_t), buffer)) { continue; // Try again, possibly on a new port. } // Next send the federation ID itself. - if (write_to_netdrv(_fed.netdrv_to_RTI, federation_id_length, (unsigned char*)federation_metadata.federation_id)) { + if (write_to_netchan(_fed.netchan_to_RTI, federation_id_length, (unsigned char*)federation_metadata.federation_id)) { continue; // Try again. } @@ -1902,7 +1902,7 @@ void lf_connect_to_rti(const char* hostname, int port) { LF_PRINT_DEBUG("Waiting for response to federation ID from the RTI."); - if (read_from_netdrv(_fed.netdrv_to_RTI, 1, &response)) { + if (read_from_netchan(_fed.netchan_to_RTI, 1, &response)) { continue; // Try again. } if (response == MSG_TYPE_REJECT) { @@ -1910,7 +1910,7 @@ void lf_connect_to_rti(const char* hostname, int port) { tracepoint_federate_from_rti(receive_REJECT, _lf_my_fed_id, NULL); // Read one more byte to determine the cause of rejection. unsigned char cause; - read_from_netdrv_fail_on_error(_fed.netdrv_to_RTI, 1, &cause, NULL, + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, 1, &cause, NULL, "Failed to read the cause of rejection by the RTI."); if (cause == FEDERATION_ID_DOES_NOT_MATCH || cause == WRONG_SERVER) { lf_print_warning("Connected to the wrong RTI. Will try again"); @@ -1934,7 +1934,7 @@ void lf_connect_to_rti(const char* hostname, int port) { // about connections between this federate and other federates // where messages are routed through the RTI. // @see MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h - lf_send_neighbor_structure_to_RTI(_fed.netdrv_to_RTI); + lf_send_neighbor_structure_to_RTI(_fed.netchan_to_RTI); uint16_t udp_port = setup_clock_synchronization_with_rti(); @@ -1942,22 +1942,22 @@ void lf_connect_to_rti(const char* hostname, int port) { unsigned char UDP_port_number[1 + sizeof(uint16_t)]; UDP_port_number[0] = MSG_TYPE_UDP_PORT; encode_uint16(udp_port, &(UDP_port_number[1])); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, "Failed to send the UDP port number to the RTI."); } void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); - netdrv_t server_netdrv = initialize_netdrv(); - set_my_port(server_netdrv, specified_port); + netchan_t server_netchan = initialize_netchan(); + set_my_port(server_netchan, specified_port); - if (create_server(server_netdrv, false)) { + if (create_server(server_netchan, false)) { lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); }; - _fed.server_netdrv = server_netdrv; + _fed.server_netchan = server_netchan; // Get the final server port to send to the RTI on an MSG_TYPE_ADDRESS_ADVERTISEMENT message. - int32_t server_port = get_my_port(server_netdrv); + int32_t server_port = get_my_port(server_netchan); LF_PRINT_LOG("Server for communicating with other federates started using port %d.", server_port); @@ -1970,8 +1970,8 @@ void lf_create_server(int specified_port) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_AD, _lf_my_fed_id, NULL); - // No need for a mutex because we have the only handle on this network driver. - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, + // No need for a mutex because we have the only handle on this network channel. + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, "Failed to send address advertisement."); LF_PRINT_DEBUG("Sent port %d to the RTI.", server_port); @@ -2008,18 +2008,18 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { _fed.inbound_netdriv_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); while (received_federates < _fed.number_of_inbound_p2p_connections && !_lf_termination_executed) { // Wait for an incoming connection request. - netdrv_t netdrv = accept_netdrv(_fed.server_netdrv, _fed.netdrv_to_RTI); - if (netdrv == NULL) { - lf_print_warning("Federate failed to accept the network driver."); + netchan_t netchan = accept_netchan(_fed.server_netchan, _fed.netchan_to_RTI); + if (netchan == NULL) { + lf_print_warning("Federate failed to accept the network channel."); return NULL; } LF_PRINT_LOG("Accepted new connection from remote federate."); size_t header_length = 1 + sizeof(uint16_t) + 1; unsigned char buffer[header_length]; - int read_failed = read_from_netdrv(netdrv, header_length, (unsigned char*)&buffer); + int read_failed = read_from_netchan(netchan, header_length, (unsigned char*)&buffer); if (read_failed || buffer[0] != MSG_TYPE_P2P_SENDING_FED_ID) { - lf_print_warning("Federate received invalid first message on P2P network driver. Closing network driver."); + lf_print_warning("Federate received invalid first message on P2P network channel. Closing network channel."); if (read_failed == 0) { // Wrong message received. unsigned char response[2]; @@ -2028,19 +2028,19 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_netdrv(netdrv, 2, response); + write_to_netchan(netchan, 2, response); } - shutdown_netdrv(netdrv, false); + shutdown_netchan(netchan, false); continue; } // Get the federation ID and check it. unsigned char federation_id_length = buffer[header_length - 1]; char remote_federation_id[federation_id_length]; - read_failed = read_from_netdrv(netdrv, federation_id_length, (unsigned char*)remote_federation_id); + read_failed = read_from_netchan(netchan, federation_id_length, (unsigned char*)remote_federation_id); if (read_failed || (strncmp(federation_metadata.federation_id, remote_federation_id, strnlen(federation_metadata.federation_id, 255)) != 0)) { - lf_print_warning("Received invalid federation ID. Closing network driver."); + lf_print_warning("Received invalid federation ID. Closing network channel."); if (read_failed == 0) { unsigned char response[2]; response[0] = MSG_TYPE_REJECT; @@ -2048,9 +2048,9 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_netdrv(netdrv, 2, response); + write_to_netchan(netchan, 2, response); } - shutdown_netdrv(netdrv, false); + shutdown_netchan(netchan, false); continue; } @@ -2061,12 +2061,12 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(receive_FED_ID, _lf_my_fed_id, remote_fed_id, NULL); - // Once we record the network driver here, all future calls to close() on - // the network driver should be done while holding the netdrv_mutex, and this array + // Once we record the network channel here, all future calls to close() on + // the network channel should be done while holding the netchan_mutex, and this array // element should be reset to NULL during that critical section. // Otherwise, there can be race condition where, during termination, - // two threads attempt to simultaneously close the network driver. - _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = netdrv; + // two threads attempt to simultaneously close the network channel. + _fed.netchans_for_inbound_p2p_connections[remote_fed_id] = netchan; // Send an MSG_TYPE_ACK message. unsigned char response = MSG_TYPE_ACK; @@ -2074,11 +2074,11 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - write_to_netdrv_fail_on_error(_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, - &lf_outbound_netdrv_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + write_to_netchan_fail_on_error(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, + &lf_outbound_netchan_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); // Start a thread to listen for incoming messages from other federates. // The fed_id is a uint16_t, which we assume can be safely cast to and from void*. @@ -2086,12 +2086,12 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { int result = lf_thread_create(&_fed.inbound_netdriv_listeners[received_federates], listen_to_federates, fed_id_arg); if (result != 0) { // Failed to create a listening thread. - LF_MUTEX_LOCK(&netdrv_mutex); - if (_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] != NULL) { - shutdown_netdrv(_fed.netdrvs_for_inbound_p2p_connections[remote_fed_id], false); - _fed.netdrvs_for_inbound_p2p_connections[remote_fed_id] = NULL; + LF_MUTEX_LOCK(&netchan_mutex); + if (_fed.netchans_for_inbound_p2p_connections[remote_fed_id] != NULL) { + shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], false); + _fed.netchans_for_inbound_p2p_connections[remote_fed_id] = NULL; } - LF_MUTEX_UNLOCK(&netdrv_mutex); + LF_MUTEX_UNLOCK(&netchan_mutex); lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", result); } @@ -2196,23 +2196,23 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa const int header_length = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); // Use a mutex lock to prevent multiple threads from simultaneously sending. - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - netdrv_t netdrv = _fed.netdrvs_for_outbound_p2p_connections[federate]; + netchan_t netchan = _fed.netchans_for_outbound_p2p_connections[federate]; // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_P2P_MSG, _lf_my_fed_id, federate, NULL); - int result = write_to_netdrv_close_on_error(netdrv, header_length, header_buffer); + int result = write_to_netchan_close_on_error(netchan, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_netdrv_close_on_error(netdrv, length, message); + result = write_to_netchan_close_on_error(netchan, length, message); } if (result != 0) { // Message did not send. Since this is used for physical connections, this is not critical. lf_print_warning("Failed to send message to %s. Dropping the message.", next_destination_str); } - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); return result; } @@ -2398,25 +2398,25 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d #ifdef FEDERATED_CENTRALIZED // Send the absent message through the RTI - netdrv_t netdrv = _fed.netdrv_to_RTI; + netchan_t netchan = _fed.netchan_to_RTI; #else // Send the absent message directly to the federate - netdrv_t netdrv = _fed.netdrvs_for_outbound_p2p_connections[fed_ID]; + netchan_t netchan = _fed.netchans_for_outbound_p2p_connections[fed_ID]; #endif - if (netdrv == _fed.netdrv_to_RTI) { + if (netchan == _fed.netchan_to_RTI) { tracepoint_federate_to_rti(send_PORT_ABS, _lf_my_fed_id, ¤t_message_intended_tag); } else { tracepoint_federate_to_federate(send_PORT_ABS, _lf_my_fed_id, fed_ID, ¤t_message_intended_tag); } - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); - int result = write_to_netdrv_close_on_error(netdrv, message_length, buffer); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + int result = write_to_netchan_close_on_error(netchan, message_length, buffer); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); if (result != 0) { // Write failed. Response depends on whether coordination is centralized. - if (netdrv == _fed.netdrv_to_RTI) { + if (netchan == _fed.netchan_to_RTI) { // Centralized coordination. This is a critical error. lf_print_error_system_failure("Failed to send port absent message for port %hu to federate %hu.", port_ID, fed_ID); @@ -2435,29 +2435,29 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { stop_tag.microstep++; ENCODE_STOP_REQUEST(buffer, stop_tag.time, stop_tag.microstep); - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); // Do not send a stop request if a stop request has been previously received from the RTI. if (!_fed.received_stop_request_from_rti) { LF_PRINT_LOG("Sending to RTI a MSG_TYPE_STOP_REQUEST message with tag " PRINTF_TAG ".", stop_tag.time - start_time, stop_tag.microstep); - if (_fed.netdrv_to_RTI == NULL) { + if (_fed.netchan_to_RTI == NULL) { lf_print_warning("RTI is no longer connected. Dropping message."); - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); return -1; } // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_STOP_REQ, _lf_my_fed_id, &stop_tag); - write_to_netdrv_fail_on_error(_fed.netdrv_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_netdrv_mutex, + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_netchan_mutex, "Failed to send stop time " PRINTF_TIME " to the RTI.", stop_tag.time - start_time); // Treat this sending as equivalent to having received a stop request from the RTI. _fed.received_stop_request_from_rti = true; - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); return 0; } else { - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); return 1; } } @@ -2510,14 +2510,14 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int current_message_intended_tag.microstep, next_destination_str); // Use a mutex lock to prevent multiple threads from simultaneously sending. - LF_MUTEX_LOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - netdrv_t netdrv; + netchan_t netchan; if (message_type == MSG_TYPE_P2P_TAGGED_MESSAGE) { - netdrv = _fed.netdrvs_for_outbound_p2p_connections[federate]; + netchan = _fed.netchans_for_outbound_p2p_connections[federate]; tracepoint_federate_to_federate(send_P2P_TAGGED_MSG, _lf_my_fed_id, federate, ¤t_message_intended_tag); } else { - netdrv = _fed.netdrv_to_RTI; + netchan = _fed.netchan_to_RTI; tracepoint_federate_to_rti(send_TAGGED_MSG, _lf_my_fed_id, ¤t_message_intended_tag); } @@ -2525,10 +2525,10 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int _fed.last_DNET = current_message_intended_tag; } - int result = write_to_netdrv_close_on_error(netdrv, header_length, header_buffer); + int result = write_to_netchan_close_on_error(netchan, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_netdrv_close_on_error(netdrv, length, message); + result = write_to_netchan_close_on_error(netchan, length, message); } if (result != 0) { // Message did not send. Handling depends on message type. @@ -2539,7 +2539,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int next_destination_str, errno, strerror(errno)); } } - LF_MUTEX_UNLOCK(&lf_outbound_netdrv_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); return result; } @@ -2577,7 +2577,7 @@ void lf_synchronize_with_other_federates(void) { // @note Up until this point, the federate has been listening for messages // from the RTI in a sequential manner in the main thread. From now on, a // separate thread is created to allow for asynchronous communication. - lf_thread_create(&_fed.RTI_netdrv_listener, listen_to_rti_netdrv, NULL); + lf_thread_create(&_fed.RTI_netchan_listener, listen_to_rti_netchan, NULL); lf_thread_t thread_id; if (create_clock_sync_thread(&thread_id)) { lf_print_warning("Failed to create thread to handle clock synchronization."); From 7f3ce7b4988fb3281c3c2f936e7b5735fef670bf Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 24 Feb 2025 13:10:38 -0700 Subject: [PATCH 131/167] Change main.c and rti_remote.c name to netchan --- core/federated/RTI/main.c | 2 +- core/federated/RTI/rti_remote.c | 230 ++++++++++++++++---------------- 2 files changed, 116 insertions(+), 116 deletions(-) diff --git a/core/federated/RTI/main.c b/core/federated/RTI/main.c index b7507615c..8c2869dc4 100644 --- a/core/federated/RTI/main.c +++ b/core/federated/RTI/main.c @@ -80,7 +80,7 @@ static void send_failed_signal(federate_info_t* fed) { if (rti.base.tracing_enabled) { tracepoint_rti_to_federate(send_FAILED, fed->enclave.id, NULL); } - int failed = write_to_netdrv(fed->fed_netdrv, bytes_to_write, &(buffer[0])); + int failed = write_to_netchan(fed->fed_netchan, bytes_to_write, &(buffer[0])); if (failed == 0) { LF_PRINT_LOG("RTI has sent failed signal to federate %d due to abnormal termination.", fed->enclave.id); } else { diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 296774338..bbf5ec5e1 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -73,9 +73,9 @@ void notify_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_TAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the network driver might close, causing the following write_to_netdrv + // function. During this call, the network channel might close, causing the following write_to_netchan // to fail. Consider a failure here a soft failure and update the federate's status. - if (write_to_netdrv(((federate_info_t*)e)->fed_netdrv, message_length, buffer)) { + if (write_to_netchan(((federate_info_t*)e)->fed_netchan, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -106,9 +106,9 @@ void notify_provisional_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_PTAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the network driver might close, causing the following write_to_netdrv + // function. During this call, the network channel might close, causing the following write_to_netchan // to fail. Consider a failure here a soft failure and update the federate's status. - if (write_to_netdrv(((federate_info_t*)e)->fed_netdrv, message_length, buffer)) { + if (write_to_netchan(((federate_info_t*)e)->fed_netchan, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -165,7 +165,7 @@ void notify_downstream_next_event_tag(scheduling_node_t* e, tag_t tag) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_DNET, e->id, &tag); } - if (write_to_netdrv(((federate_info_t*)e)->fed_netdrv, message_length, buffer)) { + if (write_to_netchan(((federate_info_t*)e)->fed_netchan, message_length, buffer)) { lf_print_error("RTI failed to send downstream next event tag to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -187,7 +187,7 @@ void update_federate_next_event_tag_locked(uint16_t federate_id, tag_t next_even void handle_port_absent_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t message_size = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(int64_t) + sizeof(uint32_t); - read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, message_size, &(buffer[1]), NULL, + read_from_netchan_fail_on_error(sending_federate->fed_netchan, message_size, &(buffer[1]), NULL, " RTI failed to read port absent message from federate %u.", sending_federate->enclave.id); @@ -200,7 +200,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char } // Need to acquire the mutex lock to ensure that the thread handling - // messages coming from the network driver connected to the destination does not + // messages coming from the network channel connected to the destination does not // issue a TAG before this message has been forwarded. LF_MUTEX_LOCK(&rti_mutex); @@ -236,7 +236,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char } // Forward the message. - write_to_netdrv_fail_on_error(fed->fed_netdrv, message_size + 1, buffer, &rti_mutex, + write_to_netchan_fail_on_error(fed->fed_netchan, message_size + 1, buffer, &rti_mutex, "RTI failed to forward message to federate %d.", federate_id); LF_MUTEX_UNLOCK(&rti_mutex); @@ -245,7 +245,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char void handle_timed_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t header_size = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(int64_t) + sizeof(uint32_t); // Read the header, minus the first byte which has already been read. - read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, header_size - 1, &(buffer[1]), NULL, + read_from_netchan_fail_on_error(sending_federate->fed_netchan, header_size - 1, &(buffer[1]), NULL, "RTI failed to read the timed message header from remote federate."); // Extract the header information. of the sender uint16_t reactor_port_id; @@ -274,7 +274,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff sending_federate->enclave.id, federate_id, reactor_port_id, intended_tag.time - lf_time_start(), intended_tag.microstep); - read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, bytes_to_read, &(buffer[header_size]), NULL, + read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, &(buffer[header_size]), NULL, "RTI failed to read timed message from federate %d.", federate_id); size_t bytes_read = bytes_to_read + header_size; // Following only works for string messages. @@ -285,12 +285,12 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff } // Need to acquire the mutex lock to ensure that the thread handling - // messages coming from the network driver connected to the destination does not + // messages coming from the network channel connected to the destination does not // issue a TAG before this message has been forwarded. LF_MUTEX_LOCK(&rti_mutex); // If the destination federate is no longer connected, issue a warning, - // remove the message from the network driver and return. + // remove the message from the network channel and return. federate_info_t* fed = GET_FED_INFO(federate_id); if (fed->enclave.state == NOT_CONNECTED) { lf_print_warning("RTI: Destination federate %d is no longer connected. Dropping message.", federate_id); @@ -310,7 +310,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, bytes_to_read, buffer, NULL, + read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, buffer, NULL, "RTI failed to clear message chunks."); total_bytes_read += bytes_to_read; } @@ -332,7 +332,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff tracepoint_rti_to_federate(send_TAGGED_MSG, federate_id, &intended_tag); } - write_to_netdrv_fail_on_error(fed->fed_netdrv, bytes_read, buffer, &rti_mutex, + write_to_netchan_fail_on_error(fed->fed_netchan, bytes_read, buffer, &rti_mutex, "RTI failed to forward message to federate %d.", federate_id); // The message length may be longer than the buffer, @@ -344,15 +344,15 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_netdrv_fail_on_error(sending_federate->fed_netdrv, bytes_to_read, buffer, NULL, + read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, buffer, NULL, "RTI failed to read message chunks."); total_bytes_read += bytes_to_read; // FIXME: a mutex needs to be held for this so that other threads // do not write to destination_socket and cause interleaving. However, // holding the rti_mutex might be very expensive. Instead, each outgoing - // network driver should probably have its own mutex. - write_to_netdrv_fail_on_error(fed->fed_netdrv, bytes_to_read, buffer, &rti_mutex, + // network channel should probably have its own mutex. + write_to_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer, &rti_mutex, "RTI failed to send message chunks."); } @@ -382,7 +382,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff void handle_latest_tag_confirmed(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, + read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, "RTI failed to read the content of the logical tag complete from federate %d.", fed->enclave.id); tag_t completed = extract_tag(buffer); @@ -400,7 +400,7 @@ void handle_latest_tag_confirmed(federate_info_t* fed) { void handle_next_event_tag(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, + read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, "RTI failed to read the content of the next event tag from federate %d.", fed->enclave.id); @@ -458,7 +458,7 @@ static void broadcast_stop_time_to_federates_locked() { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_STOP_GRN, fed->enclave.id, &rti_remote->base.max_stop_tag); } - write_to_netdrv_fail_on_error(fed->fed_netdrv, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, + write_to_netchan_fail_on_error(fed->fed_netchan, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, "RTI failed to send MSG_TYPE_STOP_GRANTED message to federate %d.", fed->enclave.id); } @@ -511,7 +511,7 @@ void handle_stop_request_message(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netdrv_fail_on_error(fed->fed_netdrv, bytes_to_read, buffer, NULL, + read_from_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer, NULL, "RTI failed to read the MSG_TYPE_STOP_REQUEST payload from federate %d.", fed->enclave.id); @@ -578,7 +578,7 @@ void handle_stop_request_message(federate_info_t* fed) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_STOP_REQ, f->enclave.id, &rti_remote->base.max_stop_tag); } - write_to_netdrv_fail_on_error(f->fed_netdrv, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, + write_to_netchan_fail_on_error(f->fed_netchan, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, "RTI failed to forward MSG_TYPE_STOP_REQUEST message to federate %d.", f->enclave.id); } @@ -591,7 +591,7 @@ void handle_stop_request_message(federate_info_t* fed) { void handle_stop_request_reply(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_REPLY_LENGTH - 1; unsigned char buffer_stop_time[bytes_to_read]; - read_from_netdrv_fail_on_error(fed->fed_netdrv, bytes_to_read, buffer_stop_time, NULL, + read_from_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer_stop_time, NULL, "RTI failed to read the reply to MSG_TYPE_STOP_REQUEST message from federate %d.", fed->enclave.id); @@ -621,7 +621,7 @@ void handle_address_query(uint16_t fed_id) { // Use buffer both for reading and constructing the reply. // The length is what is needed for the reply. unsigned char buffer[1 + sizeof(int32_t)]; - read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(uint16_t), (unsigned char*)buffer, NULL, + read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(uint16_t), (unsigned char*)buffer, NULL, "Failed to read address query."); uint16_t remote_fed_id = extract_uint16(buffer); @@ -646,30 +646,30 @@ void handle_address_query(uint16_t fed_id) { char* server_host_name; LF_MUTEX_LOCK(&rti_mutex); - // Check if the RTI has initialized the remote federate's network driver. - if (remote_fed->fed_netdrv == NULL) { + // Check if the RTI has initialized the remote federate's network channel. + if (remote_fed->fed_netchan == NULL) { // RTI has not set up the remote federate. Respond with -1 to indicate an unknown port number. server_port = -1; uint32_t temp = 0; ip_address = &temp; server_host_name = "localhost"; } else { - // The network driver is initialized, but the RTI might still not know the port number. This can happen if the RTI + // The network channel is initialized, but the RTI might still not know the port number. This can happen if the RTI // has not yet received a MSG_TYPE_ADDRESS_ADVERTISEMENT message from the remote federate. In such cases, the // returned port number might still be -1. - server_port = get_server_port(remote_fed->fed_netdrv); - ip_address = (uint32_t*)get_ip_addr(remote_fed->fed_netdrv); - server_host_name = get_server_hostname(remote_fed->fed_netdrv); + server_port = get_server_port(remote_fed->fed_netchan); + ip_address = (uint32_t*)get_ip_addr(remote_fed->fed_netchan); + server_host_name = get_server_hostname(remote_fed->fed_netchan); } encode_int32(server_port, (unsigned char*)&buffer[1]); // Send the port number (which could be -1) and the server IP address to federate. - write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int32_t), (unsigned char*)buffer, &rti_mutex, - "Failed to write port number to network driver of federate %d.", fed_id); + write_to_netchan_fail_on_error(fed->fed_netchan, 1 + sizeof(int32_t), (unsigned char*)buffer, &rti_mutex, + "Failed to write port number to network channel of federate %d.", fed_id); - write_to_netdrv_fail_on_error(fed->fed_netdrv, sizeof(uint32_t), (unsigned char*)ip_address, &rti_mutex, - "Failed to write ip address to network driver of federate %d.", fed_id); + write_to_netchan_fail_on_error(fed->fed_netchan, sizeof(uint32_t), (unsigned char*)ip_address, &rti_mutex, + "Failed to write ip address to network channel of federate %d.", fed_id); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, server_host_name, @@ -682,7 +682,7 @@ void handle_address_ad(uint16_t federate_id) { // connections to other federates int32_t server_port = -1; unsigned char buffer[sizeof(int32_t)]; - read_from_netdrv_fail_on_error(fed->fed_netdrv, sizeof(int32_t), (unsigned char*)buffer, NULL, + read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int32_t), (unsigned char*)buffer, NULL, "Error reading port data from federate %d.", federate_id); server_port = extract_int32(buffer); @@ -690,7 +690,7 @@ void handle_address_ad(uint16_t federate_id) { assert(server_port < 65536); LF_MUTEX_LOCK(&rti_mutex); - set_server_port(fed->fed_netdrv, server_port); + set_server_port(fed->fed_netchan, server_port); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_LOG("Received address advertisement with port %d from federate %d.", server_port, federate_id); @@ -701,8 +701,8 @@ void handle_address_ad(uint16_t federate_id) { void handle_timestamp(federate_info_t* my_fed) { unsigned char buffer[sizeof(int64_t)]; - // Read bytes from the network driver. We need 8 bytes. - read_from_netdrv_fail_on_error(my_fed->fed_netdrv, sizeof(int64_t), (unsigned char*)&buffer, NULL, + // Read bytes from the network channel. We need 8 bytes. + read_from_netchan_fail_on_error(my_fed->fed_netchan, sizeof(int64_t), (unsigned char*)&buffer, NULL, "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); int64_t timestamp = swap_bytes_if_big_endian_int64(*((int64_t*)(&buffer))); @@ -744,7 +744,7 @@ void handle_timestamp(federate_info_t* my_fed) { tag_t tag = {.time = start_time, .microstep = 0}; tracepoint_rti_to_federate(send_TIMESTAMP, my_fed->enclave.id, &tag); } - if (write_to_netdrv(my_fed->fed_netdrv, MSG_TYPE_TIMESTAMP_LENGTH, start_time_buffer)) { + if (write_to_netchan(my_fed->fed_netchan, MSG_TYPE_TIMESTAMP_LENGTH, start_time_buffer)) { lf_print_error("Failed to send the starting time to federate %d.", my_fed->enclave.id); } @@ -760,7 +760,7 @@ void handle_timestamp(federate_info_t* my_fed) { void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP) { if (fed->enclave.state == NOT_CONNECTED) { - lf_print_warning("Clock sync: RTI failed to send physical time to federate %d. Network driver not connected.\n", + lf_print_warning("Clock sync: RTI failed to send physical time to federate %d. network channel not connected.\n", fed->enclave.id); return; } @@ -780,10 +780,10 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool return; } } else { - // Send using network driver. + // Send using network channel. LF_PRINT_DEBUG("Clock sync: RTI sending message type %u.", buffer[0]); LF_MUTEX_LOCK(&rti_mutex); - write_to_netdrv_fail_on_error(fed->fed_netdrv, 1 + sizeof(int64_t), buffer, &rti_mutex, + write_to_netchan_fail_on_error(fed->fed_netchan, 1 + sizeof(int64_t), buffer, &rti_mutex, "Clock sync: RTI failed to send physical time to federate %d.", fed->enclave.id); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -905,7 +905,7 @@ void* clock_synchronization_thread(void* noargs) { * @param my_fed The federate sending a MSG_TYPE_FAILED message. */ static void handle_federate_failed(federate_info_t* my_fed) { - // Nothing more to do. Close the network driver and exit. + // Nothing more to do. Close the network channel and exit. LF_MUTEX_LOCK(&rti_mutex); if (rti_remote->base.tracing_enabled) { @@ -921,7 +921,7 @@ static void handle_federate_failed(federate_info_t* my_fed) { // Indicate that there will no further events from this federate. my_fed->enclave.next_event = FOREVER_TAG; - shutdown_netdrv(my_fed->fed_netdrv, false); + shutdown_netchan(my_fed->fed_netchan, false); // Check downstream federates to see whether they should now be granted a TAG. // To handle cycles, need to create a boolean array to keep @@ -940,13 +940,13 @@ static void handle_federate_failed(federate_info_t* my_fed) { * This function assumes the caller does not hold the mutex. * * @note At this point, the RTI might have outgoing messages to the federate. This - * function thus first performs a shutdown on the network driver, which sends an EOF. It then - * waits for the remote network driver to be closed before closing the network driver itself. + * function thus first performs a shutdown on the network channel, which sends an EOF. It then + * waits for the remote network channel to be closed before closing the network channel itself. * * @param my_fed The federate sending a MSG_TYPE_RESIGN message. */ static void handle_federate_resign(federate_info_t* my_fed) { - // Nothing more to do. Close the network driver and exit. + // Nothing more to do. Close the network channel and exit. LF_MUTEX_LOCK(&rti_mutex); if (rti_remote->base.tracing_enabled) { @@ -960,7 +960,7 @@ static void handle_federate_resign(federate_info_t* my_fed) { // Indicate that there will no further events from this federate. my_fed->enclave.next_event = FOREVER_TAG; - shutdown_netdrv(my_fed->fed_netdrv, true); + shutdown_netchan(my_fed->fed_netchan, true); // Check downstream federates to see whether they should now be granted a TAG. // To handle cycles, need to create a boolean array to keep @@ -984,15 +984,15 @@ void* federate_info_thread_TCP(void* fed) { // Listen for messages from the federate. while (my_fed->enclave.state != NOT_CONNECTED) { // Read no more than one byte to get the message type. - int read_failed = read_from_netdrv(my_fed->fed_netdrv, 1, buffer); + int read_failed = read_from_netchan(my_fed->fed_netchan, 1, buffer); if (read_failed) { - // ã…œetwork driver is closed - lf_print_error("RTI: Network driver to federate %d is closed. Exiting the thread.", my_fed->enclave.id); + // network channel is closed + lf_print_error("RTI: network channel to federate %d is closed. Exiting the thread.", my_fed->enclave.id); my_fed->enclave.state = NOT_CONNECTED; - // Nothing more to do. Close the network driver and exit. - // Prevent multiple threads from closing the same network driver at the same time. + // Nothing more to do. Close the network channel and exit. + // Prevent multiple threads from closing the same network channel at the same time. LF_MUTEX_LOCK(&rti_mutex); - shutdown_netdrv(my_fed->fed_netdrv, false); + shutdown_netchan(my_fed->fed_netchan, false); LF_MUTEX_UNLOCK(&rti_mutex); // FIXME: We need better error handling here, but do not stop execution here. break; @@ -1046,18 +1046,18 @@ void* federate_info_thread_TCP(void* fed) { return NULL; } -void send_reject(netdrv_t drv, unsigned char error_code) { +void send_reject(netchan_t chan, unsigned char error_code) { LF_PRINT_DEBUG("RTI sending MSG_TYPE_REJECT."); unsigned char response[2]; response[0] = MSG_TYPE_REJECT; response[1] = error_code; LF_MUTEX_LOCK(&rti_mutex); // NOTE: Ignore errors on this response. - if (write_to_netdrv(drv, 2, response)) { - lf_print_warning("RTI failed to write MSG_TYPE_REJECT message on the network driver."); + if (write_to_netchan(chan, 2, response)) { + lf_print_warning("RTI failed to write MSG_TYPE_REJECT message on the network channel."); } - // Close the network driver without reading until EOF. - shutdown_netdrv(drv, false); + // Close the network channel without reading until EOF. + shutdown_netchan(chan, false); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -1066,17 +1066,17 @@ void send_reject(netdrv_t drv, unsigned char error_code) { * a federate ID and a federation ID. If the federation ID * matches this federation, send an MSG_TYPE_ACK and otherwise send * a MSG_TYPE_REJECT message. - * @param fed_netdrv Pointer to the network driver on which to listen. + * @param fed_netchan Pointer to the network channel on which to listen. * @return The federate ID for success or -1 for failure. */ -static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { +static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { // Buffer for message ID, federate ID, and federation ID length. size_t length = 1 + sizeof(uint16_t) + 1; // Message ID, federate ID, length of fedration ID. unsigned char buffer[length]; - // Read bytes from the network driver. We need 4 bytes. - if (read_from_netdrv_close_on_error(fed_netdrv, length, buffer)) { - lf_print_error("RTI failed to read from accepted network driver."); + // Read bytes from the network channel. We need 4 bytes. + if (read_from_netchan_close_on_error(fed_netchan, length, buffer)) { + lf_print_error("RTI failed to read from accepted network channel."); return -1; } @@ -1095,12 +1095,12 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { // of the peer they want to connect to from the RTI. // If the connection is a peer-to-peer connection between two // federates, reject the connection with the WRONG_SERVER error. - send_reject(fed_netdrv, WRONG_SERVER); + send_reject(fed_netchan, WRONG_SERVER); } else if (buffer[0] == MSG_TYPE_FED_NONCE) { - send_reject(fed_netdrv, RTI_NOT_EXECUTED_WITH_AUTH); + send_reject(fed_netchan, RTI_NOT_EXECUTED_WITH_AUTH); lf_print_error("RTI not executed with HMAC authentication option using -a or --auth."); } else { - send_reject(fed_netdrv, UNEXPECTED_MESSAGE); + send_reject(fed_netchan, UNEXPECTED_MESSAGE); } lf_print_error("RTI expected a MSG_TYPE_FED_IDS message. Got %u (see net_common.h).", buffer[0]); return -1; @@ -1113,7 +1113,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { size_t federation_id_length = (size_t)buffer[sizeof(uint16_t) + 1]; char federation_id_received[federation_id_length + 1]; // One extra for null terminator. // Next read the actual federation ID. - if (read_from_netdrv_close_on_error(fed_netdrv, federation_id_length, (unsigned char*)federation_id_received)) { + if (read_from_netchan_close_on_error(fed_netchan, federation_id_length, (unsigned char*)federation_id_received)) { lf_print_error("RTI failed to read federation id from federate %d.", fed_id); return -1; } @@ -1134,7 +1134,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_netdrv, FEDERATION_ID_DOES_NOT_MATCH); + send_reject(fed_netchan, FEDERATION_ID_DOES_NOT_MATCH); return -1; } else { if (fed_id >= rti_remote->base.number_of_scheduling_nodes) { @@ -1143,7 +1143,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_netdrv, FEDERATE_ID_OUT_OF_RANGE); + send_reject(fed_netchan, FEDERATE_ID_OUT_OF_RANGE); return -1; } else { if ((rti_remote->base.scheduling_nodes[fed_id])->state != NOT_CONNECTED) { @@ -1151,7 +1151,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_netdrv, FEDERATE_ID_IN_USE); + send_reject(fed_netchan, FEDERATE_ID_IN_USE); return -1; } } @@ -1160,7 +1160,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { federate_info_t* fed = GET_FED_INFO(fed_id); // The MSG_TYPE_FED_IDS message has the right federation ID. - fed->fed_netdrv = fed_netdrv; + fed->fed_netchan = fed_netchan; // Set the federate's state as pending // because it is waiting for the start time to be @@ -1174,7 +1174,7 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { tracepoint_rti_to_federate(send_ACK, fed_id, NULL); } LF_MUTEX_LOCK(&rti_mutex); - if (write_to_netdrv_close_on_error(fed->fed_netdrv, 1, &ack_message)) { + if (write_to_netchan_close_on_error(fed->fed_netchan, 1, &ack_message)) { LF_MUTEX_UNLOCK(&rti_mutex); lf_print_error("RTI failed to write MSG_TYPE_ACK message to federate %d.", fed_id); return -1; @@ -1191,10 +1191,10 @@ static int32_t receive_and_check_fed_id_message(netdrv_t fed_netdrv) { * out the relevant information in the federate's struct. * @return 1 on success and 0 on failure. */ -static int receive_connection_information(netdrv_t fed_netdrv, uint16_t fed_id) { +static int receive_connection_information(netchan_t fed_netchan, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; - read_from_netdrv_fail_on_error(fed_netdrv, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, NULL, + read_from_netchan_fail_on_error(fed_netchan, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, NULL, "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message header from federate %d.", fed_id); @@ -1202,7 +1202,7 @@ static int receive_connection_information(netdrv_t fed_netdrv, uint16_t fed_id) lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", fed_id, connection_info_header[0]); - send_reject(fed_netdrv, UNEXPECTED_MESSAGE); + send_reject(fed_netchan, UNEXPECTED_MESSAGE); return 0; } else { federate_info_t* fed = GET_FED_INFO(fed_id); @@ -1234,7 +1234,7 @@ static int receive_connection_information(netdrv_t fed_netdrv, uint16_t fed_id) if (connections_info_body_size > 0) { connections_info_body = (unsigned char*)malloc(connections_info_body_size); LF_ASSERT_NON_NULL(connections_info_body); - read_from_netdrv_fail_on_error(fed_netdrv, connections_info_body_size, connections_info_body, NULL, + read_from_netchan_fail_on_error(fed_netchan, connections_info_body_size, connections_info_body, NULL, "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message body from federate %d.", fed_id); // Keep track of where we are in the buffer @@ -1268,23 +1268,23 @@ static int receive_connection_information(netdrv_t fed_netdrv, uint16_t fed_id) * up to perform runtime clock synchronization using the UDP port number * specified in the payload to communicate with the federate's clock * synchronization logic. - * @param fed_netdrv The network driver on which to listen. + * @param fed_netchan The network channel on which to listen. * @param fed_id The federate ID. * @return 1 for success, 0 for failure. */ -static int receive_udp_message_and_set_up_clock_sync(netdrv_t fed_netdrv, uint16_t fed_id) { +static int receive_udp_message_and_set_up_clock_sync(netchan_t fed_netchan, uint16_t fed_id) { // Read the MSG_TYPE_UDP_PORT message from the federate regardless of the status of // clock synchronization. This message will tell the RTI whether the federate // is doing clock synchronization, and if it is, what port to use for UDP. LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_UDP_PORT from federate %d.", fed_id); unsigned char response[1 + sizeof(uint16_t)]; - read_from_netdrv_fail_on_error(fed_netdrv, 1 + sizeof(uint16_t), response, NULL, + read_from_netchan_fail_on_error(fed_netchan, 1 + sizeof(uint16_t), response, NULL, "RTI failed to read MSG_TYPE_UDP_PORT message from federate %d.", fed_id); if (response[0] != MSG_TYPE_UDP_PORT) { lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", fed_id, response[0]); - send_reject(fed_netdrv, UNEXPECTED_MESSAGE); + send_reject(fed_netchan, UNEXPECTED_MESSAGE); return 0; } else { federate_info_t* fed = GET_FED_INFO(fed_id); @@ -1305,15 +1305,15 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t fed_netdrv, uint16 // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); unsigned char buffer[message_size]; - read_from_netdrv_fail_on_error(fed_netdrv, message_size, buffer, NULL, - "Network driver to federate %d unexpectedly closed.", fed_id); + read_from_netchan_fail_on_error(fed_netchan, message_size, buffer, NULL, + "network channel to federate %d unexpectedly closed.", fed_id); if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); LF_PRINT_DEBUG("RTI received T3 clock sync message from federate %d.", fed_id); handle_physical_clock_sync_message(fed, false); } else { lf_print_error("Unexpected message %u from federate %d.", buffer[0], fed_id); - send_reject(fed_netdrv, UNEXPECTED_MESSAGE); + send_reject(fed_netchan, UNEXPECTED_MESSAGE); return 0; } } @@ -1325,7 +1325,7 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t fed_netdrv, uint16 // Initialize the UDP_addr field of the federate struct fed->UDP_addr.sin_family = AF_INET; fed->UDP_addr.sin_port = htons(federate_UDP_port_number); - fed->UDP_addr.sin_addr = *get_ip_addr(fed_netdrv); + fed->UDP_addr.sin_addr = *get_ip_addr(fed_netchan); } } else { // Disable clock sync after initial round. @@ -1348,14 +1348,14 @@ static int receive_udp_message_and_set_up_clock_sync(netdrv_t fed_netdrv, uint16 /** * Authenticate incoming federate by performing HMAC-based authentication. * - * @param fed_netdrv Network driver for the incoming federate tryting to authenticate. + * @param fed_netchan network channel for the incoming federate tryting to authenticate. * @return True if authentication is successful and false otherwise. */ -static bool authenticate_federate(netdrv_t fed_netdrv) { +static bool authenticate_federate(netchan_t fed_netchan) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); unsigned char buffer[1 + fed_id_length + NONCE_LENGTH]; - read_from_netdrv_fail_on_error(fed_netdrv, 1 + fed_id_length + NONCE_LENGTH, buffer, NULL, + read_from_netchan_fail_on_error(fed_netchan, 1 + fed_id_length + NONCE_LENGTH, buffer, NULL, "Failed to read MSG_TYPE_FED_NONCE"); if (buffer[0] != MSG_TYPE_FED_NONCE) { lf_print_error_and_exit("Received unexpected response %u from the FED (see net_common.h).", buffer[0]); @@ -1380,13 +1380,13 @@ static bool authenticate_federate(netdrv_t fed_netdrv) { RAND_bytes(rti_nonce, NONCE_LENGTH); memcpy(&sender[1], rti_nonce, NONCE_LENGTH); memcpy(&sender[1 + NONCE_LENGTH], hmac_tag, hmac_length); - if (write_to_netdrv(fed_netdrv, 1 + NONCE_LENGTH + hmac_length, sender)) { + if (write_to_netchan(fed_netchan, 1 + NONCE_LENGTH + hmac_length, sender)) { lf_print_error("Failed to send nonce to federate."); } // Wait for MSG_TYPE_FED_RESPONSE unsigned char received[1 + hmac_length]; - read_from_netdrv_fail_on_error(fed_netdrv, 1 + hmac_length, received, NULL, "Failed to read federate response."); + read_from_netchan_fail_on_error(fed_netchan, 1 + hmac_length, received, NULL, "Failed to read federate response."); if (received[0] != MSG_TYPE_FED_RESPONSE) { lf_print_error_and_exit("Received unexpected response %u from the federate (see net_common.h).", received[0]); return false; @@ -1405,7 +1405,7 @@ static bool authenticate_federate(netdrv_t fed_netdrv) { if (memcmp(&received[1], rti_tag, hmac_length) != 0) { // Federation IDs do not match. Send back a HMAC_DOES_NOT_MATCH message. lf_print_warning("HMAC authentication failed. Rejecting the federate."); - send_reject(fed_netdrv, HMAC_DOES_NOT_MATCH); + send_reject(fed_netchan, HMAC_DOES_NOT_MATCH); return false; } else { LF_PRINT_LOG("Federate's HMAC verified."); @@ -1414,20 +1414,20 @@ static bool authenticate_federate(netdrv_t fed_netdrv) { } #endif -void lf_connect_to_federates(netdrv_t rti_netdrv) { +void lf_connect_to_federates(netchan_t rti_netchan) { for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { - netdrv_t fed_netdrv = accept_netdrv(rti_netdrv, NULL); - if (fed_netdrv == NULL) { + netchan_t fed_netchan = accept_netchan(rti_netchan, NULL); + if (fed_netchan == NULL) { lf_print_warning("RTI failed to accept the federate."); return; } // Wait for the first message from the federate when RTI -a option is on. #ifdef __RTI_AUTH__ if (rti_remote->authentication_enabled) { - if (!authenticate_federate(fed_netdrv)) { + if (!authenticate_federate(fed_netchan)) { lf_print_warning("RTI failed to authenticate the incoming federate."); - // Close the network driver without reading until EOF. - shutdown_netdrv(fed_netdrv, false); + // Close the network channel without reading until EOF. + shutdown_netchan(fed_netchan, false); // Ignore the federate that failed authentication. i--; continue; @@ -1436,9 +1436,9 @@ void lf_connect_to_federates(netdrv_t rti_netdrv) { #endif // The first message from the federate should contain its ID and the federation ID. - int32_t fed_id = receive_and_check_fed_id_message(fed_netdrv); - if (fed_id >= 0 && receive_connection_information(fed_netdrv, (uint16_t)fed_id) && - receive_udp_message_and_set_up_clock_sync(fed_netdrv, (uint16_t)fed_id)) { + int32_t fed_id = receive_and_check_fed_id_message(fed_netchan); + if (fed_id >= 0 && receive_connection_information(fed_netchan, (uint16_t)fed_id) && + receive_udp_message_and_set_up_clock_sync(fed_netchan, (uint16_t)fed_id)) { // Create a thread to communicate with the federate. // This has to be done after clock synchronization is finished @@ -1477,9 +1477,9 @@ void* respond_to_erroneous_connections(void* nothing) { while (true) { // Wait for an incoming connection request. // The following will block until either a federate attempts to connect - // or shutdown_netdrv(rti->rti_netdrv) is called. - netdrv_t fed_netdrv = accept_netdrv(rti_remote->rti_netdrv, NULL); - if (fed_netdrv == NULL) { + // or shutdown_netchan(rti->rti_netchan) is called. + netchan_t fed_netchan = accept_netchan(rti_remote->rti_netchan, NULL); + if (fed_netchan == NULL) { return NULL; } if (rti_remote->all_federates_exited) { @@ -1491,11 +1491,11 @@ void* respond_to_erroneous_connections(void* nothing) { response[0] = MSG_TYPE_REJECT; response[1] = FEDERATION_ID_DOES_NOT_MATCH; // Ignore errors on this response. - if (write_to_netdrv(fed_netdrv, 2, response)) { + if (write_to_netchan(fed_netchan, 2, response)) { lf_print_warning("RTI failed to write FEDERATION_ID_DOES_NOT_MATCH to erroneous incoming connection."); } - // Close the network driver without reading until EOF. - shutdown_netdrv(fed_netdrv, false); + // Close the network channel without reading until EOF. + shutdown_netchan(fed_netchan, false); } return NULL; } @@ -1509,12 +1509,12 @@ void initialize_federate(federate_info_t* fed, uint16_t id) { int start_rti_server() { _lf_initialize_clock(); - // Initialize RTI's network driver. - rti_remote->rti_netdrv = initialize_netdrv(); - // Set the user specified port to the network driver. - set_my_port(rti_remote->rti_netdrv, rti_remote->user_specified_port); + // Initialize RTI's network channel. + rti_remote->rti_netchan = initialize_netchan(); + // Set the user specified port to the network channel. + set_my_port(rti_remote->rti_netchan, rti_remote->user_specified_port); // Create the server - if (create_server(rti_remote->rti_netdrv, true)) { + if (create_server(rti_remote->rti_netchan, true)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); return -1; }; @@ -1532,12 +1532,12 @@ int start_rti_server() { void wait_for_federates() { // Wait for connections from federates and create a thread for each. - lf_connect_to_federates(rti_remote->rti_netdrv); + lf_connect_to_federates(rti_remote->rti_netchan); // All federates have connected. lf_print("RTI: All expected federates have connected. Starting execution."); - // The network driver server will not continue to accept connections after all the federates + // The network channel server will not continue to accept connections after all the federates // have joined. // In case some other federation's federates are trying to join the wrong // federation, need to respond. Start a separate thread to do that. @@ -1556,10 +1556,10 @@ void wait_for_federates() { rti_remote->all_federates_exited = true; - // Shutdown and close the network driver that is listening for incoming connections + // Shutdown and close the network channel that is listening for incoming connections // so that the accept() call in respond_to_erroneous_connections returns. // That thread should then check rti->all_federates_exited and it should exit. - shutdown_netdrv(rti_remote->rti_netdrv, false); + shutdown_netchan(rti_remote->rti_netchan, false); if (rti_remote->socket_descriptor_UDP > 0) { // UDP only uses sockets. From 3ec6ade6ec70961cd9bac08de40edaa128297673 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 24 Feb 2025 14:02:19 -0700 Subject: [PATCH 132/167] Change clock-sync.h, federate.h, and rti_remote.h name to netchan --- core/federated/RTI/rti_remote.h | 18 +++---- include/core/federated/clock-sync.h | 24 ++++----- include/core/federated/federate.h | 80 ++++++++++++++--------------- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 800b696d9..c6d7be099 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -46,7 +46,7 @@ typedef struct federate_info_t { // to a request for stop from the RTI. Used to prevent double-counting // a federate when handling lf_request_stop(). lf_thread_t thread_id; // The ID of the thread handling communication with this federate. - netdrv_t fed_netdrv; // The netdriver that the RTI handling each federate. + netchan_t fed_netchan; // The netdriver that the RTI handling each federate. struct sockaddr_in UDP_addr; // The UDP address for the federate. bool clock_synchronization_enabled; // Indicates the status of clock synchronization // for this federate. Enabled by default. @@ -112,9 +112,9 @@ typedef struct rti_remote_t { int socket_descriptor_UDP; /** - * The rti's network driver. + * The rti's network channel. */ - netdrv_t rti_netdrv; + netchan_t rti_netchan; /************* Clock synchronization information *************/ /* Thread performing PTP clock sync sessions periodically. */ @@ -282,13 +282,13 @@ void handle_timestamp(federate_info_t* my_fed); /** * Take a snapshot of the physical clock time and send - * it to federate fed_id using the network driver. + * it to federate fed_id using the network channel. * * This version assumes the caller holds the mutex lock. * * @param message_type The type of the clock sync message (see net_common.h). * @param fed The federate to send the physical time to. - * @param use_UDP Boolean to use UDP or the network driver. + * @param use_UDP Boolean to use UDP or the network channel. */ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP); @@ -329,18 +329,18 @@ void* federate_info_thread_TCP(void* fed); /** * Send a MSG_TYPE_REJECT message to the specified socket and close the socket. - * @param drv Pointer to the network driver. + * @param chan Pointer to the network channel. * @param error_code An error code. */ -void send_reject(netdrv_t drv, unsigned char error_code); +void send_reject(netchan_t chan, unsigned char error_code); /** * Wait for one incoming connection request from each federate, * and upon receiving it, create a thread to communicate with * that federate. Return when all federates have connected. - * @param rti_netdrv The rti's network driver on which to accept connections. + * @param rti_netchan The rti's network channel on which to accept connections. */ -void lf_connect_to_federates(netdrv_t rti_netdrv); +void lf_connect_to_federates(netchan_t rti_netchan); /** * Thread to respond to new connections, which could be federates of other diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index 8f0f0e5ca..0afddf0d9 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -158,15 +158,15 @@ uint16_t setup_clock_synchronization_with_rti(void); * is required. * * This is a blocking function that expects - * to read a MSG_TYPE_CLOCK_SYNC_T1 from the RTI network driver. + * to read a MSG_TYPE_CLOCK_SYNC_T1 from the RTI network channel. * It will then follow the PTP protocol to synchronize the local * physical clock with the RTI. * Failing to complete this protocol is treated as a catastrophic * error that causes the federate to exit. * - * @param rti_netdrv Pointer to the RTI's network driver. + * @param rti_netchan Pointer to the RTI's network channel. */ -void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv); +void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan); /** * Handle a clock synchroninzation message T1 coming from the RTI. @@ -175,31 +175,31 @@ void synchronize_initial_physical_clock_with_rti(netdrv_t rti_netdrv); * It also measures the time it takes between when the method is * called and the reply has been sent. * @param buffer The buffer containing the message, including the message type. - * @param netdrv_t The pointer to the network driver. + * @param netchan_t The pointer to the network channel. * @param t2 The physical time at which the T1 message was received. - * @param use_UDP Boolean to use UDP or the network driver. + * @param use_UDP Boolean to use UDP or the network channel. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, instant_t t2, bool use_udp); +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t t2, bool use_udp); /** * Handle a clock synchronization message T4 coming from the RTI. - * If the socket_or_netdrv is a network driver, then assume we are in the + * If the socket_or_netchan is a network channel, then assume we are in the * initial clock synchronization phase and set the clock offset * based on the estimated clock synchronization error. - * Otherwise, if the socket_or_netdrv is UDP socket, then this looks also for a + * Otherwise, if the socket_or_netchan is UDP socket, then this looks also for a * subsequent "coded probe" message on the socket. If the delay between * the T4 and the coded probe message is not as expected, then reject * this clock synchronization round. If it is not rejected, then make * an adjustment to the clock offset based on the estimated error. - * This function does not acquire the netdrv_mutex lock. + * This function does not acquire the netchan_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. - * @param netdrv_t The pointer to the network driver. + * @param netchan_t The pointer to the network channel. * @param r4 The physical time at which this T4 message was received.\ - * @param use_UDP Boolean to use UDP or the network driver. + * @param use_UDP Boolean to use UDP or the network channel. */ -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netdrv, instant_t r4, bool use_udp); +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t r4, bool use_udp); /** * Thread that listens for UDP inputs from the RTI. diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index 37d800379..90cda32a8 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -32,16 +32,16 @@ */ typedef struct federate_instance_t { /** - * The network driver for this federate to communicate with the RTI. + * The network channel for this federate to communicate with the RTI. * This is set by lf_connect_to_rti(), which must be called before other * functions that communicate with the rti are called. */ - netdrv_t netdrv_to_RTI; + netchan_t netchan_to_RTI; /** * Thread listening for incoming messages from the RTI. */ - lf_thread_t RTI_netdrv_listener; + lf_thread_t RTI_netchan_listener; /** * Number of inbound physical connections to the federate. @@ -65,50 +65,50 @@ typedef struct federate_instance_t { size_t number_of_outbound_p2p_connections; /** - * An array that holds the network drivers for inbound + * An array that holds the network channels for inbound * connections from each federate. The index will be the federate * ID of the remote sending federate. This is initialized at startup - * to NULL and is set to the pointer of the network driver by lf_connect_to_federate() - * when the network drivers is opened. + * to NULL and is set to the pointer of the network channel by lf_connect_to_federate() + * when the network channels is opened. * - * @note There will not be an inbound network driver unless a physical connection + * @note There will not be an inbound network channel unless a physical connection * or a p2p logical connection (by setting the coordination target property * to "distributed") is specified in the Lingua Franca program where this * federate is the destination. Multiple incoming p2p connections from the - * same remote federate will use the same network driver. + * same remote federate will use the same network channel. */ - netdrv_t netdrvs_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; + netchan_t netchans_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; /** - * An array that holds the network drivers for outbound direct + * An array that holds the network channels for outbound direct * connections to each remote federate. The index will be the federate * ID of the remote receiving federate. This is initialized at startup - * to NULL and is set to the pointer of the network driver by lf_connect_to_federate() - * when the network drivers is opened. + * to NULL and is set to the pointer of the network channel by lf_connect_to_federate() + * when the network channels is opened. * - * @note This federate will not open an outbound network drivers unless a physical + * @note This federate will not open an outbound network channels unless a physical * connection or a p2p logical connection (by setting the coordination target * property to "distributed") is specified in the Lingua Franca * program where this federate acts as the source. Multiple outgoing p2p - * connections to the same remote federate will use the same network drivers. + * connections to the same remote federate will use the same network channels. */ - netdrv_t netdrvs_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; + netchan_t netchans_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; /** - * Thread ID for a thread that accepts network drivers and then supervises - * listening to those network drivers for incoming P2P (physical) connections. + * Thread ID for a thread that accepts network channels and then supervises + * listening to those network channels for incoming P2P (physical) connections. */ lf_thread_t inbound_p2p_handling_thread_id; /** - * A network driver for the server of the federate. + * A network channel for the server of the federate. * This is assigned in lf_create_server(). - * This network driver is used to listen to incoming physical connections from + * This network channel is used to listen to incoming physical connections from * remote federates. Once an incoming connection is accepted, the - * opened network driver will be stored in - * federate_netdrvs_for_inbound_p2p_connections. + * opened network channel will be stored in + * federate_netchans_for_inbound_p2p_connections. */ - netdrv_t server_netdrv; + netchan_t server_netchan; /** * Most recent tag advance grant (TAG) received from the RTI, or NEVER if none @@ -215,9 +215,9 @@ typedef enum parse_rti_code_t { SUCCESS, INVALID_PORT, INVALID_HOST, INVALID_USE // Global variables /** - * Mutex lock held while performing network driver write and close operations. + * Mutex lock held while performing network channel write and close operations. */ -extern lf_mutex_t lf_outbound_netdrv_mutex; +extern lf_mutex_t lf_outbound_netchan_mutex; /** * Condition variable for blocking on unkonwn federate input ports. @@ -234,10 +234,10 @@ extern lf_cond_t lf_port_status_changed; * to send messages directly to the specified federate. * This function first sends an MSG_TYPE_ADDRESS_QUERY message to the RTI to obtain * the IP address and port number of the specified federate. It then attempts - * to establish a network driver connection to the specified federate. + * to establish a network channel connection to the specified federate. * If this fails, the program exits. If it succeeds, it sets element [id] of - * the _fed.netdrvs_for_outbound_p2p_connections global array to - * refer to the network driver for communicating directly with the federate. + * the _fed.netchans_for_outbound_p2p_connections global array to + * refer to the network channel for communicating directly with the federate. * @param remote_federate_id The ID of the remote federate. */ void lf_connect_to_federate(uint16_t); @@ -245,12 +245,12 @@ void lf_connect_to_federate(uint16_t); /** * @brief Connect to the RTI at the specified host and port. * - * This will return the network driver for the connection. + * This will return the network channel for the connection. * If port_number is 0, then start at DEFAULT_PORT and increment * the port number on each attempt. If an attempt fails, wait CONNECT_RETRY_INTERVAL * and try again. If it fails after CONNECT_TIMEOUT, the program exits. - * If it succeeds, it sets the _fed.netdrv_to_RTI global variable to refer to - * the network driver for communicating with the RTI. + * If it succeeds, it sets the _fed.netchan_to_RTI global variable to refer to + * the network channel for communicating with the RTI. * @param hostname A hostname, such as "localhost". * @param port_number A port number or 0 to start with the default. */ @@ -260,8 +260,8 @@ void lf_connect_to_rti(const char* hostname, int port_number); * @brief Create a server to listen to incoming P2P connections. * * Such connections are used for physical connections or any connection if using - * decentralized coordination. This function only handles the creation of the server network driver. - * The bound port for the server network driver is then sent to the RTI by sending an + * decentralized coordination. This function only handles the creation of the server network channel. + * The bound port for the server network channel is then sent to the RTI by sending an * MSG_TYPE_ADDRESS_ADVERTISEMENT message (@see net_common.h). * This function expects no response from the RTI. * @@ -288,8 +288,8 @@ void lf_enqueue_port_absent_reactions(environment_t* env); * * This thread accepts connections from federates that send messages directly * to this one (not through the RTI). This thread starts a thread for - * each accepted network driver connection to read messages and, once it has opened all expected - * network drivers, exits. + * each accepted network channel connection to read messages and, once it has opened all expected + * network channels, exits. * @param ignored No argument needed for this thread. */ void* lf_handle_p2p_connections_from_federates(void*); @@ -331,7 +331,7 @@ void lf_reset_status_fields_on_input_port_triggers(); * between federates. If the connection to the remote federate or the RTI has been broken, * then this returns -1 without sending. Otherwise, it returns 0. * - * This method assumes that the caller does not hold the lf_outbound_netdrv_mutex lock, + * This method assumes that the caller does not hold the lf_outbound_netchan_mutex lock, * which it acquires to perform the send. * * @param message_type The type of the message being sent (currently only MSG_TYPE_P2P_MESSAGE). @@ -354,7 +354,7 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa * information is needed for the RTI to perform the centralized coordination. * @see MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h */ -void lf_send_neighbor_structure_to_RTI(netdrv_t); +void lf_send_neighbor_structure_to_RTI(netchan_t); /** * @brief Send a next event tag (NET) signal. @@ -433,7 +433,7 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d * * The payload is the specified tag plus one microstep. If this federate has previously * received a stop request from the RTI, then do not send the message and - * return 1. Return -1 if the network driver is disconnected. Otherwise, return 0. + * return 1. Return -1 if the network channel is disconnected. Otherwise, return 0. * @return 0 if the message is sent. */ int lf_send_stop_request_to_rti(tag_t stop_tag); @@ -445,7 +445,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag); * If the delayed tag falls after the timeout time, then the message is not sent and -1 is returned. * The caller can reuse or free the memory storing the message after this returns. * - * If the message fails to send (e.g. the network driver connection is broken), then the + * If the message fails to send (e.g. the network channel connection is broken), then the * response depends on the message_type. For MSG_TYPE_TAGGED_MESSAGE, the message is * supposed to go via the RTI, and failure to communicate with the RTI is a critical failure. * In this case, the program will exit with an error message. If the message type is @@ -454,7 +454,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag); * to believe that there were no messages forthcoming. In this case, on failure to send * the message, this function returns -11. * - * This method assumes that the caller does not hold the lf_outbound_netdrv_mutex lock, + * This method assumes that the caller does not hold the lf_outbound_netchan_mutex lock, * which it acquires to perform the send. * * @param env The environment from which to get the current tag. @@ -510,7 +510,7 @@ void lf_stall_advance_level_federation_locked(size_t level); * @brief Synchronize the start with other federates via the RTI. * * This assumes that a connection to the RTI is already made - * and netdrv_to_RTI is valid. It then sends the current logical + * and netchan_to_RTI is valid. It then sends the current logical * time to the RTI and waits for the RTI to respond with a specified * time. It starts a thread to listen for messages from the RTI. */ From e2cc85835f4b32e50f27f068fc265cff842c3120 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 24 Feb 2025 14:56:00 -0700 Subject: [PATCH 133/167] Change net_driver.h, socket_common.h, and rti_remote.h name to netchan --- network/api/net_driver.h | 136 ++++++++++++++++++------------------ network/api/socket_common.h | 2 +- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index b29e8b108..c6c2bc85d 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -3,85 +3,85 @@ #include "socket_common.h" -typedef void* netdrv_t; +typedef void* netchan_t; /** - * Allocate memory for the network driver. - * @return netdrv_t Initialized network driver. + * Allocate memory for the network channel. + * @return netchan_t Initialized network channel. */ -netdrv_t initialize_netdrv(); +netchan_t initialize_netchan(); /** * Create a netdriver server. This is such as a server socket which accepts connections. * However this is only the creation of the server netdriver. * - * @param drv Server's network driver. + * @param chan Server's network channel. * @param serv_type Type of server, RTI or FED. * @return int 0 for success, -1 for failure. */ -int create_server(netdrv_t drv, bool increment_port_on_retry); +int create_server(netchan_t chan, bool increment_port_on_retry); /** - * Wait for an incoming connection request on the specified server network driver. + * Wait for an incoming connection request on the specified server network channel. * The implementation should include three steps. - * 1. Initialize the network driver of the connected federate. + * 1. Initialize the network channel of the connected federate. * 2. Wait for the incoming connection request. This should block until the connection is successfully accepted. - * 3. Save the information in the connected network driver, such as the address of the connected peer, for future + * 3. Save the information in the connected network channel, such as the address of the connected peer, for future * querying address. * - * @param server_drv The server network driver that is listening for incoming connections. - * @param rti_drv The rti's network driver to check if it is still open. - * @return netdrv_t The network driver for the newly accepted connection on success, or NULL on failure + * @param server_chan The server network channel that is listening for incoming connections. + * @param rti_chan The rti's network channel to check if it is still open. + * @return netchan_t The network channel for the newly accepted connection on success, or NULL on failure */ -netdrv_t accept_netdrv(netdrv_t server_drv, netdrv_t rti_drv); +netchan_t accept_netchan(netchan_t server_chan, netchan_t rti_chan); /** - * Using the initialized network driver, create a client network driver ready to connect to a server. + * Using the initialized network channel, create a client network channel ready to connect to a server. * - * @param drv The initialized network driver. + * @param chan The initialized network channel. */ -void create_client(netdrv_t drv); +void create_client(netchan_t chan); /** - * Connect to the server network driver. The server's connection information, + * Connect to the server network channel. The server's connection information, * such as the port and address should be set before calling this function. * - * @param drv Network driver to connect. + * @param chan network channel to connect. * @return int 0 on success, -1 on failure, and `errno` is set to indicate the specific error. */ -int connect_to_netdrv(netdrv_t drv); +int connect_to_netchan(netchan_t chan); /** - * Read the specified number of bytes from the specified network driver into the specified buffer. + * Read the specified number of bytes from the specified network channel into the specified buffer. * If an error occurs during this reading, return -1 and set errno to indicate * the cause of the error. If the read succeeds in reading the specified number of bytes, * return 0. If an EOF occurs before reading the specified number of bytes, return 1. - * @param drv The network driver. + * @param chan The network channel. * @param num_bytes The number of bytes to read. * @param buffer The buffer into which to put the bytes. * @return 0 for success, 1 for EOF, and -1 for an error. */ -int read_from_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); +int read_from_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer); /** - * Read the specified number of bytes to the specified network driver using read_from_netdrv - * and close the network driver if an error occurs. - * @param drv The network driver. + * Read the specified number of bytes to the specified network channel using read_from_netchan + * and close the network channel if an error occurs. + * @param chan The network channel. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. */ -int read_from_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer); +int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer); /** - * Read the specified number of bytes from the specified network driver into the + * Read the specified number of bytes from the specified network channel into the * specified buffer. If a disconnect or an EOF occurs during this * reading, then if format is non-null, report an error and exit. * If the mutex argument is non-NULL, release the mutex before exiting. * If format is null, then report the error, but do not exit. * This function takes a formatted string and additional optional arguments * similar to printf(format, ...) that is appended to the error messages. - * @param drv The network driver. + * @param chan The network channel. * @param num_bytes The number of bytes to read. * @param buffer The buffer into which to put the bytes. * @param format A printf-style format string, followed by arguments to @@ -89,40 +89,40 @@ int read_from_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned cha * @return The number of bytes read, or 0 if an EOF is received, or * a negative number for an error. */ -void read_from_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, +void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...); /** - * Write the specified number of bytes to the specified network driver from the + * Write the specified number of bytes to the specified network channel from the * specified buffer. If an error occurs, return -1 and set errno to indicate * the cause of the error. If the write succeeds, return 0. * This function repeats the attempt until the specified number of bytes * have been written or an error occurs. - * @param drv The network driver. + * @param chan The network channel. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. */ -int write_to_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer); +int write_to_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer); /** - * Write the specified number of bytes to the specified network driver using write_to_netdrv - * and close the network driver if an error occurs. - * @param drv The network driver. + * Write the specified number of bytes to the specified network channel using write_to_netchan + * and close the network channel if an error occurs. + * @param chan The network channel. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. */ -int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer); +int write_to_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer); /** - * Write the specified number of bytes to the specified network driver using - * write_to_netdrv_close_on_error and exit with an error code if an error occurs. + * Write the specified number of bytes to the specified network channel using + * write_to_netchan_close_on_error and exit with an error code if an error occurs. * If the mutex argument is non-NULL, release the mutex before exiting. If the * format argument is non-null, then use it an any additional arguments to form * the error message using printf conventions. Otherwise, print a generic error * message. - * @param drv The network driver. + * @param chan The network channel. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @param mutex If non-NULL, the mutex to unlock before exiting. @@ -130,89 +130,89 @@ int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char * fields that will be used to fill the format string as in printf, or NULL * to print a generic error message. */ -void write_to_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, +void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...); /** - * Checks if the network driver is still connected to the peer. + * Checks if the network channel is still connected to the peer. * - * @param drv The network driver. + * @param chan The network channel. * @return true if closed, false if still open. */ -bool check_netdrv_closed(netdrv_t drv); +bool check_netchan_closed(netchan_t chan); /** - * @brief Gracefully shuts down and closes the network driver, optionally reading until EOF. - * Shutdown and close the network driver. If read_before_closing is false, it just immediately calls shutdown() with + * @brief Gracefully shuts down and closes the network channel, optionally reading until EOF. + * Shutdown and close the network channel. If read_before_closing is false, it just immediately calls shutdown() with * SHUT_RDWR and close(). If read_before_closing is true, it calls shutdown with SHUT_WR, only disallowing further * writing. Then, it calls read() until EOF is received, and discards all received bytes. - * @param drv The network driver to shutdown and close. - * @param read_before_closing If true, read until EOF before closing the network driver. + * @param chan The network channel to shutdown and close. + * @param read_before_closing If true, read until EOF before closing the network channel. * @return int Returns 0 on success, -1 on failure (errno will indicate the error). */ -int shutdown_netdrv(netdrv_t drv, bool read_before_closing); +int shutdown_netchan(netchan_t chan, bool read_before_closing); /** - * Get the open port number from the network driver. + * Get the open port number from the network channel. * This is used when the federate sends a MSG_TYPE_ADDRESS_ADVERTISEMENT to the RTI, informing its port number. The RTI * will save this port number, and send it to the other federate in a MSG_TYPE_ADDRESS_QUERY_REPLY message. * - * @param drv The network driver. - * @return The port number of a server network driver. + * @param chan The network channel. + * @return The port number of a server network channel. */ -int32_t get_my_port(netdrv_t drv); +int32_t get_my_port(netchan_t chan); /** * Get the port number of the connected peer. * This is used by the RTI, when there is a request from the federate to the RTI, for the MSG_TYPE_ADDRESS_QUERY * message. * - * @param drv The network driver. + * @param chan The network channel. * @return Port number of the connected peer. */ -int32_t get_server_port(netdrv_t drv); +int32_t get_server_port(netchan_t chan); /** * Get the IP address of the connected peer. * - * @param drv The network driver. + * @param chan The network channel. * @return Pointer to the server IP address */ -struct in_addr* get_ip_addr(netdrv_t drv); +struct in_addr* get_ip_addr(netchan_t chan); /** * Get the hostname of the connected peer. * - * @param drv The network driver. + * @param chan The network channel. * @return Pointer to the server hostname */ -char* get_server_hostname(netdrv_t drv); +char* get_server_hostname(netchan_t chan); /** - * Set the user specified port to the created network driver. + * Set the user specified port to the created network channel. * - * @param drv The network driver. + * @param chan The network channel. * @param port The user specified port */ -void set_my_port(netdrv_t drv, int32_t port); +void set_my_port(netchan_t chan, int32_t port); /** - * Set server port number to the target network driver. + * Set server port number to the target network channel. * The federate and RTI receives the port number from another * federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. - * This function is used to set the network driver's target server port number. + * This function is used to set the network channel's target server port number. * - * @param drv The network driver. + * @param chan The network channel. * @param port The target server's port */ -void set_server_port(netdrv_t drv, int32_t port); +void set_server_port(netchan_t chan, int32_t port); /** - * Set the target server's hostname to the network driver. + * Set the target server's hostname to the network channel. * - * @param drv The network driver. + * @param chan The network channel. * @param hostname The target server's hostname */ -void set_server_hostname(netdrv_t drv, const char* hostname); +void set_server_hostname(netchan_t chan, const char* hostname); #endif /* NET_DRIVER_H */ diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 4841a91f2..0a8f18160 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -79,7 +79,7 @@ typedef enum socket_type_t { TCP, UDP } socket_type_t; /** * Mutex protecting socket close operations. */ -extern lf_mutex_t netdrv_mutex; +extern lf_mutex_t netchan_mutex; typedef struct socket_priv_t { int socket_descriptor; From dfce1533b23bc4c3f299a0f3f9a13453f4874a51 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 24 Feb 2025 15:15:37 -0700 Subject: [PATCH 134/167] Change lf_socket_support.c and socket_common.c name to netchan --- network/impl/src/lf_socket_support.c | 114 +++++++++++++-------------- network/impl/src/socket_common.c | 6 +- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index f82d5b456..fff54f805 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -8,15 +8,15 @@ #include "socket_common.h" #include "util.h" -static socket_priv_t* get_socket_priv_t(netdrv_t drv) { - if (drv == NULL) { - lf_print_error("Network driver is already closed."); +static socket_priv_t* get_socket_priv_t(netchan_t chan) { + if (chan == NULL) { + lf_print_error("Network channel is already closed."); return NULL; } - return (socket_priv_t*)drv; + return (socket_priv_t*)chan; } -netdrv_t initialize_netdrv() { +netchan_t initialize_netchan() { // Initialize priv. socket_priv_t* priv = malloc(sizeof(socket_priv_t)); if (priv == NULL) { @@ -33,37 +33,37 @@ netdrv_t initialize_netdrv() { priv->server_ip_addr.s_addr = 0; priv->server_port = -1; - return (netdrv_t)priv; + return (netchan_t)priv; } -void free_netdrv(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); +void free_netchan(netchan_t chan) { + socket_priv_t* priv = get_socket_priv_t(chan); free(priv); } -int create_server(netdrv_t drv, bool increment_port_on_retry) { - socket_priv_t* priv = get_socket_priv_t(drv); +int create_server(netchan_t chan, bool increment_port_on_retry) { + socket_priv_t* priv = get_socket_priv_t(chan); return create_socket_server(priv->user_specified_port, &priv->socket_descriptor, &priv->port, TCP, increment_port_on_retry); } -netdrv_t accept_netdrv(netdrv_t server_drv, netdrv_t rti_drv) { - socket_priv_t* serv_priv = get_socket_priv_t(server_drv); +netchan_t accept_netchan(netchan_t server_chan, netchan_t rti_chan) { + socket_priv_t* serv_priv = get_socket_priv_t(server_chan); int rti_socket; - if (rti_drv == NULL) { - // Set to -1, to indicate that this accept_netdrv() call is not trying to check if the rti_drv is available, inside + if (rti_chan == NULL) { + // Set to -1, to indicate that this accept_netchan() call is not trying to check if the rti_chan is available, inside // the accept_socket() function. rti_socket = -1; } else { - socket_priv_t* rti_priv = get_socket_priv_t(rti_drv); + socket_priv_t* rti_priv = get_socket_priv_t(rti_chan); rti_socket = rti_priv->socket_descriptor; } - netdrv_t fed_netdrv = initialize_netdrv(); - socket_priv_t* fed_priv = get_socket_priv_t(fed_netdrv); + netchan_t fed_netchan = initialize_netchan(); + socket_priv_t* fed_priv = get_socket_priv_t(fed_netchan); int sock = accept_socket(serv_priv->socket_descriptor, rti_socket); if (sock == -1) { - free_netdrv(fed_netdrv); + free_netchan(fed_netchan); return NULL; } fed_priv->socket_descriptor = sock; @@ -71,27 +71,27 @@ netdrv_t accept_netdrv(netdrv_t server_drv, netdrv_t rti_drv) { if (get_peer_address(fed_priv) != 0) { lf_print_error("RTI failed to get peer address."); }; - return fed_netdrv; + return fed_netchan; } -void create_client(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); +void create_client(netchan_t chan) { + socket_priv_t* priv = get_socket_priv_t(chan); priv->socket_descriptor = create_real_time_tcp_socket_errexit(); } -int connect_to_netdrv(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); +int connect_to_netchan(netchan_t chan) { + socket_priv_t* priv = get_socket_priv_t(chan); return connect_to_socket(priv->socket_descriptor, priv->server_hostname, priv->server_port); } -int read_from_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = get_socket_priv_t(drv); +int read_from_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = get_socket_priv_t(chan); return read_from_socket(priv->socket_descriptor, num_bytes, buffer); } -int read_from_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = get_socket_priv_t(drv); - int read_failed = read_from_netdrv(drv, num_bytes, buffer); +int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = get_socket_priv_t(chan); + int read_failed = read_from_netchan(chan, num_bytes, buffer); if (read_failed) { // Read failed. // Socket has probably been closed from the other side. @@ -102,10 +102,10 @@ int read_from_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned cha return 0; } -void read_from_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, +void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...) { va_list args; - int read_failed = read_from_netdrv_close_on_error(drv, num_bytes, buffer); + int read_failed = read_from_netchan_close_on_error(chan, num_bytes, buffer); if (read_failed) { // Read failed. if (mutex != NULL) { @@ -121,14 +121,14 @@ void read_from_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned cha } } -int write_to_netdrv(netdrv_t drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = get_socket_priv_t(drv); +int write_to_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = get_socket_priv_t(chan); return write_to_socket(priv->socket_descriptor, num_bytes, buffer); } -int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = get_socket_priv_t(drv); - int result = write_to_netdrv(drv, num_bytes, buffer); +int write_to_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = get_socket_priv_t(chan); + int result = write_to_netchan(chan, num_bytes, buffer); if (result) { // Write failed. // Socket has probably been closed from the other side. @@ -138,10 +138,10 @@ int write_to_netdrv_close_on_error(netdrv_t drv, size_t num_bytes, unsigned char return result; } -void write_to_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, +void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...) { va_list args; - int result = write_to_netdrv_close_on_error(drv, num_bytes, buffer); + int result = write_to_netchan_close_on_error(chan, num_bytes, buffer); if (result) { // Write failed. if (mutex != NULL) { @@ -157,56 +157,56 @@ void write_to_netdrv_fail_on_error(netdrv_t drv, size_t num_bytes, unsigned char } } -bool check_netdrv_closed(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); +bool check_netchan_closed(netchan_t chan) { + socket_priv_t* priv = get_socket_priv_t(chan); return check_socket_closed(priv->socket_descriptor); } -int shutdown_netdrv(netdrv_t drv, bool read_before_closing) { - if (drv == NULL) { +int shutdown_netchan(netchan_t chan, bool read_before_closing) { + if (chan == NULL) { lf_print("Socket already closed."); return 0; } - socket_priv_t* priv = get_socket_priv_t(drv); + socket_priv_t* priv = get_socket_priv_t(chan); int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); if (ret != 0) { lf_print_error("Failed to shutdown socket."); } - free_netdrv(drv); + free_netchan(chan); return ret; } -int32_t get_my_port(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); +int32_t get_my_port(netchan_t chan) { + socket_priv_t* priv = get_socket_priv_t(chan); return priv->port; } -int32_t get_server_port(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); +int32_t get_server_port(netchan_t chan) { + socket_priv_t* priv = get_socket_priv_t(chan); return priv->server_port; } -struct in_addr* get_ip_addr(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); +struct in_addr* get_ip_addr(netchan_t chan) { + socket_priv_t* priv = get_socket_priv_t(chan); return &priv->server_ip_addr; } -char* get_server_hostname(netdrv_t drv) { - socket_priv_t* priv = get_socket_priv_t(drv); +char* get_server_hostname(netchan_t chan) { + socket_priv_t* priv = get_socket_priv_t(chan); return priv->server_hostname; } -void set_my_port(netdrv_t drv, int32_t port) { - socket_priv_t* priv = get_socket_priv_t(drv); +void set_my_port(netchan_t chan, int32_t port) { + socket_priv_t* priv = get_socket_priv_t(chan); priv->port = port; } -void set_server_port(netdrv_t drv, int32_t port) { - socket_priv_t* priv = get_socket_priv_t(drv); +void set_server_port(netchan_t chan, int32_t port) { + socket_priv_t* priv = get_socket_priv_t(chan); priv->server_port = port; } -void set_server_hostname(netdrv_t drv, const char* hostname) { - socket_priv_t* priv = get_socket_priv_t(drv); +void set_server_hostname(netchan_t chan, const char* hostname) { + socket_priv_t* priv = get_socket_priv_t(chan); memcpy(priv->server_hostname, hostname, INET_ADDRSTRLEN); } diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 159de1d66..f5e1089ef 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -21,9 +21,9 @@ /** Number of nanoseconds to sleep before retrying a socket read. */ #define SOCKET_READ_RETRY_INTERVAL 1000000 -// Mutex lock held while performing networ driver close operations. -// A deadlock can occur if two threads simulataneously attempt to close the same network driver. -lf_mutex_t netdrv_mutex; +// Mutex lock held while performing network channel close operations. +// A deadlock can occur if two threads simulataneously attempt to close the same network channel. +lf_mutex_t netchan_mutex; int create_real_time_tcp_socket_errexit(void) { int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); From b46e98dcbb33cf9bbb64c2eafe42cc7a59fca990 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 24 Feb 2025 15:52:50 -0700 Subject: [PATCH 135/167] Minor fix. --- core/federated/RTI/rti_remote.h | 2 +- core/federated/federate.c | 12 ++++++------ network/api/net_driver.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index c6d7be099..81ab67984 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -46,7 +46,7 @@ typedef struct federate_info_t { // to a request for stop from the RTI. Used to prevent double-counting // a federate when handling lf_request_stop(). lf_thread_t thread_id; // The ID of the thread handling communication with this federate. - netchan_t fed_netchan; // The netdriver that the RTI handling each federate. + netchan_t fed_netchan; // The netchannel that the RTI handling each federate. struct sockaddr_in UDP_addr; // The UDP address for the federate. bool clock_synchronization_enabled; // Indicates the status of clock synchronization // for this federate. Enabled by default. diff --git a/core/federated/federate.c b/core/federated/federate.c index 14b9e4784..a9bb6d94e 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -72,7 +72,7 @@ int max_level_allowed_to_advance; * and the _fed global variable refers to that instance. */ federate_instance_t _fed = {.number_of_inbound_p2p_connections = 0, - .inbound_netdriv_listeners = NULL, + .inbound_netchan_listeners = NULL, .number_of_outbound_p2p_connections = 0, .inbound_p2p_handling_thread_id = 0, .last_TAG = {.time = NEVER, .microstep = 0u}, @@ -1665,12 +1665,12 @@ void lf_terminate_execution(environment_t* env) { LF_PRINT_DEBUG("Waiting for inbound p2p network channel listener threads."); // Wait for each inbound network channel listener thread to close. - if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_netdriv_listeners != NULL) { + if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_netchan_listeners != NULL) { LF_PRINT_LOG("Waiting for %zu threads listening for incoming messages to exit.", _fed.number_of_inbound_p2p_connections); for (size_t i = 0; i < _fed.number_of_inbound_p2p_connections; i++) { // Ignoring errors here. - lf_thread_join(_fed.inbound_netdriv_listeners[i], NULL); + lf_thread_join(_fed.inbound_netchan_listeners[i], NULL); } } @@ -1681,7 +1681,7 @@ void lf_terminate_execution(environment_t* env) { // For abnormal termination, there is no need to free memory. if (_lf_normal_termination) { LF_PRINT_DEBUG("Freeing memory occupied by the federate."); - free(_fed.inbound_netdriv_listeners); + free(_fed.inbound_netchan_listeners); free(federation_metadata.rti_host); free(federation_metadata.rti_user); } @@ -2005,7 +2005,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { LF_ASSERT_NON_NULL(env_arg); size_t received_federates = 0; // Allocate memory to store thread IDs. - _fed.inbound_netdriv_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); + _fed.inbound_netchan_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); while (received_federates < _fed.number_of_inbound_p2p_connections && !_lf_termination_executed) { // Wait for an incoming connection request. netchan_t netchan = accept_netchan(_fed.server_netchan, _fed.netchan_to_RTI); @@ -2083,7 +2083,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Start a thread to listen for incoming messages from other federates. // The fed_id is a uint16_t, which we assume can be safely cast to and from void*. void* fed_id_arg = (void*)(uintptr_t)remote_fed_id; - int result = lf_thread_create(&_fed.inbound_netdriv_listeners[received_federates], listen_to_federates, fed_id_arg); + int result = lf_thread_create(&_fed.inbound_netchan_listeners[received_federates], listen_to_federates, fed_id_arg); if (result != 0) { // Failed to create a listening thread. LF_MUTEX_LOCK(&netchan_mutex); diff --git a/network/api/net_driver.h b/network/api/net_driver.h index c6c2bc85d..07f37755d 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -12,8 +12,8 @@ typedef void* netchan_t; netchan_t initialize_netchan(); /** - * Create a netdriver server. This is such as a server socket which accepts connections. - * However this is only the creation of the server netdriver. + * Create a netchannel server. This is such as a server socket which accepts connections. + * However this is only the creation of the server network channel. * * @param chan Server's network channel. * @param serv_type Type of server, RTI or FED. From 392166f0d54dc38e4084fcf970708e91bdb85548 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Mar 2025 15:00:36 -0700 Subject: [PATCH 136/167] Minor fix on wrong merge. --- core/federated/federate.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index a948b1192..0024ca7b6 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -402,12 +402,12 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen * @param fed_id The ID of the peer federate sending messages to this * federate. */ -static void close_inbound_socket(int fed_id) { - LF_MUTEX_LOCK(&socket_mutex); - if (_fed.sockets_for_inbound_p2p_connections[fed_id] >= 0) { - shutdown_socket(&_fed.sockets_for_inbound_p2p_connections[fed_id], false); +static void close_inbound_netchan(int fed_id) { + LF_MUTEX_LOCK(&lf_inbound_netchan_mutex); + if (_fed.netchans_for_inbound_p2p_connections[fed_id] >= 0) { + shutdown_netchan(&_fed.netchans_for_inbound_p2p_connections[fed_id], false); } - LF_MUTEX_UNLOCK(&socket_mutex); + LF_MUTEX_UNLOCK(&lf_inbound_netchan_mutex); } /** @@ -2080,12 +2080,12 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { int result = lf_thread_create(&_fed.inbound_netchan_listeners[received_federates], listen_to_federates, fed_id_arg); if (result != 0) { // Failed to create a listening thread. - LF_MUTEX_LOCK(&socket_mutex); - if (_fed.sockets_for_inbound_p2p_connections[remote_fed_id] != -1) { - shutdown_socket(&socket_id, false); - _fed.sockets_for_inbound_p2p_connections[remote_fed_id] = -1; + LF_MUTEX_LOCK(&lf_inbound_netchan_mutex); + if (_fed.netchans_for_inbound_p2p_connections[remote_fed_id] != NULL) { + shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], false); + _fed.netchans_for_inbound_p2p_connections[remote_fed_id] = NULL; } - LF_MUTEX_UNLOCK(&socket_mutex); + LF_MUTEX_UNLOCK(&lf_inbound_netchan_mutex); lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", result); } From 287bdf8b94cdad1ec6a6f4b8bdf1c13d408a5451 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Thu, 6 Mar 2025 10:05:34 -0700 Subject: [PATCH 137/167] FIx merge errors. --- core/federated/federate.c | 16 ++++++++++++---- include/core/federated/federate.h | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 0024ca7b6..bbb8fdc38 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1950,10 +1950,18 @@ void lf_connect_to_rti(const char* hostname, int port) { void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); - if (create_server(specified_port, &_fed.server_socket, (uint16_t*)&_fed.server_port, TCP, false)) { - lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); + + netchan_t* server_netchan = initialize_netchan(); + set_my_port(server_netchan, specified_port); + + if (create_server(server_netchan, false)) { + lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); }; - LF_PRINT_LOG("Server for communicating with other federates started using port %d.", _fed.server_port); + _fed.server_netchan = server_netchan; + // Get the final server port to send to the RTI on an MSG_TYPE_ADDRESS_ADVERTISEMENT message. + int32_t server_port = get_my_port(server_netchan); + + LF_PRINT_LOG("Server for communicating with other federates started using port %d.", server_port); // Send the server port number to the RTI // on an MSG_TYPE_ADDRESS_ADVERTISEMENT message (@see net_common.h). @@ -1964,7 +1972,7 @@ void lf_create_server(int specified_port) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_AD, _lf_my_fed_id, NULL); - // No need for a mutex because we have the only handle on this network channel. + // No need for a mutex because we have the only handle on this network driver. write_to_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, "Failed to send address advertisement."); diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index c4eeb6fc9..56e1e6467 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -55,7 +55,7 @@ typedef struct federate_instance_t { * This is NULL if there are none and otherwise has size given by * number_of_inbound_p2p_connections. */ - lf_thread_t* inbound_netdriv_listeners; + lf_thread_t* inbound_netchan_listeners; /** * Number of outbound peer-to-peer connections from the federate. From 718d56d1d504a2ccab8b6ba02c77f3f9623ccc4e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 14 Mar 2025 09:39:55 +0900 Subject: [PATCH 138/167] Formatting --- network/api/net_driver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 07f37755d..dd6e86f7d 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -90,7 +90,7 @@ int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned * a negative number for an error. */ void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...); + char* format, ...); /** * Write the specified number of bytes to the specified network channel from the @@ -131,7 +131,7 @@ int write_to_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned c * to print a generic error message. */ void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...); + char* format, ...); /** * Checks if the network channel is still connected to the peer. From b95329c4d43866eab11c04887b5811d7281e12b7 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 14 Mar 2025 09:40:38 +0900 Subject: [PATCH 139/167] Minor change. --- network/impl/src/lf_socket_support.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index fff54f805..29f01da2e 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -51,8 +51,8 @@ netchan_t accept_netchan(netchan_t server_chan, netchan_t rti_chan) { socket_priv_t* serv_priv = get_socket_priv_t(server_chan); int rti_socket; if (rti_chan == NULL) { - // Set to -1, to indicate that this accept_netchan() call is not trying to check if the rti_chan is available, inside - // the accept_socket() function. + // Set to -1, to indicate that this accept_netchan() call is not trying to check if the rti_chan is available, + // inside the accept_socket() function. rti_socket = -1; } else { socket_priv_t* rti_priv = get_socket_priv_t(rti_chan); @@ -103,7 +103,7 @@ int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned } void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...) { + char* format, ...) { va_list args; int read_failed = read_from_netchan_close_on_error(chan, num_bytes, buffer); if (read_failed) { @@ -139,7 +139,7 @@ int write_to_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned c } void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...) { + char* format, ...) { va_list args; int result = write_to_netchan_close_on_error(chan, num_bytes, buffer); if (result) { From a59ec5d0e22e744a5c722d8edc7eea6d123f1f06 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 3 Nov 2025 15:04:29 -0700 Subject: [PATCH 140/167] Remove duplicate. --- network/api/socket_common.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 28ab6755a..c5705c67b 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -144,23 +144,6 @@ typedef struct socket_priv_t { struct sockaddr_in UDP_addr; // The UDP address for the federate. } socket_priv_t; -typedef struct socket_priv_t { - int socket_descriptor; - uint16_t port; // The port number. // - uint16_t user_specified_port; // Default as 0 for both RTI and federate. - - // The connected other side's info. The - char server_hostname[INET_ADDRSTRLEN]; // Human-readable IP address and - int32_t server_port; // port number of the socket server of the federate - // if it has any incoming direct connections from other federates. - // The port number will be -1 if there is no server or if the - // RTI has not been informed of the port number. - struct in_addr server_ip_addr; // Information about the IP address of the socket - // server of the federate. - - struct sockaddr_in UDP_addr; // The UDP address for the federate. -} socket_priv_t; - /** * @brief Create an IPv4 TCP socket with Nagle's algorithm disabled. * @ingroup Federated From ffe24abefea7c34e4acb2fc38ca04884514373e5 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 3 Nov 2025 15:06:08 -0700 Subject: [PATCH 141/167] Remove null on reads. --- core/federated/RTI/rti_remote.c | 102 +++++++++++++-------------- core/federated/clock-sync.c | 12 ++-- core/federated/federate.c | 86 +++++++++++----------- network/api/net_driver.h | 3 +- network/impl/src/lf_socket_support.c | 6 +- 5 files changed, 102 insertions(+), 107 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index f670fc746..211cad1df 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -185,9 +185,9 @@ void update_federate_next_event_tag_locked(uint16_t federate_id, tag_t next_even void handle_port_absent_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t message_size = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(int64_t) + sizeof(uint32_t); - read_from_netchan_fail_on_error(sending_federate->fed_netchan, message_size, &(buffer[1]), NULL, - " RTI failed to read port absent message from federate %u.", - sending_federate->enclave.id); + read_from_netchan_fail_on_error(sending_federate->fed_netchan, message_size, &(buffer[1]), + " RTI failed to read port absent message from federate %u.", + sending_federate->enclave.id); uint16_t reactor_port_id = extract_uint16(&(buffer[1])); uint16_t federate_id = extract_uint16(&(buffer[1 + sizeof(uint16_t)])); @@ -235,7 +235,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char // Forward the message. write_to_netchan_fail_on_error(fed->fed_netchan, message_size + 1, buffer, &rti_mutex, - "RTI failed to forward message to federate %d.", federate_id); + "RTI failed to forward message to federate %d.", federate_id); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -243,8 +243,8 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char void handle_timed_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t header_size = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(int64_t) + sizeof(uint32_t); // Read the header, minus the first byte which has already been read. - read_from_netchan_fail_on_error(sending_federate->fed_netchan, header_size - 1, &(buffer[1]), NULL, - "RTI failed to read the timed message header from remote federate."); + read_from_netchan_fail_on_error(sending_federate->fed_netchan, header_size - 1, &(buffer[1]), + "RTI failed to read the timed message header from remote federate."); // Extract the header information. of the sender uint16_t reactor_port_id; uint16_t federate_id; @@ -272,8 +272,8 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff sending_federate->enclave.id, federate_id, reactor_port_id, intended_tag.time - lf_time_start(), intended_tag.microstep); - read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, &(buffer[header_size]), NULL, - "RTI failed to read timed message from federate %d.", federate_id); + read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, &(buffer[header_size]), + "RTI failed to read timed message from federate %d.", federate_id); size_t bytes_read = bytes_to_read + header_size; // Following only works for string messages. // LF_PRINT_DEBUG("Message received by RTI: %s.", buffer + header_size); @@ -308,8 +308,8 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, buffer, NULL, - "RTI failed to clear message chunks."); + read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, buffer, + "RTI failed to clear message chunks."); total_bytes_read += bytes_to_read; } LF_MUTEX_UNLOCK(&rti_mutex); @@ -331,7 +331,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff } write_to_netchan_fail_on_error(fed->fed_netchan, bytes_read, buffer, &rti_mutex, - "RTI failed to forward message to federate %d.", federate_id); + "RTI failed to forward message to federate %d.", federate_id); // The message length may be longer than the buffer, // in which case we have to handle it in chunks. @@ -342,8 +342,8 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, buffer, NULL, - "RTI failed to read message chunks."); + read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, buffer, + "RTI failed to read message chunks."); total_bytes_read += bytes_to_read; // FIXME: a mutex needs to be held for this so that other threads @@ -351,7 +351,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff // holding the rti_mutex might be very expensive. Instead, each outgoing // network channel should probably have its own mutex. write_to_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer, &rti_mutex, - "RTI failed to send message chunks."); + "RTI failed to send message chunks."); } // Record this in-transit message in federate's in-transit message queue. @@ -380,9 +380,9 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff void handle_latest_tag_confirmed(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, - "RTI failed to read the content of the logical tag complete from federate %d.", - fed->enclave.id); + read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int64_t) + sizeof(uint32_t), buffer, + "RTI failed to read the content of the logical tag complete from federate %d.", + fed->enclave.id); tag_t completed = extract_tag(buffer); if (rti_remote->base.tracing_enabled) { tracepoint_rti_from_federate(receive_LTC, fed->enclave.id, &completed); @@ -398,9 +398,9 @@ void handle_latest_tag_confirmed(federate_info_t* fed) { void handle_next_event_tag(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int64_t) + sizeof(uint32_t), buffer, NULL, - "RTI failed to read the content of the next event tag from federate %d.", - fed->enclave.id); + read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int64_t) + sizeof(uint32_t), buffer, + "RTI failed to read the content of the next event tag from federate %d.", + fed->enclave.id); // Acquire a mutex lock to ensure that this state does not change while a // message is in transport or being used to determine a TAG. @@ -457,7 +457,7 @@ static void broadcast_stop_time_to_federates_locked() { tracepoint_rti_to_federate(send_STOP_GRN, fed->enclave.id, &rti_remote->base.max_stop_tag); } write_to_netchan_fail_on_error(fed->fed_netchan, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, - "RTI failed to send MSG_TYPE_STOP_GRANTED message to federate %d.", fed->enclave.id); + "RTI failed to send MSG_TYPE_STOP_GRANTED message to federate %d.", fed->enclave.id); } LF_PRINT_LOG("RTI sent to federates MSG_TYPE_STOP_GRANTED with tag " PRINTF_TAG, @@ -509,9 +509,9 @@ void handle_stop_request_message(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer, NULL, - "RTI failed to read the MSG_TYPE_STOP_REQUEST payload from federate %d.", - fed->enclave.id); + read_from_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer, + "RTI failed to read the MSG_TYPE_STOP_REQUEST payload from federate %d.", + fed->enclave.id); // Extract the proposed stop tag for the federate tag_t proposed_stop_tag = extract_tag(buffer); @@ -577,8 +577,8 @@ void handle_stop_request_message(federate_info_t* fed) { tracepoint_rti_to_federate(send_STOP_REQ, f->enclave.id, &rti_remote->base.max_stop_tag); } write_to_netchan_fail_on_error(f->fed_netchan, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, - "RTI failed to forward MSG_TYPE_STOP_REQUEST message to federate %d.", - f->enclave.id); + "RTI failed to forward MSG_TYPE_STOP_REQUEST message to federate %d.", + f->enclave.id); } } LF_PRINT_LOG("RTI forwarded to federates MSG_TYPE_STOP_REQUEST with tag (" PRINTF_TIME ", %u).", @@ -589,9 +589,9 @@ void handle_stop_request_message(federate_info_t* fed) { void handle_stop_request_reply(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_REPLY_LENGTH - 1; unsigned char buffer_stop_time[bytes_to_read]; - read_from_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer_stop_time, NULL, - "RTI failed to read the reply to MSG_TYPE_STOP_REQUEST message from federate %d.", - fed->enclave.id); + read_from_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer_stop_time, + "RTI failed to read the reply to MSG_TYPE_STOP_REQUEST message from federate %d.", + fed->enclave.id); tag_t federate_stop_tag = extract_tag(buffer_stop_time); @@ -619,8 +619,8 @@ void handle_address_query(uint16_t fed_id) { // Use buffer both for reading and constructing the reply. // The length is what is needed for the reply. unsigned char buffer[1 + sizeof(int32_t)]; - read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(uint16_t), (unsigned char*)buffer, NULL, - "Failed to read address query."); + read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(uint16_t), (unsigned char*)buffer, + "Failed to read address query."); uint16_t remote_fed_id = extract_uint16(buffer); if (rti_remote->base.tracing_enabled) { @@ -664,10 +664,10 @@ void handle_address_query(uint16_t fed_id) { // Send the port number (which could be -1) and the server IP address to federate. write_to_netchan_fail_on_error(fed->fed_netchan, 1 + sizeof(int32_t), (unsigned char*)buffer, &rti_mutex, - "Failed to write port number to network channel of federate %d.", fed_id); + "Failed to write port number to network channel of federate %d.", fed_id); write_to_netchan_fail_on_error(fed->fed_netchan, sizeof(uint32_t), (unsigned char*)ip_address, &rti_mutex, - "Failed to write ip address to network channel of federate %d.", fed_id); + "Failed to write ip address to network channel of federate %d.", fed_id); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, server_host_name, @@ -680,8 +680,8 @@ void handle_address_ad(uint16_t federate_id) { // connections to other federates int32_t server_port = -1; unsigned char buffer[sizeof(int32_t)]; - read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int32_t), (unsigned char*)buffer, NULL, - "Error reading port data from federate %d.", federate_id); + read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int32_t), (unsigned char*)buffer, + "Error reading port data from federate %d.", federate_id); server_port = extract_int32(buffer); @@ -700,8 +700,8 @@ void handle_address_ad(uint16_t federate_id) { void handle_timestamp(federate_info_t* my_fed) { unsigned char buffer[sizeof(int64_t)]; // Read bytes from the network channel. We need 8 bytes. - read_from_netchan_fail_on_error(my_fed->fed_netchan, sizeof(int64_t), (unsigned char*)&buffer, NULL, - "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); + read_from_netchan_fail_on_error(my_fed->fed_netchan, sizeof(int64_t), (unsigned char*)&buffer, + "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); int64_t timestamp = swap_bytes_if_big_endian_int64(*((int64_t*)(&buffer))); if (rti_remote->base.tracing_enabled) { @@ -782,7 +782,7 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool LF_PRINT_DEBUG("Clock sync: RTI sending message type %u.", buffer[0]); LF_MUTEX_LOCK(&rti_mutex); write_to_netchan_fail_on_error(fed->fed_netchan, 1 + sizeof(int64_t), buffer, &rti_mutex, - "Clock sync: RTI failed to send physical time to federate %d.", fed->enclave.id); + "Clock sync: RTI failed to send physical time to federate %d.", fed->enclave.id); LF_MUTEX_UNLOCK(&rti_mutex); } LF_PRINT_DEBUG("Clock sync: RTI sent PHYSICAL_TIME_SYNC_MESSAGE with timestamp " PRINTF_TIME " to federate %d.", @@ -1190,9 +1190,9 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { static int receive_connection_information(netchan_t fed_netchan, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; - read_from_netchan_fail_on_error(fed_netchan, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, NULL, - "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message header from federate %d.", - fed_id); + read_from_netchan_fail_on_error(fed_netchan, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, + "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message header from federate %d.", + fed_id); if (connection_info_header[0] != MSG_TYPE_NEIGHBOR_STRUCTURE) { lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " @@ -1230,9 +1230,9 @@ static int receive_connection_information(netchan_t fed_netchan, uint16_t fed_id if (connections_info_body_size > 0) { connections_info_body = (unsigned char*)malloc(connections_info_body_size); LF_ASSERT_NON_NULL(connections_info_body); - read_from_netchan_fail_on_error(fed_netchan, connections_info_body_size, connections_info_body, NULL, - "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message body from federate %d.", - fed_id); + read_from_netchan_fail_on_error(fed_netchan, connections_info_body_size, connections_info_body, + "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message body from federate %d.", + fed_id); // Keep track of where we are in the buffer size_t message_head = 0; // First, read the info about upstream federates @@ -1274,8 +1274,8 @@ static int receive_udp_message_and_set_up_clock_sync(netchan_t fed_netchan, uint // is doing clock synchronization, and if it is, what port to use for UDP. LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_UDP_PORT from federate %d.", fed_id); unsigned char response[1 + sizeof(uint16_t)]; - read_from_netchan_fail_on_error(fed_netchan, 1 + sizeof(uint16_t), response, NULL, - "RTI failed to read MSG_TYPE_UDP_PORT message from federate %d.", fed_id); + read_from_netchan_fail_on_error(fed_netchan, 1 + sizeof(uint16_t), response, + "RTI failed to read MSG_TYPE_UDP_PORT message from federate %d.", fed_id); if (response[0] != MSG_TYPE_UDP_PORT) { lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", @@ -1301,8 +1301,8 @@ static int receive_udp_message_and_set_up_clock_sync(netchan_t fed_netchan, uint // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); unsigned char buffer[message_size]; - read_from_netchan_fail_on_error(fed_netchan, message_size, buffer, NULL, - "network channel to federate %d unexpectedly closed.", fed_id); + read_from_netchan_fail_on_error(fed_netchan, message_size, buffer, + "network channel to federate %d unexpectedly closed.", fed_id); if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); LF_PRINT_DEBUG("RTI received T3 clock sync message from federate %d.", fed_id); @@ -1351,8 +1351,8 @@ static bool authenticate_federate(netchan_t fed_netchan) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); unsigned char buffer[1 + fed_id_length + NONCE_LENGTH]; - read_from_netchan_fail_on_error(fed_netchan, 1 + fed_id_length + NONCE_LENGTH, buffer, NULL, - "Failed to read MSG_TYPE_FED_NONCE"); + read_from_netchan_fail_on_error(fed_netchan, 1 + fed_id_length + NONCE_LENGTH, buffer, + "Failed to read MSG_TYPE_FED_NONCE"); if (buffer[0] != MSG_TYPE_FED_NONCE) { lf_print_error_and_exit("Received unexpected response %u from the FED (see net_common.h).", buffer[0]); } @@ -1382,7 +1382,7 @@ static bool authenticate_federate(netchan_t fed_netchan) { // Wait for MSG_TYPE_FED_RESPONSE unsigned char received[1 + hmac_length]; - read_from_netchan_fail_on_error(fed_netchan, 1 + hmac_length, received, NULL, "Failed to read federate response."); + read_from_netchan_fail_on_error(fed_netchan, 1 + hmac_length, received, "Failed to read federate response."); if (received[0] != MSG_TYPE_FED_RESPONSE) { lf_print_error_and_exit("Received unexpected response %u from the federate (see net_common.h).", received[0]); return false; diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index ad0d31e1d..ee8598fca 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -178,9 +178,9 @@ void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan) { for (int i = 0; i < _LF_CLOCK_SYNC_EXCHANGES_PER_INTERVAL; i++) { // The first message expected from the RTI is MSG_TYPE_CLOCK_SYNC_T1 - read_from_netchan_fail_on_error(rti_netchan, message_size, buffer, NULL, - "Federate %d did not get the initial clock synchronization message T1 from the RTI.", - _lf_my_fed_id); + read_from_netchan_fail_on_error( + rti_netchan, message_size, buffer, + "Federate %d did not get the initial clock synchronization message T1 from the RTI.", _lf_my_fed_id); // Get local physical time before doing anything else. instant_t receive_time = lf_time_physical(); @@ -197,9 +197,9 @@ void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan) { } // Next message from the RTI is required to be MSG_TYPE_CLOCK_SYNC_T4 - read_from_netchan_fail_on_error(rti_netchan, message_size, buffer, NULL, - "Federate %d did not get the clock synchronization message T4 from the RTI.", - _lf_my_fed_id); + read_from_netchan_fail_on_error(rti_netchan, message_size, buffer, + "Federate %d did not get the clock synchronization message T4 from the RTI.", + _lf_my_fed_id); // Check that this is the T4 message. if (buffer[0] != MSG_TYPE_CLOCK_SYNC_T4) { diff --git a/core/federated/federate.c b/core/federated/federate.c index 9bb248feb..a64c75c9b 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -112,7 +112,7 @@ static void send_time(unsigned char type, instant_t time) { LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, buffer, &lf_outbound_netchan_mutex, - "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); + "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); } @@ -139,7 +139,7 @@ static void send_tag(unsigned char type, tag_t tag) { return; } write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, buffer, &lf_outbound_netchan_mutex, - "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); + "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); } @@ -929,8 +929,8 @@ static instant_t get_start_time_from_rti(instant_t my_physical_time) { size_t buffer_length = 1 + sizeof(instant_t); unsigned char buffer[buffer_length]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, buffer_length, buffer, NULL, - "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, buffer_length, buffer, + "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); LF_PRINT_DEBUG("Read 9 bytes."); // First byte received is the message ID. @@ -973,8 +973,8 @@ static void handle_tag_advance_grant(void) { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, - "Failed to read tag advance grant from RTI."); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, + "Failed to read tag advance grant from RTI."); tag_t TAG = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1220,8 +1220,8 @@ static void handle_provisional_tag_advance_grant() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, - "Failed to read provisional tag advance grant from RTI."); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, + "Failed to read provisional tag advance grant from RTI."); tag_t PTAG = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1310,8 +1310,7 @@ static void handle_stop_granted_message() { size_t bytes_to_read = MSG_TYPE_STOP_GRANTED_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, - "Failed to read stop granted from RTI."); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, "Failed to read stop granted from RTI."); tag_t received_stop_tag = extract_tag(buffer); @@ -1354,8 +1353,7 @@ static void handle_stop_granted_message() { static void handle_stop_request_message() { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, - "Failed to read stop request from RTI."); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, "Failed to read stop request from RTI."); tag_t tag_to_stop = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1428,8 +1426,8 @@ static void handle_stop_request_message() { // Send the current logical time to the RTI. LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); write_to_netchan_fail_on_error(_fed.netchan_to_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, - &lf_outbound_netchan_mutex, - "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); + &lf_outbound_netchan_mutex, + "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); LF_PRINT_DEBUG("Sent MSG_TYPE_STOP_REQUEST_REPLY to RTI with tag " PRINTF_TAG, tag_to_stop.time, @@ -1442,8 +1440,8 @@ static void handle_stop_request_message() { static void handle_downstream_next_event_tag() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, NULL, - "Failed to read downstream next event tag from RTI."); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, + "Failed to read downstream next event tag from RTI."); tag_t DNET = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1475,7 +1473,7 @@ static void send_resign_signal() { buffer[0] = MSG_TYPE_RESIGN; LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netchan_mutex, - "Failed to send MSG_TYPE_RESIGN."); + "Failed to send MSG_TYPE_RESIGN."); LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); LF_PRINT_LOG("Resigned."); } @@ -1488,7 +1486,7 @@ static void send_failed_signal() { unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_FAILED; write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, &(buffer[0]), NULL, - "Failed to send MSG_TYPE_FAILED."); + "Failed to send MSG_TYPE_FAILED."); LF_PRINT_LOG("Failed."); } @@ -1721,13 +1719,13 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); write_to_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netchan_mutex, - "Failed to send address query for federate %d to RTI.", remote_federate_id); + "Failed to send address query for federate %d to RTI.", remote_federate_id); LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); // Read RTI's response. - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(int32_t) + 1, buffer, NULL, - "Failed to read the requested port number for federate %d from RTI.", - remote_federate_id); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(int32_t) + 1, buffer, + "Failed to read the requested port number for federate %d from RTI.", + remote_federate_id); if (buffer[0] != MSG_TYPE_ADDRESS_QUERY_REPLY) { // Unexpected reply. Could be that RTI has failed and sent a resignation. @@ -1739,8 +1737,8 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } port = extract_int32(&buffer[1]); - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, NULL, - "Failed to read the IP address for federate %d from RTI.", remote_federate_id); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, + "Failed to read the IP address for federate %d from RTI.", remote_federate_id); // A reply of -1 for the port means that the RTI does not know // the port number of the remote federate, presumably because the @@ -1806,18 +1804,18 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // No need for a mutex because we have the only handle on the network channel. write_to_netchan_fail_on_error(netchan, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", - remote_federate_id); - write_to_netchan_fail_on_error(netchan, federation_id_length, (unsigned char*)federation_metadata.federation_id, NULL, - "Failed to send federation id to federate %d.", remote_federate_id); - - read_from_netchan_fail_on_error(netchan, 1, (unsigned char*)buffer, NULL, - "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", remote_federate_id); + write_to_netchan_fail_on_error(netchan, federation_id_length, (unsigned char*)federation_metadata.federation_id, + NULL, "Failed to send federation id to federate %d.", remote_federate_id); + + read_from_netchan_fail_on_error(netchan, 1, (unsigned char*)buffer, + "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", + remote_federate_id); if (buffer[0] != MSG_TYPE_ACK) { // Get the error code. - read_from_netchan_fail_on_error(netchan, 1, (unsigned char*)buffer, NULL, - "Failed to read error code from federate %d in response to sending fed_id.", - remote_federate_id); + read_from_netchan_fail_on_error(netchan, 1, (unsigned char*)buffer, + "Failed to read error code from federate %d in response to sending fed_id.", + remote_federate_id); lf_print_error("Received MSG_TYPE_REJECT message from remote federate (%d).", buffer[0]); result = -1; // Wait ADDRESS_QUERY_RETRY_INTERVAL nanoseconds. @@ -1899,7 +1897,8 @@ void lf_connect_to_rti(const char* hostname, int port) { } // Next send the federation ID itself. - if (write_to_netchan(_fed.netchan_to_RTI, federation_id_length, (unsigned char*)federation_metadata.federation_id)) { + if (write_to_netchan(_fed.netchan_to_RTI, federation_id_length, + (unsigned char*)federation_metadata.federation_id)) { continue; // Try again. } @@ -1919,8 +1918,8 @@ void lf_connect_to_rti(const char* hostname, int port) { tracepoint_federate_from_rti(receive_REJECT, _lf_my_fed_id, NULL); // Read one more byte to determine the cause of rejection. unsigned char cause; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, 1, &cause, NULL, - "Failed to read the cause of rejection by the RTI."); + read_from_netchan_fail_on_error(_fed.netchan_to_RTI, 1, &cause, + "Failed to read the cause of rejection by the RTI."); if (cause == FEDERATION_ID_DOES_NOT_MATCH || cause == WRONG_SERVER) { lf_print_warning("Connected to the wrong RTI. Will try again"); continue; @@ -1952,7 +1951,7 @@ void lf_connect_to_rti(const char* hostname, int port) { UDP_port_number[0] = MSG_TYPE_UDP_PORT; encode_uint16(udp_port, &(UDP_port_number[1])); write_to_netchan_fail_on_error(_fed.netchan_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, - "Failed to send the UDP port number to the RTI."); + "Failed to send the UDP port number to the RTI."); } void lf_create_server(int specified_port) { @@ -1981,7 +1980,7 @@ void lf_create_server(int specified_port) { // No need for a mutex because we have the only handle on this network driver. write_to_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, - "Failed to send address advertisement."); + "Failed to send address advertisement."); LF_PRINT_DEBUG("Sent port %d to the RTI.", server_port); } @@ -2084,9 +2083,9 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - write_to_netchan_fail_on_error(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, - &lf_outbound_netchan_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", - remote_fed_id); + write_to_netchan_fail_on_error(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], 1, + (unsigned char*)&response, &lf_outbound_netchan_mutex, + "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); // Start a thread to listen for incoming messages from other federates. @@ -2459,8 +2458,9 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_STOP_REQ, _lf_my_fed_id, &stop_tag); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_netchan_mutex, - "Failed to send stop time " PRINTF_TIME " to the RTI.", stop_tag.time - start_time); + write_to_netchan_fail_on_error(_fed.netchan_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, + &lf_outbound_netchan_mutex, "Failed to send stop time " PRINTF_TIME " to the RTI.", + stop_tag.time - start_time); // Treat this sending as equivalent to having received a stop request from the RTI. _fed.received_stop_request_from_rti = true; diff --git a/network/api/net_driver.h b/network/api/net_driver.h index dd6e86f7d..f80a05c69 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -89,8 +89,7 @@ int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned * @return The number of bytes read, or 0 if an EOF is received, or * a negative number for an error. */ -void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...); +void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, char* format, ...); /** * Write the specified number of bytes to the specified network channel from the diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 29f01da2e..d0daca34f 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -102,15 +102,11 @@ int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned return 0; } -void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...) { +void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, char* format, ...) { va_list args; int read_failed = read_from_netchan_close_on_error(chan, num_bytes, buffer); if (read_failed) { // Read failed. - if (mutex != NULL) { - LF_MUTEX_UNLOCK(mutex); - } if (format != NULL) { va_start(args, format); lf_print_error_system_failure(format, args); From 56f9813784937b7d2e7196ab10a7e566b592780c Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 3 Nov 2025 15:26:41 -0700 Subject: [PATCH 142/167] Fix comments. --- core/federated/clock-sync.c | 29 ----------------------------- network/api/socket_common.h | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 42 deletions(-) diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index ee8598fca..396bcabf0 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -213,18 +213,6 @@ void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan) { LF_PRINT_LOG("Finished initial clock synchronization with the RTI."); } -/** - * Handle a clock synchroninzation message T1 coming from the RTI. - * T1 is the first message in a PTP exchange. - * This replies to the RTI with a T3 message. - * It also measures the time it takes between when the method is - * called and the reply has been sent. - * @param buffer The buffer containing the message, including the message type. - * @param socket_or_netchan The pointer of either UDP socket or the network channel. - * @param t2 The physical time at which the T1 message was received. - * @param use_UDP Boolean to use UDP or the network channel. - * @return 0 if T3 reply is successfully sent, -1 otherwise. - */ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t t2, bool use_udp) { // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); @@ -260,23 +248,6 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, return 0; } -/** - * Handle a clock synchronization message T4 coming from the RTI. - * If using the network channel, then assume we are in the - * initial clock synchronization phase and set the clock offset - * based on the estimated clock synchronization error. - * Otherwise, if using the UDP socket, then this looks also for a - * subsequent "coded probe" message on the socket. If the delay between - * the T4 and the coded probe message is not as expected, then reject - * this clock synchronization round. If it is not rejected, then make - * an adjustment to the clock offset based on the estimated error. - * This function does not acquire the netchan_mutex lock. - * The caller should acquire it unless it is sure there is only one thread running. - * @param buffer The buffer containing the message, including the message type. - * @param socket_or_netchan The pointer of either UDP socket or the network channel. - * @param r4 The physical time at which this T4 message was received. - * @param use_UDP Boolean to use UDP or the network channel. - */ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t r4, bool use_udp) { // Increment the number of received T4 messages _lf_rti_socket_stat.received_T4_messages_in_current_sync_window++; diff --git a/network/api/socket_common.h b/network/api/socket_common.h index c5705c67b..a1c92be9b 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -128,20 +128,22 @@ typedef enum socket_type_t { TCP, UDP } socket_type_t; typedef struct socket_priv_t { + /** @brief The TCP socket descriptor for the socket server. */ int socket_descriptor; - uint16_t port; // The port number. // - uint16_t user_specified_port; // Default as 0 for both RTI and federate. + /** @brief The final port number that the TCP socket server ends up using. */ + uint16_t port; + /** @brief The desired port specified by the user on the command line. */ + uint16_t user_specified_port; - // The connected other side's info. The + /** @brief Human-readable IP address of the federate's socket server. */ char server_hostname[INET_ADDRSTRLEN]; // Human-readable IP address and - int32_t server_port; // port number of the socket server of the federate - // if it has any incoming direct connections from other federates. - // The port number will be -1 if there is no server or if the - // RTI has not been informed of the port number. - struct in_addr server_ip_addr; // Information about the IP address of the socket - // server of the federate. - - struct sockaddr_in UDP_addr; // The UDP address for the federate. + /** @brief Port number of the socket server of the federate. The port number will be -1 if there is no server or if + * the RTI has not been informed of the port number. */ + int32_t server_port; + /** @brief Information about the IP address of the socket server of the federate. */ + struct in_addr server_ip_addr; + /** @brief The UDP address for the federate. */ + struct sockaddr_in UDP_addr; } socket_priv_t; /** @@ -293,8 +295,6 @@ bool check_socket_closed(int socket); */ int get_peer_address(socket_priv_t* priv); - - /** * @brief Write the specified number of bytes to the specified socket from the specified buffer. * @ingroup Federated From cba1cb1c92ec6970c621e4ae47b6aee34f35fd0f Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 3 Nov 2025 15:46:59 -0700 Subject: [PATCH 143/167] Fix on wrong mutex unlock. --- core/federated/federate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index a64c75c9b..9579a9fb2 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -2086,7 +2086,6 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { write_to_netchan_fail_on_error(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, &lf_outbound_netchan_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); // Start a thread to listen for incoming messages from other federates. // The fed_id is a uint16_t, which we assume can be safely cast to and from void*. @@ -2101,7 +2100,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", result); } - LF_MUTEX_UNLOCK(&lf_outbound_socket_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); received_federates++; } From 4f03dff2210fca2bd7b8cb042ce90523a86fb3cc Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Nov 2025 11:39:50 -0700 Subject: [PATCH 144/167] Merge with #540. --- core/federated/federate.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 9579a9fb2..0b9542bd9 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -133,11 +133,6 @@ static void send_tag(unsigned char type, tag_t tag) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(event_type, _lf_my_fed_id, &tag); LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - if (_fed.netchan_to_RTI == NULL) { - lf_print_warning("RTI is no longer connected. Dropping message."); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); - return; - } write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, buffer, &lf_outbound_netchan_mutex, "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); From fdbcb1ba7d48cd81412b4963f8bb120bcd95095d Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Nov 2025 11:40:02 -0700 Subject: [PATCH 145/167] Capitalize lf_print_log --- network/impl/src/socket_common.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 55e04d9bd..43a5ae6bd 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -280,7 +280,6 @@ int connect_to_socket(int sock, const char* hostname, int port) { freeaddrinfo(result); continue; } else { - freeaddrinfo(result); break; } } @@ -429,11 +428,11 @@ int shutdown_socket(int* socket, bool read_before_closing) { LF_MUTEX_LOCK(&shutdown_mutex); int result = 0; if (*socket < 0) { - lf_print_log("Socket is already closed."); + LF_PRINT_LOG("Socket is already closed."); } else { if (!read_before_closing) { if (shutdown(*socket, SHUT_RDWR)) { - lf_print_log("On shutdown socket, received reply: %s", strerror(errno)); + LF_PRINT_LOG("On shutdown socket, received reply: %s", strerror(errno)); result = -1; } // else shutdown reads and writes succeeded. } else { @@ -441,7 +440,7 @@ int shutdown_socket(int* socket, bool read_before_closing) { // This indicates the write direction is closed. For more details, refer to: // https://stackoverflow.com/questions/4160347/close-vs-shutdown-socket if (shutdown(*socket, SHUT_WR)) { - lf_print_log("Failed to shutdown socket: %s", strerror(errno)); + LF_PRINT_LOG("Failed to shutdown socket: %s", strerror(errno)); result = -1; } else { // Shutdown writes succeeded. @@ -463,7 +462,7 @@ int shutdown_socket(int* socket, bool read_before_closing) { // duplicated packets intended for this program. if (result != 0 && close(*socket)) { // Close failed. - lf_print_log("Error while closing socket: %s\n", strerror(errno)); + LF_PRINT_LOG("Error while closing socket: %s\n", strerror(errno)); result = -1; } *socket = -1; From fd533a675fc08e6d0310ea639f95df3a238d360e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Nov 2025 13:35:50 -0700 Subject: [PATCH 146/167] Cleanup and match #540 --- core/federated/federate.c | 30 ++---------------- network/impl/src/lf_socket_support.c | 9 ++---- network/impl/src/socket_common.c | 46 +++++----------------------- 3 files changed, 14 insertions(+), 71 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index 0b9542bd9..3190bf09e 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -389,21 +389,6 @@ static trigger_handle_t schedule_message_received_from_network_locked(environmen return return_value; } -/** - * Close the network channel that receives incoming messages from the - * specified federate ID. This function should be called when a read - * of incoming network channel fails or when an EOF is received. - * It can also be called when the receiving end wants to stop communication. - * - * @param fed_id The ID of the peer federate sending messages to this - * federate. - */ -static void close_inbound_netchan(int fed_id) { - if (_fed.netchans_for_inbound_p2p_connections[fed_id] >= 0) { - shutdown_netchan(&_fed.netchans_for_inbound_p2p_connections[fed_id], false); - } -} - /** * Return true if reactions need to be inserted directly into the reaction queue and * false if a call to schedule is needed (the normal case). This function handles zero-delay @@ -643,7 +628,7 @@ static int handle_tagged_message(netchan_t netchan, int fed_id) { // Free the allocated memory before returning _lf_done_using(message_token); // Close network channel, reading any incoming data and discarding it. - close_inbound_netchan(fed_id); + shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[fed_id], false); LF_MUTEX_UNLOCK(&env->mutex); return -1; } else { @@ -1648,7 +1633,7 @@ void lf_terminate_execution(environment_t* env) { LF_PRINT_DEBUG("Closing incoming P2P network channels."); // Close any incoming P2P network channels that are still open. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { - close_inbound_netchan(i); + shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[i], false); // Ignore errors. Mark the network channel closed. _fed.netchans_for_inbound_p2p_connections[i] = NULL; } @@ -2088,10 +2073,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { int result = lf_thread_create(&_fed.inbound_netchan_listeners[received_federates], listen_to_federates, fed_id_arg); if (result != 0) { // Failed to create a listening thread. - if (_fed.netchans_for_inbound_p2p_connections[remote_fed_id] != NULL) { - shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], false); - _fed.netchans_for_inbound_p2p_connections[remote_fed_id] = NULL; - } + shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], false); lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", result); } @@ -2407,12 +2389,6 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d tracepoint_federate_to_federate(send_PORT_ABS, _lf_my_fed_id, fed_ID, ¤t_message_intended_tag); #endif - if (netchan == _fed.netchan_to_RTI) { - tracepoint_federate_to_rti(send_PORT_ABS, _lf_my_fed_id, ¤t_message_intended_tag); - } else { - tracepoint_federate_to_federate(send_PORT_ABS, _lf_my_fed_id, fed_ID, ¤t_message_intended_tag); - } - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); int result = write_to_netchan_close_on_error(netchan, message_length, buffer); LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index d0daca34f..4e22b2517 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -148,7 +148,7 @@ void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned c lf_print_error_system_failure(format, args); va_end(args); } else { - lf_print_error("Failed to write to socket. Closing it."); + lf_print_error_and_exit("Failed to write to socket. Shutting down."); } } } @@ -160,14 +160,11 @@ bool check_netchan_closed(netchan_t chan) { int shutdown_netchan(netchan_t chan, bool read_before_closing) { if (chan == NULL) { - lf_print("Socket already closed."); + LF_PRINT_LOG("Socket already closed."); return 0; } socket_priv_t* priv = get_socket_priv_t(chan); - int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); - if (ret != 0) { - lf_print_error("Failed to shutdown socket."); - } + shutdown_socket(&priv->socket_descriptor, read_before_closing); free_netchan(chan); return ret; } diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 43a5ae6bd..33b699575 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -169,11 +169,15 @@ int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, bool check_socket_closed(int socket) { unsigned char first_byte; ssize_t bytes = peek_from_socket(socket, &first_byte); - if (bytes < 0 || (bytes == 1 && first_byte == MSG_TYPE_FAILED)) { - return true; - } else { - return false; + if (socket > 0) { + if (bytes < 0 || (bytes == 1 && first_byte == MSG_TYPE_FAILED)) { + return true; + } else { + return false; + } } + lf_print_warning("Socket is no longer connected."); + return true; } int get_peer_address(socket_priv_t* priv) { @@ -316,40 +320,6 @@ int read_from_socket(int socket, size_t num_bytes, unsigned char* buffer) { return 0; } -int read_from_socket_close_on_error(int* socket, size_t num_bytes, unsigned char* buffer) { - assert(socket); - int socket_id = *socket; // Assume atomic read so we don't pass -1 to read_from_socket. - if (socket_id >= 0) { - int read_failed = read_from_socket(socket_id, num_bytes, buffer); - if (read_failed) { - // Read failed. - // Socket has probably been closed from the other side. - // Shut down and close the socket from this side. - shutdown_socket(socket, false); - return -1; - } - return 0; - } - lf_print_warning("Socket is no longer connected. Read failed."); - return -1; -} - -void read_from_socket_fail_on_error(int* socket, size_t num_bytes, unsigned char* buffer, char* format, ...) { - va_list args; - assert(socket); - int read_failed = read_from_socket_close_on_error(socket, num_bytes, buffer); - if (read_failed) { - // Read failed. - if (format != NULL) { - va_start(args, format); - lf_print_error_system_failure(format, args); - va_end(args); - } else { - lf_print_error_system_failure("Failed to read from socket."); - } - } -} - ssize_t peek_from_socket(int socket, unsigned char* result) { ssize_t bytes_read = recv(socket, result, 1, MSG_DONTWAIT | MSG_PEEK); if (bytes_read < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) From e9bce57072bf62f7d8be217be8ef955d2bdd1f4d Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Nov 2025 13:38:23 -0700 Subject: [PATCH 147/167] Minor fix. --- network/impl/src/lf_socket_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 4e22b2517..a7029d9b2 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -164,7 +164,7 @@ int shutdown_netchan(netchan_t chan, bool read_before_closing) { return 0; } socket_priv_t* priv = get_socket_priv_t(chan); - shutdown_socket(&priv->socket_descriptor, read_before_closing); + int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); free_netchan(chan); return ret; } From 47542b1f7d9d2a09105cbfcfeb8e7a3d08960c9e Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Nov 2025 14:43:11 -0700 Subject: [PATCH 148/167] Minor remove. --- include/core/federated/clock-sync.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index cfbff3b2e..712433aa0 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -281,11 +281,6 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, */ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t r4, bool use_udp); -/** - * Thread that listens for UDP inputs from the RTI. - */ - void* listen_to_rti_UDP_thread(void* args); - /** * @brief Create the thread responsible for handling clock synchronization * with the RTI if (runtime) clock synchronization is on. From 626694de34179fd83bbc7a83a4b221d0773c8126 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Nov 2025 18:54:34 -0700 Subject: [PATCH 149/167] Minor fix. --- network/api/net_driver.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index f80a05c69..9df66bf74 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -175,7 +175,7 @@ int32_t get_server_port(netchan_t chan); * Get the IP address of the connected peer. * * @param chan The network channel. - * @return Pointer to the server IP address + * @return Pointer to the server IP address. */ struct in_addr* get_ip_addr(netchan_t chan); @@ -183,7 +183,7 @@ struct in_addr* get_ip_addr(netchan_t chan); * Get the hostname of the connected peer. * * @param chan The network channel. - * @return Pointer to the server hostname + * @return Pointer to the server hostname. */ char* get_server_hostname(netchan_t chan); @@ -191,7 +191,7 @@ char* get_server_hostname(netchan_t chan); * Set the user specified port to the created network channel. * * @param chan The network channel. - * @param port The user specified port + * @param port The user specified port. */ void set_my_port(netchan_t chan, int32_t port); @@ -202,7 +202,7 @@ void set_my_port(netchan_t chan, int32_t port); * This function is used to set the network channel's target server port number. * * @param chan The network channel. - * @param port The target server's port + * @param port The target server's port. */ void set_server_port(netchan_t chan, int32_t port); @@ -210,7 +210,7 @@ void set_server_port(netchan_t chan, int32_t port); * Set the target server's hostname to the network channel. * * @param chan The network channel. - * @param hostname The target server's hostname + * @param hostname The target server's hostname. */ void set_server_hostname(netchan_t chan, const char* hostname); From ed23af673f6959688de02f7c59509a859e312ca7 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Nov 2025 22:07:31 -0700 Subject: [PATCH 150/167] Minor fix. --- network/api/net_driver.h | 2 +- network/impl/src/lf_socket_support.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 9df66bf74..411ff89f6 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -47,7 +47,7 @@ void create_client(netchan_t chan); * such as the port and address should be set before calling this function. * * @param chan network channel to connect. - * @return int 0 on success, -1 on failure, and `errno` is set to indicate the specific error. + * @return 0 for success, -1 on failure, and `errno` is set to indicate the specific error. */ int connect_to_netchan(netchan_t chan); diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index a7029d9b2..8d84284bb 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -6,7 +6,7 @@ #include "net_driver.h" #include "socket_common.h" -#include "util.h" +#include "util.h" //TODO: need to check. static socket_priv_t* get_socket_priv_t(netchan_t chan) { if (chan == NULL) { From db8aa14d6fb00c5af6c81964d0bad6734d415f92 Mon Sep 17 00:00:00 2001 From: "Edward A. Lee" Date: Tue, 4 Nov 2025 22:59:08 -0800 Subject: [PATCH 151/167] format --- core/federated/RTI/rti_remote.h | 1 - 1 file changed, 1 deletion(-) diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 27e2a42c6..aafd4b7cb 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -123,7 +123,6 @@ typedef struct rti_remote_t { /** @brief The UDP socket descriptor for the socket server. */ int socket_descriptor_UDP; - /** * The rti's network channel. */ From d1642f28136e7043beae6f92ff07bcb3549332e2 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 5 Nov 2025 13:03:00 -0700 Subject: [PATCH 152/167] Minor change on comments. --- core/federated/RTI/rti_remote.h | 2 -- core/federated/federate.c | 2 +- network/api/socket_common.h | 15 ++++++----- network/impl/src/lf_socket_support.c | 2 +- network/impl/src/net_util.c | 3 +-- network/impl/src/socket_common.c | 40 +--------------------------- 6 files changed, 12 insertions(+), 52 deletions(-) diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index aafd4b7cb..dd28f32b9 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -393,8 +393,6 @@ void initialize_federate(federate_info_t* fed, uint16_t id); int start_rti_server(); /** - * Start the runtime infrastructure (RTI) interaction with the federates - * and wait for the federates to exit. * @brief Start the runtime infrastructure (RTI) interaction with the federates and wait for the federates to exit. * @ingroup RTI * diff --git a/core/federated/federate.c b/core/federated/federate.c index 3190bf09e..cee1d1feb 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -1493,7 +1493,7 @@ static void* listen_to_rti_netchan(void* args) { // Listen for messages from the federate. while (!_lf_termination_executed) { - // Check whether the RTI network channel is still valid + // Check whether the RTI network channel is still valid. if (_fed.netchan_to_RTI == NULL) { lf_print_warning("network channel to the RTI unexpectedly closed."); return NULL; diff --git a/network/api/socket_common.h b/network/api/socket_common.h index a1c92be9b..39bdf3673 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -110,11 +110,6 @@ */ #define DEFAULT_UDP_PORT 15061u -/** - * Default port number for the RTI's clock server. - */ -#define DEFAULT_UDP_PORT 15061u - /** * @brief Byte identifying that the federate or the RTI has failed. * @ingroup Federated @@ -134,9 +129,8 @@ typedef struct socket_priv_t { uint16_t port; /** @brief The desired port specified by the user on the command line. */ uint16_t user_specified_port; - /** @brief Human-readable IP address of the federate's socket server. */ - char server_hostname[INET_ADDRSTRLEN]; // Human-readable IP address and + char server_hostname[INET_ADDRSTRLEN]; /** @brief Port number of the socket server of the federate. The port number will be -1 if there is no server or if * the RTI has not been informed of the port number. */ int32_t server_port; @@ -174,6 +168,7 @@ int create_real_time_tcp_socket_errexit(void); * @param port The port number to use or 0 to let the OS pick or 1 to start trying at DEFAULT_PORT. * @param final_socket Pointer to the returned socket descriptor on which accepting connections will occur. * @param final_port Pointer to the final port the server will use. + * @param sock_type Type of the socket, TCP or UDP. * @param increment_port_on_retry Boolean to retry port increment. * @return 0 for success, -1 for failure. */ @@ -280,6 +275,9 @@ void read_from_socket_fail_on_error(int* socket, size_t num_bytes, unsigned char ssize_t peek_from_socket(int socket, unsigned char* result); /** + * @brief Check if the socket is closed. + * @ingroup Federated + * * Return true if either the socket to the RTI is broken or the socket is * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. * @param socket Socket to check. @@ -287,6 +285,9 @@ ssize_t peek_from_socket(int socket, unsigned char* result); */ bool check_socket_closed(int socket); /** + * @brief Get the connected peer address. + * @ingroup Federated + * * Get the connected peer name from the connected socket. * Set it to the server_ip_addr. Also, set server_hostname if LOG_LEVEL is higher than LOG_LEVEL_DEBUG. * diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 8d84284bb..956bd3743 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -6,7 +6,7 @@ #include "net_driver.h" #include "socket_common.h" -#include "util.h" //TODO: need to check. +#include "util.h" // LF_MUTEX_UNLOCK, "logging.h" static socket_priv_t* get_socket_priv_t(netchan_t chan) { if (chan == NULL) { diff --git a/network/impl/src/net_util.c b/network/impl/src/net_util.c index 491b29695..1f0aba0e8 100644 --- a/network/impl/src/net_util.c +++ b/network/impl/src/net_util.c @@ -9,7 +9,6 @@ #include #include #include -#include // For sqrtl() and powl #include // Defines va_list #include #include @@ -17,7 +16,7 @@ #include // Defines nanosleep() #include "net_util.h" -#include "util.h" +#include "logging_macros.h" // Below are more generally useful functions. diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 33b699575..04c086543 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -11,7 +11,7 @@ #include //va_list #include // strerror -#include "util.h" +#include "util.h" // LF_MUTEX_UNLOCK(), logging.h #include "net_driver.h" /** Number of nanoseconds to sleep before retrying a socket read. */ @@ -354,44 +354,6 @@ int write_to_socket(int socket, size_t num_bytes, unsigned char* buffer) { return 0; } -int write_to_socket_close_on_error(int* socket, size_t num_bytes, unsigned char* buffer) { - assert(socket); - int socket_id = *socket; // Assume atomic read so we don't pass -1 to write_to_socket. - if (socket_id >= 0) { - int result = write_to_socket(socket_id, num_bytes, buffer); - if (result) { - // Write failed. - // Socket has probably been closed from the other side. - // Shut down and close the socket from this side. - shutdown_socket(socket, false); - return -1; - } - return result; - } - lf_print_warning("Socket is no longer connected. Write failed."); - return -1; -} - -void write_to_socket_fail_on_error(int* socket, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...) { - va_list args; - assert(socket); - int result = write_to_socket_close_on_error(socket, num_bytes, buffer); - if (result) { - // Write failed. - if (mutex != NULL) { - LF_MUTEX_UNLOCK(mutex); - } - if (format != NULL) { - va_start(args, format); - lf_print_error_system_failure(format, args); - va_end(args); - } else { - lf_print_error_and_exit("Failed to write to socket. Shutting down."); - } - } -} - void init_shutdown_mutex(void) { LF_MUTEX_INIT(&shutdown_mutex); } int shutdown_socket(int* socket, bool read_before_closing) { From 0f44ebab4ccd2d26a0044d55139b9b42cca95b12 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 5 Nov 2025 13:10:10 -0700 Subject: [PATCH 153/167] Fix ingroup to Network --- network/api/net_common.h | 102 ++++++++++++++++++------------------ network/api/net_util.h | 48 ++++++++--------- network/api/socket_common.h | 56 ++++++++++---------- 3 files changed, 103 insertions(+), 103 deletions(-) diff --git a/network/api/net_common.h b/network/api/net_common.h index 07641fdbf..8f4855fcc 100644 --- a/network/api/net_common.h +++ b/network/api/net_common.h @@ -1,7 +1,7 @@ /** * @file net_common.h * @brief Common message types and definitions for federated Lingua Franca programs. - * @ingroup Federated + * @ingroup Network * * @author Edward A. Lee * @author Soroush Bateni @@ -185,7 +185,7 @@ /** * @brief Size of the buffer used for messages sent between federates. - * @ingroup Federated + * @ingroup Network * * This is used by both the federates and the RTI, so message lengths * should generally match. @@ -194,7 +194,7 @@ /** * @brief Time that a federate waits before asking the RTI again for the port and IP address of a federate. - * @ingroup Federated + * @ingroup Network * * The federate repeatedly sends an MSG_TYPE_ADDRESS_QUERY message after the RTI responds that it * does not know to previous such messages. This allows time for federates to start separately. @@ -203,7 +203,7 @@ /** * @brief Delay the start of all federates by this amount. - * @ingroup Federated + * @ingroup Network * * This helps ensure that the federates do not start at the same time. * Each federate has provided its current physical time to the RTI, and @@ -225,7 +225,7 @@ /** * @brief Byte identifying a rejection of the previously received message. - * @ingroup Federated + * @ingroup Network * * The reason for the rejection is included as an additional byte * (uchar) (see below for encodings of rejection reasons). @@ -234,7 +234,7 @@ /** * @brief Byte identifying an acknowledgment of the previously received message. - * @ingroup Federated + * @ingroup Network * * This message carries no payload. */ @@ -242,7 +242,7 @@ /** * @brief Byte identifying an acknowledgment of the previously received MSG_TYPE_FED_IDS message. - * @ingroup Federated + * @ingroup Network * * This message is sent by the RTI to the federate with a payload indicating the UDP port to use * for clock synchronization. The next four bytes will be the port number for the UDP server, or @@ -254,7 +254,7 @@ /** * @brief Byte identifying a message from a federate to an RTI containing * the federation ID and the federate ID. - * @ingroup Federated + * @ingroup Network * * The message contains, in this order: * * One byte equal to MSG_TYPE_FED_IDS. @@ -276,7 +276,7 @@ /** * @brief Byte identifying a message from a federate to an RTI containing * federate's 8-byte random nonce for HMAC-based authentication. - * @ingroup Federated + * @ingroup Network * * The federate sends this message to an incoming RTI when TCP connection is established * between the RTI and the federate. @@ -290,7 +290,7 @@ /** * @brief Byte identifying a message from RTI to federate as a response to the FED_NONCE * message. - * @ingroup Federated + * @ingroup Network * * The RTI sends this message to federate for HMAC-based authentication. * The message contains, in this order: @@ -307,7 +307,7 @@ /** * @brief Byte identifying a message from federate to RTI as a response to the RTI_RESPONSE * message. - * @ingroup Federated + * @ingroup Network * * The federate sends this message to RTI for HMAC-based authentication. * The message contains, in this order: @@ -321,19 +321,19 @@ /** * @brief The randomly created nonce size will be 8 bytes. - * @ingroup Federated + * @ingroup Network */ #define NONCE_LENGTH 8 /** * @brief The HMAC tag uses the SHA256 hash algorithm, creating a 32 byte length hash tag. - * @ingroup Federated + * @ingroup Network */ #define SHA256_HMAC_LENGTH 32 /** * @brief Byte identifying a timestamp message, which is 64 bits long. - * @ingroup Federated + * @ingroup Network * * Each federate sends its starting physical time as a message of this * type, and the RTI broadcasts to all the federates the starting logical @@ -343,13 +343,13 @@ /** * @brief The length of a timestamp message. - * @ingroup Federated + * @ingroup Network */ #define MSG_TYPE_TIMESTAMP_LENGTH (1 + sizeof(int64_t)) /** * @brief Byte identifying a message to forward to another federate. - * @ingroup Federated + * @ingroup Network * * The next two bytes will be the ID of the destination port. * The next two bytes are the destination federate ID. @@ -363,13 +363,13 @@ /** * @brief Byte identifying that the federate or the RTI is ending its execution. - * @ingroup Federated + * @ingroup Network */ #define MSG_TYPE_RESIGN 4 /** * @brief Byte identifying a timestamped message to forward to another federate. - * @ingroup Federated + * @ingroup Network * * The next two bytes will be the ID of the destination reactor port. * The next two bytes are the destination federate ID. @@ -387,7 +387,7 @@ /** * @brief Byte identifying a next event tag (NET) message sent from a federate in * centralized coordination. - * @ingroup Federated + * @ingroup Network * * The next eight bytes will be the timestamp. The next four bytes will be the microstep. * This message from a federate tells the RTI the tag of the earliest event on that @@ -406,7 +406,7 @@ /** * @brief Byte identifying a time advance grant (TAG) sent by the RTI to a federate * in centralized coordination. - * @ingroup Federated + * @ingroup Network * * This message is a promise by the RTI to the federate that no later message sent to the * federate will have a tag earlier than or equal to the tag carried by this TAG message. @@ -418,7 +418,7 @@ /** * @brief Byte identifying a provisional time advance grant (PTAG) sent by the RTI to a federate * in centralized coordination. - * @ingroup Federated + * @ingroup Network * * This message is a promise by the RTI to the federate that no later message sent to the * federate will have a tag earlier than the tag carried by this PTAG message. @@ -430,7 +430,7 @@ /** * @brief Byte identifying a latest tag confirmed (LTC) message sent by a federate * to the RTI. - * @ingroup Federated + * @ingroup Network * * The next eight bytes will be the timestep of the completed tag. * The next four bytes will be the microsteps of the completed tag. @@ -463,13 +463,13 @@ /** * @brief The length of a stop request message. - * @ingroup Federated + * @ingroup Network */ #define MSG_TYPE_STOP_REQUEST_LENGTH (1 + sizeof(instant_t) + sizeof(microstep_t)) /** * @brief Encode a stop request message. - * @ingroup Federated + * @ingroup Network * * @param buffer The buffer to encode the message into. * @param time The time at which the federates will stop. @@ -494,13 +494,13 @@ /** * @brief The length of a stop request reply message. - * @ingroup Federated + * @ingroup Network */ #define MSG_TYPE_STOP_REQUEST_REPLY_LENGTH (1 + sizeof(instant_t) + sizeof(microstep_t)) /** * @brief Encode a stop request reply message. - * @ingroup Federated + * @ingroup Network * * @param buffer The buffer to encode the message into. * @param time The time at which the federates will stop. @@ -516,7 +516,7 @@ /** * @brief Byte sent by the RTI indicating that the stop request from some federate * has been granted. - * @ingroup Federated + * @ingroup Network * * The payload is the tag at which all federates have agreed that they can stop. * The next 8 bytes will be the time at which the federates will stop. @@ -526,13 +526,13 @@ /** * @brief The length of a stop granted message. - * @ingroup Federated + * @ingroup Network */ #define MSG_TYPE_STOP_GRANTED_LENGTH (1 + sizeof(instant_t) + sizeof(microstep_t)) /** * @brief Encode a stop granted message. - * @ingroup Federated + * @ingroup Network * * @param buffer The buffer to encode the message into. * @param time The time at which the federates will stop. @@ -550,7 +550,7 @@ /** * @brief Byte identifying a address query message, sent by a federate to RTI * to ask for another federate's address and port number. - * @ingroup Federated + * @ingroup Network * * The next two bytes are the other federate's ID. */ @@ -559,7 +559,7 @@ /** * @brief Byte identifying a address query message reply, sent by a RTI to a federate * to reply with a remote federate's address and port number. - * @ingroup Federated + * @ingroup Network * * The reply from the RTI will be a port number (an int32_t), which is -1 * if the RTI does not know yet (it has not received MSG_TYPE_ADDRESS_ADVERTISEMENT from @@ -573,7 +573,7 @@ /** * @brief Byte identifying a message advertising the port for the TCP connection server * of a federate. - * @ingroup Federated + * @ingroup Network * * This is utilized in decentralized coordination as well as for physical * connections in centralized coordination. @@ -586,7 +586,7 @@ /** * @brief Byte identifying a first message that is sent by a federate directly to another federate * after establishing a socket connection to send messages directly to the federate. - * @ingroup Federated + * @ingroup Network * * This * first message contains two bytes identifying the sending federate (its ID), a byte @@ -599,7 +599,7 @@ /** * @brief Byte identifying a message to send directly to another federate. - * @ingroup Federated + * @ingroup Network * * The next two bytes will be the ID of the destination port. * The next two bytes are the destination federate ID. This is checked against @@ -611,7 +611,7 @@ /** * @brief Byte identifying a timestamped message to send directly to another federate. - * @ingroup Federated + * @ingroup Network * * This is a variant of @see MSG_TYPE_TAGGED_MESSAGE that is used in P2P connections between * federates. Having a separate message type for P2P connections between federates @@ -631,7 +631,7 @@ //////////////////////////////////////////////// /** * @brief Physical clock synchronization messages according to PTP. - * @ingroup Federated + * @ingroup Network * * The next 8 bytes will be a timestamp sent according to PTP. */ @@ -639,7 +639,7 @@ /** * @brief Prompt the master to send a T4. - * @ingroup Federated + * @ingroup Network * * The next four bytes will be the sending federate's id. */ @@ -647,7 +647,7 @@ /** * @brief Physical clock synchronization message according to PTP. - * @ingroup Federated + * @ingroup Network * * The next 8 bytes will be a timestamp sent according to PTP. */ @@ -655,7 +655,7 @@ /** * @brief Coded probe message. - * @ingroup Federated + * @ingroup Network * * This messages is sent by the server (master) * right after MSG_TYPE_CLOCK_SYNC_T4(t1) with a new physical clock snapshot t2. @@ -670,7 +670,7 @@ /** * @brief A port absent message, informing the receiver that a given port * will not have event for the current logical time. - * @ingroup Federated + * @ingroup Network * * The next 2 bytes is the port id. * The next 2 bytes will be the federate id of the destination federate. @@ -684,7 +684,7 @@ /** * @brief A message that informs the RTI about connections between this federate and * other federates where messages are routed through the RTI. - * @ingroup Federated + * @ingroup Network * * Currently, this only includes logical connections when the coordination is centralized. * This information is needed for the RTI to perform the centralized coordination. @@ -712,20 +712,20 @@ /** * @brief The size of the header of a neighbor structure message. - * @ingroup Federated + * @ingroup Network */ #define MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE 9 /** * @brief Byte identifying that the federate or the RTI has failed. - * @ingroup Federated + * @ingroup Network */ #define MSG_TYPE_FAILED 25 /** * @brief Byte identifying a downstream next event tag (DNET) message sent * from the RTI in centralized coordination. - * @ingroup Federated + * @ingroup Network * * The next eight bytes will be the timestamp. * The next four bytes will be the microstep. @@ -742,49 +742,49 @@ /** * @brief Code sent with a @ref MSG_TYPE_REJECT message indicating that the * federation ID does not match. - * @ingroup Federated + * @ingroup Network */ #define FEDERATION_ID_DOES_NOT_MATCH 1 /** * @brief Code sent with a @ref MSG_TYPE_REJECT message indicating that the * federate ID is already in use. - * @ingroup Federated + * @ingroup Network */ #define FEDERATE_ID_IN_USE 2 /** * @brief Code sent with a @ref MSG_TYPE_REJECT message indicating that the * federate ID is out of range. - * @ingroup Federated + * @ingroup Network */ #define FEDERATE_ID_OUT_OF_RANGE 3 /** * @brief Code sent with a @ref MSG_TYPE_REJECT message indicating that the * incoming message is not expected. - * @ingroup Federated + * @ingroup Network */ #define UNEXPECTED_MESSAGE 4 /** * @brief Code sent with a @ref MSG_TYPE_REJECT message indicating that the * connected to the wrong server. - * @ingroup Federated + * @ingroup Network */ #define WRONG_SERVER 5 /** * @brief Code sent with a @ref MSG_TYPE_REJECT message indicating that the * HMAC authentication failed. - * @ingroup Federated + * @ingroup Network */ #define HMAC_DOES_NOT_MATCH 6 /** * @brief Code sent with a @ref MSG_TYPE_REJECT message indicating that the * RTI was not executed using the -a or --auth option. - * @ingroup Federated + * @ingroup Network */ #define RTI_NOT_EXECUTED_WITH_AUTH 7 diff --git a/network/api/net_util.h b/network/api/net_util.h index 77e8db3c4..bdf7bccf0 100644 --- a/network/api/net_util.h +++ b/network/api/net_util.h @@ -1,7 +1,7 @@ /** * @file net_util.h * @brief Network utility functions for Lingua Franca programs. - * @ingroup Federated + * @ingroup Network * * @author Edward A. Lee * @author Soroush Bateni @@ -35,13 +35,13 @@ /** * @brief Return true (1) if the host is big endian. Otherwise, return false. - * @ingroup Federated + * @ingroup Network */ int host_is_big_endian(void); /** * @brief Write the specified data as a sequence of bytes starting at the specified address. - * @ingroup Federated + * @ingroup Network * * This encodes the data in little-endian order (lowest order byte first). * @param data The data to write. @@ -51,7 +51,7 @@ void encode_int64(int64_t data, unsigned char* buffer); /** * @brief Write the specified data as a sequence of bytes starting at the specified address. - * @ingroup Federated + * @ingroup Network * * This encodes the data in little-endian order (lowest order byte first). * This works for int32_t. @@ -62,7 +62,7 @@ void encode_int32(int32_t data, unsigned char* buffer); /** * @brief Write the specified data as a sequence of bytes starting at the specified address. - * @ingroup Federated + * @ingroup Network * * This encodes the data in little-endian order (lowest order byte first). * This works for uint32_t. @@ -73,7 +73,7 @@ void encode_uint32(uint32_t data, unsigned char* buffer); /** * @brief Write the specified data as a sequence of bytes starting at the specified address. - * @ingroup Federated + * @ingroup Network * * This encodes the data in little-endian order (lowest order byte first). * @param data The data to write. @@ -83,7 +83,7 @@ void encode_uint16(uint16_t data, unsigned char* buffer); /** * @brief If this host is little endian, then reverse the order of the bytes of the argument. - * @ingroup Federated + * @ingroup Network * * Otherwise, return the argument unchanged. * This can be used to convert the argument to network order (big endian) and then back again. @@ -97,7 +97,7 @@ int32_t swap_bytes_if_big_endian_int32(int32_t src); /** * @brief If this host is little endian, then reverse the order of the bytes of the argument. - * @ingroup Federated + * @ingroup Network * * Otherwise, return the argument unchanged. * This can be used to convert the argument to network order (big endian) and then back again. @@ -109,7 +109,7 @@ int64_t swap_bytes_if_big_endian_int64(int64_t src); /** * @brief If this host is little endian, then reverse the order of the bytes of the argument. - * @ingroup Federated + * @ingroup Network * * Otherwise, return the argument unchanged. * This can be used to convert the argument to network order (big endian) and then back again. @@ -123,7 +123,7 @@ uint16_t swap_bytes_if_big_endian_uint16(uint16_t src); /** * @brief This will swap the order of the bytes if this machine is big endian. - * @ingroup Federated + * @ingroup Network * * @param bytes The address of the start of the sequence of bytes. */ @@ -131,7 +131,7 @@ int32_t extract_int32(unsigned char* bytes); /** * @brief This will swap the order of the bytes if this machine is big endian. - * @ingroup Federated + * @ingroup Network * * @param bytes The address of the start of the sequence of bytes. */ @@ -139,7 +139,7 @@ int64_t extract_int64(unsigned char* bytes); /** * @brief Extract an uint16_t from the specified byte sequence. - * @ingroup Federated + * @ingroup Network * * This will swap the order of the bytes if this machine is big endian. * @param bytes The address of the start of the sequence of bytes. @@ -150,7 +150,7 @@ uint16_t extract_uint16(unsigned char* bytes); /** * @brief Extract the core header information that all messages between federates share. - * @ingroup Federated + * @ingroup Network * * The core header information is two bytes with the ID of the destination port, * two bytes with the ID of the destination federate, and four bytes with the length of the message. @@ -164,7 +164,7 @@ void extract_header(unsigned char* buffer, uint16_t* port_id, uint16_t* federate /** * @brief Extract the timed header information for timed messages between federates. - * @ingroup Federated + * @ingroup Network * * This is two bytes with the ID of the destination port, two bytes with the ID of the destination * federate, four bytes with the length of the message, eight bytes with a timestamp, and four bytes with a microstep. @@ -178,7 +178,7 @@ void extract_timed_header(unsigned char* buffer, uint16_t* port_id, uint16_t* fe /** * @brief Extract tag information from buffer. - * @ingroup Federated + * @ingroup Network * * The tag is transmitted as a 64-bit (8 byte) signed integer for time and a 32-bit (4 byte) unsigned integer for * microstep. @@ -189,7 +189,7 @@ tag_t extract_tag(unsigned char* buffer); /** * @brief Encode tag information into buffer. - * @ingroup Federated + * @ingroup Network * * Buffer must have been allocated externally. * @param buffer The buffer to encode into. @@ -199,7 +199,7 @@ void encode_tag(unsigned char* buffer, tag_t tag); /** * @brief A helper struct for passing rti_addr information between lf_parse_rti_addr and extract_rti_addr_info - * @ingroup Federated + * @ingroup Network * */ typedef struct rti_addr_info_t { @@ -213,7 +213,7 @@ typedef struct rti_addr_info_t { /** * @brief Check whether str matches regex. - * @ingroup Federated + * @ingroup Network * * @param str The string to check. * @param regex The regex to check against. @@ -223,7 +223,7 @@ bool match_regex(const char* str, char* regex); /** * @brief Check whether port is valid. - * @ingroup Federated + * @ingroup Network * * @param port The port to check. * @return true if valid, false otherwise. @@ -232,7 +232,7 @@ bool validate_port(char* port); /** * @brief Check whether host is valid. - * @ingroup Federated + * @ingroup Network * * @param host The host to check. * @return true if valid, false otherwise. @@ -241,7 +241,7 @@ bool validate_host(const char* host); /** * @brief Check whether user is valid. - * @ingroup Federated + * @ingroup Network * * @param user The user to check. * @return true if valid, false otherwise. @@ -250,7 +250,7 @@ bool validate_user(const char* user); /** * @brief Extract one match group from the rti_addr regex . - * @ingroup Federated + * @ingroup Network * * @param rti_addr The rti_addr to extract from. * @param dest The destination to store the match group. @@ -265,7 +265,7 @@ bool extract_match_group(const char* rti_addr, char* dest, regmatch_t group, siz /** * @brief Extract match groups from the rti_addr regex. - * @ingroup Federated + * @ingroup Network * * @param rti_addr The rti_addr to extract from. * @param rti_addr_strs The array of rti_addr strings to store the match groups. @@ -282,7 +282,7 @@ bool extract_match_groups(const char* rti_addr, char** rti_addr_strs, bool** rti /** * @brief Extract the host, port and user from rti_addr. - * @ingroup Federated + * @ingroup Network * * @param rti_addr The rti_addr to extract from. * @param rti_addr_info The rti_addr_info into which to store the extracted information. diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 39bdf3673..319bd0eba 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -1,7 +1,7 @@ /** * @file socket_common.h * @brief Common socket operations and utilities for federated Lingua Franca programs. - * @ingroup Federated + * @ingroup Network * * @author Edward A. Lee * @author Soroush Bateni @@ -22,7 +22,7 @@ /** * @brief The number of federates. - * @ingroup Federated + * @ingroup Network * * This defaults to 1. */ @@ -32,7 +32,7 @@ /** * @brief The amount of time to wait after a failed socket read or write before trying again. - * @ingroup Federated + * @ingroup Network * * This defaults to 100 ms. */ @@ -40,7 +40,7 @@ /** * @brief The timeout time in ns for TCP operations. - * @ingroup Federated + * @ingroup Network * * Default value is 10 secs. */ @@ -48,7 +48,7 @@ /** * @brief The timeout time in ns for UDP operations. - * @ingroup Federated + * @ingroup Network * * Default value is 1 sec. */ @@ -56,13 +56,13 @@ /** * @brief Time between a federate's attempts to connect to the RTI. - * @ingroup Federated + * @ingroup Network */ #define CONNECT_RETRY_INTERVAL MSEC(500) /** * @brief Bound on the number of retries to connect to the RTI. - * @ingroup Federated + * @ingroup Network * * A federate will retry every CONNECT_RETRY_INTERVAL nanoseconds until * CONNECTION_TIMEOUT expires. @@ -71,7 +71,7 @@ /** * @brief Maximum number of port addresses that a federate will try to connect to the RTI on. - * @ingroup Federated + * @ingroup Network * * If you are using automatic ports begining at DEFAULT_PORT, this puts an upper bound * on the number of RTIs that can be running on the same host. @@ -80,7 +80,7 @@ /** * @brief Time to wait before re-attempting to bind to a port. - * @ingroup Federated + * @ingroup Network * * When a process closes, the network stack typically waits between 30 and 120 * seconds before releasing the port. This is to allow for delayed packets so @@ -91,13 +91,13 @@ /** * @brief Number of attempts to bind to a port before giving up. - * @ingroup Federated + * @ingroup Network */ #define PORT_BIND_RETRY_LIMIT 60 /** * @brief Default port number for the RTI. - * @ingroup Federated + * @ingroup Network * * Unless a specific port has been specified by the LF program in the "at" * for the RTI or on the command line, when the RTI starts up, it will attempt @@ -112,13 +112,13 @@ /** * @brief Byte identifying that the federate or the RTI has failed. - * @ingroup Federated + * @ingroup Network */ #define MSG_TYPE_FAILED 25 /** * @brief Type of socket. - * @ingroup Federated + * @ingroup Network */ typedef enum socket_type_t { TCP, UDP } socket_type_t; @@ -142,7 +142,7 @@ typedef struct socket_priv_t { /** * @brief Create an IPv4 TCP socket with Nagle's algorithm disabled. - * @ingroup Federated + * @ingroup Network * * This uses TCP_NODELAY and Delayed ACKs disabled with TCP_QUICKACK. * It exits application on any error. @@ -153,7 +153,7 @@ int create_real_time_tcp_socket_errexit(void); /** * @brief Create a TCP server that listens for socket connections. - * @ingroup Federated + * @ingroup Network * * If the specified port number is greater than zero, this function will attempt to acquire that port. * If the specified port number is zero, and the increment_port_on_retry is true, it will attempt to acquire @@ -177,7 +177,7 @@ int create_socket_server(uint16_t port, int* final_socket, uint16_t* final_port, /** * @brief Wait for an incoming connection request on the specified server socket. - * @ingroup Federated + * @ingroup Network * * This blocks until a connection is successfully accepted. If an error occurs that is not * temporary (e.g., `EAGAIN` or `EWOULDBLOCK`), it reports the error and exits. Temporary @@ -197,7 +197,7 @@ int accept_socket(int socket, int rti_socket); /** * @brief Attempt to establish a TCP connection to the specified hostname and port. - * @ingroup Federated + * @ingroup Network * * Attempt to establish a TCP connection to the specified hostname * and port. This function uses `getaddrinfo` to resolve the hostname and retries the connection @@ -214,7 +214,7 @@ int connect_to_socket(int sock, const char* hostname, int port); /** * @brief Read the specified number of bytes from the specified socket into the specified buffer. - * @ingroup Federated + * @ingroup Network * * If an error occurs during this reading, return -1 and set errno to indicate * the cause of the error. If the read succeeds in reading the specified number of bytes, @@ -232,7 +232,7 @@ int read_from_socket(int socket, size_t num_bytes, unsigned char* buffer); /** * @brief Read the specified number of bytes from the specified socket into the specified buffer. - * @ingroup Federated + * @ingroup Network * * This uses @ref read_from_socket, but if a failure occurs, it closes the socket using * @ref shutdown_socket and returns -1. Otherwise, it returns 0. @@ -246,7 +246,7 @@ int read_from_socket_close_on_error(int* socket, size_t num_bytes, unsigned char /** * @brief Read the specified number of bytes from the specified socket into the specified * buffer and close the socket if an error occurs. - * @ingroup Federated + * @ingroup Network * * If a disconnect or an EOF occurs during this reading, then if format is non-null, * report an error and exit. @@ -264,7 +264,7 @@ void read_from_socket_fail_on_error(int* socket, size_t num_bytes, unsigned char /** * @brief Without blocking, peek at the specified socket. - * @ingroup Federated + * @ingroup Network * * If there is anything on the queue, put its first byte at the specified address and return 1. * If there is nothing on the queue, return 0, and if an error occurs, return -1. @@ -276,7 +276,7 @@ ssize_t peek_from_socket(int socket, unsigned char* result); /** * @brief Check if the socket is closed. - * @ingroup Federated + * @ingroup Network * * Return true if either the socket to the RTI is broken or the socket is * alive and the first unread byte on the socket's queue is MSG_TYPE_FAILED. @@ -286,7 +286,7 @@ ssize_t peek_from_socket(int socket, unsigned char* result); bool check_socket_closed(int socket); /** * @brief Get the connected peer address. - * @ingroup Federated + * @ingroup Network * * Get the connected peer name from the connected socket. * Set it to the server_ip_addr. Also, set server_hostname if LOG_LEVEL is higher than LOG_LEVEL_DEBUG. @@ -298,7 +298,7 @@ int get_peer_address(socket_priv_t* priv); /** * @brief Write the specified number of bytes to the specified socket from the specified buffer. - * @ingroup Federated + * @ingroup Network * * If an error occurs, return -1 and set errno to indicate the cause of the error. * If the write succeeds, return 0. @@ -316,7 +316,7 @@ int write_to_socket(int socket, size_t num_bytes, unsigned char* buffer); /** * @brief Write the specified number of bytes to the specified socket. - * @ingroup Federated + * @ingroup Network * * This uses @ref write_to_socket and closes the socket if an error occurs. * If an error occurs, this will change the socket ID pointed to by the first argument to -1 and will return -1. @@ -330,7 +330,7 @@ int write_to_socket_close_on_error(int* socket, size_t num_bytes, unsigned char* /** * @brief Write the specified number of bytes to the specified socket. - * @ingroup Federated + * @ingroup Network * * This uses @ref write_to_socket_close_on_error and exits with an error code if an error occurs. * If the mutex argument is non-NULL, release the mutex before exiting. @@ -351,7 +351,7 @@ void write_to_socket_fail_on_error(int* socket, size_t num_bytes, unsigned char* /** * @brief Initialize shutdown mutex. - * @ingroup Federated + * @ingroup Network * * This is used to synchronize the shutdown of the federate. */ @@ -359,7 +359,7 @@ void init_shutdown_mutex(void); /** * @brief Shutdown and close the socket. - * @ingroup Federated + * @ingroup Network * * If `read_before_closing` is false, this calls `shutdown` with `SHUT_RDWR`, shutting down both directions. * If this fails, then it calls `close`. From dc019049d61ef336600512fcf7ed37d27e3d70b9 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 5 Nov 2025 13:41:11 -0700 Subject: [PATCH 154/167] Fix for Doxygen. --- network/api/net_driver.h | 117 ++++++++++++++++++++++----- network/api/socket_common.h | 2 + network/impl/src/lf_socket_support.c | 8 ++ network/impl/src/socket_common.c | 10 +++ 4 files changed, 115 insertions(+), 22 deletions(-) diff --git a/network/api/net_driver.h b/network/api/net_driver.h index 411ff89f6..cf37367cc 100644 --- a/network/api/net_driver.h +++ b/network/api/net_driver.h @@ -1,3 +1,17 @@ +/** + * @file net_driver.h + * @brief Public network channel API (netchan) interface. + * @ingroup Network + * + * @author Dongha Kim + * @author Hokeun Kim + * + * This header defines the interface for network channels used by federated Lingua Franca programs. + * It abstracts network operations behind a small API that supports server/client creation, + * connection management, robust read/write with error handling, graceful shutdown, and + * querying local/peer addressing information. + */ + #ifndef NET_DRIVER_H #define NET_DRIVER_H @@ -6,22 +20,31 @@ typedef void* netchan_t; /** + * @brief Allocate and initialize a network channel handle. + * @ingroup Network + * * Allocate memory for the network channel. * @return netchan_t Initialized network channel. */ netchan_t initialize_netchan(); /** + * @brief Create a server network channel that will accept incoming connections. + * @ingroup Network + * * Create a netchannel server. This is such as a server socket which accepts connections. * However this is only the creation of the server network channel. * * @param chan Server's network channel. - * @param serv_type Type of server, RTI or FED. + * @param increment_port_on_retry Whether to increment the port on retry if binding fails. * @return int 0 for success, -1 for failure. */ int create_server(netchan_t chan, bool increment_port_on_retry); /** + * @brief Accept an incoming connection on a server network channel. + * @ingroup Network + * * Wait for an incoming connection request on the specified server network channel. * The implementation should include three steps. * 1. Initialize the network channel of the connected federate. @@ -36,6 +59,9 @@ int create_server(netchan_t chan, bool increment_port_on_retry); netchan_t accept_netchan(netchan_t server_chan, netchan_t rti_chan); /** + * @brief Initialize a client network channel for connecting to a server. + * @ingroup Network + * * Using the initialized network channel, create a client network channel ready to connect to a server. * * @param chan The initialized network channel. @@ -43,6 +69,9 @@ netchan_t accept_netchan(netchan_t server_chan, netchan_t rti_chan); void create_client(netchan_t chan); /** + * @brief Connect a client network channel to its configured server. + * @ingroup Network + * * Connect to the server network channel. The server's connection information, * such as the port and address should be set before calling this function. * @@ -52,10 +81,14 @@ void create_client(netchan_t chan); int connect_to_netchan(netchan_t chan); /** + * @brief Read a fixed number of bytes from a network channel. + * @ingroup Network + * * Read the specified number of bytes from the specified network channel into the specified buffer. - * If an error occurs during this reading, return -1 and set errno to indicate - * the cause of the error. If the read succeeds in reading the specified number of bytes, - * return 0. If an EOF occurs before reading the specified number of bytes, return 1. + * If an error occurs during reading, return -1 and set errno to indicate the cause. + * If the read succeeds in reading the specified number of bytes, return 0. + * If an EOF occurs before reading the specified number of bytes, return 1. + * * @param chan The network channel. * @param num_bytes The number of bytes to read. * @param buffer The buffer into which to put the bytes. @@ -64,39 +97,46 @@ int connect_to_netchan(netchan_t chan); int read_from_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer); /** - * Read the specified number of bytes to the specified network channel using read_from_netchan - * and close the network channel if an error occurs. + * @brief Read bytes and close the network channel on error. + * @ingroup Network + * + * Uses read_from_netchan and closes the channel if an error occurs. + * * @param chan The network channel. - * @param num_bytes The number of bytes to write. - * @param buffer The buffer from which to get the bytes. + * @param num_bytes The number of bytes to read. + * @param buffer The buffer into which to get the bytes. * @return 0 for success, -1 for failure. */ int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer); /** + * @brief Read bytes from a network channel and fail (exit) on error. + * @ingroup Network + * * Read the specified number of bytes from the specified network channel into the * specified buffer. If a disconnect or an EOF occurs during this * reading, then if format is non-null, report an error and exit. - * If the mutex argument is non-NULL, release the mutex before exiting. * If format is null, then report the error, but do not exit. * This function takes a formatted string and additional optional arguments * similar to printf(format, ...) that is appended to the error messages. + * * @param chan The network channel. * @param num_bytes The number of bytes to read. * @param buffer The buffer into which to put the bytes. * @param format A printf-style format string, followed by arguments to * fill the string, or NULL to not exit with an error message. - * @return The number of bytes read, or 0 if an EOF is received, or - * a negative number for an error. */ void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, char* format, ...); /** - * Write the specified number of bytes to the specified network channel from the - * specified buffer. If an error occurs, return -1 and set errno to indicate - * the cause of the error. If the write succeeds, return 0. - * This function repeats the attempt until the specified number of bytes - * have been written or an error occurs. + * @brief Write a fixed number of bytes to a network channel. + * @ingroup Network + * + * Write the specified number of bytes to the specified network channel using write_to_netchan + * and close the network channel if an error occurs. + * If an error occurs, return -1 and set errno to indicate the cause. If the write succeeds, return 0. + * This function retries until the specified number of bytes have been written or an error occurs. + * * @param chan The network channel. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. @@ -105,8 +145,11 @@ void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned int write_to_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer); /** - * Write the specified number of bytes to the specified network channel using write_to_netchan - * and close the network channel if an error occurs. + * @brief Write bytes to a network channel and close on error. + * @ingroup Network + * + * Uses write_to_netchan and closes the channel if an error occurs. + * * @param chan The network channel. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. @@ -115,6 +158,9 @@ int write_to_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer); int write_to_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer); /** + * @brief Write bytes to a network channel and fail (exit) on error. + * @ingroup Network + * * Write the specified number of bytes to the specified network channel using * write_to_netchan_close_on_error and exit with an error code if an error occurs. * If the mutex argument is non-NULL, release the mutex before exiting. If the @@ -133,6 +179,9 @@ void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned c char* format, ...); /** + * @brief Check whether the network channel is closed. + * @ingroup Network + * * Checks if the network channel is still connected to the peer. * * @param chan The network channel. @@ -141,10 +190,13 @@ void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned c bool check_netchan_closed(netchan_t chan); /** - * @brief Gracefully shuts down and closes the network channel, optionally reading until EOF. - * Shutdown and close the network channel. If read_before_closing is false, it just immediately calls shutdown() with - * SHUT_RDWR and close(). If read_before_closing is true, it calls shutdown with SHUT_WR, only disallowing further - * writing. Then, it calls read() until EOF is received, and discards all received bytes. + * @brief Gracefully shut down and close a network channel. + * @ingroup Network + * + * If read_before_closing is false, call shutdown() with SHUT_RDWR and then close(). If true, call shutdown() with SHUT_WR, + * then read() until EOF and discard received bytes before closing. + * + * @param chan The network channel to shut down and close. * @param chan The network channel to shutdown and close. * @param read_before_closing If true, read until EOF before closing the network channel. * @return int Returns 0 on success, -1 on failure (errno will indicate the error). @@ -152,6 +204,9 @@ bool check_netchan_closed(netchan_t chan); int shutdown_netchan(netchan_t chan, bool read_before_closing); /** + * @brief Get the server port number of this network channel. + * @ingroup Network + * * Get the open port number from the network channel. * This is used when the federate sends a MSG_TYPE_ADDRESS_ADVERTISEMENT to the RTI, informing its port number. The RTI * will save this port number, and send it to the other federate in a MSG_TYPE_ADDRESS_QUERY_REPLY message. @@ -162,6 +217,9 @@ int shutdown_netchan(netchan_t chan, bool read_before_closing); int32_t get_my_port(netchan_t chan); /** + * @brief Get the connected peer's port number. + * @ingroup Network + * * Get the port number of the connected peer. * This is used by the RTI, when there is a request from the federate to the RTI, for the MSG_TYPE_ADDRESS_QUERY * message. @@ -172,6 +230,9 @@ int32_t get_my_port(netchan_t chan); int32_t get_server_port(netchan_t chan); /** + * @brief Get the connected peer's IP address. + * @ingroup Network + * * Get the IP address of the connected peer. * * @param chan The network channel. @@ -180,6 +241,9 @@ int32_t get_server_port(netchan_t chan); struct in_addr* get_ip_addr(netchan_t chan); /** + * @brief Get the connected peer's hostname. + * @ingroup Network + * * Get the hostname of the connected peer. * * @param chan The network channel. @@ -188,6 +252,9 @@ struct in_addr* get_ip_addr(netchan_t chan); char* get_server_hostname(netchan_t chan); /** + * @brief Set the user-specified port for this network channel. + * @ingroup Network + * * Set the user specified port to the created network channel. * * @param chan The network channel. @@ -196,6 +263,9 @@ char* get_server_hostname(netchan_t chan); void set_my_port(netchan_t chan, int32_t port); /** + * @brief Set the target server's port number for this network channel. + * @ingroup Network + * * Set server port number to the target network channel. * The federate and RTI receives the port number from another * federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. @@ -207,6 +277,9 @@ void set_my_port(netchan_t chan, int32_t port); void set_server_port(netchan_t chan, int32_t port); /** + * @brief Set the target server's port number for this network channel. + * @ingroup Network + * * Set the target server's hostname to the network channel. * * @param chan The network channel. diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 319bd0eba..0e9490c5c 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -6,12 +6,14 @@ * @author Edward A. Lee * @author Soroush Bateni * @author Peter Donovan + * @author Dongha Kim * * This file provides common socket operations and utilities used in federated Lingua Franca programs. * It includes functions for creating and managing TCP/UDP sockets, handling connections, * and performing read/write operations with proper error handling and retry mechanisms. * The file also defines various constants for timeouts, retry intervals, and port configurations. */ + #ifndef SOCKET_COMMON_H #define SOCKET_COMMON_H diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 956bd3743..f13b72ad1 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -1,3 +1,11 @@ +/** + * @file + * @author Edward A. Lee + * @author Dongha Kim + * + * @brief Implementation of socket interface for federated Lingua Franca programs. + */ + #include // malloc() #include // strerror() #include // errno diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 04c086543..e424c3446 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -1,3 +1,13 @@ +/** + * @file + * @author Edward A. Lee + * @author Soroush Bateni + * @author Peter Donovan + * @author Dongha Kim + * + * @brief Common socket operations and utilities for federated Lingua Franca programs. + */ + #include // Defines read(), write(), and close() #include // IPPROTO_TCP, IPPROTO_UDP #include // TCP_NODELAY From a9c6cc435304fb10f56803fbb2f6311a580c04db Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 7 Nov 2025 12:41:51 -0700 Subject: [PATCH 155/167] Change names from net channel to network abstraction. --- core/federated/RTI/main.c | 2 +- core/federated/RTI/rti_remote.c | 301 ++++++++--------- core/federated/RTI/rti_remote.h | 22 +- core/federated/clock-sync.c | 27 +- core/federated/federate.c | 462 ++++++++++++++------------- include/core/federated/clock-sync.h | 26 +- include/core/federated/federate.h | 84 ++--- network/api/net_abstraction.h | 291 +++++++++++++++++ network/api/net_driver.h | 290 ----------------- network/impl/src/lf_socket_support.c | 115 +++---- network/impl/src/socket_common.c | 4 +- 11 files changed, 824 insertions(+), 800 deletions(-) create mode 100644 network/api/net_abstraction.h delete mode 100644 network/api/net_driver.h diff --git a/core/federated/RTI/main.c b/core/federated/RTI/main.c index 0bd37e64f..f8afef687 100644 --- a/core/federated/RTI/main.c +++ b/core/federated/RTI/main.c @@ -56,7 +56,7 @@ static void send_failed_signal(federate_info_t* fed) { if (rti.base.tracing_enabled) { tracepoint_rti_to_federate(send_FAILED, fed->enclave.id, NULL); } - int failed = write_to_netchan(fed->fed_netchan, bytes_to_write, &(buffer[0])); + int failed = write_to_net_abstraction(fed->fed_net_abstraction, bytes_to_write, &(buffer[0])); if (failed == 0) { LF_PRINT_LOG("RTI has sent failed signal to federate %d due to abnormal termination.", fed->enclave.id); } else { diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 211cad1df..2a26599ad 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -71,9 +71,9 @@ void notify_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_TAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the network channel might close, causing the following write_to_netchan + // function. During this call, the network abstraction might close, causing the following write_to_net_abstraction // to fail. Consider a failure here a soft failure and update the federate's status. - if (write_to_netchan(((federate_info_t*)e)->fed_netchan, message_length, buffer)) { + if (write_to_net_abstraction(((federate_info_t*)e)->fed_net_abstraction, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -104,9 +104,9 @@ void notify_provisional_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_PTAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the network channel might close, causing the following write_to_netchan + // function. During this call, the network abstraction might close, causing the following write_to_net_abstraction // to fail. Consider a failure here a soft failure and update the federate's status. - if (write_to_netchan(((federate_info_t*)e)->fed_netchan, message_length, buffer)) { + if (write_to_net_abstraction(((federate_info_t*)e)->fed_net_abstraction, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -163,7 +163,7 @@ void notify_downstream_next_event_tag(scheduling_node_t* e, tag_t tag) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_DNET, e->id, &tag); } - if (write_to_netchan(((federate_info_t*)e)->fed_netchan, message_length, buffer)) { + if (write_to_net_abstraction(((federate_info_t*)e)->fed_net_abstraction, message_length, buffer)) { lf_print_error("RTI failed to send downstream next event tag to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -185,9 +185,9 @@ void update_federate_next_event_tag_locked(uint16_t federate_id, tag_t next_even void handle_port_absent_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t message_size = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(int64_t) + sizeof(uint32_t); - read_from_netchan_fail_on_error(sending_federate->fed_netchan, message_size, &(buffer[1]), - " RTI failed to read port absent message from federate %u.", - sending_federate->enclave.id); + read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, message_size, &(buffer[1]), + " RTI failed to read port absent message from federate %u.", + sending_federate->enclave.id); uint16_t reactor_port_id = extract_uint16(&(buffer[1])); uint16_t federate_id = extract_uint16(&(buffer[1 + sizeof(uint16_t)])); @@ -198,7 +198,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char } // Need to acquire the mutex lock to ensure that the thread handling - // messages coming from the network channel connected to the destination does not + // messages coming from the network abstraction connected to the destination does not // issue a TAG before this message has been forwarded. LF_MUTEX_LOCK(&rti_mutex); @@ -234,8 +234,8 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char } // Forward the message. - write_to_netchan_fail_on_error(fed->fed_netchan, message_size + 1, buffer, &rti_mutex, - "RTI failed to forward message to federate %d.", federate_id); + write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, message_size + 1, buffer, &rti_mutex, + "RTI failed to forward message to federate %d.", federate_id); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -243,8 +243,8 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char void handle_timed_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t header_size = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(int64_t) + sizeof(uint32_t); // Read the header, minus the first byte which has already been read. - read_from_netchan_fail_on_error(sending_federate->fed_netchan, header_size - 1, &(buffer[1]), - "RTI failed to read the timed message header from remote federate."); + read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, header_size - 1, &(buffer[1]), + "RTI failed to read the timed message header from remote federate."); // Extract the header information. of the sender uint16_t reactor_port_id; uint16_t federate_id; @@ -272,8 +272,8 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff sending_federate->enclave.id, federate_id, reactor_port_id, intended_tag.time - lf_time_start(), intended_tag.microstep); - read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, &(buffer[header_size]), - "RTI failed to read timed message from federate %d.", federate_id); + read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, bytes_to_read, &(buffer[header_size]), + "RTI failed to read timed message from federate %d.", federate_id); size_t bytes_read = bytes_to_read + header_size; // Following only works for string messages. // LF_PRINT_DEBUG("Message received by RTI: %s.", buffer + header_size); @@ -283,12 +283,12 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff } // Need to acquire the mutex lock to ensure that the thread handling - // messages coming from the network channel connected to the destination does not + // messages coming from the network abstraction connected to the destination does not // issue a TAG before this message has been forwarded. LF_MUTEX_LOCK(&rti_mutex); // If the destination federate is no longer connected, issue a warning, - // remove the message from the network channel and return. + // remove the message from the network abstraction and return. federate_info_t* fed = GET_FED_INFO(federate_id); if (fed->enclave.state == NOT_CONNECTED) { lf_print_warning("RTI: Destination federate %d is no longer connected. Dropping message.", federate_id); @@ -308,8 +308,8 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, buffer, - "RTI failed to clear message chunks."); + read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, bytes_to_read, buffer, + "RTI failed to clear message chunks."); total_bytes_read += bytes_to_read; } LF_MUTEX_UNLOCK(&rti_mutex); @@ -330,8 +330,8 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff tracepoint_rti_to_federate(send_TAGGED_MSG, federate_id, &intended_tag); } - write_to_netchan_fail_on_error(fed->fed_netchan, bytes_read, buffer, &rti_mutex, - "RTI failed to forward message to federate %d.", federate_id); + write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, bytes_read, buffer, &rti_mutex, + "RTI failed to forward message to federate %d.", federate_id); // The message length may be longer than the buffer, // in which case we have to handle it in chunks. @@ -342,16 +342,16 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_netchan_fail_on_error(sending_federate->fed_netchan, bytes_to_read, buffer, - "RTI failed to read message chunks."); + read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, bytes_to_read, buffer, + "RTI failed to read message chunks."); total_bytes_read += bytes_to_read; // FIXME: a mutex needs to be held for this so that other threads // do not write to destination_socket and cause interleaving. However, // holding the rti_mutex might be very expensive. Instead, each outgoing - // network channel should probably have its own mutex. - write_to_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer, &rti_mutex, - "RTI failed to send message chunks."); + // network abstraction should probably have its own mutex. + write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, bytes_to_read, buffer, &rti_mutex, + "RTI failed to send message chunks."); } // Record this in-transit message in federate's in-transit message queue. @@ -380,9 +380,9 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff void handle_latest_tag_confirmed(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int64_t) + sizeof(uint32_t), buffer, - "RTI failed to read the content of the logical tag complete from federate %d.", - fed->enclave.id); + read_from_net_abstraction_fail_on_error( + fed->fed_net_abstraction, sizeof(int64_t) + sizeof(uint32_t), buffer, + "RTI failed to read the content of the logical tag complete from federate %d.", fed->enclave.id); tag_t completed = extract_tag(buffer); if (rti_remote->base.tracing_enabled) { tracepoint_rti_from_federate(receive_LTC, fed->enclave.id, &completed); @@ -398,9 +398,9 @@ void handle_latest_tag_confirmed(federate_info_t* fed) { void handle_next_event_tag(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int64_t) + sizeof(uint32_t), buffer, - "RTI failed to read the content of the next event tag from federate %d.", - fed->enclave.id); + read_from_net_abstraction_fail_on_error(fed->fed_net_abstraction, sizeof(int64_t) + sizeof(uint32_t), buffer, + "RTI failed to read the content of the next event tag from federate %d.", + fed->enclave.id); // Acquire a mutex lock to ensure that this state does not change while a // message is in transport or being used to determine a TAG. @@ -456,8 +456,9 @@ static void broadcast_stop_time_to_federates_locked() { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_STOP_GRN, fed->enclave.id, &rti_remote->base.max_stop_tag); } - write_to_netchan_fail_on_error(fed->fed_netchan, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, - "RTI failed to send MSG_TYPE_STOP_GRANTED message to federate %d.", fed->enclave.id); + write_to_net_abstraction_fail_on_error( + fed->fed_net_abstraction, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, + "RTI failed to send MSG_TYPE_STOP_GRANTED message to federate %d.", fed->enclave.id); } LF_PRINT_LOG("RTI sent to federates MSG_TYPE_STOP_GRANTED with tag " PRINTF_TAG, @@ -509,9 +510,9 @@ void handle_stop_request_message(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer, - "RTI failed to read the MSG_TYPE_STOP_REQUEST payload from federate %d.", - fed->enclave.id); + read_from_net_abstraction_fail_on_error(fed->fed_net_abstraction, bytes_to_read, buffer, + "RTI failed to read the MSG_TYPE_STOP_REQUEST payload from federate %d.", + fed->enclave.id); // Extract the proposed stop tag for the federate tag_t proposed_stop_tag = extract_tag(buffer); @@ -576,9 +577,9 @@ void handle_stop_request_message(federate_info_t* fed) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_STOP_REQ, f->enclave.id, &rti_remote->base.max_stop_tag); } - write_to_netchan_fail_on_error(f->fed_netchan, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, - "RTI failed to forward MSG_TYPE_STOP_REQUEST message to federate %d.", - f->enclave.id); + write_to_net_abstraction_fail_on_error( + f->fed_net_abstraction, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, + "RTI failed to forward MSG_TYPE_STOP_REQUEST message to federate %d.", f->enclave.id); } } LF_PRINT_LOG("RTI forwarded to federates MSG_TYPE_STOP_REQUEST with tag (" PRINTF_TIME ", %u).", @@ -589,9 +590,9 @@ void handle_stop_request_message(federate_info_t* fed) { void handle_stop_request_reply(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_REPLY_LENGTH - 1; unsigned char buffer_stop_time[bytes_to_read]; - read_from_netchan_fail_on_error(fed->fed_netchan, bytes_to_read, buffer_stop_time, - "RTI failed to read the reply to MSG_TYPE_STOP_REQUEST message from federate %d.", - fed->enclave.id); + read_from_net_abstraction_fail_on_error( + fed->fed_net_abstraction, bytes_to_read, buffer_stop_time, + "RTI failed to read the reply to MSG_TYPE_STOP_REQUEST message from federate %d.", fed->enclave.id); tag_t federate_stop_tag = extract_tag(buffer_stop_time); @@ -619,8 +620,8 @@ void handle_address_query(uint16_t fed_id) { // Use buffer both for reading and constructing the reply. // The length is what is needed for the reply. unsigned char buffer[1 + sizeof(int32_t)]; - read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(uint16_t), (unsigned char*)buffer, - "Failed to read address query."); + read_from_net_abstraction_fail_on_error(fed->fed_net_abstraction, sizeof(uint16_t), (unsigned char*)buffer, + "Failed to read address query."); uint16_t remote_fed_id = extract_uint16(buffer); if (rti_remote->base.tracing_enabled) { @@ -644,30 +645,32 @@ void handle_address_query(uint16_t fed_id) { char* server_host_name; LF_MUTEX_LOCK(&rti_mutex); - // Check if the RTI has initialized the remote federate's network channel. - if (remote_fed->fed_netchan == NULL) { + // Check if the RTI has initialized the remote federate's network abstraction. + if (remote_fed->fed_net_abstraction == NULL) { // RTI has not set up the remote federate. Respond with -1 to indicate an unknown port number. server_port = -1; uint32_t temp = 0; ip_address = &temp; server_host_name = "localhost"; } else { - // The network channel is initialized, but the RTI might still not know the port number. This can happen if the RTI - // has not yet received a MSG_TYPE_ADDRESS_ADVERTISEMENT message from the remote federate. In such cases, the + // The network abstraction is initialized, but the RTI might still not know the port number. This can happen if the + // RTI has not yet received a MSG_TYPE_ADDRESS_ADVERTISEMENT message from the remote federate. In such cases, the // returned port number might still be -1. - server_port = get_server_port(remote_fed->fed_netchan); - ip_address = (uint32_t*)get_ip_addr(remote_fed->fed_netchan); - server_host_name = get_server_hostname(remote_fed->fed_netchan); + server_port = get_server_port(remote_fed->fed_net_abstraction); + ip_address = (uint32_t*)get_ip_addr(remote_fed->fed_net_abstraction); + server_host_name = get_server_hostname(remote_fed->fed_net_abstraction); } encode_int32(server_port, (unsigned char*)&buffer[1]); // Send the port number (which could be -1) and the server IP address to federate. - write_to_netchan_fail_on_error(fed->fed_netchan, 1 + sizeof(int32_t), (unsigned char*)buffer, &rti_mutex, - "Failed to write port number to network channel of federate %d.", fed_id); + write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, 1 + sizeof(int32_t), (unsigned char*)buffer, + &rti_mutex, + "Failed to write port number to network abstraction of federate %d.", fed_id); - write_to_netchan_fail_on_error(fed->fed_netchan, sizeof(uint32_t), (unsigned char*)ip_address, &rti_mutex, - "Failed to write ip address to network channel of federate %d.", fed_id); + write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, sizeof(uint32_t), (unsigned char*)ip_address, + &rti_mutex, + "Failed to write ip address to network abstraction of federate %d.", fed_id); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, server_host_name, @@ -680,15 +683,15 @@ void handle_address_ad(uint16_t federate_id) { // connections to other federates int32_t server_port = -1; unsigned char buffer[sizeof(int32_t)]; - read_from_netchan_fail_on_error(fed->fed_netchan, sizeof(int32_t), (unsigned char*)buffer, - "Error reading port data from federate %d.", federate_id); + read_from_net_abstraction_fail_on_error(fed->fed_net_abstraction, sizeof(int32_t), (unsigned char*)buffer, + "Error reading port data from federate %d.", federate_id); server_port = extract_int32(buffer); assert(server_port < 65536); LF_MUTEX_LOCK(&rti_mutex); - set_server_port(fed->fed_netchan, server_port); + set_server_port(fed->fed_net_abstraction, server_port); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_LOG("Received address advertisement with port %d from federate %d.", server_port, federate_id); @@ -699,9 +702,9 @@ void handle_address_ad(uint16_t federate_id) { void handle_timestamp(federate_info_t* my_fed) { unsigned char buffer[sizeof(int64_t)]; - // Read bytes from the network channel. We need 8 bytes. - read_from_netchan_fail_on_error(my_fed->fed_netchan, sizeof(int64_t), (unsigned char*)&buffer, - "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); + // Read bytes from the network abstraction. We need 8 bytes. + read_from_net_abstraction_fail_on_error(my_fed->fed_net_abstraction, sizeof(int64_t), (unsigned char*)&buffer, + "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); int64_t timestamp = swap_bytes_if_big_endian_int64(*((int64_t*)(&buffer))); if (rti_remote->base.tracing_enabled) { @@ -742,7 +745,7 @@ void handle_timestamp(federate_info_t* my_fed) { tag_t tag = {.time = start_time, .microstep = 0}; tracepoint_rti_to_federate(send_TIMESTAMP, my_fed->enclave.id, &tag); } - if (write_to_netchan(my_fed->fed_netchan, MSG_TYPE_TIMESTAMP_LENGTH, start_time_buffer)) { + if (write_to_net_abstraction(my_fed->fed_net_abstraction, MSG_TYPE_TIMESTAMP_LENGTH, start_time_buffer)) { lf_print_error("Failed to send the starting time to federate %d.", my_fed->enclave.id); } @@ -758,8 +761,9 @@ void handle_timestamp(federate_info_t* my_fed) { void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP) { if (fed->enclave.state == NOT_CONNECTED) { - lf_print_warning("Clock sync: RTI failed to send physical time to federate %d. network channel not connected.\n", - fed->enclave.id); + lf_print_warning( + "Clock sync: RTI failed to send physical time to federate %d. network abstraction not connected.\n", + fed->enclave.id); return; } unsigned char buffer[sizeof(int64_t) + 1]; @@ -778,11 +782,12 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool return; } } else { - // Send using network channel. + // Send using network abstraction. LF_PRINT_DEBUG("Clock sync: RTI sending message type %u.", buffer[0]); LF_MUTEX_LOCK(&rti_mutex); - write_to_netchan_fail_on_error(fed->fed_netchan, 1 + sizeof(int64_t), buffer, &rti_mutex, - "Clock sync: RTI failed to send physical time to federate %d.", fed->enclave.id); + write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, 1 + sizeof(int64_t), buffer, &rti_mutex, + "Clock sync: RTI failed to send physical time to federate %d.", + fed->enclave.id); LF_MUTEX_UNLOCK(&rti_mutex); } LF_PRINT_DEBUG("Clock sync: RTI sent PHYSICAL_TIME_SYNC_MESSAGE with timestamp " PRINTF_TIME " to federate %d.", @@ -903,7 +908,7 @@ void* clock_synchronization_thread(void* noargs) { * @param my_fed The federate sending a MSG_TYPE_FAILED message. */ static void handle_federate_failed(federate_info_t* my_fed) { - // Nothing more to do. Close the network channel and exit. + // Nothing more to do. Close the network abstraction and exit. LF_MUTEX_LOCK(&rti_mutex); if (rti_remote->base.tracing_enabled) { @@ -919,7 +924,7 @@ static void handle_federate_failed(federate_info_t* my_fed) { // Indicate that there will no further events from this federate. my_fed->enclave.next_event = FOREVER_TAG; - shutdown_netchan(my_fed->fed_netchan, false); + shutdown_net_abstraction(my_fed->fed_net_abstraction, false); // Check downstream federates to see whether they should now be granted a TAG. // To handle cycles, need to create a boolean array to keep @@ -938,13 +943,13 @@ static void handle_federate_failed(federate_info_t* my_fed) { * This function assumes the caller does not hold the mutex. * * @note At this point, the RTI might have outgoing messages to the federate. This - * function thus first performs a shutdown on the network channel, which sends an EOF. It then - * waits for the remote network channel to be closed before closing the network channel itself. + * function thus first performs a shutdown on the network abstraction, which sends an EOF. It then + * waits for the remote network abstraction to be closed before closing the network abstraction itself. * * @param my_fed The federate sending a MSG_TYPE_RESIGN message. */ static void handle_federate_resign(federate_info_t* my_fed) { - // Nothing more to do. Close the network channel and exit. + // Nothing more to do. Close the network abstraction and exit. LF_MUTEX_LOCK(&rti_mutex); if (rti_remote->base.tracing_enabled) { @@ -958,7 +963,7 @@ static void handle_federate_resign(federate_info_t* my_fed) { // Indicate that there will no further events from this federate. my_fed->enclave.next_event = FOREVER_TAG; - shutdown_netchan(my_fed->fed_netchan, true); + shutdown_net_abstraction(my_fed->fed_net_abstraction, true); // Check downstream federates to see whether they should now be granted a TAG. // To handle cycles, need to create a boolean array to keep @@ -982,14 +987,14 @@ void* federate_info_thread_TCP(void* fed) { // Listen for messages from the federate. while (my_fed->enclave.state != NOT_CONNECTED) { // Read no more than one byte to get the message type. - int read_failed = read_from_netchan(my_fed->fed_netchan, 1, buffer); + int read_failed = read_from_net_abstraction(my_fed->fed_net_abstraction, 1, buffer); if (read_failed) { - // network channel is closed - lf_print_error("RTI: network channel to federate %d is closed. Exiting the thread.", my_fed->enclave.id); + // network abstraction is closed + lf_print_error("RTI: network abstraction to federate %d is closed. Exiting the thread.", my_fed->enclave.id); my_fed->enclave.state = NOT_CONNECTED; - // Nothing more to do. Close the network channel and exit. - // Prevent multiple threads from closing the same network channel at the same time. - shutdown_netchan(my_fed->fed_netchan, false); + // Nothing more to do. Close the network abstraction and exit. + // Prevent multiple threads from closing the same network abstraction at the same time. + shutdown_net_abstraction(my_fed->fed_net_abstraction, false); // FIXME: We need better error handling here, but do not stop execution here. break; } @@ -1042,18 +1047,18 @@ void* federate_info_thread_TCP(void* fed) { return NULL; } -void send_reject(netchan_t chan, unsigned char error_code) { +void send_reject(net_abstraction_t net_abs, unsigned char error_code) { LF_PRINT_DEBUG("RTI sending MSG_TYPE_REJECT."); unsigned char response[2]; response[0] = MSG_TYPE_REJECT; response[1] = error_code; LF_MUTEX_LOCK(&rti_mutex); // NOTE: Ignore errors on this response. - if (write_to_netchan(chan, 2, response)) { - lf_print_warning("RTI failed to write MSG_TYPE_REJECT message on the network channel."); + if (write_to_net_abstraction(net_abs, 2, response)) { + lf_print_warning("RTI failed to write MSG_TYPE_REJECT message on the network abstraction."); } - // Close the network channel without reading until EOF. - shutdown_netchan(chan, false); + // Close the network abstraction without reading until EOF. + shutdown_net_abstraction(net_abs, false); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -1062,17 +1067,17 @@ void send_reject(netchan_t chan, unsigned char error_code) { * a federate ID and a federation ID. If the federation ID * matches this federation, send an MSG_TYPE_ACK and otherwise send * a MSG_TYPE_REJECT message. - * @param fed_netchan Pointer to the network channel on which to listen. + * @param fed_net_abstraction Pointer to the network abstraction on which to listen. * @return The federate ID for success or -1 for failure. */ -static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { +static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstraction) { // Buffer for message ID, federate ID, and federation ID length. size_t length = 1 + sizeof(uint16_t) + 1; // Message ID, federate ID, length of fedration ID. unsigned char buffer[length]; - // Read bytes from the network channel. We need 4 bytes. - if (read_from_netchan_close_on_error(fed_netchan, length, buffer)) { - lf_print_error("RTI failed to read from accepted network channel."); + // Read bytes from the network abstraction. We need 4 bytes. + if (read_from_net_abstraction_close_on_error(fed_net_abstraction, length, buffer)) { + lf_print_error("RTI failed to read from accepted network abstraction."); return -1; } @@ -1091,12 +1096,12 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { // of the peer they want to connect to from the RTI. // If the connection is a peer-to-peer connection between two // federates, reject the connection with the WRONG_SERVER error. - send_reject(fed_netchan, WRONG_SERVER); + send_reject(fed_net_abstraction, WRONG_SERVER); } else if (buffer[0] == MSG_TYPE_FED_NONCE) { - send_reject(fed_netchan, RTI_NOT_EXECUTED_WITH_AUTH); + send_reject(fed_net_abstraction, RTI_NOT_EXECUTED_WITH_AUTH); lf_print_error("RTI not executed with HMAC authentication option using -a or --auth."); } else { - send_reject(fed_netchan, UNEXPECTED_MESSAGE); + send_reject(fed_net_abstraction, UNEXPECTED_MESSAGE); } lf_print_error("RTI expected a MSG_TYPE_FED_IDS message. Got %u (see net_common.h).", buffer[0]); return -1; @@ -1109,7 +1114,8 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { size_t federation_id_length = (size_t)buffer[sizeof(uint16_t) + 1]; char federation_id_received[federation_id_length + 1]; // One extra for null terminator. // Next read the actual federation ID. - if (read_from_netchan_close_on_error(fed_netchan, federation_id_length, (unsigned char*)federation_id_received)) { + if (read_from_net_abstraction_close_on_error(fed_net_abstraction, federation_id_length, + (unsigned char*)federation_id_received)) { lf_print_error("RTI failed to read federation id from federate %d.", fed_id); return -1; } @@ -1130,7 +1136,7 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_netchan, FEDERATION_ID_DOES_NOT_MATCH); + send_reject(fed_net_abstraction, FEDERATION_ID_DOES_NOT_MATCH); return -1; } else { if (fed_id >= rti_remote->base.number_of_scheduling_nodes) { @@ -1139,7 +1145,7 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_netchan, FEDERATE_ID_OUT_OF_RANGE); + send_reject(fed_net_abstraction, FEDERATE_ID_OUT_OF_RANGE); return -1; } else { if ((rti_remote->base.scheduling_nodes[fed_id])->state != NOT_CONNECTED) { @@ -1147,7 +1153,7 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_netchan, FEDERATE_ID_IN_USE); + send_reject(fed_net_abstraction, FEDERATE_ID_IN_USE); return -1; } } @@ -1156,7 +1162,7 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { federate_info_t* fed = GET_FED_INFO(fed_id); // The MSG_TYPE_FED_IDS message has the right federation ID. - fed->fed_netchan = fed_netchan; + fed->fed_net_abstraction = fed_net_abstraction; // Set the federate's state as pending // because it is waiting for the start time to be @@ -1170,7 +1176,7 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { tracepoint_rti_to_federate(send_ACK, fed_id, NULL); } LF_MUTEX_LOCK(&rti_mutex); - if (write_to_netchan_close_on_error(fed->fed_netchan, 1, &ack_message)) { + if (write_to_net_abstraction_close_on_error(fed->fed_net_abstraction, 1, &ack_message)) { LF_MUTEX_UNLOCK(&rti_mutex); lf_print_error("RTI failed to write MSG_TYPE_ACK message to federate %d.", fed_id); return -1; @@ -1187,18 +1193,18 @@ static int32_t receive_and_check_fed_id_message(netchan_t fed_netchan) { * out the relevant information in the federate's struct. * @return 1 on success and 0 on failure. */ -static int receive_connection_information(netchan_t fed_netchan, uint16_t fed_id) { +static int receive_connection_information(net_abstraction_t fed_net_abstraction, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; - read_from_netchan_fail_on_error(fed_netchan, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, - "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message header from federate %d.", - fed_id); + read_from_net_abstraction_fail_on_error( + fed_net_abstraction, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, + "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message header from federate %d.", fed_id); if (connection_info_header[0] != MSG_TYPE_NEIGHBOR_STRUCTURE) { lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", fed_id, connection_info_header[0]); - send_reject(fed_netchan, UNEXPECTED_MESSAGE); + send_reject(fed_net_abstraction, UNEXPECTED_MESSAGE); return 0; } else { federate_info_t* fed = GET_FED_INFO(fed_id); @@ -1230,9 +1236,9 @@ static int receive_connection_information(netchan_t fed_netchan, uint16_t fed_id if (connections_info_body_size > 0) { connections_info_body = (unsigned char*)malloc(connections_info_body_size); LF_ASSERT_NON_NULL(connections_info_body); - read_from_netchan_fail_on_error(fed_netchan, connections_info_body_size, connections_info_body, - "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message body from federate %d.", - fed_id); + read_from_net_abstraction_fail_on_error( + fed_net_abstraction, connections_info_body_size, connections_info_body, + "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message body from federate %d.", fed_id); // Keep track of where we are in the buffer size_t message_head = 0; // First, read the info about upstream federates @@ -1264,23 +1270,23 @@ static int receive_connection_information(netchan_t fed_netchan, uint16_t fed_id * up to perform runtime clock synchronization using the UDP port number * specified in the payload to communicate with the federate's clock * synchronization logic. - * @param fed_netchan The network channel on which to listen. + * @param fed_net_abstraction The network abstraction on which to listen. * @param fed_id The federate ID. * @return 1 for success, 0 for failure. */ -static int receive_udp_message_and_set_up_clock_sync(netchan_t fed_netchan, uint16_t fed_id) { +static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net_abstraction, uint16_t fed_id) { // Read the MSG_TYPE_UDP_PORT message from the federate regardless of the status of // clock synchronization. This message will tell the RTI whether the federate // is doing clock synchronization, and if it is, what port to use for UDP. LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_UDP_PORT from federate %d.", fed_id); unsigned char response[1 + sizeof(uint16_t)]; - read_from_netchan_fail_on_error(fed_netchan, 1 + sizeof(uint16_t), response, - "RTI failed to read MSG_TYPE_UDP_PORT message from federate %d.", fed_id); + read_from_net_abstraction_fail_on_error(fed_net_abstraction, 1 + sizeof(uint16_t), response, + "RTI failed to read MSG_TYPE_UDP_PORT message from federate %d.", fed_id); if (response[0] != MSG_TYPE_UDP_PORT) { lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", fed_id, response[0]); - send_reject(fed_netchan, UNEXPECTED_MESSAGE); + send_reject(fed_net_abstraction, UNEXPECTED_MESSAGE); return 0; } else { federate_info_t* fed = GET_FED_INFO(fed_id); @@ -1301,15 +1307,15 @@ static int receive_udp_message_and_set_up_clock_sync(netchan_t fed_netchan, uint // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); unsigned char buffer[message_size]; - read_from_netchan_fail_on_error(fed_netchan, message_size, buffer, - "network channel to federate %d unexpectedly closed.", fed_id); + read_from_net_abstraction_fail_on_error(fed_net_abstraction, message_size, buffer, + "network abstraction to federate %d unexpectedly closed.", fed_id); if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); LF_PRINT_DEBUG("RTI received T3 clock sync message from federate %d.", fed_id); handle_physical_clock_sync_message(fed, false); } else { lf_print_error("Unexpected message %u from federate %d.", buffer[0], fed_id); - send_reject(fed_netchan, UNEXPECTED_MESSAGE); + send_reject(fed_net_abstraction, UNEXPECTED_MESSAGE); return 0; } } @@ -1321,7 +1327,7 @@ static int receive_udp_message_and_set_up_clock_sync(netchan_t fed_netchan, uint // Initialize the UDP_addr field of the federate struct fed->UDP_addr.sin_family = AF_INET; fed->UDP_addr.sin_port = htons(federate_UDP_port_number); - fed->UDP_addr.sin_addr = *get_ip_addr(fed_netchan); + fed->UDP_addr.sin_addr = *get_ip_addr(fed_net_abstraction); } } else { // Disable clock sync after initial round. @@ -1344,15 +1350,15 @@ static int receive_udp_message_and_set_up_clock_sync(netchan_t fed_netchan, uint /** * Authenticate incoming federate by performing HMAC-based authentication. * - * @param fed_netchan network channel for the incoming federate tryting to authenticate. + * @param fed_net_abstraction network abstraction for the incoming federate tryting to authenticate. * @return True if authentication is successful and false otherwise. */ -static bool authenticate_federate(netchan_t fed_netchan) { +static bool authenticate_federate(net_abstraction_t fed_net_abstraction) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); unsigned char buffer[1 + fed_id_length + NONCE_LENGTH]; - read_from_netchan_fail_on_error(fed_netchan, 1 + fed_id_length + NONCE_LENGTH, buffer, - "Failed to read MSG_TYPE_FED_NONCE"); + read_from_net_abstraction_fail_on_error(fed_net_abstraction, 1 + fed_id_length + NONCE_LENGTH, buffer, + "Failed to read MSG_TYPE_FED_NONCE"); if (buffer[0] != MSG_TYPE_FED_NONCE) { lf_print_error_and_exit("Received unexpected response %u from the FED (see net_common.h).", buffer[0]); } @@ -1376,13 +1382,14 @@ static bool authenticate_federate(netchan_t fed_netchan) { RAND_bytes(rti_nonce, NONCE_LENGTH); memcpy(&sender[1], rti_nonce, NONCE_LENGTH); memcpy(&sender[1 + NONCE_LENGTH], hmac_tag, hmac_length); - if (write_to_netchan(fed_netchan, 1 + NONCE_LENGTH + hmac_length, sender)) { + if (write_to_net_abstraction(fed_net_abstraction, 1 + NONCE_LENGTH + hmac_length, sender)) { lf_print_error("Failed to send nonce to federate."); } // Wait for MSG_TYPE_FED_RESPONSE unsigned char received[1 + hmac_length]; - read_from_netchan_fail_on_error(fed_netchan, 1 + hmac_length, received, "Failed to read federate response."); + read_from_net_abstraction_fail_on_error(fed_net_abstraction, 1 + hmac_length, received, + "Failed to read federate response."); if (received[0] != MSG_TYPE_FED_RESPONSE) { lf_print_error_and_exit("Received unexpected response %u from the federate (see net_common.h).", received[0]); return false; @@ -1401,7 +1408,7 @@ static bool authenticate_federate(netchan_t fed_netchan) { if (memcmp(&received[1], rti_tag, hmac_length) != 0) { // Federation IDs do not match. Send back a HMAC_DOES_NOT_MATCH message. lf_print_warning("HMAC authentication failed. Rejecting the federate."); - send_reject(fed_netchan, HMAC_DOES_NOT_MATCH); + send_reject(fed_net_abstraction, HMAC_DOES_NOT_MATCH); return false; } else { LF_PRINT_LOG("Federate's HMAC verified."); @@ -1410,20 +1417,20 @@ static bool authenticate_federate(netchan_t fed_netchan) { } #endif -void lf_connect_to_federates(netchan_t rti_netchan) { +void lf_connect_to_federates(net_abstraction_t rti_net_abstraction) { for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { - netchan_t fed_netchan = accept_netchan(rti_netchan, NULL); - if (fed_netchan == NULL) { + net_abstraction_t fed_net_abstraction = accept_net_abstraction(rti_net_abstraction, NULL); + if (fed_net_abstraction == NULL) { lf_print_warning("RTI failed to accept the federate."); return; } // Wait for the first message from the federate when RTI -a option is on. #ifdef __RTI_AUTH__ if (rti_remote->authentication_enabled) { - if (!authenticate_federate(fed_netchan)) { + if (!authenticate_federate(fed_net_abstraction)) { lf_print_warning("RTI failed to authenticate the incoming federate."); - // Close the network channel without reading until EOF. - shutdown_netchan(fed_netchan, false); + // Close the network abstraction without reading until EOF. + shutdown_net_abstraction(fed_net_abstraction, false); // Ignore the federate that failed authentication. i--; continue; @@ -1432,9 +1439,9 @@ void lf_connect_to_federates(netchan_t rti_netchan) { #endif // The first message from the federate should contain its ID and the federation ID. - int32_t fed_id = receive_and_check_fed_id_message(fed_netchan); - if (fed_id >= 0 && receive_connection_information(fed_netchan, (uint16_t)fed_id) && - receive_udp_message_and_set_up_clock_sync(fed_netchan, (uint16_t)fed_id)) { + int32_t fed_id = receive_and_check_fed_id_message(fed_net_abstraction); + if (fed_id >= 0 && receive_connection_information(fed_net_abstraction, (uint16_t)fed_id) && + receive_udp_message_and_set_up_clock_sync(fed_net_abstraction, (uint16_t)fed_id)) { // Create a thread to communicate with the federate. // This has to be done after clock synchronization is finished @@ -1473,9 +1480,9 @@ void* respond_to_erroneous_connections(void* nothing) { while (true) { // Wait for an incoming connection request. // The following will block until either a federate attempts to connect - // or shutdown_netchan(rti->rti_netchan) is called. - netchan_t fed_netchan = accept_netchan(rti_remote->rti_netchan, NULL); - if (fed_netchan == NULL) { + // or shutdown_net_abstraction(rti->rti_net_abstraction) is called. + net_abstraction_t fed_net_abstraction = accept_net_abstraction(rti_remote->rti_net_abstraction, NULL); + if (fed_net_abstraction == NULL) { return NULL; } if (rti_remote->all_federates_exited) { @@ -1487,11 +1494,11 @@ void* respond_to_erroneous_connections(void* nothing) { response[0] = MSG_TYPE_REJECT; response[1] = FEDERATION_ID_DOES_NOT_MATCH; // Ignore errors on this response. - if (write_to_netchan(fed_netchan, 2, response)) { + if (write_to_net_abstraction(fed_net_abstraction, 2, response)) { lf_print_warning("RTI failed to write FEDERATION_ID_DOES_NOT_MATCH to erroneous incoming connection."); } - // Close the network channel without reading until EOF. - shutdown_netchan(fed_netchan, false); + // Close the network abstraction without reading until EOF. + shutdown_net_abstraction(fed_net_abstraction, false); } return NULL; } @@ -1505,12 +1512,12 @@ void initialize_federate(federate_info_t* fed, uint16_t id) { int start_rti_server() { _lf_initialize_clock(); - // Initialize RTI's network channel. - rti_remote->rti_netchan = initialize_netchan(); - // Set the user specified port to the network channel. - set_my_port(rti_remote->rti_netchan, rti_remote->user_specified_port); + // Initialize RTI's network abstraction. + rti_remote->rti_net_abstraction = initialize_net_abstraction(); + // Set the user specified port to the network abstraction. + set_my_port(rti_remote->rti_net_abstraction, rti_remote->user_specified_port); // Create the server - if (create_server(rti_remote->rti_netchan, true)) { + if (create_server(rti_remote->rti_net_abstraction, true)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); return -1; }; @@ -1528,12 +1535,12 @@ int start_rti_server() { void wait_for_federates() { // Wait for connections from federates and create a thread for each. - lf_connect_to_federates(rti_remote->rti_netchan); + lf_connect_to_federates(rti_remote->rti_net_abstraction); // All federates have connected. lf_print("RTI: All expected federates have connected. Starting execution."); - // The network channel server will not continue to accept connections after all the federates + // The network abstraction server will not continue to accept connections after all the federates // have joined. // In case some other federation's federates are trying to join the wrong // federation, need to respond. Start a separate thread to do that. @@ -1552,10 +1559,10 @@ void wait_for_federates() { rti_remote->all_federates_exited = true; - // Shutdown and close the network channel that is listening for incoming connections + // Shutdown and close the network abstraction that is listening for incoming connections // so that the accept() call in respond_to_erroneous_connections returns. // That thread should then check rti->all_federates_exited and it should exit. - shutdown_netchan(rti_remote->rti_netchan, false); + shutdown_net_abstraction(rti_remote->rti_net_abstraction, false); if (rti_remote->socket_descriptor_UDP > 0) { // UDP only uses sockets. diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index dd28f32b9..dae2dfdaf 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -24,7 +24,7 @@ #include "lf_types.h" #include "pqueue_tag.h" -#include "net_driver.h" +#include "net_abstraction.h" /** * @brief Time allowed for federates to reply to stop request. @@ -53,8 +53,8 @@ typedef struct federate_info_t { bool requested_stop; /** @brief The ID of the thread handling communication with this federate. */ lf_thread_t thread_id; - /** @brief The network channel for communicating with this federate. */ - netchan_t fed_netchan; + /** @brief The network abstraction for communicating with this federate. */ + net_abstraction_t fed_net_abstraction; /** @brief The UDP address for the federate. */ struct sockaddr_in UDP_addr; /** @brief Indicates the status of clock synchronization for this federate. Enabled by default. */ @@ -113,7 +113,7 @@ typedef struct rti_remote_t { const char* federation_id; /** @brief The desired port specified by the user on the command line. - * This should be not moved to the net_driver, because the user can configure this as -p or --port. + * This should be not moved to the net_abstraction, because the user can configure this as -p or --port. */ uint16_t user_specified_port; @@ -124,9 +124,9 @@ typedef struct rti_remote_t { int socket_descriptor_UDP; /** - * The rti's network channel. + * The rti's network abstraction. */ - netchan_t rti_netchan; + net_abstraction_t rti_net_abstraction; /** @brief Thread performing PTP clock sync sessions periodically. */ lf_thread_t clock_thread; @@ -297,7 +297,7 @@ void handle_timestamp(federate_info_t* my_fed); * * @param message_type The type of the clock sync message (see @ref net_common.h). * @param fed The federate to send the physical time to. - * @param use_UDP Boolean to use UDP or the network channel. + * @param use_UDP Boolean to use UDP or the network abstraction. */ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP); @@ -349,10 +349,10 @@ void* federate_info_thread_TCP(void* fed); * @brief Send a MSG_TYPE_REJECT message to the specified channel and close the channel. * @ingroup RTI * - * @param chan Pointer to the network channel. + * @param net_abs Pointer to the network abstraction. * @param error_code An error code. */ -void send_reject(netchan_t chan, unsigned char error_code); +void send_reject(net_abstraction_t net_abs, unsigned char error_code); /** * @brief Wait for one incoming connection request from each federate, @@ -361,9 +361,9 @@ void send_reject(netchan_t chan, unsigned char error_code); * * Return when all federates have connected. * - * @param rti_netchan The rti's network channel on which to accept connections. + * @param rti_net_abstraction The rti's network abstraction on which to accept connections. */ -void lf_connect_to_federates(netchan_t rti_netchan); +void lf_connect_to_federates(net_abstraction_t rti_net_abstraction); /** * @brief Thread to respond to new connections, which could be federates of other federations diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index 396bcabf0..6ee7f2720 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -170,7 +170,7 @@ uint16_t setup_clock_synchronization_with_rti() { return port_to_return; } -void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan) { +void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net_abstraction) { LF_PRINT_DEBUG("Waiting for initial clock synchronization messages from the RTI."); size_t message_size = 1 + sizeof(instant_t); @@ -178,8 +178,8 @@ void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan) { for (int i = 0; i < _LF_CLOCK_SYNC_EXCHANGES_PER_INTERVAL; i++) { // The first message expected from the RTI is MSG_TYPE_CLOCK_SYNC_T1 - read_from_netchan_fail_on_error( - rti_netchan, message_size, buffer, + read_from_net_abstraction_fail_on_error( + rti_net_abstraction, message_size, buffer, "Federate %d did not get the initial clock synchronization message T1 from the RTI.", _lf_my_fed_id); // Get local physical time before doing anything else. @@ -192,14 +192,14 @@ void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan) { // Handle the message and send a reply T3 message. // NOTE: No need to acquire the mutex lock during initialization because only // one thread is running. - if (handle_T1_clock_sync_message(buffer, (void*)rti_netchan, receive_time, false) != 0) { + if (handle_T1_clock_sync_message(buffer, (void*)rti_net_abstraction, receive_time, false) != 0) { lf_print_error_and_exit("Initial clock sync: Failed to send T3 reply to RTI."); } // Next message from the RTI is required to be MSG_TYPE_CLOCK_SYNC_T4 - read_from_netchan_fail_on_error(rti_netchan, message_size, buffer, - "Federate %d did not get the clock synchronization message T4 from the RTI.", - _lf_my_fed_id); + read_from_net_abstraction_fail_on_error( + rti_net_abstraction, message_size, buffer, + "Federate %d did not get the clock synchronization message T4 from the RTI.", _lf_my_fed_id); // Check that this is the T4 message. if (buffer[0] != MSG_TYPE_CLOCK_SYNC_T4) { @@ -207,13 +207,13 @@ void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan) { } // Handle the message. - handle_T4_clock_sync_message(buffer, (void*)rti_netchan, receive_time, false); + handle_T4_clock_sync_message(buffer, (void*)rti_net_abstraction, receive_time, false); } LF_PRINT_LOG("Finished initial clock synchronization with the RTI."); } -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t t2, bool use_udp) { +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net_abstraction, instant_t t2, bool use_udp) { // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); @@ -233,8 +233,9 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); - int result = use_udp ? write_to_socket(*(int*)socket_or_netchan, 1 + sizeof(uint16_t), reply_buffer) - : write_to_netchan((netchan_t)socket_or_netchan, 1 + sizeof(uint16_t), reply_buffer); + int result = use_udp ? write_to_socket(*(int*)socket_or_net_abstraction, 1 + sizeof(uint16_t), reply_buffer) + : write_to_net_abstraction((net_abstraction_t)socket_or_net_abstraction, 1 + sizeof(uint16_t), + reply_buffer); if (result) { lf_print_error("Clock sync: Failed to send T3 message to RTI."); @@ -248,7 +249,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, return 0; } -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t r4, bool use_udp) { +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net_abstraction, instant_t r4, bool use_udp) { // Increment the number of received T4 messages _lf_rti_socket_stat.received_T4_messages_in_current_sync_window++; @@ -283,7 +284,7 @@ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netchan if (use_udp) { // Read the coded probe message. // We can reuse the same buffer. - int read_failed = read_from_socket(*(int*)socket_or_netchan, 1 + sizeof(instant_t), buffer); + int read_failed = read_from_socket(*(int*)socket_or_net_abstraction, 1 + sizeof(instant_t), buffer); instant_t r5 = lf_time_physical(); diff --git a/core/federated/federate.c b/core/federated/federate.c index cee1d1feb..c5fa94284 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -24,7 +24,7 @@ #include "federate.h" #include "net_common.h" #include "net_util.h" -#include "net_driver.h" +#include "net_abstraction.h" #include "reactor.h" #include "reactor_common.h" #include "reactor_threaded.h" @@ -44,7 +44,7 @@ extern instant_t start_time; extern bool _lf_termination_executed; // Global variables references in federate.h -lf_mutex_t lf_outbound_netchan_mutex; +lf_mutex_t lf_outbound_net_abstraction_mutex; lf_cond_t lf_port_status_changed; @@ -72,7 +72,7 @@ int max_level_allowed_to_advance; * and the _fed global variable refers to that instance. */ federate_instance_t _fed = {.number_of_inbound_p2p_connections = 0, - .inbound_netchan_listeners = NULL, + .inbound_net_abstraction_listeners = NULL, .number_of_outbound_p2p_connections = 0, .inbound_p2p_handling_thread_id = 0, .last_TAG = {.time = NEVER, .microstep = 0u}, @@ -95,7 +95,7 @@ federation_metadata_t federation_metadata = { // Static functions (used only internally) /** - * Send a time to the RTI. This acquires the lf_outbound_netchan_mutex. + * Send a time to the RTI. This acquires the lf_outbound_net_abstraction_mutex. * @param type The message type (MSG_TYPE_TIMESTAMP). * @param time The time. */ @@ -110,15 +110,16 @@ static void send_time(unsigned char type, instant_t time) { tag_t tag = {.time = time, .microstep = 0}; tracepoint_federate_to_rti(send_TIMESTAMP, _lf_my_fed_id, &tag); - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, buffer, &lf_outbound_netchan_mutex, - "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_write, buffer, + &lf_outbound_net_abstraction_mutex, + "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); } /** * Send a tag to the RTI. - * This function acquires the lf_outbound_netchan_mutex. + * This function acquires the lf_outbound_net_abstraction_mutex. * @param type The message type (MSG_TYPE_NEXT_EVENT_TAG or MSG_TYPE_LATEST_TAG_CONFIRMED). * @param tag The tag. */ @@ -132,17 +133,18 @@ static void send_tag(unsigned char type, tag_t tag) { trace_event_t event_type = (type == MSG_TYPE_NEXT_EVENT_TAG) ? send_NET : send_LTC; // Trace the event when tracing is enabled tracepoint_federate_to_rti(event_type, _lf_my_fed_id, &tag); - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, buffer, &lf_outbound_netchan_mutex, - "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + write_to_net_abstraction_fail_on_error( + _fed.net_abstraction_to_RTI, bytes_to_write, buffer, &lf_outbound_net_abstraction_mutex, + "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); } /** - * Return true if either the network channel to the RTI is broken or the network channel is - * alive and the first unread byte on the network channel's queue is MSG_TYPE_FAILED. + * Return true if either the network abstraction to the RTI is broken or the network abstraction is + * alive and the first unread byte on the network abstraction's queue is MSG_TYPE_FAILED. */ -static bool rti_failed() { return check_netchan_closed(_fed.netchan_to_RTI); } +static bool rti_failed() { return check_net_abstraction_closed(_fed.net_abstraction_to_RTI); } //////////////////////////////// Port Status Handling /////////////////////////////////////// @@ -436,17 +438,17 @@ static bool handle_message_now(environment_t* env, trigger_t* trigger, tag_t int * Handle a message being received from a remote federate. * * This function assumes the caller does not hold the mutex lock. - * @param netchan Pointer to the network channel to read the message from. + * @param net_abstraction Pointer to the network abstraction to read the message from. * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure. */ -static int handle_message(netchan_t netchan, int fed_id) { +static int handle_message(net_abstraction_t net_abstraction, int fed_id) { (void)fed_id; // Read the header. size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); unsigned char buffer[bytes_to_read]; - if (read_from_netchan_close_on_error(netchan, bytes_to_read, buffer)) { - // Read failed, which means the network channel has been closed between reading the + if (read_from_net_abstraction_close_on_error(net_abstraction, bytes_to_read, buffer)) { + // Read failed, which means the network abstraction has been closed between reading the // message ID byte and here. return -1; } @@ -466,7 +468,7 @@ static int handle_message(netchan_t netchan, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_netchan_close_on_error(netchan, length, message_contents)) { + if (read_from_net_abstraction_close_on_error(net_abstraction, length, message_contents)) { return -1; } // Trace the event when tracing is enabled @@ -490,11 +492,11 @@ static int handle_message(netchan_t netchan, int fed_id) { * will not advance to the tag of the message if it is in the future, or * the tag will not advance at all if the tag of the message is * now or in the past. - * @param netchan Pointer to the network channel to read the message from. + * @param net_abstraction Pointer to the network abstraction to read the message from. * @param fed_id The sending federate ID or -1 if the centralized coordination. - * @return 0 on successfully reading the message, -1 on failure (e.g. due to network channel closed). + * @return 0 on successfully reading the message, -1 on failure (e.g. due to network abstraction closed). */ -static int handle_tagged_message(netchan_t netchan, int fed_id) { +static int handle_tagged_message(net_abstraction_t net_abstraction, int fed_id) { // Environment is always the one corresponding to the top-level scheduling enclave. environment_t* env; _lf_get_environments(&env); @@ -503,7 +505,7 @@ static int handle_tagged_message(netchan_t netchan, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_netchan_close_on_error(netchan, bytes_to_read, buffer)) { + if (read_from_net_abstraction_close_on_error(net_abstraction, bytes_to_read, buffer)) { return -1; // Read failed. } @@ -552,7 +554,7 @@ static int handle_tagged_message(netchan_t netchan, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_netchan_close_on_error(netchan, length, message_contents)) { + if (read_from_net_abstraction_close_on_error(net_abstraction, length, message_contents)) { #ifdef FEDERATED_DECENTRALIZED _lf_decrement_tag_barrier_locked(env); #endif @@ -622,13 +624,13 @@ static int handle_tagged_message(netchan_t netchan, int fed_id) { if (lf_tag_compare(env->current_tag, env->stop_tag) >= 0 && env->execution_started) { lf_print_error("Received message too late. Already at stop tag.\n" " Current tag is " PRINTF_TAG " and intended tag is " PRINTF_TAG ".\n" - " Discarding message and closing the network channel.", + " Discarding message and closing the network abstraction.", env->current_tag.time - start_time, env->current_tag.microstep, intended_tag.time - start_time, intended_tag.microstep); // Free the allocated memory before returning _lf_done_using(message_token); - // Close network channel, reading any incoming data and discarding it. - shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[fed_id], false); + // Close network abstraction, reading any incoming data and discarding it. + shutdown_net_abstraction(_fed.net_abstractions_for_inbound_p2p_connections[fed_id], false); LF_MUTEX_UNLOCK(&env->mutex); return -1; } else { @@ -659,14 +661,14 @@ static int handle_tagged_message(netchan_t netchan, int fed_id) { * This just sets the last known status tag of the port specified * in the message. * - * @param netchan Pointer to the network channel to read the message from + * @param net_abstraction Pointer to the network abstraction to read the message from * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure to complete the read. */ -static int handle_port_absent_message(netchan_t netchan, int fed_id) { +static int handle_port_absent_message(net_abstraction_t net_abstraction, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_netchan_close_on_error(netchan, bytes_to_read, buffer)) { + if (read_from_net_abstraction_close_on_error(net_abstraction, bytes_to_read, buffer)) { return -1; } @@ -703,7 +705,7 @@ static int handle_port_absent_message(netchan_t netchan, int fed_id) { * peer federate and calls the appropriate handling function for * each message type. If an error occurs or an EOF is received * from the peer, then this procedure sets the corresponding - * network channel in _fed.netchans_for_inbound_p2p_connections + * network abstraction in _fed.net_abstractions_for_inbound_p2p_connections * to -1 and returns, terminating the thread. * @param _args The remote federate ID (cast to void*). * @param fed_id_ptr A pointer to a uint16_t containing federate ID being listened to. @@ -715,7 +717,7 @@ static void* listen_to_federates(void* _args) { LF_PRINT_LOG("Listening to federate %d.", fed_id); - netchan_t netchan = _fed.netchans_for_inbound_p2p_connections[fed_id]; + net_abstraction_t net_abstraction = _fed.net_abstractions_for_inbound_p2p_connections[fed_id]; // Buffer for incoming messages. // This does not constrain the message size @@ -724,44 +726,44 @@ static void* listen_to_federates(void* _args) { // Listen for messages from the federate. while (!_lf_termination_executed) { - bool netchan_closed = false; + bool net_abstraction_closed = false; // Read one byte to get the message type. LF_PRINT_DEBUG("Waiting for a P2P message."); bool bad_message = false; - if (read_from_netchan_close_on_error(netchan, 1, buffer)) { - // network channel has been closed. - lf_print("network channel from federate %d is closed.", fed_id); + if (read_from_net_abstraction_close_on_error(net_abstraction, 1, buffer)) { + // network abstraction has been closed. + lf_print("network abstraction from federate %d is closed.", fed_id); // Stop listening to this federate. - netchan_closed = true; + net_abstraction_closed = true; } else { LF_PRINT_DEBUG("Received a P2P message of type %d.", buffer[0]); switch (buffer[0]) { case MSG_TYPE_P2P_MESSAGE: LF_PRINT_LOG("Received untimed message from federate %d.", fed_id); - if (handle_message(netchan, fed_id)) { + if (handle_message(net_abstraction, fed_id)) { // Failed to complete the reading of a message on a physical connection. lf_print_warning("Failed to complete reading of message on physical connection."); - netchan_closed = true; + net_abstraction_closed = true; } break; case MSG_TYPE_P2P_TAGGED_MESSAGE: LF_PRINT_LOG("Received tagged message from federate %d.", fed_id); - if (handle_tagged_message(netchan, fed_id)) { + if (handle_tagged_message(net_abstraction, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and - // it is not a fatal error if the network channel is closed before the whole message is read. + // it is not a fatal error if the network abstraction is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); - netchan_closed = true; + net_abstraction_closed = true; } break; case MSG_TYPE_PORT_ABSENT: LF_PRINT_LOG("Received port absent message from federate %d.", fed_id); - if (handle_port_absent_message(netchan, fed_id)) { + if (handle_port_absent_message(net_abstraction, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and - // it is not a fatal error if the network channel is closed before the whole message is read. + // it is not a fatal error if the network abstraction is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); - netchan_closed = true; + net_abstraction_closed = true; } break; default: @@ -769,13 +771,13 @@ static void* listen_to_federates(void* _args) { } } if (bad_message) { - lf_print_error("Received erroneous message type: %d. Closing the network channel.", buffer[0]); + lf_print_error("Received erroneous message type: %d. Closing the network abstraction.", buffer[0]); // Trace the event when tracing is enabled tracepoint_federate_from_federate(receive_UNIDENTIFIED, _lf_my_fed_id, fed_id, NULL); break; // while loop } - if (netchan_closed) { - // For decentralized execution, once this network channel is closed, we + if (net_abstraction_closed) { + // For decentralized execution, once this network abstraction is closed, we // update last known tags of all ports connected to the specified federate to FOREVER_TAG, // which would eliminate the need to wait for STAA to assume an input is absent. mark_inputs_known_absent(fed_id); @@ -787,27 +789,27 @@ static void* listen_to_federates(void* _args) { } /** - * Close the network channel that sends outgoing messages to the - * specified federate ID. This function acquires the lf_outbound_netchan_mutex mutex lock + * Close the network abstraction that sends outgoing messages to the + * specified federate ID. This function acquires the lf_outbound_net_abstraction_mutex mutex lock * if _lf_normal_termination is true and otherwise proceeds without the lock. * @param fed_id The ID of the peer federate receiving messages from this * federate, or -1 if the RTI (centralized coordination). */ -static void close_outbound_netchan(int fed_id) { +static void close_outbound_net_abstraction(int fed_id) { assert(fed_id >= 0 && fed_id < NUMBER_OF_FEDERATES); // Close outbound connections, in case they have not closed themselves. // This will result in EOF being sent to the remote federate, except for - // abnormal termination, in which case it will just close the network channel. + // abnormal termination, in which case it will just close the network abstraction. if (_lf_normal_termination) { - if (_fed.netchans_for_outbound_p2p_connections[fed_id] != NULL) { - // Close the network channel by sending a FIN packet indicating that no further writes + if (_fed.net_abstractions_for_outbound_p2p_connections[fed_id] != NULL) { + // Close the network abstraction by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. - shutdown_netchan(_fed.netchans_for_outbound_p2p_connections[fed_id], true); - _fed.netchans_for_outbound_p2p_connections[fed_id] = NULL; + shutdown_net_abstraction(_fed.net_abstractions_for_outbound_p2p_connections[fed_id], true); + _fed.net_abstractions_for_outbound_p2p_connections[fed_id] = NULL; } } else { - shutdown_netchan(_fed.netchans_for_outbound_p2p_connections[fed_id], false); - _fed.netchans_for_outbound_p2p_connections[fed_id] = NULL; + shutdown_net_abstraction(_fed.net_abstractions_for_outbound_p2p_connections[fed_id], false); + _fed.net_abstractions_for_outbound_p2p_connections[fed_id] = NULL; } } @@ -830,14 +832,15 @@ static int perform_hmac_authentication() { memcpy(&fed_hello_buf[1 + fed_id_length], fed_nonce, NONCE_LENGTH); // No mutex needed during startup, hence the NULL argument. - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, message_length, fed_hello_buf, NULL, "Failed to write nonce."); + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, message_length, fed_hello_buf, NULL, + "Failed to write nonce."); // Check HMAC of received FED_RESPONSE message. unsigned int hmac_length = SHA256_HMAC_LENGTH; size_t federation_id_length = strnlen(federation_metadata.federation_id, 255); unsigned char received[1 + NONCE_LENGTH + hmac_length]; - if (read_from_netchan_close_on_error(_fed.netchan_to_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { + if (read_from_net_abstraction_close_on_error(_fed.net_abstraction_to_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { lf_print_warning("Failed to read RTI response."); return -1; } @@ -871,7 +874,7 @@ static int perform_hmac_authentication() { response[1] = HMAC_DOES_NOT_MATCH; // Ignore errors on writing back. - write_to_netchan(_fed.netchan_to_RTI, 2, response); + write_to_net_abstraction(_fed.net_abstraction_to_RTI, 2, response); return -1; } else { LF_PRINT_LOG("HMAC verified."); @@ -885,7 +888,8 @@ static int perform_hmac_authentication() { HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH, &sender[1], &hmac_length); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, 1 + hmac_length, sender, NULL, "Failed to write fed response."); + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, 1 + hmac_length, sender, NULL, + "Failed to write fed response."); } return 0; } @@ -904,13 +908,13 @@ static instant_t get_start_time_from_rti(instant_t my_physical_time) { // Send the timestamp marker first. send_time(MSG_TYPE_TIMESTAMP, my_physical_time); - // Read bytes from the network channel. We need 9 bytes. + // Read bytes from the network abstraction. We need 9 bytes. // Buffer for message ID plus timestamp. size_t buffer_length = 1 + sizeof(instant_t); unsigned char buffer[buffer_length]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, buffer_length, buffer, - "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); + read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, buffer_length, buffer, + "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); LF_PRINT_DEBUG("Read 9 bytes."); // First byte received is the message ID. @@ -953,8 +957,8 @@ static void handle_tag_advance_grant(void) { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, - "Failed to read tag advance grant from RTI."); + read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, + "Failed to read tag advance grant from RTI."); tag_t TAG = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1200,8 +1204,8 @@ static void handle_provisional_tag_advance_grant() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, - "Failed to read provisional tag advance grant from RTI."); + read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, + "Failed to read provisional tag advance grant from RTI."); tag_t PTAG = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1290,7 +1294,8 @@ static void handle_stop_granted_message() { size_t bytes_to_read = MSG_TYPE_STOP_GRANTED_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, "Failed to read stop granted from RTI."); + read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, + "Failed to read stop granted from RTI."); tag_t received_stop_tag = extract_tag(buffer); @@ -1333,7 +1338,8 @@ static void handle_stop_granted_message() { static void handle_stop_request_message() { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, "Failed to read stop request from RTI."); + read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, + "Failed to read stop request from RTI."); tag_t tag_to_stop = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1358,10 +1364,10 @@ static void handle_stop_request_message() { // or we have previously sent a stop request to the RTI, // then we have already blocked tag advance in enclaves. // Do not do this twice. The record of whether the first has occurred - // is guarded by the outbound network channel mutex. + // is guarded by the outbound network abstraction mutex. // The second is guarded by the global mutex. // Note that the RTI should not send stop requests more than once to federates. - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); if (_fed.received_stop_request_from_rti) { LF_PRINT_LOG("Redundant MSG_TYPE_STOP_REQUEST from RTI. Ignoring it."); already_blocked = true; @@ -1370,7 +1376,7 @@ static void handle_stop_request_message() { // prevent lf_request_stop from sending. _fed.received_stop_request_from_rti = true; } - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); if (already_blocked) { // Either we have sent a stop request to the RTI ourselves, @@ -1404,11 +1410,11 @@ static void handle_stop_request_message() { tracepoint_federate_to_rti(send_STOP_REQ_REP, _lf_my_fed_id, &tag_to_stop); // Send the current logical time to the RTI. - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, - &lf_outbound_netchan_mutex, - "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, + outgoing_buffer, &lf_outbound_net_abstraction_mutex, + "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); LF_PRINT_DEBUG("Sent MSG_TYPE_STOP_REQUEST_REPLY to RTI with tag " PRINTF_TAG, tag_to_stop.time, tag_to_stop.microstep); @@ -1420,8 +1426,8 @@ static void handle_stop_request_message() { static void handle_downstream_next_event_tag() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_read, buffer, - "Failed to read downstream next event tag from RTI."); + read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, + "Failed to read downstream next event tag from RTI."); tag_t DNET = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1451,10 +1457,10 @@ static void send_resign_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_RESIGN; - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_netchan_mutex, - "Failed to send MSG_TYPE_RESIGN."); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_write, &(buffer[0]), + &lf_outbound_net_abstraction_mutex, "Failed to send MSG_TYPE_RESIGN."); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); LF_PRINT_LOG("Resigned."); } @@ -1465,8 +1471,8 @@ static void send_failed_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_FAILED; - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, bytes_to_write, &(buffer[0]), NULL, - "Failed to send MSG_TYPE_FAILED."); + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_write, &(buffer[0]), NULL, + "Failed to send MSG_TYPE_FAILED."); LF_PRINT_LOG("Failed."); } @@ -1479,11 +1485,11 @@ static void send_failed_signal() { static void handle_rti_failed_message(void) { exit(1); } /** - * Thread that listens for network channel inputs from the RTI. + * Thread that listens for network abstraction inputs from the RTI. * When messages arrive, this calls the appropriate handler. * @param args Ignored */ -static void* listen_to_rti_netchan(void* args) { +static void* listen_to_rti_net_abstraction(void* args) { (void)args; initialize_lf_thread_id(); // Buffer for incoming messages. @@ -1493,27 +1499,27 @@ static void* listen_to_rti_netchan(void* args) { // Listen for messages from the federate. while (!_lf_termination_executed) { - // Check whether the RTI network channel is still valid. - if (_fed.netchan_to_RTI == NULL) { - lf_print_warning("network channel to the RTI unexpectedly closed."); + // Check whether the RTI network abstraction is still valid. + if (_fed.net_abstraction_to_RTI == NULL) { + lf_print_warning("network abstraction to the RTI unexpectedly closed."); return NULL; } // Read one byte to get the message type. // This will exit if the read fails. - int read_failed = read_from_netchan(_fed.netchan_to_RTI, 1, buffer); + int read_failed = read_from_net_abstraction(_fed.net_abstraction_to_RTI, 1, buffer); if (read_failed < 0) { lf_print_error("Connection to the RTI was closed by the RTI with an error. Considering this a soft error."); - shutdown_netchan(_fed.netchan_to_RTI, false); + shutdown_net_abstraction(_fed.net_abstraction_to_RTI, false); return NULL; } else if (read_failed > 0) { // EOF received. lf_print("Connection to the RTI closed with an EOF."); - shutdown_netchan(_fed.netchan_to_RTI, false); + shutdown_net_abstraction(_fed.net_abstraction_to_RTI, false); return NULL; } switch (buffer[0]) { case MSG_TYPE_TAGGED_MESSAGE: - if (handle_tagged_message(_fed.netchan_to_RTI, -1)) { + if (handle_tagged_message(_fed.net_abstraction_to_RTI, -1)) { // Failures to complete the read of messages from the RTI are fatal. lf_print_error_and_exit("Failed to complete the reading of a message from the RTI."); } @@ -1531,7 +1537,7 @@ static void* listen_to_rti_netchan(void* args) { handle_stop_granted_message(); break; case MSG_TYPE_PORT_ABSENT: - if (handle_port_absent_message(_fed.netchan_to_RTI, -1)) { + if (handle_port_absent_message(_fed.net_abstraction_to_RTI, -1)) { // Failures to complete the read of absent messages from the RTI are fatal. lf_print_error_and_exit("Failed to complete the reading of an absent message from the RTI."); } @@ -1609,7 +1615,7 @@ static bool bounded_NET(tag_t* tag) { // An empty version of this function is code generated for unfederated execution. /** - * Close network channels used to communicate with other federates, if they are open, + * Close network abstractions used to communicate with other federates, if they are open, * and send a MSG_TYPE_RESIGN message to the RTI. This implements the function * defined in reactor.h. For unfederated execution, the code generator * generates an empty implementation. @@ -1620,7 +1626,7 @@ void lf_terminate_execution(environment_t* env) { // For an abnormal termination (e.g. a SIGINT), we need to send a // MSG_TYPE_FAILED message to the RTI, but we should not acquire a mutex. - if (_fed.netchan_to_RTI != NULL) { + if (_fed.net_abstraction_to_RTI != NULL) { if (_lf_normal_termination) { tracepoint_federate_to_rti(send_RESIGN, _lf_my_fed_id, &env->current_tag); send_resign_signal(); @@ -1630,45 +1636,45 @@ void lf_terminate_execution(environment_t* env) { } } - LF_PRINT_DEBUG("Closing incoming P2P network channels."); - // Close any incoming P2P network channels that are still open. + LF_PRINT_DEBUG("Closing incoming P2P network abstractions."); + // Close any incoming P2P network abstractions that are still open. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { - shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[i], false); - // Ignore errors. Mark the network channel closed. - _fed.netchans_for_inbound_p2p_connections[i] = NULL; + shutdown_net_abstraction(_fed.net_abstractions_for_inbound_p2p_connections[i], false); + // Ignore errors. Mark the network abstraction closed. + _fed.net_abstractions_for_inbound_p2p_connections[i] = NULL; } // Check for all outgoing physical connections in - // _fed.netchans_for_outbound_p2p_connections and - // if the network channel ID is not NULL, the connection is still open. - // Send an EOF by closing the network channel here. + // _fed.net_abstractions_for_outbound_p2p_connections and + // if the network abstraction ID is not NULL, the connection is still open. + // Send an EOF by closing the network abstraction here. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { // Close outbound connections, in case they have not closed themselves. // This will result in EOF being sent to the remote federate, except for - // abnormal termination, in which case it will just close the network channel. - close_outbound_netchan(i); + // abnormal termination, in which case it will just close the network abstraction. + close_outbound_net_abstraction(i); } - LF_PRINT_DEBUG("Waiting for inbound p2p network channel listener threads."); - // Wait for each inbound network channel listener thread to close. - if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_netchan_listeners != NULL) { + LF_PRINT_DEBUG("Waiting for inbound p2p network abstraction listener threads."); + // Wait for each inbound network abstraction listener thread to close. + if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_net_abstraction_listeners != NULL) { LF_PRINT_LOG("Waiting for %zu threads listening for incoming messages to exit.", _fed.number_of_inbound_p2p_connections); for (size_t i = 0; i < _fed.number_of_inbound_p2p_connections; i++) { // Ignoring errors here. - lf_thread_join(_fed.inbound_netchan_listeners[i], NULL); + lf_thread_join(_fed.inbound_net_abstraction_listeners[i], NULL); } } - LF_PRINT_DEBUG("Waiting for RTI's network channel listener threads."); + LF_PRINT_DEBUG("Waiting for RTI's network abstraction listener threads."); // Wait for the thread listening for messages from the RTI to close. - lf_thread_join(_fed.RTI_netchan_listener, NULL); + lf_thread_join(_fed.RTI_net_abstraction_listener, NULL); // For abnormal termination, there is no need to free memory. if (_lf_normal_termination) { LF_PRINT_DEBUG("Freeing memory occupied by the federate."); - free(_fed.inbound_netchan_listeners); + free(_fed.inbound_net_abstraction_listeners); free(federation_metadata.rti_host); free(federation_metadata.rti_user); } @@ -1697,15 +1703,16 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_QR, _lf_my_fed_id, NULL); - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_netchan_mutex, - "Failed to send address query for federate %d to RTI.", remote_federate_id); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, sizeof(uint16_t) + 1, buffer, + &lf_outbound_net_abstraction_mutex, + "Failed to send address query for federate %d to RTI.", remote_federate_id); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); // Read RTI's response. - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(int32_t) + 1, buffer, - "Failed to read the requested port number for federate %d from RTI.", - remote_federate_id); + read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, sizeof(int32_t) + 1, buffer, + "Failed to read the requested port number for federate %d from RTI.", + remote_federate_id); if (buffer[0] != MSG_TYPE_ADDRESS_QUERY_REPLY) { // Unexpected reply. Could be that RTI has failed and sent a resignation. @@ -1717,8 +1724,9 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } port = extract_int32(&buffer[1]); - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, - "Failed to read the IP address for federate %d from RTI.", remote_federate_id); + read_from_net_abstraction_fail_on_error( + _fed.net_abstraction_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, + "Failed to read the IP address for federate %d from RTI.", remote_federate_id); // A reply of -1 for the port means that the RTI does not know // the port number of the remote federate, presumably because the @@ -1739,14 +1747,14 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { char hostname[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &host_ip_addr, hostname, INET_ADDRSTRLEN); - // Create a network channel. - netchan_t netchan = initialize_netchan(); - // Set the received host name and port to the network channel. - set_server_port(netchan, uport); - set_server_hostname(netchan, hostname); - // Create the client network channel. - create_client(netchan); - if (connect_to_netchan(netchan) < 0) { + // Create a network abstraction. + net_abstraction_t net_abstraction = initialize_net_abstraction(); + // Set the received host name and port to the network abstraction. + set_server_port(net_abstraction, uport); + set_server_hostname(net_abstraction, hostname); + // Create the client network abstraction. + create_client(net_abstraction); + if (connect_to_net_abstraction(net_abstraction) < 0) { lf_print_error_and_exit("Failed to connect to federate."); } @@ -1782,20 +1790,21 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_FED_ID, _lf_my_fed_id, remote_federate_id, NULL); - // No need for a mutex because we have the only handle on the network channel. - write_to_netchan_fail_on_error(netchan, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", - remote_federate_id); - write_to_netchan_fail_on_error(netchan, federation_id_length, (unsigned char*)federation_metadata.federation_id, - NULL, "Failed to send federation id to federate %d.", remote_federate_id); + // No need for a mutex because we have the only handle on the network abstraction. + write_to_net_abstraction_fail_on_error(net_abstraction, buffer_length, buffer, NULL, + "Failed to send fed_id to federate %d.", remote_federate_id); + write_to_net_abstraction_fail_on_error(net_abstraction, federation_id_length, + (unsigned char*)federation_metadata.federation_id, NULL, + "Failed to send federation id to federate %d.", remote_federate_id); - read_from_netchan_fail_on_error(netchan, 1, (unsigned char*)buffer, - "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", - remote_federate_id); + read_from_net_abstraction_fail_on_error( + net_abstraction, 1, (unsigned char*)buffer, + "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", remote_federate_id); if (buffer[0] != MSG_TYPE_ACK) { // Get the error code. - read_from_netchan_fail_on_error(netchan, 1, (unsigned char*)buffer, - "Failed to read error code from federate %d in response to sending fed_id.", - remote_federate_id); + read_from_net_abstraction_fail_on_error( + net_abstraction, 1, (unsigned char*)buffer, + "Failed to read error code from federate %d in response to sending fed_id.", remote_federate_id); lf_print_error("Received MSG_TYPE_REJECT message from remote federate (%d).", buffer[0]); result = -1; // Wait ADDRESS_QUERY_RETRY_INTERVAL nanoseconds. @@ -1811,8 +1820,8 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } } // Once we set this variable, then all future calls to close() on this - // network channel should reset it to NULL within a critical section. - _fed.netchans_for_outbound_p2p_connections[remote_federate_id] = netchan; + // network abstraction should reset it to NULL within a critical section. + _fed.net_abstractions_for_outbound_p2p_connections[remote_federate_id] = net_abstraction; } void lf_connect_to_rti(const char* hostname, int port) { @@ -1822,15 +1831,15 @@ void lf_connect_to_rti(const char* hostname, int port) { hostname = federation_metadata.rti_host ? federation_metadata.rti_host : hostname; port = federation_metadata.rti_port >= 0 ? federation_metadata.rti_port : port; - // Create a network channel. - _fed.netchan_to_RTI = initialize_netchan(); - // Set the user specified host name and port to the network channel. - set_server_port(_fed.netchan_to_RTI, port); - set_server_hostname(_fed.netchan_to_RTI, hostname); + // Create a network abstraction. + _fed.net_abstraction_to_RTI = initialize_net_abstraction(); + // Set the user specified host name and port to the network abstraction. + set_server_port(_fed.net_abstraction_to_RTI, port); + set_server_hostname(_fed.net_abstraction_to_RTI, hostname); - // Create the client network channel. - create_client(_fed.netchan_to_RTI); - if (connect_to_netchan(_fed.netchan_to_RTI) < 0) { + // Create the client network abstraction. + create_client(_fed.net_abstraction_to_RTI); + if (connect_to_net_abstraction(_fed.net_abstraction_to_RTI) < 0) { lf_print_error_and_exit("Failed to connect to RTI."); } @@ -1871,14 +1880,14 @@ void lf_connect_to_rti(const char* hostname, int port) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_FED_ID, _lf_my_fed_id, NULL); - // No need for a mutex here because no other threads are writing to this network channel. - if (write_to_netchan(_fed.netchan_to_RTI, 2 + sizeof(uint16_t), buffer)) { + // No need for a mutex here because no other threads are writing to this network abstraction. + if (write_to_net_abstraction(_fed.net_abstraction_to_RTI, 2 + sizeof(uint16_t), buffer)) { continue; // Try again, possibly on a new port. } // Next send the federation ID itself. - if (write_to_netchan(_fed.netchan_to_RTI, federation_id_length, - (unsigned char*)federation_metadata.federation_id)) { + if (write_to_net_abstraction(_fed.net_abstraction_to_RTI, federation_id_length, + (unsigned char*)federation_metadata.federation_id)) { continue; // Try again. } @@ -1890,7 +1899,7 @@ void lf_connect_to_rti(const char* hostname, int port) { LF_PRINT_DEBUG("Waiting for response to federation ID from the RTI."); - if (read_from_netchan(_fed.netchan_to_RTI, 1, &response)) { + if (read_from_net_abstraction(_fed.net_abstraction_to_RTI, 1, &response)) { continue; // Try again. } if (response == MSG_TYPE_REJECT) { @@ -1898,8 +1907,8 @@ void lf_connect_to_rti(const char* hostname, int port) { tracepoint_federate_from_rti(receive_REJECT, _lf_my_fed_id, NULL); // Read one more byte to determine the cause of rejection. unsigned char cause; - read_from_netchan_fail_on_error(_fed.netchan_to_RTI, 1, &cause, - "Failed to read the cause of rejection by the RTI."); + read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, 1, &cause, + "Failed to read the cause of rejection by the RTI."); if (cause == FEDERATION_ID_DOES_NOT_MATCH || cause == WRONG_SERVER) { lf_print_warning("Connected to the wrong RTI. Will try again"); continue; @@ -1922,7 +1931,7 @@ void lf_connect_to_rti(const char* hostname, int port) { // about connections between this federate and other federates // where messages are routed through the RTI. // @see MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h - lf_send_neighbor_structure_to_RTI(_fed.netchan_to_RTI); + lf_send_neighbor_structure_to_RTI(_fed.net_abstraction_to_RTI); uint16_t udp_port = setup_clock_synchronization_with_rti(); @@ -1930,22 +1939,22 @@ void lf_connect_to_rti(const char* hostname, int port) { unsigned char UDP_port_number[1 + sizeof(uint16_t)]; UDP_port_number[0] = MSG_TYPE_UDP_PORT; encode_uint16(udp_port, &(UDP_port_number[1])); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, - "Failed to send the UDP port number to the RTI."); + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, + "Failed to send the UDP port number to the RTI."); } void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); - netchan_t* server_netchan = initialize_netchan(); - set_my_port(server_netchan, specified_port); + net_abstraction_t* server_net_abstraction = initialize_net_abstraction(); + set_my_port(server_net_abstraction, specified_port); - if (create_server(server_netchan, false)) { + if (create_server(server_net_abstraction, false)) { lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); }; - _fed.server_netchan = server_netchan; + _fed.server_net_abstraction = server_net_abstraction; // Get the final server port to send to the RTI on an MSG_TYPE_ADDRESS_ADVERTISEMENT message. - int32_t server_port = get_my_port(server_netchan); + int32_t server_port = get_my_port(server_net_abstraction); LF_PRINT_LOG("Server for communicating with other federates started using port %d.", server_port); @@ -1958,9 +1967,9 @@ void lf_create_server(int specified_port) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_AD, _lf_my_fed_id, NULL); - // No need for a mutex because we have the only handle on this network driver. - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, - "Failed to send address advertisement."); + // No need for a mutex because we have the only handle on this network abstraction. + write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, + "Failed to send address advertisement."); LF_PRINT_DEBUG("Sent port %d to the RTI.", server_port); } @@ -1993,21 +2002,24 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { LF_ASSERT_NON_NULL(env_arg); size_t received_federates = 0; // Allocate memory to store thread IDs. - _fed.inbound_netchan_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); + _fed.inbound_net_abstraction_listeners = + (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); while (received_federates < _fed.number_of_inbound_p2p_connections && !_lf_termination_executed) { // Wait for an incoming connection request. - netchan_t netchan = accept_netchan(_fed.server_netchan, _fed.netchan_to_RTI); - if (netchan == NULL) { - lf_print_warning("Federate failed to accept the network channel."); + net_abstraction_t net_abstraction = + accept_net_abstraction(_fed.server_net_abstraction, _fed.net_abstraction_to_RTI); + if (net_abstraction == NULL) { + lf_print_warning("Federate failed to accept the network abstraction."); return NULL; } LF_PRINT_LOG("Accepted new connection from remote federate."); size_t header_length = 1 + sizeof(uint16_t) + 1; unsigned char buffer[header_length]; - int read_failed = read_from_netchan(netchan, header_length, (unsigned char*)&buffer); + int read_failed = read_from_net_abstraction(net_abstraction, header_length, (unsigned char*)&buffer); if (read_failed || buffer[0] != MSG_TYPE_P2P_SENDING_FED_ID) { - lf_print_warning("Federate received invalid first message on P2P network channel. Closing network channel."); + lf_print_warning( + "Federate received invalid first message on P2P network abstraction. Closing network abstraction."); if (read_failed == 0) { // Wrong message received. unsigned char response[2]; @@ -2016,19 +2028,20 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_netchan(netchan, 2, response); + write_to_net_abstraction(net_abstraction, 2, response); } - shutdown_netchan(netchan, false); + shutdown_net_abstraction(net_abstraction, false); continue; } // Get the federation ID and check it. unsigned char federation_id_length = buffer[header_length - 1]; char remote_federation_id[federation_id_length]; - read_failed = read_from_netchan(netchan, federation_id_length, (unsigned char*)remote_federation_id); + read_failed = + read_from_net_abstraction(net_abstraction, federation_id_length, (unsigned char*)remote_federation_id); if (read_failed || (strncmp(federation_metadata.federation_id, remote_federation_id, strnlen(federation_metadata.federation_id, 255)) != 0)) { - lf_print_warning("Received invalid federation ID. Closing network channel."); + lf_print_warning("Received invalid federation ID. Closing network abstraction."); if (read_failed == 0) { unsigned char response[2]; response[0] = MSG_TYPE_REJECT; @@ -2036,9 +2049,9 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_netchan(netchan, 2, response); + write_to_net_abstraction(net_abstraction, 2, response); } - shutdown_netchan(netchan, false); + shutdown_net_abstraction(net_abstraction, false); continue; } @@ -2049,12 +2062,12 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(receive_FED_ID, _lf_my_fed_id, remote_fed_id, NULL); - // Once we record the network channel here, all future calls to close() on - // the network channel should be done while holding the netchan_mutex, and this array + // Once we record the network abstraction here, all future calls to close() on + // the network abstraction should be done while holding the net_abstraction_mutex, and this array // element should be reset to NULL during that critical section. // Otherwise, there can be race condition where, during termination, - // two threads attempt to simultaneously close the network channel. - _fed.netchans_for_inbound_p2p_connections[remote_fed_id] = netchan; + // two threads attempt to simultaneously close the network abstraction. + _fed.net_abstractions_for_inbound_p2p_connections[remote_fed_id] = net_abstraction; // Send an MSG_TYPE_ACK message. unsigned char response = MSG_TYPE_ACK; @@ -2062,22 +2075,23 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - write_to_netchan_fail_on_error(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], 1, - (unsigned char*)&response, &lf_outbound_netchan_mutex, - "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + write_to_net_abstraction_fail_on_error(_fed.net_abstractions_for_inbound_p2p_connections[remote_fed_id], 1, + (unsigned char*)&response, &lf_outbound_net_abstraction_mutex, + "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); // Start a thread to listen for incoming messages from other federates. // The fed_id is a uint16_t, which we assume can be safely cast to and from void*. void* fed_id_arg = (void*)(uintptr_t)remote_fed_id; - int result = lf_thread_create(&_fed.inbound_netchan_listeners[received_federates], listen_to_federates, fed_id_arg); + int result = + lf_thread_create(&_fed.inbound_net_abstraction_listeners[received_federates], listen_to_federates, fed_id_arg); if (result != 0) { // Failed to create a listening thread. - shutdown_netchan(_fed.netchans_for_inbound_p2p_connections[remote_fed_id], false); + shutdown_net_abstraction(_fed.net_abstractions_for_inbound_p2p_connections[remote_fed_id], false); lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", result); } - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); received_federates++; } @@ -2179,23 +2193,23 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa const int header_length = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); // Use a mutex lock to prevent multiple threads from simultaneously sending. - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - netchan_t netchan = _fed.netchans_for_outbound_p2p_connections[federate]; + net_abstraction_t net_abstraction = _fed.net_abstractions_for_outbound_p2p_connections[federate]; // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_P2P_MSG, _lf_my_fed_id, federate, NULL); - int result = write_to_netchan_close_on_error(netchan, header_length, header_buffer); + int result = write_to_net_abstraction_close_on_error(net_abstraction, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_netchan_close_on_error(netchan, length, message); + result = write_to_net_abstraction_close_on_error(net_abstraction, length, message); } if (result != 0) { // Message did not send. Since this is used for physical connections, this is not critical. lf_print_warning("Failed to send message to %s. Dropping the message.", next_destination_str); } - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); return result; } @@ -2381,21 +2395,21 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d #ifdef FEDERATED_CENTRALIZED // Send the absent message through the RTI - netchan_t netchan = _fed.netchan_to_RTI; + net_abstraction_t net_abstraction = _fed.net_abstraction_to_RTI; tracepoint_federate_to_rti(send_PORT_ABS, _lf_my_fed_id, ¤t_message_intended_tag); #else // Send the absent message directly to the federate - netchan_t netchan = _fed.netchans_for_outbound_p2p_connections[fed_ID]; + net_abstraction_t net_abstraction = _fed.net_abstractions_for_outbound_p2p_connections[fed_ID]; tracepoint_federate_to_federate(send_PORT_ABS, _lf_my_fed_id, fed_ID, ¤t_message_intended_tag); #endif - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); - int result = write_to_netchan_close_on_error(netchan, message_length, buffer); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + int result = write_to_net_abstraction_close_on_error(net_abstraction, message_length, buffer); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); if (result != 0) { // Write failed. Response depends on whether coordination is centralized. - if (netchan == _fed.netchan_to_RTI) { + if (net_abstraction == _fed.net_abstraction_to_RTI) { // Centralized coordination. This is a critical error. lf_print_error_system_failure("Failed to send port absent message for port %hu to federate %hu.", port_ID, fed_ID); @@ -2414,30 +2428,30 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { stop_tag.microstep++; ENCODE_STOP_REQUEST(buffer, stop_tag.time, stop_tag.microstep); - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); // Do not send a stop request if a stop request has been previously received from the RTI. if (!_fed.received_stop_request_from_rti) { LF_PRINT_LOG("Sending to RTI a MSG_TYPE_STOP_REQUEST message with tag " PRINTF_TAG ".", stop_tag.time - start_time, stop_tag.microstep); - if (_fed.netchan_to_RTI == NULL) { + if (_fed.net_abstraction_to_RTI == NULL) { lf_print_warning("RTI is no longer connected. Dropping message."); - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); return -1; } // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_STOP_REQ, _lf_my_fed_id, &stop_tag); - write_to_netchan_fail_on_error(_fed.netchan_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, - &lf_outbound_netchan_mutex, "Failed to send stop time " PRINTF_TIME " to the RTI.", - stop_tag.time - start_time); + write_to_net_abstraction_fail_on_error( + _fed.net_abstraction_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_net_abstraction_mutex, + "Failed to send stop time " PRINTF_TIME " to the RTI.", stop_tag.time - start_time); // Treat this sending as equivalent to having received a stop request from the RTI. _fed.received_stop_request_from_rti = true; - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); return 0; } else { - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); return 1; } } @@ -2490,14 +2504,14 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int current_message_intended_tag.microstep, next_destination_str); // Use a mutex lock to prevent multiple threads from simultaneously sending. - LF_MUTEX_LOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - netchan_t netchan; + net_abstraction_t net_abstraction; if (message_type == MSG_TYPE_P2P_TAGGED_MESSAGE) { - netchan = _fed.netchans_for_outbound_p2p_connections[federate]; + net_abstraction = _fed.net_abstractions_for_outbound_p2p_connections[federate]; tracepoint_federate_to_federate(send_P2P_TAGGED_MSG, _lf_my_fed_id, federate, ¤t_message_intended_tag); } else { - netchan = _fed.netchan_to_RTI; + net_abstraction = _fed.net_abstraction_to_RTI; tracepoint_federate_to_rti(send_TAGGED_MSG, _lf_my_fed_id, ¤t_message_intended_tag); } @@ -2505,10 +2519,10 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int _fed.last_DNET = current_message_intended_tag; } - int result = write_to_netchan_close_on_error(netchan, header_length, header_buffer); + int result = write_to_net_abstraction_close_on_error(net_abstraction, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_netchan_close_on_error(netchan, length, message); + result = write_to_net_abstraction_close_on_error(net_abstraction, length, message); } if (result != 0) { // Message did not send. Handling depends on message type. @@ -2519,7 +2533,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int next_destination_str, errno, strerror(errno)); } } - LF_MUTEX_UNLOCK(&lf_outbound_netchan_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); return result; } @@ -2565,7 +2579,7 @@ void lf_synchronize_with_other_federates(void) { // @note Up until this point, the federate has been listening for messages // from the RTI in a sequential manner in the main thread. From now on, a // separate thread is created to allow for asynchronous communication. - lf_thread_create(&_fed.RTI_netchan_listener, listen_to_rti_netchan, NULL); + lf_thread_create(&_fed.RTI_net_abstraction_listener, listen_to_rti_net_abstraction, NULL); lf_thread_t thread_id; if (create_clock_sync_thread(&thread_id)) { lf_print_warning("Failed to create thread to handle clock synchronization."); diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index 712433aa0..098593b84 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -18,7 +18,7 @@ #define CLOCK_SYNC_H #include "low_level_platform.h" -#include "net_driver.h" +#include "net_abstraction.h" #ifndef LF_CLOCK_SYNC /** @@ -234,15 +234,15 @@ uint16_t setup_clock_synchronization_with_rti(void); * is required. * * This is a blocking function that expects - * to read a MSG_TYPE_CLOCK_SYNC_T1 from the RTI network channel. + * to read a MSG_TYPE_CLOCK_SYNC_T1 from the RTI network abstraction. * It will then follow the PTP protocol to synchronize the local * physical clock with the RTI. * Failing to complete this protocol is treated as a catastrophic * error that causes the federate to exit. * - * @param rti_netchan Pointer to the RTI's network channel. + * @param rti_net_abstraction Pointer to the RTI's network abstraction. */ -void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan); +void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net_abstraction); /** * @brief Handle a clock synchroninzation message T1 coming from the RTI. @@ -253,33 +253,33 @@ void synchronize_initial_physical_clock_with_rti(netchan_t rti_netchan); * It also measures the time it takes between when the method is * called and the reply has been sent. * @param buffer The buffer containing the message, including the message type. - * @param netchan_t The pointer to the network channel. + * @param net_abstraction_t The pointer to the network abstraction. * @param t2 The physical time at which the T1 message was received. - * @param use_UDP Boolean to use UDP or the network channel. + * @param use_UDP Boolean to use UDP or the network abstraction. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t t2, bool use_udp); +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net_abstraction, instant_t t2, bool use_udp); /** * @brief Handle a clock synchronization message T4 coming from the RTI. * @ingroup Federated * - * If the socket_or_netchan is a network channel, then assume we are in the + * If the socket_or_net_abstraction is a network abstraction, then assume we are in the * initial clock synchronization phase and set the clock offset * based on the estimated clock synchronization error. - * Otherwise, if the socket_or_netchan is UDP socket, then this looks also for a + * Otherwise, if the socket_or_net_abstraction is UDP socket, then this looks also for a * subsequent "coded probe" message on the socket. If the delay between * the T4 and the coded probe message is not as expected, then reject * this clock synchronization round. If it is not rejected, then make * an adjustment to the clock offset based on the estimated error. - * This function does not acquire the netchan_mutex lock. + * This function does not acquire the net_abstraction_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. - * @param netchan_t The pointer to the network channel. + * @param net_abstraction_t The pointer to the network abstraction. * @param r4 The physical time at which this T4 message was received.\ - * @param use_UDP Boolean to use UDP or the network channel. + * @param use_UDP Boolean to use UDP or the network abstraction. */ -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_netchan, instant_t r4, bool use_udp); +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net_abstraction, instant_t r4, bool use_udp); /** * @brief Create the thread responsible for handling clock synchronization diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index d06131821..35c351cb4 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -24,7 +24,7 @@ #include "lf_types.h" #include "environment.h" #include "low_level_platform.h" -#include "net_driver.h" +#include "net_abstraction.h" #ifndef ADVANCE_MESSAGE_INTERVAL #define ADVANCE_MESSAGE_INTERVAL MSEC(10) @@ -39,16 +39,16 @@ */ typedef struct federate_instance_t { /** - * The network channel for this federate to communicate with the RTI. + * The network abstraction for this federate to communicate with the RTI. * This is set by lf_connect_to_rti(), which must be called before other * functions that communicate with the rti are called. */ - netchan_t netchan_to_RTI; + net_abstraction_t net_abstraction_to_RTI; /** * Thread listening for incoming messages from the RTI. */ - lf_thread_t RTI_netchan_listener; + lf_thread_t RTI_net_abstraction_listener; /** * Number of inbound physical connections to the federate. @@ -62,7 +62,7 @@ typedef struct federate_instance_t { * This is NULL if there are none and otherwise has size given by * number_of_inbound_p2p_connections. */ - lf_thread_t* inbound_netchan_listeners; + lf_thread_t* inbound_net_abstraction_listeners; /** * Number of outbound peer-to-peer connections from the federate. @@ -72,50 +72,50 @@ typedef struct federate_instance_t { size_t number_of_outbound_p2p_connections; /** - * An array that holds the network channels for inbound + * An array that holds the network abstractions for inbound * connections from each federate. The index will be the federate * ID of the remote sending federate. This is initialized at startup - * to NULL and is set to the pointer of the network channel by lf_connect_to_federate() - * when the network channels is opened. + * to NULL and is set to the pointer of the network abstraction by lf_connect_to_federate() + * when the network abstractions is opened. * - * @note There will not be an inbound network channel unless a physical connection + * @note There will not be an inbound network abstraction unless a physical connection * or a p2p logical connection (by setting the coordination target property * to "distributed") is specified in the Lingua Franca program where this * federate is the destination. Multiple incoming p2p connections from the - * same remote federate will use the same network channel. + * same remote federate will use the same network abstraction. */ - netchan_t netchans_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; + net_abstraction_t net_abstractions_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; /** - * An array that holds the network channels for outbound direct + * An array that holds the network abstractions for outbound direct * connections to each remote federate. The index will be the federate * ID of the remote receiving federate. This is initialized at startup - * to NULL and is set to the pointer of the network channel by lf_connect_to_federate() - * when the network channels is opened. + * to NULL and is set to the pointer of the network abstraction by lf_connect_to_federate() + * when the network abstractions is opened. * - * @note This federate will not open an outbound network channels unless a physical + * @note This federate will not open an outbound network abstractions unless a physical * connection or a p2p logical connection (by setting the coordination target * property to "distributed") is specified in the Lingua Franca * program where this federate acts as the source. Multiple outgoing p2p - * connections to the same remote federate will use the same network channels. + * connections to the same remote federate will use the same network abstractions. */ - netchan_t netchans_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; + net_abstraction_t net_abstractions_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; /** - * Thread ID for a thread that accepts network channels and then supervises - * listening to those network channels for incoming P2P (physical) connections. + * Thread ID for a thread that accepts network abstractions and then supervises + * listening to those network abstractions for incoming P2P (physical) connections. */ lf_thread_t inbound_p2p_handling_thread_id; /** - * A network channel for the server of the federate. + * A network abstraction for the server of the federate. * This is assigned in lf_create_server(). - * This network channel is used to listen to incoming physical connections from + * This network abstraction is used to listen to incoming physical connections from * remote federates. Once an incoming connection is accepted, the - * opened network channel will be stored in - * federate_netchans_for_inbound_p2p_connections. + * opened network abstraction will be stored in + * federate_net_abstractions_for_inbound_p2p_connections. */ - netchan_t server_netchan; + net_abstraction_t server_net_abstraction; /** * Most recent tag advance grant (TAG) received from the RTI, or NEVER if none @@ -234,10 +234,10 @@ typedef enum parse_rti_code_t { SUCCESS, INVALID_PORT, INVALID_HOST, INVALID_USE // Global variables /** - * @brief Mutex lock held while performing outbound network channel write and close operations. + * @brief Mutex lock held while performing outbound network abstraction write and close operations. * @ingroup Federated */ -extern lf_mutex_t lf_outbound_netchan_mutex; +extern lf_mutex_t lf_outbound_net_abstraction_mutex; /** * @brief Condition variable for blocking on unkonwn federate input ports. @@ -256,10 +256,10 @@ extern lf_cond_t lf_port_status_changed; * to send messages directly to the specified federate. * This function first sends an MSG_TYPE_ADDRESS_QUERY message to the RTI to obtain * the IP address and port number of the specified federate. It then attempts - * to establish a network channel connection to the specified federate. + * to establish a network abstraction connection to the specified federate. * If this fails, the program exits. If it succeeds, it sets element [id] of - * the _fed.netchans_for_outbound_p2p_connections global array to - * refer to the network channel for communicating directly with the federate. + * the _fed.net_abstractions_for_outbound_p2p_connections global array to + * refer to the network abstraction for communicating directly with the federate. * * @param remote_federate_id The ID of the remote federate. */ @@ -269,12 +269,12 @@ void lf_connect_to_federate(uint16_t remote_federate_id); * @brief Connect to the RTI at the specified host and port. * @ingroup Federated * - * This will return the network channel for the connection. + * This will return the network abstraction for the connection. * If port_number is 0, then start at DEFAULT_PORT and increment * the port number on each attempt. If an attempt fails, wait CONNECT_RETRY_INTERVAL * and try again. If it fails after CONNECT_TIMEOUT, the program exits. - * If it succeeds, it sets the _fed.netchan_to_RTI global variable to refer to - * the network channel for communicating with the RTI. + * If it succeeds, it sets the _fed.net_abstraction_to_RTI global variable to refer to + * the network abstraction for communicating with the RTI. * * @param hostname A hostname, such as "localhost". * @param port_number A port number or 0 to start with the default. @@ -286,8 +286,8 @@ void lf_connect_to_rti(const char* hostname, int port_number); * @ingroup Federated * * Such connections are used for physical connections or any connection if using - * decentralized coordination. This function only handles the creation of the server network channel. - * The bound port for the server network channel is then sent to the RTI by sending an + * decentralized coordination. This function only handles the creation of the server network abstraction. + * The bound port for the server network abstraction is then sent to the RTI by sending an * MSG_TYPE_ADDRESS_ADVERTISEMENT message (@see net_common.h). * This function expects no response from the RTI. * @@ -317,8 +317,8 @@ void lf_enqueue_port_absent_reactions(environment_t* env); * * This thread accepts connections from federates that send messages directly * to this one (not through the RTI). This thread starts a thread for - * each accepted network channel connection to read messages and, once it has opened all expected - * network channels, exits. + * each accepted network abstraction connection to read messages and, once it has opened all expected + * network abstractions, exits. * @param ignored No argument needed for this thread. */ void* lf_handle_p2p_connections_from_federates(void* ignored); @@ -365,7 +365,7 @@ void lf_reset_status_fields_on_input_port_triggers(void); * between federates. If the connection to the remote federate or the RTI has been broken, * then this returns -1 without sending. Otherwise, it returns 0. * - * This method assumes that the caller does not hold the lf_outbound_netchan_mutex lock, + * This method assumes that the caller does not hold the lf_outbound_net_abstraction_mutex lock, * which it acquires to perform the send. * * @param message_type The type of the message being sent (currently only MSG_TYPE_P2P_MESSAGE). @@ -390,7 +390,7 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa * @see @ref MSG_TYPE_NEIGHBOR_STRUCTURE in @ref net_common.h * @param socket_TCP_RTI The socket descriptor for the connection to the RTI. */ -void lf_send_neighbor_structure_to_RTI(netchan_t); +void lf_send_neighbor_structure_to_RTI(net_abstraction_t); /** * @brief Send a next event tag (NET) signal. @@ -472,7 +472,7 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d * * The payload is the specified tag plus one microstep. If this federate has previously * received a stop request from the RTI, then do not send the message and - * return 1. Return -1 if the network channel is disconnected. Otherwise, return 0. + * return 1. Return -1 if the network abstraction is disconnected. Otherwise, return 0. * @return 0 if the message is sent. */ int lf_send_stop_request_to_rti(tag_t stop_tag); @@ -485,7 +485,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag); * If the delayed tag falls after the timeout time, then the message is not sent and -1 is returned. * The caller can reuse or free the memory storing the message after this returns. * - * If the message fails to send (e.g. the network channel connection is broken), then the + * If the message fails to send (e.g. the network abstraction connection is broken), then the * response depends on the message_type. For MSG_TYPE_TAGGED_MESSAGE, the message is * supposed to go via the RTI, and failure to communicate with the RTI is a critical failure. * In this case, the program will exit with an error message. If the message type is @@ -494,7 +494,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag); * to believe that there were no messages forthcoming. In this case, on failure to send * the message, this function returns -11. * - * This method assumes that the caller does not hold the lf_outbound_netchan_mutex lock, + * This method assumes that the caller does not hold the lf_outbound_net_abstraction_mutex lock, * which it acquires to perform the send. * * @param env The environment from which to get the current tag. @@ -557,7 +557,7 @@ void lf_stall_advance_level_federation_locked(size_t level); * @ingroup Federated * * This assumes that a connection to the RTI is already made - * and netchan_to_RTI is valid. It then sends the current logical + * and net_abstraction_to_RTI is valid. It then sends the current logical * time to the RTI and waits for the RTI to respond with a specified * time. It starts a thread to listen for messages from the RTI. */ diff --git a/network/api/net_abstraction.h b/network/api/net_abstraction.h new file mode 100644 index 000000000..834cc8497 --- /dev/null +++ b/network/api/net_abstraction.h @@ -0,0 +1,291 @@ +/** + * @file net_abstraction.h + * @brief Public network abstraction API (net_abstraction) interface. + * @ingroup Network + * + * @author Dongha Kim + * @author Hokeun Kim + * + * This header defines the interface for network abstractions used by federated Lingua Franca programs. + * It abstracts network operations behind a small API that supports server/client creation, + * connection management, robust read/write with error handling, graceful shutdown, and + * querying local/peer addressing information. + */ + +#ifndef NET_ABSTRACTION_H +#define NET_ABSTRACTION_H + +#include "socket_common.h" + +typedef void* net_abstraction_t; +// net_abstraction_t +/** + * @brief Allocate and initialize a network abstraction handle. + * @ingroup Network + * + * Allocate memory for the network abstraction. + * @return net_abstraction_t Initialized network abstraction. + */ +net_abstraction_t initialize_net_abstraction(); + +/** + * @brief Create a server network abstraction that will accept incoming connections. + * @ingroup Network + * + * Create a network abstraction server. This is such as a server socket which accepts connections. + * However this is only the creation of the server network abstraction. + * + * @param net_abs Server's network abstraction. + * @param increment_port_on_retry Whether to increment the port on retry if binding fails. + * @return int 0 for success, -1 for failure. + */ +int create_server(net_abstraction_t net_abs, bool increment_port_on_retry); + +/** + * @brief Accept an incoming connection on a server network abstraction. + * @ingroup Network + * + * Wait for an incoming connection request on the specified server network abstraction. + * The implementation should include three steps. + * 1. Initialize the network abstraction of the connected federate. + * 2. Wait for the incoming connection request. This should block until the connection is successfully accepted. + * 3. Save the information in the connected network abstraction, such as the address of the connected peer, for future + * querying address. + * + * @param server_chan The server network abstraction that is listening for incoming connections. + * @param rti_chan The rti's network abstraction to check if it is still open. + * @return net_abstraction_t The network abstraction for the newly accepted connection on success, or NULL on failure + */ +net_abstraction_t accept_net_abstraction(net_abstraction_t server_chan, net_abstraction_t rti_chan); + +/** + * @brief Initialize a client network abstraction for connecting to a server. + * @ingroup Network + * + * Using the initialized network abstraction, create a client network abstraction ready to connect to a server. + * + * @param net_abs The initialized network abstraction. + */ +void create_client(net_abstraction_t net_abs); + +/** + * @brief Connect a client network abstraction to its configured server. + * @ingroup Network + * + * Connect to the server network abstraction. The server's connection information, + * such as the port and address should be set before calling this function. + * + * @param net_abs network abstraction to connect. + * @return 0 for success, -1 on failure, and `errno` is set to indicate the specific error. + */ +int connect_to_net_abstraction(net_abstraction_t net_abs); + +/** + * @brief Read a fixed number of bytes from a network abstraction. + * @ingroup Network + * + * Read the specified number of bytes from the specified network abstraction into the specified buffer. + * If an error occurs during reading, return -1 and set errno to indicate the cause. + * If the read succeeds in reading the specified number of bytes, return 0. + * If an EOF occurs before reading the specified number of bytes, return 1. + * + * @param net_abs The network abstraction. + * @param num_bytes The number of bytes to read. + * @param buffer The buffer into which to put the bytes. + * @return 0 for success, 1 for EOF, and -1 for an error. + */ +int read_from_net_abstraction(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); + +/** + * @brief Read bytes and close the network abstraction on error. + * @ingroup Network + * + * Uses read_from_net_abstraction and closes the channel if an error occurs. + * + * @param net_abs The network abstraction. + * @param num_bytes The number of bytes to read. + * @param buffer The buffer into which to get the bytes. + * @return 0 for success, -1 for failure. + */ +int read_from_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); + +/** + * @brief Read bytes from a network abstraction and fail (exit) on error. + * @ingroup Network + * + * Read the specified number of bytes from the specified network abstraction into the + * specified buffer. If a disconnect or an EOF occurs during this + * reading, then if format is non-null, report an error and exit. + * If format is null, then report the error, but do not exit. + * This function takes a formatted string and additional optional arguments + * similar to printf(format, ...) that is appended to the error messages. + * + * @param net_abs The network abstraction. + * @param num_bytes The number of bytes to read. + * @param buffer The buffer into which to put the bytes. + * @param format A printf-style format string, followed by arguments to + * fill the string, or NULL to not exit with an error message. + */ +void read_from_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, + char* format, ...); + +/** + * @brief Write a fixed number of bytes to a network abstraction. + * @ingroup Network + * + * Write the specified number of bytes to the specified network abstraction using write_to_net_abstraction + * and close the network abstraction if an error occurs. + * If an error occurs, return -1 and set errno to indicate the cause. If the write succeeds, return 0. + * This function retries until the specified number of bytes have been written or an error occurs. + * + * @param net_abs The network abstraction. + * @param num_bytes The number of bytes to write. + * @param buffer The buffer from which to get the bytes. + * @return 0 for success, -1 for failure. + */ +int write_to_net_abstraction(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); + +/** + * @brief Write bytes to a network abstraction and close on error. + * @ingroup Network + * + * Uses write_to_net_abstraction and closes the channel if an error occurs. + * + * @param net_abs The network abstraction. + * @param num_bytes The number of bytes to write. + * @param buffer The buffer from which to get the bytes. + * @return 0 for success, -1 for failure. + */ +int write_to_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); + +/** + * @brief Write bytes to a network abstraction and fail (exit) on error. + * @ingroup Network + * + * Write the specified number of bytes to the specified network abstraction using + * write_to_net_abstraction_close_on_error and exit with an error code if an error occurs. + * If the mutex argument is non-NULL, release the mutex before exiting. If the + * format argument is non-null, then use it an any additional arguments to form + * the error message using printf conventions. Otherwise, print a generic error + * message. + * @param net_abs The network abstraction. + * @param num_bytes The number of bytes to write. + * @param buffer The buffer from which to get the bytes. + * @param mutex If non-NULL, the mutex to unlock before exiting. + * @param format A format string for error messages, followed by any number of + * fields that will be used to fill the format string as in printf, or NULL + * to print a generic error message. + */ +void write_to_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, + lf_mutex_t* mutex, char* format, ...); + +/** + * @brief Check whether the network abstraction is closed. + * @ingroup Network + * + * Checks if the network abstraction is still connected to the peer. + * + * @param net_abs The network abstraction. + * @return true if closed, false if still open. + */ +bool check_net_abstraction_closed(net_abstraction_t net_abs); + +/** + * @brief Gracefully shut down and close a network abstraction. + * @ingroup Network + * + * If read_before_closing is false, call shutdown() with SHUT_RDWR and then close(). If true, call shutdown() with + * SHUT_WR, then read() until EOF and discard received bytes before closing. + * + * @param net_abs The network abstraction to shut down and close. + * @param net_abs The network abstraction to shutdown and close. + * @param read_before_closing If true, read until EOF before closing the network abstraction. + * @return int Returns 0 on success, -1 on failure (errno will indicate the error). + */ +int shutdown_net_abstraction(net_abstraction_t net_abs, bool read_before_closing); + +/** + * @brief Get the server port number of this network abstraction. + * @ingroup Network + * + * Get the open port number from the network abstraction. + * This is used when the federate sends a MSG_TYPE_ADDRESS_ADVERTISEMENT to the RTI, informing its port number. The RTI + * will save this port number, and send it to the other federate in a MSG_TYPE_ADDRESS_QUERY_REPLY message. + * + * @param net_abs The network abstraction. + * @return The port number of a server network abstraction. + */ +int32_t get_my_port(net_abstraction_t net_abs); + +/** + * @brief Get the connected peer's port number. + * @ingroup Network + * + * Get the port number of the connected peer. + * This is used by the RTI, when there is a request from the federate to the RTI, for the MSG_TYPE_ADDRESS_QUERY + * message. + * + * @param net_abs The network abstraction. + * @return Port number of the connected peer. + */ +int32_t get_server_port(net_abstraction_t net_abs); + +/** + * @brief Get the connected peer's IP address. + * @ingroup Network + * + * Get the IP address of the connected peer. + * + * @param net_abs The network abstraction. + * @return Pointer to the server IP address. + */ +struct in_addr* get_ip_addr(net_abstraction_t net_abs); + +/** + * @brief Get the connected peer's hostname. + * @ingroup Network + * + * Get the hostname of the connected peer. + * + * @param net_abs The network abstraction. + * @return Pointer to the server hostname. + */ +char* get_server_hostname(net_abstraction_t net_abs); + +/** + * @brief Set the user-specified port for this network abstraction. + * @ingroup Network + * + * Set the user specified port to the created network abstraction. + * + * @param net_abs The network abstraction. + * @param port The user specified port. + */ +void set_my_port(net_abstraction_t net_abs, int32_t port); + +/** + * @brief Set the target server's port number for this network abstraction. + * @ingroup Network + * + * Set server port number to the target network abstraction. + * The federate and RTI receives the port number from another + * federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. + * This function is used to set the network abstraction's target server port number. + * + * @param net_abs The network abstraction. + * @param port The target server's port. + */ +void set_server_port(net_abstraction_t net_abs, int32_t port); + +/** + * @brief Set the target server's port number for this network abstraction. + * @ingroup Network + * + * Set the target server's hostname to the network abstraction. + * + * @param net_abs The network abstraction. + * @param hostname The target server's hostname. + */ +void set_server_hostname(net_abstraction_t net_abs, const char* hostname); + +#endif /* NET_ABSTRACTION_H */ diff --git a/network/api/net_driver.h b/network/api/net_driver.h deleted file mode 100644 index cf37367cc..000000000 --- a/network/api/net_driver.h +++ /dev/null @@ -1,290 +0,0 @@ -/** - * @file net_driver.h - * @brief Public network channel API (netchan) interface. - * @ingroup Network - * - * @author Dongha Kim - * @author Hokeun Kim - * - * This header defines the interface for network channels used by federated Lingua Franca programs. - * It abstracts network operations behind a small API that supports server/client creation, - * connection management, robust read/write with error handling, graceful shutdown, and - * querying local/peer addressing information. - */ - -#ifndef NET_DRIVER_H -#define NET_DRIVER_H - -#include "socket_common.h" - -typedef void* netchan_t; - -/** - * @brief Allocate and initialize a network channel handle. - * @ingroup Network - * - * Allocate memory for the network channel. - * @return netchan_t Initialized network channel. - */ -netchan_t initialize_netchan(); - -/** - * @brief Create a server network channel that will accept incoming connections. - * @ingroup Network - * - * Create a netchannel server. This is such as a server socket which accepts connections. - * However this is only the creation of the server network channel. - * - * @param chan Server's network channel. - * @param increment_port_on_retry Whether to increment the port on retry if binding fails. - * @return int 0 for success, -1 for failure. - */ -int create_server(netchan_t chan, bool increment_port_on_retry); - -/** - * @brief Accept an incoming connection on a server network channel. - * @ingroup Network - * - * Wait for an incoming connection request on the specified server network channel. - * The implementation should include three steps. - * 1. Initialize the network channel of the connected federate. - * 2. Wait for the incoming connection request. This should block until the connection is successfully accepted. - * 3. Save the information in the connected network channel, such as the address of the connected peer, for future - * querying address. - * - * @param server_chan The server network channel that is listening for incoming connections. - * @param rti_chan The rti's network channel to check if it is still open. - * @return netchan_t The network channel for the newly accepted connection on success, or NULL on failure - */ -netchan_t accept_netchan(netchan_t server_chan, netchan_t rti_chan); - -/** - * @brief Initialize a client network channel for connecting to a server. - * @ingroup Network - * - * Using the initialized network channel, create a client network channel ready to connect to a server. - * - * @param chan The initialized network channel. - */ -void create_client(netchan_t chan); - -/** - * @brief Connect a client network channel to its configured server. - * @ingroup Network - * - * Connect to the server network channel. The server's connection information, - * such as the port and address should be set before calling this function. - * - * @param chan network channel to connect. - * @return 0 for success, -1 on failure, and `errno` is set to indicate the specific error. - */ -int connect_to_netchan(netchan_t chan); - -/** - * @brief Read a fixed number of bytes from a network channel. - * @ingroup Network - * - * Read the specified number of bytes from the specified network channel into the specified buffer. - * If an error occurs during reading, return -1 and set errno to indicate the cause. - * If the read succeeds in reading the specified number of bytes, return 0. - * If an EOF occurs before reading the specified number of bytes, return 1. - * - * @param chan The network channel. - * @param num_bytes The number of bytes to read. - * @param buffer The buffer into which to put the bytes. - * @return 0 for success, 1 for EOF, and -1 for an error. - */ -int read_from_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer); - -/** - * @brief Read bytes and close the network channel on error. - * @ingroup Network - * - * Uses read_from_netchan and closes the channel if an error occurs. - * - * @param chan The network channel. - * @param num_bytes The number of bytes to read. - * @param buffer The buffer into which to get the bytes. - * @return 0 for success, -1 for failure. - */ -int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer); - -/** - * @brief Read bytes from a network channel and fail (exit) on error. - * @ingroup Network - * - * Read the specified number of bytes from the specified network channel into the - * specified buffer. If a disconnect or an EOF occurs during this - * reading, then if format is non-null, report an error and exit. - * If format is null, then report the error, but do not exit. - * This function takes a formatted string and additional optional arguments - * similar to printf(format, ...) that is appended to the error messages. - * - * @param chan The network channel. - * @param num_bytes The number of bytes to read. - * @param buffer The buffer into which to put the bytes. - * @param format A printf-style format string, followed by arguments to - * fill the string, or NULL to not exit with an error message. - */ -void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, char* format, ...); - -/** - * @brief Write a fixed number of bytes to a network channel. - * @ingroup Network - * - * Write the specified number of bytes to the specified network channel using write_to_netchan - * and close the network channel if an error occurs. - * If an error occurs, return -1 and set errno to indicate the cause. If the write succeeds, return 0. - * This function retries until the specified number of bytes have been written or an error occurs. - * - * @param chan The network channel. - * @param num_bytes The number of bytes to write. - * @param buffer The buffer from which to get the bytes. - * @return 0 for success, -1 for failure. - */ -int write_to_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer); - -/** - * @brief Write bytes to a network channel and close on error. - * @ingroup Network - * - * Uses write_to_netchan and closes the channel if an error occurs. - * - * @param chan The network channel. - * @param num_bytes The number of bytes to write. - * @param buffer The buffer from which to get the bytes. - * @return 0 for success, -1 for failure. - */ -int write_to_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer); - -/** - * @brief Write bytes to a network channel and fail (exit) on error. - * @ingroup Network - * - * Write the specified number of bytes to the specified network channel using - * write_to_netchan_close_on_error and exit with an error code if an error occurs. - * If the mutex argument is non-NULL, release the mutex before exiting. If the - * format argument is non-null, then use it an any additional arguments to form - * the error message using printf conventions. Otherwise, print a generic error - * message. - * @param chan The network channel. - * @param num_bytes The number of bytes to write. - * @param buffer The buffer from which to get the bytes. - * @param mutex If non-NULL, the mutex to unlock before exiting. - * @param format A format string for error messages, followed by any number of - * fields that will be used to fill the format string as in printf, or NULL - * to print a generic error message. - */ -void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...); - -/** - * @brief Check whether the network channel is closed. - * @ingroup Network - * - * Checks if the network channel is still connected to the peer. - * - * @param chan The network channel. - * @return true if closed, false if still open. - */ -bool check_netchan_closed(netchan_t chan); - -/** - * @brief Gracefully shut down and close a network channel. - * @ingroup Network - * - * If read_before_closing is false, call shutdown() with SHUT_RDWR and then close(). If true, call shutdown() with SHUT_WR, - * then read() until EOF and discard received bytes before closing. - * - * @param chan The network channel to shut down and close. - * @param chan The network channel to shutdown and close. - * @param read_before_closing If true, read until EOF before closing the network channel. - * @return int Returns 0 on success, -1 on failure (errno will indicate the error). - */ -int shutdown_netchan(netchan_t chan, bool read_before_closing); - -/** - * @brief Get the server port number of this network channel. - * @ingroup Network - * - * Get the open port number from the network channel. - * This is used when the federate sends a MSG_TYPE_ADDRESS_ADVERTISEMENT to the RTI, informing its port number. The RTI - * will save this port number, and send it to the other federate in a MSG_TYPE_ADDRESS_QUERY_REPLY message. - * - * @param chan The network channel. - * @return The port number of a server network channel. - */ -int32_t get_my_port(netchan_t chan); - -/** - * @brief Get the connected peer's port number. - * @ingroup Network - * - * Get the port number of the connected peer. - * This is used by the RTI, when there is a request from the federate to the RTI, for the MSG_TYPE_ADDRESS_QUERY - * message. - * - * @param chan The network channel. - * @return Port number of the connected peer. - */ -int32_t get_server_port(netchan_t chan); - -/** - * @brief Get the connected peer's IP address. - * @ingroup Network - * - * Get the IP address of the connected peer. - * - * @param chan The network channel. - * @return Pointer to the server IP address. - */ -struct in_addr* get_ip_addr(netchan_t chan); - -/** - * @brief Get the connected peer's hostname. - * @ingroup Network - * - * Get the hostname of the connected peer. - * - * @param chan The network channel. - * @return Pointer to the server hostname. - */ -char* get_server_hostname(netchan_t chan); - -/** - * @brief Set the user-specified port for this network channel. - * @ingroup Network - * - * Set the user specified port to the created network channel. - * - * @param chan The network channel. - * @param port The user specified port. - */ -void set_my_port(netchan_t chan, int32_t port); - -/** - * @brief Set the target server's port number for this network channel. - * @ingroup Network - * - * Set server port number to the target network channel. - * The federate and RTI receives the port number from another - * federate MSG_TYPE_ADDRESS_ADVERTISEMENT message. - * This function is used to set the network channel's target server port number. - * - * @param chan The network channel. - * @param port The target server's port. - */ -void set_server_port(netchan_t chan, int32_t port); - -/** - * @brief Set the target server's port number for this network channel. - * @ingroup Network - * - * Set the target server's hostname to the network channel. - * - * @param chan The network channel. - * @param hostname The target server's hostname. - */ -void set_server_hostname(netchan_t chan, const char* hostname); - -#endif /* NET_DRIVER_H */ diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index f13b72ad1..2ad52b0ef 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -12,19 +12,19 @@ #include // read() write() #include // inet_ntop -#include "net_driver.h" +#include "net_abstraction.h" #include "socket_common.h" #include "util.h" // LF_MUTEX_UNLOCK, "logging.h" -static socket_priv_t* get_socket_priv_t(netchan_t chan) { - if (chan == NULL) { - lf_print_error("Network channel is already closed."); +static socket_priv_t* get_socket_priv_t(net_abstraction_t net_abs) { + if (net_abs == NULL) { + lf_print_error("Network abstraction is already closed."); return NULL; } - return (socket_priv_t*)chan; + return (socket_priv_t*)net_abs; } -netchan_t initialize_netchan() { +net_abstraction_t initialize_net_abstraction() { // Initialize priv. socket_priv_t* priv = malloc(sizeof(socket_priv_t)); if (priv == NULL) { @@ -41,37 +41,37 @@ netchan_t initialize_netchan() { priv->server_ip_addr.s_addr = 0; priv->server_port = -1; - return (netchan_t)priv; + return (net_abstraction_t)priv; } -void free_netchan(netchan_t chan) { - socket_priv_t* priv = get_socket_priv_t(chan); +void free_net_abstraction(net_abstraction_t net_abs) { + socket_priv_t* priv = get_socket_priv_t(net_abs); free(priv); } -int create_server(netchan_t chan, bool increment_port_on_retry) { - socket_priv_t* priv = get_socket_priv_t(chan); +int create_server(net_abstraction_t net_abs, bool increment_port_on_retry) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return create_socket_server(priv->user_specified_port, &priv->socket_descriptor, &priv->port, TCP, increment_port_on_retry); } -netchan_t accept_netchan(netchan_t server_chan, netchan_t rti_chan) { +net_abstraction_t accept_net_abstraction(net_abstraction_t server_chan, net_abstraction_t rti_chan) { socket_priv_t* serv_priv = get_socket_priv_t(server_chan); int rti_socket; if (rti_chan == NULL) { - // Set to -1, to indicate that this accept_netchan() call is not trying to check if the rti_chan is available, - // inside the accept_socket() function. + // Set to -1, to indicate that this accept_net_abstraction() call is not trying to check if the rti_chan is + // available, inside the accept_socket() function. rti_socket = -1; } else { socket_priv_t* rti_priv = get_socket_priv_t(rti_chan); rti_socket = rti_priv->socket_descriptor; } - netchan_t fed_netchan = initialize_netchan(); - socket_priv_t* fed_priv = get_socket_priv_t(fed_netchan); + net_abstraction_t fed_net_abstraction = initialize_net_abstraction(); + socket_priv_t* fed_priv = get_socket_priv_t(fed_net_abstraction); int sock = accept_socket(serv_priv->socket_descriptor, rti_socket); if (sock == -1) { - free_netchan(fed_netchan); + free_net_abstraction(fed_net_abstraction); return NULL; } fed_priv->socket_descriptor = sock; @@ -79,27 +79,27 @@ netchan_t accept_netchan(netchan_t server_chan, netchan_t rti_chan) { if (get_peer_address(fed_priv) != 0) { lf_print_error("RTI failed to get peer address."); }; - return fed_netchan; + return fed_net_abstraction; } -void create_client(netchan_t chan) { - socket_priv_t* priv = get_socket_priv_t(chan); +void create_client(net_abstraction_t net_abs) { + socket_priv_t* priv = get_socket_priv_t(net_abs); priv->socket_descriptor = create_real_time_tcp_socket_errexit(); } -int connect_to_netchan(netchan_t chan) { - socket_priv_t* priv = get_socket_priv_t(chan); +int connect_to_net_abstraction(net_abstraction_t net_abs) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return connect_to_socket(priv->socket_descriptor, priv->server_hostname, priv->server_port); } -int read_from_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = get_socket_priv_t(chan); +int read_from_net_abstraction(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return read_from_socket(priv->socket_descriptor, num_bytes, buffer); } -int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = get_socket_priv_t(chan); - int read_failed = read_from_netchan(chan, num_bytes, buffer); +int read_from_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = get_socket_priv_t(net_abs); + int read_failed = read_from_net_abstraction(net_abs, num_bytes, buffer); if (read_failed) { // Read failed. // Socket has probably been closed from the other side. @@ -110,9 +110,10 @@ int read_from_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned return 0; } -void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, char* format, ...) { +void read_from_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, + char* format, ...) { va_list args; - int read_failed = read_from_netchan_close_on_error(chan, num_bytes, buffer); + int read_failed = read_from_net_abstraction_close_on_error(net_abs, num_bytes, buffer); if (read_failed) { // Read failed. if (format != NULL) { @@ -125,14 +126,14 @@ void read_from_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned } } -int write_to_netchan(netchan_t chan, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = get_socket_priv_t(chan); +int write_to_net_abstraction(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return write_to_socket(priv->socket_descriptor, num_bytes, buffer); } -int write_to_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer) { - socket_priv_t* priv = get_socket_priv_t(chan); - int result = write_to_netchan(chan, num_bytes, buffer); +int write_to_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { + socket_priv_t* priv = get_socket_priv_t(net_abs); + int result = write_to_net_abstraction(net_abs, num_bytes, buffer); if (result) { // Write failed. // Socket has probably been closed from the other side. @@ -142,10 +143,10 @@ int write_to_netchan_close_on_error(netchan_t chan, size_t num_bytes, unsigned c return result; } -void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, - char* format, ...) { +void write_to_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, + lf_mutex_t* mutex, char* format, ...) { va_list args; - int result = write_to_netchan_close_on_error(chan, num_bytes, buffer); + int result = write_to_net_abstraction_close_on_error(net_abs, num_bytes, buffer); if (result) { // Write failed. if (mutex != NULL) { @@ -161,53 +162,53 @@ void write_to_netchan_fail_on_error(netchan_t chan, size_t num_bytes, unsigned c } } -bool check_netchan_closed(netchan_t chan) { - socket_priv_t* priv = get_socket_priv_t(chan); +bool check_net_abstraction_closed(net_abstraction_t net_abs) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return check_socket_closed(priv->socket_descriptor); } -int shutdown_netchan(netchan_t chan, bool read_before_closing) { - if (chan == NULL) { +int shutdown_net_abstraction(net_abstraction_t net_abs, bool read_before_closing) { + if (net_abs == NULL) { LF_PRINT_LOG("Socket already closed."); return 0; } - socket_priv_t* priv = get_socket_priv_t(chan); + socket_priv_t* priv = get_socket_priv_t(net_abs); int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); - free_netchan(chan); + free_net_abstraction(net_abs); return ret; } -int32_t get_my_port(netchan_t chan) { - socket_priv_t* priv = get_socket_priv_t(chan); +int32_t get_my_port(net_abstraction_t net_abs) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return priv->port; } -int32_t get_server_port(netchan_t chan) { - socket_priv_t* priv = get_socket_priv_t(chan); +int32_t get_server_port(net_abstraction_t net_abs) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return priv->server_port; } -struct in_addr* get_ip_addr(netchan_t chan) { - socket_priv_t* priv = get_socket_priv_t(chan); +struct in_addr* get_ip_addr(net_abstraction_t net_abs) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return &priv->server_ip_addr; } -char* get_server_hostname(netchan_t chan) { - socket_priv_t* priv = get_socket_priv_t(chan); +char* get_server_hostname(net_abstraction_t net_abs) { + socket_priv_t* priv = get_socket_priv_t(net_abs); return priv->server_hostname; } -void set_my_port(netchan_t chan, int32_t port) { - socket_priv_t* priv = get_socket_priv_t(chan); +void set_my_port(net_abstraction_t net_abs, int32_t port) { + socket_priv_t* priv = get_socket_priv_t(net_abs); priv->port = port; } -void set_server_port(netchan_t chan, int32_t port) { - socket_priv_t* priv = get_socket_priv_t(chan); +void set_server_port(net_abstraction_t net_abs, int32_t port) { + socket_priv_t* priv = get_socket_priv_t(net_abs); priv->server_port = port; } -void set_server_hostname(netchan_t chan, const char* hostname) { - socket_priv_t* priv = get_socket_priv_t(chan); +void set_server_hostname(net_abstraction_t net_abs, const char* hostname) { + socket_priv_t* priv = get_socket_priv_t(net_abs); memcpy(priv->server_hostname, hostname, INET_ADDRSTRLEN); } diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index e424c3446..1e6a0a187 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -22,12 +22,12 @@ #include // strerror #include "util.h" // LF_MUTEX_UNLOCK(), logging.h -#include "net_driver.h" +#include "net_abstraction.h" /** Number of nanoseconds to sleep before retrying a socket read. */ #define SOCKET_READ_RETRY_INTERVAL 1000000 -// Mutex lock held while performing network channel shutdown and close operations. +// Mutex lock held while performing network abstraction shutdown and close operations. lf_mutex_t shutdown_mutex; int create_real_time_tcp_socket_errexit(void) { From 29e15fe68f1fb6f0b806096ba623e346d21b09ff Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 7 Nov 2025 12:45:03 -0700 Subject: [PATCH 156/167] format --- network/api/socket_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/api/socket_common.h b/network/api/socket_common.h index 0e9490c5c..c14633f1d 100644 --- a/network/api/socket_common.h +++ b/network/api/socket_common.h @@ -13,7 +13,7 @@ * and performing read/write operations with proper error handling and retry mechanisms. * The file also defines various constants for timeouts, retry intervals, and port configurations. */ - + #ifndef SOCKET_COMMON_H #define SOCKET_COMMON_H From 322be0c774c825e681b6221b61ba488ed09420d3 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 14 Nov 2025 10:49:33 -0700 Subject: [PATCH 157/167] Shorten names from net_abstraction to net. --- core/federated/RTI/main.c | 2 +- core/federated/RTI/rti_remote.c | 234 ++++++++--------- core/federated/RTI/rti_remote.h | 10 +- core/federated/clock-sync.c | 29 +-- core/federated/federate.c | 365 +++++++++++++-------------- include/core/federated/clock-sync.h | 14 +- include/core/federated/federate.h | 26 +- network/api/net_abstraction.h | 33 ++- network/impl/src/lf_socket_support.c | 48 ++-- 9 files changed, 364 insertions(+), 397 deletions(-) diff --git a/core/federated/RTI/main.c b/core/federated/RTI/main.c index f8afef687..13e93eaa9 100644 --- a/core/federated/RTI/main.c +++ b/core/federated/RTI/main.c @@ -56,7 +56,7 @@ static void send_failed_signal(federate_info_t* fed) { if (rti.base.tracing_enabled) { tracepoint_rti_to_federate(send_FAILED, fed->enclave.id, NULL); } - int failed = write_to_net_abstraction(fed->fed_net_abstraction, bytes_to_write, &(buffer[0])); + int failed = write_to_net(fed->net, bytes_to_write, &(buffer[0])); if (failed == 0) { LF_PRINT_LOG("RTI has sent failed signal to federate %d due to abnormal termination.", fed->enclave.id); } else { diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 2a26599ad..1fee3b657 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -71,9 +71,9 @@ void notify_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_TAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the network abstraction might close, causing the following write_to_net_abstraction + // function. During this call, the network abstraction might close, causing the following write_to_net // to fail. Consider a failure here a soft failure and update the federate's status. - if (write_to_net_abstraction(((federate_info_t*)e)->fed_net_abstraction, message_length, buffer)) { + if (write_to_net(((federate_info_t*)e)->net, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -104,9 +104,9 @@ void notify_provisional_tag_advance_grant(scheduling_node_t* e, tag_t tag) { tracepoint_rti_to_federate(send_PTAG, e->id, &tag); } // This function is called in notify_advance_grant_if_safe(), which is a long - // function. During this call, the network abstraction might close, causing the following write_to_net_abstraction + // function. During this call, the network abstraction might close, causing the following write_to_net // to fail. Consider a failure here a soft failure and update the federate's status. - if (write_to_net_abstraction(((federate_info_t*)e)->fed_net_abstraction, message_length, buffer)) { + if (write_to_net(((federate_info_t*)e)->net, message_length, buffer)) { lf_print_error("RTI failed to send tag advance grant to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -163,7 +163,7 @@ void notify_downstream_next_event_tag(scheduling_node_t* e, tag_t tag) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_DNET, e->id, &tag); } - if (write_to_net_abstraction(((federate_info_t*)e)->fed_net_abstraction, message_length, buffer)) { + if (write_to_net(((federate_info_t*)e)->net, message_length, buffer)) { lf_print_error("RTI failed to send downstream next event tag to federate %d.", e->id); e->state = NOT_CONNECTED; } else { @@ -185,9 +185,9 @@ void update_federate_next_event_tag_locked(uint16_t federate_id, tag_t next_even void handle_port_absent_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t message_size = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(int64_t) + sizeof(uint32_t); - read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, message_size, &(buffer[1]), - " RTI failed to read port absent message from federate %u.", - sending_federate->enclave.id); + read_from_net_fail_on_error(sending_federate->net, message_size, &(buffer[1]), + " RTI failed to read port absent message from federate %u.", + sending_federate->enclave.id); uint16_t reactor_port_id = extract_uint16(&(buffer[1])); uint16_t federate_id = extract_uint16(&(buffer[1 + sizeof(uint16_t)])); @@ -234,8 +234,8 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char } // Forward the message. - write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, message_size + 1, buffer, &rti_mutex, - "RTI failed to forward message to federate %d.", federate_id); + write_to_net_fail_on_error(fed->net, message_size + 1, buffer, &rti_mutex, + "RTI failed to forward message to federate %d.", federate_id); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -243,8 +243,8 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char void handle_timed_message(federate_info_t* sending_federate, unsigned char* buffer) { size_t header_size = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(int64_t) + sizeof(uint32_t); // Read the header, minus the first byte which has already been read. - read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, header_size - 1, &(buffer[1]), - "RTI failed to read the timed message header from remote federate."); + read_from_net_fail_on_error(sending_federate->net, header_size - 1, &(buffer[1]), + "RTI failed to read the timed message header from remote federate."); // Extract the header information. of the sender uint16_t reactor_port_id; uint16_t federate_id; @@ -272,8 +272,8 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff sending_federate->enclave.id, federate_id, reactor_port_id, intended_tag.time - lf_time_start(), intended_tag.microstep); - read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, bytes_to_read, &(buffer[header_size]), - "RTI failed to read timed message from federate %d.", federate_id); + read_from_net_fail_on_error(sending_federate->net, bytes_to_read, &(buffer[header_size]), + "RTI failed to read timed message from federate %d.", federate_id); size_t bytes_read = bytes_to_read + header_size; // Following only works for string messages. // LF_PRINT_DEBUG("Message received by RTI: %s.", buffer + header_size); @@ -308,8 +308,7 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, bytes_to_read, buffer, - "RTI failed to clear message chunks."); + read_from_net_fail_on_error(sending_federate->net, bytes_to_read, buffer, "RTI failed to clear message chunks."); total_bytes_read += bytes_to_read; } LF_MUTEX_UNLOCK(&rti_mutex); @@ -330,8 +329,8 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff tracepoint_rti_to_federate(send_TAGGED_MSG, federate_id, &intended_tag); } - write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, bytes_read, buffer, &rti_mutex, - "RTI failed to forward message to federate %d.", federate_id); + write_to_net_fail_on_error(fed->net, bytes_read, buffer, &rti_mutex, "RTI failed to forward message to federate %d.", + federate_id); // The message length may be longer than the buffer, // in which case we have to handle it in chunks. @@ -342,16 +341,14 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff if (bytes_to_read > FED_COM_BUFFER_SIZE) { bytes_to_read = FED_COM_BUFFER_SIZE; } - read_from_net_abstraction_fail_on_error(sending_federate->fed_net_abstraction, bytes_to_read, buffer, - "RTI failed to read message chunks."); + read_from_net_fail_on_error(sending_federate->net, bytes_to_read, buffer, "RTI failed to read message chunks."); total_bytes_read += bytes_to_read; // FIXME: a mutex needs to be held for this so that other threads // do not write to destination_socket and cause interleaving. However, // holding the rti_mutex might be very expensive. Instead, each outgoing // network abstraction should probably have its own mutex. - write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, bytes_to_read, buffer, &rti_mutex, - "RTI failed to send message chunks."); + write_to_net_fail_on_error(fed->net, bytes_to_read, buffer, &rti_mutex, "RTI failed to send message chunks."); } // Record this in-transit message in federate's in-transit message queue. @@ -380,9 +377,9 @@ void handle_timed_message(federate_info_t* sending_federate, unsigned char* buff void handle_latest_tag_confirmed(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_net_abstraction_fail_on_error( - fed->fed_net_abstraction, sizeof(int64_t) + sizeof(uint32_t), buffer, - "RTI failed to read the content of the logical tag complete from federate %d.", fed->enclave.id); + read_from_net_fail_on_error(fed->net, sizeof(int64_t) + sizeof(uint32_t), buffer, + "RTI failed to read the content of the logical tag complete from federate %d.", + fed->enclave.id); tag_t completed = extract_tag(buffer); if (rti_remote->base.tracing_enabled) { tracepoint_rti_from_federate(receive_LTC, fed->enclave.id, &completed); @@ -398,9 +395,9 @@ void handle_latest_tag_confirmed(federate_info_t* fed) { void handle_next_event_tag(federate_info_t* fed) { unsigned char buffer[sizeof(int64_t) + sizeof(uint32_t)]; - read_from_net_abstraction_fail_on_error(fed->fed_net_abstraction, sizeof(int64_t) + sizeof(uint32_t), buffer, - "RTI failed to read the content of the next event tag from federate %d.", - fed->enclave.id); + read_from_net_fail_on_error(fed->net, sizeof(int64_t) + sizeof(uint32_t), buffer, + "RTI failed to read the content of the next event tag from federate %d.", + fed->enclave.id); // Acquire a mutex lock to ensure that this state does not change while a // message is in transport or being used to determine a TAG. @@ -456,9 +453,8 @@ static void broadcast_stop_time_to_federates_locked() { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_STOP_GRN, fed->enclave.id, &rti_remote->base.max_stop_tag); } - write_to_net_abstraction_fail_on_error( - fed->fed_net_abstraction, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, - "RTI failed to send MSG_TYPE_STOP_GRANTED message to federate %d.", fed->enclave.id); + write_to_net_fail_on_error(fed->net, MSG_TYPE_STOP_GRANTED_LENGTH, outgoing_buffer, &rti_mutex, + "RTI failed to send MSG_TYPE_STOP_GRANTED message to federate %d.", fed->enclave.id); } LF_PRINT_LOG("RTI sent to federates MSG_TYPE_STOP_GRANTED with tag " PRINTF_TAG, @@ -510,9 +506,9 @@ void handle_stop_request_message(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_net_abstraction_fail_on_error(fed->fed_net_abstraction, bytes_to_read, buffer, - "RTI failed to read the MSG_TYPE_STOP_REQUEST payload from federate %d.", - fed->enclave.id); + read_from_net_fail_on_error(fed->net, bytes_to_read, buffer, + "RTI failed to read the MSG_TYPE_STOP_REQUEST payload from federate %d.", + fed->enclave.id); // Extract the proposed stop tag for the federate tag_t proposed_stop_tag = extract_tag(buffer); @@ -577,9 +573,8 @@ void handle_stop_request_message(federate_info_t* fed) { if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_STOP_REQ, f->enclave.id, &rti_remote->base.max_stop_tag); } - write_to_net_abstraction_fail_on_error( - f->fed_net_abstraction, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, - "RTI failed to forward MSG_TYPE_STOP_REQUEST message to federate %d.", f->enclave.id); + write_to_net_fail_on_error(f->net, MSG_TYPE_STOP_REQUEST_LENGTH, stop_request_buffer, &rti_mutex, + "RTI failed to forward MSG_TYPE_STOP_REQUEST message to federate %d.", f->enclave.id); } } LF_PRINT_LOG("RTI forwarded to federates MSG_TYPE_STOP_REQUEST with tag (" PRINTF_TIME ", %u).", @@ -590,9 +585,9 @@ void handle_stop_request_message(federate_info_t* fed) { void handle_stop_request_reply(federate_info_t* fed) { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_REPLY_LENGTH - 1; unsigned char buffer_stop_time[bytes_to_read]; - read_from_net_abstraction_fail_on_error( - fed->fed_net_abstraction, bytes_to_read, buffer_stop_time, - "RTI failed to read the reply to MSG_TYPE_STOP_REQUEST message from federate %d.", fed->enclave.id); + read_from_net_fail_on_error(fed->net, bytes_to_read, buffer_stop_time, + "RTI failed to read the reply to MSG_TYPE_STOP_REQUEST message from federate %d.", + fed->enclave.id); tag_t federate_stop_tag = extract_tag(buffer_stop_time); @@ -620,8 +615,7 @@ void handle_address_query(uint16_t fed_id) { // Use buffer both for reading and constructing the reply. // The length is what is needed for the reply. unsigned char buffer[1 + sizeof(int32_t)]; - read_from_net_abstraction_fail_on_error(fed->fed_net_abstraction, sizeof(uint16_t), (unsigned char*)buffer, - "Failed to read address query."); + read_from_net_fail_on_error(fed->net, sizeof(uint16_t), (unsigned char*)buffer, "Failed to read address query."); uint16_t remote_fed_id = extract_uint16(buffer); if (rti_remote->base.tracing_enabled) { @@ -646,7 +640,7 @@ void handle_address_query(uint16_t fed_id) { LF_MUTEX_LOCK(&rti_mutex); // Check if the RTI has initialized the remote federate's network abstraction. - if (remote_fed->fed_net_abstraction == NULL) { + if (remote_fed->net == NULL) { // RTI has not set up the remote federate. Respond with -1 to indicate an unknown port number. server_port = -1; uint32_t temp = 0; @@ -656,21 +650,19 @@ void handle_address_query(uint16_t fed_id) { // The network abstraction is initialized, but the RTI might still not know the port number. This can happen if the // RTI has not yet received a MSG_TYPE_ADDRESS_ADVERTISEMENT message from the remote federate. In such cases, the // returned port number might still be -1. - server_port = get_server_port(remote_fed->fed_net_abstraction); - ip_address = (uint32_t*)get_ip_addr(remote_fed->fed_net_abstraction); - server_host_name = get_server_hostname(remote_fed->fed_net_abstraction); + server_port = get_server_port(remote_fed->net); + ip_address = (uint32_t*)get_ip_addr(remote_fed->net); + server_host_name = get_server_hostname(remote_fed->net); } encode_int32(server_port, (unsigned char*)&buffer[1]); // Send the port number (which could be -1) and the server IP address to federate. - write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, 1 + sizeof(int32_t), (unsigned char*)buffer, - &rti_mutex, - "Failed to write port number to network abstraction of federate %d.", fed_id); + write_to_net_fail_on_error(fed->net, 1 + sizeof(int32_t), (unsigned char*)buffer, &rti_mutex, + "Failed to write port number to network abstraction of federate %d.", fed_id); - write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, sizeof(uint32_t), (unsigned char*)ip_address, - &rti_mutex, - "Failed to write ip address to network abstraction of federate %d.", fed_id); + write_to_net_fail_on_error(fed->net, sizeof(uint32_t), (unsigned char*)ip_address, &rti_mutex, + "Failed to write ip address to network abstraction of federate %d.", fed_id); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_DEBUG("Replied to address query from federate %d with address %s:%d.", fed_id, server_host_name, @@ -683,15 +675,15 @@ void handle_address_ad(uint16_t federate_id) { // connections to other federates int32_t server_port = -1; unsigned char buffer[sizeof(int32_t)]; - read_from_net_abstraction_fail_on_error(fed->fed_net_abstraction, sizeof(int32_t), (unsigned char*)buffer, - "Error reading port data from federate %d.", federate_id); + read_from_net_fail_on_error(fed->net, sizeof(int32_t), (unsigned char*)buffer, + "Error reading port data from federate %d.", federate_id); server_port = extract_int32(buffer); assert(server_port < 65536); LF_MUTEX_LOCK(&rti_mutex); - set_server_port(fed->fed_net_abstraction, server_port); + set_server_port(fed->net, server_port); LF_MUTEX_UNLOCK(&rti_mutex); LF_PRINT_LOG("Received address advertisement with port %d from federate %d.", server_port, federate_id); @@ -703,8 +695,8 @@ void handle_address_ad(uint16_t federate_id) { void handle_timestamp(federate_info_t* my_fed) { unsigned char buffer[sizeof(int64_t)]; // Read bytes from the network abstraction. We need 8 bytes. - read_from_net_abstraction_fail_on_error(my_fed->fed_net_abstraction, sizeof(int64_t), (unsigned char*)&buffer, - "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); + read_from_net_fail_on_error(my_fed->net, sizeof(int64_t), (unsigned char*)&buffer, + "ERROR reading timestamp from federate %d.\n", my_fed->enclave.id); int64_t timestamp = swap_bytes_if_big_endian_int64(*((int64_t*)(&buffer))); if (rti_remote->base.tracing_enabled) { @@ -745,7 +737,7 @@ void handle_timestamp(federate_info_t* my_fed) { tag_t tag = {.time = start_time, .microstep = 0}; tracepoint_rti_to_federate(send_TIMESTAMP, my_fed->enclave.id, &tag); } - if (write_to_net_abstraction(my_fed->fed_net_abstraction, MSG_TYPE_TIMESTAMP_LENGTH, start_time_buffer)) { + if (write_to_net(my_fed->net, MSG_TYPE_TIMESTAMP_LENGTH, start_time_buffer)) { lf_print_error("Failed to send the starting time to federate %d.", my_fed->enclave.id); } @@ -785,9 +777,8 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool // Send using network abstraction. LF_PRINT_DEBUG("Clock sync: RTI sending message type %u.", buffer[0]); LF_MUTEX_LOCK(&rti_mutex); - write_to_net_abstraction_fail_on_error(fed->fed_net_abstraction, 1 + sizeof(int64_t), buffer, &rti_mutex, - "Clock sync: RTI failed to send physical time to federate %d.", - fed->enclave.id); + write_to_net_fail_on_error(fed->net, 1 + sizeof(int64_t), buffer, &rti_mutex, + "Clock sync: RTI failed to send physical time to federate %d.", fed->enclave.id); LF_MUTEX_UNLOCK(&rti_mutex); } LF_PRINT_DEBUG("Clock sync: RTI sent PHYSICAL_TIME_SYNC_MESSAGE with timestamp " PRINTF_TIME " to federate %d.", @@ -924,7 +915,7 @@ static void handle_federate_failed(federate_info_t* my_fed) { // Indicate that there will no further events from this federate. my_fed->enclave.next_event = FOREVER_TAG; - shutdown_net_abstraction(my_fed->fed_net_abstraction, false); + shutdown_net(my_fed->net, false); // Check downstream federates to see whether they should now be granted a TAG. // To handle cycles, need to create a boolean array to keep @@ -963,7 +954,7 @@ static void handle_federate_resign(federate_info_t* my_fed) { // Indicate that there will no further events from this federate. my_fed->enclave.next_event = FOREVER_TAG; - shutdown_net_abstraction(my_fed->fed_net_abstraction, true); + shutdown_net(my_fed->net, true); // Check downstream federates to see whether they should now be granted a TAG. // To handle cycles, need to create a boolean array to keep @@ -987,14 +978,14 @@ void* federate_info_thread_TCP(void* fed) { // Listen for messages from the federate. while (my_fed->enclave.state != NOT_CONNECTED) { // Read no more than one byte to get the message type. - int read_failed = read_from_net_abstraction(my_fed->fed_net_abstraction, 1, buffer); + int read_failed = read_from_net(my_fed->net, 1, buffer); if (read_failed) { // network abstraction is closed lf_print_error("RTI: network abstraction to federate %d is closed. Exiting the thread.", my_fed->enclave.id); my_fed->enclave.state = NOT_CONNECTED; // Nothing more to do. Close the network abstraction and exit. // Prevent multiple threads from closing the same network abstraction at the same time. - shutdown_net_abstraction(my_fed->fed_net_abstraction, false); + shutdown_net(my_fed->net, false); // FIXME: We need better error handling here, but do not stop execution here. break; } @@ -1054,11 +1045,11 @@ void send_reject(net_abstraction_t net_abs, unsigned char error_code) { response[1] = error_code; LF_MUTEX_LOCK(&rti_mutex); // NOTE: Ignore errors on this response. - if (write_to_net_abstraction(net_abs, 2, response)) { + if (write_to_net(net_abs, 2, response)) { lf_print_warning("RTI failed to write MSG_TYPE_REJECT message on the network abstraction."); } // Close the network abstraction without reading until EOF. - shutdown_net_abstraction(net_abs, false); + shutdown_net(net_abs, false); LF_MUTEX_UNLOCK(&rti_mutex); } @@ -1067,16 +1058,16 @@ void send_reject(net_abstraction_t net_abs, unsigned char error_code) { * a federate ID and a federation ID. If the federation ID * matches this federation, send an MSG_TYPE_ACK and otherwise send * a MSG_TYPE_REJECT message. - * @param fed_net_abstraction Pointer to the network abstraction on which to listen. + * @param fed_net Pointer to the network abstraction on which to listen. * @return The federate ID for success or -1 for failure. */ -static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstraction) { +static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net) { // Buffer for message ID, federate ID, and federation ID length. size_t length = 1 + sizeof(uint16_t) + 1; // Message ID, federate ID, length of fedration ID. unsigned char buffer[length]; // Read bytes from the network abstraction. We need 4 bytes. - if (read_from_net_abstraction_close_on_error(fed_net_abstraction, length, buffer)) { + if (read_from_net_close_on_error(fed_net, length, buffer)) { lf_print_error("RTI failed to read from accepted network abstraction."); return -1; } @@ -1096,12 +1087,12 @@ static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstra // of the peer they want to connect to from the RTI. // If the connection is a peer-to-peer connection between two // federates, reject the connection with the WRONG_SERVER error. - send_reject(fed_net_abstraction, WRONG_SERVER); + send_reject(fed_net, WRONG_SERVER); } else if (buffer[0] == MSG_TYPE_FED_NONCE) { - send_reject(fed_net_abstraction, RTI_NOT_EXECUTED_WITH_AUTH); + send_reject(fed_net, RTI_NOT_EXECUTED_WITH_AUTH); lf_print_error("RTI not executed with HMAC authentication option using -a or --auth."); } else { - send_reject(fed_net_abstraction, UNEXPECTED_MESSAGE); + send_reject(fed_net, UNEXPECTED_MESSAGE); } lf_print_error("RTI expected a MSG_TYPE_FED_IDS message. Got %u (see net_common.h).", buffer[0]); return -1; @@ -1114,8 +1105,7 @@ static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstra size_t federation_id_length = (size_t)buffer[sizeof(uint16_t) + 1]; char federation_id_received[federation_id_length + 1]; // One extra for null terminator. // Next read the actual federation ID. - if (read_from_net_abstraction_close_on_error(fed_net_abstraction, federation_id_length, - (unsigned char*)federation_id_received)) { + if (read_from_net_close_on_error(fed_net, federation_id_length, (unsigned char*)federation_id_received)) { lf_print_error("RTI failed to read federation id from federate %d.", fed_id); return -1; } @@ -1136,7 +1126,7 @@ static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstra if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_net_abstraction, FEDERATION_ID_DOES_NOT_MATCH); + send_reject(fed_net, FEDERATION_ID_DOES_NOT_MATCH); return -1; } else { if (fed_id >= rti_remote->base.number_of_scheduling_nodes) { @@ -1145,7 +1135,7 @@ static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstra if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_net_abstraction, FEDERATE_ID_OUT_OF_RANGE); + send_reject(fed_net, FEDERATE_ID_OUT_OF_RANGE); return -1; } else { if ((rti_remote->base.scheduling_nodes[fed_id])->state != NOT_CONNECTED) { @@ -1153,7 +1143,7 @@ static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstra if (rti_remote->base.tracing_enabled) { tracepoint_rti_to_federate(send_REJECT, fed_id, NULL); } - send_reject(fed_net_abstraction, FEDERATE_ID_IN_USE); + send_reject(fed_net, FEDERATE_ID_IN_USE); return -1; } } @@ -1162,7 +1152,7 @@ static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstra federate_info_t* fed = GET_FED_INFO(fed_id); // The MSG_TYPE_FED_IDS message has the right federation ID. - fed->fed_net_abstraction = fed_net_abstraction; + fed->net = fed_net; // Set the federate's state as pending // because it is waiting for the start time to be @@ -1176,7 +1166,7 @@ static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstra tracepoint_rti_to_federate(send_ACK, fed_id, NULL); } LF_MUTEX_LOCK(&rti_mutex); - if (write_to_net_abstraction_close_on_error(fed->fed_net_abstraction, 1, &ack_message)) { + if (write_to_net_close_on_error(fed->net, 1, &ack_message)) { LF_MUTEX_UNLOCK(&rti_mutex); lf_print_error("RTI failed to write MSG_TYPE_ACK message to federate %d.", fed_id); return -1; @@ -1193,18 +1183,18 @@ static int32_t receive_and_check_fed_id_message(net_abstraction_t fed_net_abstra * out the relevant information in the federate's struct. * @return 1 on success and 0 on failure. */ -static int receive_connection_information(net_abstraction_t fed_net_abstraction, uint16_t fed_id) { +static int receive_connection_information(net_abstraction_t fed_net, uint16_t fed_id) { LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_NEIGHBOR_STRUCTURE from federate %d.", fed_id); unsigned char connection_info_header[MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE]; - read_from_net_abstraction_fail_on_error( - fed_net_abstraction, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, - "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message header from federate %d.", fed_id); + read_from_net_fail_on_error(fed_net, MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE, connection_info_header, + "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message header from federate %d.", + fed_id); if (connection_info_header[0] != MSG_TYPE_NEIGHBOR_STRUCTURE) { lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", fed_id, connection_info_header[0]); - send_reject(fed_net_abstraction, UNEXPECTED_MESSAGE); + send_reject(fed_net, UNEXPECTED_MESSAGE); return 0; } else { federate_info_t* fed = GET_FED_INFO(fed_id); @@ -1236,9 +1226,9 @@ static int receive_connection_information(net_abstraction_t fed_net_abstraction, if (connections_info_body_size > 0) { connections_info_body = (unsigned char*)malloc(connections_info_body_size); LF_ASSERT_NON_NULL(connections_info_body); - read_from_net_abstraction_fail_on_error( - fed_net_abstraction, connections_info_body_size, connections_info_body, - "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message body from federate %d.", fed_id); + read_from_net_fail_on_error(fed_net, connections_info_body_size, connections_info_body, + "RTI failed to read MSG_TYPE_NEIGHBOR_STRUCTURE message body from federate %d.", + fed_id); // Keep track of where we are in the buffer size_t message_head = 0; // First, read the info about upstream federates @@ -1270,23 +1260,23 @@ static int receive_connection_information(net_abstraction_t fed_net_abstraction, * up to perform runtime clock synchronization using the UDP port number * specified in the payload to communicate with the federate's clock * synchronization logic. - * @param fed_net_abstraction The network abstraction on which to listen. + * @param fed_net The network abstraction on which to listen. * @param fed_id The federate ID. * @return 1 for success, 0 for failure. */ -static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net_abstraction, uint16_t fed_id) { +static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net, uint16_t fed_id) { // Read the MSG_TYPE_UDP_PORT message from the federate regardless of the status of // clock synchronization. This message will tell the RTI whether the federate // is doing clock synchronization, and if it is, what port to use for UDP. LF_PRINT_DEBUG("RTI waiting for MSG_TYPE_UDP_PORT from federate %d.", fed_id); unsigned char response[1 + sizeof(uint16_t)]; - read_from_net_abstraction_fail_on_error(fed_net_abstraction, 1 + sizeof(uint16_t), response, - "RTI failed to read MSG_TYPE_UDP_PORT message from federate %d.", fed_id); + read_from_net_fail_on_error(fed_net, 1 + sizeof(uint16_t), response, + "RTI failed to read MSG_TYPE_UDP_PORT message from federate %d.", fed_id); if (response[0] != MSG_TYPE_UDP_PORT) { lf_print_error("RTI was expecting a MSG_TYPE_UDP_PORT message from federate %d. Got %u instead. " "Rejecting federate.", fed_id, response[0]); - send_reject(fed_net_abstraction, UNEXPECTED_MESSAGE); + send_reject(fed_net, UNEXPECTED_MESSAGE); return 0; } else { federate_info_t* fed = GET_FED_INFO(fed_id); @@ -1307,15 +1297,15 @@ static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net_a // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); unsigned char buffer[message_size]; - read_from_net_abstraction_fail_on_error(fed_net_abstraction, message_size, buffer, - "network abstraction to federate %d unexpectedly closed.", fed_id); + read_from_net_fail_on_error(fed_net, message_size, buffer, + "network abstraction to federate %d unexpectedly closed.", fed_id); if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); LF_PRINT_DEBUG("RTI received T3 clock sync message from federate %d.", fed_id); handle_physical_clock_sync_message(fed, false); } else { lf_print_error("Unexpected message %u from federate %d.", buffer[0], fed_id); - send_reject(fed_net_abstraction, UNEXPECTED_MESSAGE); + send_reject(fed_net, UNEXPECTED_MESSAGE); return 0; } } @@ -1327,7 +1317,7 @@ static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net_a // Initialize the UDP_addr field of the federate struct fed->UDP_addr.sin_family = AF_INET; fed->UDP_addr.sin_port = htons(federate_UDP_port_number); - fed->UDP_addr.sin_addr = *get_ip_addr(fed_net_abstraction); + fed->UDP_addr.sin_addr = *get_ip_addr(fed_net); } } else { // Disable clock sync after initial round. @@ -1350,15 +1340,14 @@ static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net_a /** * Authenticate incoming federate by performing HMAC-based authentication. * - * @param fed_net_abstraction network abstraction for the incoming federate tryting to authenticate. + * @param fed_net network abstraction for the incoming federate tryting to authenticate. * @return True if authentication is successful and false otherwise. */ -static bool authenticate_federate(net_abstraction_t fed_net_abstraction) { +static bool authenticate_federate(net_abstraction_t fed_net) { // Wait for MSG_TYPE_FED_NONCE from federate. size_t fed_id_length = sizeof(uint16_t); unsigned char buffer[1 + fed_id_length + NONCE_LENGTH]; - read_from_net_abstraction_fail_on_error(fed_net_abstraction, 1 + fed_id_length + NONCE_LENGTH, buffer, - "Failed to read MSG_TYPE_FED_NONCE"); + read_from_net_fail_on_error(fed_net, 1 + fed_id_length + NONCE_LENGTH, buffer, "Failed to read MSG_TYPE_FED_NONCE"); if (buffer[0] != MSG_TYPE_FED_NONCE) { lf_print_error_and_exit("Received unexpected response %u from the FED (see net_common.h).", buffer[0]); } @@ -1382,14 +1371,13 @@ static bool authenticate_federate(net_abstraction_t fed_net_abstraction) { RAND_bytes(rti_nonce, NONCE_LENGTH); memcpy(&sender[1], rti_nonce, NONCE_LENGTH); memcpy(&sender[1 + NONCE_LENGTH], hmac_tag, hmac_length); - if (write_to_net_abstraction(fed_net_abstraction, 1 + NONCE_LENGTH + hmac_length, sender)) { + if (write_to_net(fed_net, 1 + NONCE_LENGTH + hmac_length, sender)) { lf_print_error("Failed to send nonce to federate."); } // Wait for MSG_TYPE_FED_RESPONSE unsigned char received[1 + hmac_length]; - read_from_net_abstraction_fail_on_error(fed_net_abstraction, 1 + hmac_length, received, - "Failed to read federate response."); + read_from_net_fail_on_error(fed_net, 1 + hmac_length, received, "Failed to read federate response."); if (received[0] != MSG_TYPE_FED_RESPONSE) { lf_print_error_and_exit("Received unexpected response %u from the federate (see net_common.h).", received[0]); return false; @@ -1408,7 +1396,7 @@ static bool authenticate_federate(net_abstraction_t fed_net_abstraction) { if (memcmp(&received[1], rti_tag, hmac_length) != 0) { // Federation IDs do not match. Send back a HMAC_DOES_NOT_MATCH message. lf_print_warning("HMAC authentication failed. Rejecting the federate."); - send_reject(fed_net_abstraction, HMAC_DOES_NOT_MATCH); + send_reject(fed_net, HMAC_DOES_NOT_MATCH); return false; } else { LF_PRINT_LOG("Federate's HMAC verified."); @@ -1417,20 +1405,20 @@ static bool authenticate_federate(net_abstraction_t fed_net_abstraction) { } #endif -void lf_connect_to_federates(net_abstraction_t rti_net_abstraction) { +void lf_connect_to_federates(net_abstraction_t rti_net) { for (int i = 0; i < rti_remote->base.number_of_scheduling_nodes; i++) { - net_abstraction_t fed_net_abstraction = accept_net_abstraction(rti_net_abstraction, NULL); - if (fed_net_abstraction == NULL) { + net_abstraction_t fed_net = accept_net(rti_net, NULL); + if (fed_net == NULL) { lf_print_warning("RTI failed to accept the federate."); return; } // Wait for the first message from the federate when RTI -a option is on. #ifdef __RTI_AUTH__ if (rti_remote->authentication_enabled) { - if (!authenticate_federate(fed_net_abstraction)) { + if (!authenticate_federate(fed_net)) { lf_print_warning("RTI failed to authenticate the incoming federate."); // Close the network abstraction without reading until EOF. - shutdown_net_abstraction(fed_net_abstraction, false); + shutdown_net(fed_net, false); // Ignore the federate that failed authentication. i--; continue; @@ -1439,9 +1427,9 @@ void lf_connect_to_federates(net_abstraction_t rti_net_abstraction) { #endif // The first message from the federate should contain its ID and the federation ID. - int32_t fed_id = receive_and_check_fed_id_message(fed_net_abstraction); - if (fed_id >= 0 && receive_connection_information(fed_net_abstraction, (uint16_t)fed_id) && - receive_udp_message_and_set_up_clock_sync(fed_net_abstraction, (uint16_t)fed_id)) { + int32_t fed_id = receive_and_check_fed_id_message(fed_net); + if (fed_id >= 0 && receive_connection_information(fed_net, (uint16_t)fed_id) && + receive_udp_message_and_set_up_clock_sync(fed_net, (uint16_t)fed_id)) { // Create a thread to communicate with the federate. // This has to be done after clock synchronization is finished @@ -1480,9 +1468,9 @@ void* respond_to_erroneous_connections(void* nothing) { while (true) { // Wait for an incoming connection request. // The following will block until either a federate attempts to connect - // or shutdown_net_abstraction(rti->rti_net_abstraction) is called. - net_abstraction_t fed_net_abstraction = accept_net_abstraction(rti_remote->rti_net_abstraction, NULL); - if (fed_net_abstraction == NULL) { + // or shutdown_net(rti->rti_net) is called. + net_abstraction_t fed_net = accept_net(rti_remote->rti_net, NULL); + if (fed_net == NULL) { return NULL; } if (rti_remote->all_federates_exited) { @@ -1494,11 +1482,11 @@ void* respond_to_erroneous_connections(void* nothing) { response[0] = MSG_TYPE_REJECT; response[1] = FEDERATION_ID_DOES_NOT_MATCH; // Ignore errors on this response. - if (write_to_net_abstraction(fed_net_abstraction, 2, response)) { + if (write_to_net(fed_net, 2, response)) { lf_print_warning("RTI failed to write FEDERATION_ID_DOES_NOT_MATCH to erroneous incoming connection."); } // Close the network abstraction without reading until EOF. - shutdown_net_abstraction(fed_net_abstraction, false); + shutdown_net(fed_net, false); } return NULL; } @@ -1513,11 +1501,11 @@ void initialize_federate(federate_info_t* fed, uint16_t id) { int start_rti_server() { _lf_initialize_clock(); // Initialize RTI's network abstraction. - rti_remote->rti_net_abstraction = initialize_net_abstraction(); + rti_remote->rti_net = initialize_net(); // Set the user specified port to the network abstraction. - set_my_port(rti_remote->rti_net_abstraction, rti_remote->user_specified_port); + set_my_port(rti_remote->rti_net, rti_remote->user_specified_port); // Create the server - if (create_server(rti_remote->rti_net_abstraction, true)) { + if (create_server(rti_remote->rti_net, true)) { lf_print_error_system_failure("RTI failed to create TCP server: %s.", strerror(errno)); return -1; }; @@ -1535,7 +1523,7 @@ int start_rti_server() { void wait_for_federates() { // Wait for connections from federates and create a thread for each. - lf_connect_to_federates(rti_remote->rti_net_abstraction); + lf_connect_to_federates(rti_remote->rti_net); // All federates have connected. lf_print("RTI: All expected federates have connected. Starting execution."); @@ -1562,7 +1550,7 @@ void wait_for_federates() { // Shutdown and close the network abstraction that is listening for incoming connections // so that the accept() call in respond_to_erroneous_connections returns. // That thread should then check rti->all_federates_exited and it should exit. - shutdown_net_abstraction(rti_remote->rti_net_abstraction, false); + shutdown_net(rti_remote->rti_net, false); if (rti_remote->socket_descriptor_UDP > 0) { // UDP only uses sockets. diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index dae2dfdaf..0ea32c826 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -54,7 +54,7 @@ typedef struct federate_info_t { /** @brief The ID of the thread handling communication with this federate. */ lf_thread_t thread_id; /** @brief The network abstraction for communicating with this federate. */ - net_abstraction_t fed_net_abstraction; + net_abstraction_t net; /** @brief The UDP address for the federate. */ struct sockaddr_in UDP_addr; /** @brief Indicates the status of clock synchronization for this federate. Enabled by default. */ @@ -113,7 +113,7 @@ typedef struct rti_remote_t { const char* federation_id; /** @brief The desired port specified by the user on the command line. - * This should be not moved to the net_abstraction, because the user can configure this as -p or --port. + * This should be not moved to the net_abstraction_t, because the user can configure this as -p or --port. */ uint16_t user_specified_port; @@ -126,7 +126,7 @@ typedef struct rti_remote_t { /** * The rti's network abstraction. */ - net_abstraction_t rti_net_abstraction; + net_abstraction_t rti_net; /** @brief Thread performing PTP clock sync sessions periodically. */ lf_thread_t clock_thread; @@ -361,9 +361,9 @@ void send_reject(net_abstraction_t net_abs, unsigned char error_code); * * Return when all federates have connected. * - * @param rti_net_abstraction The rti's network abstraction on which to accept connections. + * @param rti_net The rti's network abstraction on which to accept connections. */ -void lf_connect_to_federates(net_abstraction_t rti_net_abstraction); +void lf_connect_to_federates(net_abstraction_t rti_net); /** * @brief Thread to respond to new connections, which could be federates of other federations diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index 6ee7f2720..ee4abe5a5 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -170,7 +170,7 @@ uint16_t setup_clock_synchronization_with_rti() { return port_to_return; } -void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net_abstraction) { +void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net) { LF_PRINT_DEBUG("Waiting for initial clock synchronization messages from the RTI."); size_t message_size = 1 + sizeof(instant_t); @@ -178,9 +178,9 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net_abstr for (int i = 0; i < _LF_CLOCK_SYNC_EXCHANGES_PER_INTERVAL; i++) { // The first message expected from the RTI is MSG_TYPE_CLOCK_SYNC_T1 - read_from_net_abstraction_fail_on_error( - rti_net_abstraction, message_size, buffer, - "Federate %d did not get the initial clock synchronization message T1 from the RTI.", _lf_my_fed_id); + read_from_net_fail_on_error(rti_net, message_size, buffer, + "Federate %d did not get the initial clock synchronization message T1 from the RTI.", + _lf_my_fed_id); // Get local physical time before doing anything else. instant_t receive_time = lf_time_physical(); @@ -192,14 +192,14 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net_abstr // Handle the message and send a reply T3 message. // NOTE: No need to acquire the mutex lock during initialization because only // one thread is running. - if (handle_T1_clock_sync_message(buffer, (void*)rti_net_abstraction, receive_time, false) != 0) { + if (handle_T1_clock_sync_message(buffer, (void*)rti_net, receive_time, false) != 0) { lf_print_error_and_exit("Initial clock sync: Failed to send T3 reply to RTI."); } // Next message from the RTI is required to be MSG_TYPE_CLOCK_SYNC_T4 - read_from_net_abstraction_fail_on_error( - rti_net_abstraction, message_size, buffer, - "Federate %d did not get the clock synchronization message T4 from the RTI.", _lf_my_fed_id); + read_from_net_fail_on_error(rti_net, message_size, buffer, + "Federate %d did not get the clock synchronization message T4 from the RTI.", + _lf_my_fed_id); // Check that this is the T4 message. if (buffer[0] != MSG_TYPE_CLOCK_SYNC_T4) { @@ -207,13 +207,13 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net_abstr } // Handle the message. - handle_T4_clock_sync_message(buffer, (void*)rti_net_abstraction, receive_time, false); + handle_T4_clock_sync_message(buffer, (void*)rti_net, receive_time, false); } LF_PRINT_LOG("Finished initial clock synchronization with the RTI."); } -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net_abstraction, instant_t t2, bool use_udp) { +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, bool use_udp) { // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); @@ -233,9 +233,8 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net_abst // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); - int result = use_udp ? write_to_socket(*(int*)socket_or_net_abstraction, 1 + sizeof(uint16_t), reply_buffer) - : write_to_net_abstraction((net_abstraction_t)socket_or_net_abstraction, 1 + sizeof(uint16_t), - reply_buffer); + int result = use_udp ? write_to_socket(*(int*)socket_or_net, 1 + sizeof(uint16_t), reply_buffer) + : write_to_net((net_abstraction_t)socket_or_net, 1 + sizeof(uint16_t), reply_buffer); if (result) { lf_print_error("Clock sync: Failed to send T3 message to RTI."); @@ -249,7 +248,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net_abst return 0; } -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net_abstraction, instant_t r4, bool use_udp) { +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, bool use_udp) { // Increment the number of received T4 messages _lf_rti_socket_stat.received_T4_messages_in_current_sync_window++; @@ -284,7 +283,7 @@ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net_abs if (use_udp) { // Read the coded probe message. // We can reuse the same buffer. - int read_failed = read_from_socket(*(int*)socket_or_net_abstraction, 1 + sizeof(instant_t), buffer); + int read_failed = read_from_socket(*(int*)socket_or_net, 1 + sizeof(instant_t), buffer); instant_t r5 = lf_time_physical(); diff --git a/core/federated/federate.c b/core/federated/federate.c index c5fa94284..b1bf08915 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -44,7 +44,7 @@ extern instant_t start_time; extern bool _lf_termination_executed; // Global variables references in federate.h -lf_mutex_t lf_outbound_net_abstraction_mutex; +lf_mutex_t lf_outbound_net_mutex; lf_cond_t lf_port_status_changed; @@ -72,7 +72,7 @@ int max_level_allowed_to_advance; * and the _fed global variable refers to that instance. */ federate_instance_t _fed = {.number_of_inbound_p2p_connections = 0, - .inbound_net_abstraction_listeners = NULL, + .inbound_net_listeners = NULL, .number_of_outbound_p2p_connections = 0, .inbound_p2p_handling_thread_id = 0, .last_TAG = {.time = NEVER, .microstep = 0u}, @@ -95,7 +95,7 @@ federation_metadata_t federation_metadata = { // Static functions (used only internally) /** - * Send a time to the RTI. This acquires the lf_outbound_net_abstraction_mutex. + * Send a time to the RTI. This acquires the lf_outbound_net_mutex. * @param type The message type (MSG_TYPE_TIMESTAMP). * @param time The time. */ @@ -110,16 +110,15 @@ static void send_time(unsigned char type, instant_t time) { tag_t tag = {.time = time, .microstep = 0}; tracepoint_federate_to_rti(send_TIMESTAMP, _lf_my_fed_id, &tag); - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_write, buffer, - &lf_outbound_net_abstraction_mutex, - "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); + write_to_net_fail_on_error(_fed.net_to_RTI, bytes_to_write, buffer, &lf_outbound_net_mutex, + "Failed to send time " PRINTF_TIME " to the RTI.", time - start_time); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); } /** * Send a tag to the RTI. - * This function acquires the lf_outbound_net_abstraction_mutex. + * This function acquires the lf_outbound_net_mutex. * @param type The message type (MSG_TYPE_NEXT_EVENT_TAG or MSG_TYPE_LATEST_TAG_CONFIRMED). * @param tag The tag. */ @@ -133,18 +132,17 @@ static void send_tag(unsigned char type, tag_t tag) { trace_event_t event_type = (type == MSG_TYPE_NEXT_EVENT_TAG) ? send_NET : send_LTC; // Trace the event when tracing is enabled tracepoint_federate_to_rti(event_type, _lf_my_fed_id, &tag); - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - write_to_net_abstraction_fail_on_error( - _fed.net_abstraction_to_RTI, bytes_to_write, buffer, &lf_outbound_net_abstraction_mutex, - "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); + write_to_net_fail_on_error(_fed.net_to_RTI, bytes_to_write, buffer, &lf_outbound_net_mutex, + "Failed to send tag " PRINTF_TAG " to the RTI.", tag.time - start_time, tag.microstep); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); } /** * Return true if either the network abstraction to the RTI is broken or the network abstraction is * alive and the first unread byte on the network abstraction's queue is MSG_TYPE_FAILED. */ -static bool rti_failed() { return check_net_abstraction_closed(_fed.net_abstraction_to_RTI); } +static bool rti_failed() { return check_net_closed(_fed.net_to_RTI); } //////////////////////////////// Port Status Handling /////////////////////////////////////// @@ -438,16 +436,16 @@ static bool handle_message_now(environment_t* env, trigger_t* trigger, tag_t int * Handle a message being received from a remote federate. * * This function assumes the caller does not hold the mutex lock. - * @param net_abstraction Pointer to the network abstraction to read the message from. + * @param net Pointer to the network abstraction to read the message from. * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure. */ -static int handle_message(net_abstraction_t net_abstraction, int fed_id) { +static int handle_message(net_abstraction_t net, int fed_id) { (void)fed_id; // Read the header. size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); unsigned char buffer[bytes_to_read]; - if (read_from_net_abstraction_close_on_error(net_abstraction, bytes_to_read, buffer)) { + if (read_from_net_close_on_error(net, bytes_to_read, buffer)) { // Read failed, which means the network abstraction has been closed between reading the // message ID byte and here. return -1; @@ -468,7 +466,7 @@ static int handle_message(net_abstraction_t net_abstraction, int fed_id) { // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_net_abstraction_close_on_error(net_abstraction, length, message_contents)) { + if (read_from_net_close_on_error(net, length, message_contents)) { return -1; } // Trace the event when tracing is enabled @@ -492,11 +490,11 @@ static int handle_message(net_abstraction_t net_abstraction, int fed_id) { * will not advance to the tag of the message if it is in the future, or * the tag will not advance at all if the tag of the message is * now or in the past. - * @param net_abstraction Pointer to the network abstraction to read the message from. + * @param net Pointer to the network abstraction to read the message from. * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 on successfully reading the message, -1 on failure (e.g. due to network abstraction closed). */ -static int handle_tagged_message(net_abstraction_t net_abstraction, int fed_id) { +static int handle_tagged_message(net_abstraction_t net, int fed_id) { // Environment is always the one corresponding to the top-level scheduling enclave. environment_t* env; _lf_get_environments(&env); @@ -505,7 +503,7 @@ static int handle_tagged_message(net_abstraction_t net_abstraction, int fed_id) size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_net_abstraction_close_on_error(net_abstraction, bytes_to_read, buffer)) { + if (read_from_net_close_on_error(net, bytes_to_read, buffer)) { return -1; // Read failed. } @@ -554,7 +552,7 @@ static int handle_tagged_message(net_abstraction_t net_abstraction, int fed_id) // Read the payload. // Allocate memory for the message contents. unsigned char* message_contents = (unsigned char*)malloc(length); - if (read_from_net_abstraction_close_on_error(net_abstraction, length, message_contents)) { + if (read_from_net_close_on_error(net, length, message_contents)) { #ifdef FEDERATED_DECENTRALIZED _lf_decrement_tag_barrier_locked(env); #endif @@ -630,7 +628,7 @@ static int handle_tagged_message(net_abstraction_t net_abstraction, int fed_id) // Free the allocated memory before returning _lf_done_using(message_token); // Close network abstraction, reading any incoming data and discarding it. - shutdown_net_abstraction(_fed.net_abstractions_for_inbound_p2p_connections[fed_id], false); + shutdown_net(_fed.net_for_inbound_p2p_connections[fed_id], false); LF_MUTEX_UNLOCK(&env->mutex); return -1; } else { @@ -661,14 +659,14 @@ static int handle_tagged_message(net_abstraction_t net_abstraction, int fed_id) * This just sets the last known status tag of the port specified * in the message. * - * @param net_abstraction Pointer to the network abstraction to read the message from + * @param net Pointer to the network abstraction to read the message from * @param fed_id The sending federate ID or -1 if the centralized coordination. * @return 0 for success, -1 for failure to complete the read. */ -static int handle_port_absent_message(net_abstraction_t net_abstraction, int fed_id) { +static int handle_port_absent_message(net_abstraction_t net, int fed_id) { size_t bytes_to_read = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - if (read_from_net_abstraction_close_on_error(net_abstraction, bytes_to_read, buffer)) { + if (read_from_net_close_on_error(net, bytes_to_read, buffer)) { return -1; } @@ -705,7 +703,7 @@ static int handle_port_absent_message(net_abstraction_t net_abstraction, int fed * peer federate and calls the appropriate handling function for * each message type. If an error occurs or an EOF is received * from the peer, then this procedure sets the corresponding - * network abstraction in _fed.net_abstractions_for_inbound_p2p_connections + * network abstraction in _fed.net_for_inbound_p2p_connections * to -1 and returns, terminating the thread. * @param _args The remote federate ID (cast to void*). * @param fed_id_ptr A pointer to a uint16_t containing federate ID being listened to. @@ -717,7 +715,7 @@ static void* listen_to_federates(void* _args) { LF_PRINT_LOG("Listening to federate %d.", fed_id); - net_abstraction_t net_abstraction = _fed.net_abstractions_for_inbound_p2p_connections[fed_id]; + net_abstraction_t net = _fed.net_for_inbound_p2p_connections[fed_id]; // Buffer for incoming messages. // This does not constrain the message size @@ -726,44 +724,44 @@ static void* listen_to_federates(void* _args) { // Listen for messages from the federate. while (!_lf_termination_executed) { - bool net_abstraction_closed = false; + bool net_closed = false; // Read one byte to get the message type. LF_PRINT_DEBUG("Waiting for a P2P message."); bool bad_message = false; - if (read_from_net_abstraction_close_on_error(net_abstraction, 1, buffer)) { + if (read_from_net_close_on_error(net, 1, buffer)) { // network abstraction has been closed. lf_print("network abstraction from federate %d is closed.", fed_id); // Stop listening to this federate. - net_abstraction_closed = true; + net_closed = true; } else { LF_PRINT_DEBUG("Received a P2P message of type %d.", buffer[0]); switch (buffer[0]) { case MSG_TYPE_P2P_MESSAGE: LF_PRINT_LOG("Received untimed message from federate %d.", fed_id); - if (handle_message(net_abstraction, fed_id)) { + if (handle_message(net, fed_id)) { // Failed to complete the reading of a message on a physical connection. lf_print_warning("Failed to complete reading of message on physical connection."); - net_abstraction_closed = true; + net_closed = true; } break; case MSG_TYPE_P2P_TAGGED_MESSAGE: LF_PRINT_LOG("Received tagged message from federate %d.", fed_id); - if (handle_tagged_message(net_abstraction, fed_id)) { + if (handle_tagged_message(net, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and // it is not a fatal error if the network abstraction is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); - net_abstraction_closed = true; + net_closed = true; } break; case MSG_TYPE_PORT_ABSENT: LF_PRINT_LOG("Received port absent message from federate %d.", fed_id); - if (handle_port_absent_message(net_abstraction, fed_id)) { + if (handle_port_absent_message(net, fed_id)) { // P2P tagged messages are only used in decentralized coordination, and // it is not a fatal error if the network abstraction is closed before the whole message is read. // But this thread should exit. lf_print_warning("Failed to complete reading of tagged message."); - net_abstraction_closed = true; + net_closed = true; } break; default: @@ -776,7 +774,7 @@ static void* listen_to_federates(void* _args) { tracepoint_federate_from_federate(receive_UNIDENTIFIED, _lf_my_fed_id, fed_id, NULL); break; // while loop } - if (net_abstraction_closed) { + if (net_closed) { // For decentralized execution, once this network abstraction is closed, we // update last known tags of all ports connected to the specified federate to FOREVER_TAG, // which would eliminate the need to wait for STAA to assume an input is absent. @@ -790,26 +788,26 @@ static void* listen_to_federates(void* _args) { /** * Close the network abstraction that sends outgoing messages to the - * specified federate ID. This function acquires the lf_outbound_net_abstraction_mutex mutex lock + * specified federate ID. This function acquires the lf_outbound_net_mutex mutex lock * if _lf_normal_termination is true and otherwise proceeds without the lock. * @param fed_id The ID of the peer federate receiving messages from this * federate, or -1 if the RTI (centralized coordination). */ -static void close_outbound_net_abstraction(int fed_id) { +static void close_outbound_net(int fed_id) { assert(fed_id >= 0 && fed_id < NUMBER_OF_FEDERATES); // Close outbound connections, in case they have not closed themselves. // This will result in EOF being sent to the remote federate, except for // abnormal termination, in which case it will just close the network abstraction. if (_lf_normal_termination) { - if (_fed.net_abstractions_for_outbound_p2p_connections[fed_id] != NULL) { + if (_fed.net_for_outbound_p2p_connections[fed_id] != NULL) { // Close the network abstraction by sending a FIN packet indicating that no further writes // are expected. Then read until we get an EOF indication. - shutdown_net_abstraction(_fed.net_abstractions_for_outbound_p2p_connections[fed_id], true); - _fed.net_abstractions_for_outbound_p2p_connections[fed_id] = NULL; + shutdown_net(_fed.net_for_outbound_p2p_connections[fed_id], true); + _fed.net_for_outbound_p2p_connections[fed_id] = NULL; } } else { - shutdown_net_abstraction(_fed.net_abstractions_for_outbound_p2p_connections[fed_id], false); - _fed.net_abstractions_for_outbound_p2p_connections[fed_id] = NULL; + shutdown_net(_fed.net_for_outbound_p2p_connections[fed_id], false); + _fed.net_for_outbound_p2p_connections[fed_id] = NULL; } } @@ -832,15 +830,14 @@ static int perform_hmac_authentication() { memcpy(&fed_hello_buf[1 + fed_id_length], fed_nonce, NONCE_LENGTH); // No mutex needed during startup, hence the NULL argument. - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, message_length, fed_hello_buf, NULL, - "Failed to write nonce."); + write_to_net_fail_on_error(_fed.net_to_RTI, message_length, fed_hello_buf, NULL, "Failed to write nonce."); // Check HMAC of received FED_RESPONSE message. unsigned int hmac_length = SHA256_HMAC_LENGTH; size_t federation_id_length = strnlen(federation_metadata.federation_id, 255); unsigned char received[1 + NONCE_LENGTH + hmac_length]; - if (read_from_net_abstraction_close_on_error(_fed.net_abstraction_to_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { + if (read_from_net_close_on_error(_fed.net_to_RTI, 1 + NONCE_LENGTH + hmac_length, received)) { lf_print_warning("Failed to read RTI response."); return -1; } @@ -874,7 +871,7 @@ static int perform_hmac_authentication() { response[1] = HMAC_DOES_NOT_MATCH; // Ignore errors on writing back. - write_to_net_abstraction(_fed.net_abstraction_to_RTI, 2, response); + write_to_net(_fed.net_to_RTI, 2, response); return -1; } else { LF_PRINT_LOG("HMAC verified."); @@ -888,8 +885,7 @@ static int perform_hmac_authentication() { HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH, &sender[1], &hmac_length); - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, 1 + hmac_length, sender, NULL, - "Failed to write fed response."); + write_to_net_fail_on_error(_fed.net_to_RTI, 1 + hmac_length, sender, NULL, "Failed to write fed response."); } return 0; } @@ -913,8 +909,8 @@ static instant_t get_start_time_from_rti(instant_t my_physical_time) { size_t buffer_length = 1 + sizeof(instant_t); unsigned char buffer[buffer_length]; - read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, buffer_length, buffer, - "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); + read_from_net_fail_on_error(_fed.net_to_RTI, buffer_length, buffer, + "Failed to read MSG_TYPE_TIMESTAMP message from RTI."); LF_PRINT_DEBUG("Read 9 bytes."); // First byte received is the message ID. @@ -957,8 +953,7 @@ static void handle_tag_advance_grant(void) { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, - "Failed to read tag advance grant from RTI."); + read_from_net_fail_on_error(_fed.net_to_RTI, bytes_to_read, buffer, "Failed to read tag advance grant from RTI."); tag_t TAG = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1204,8 +1199,8 @@ static void handle_provisional_tag_advance_grant() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, - "Failed to read provisional tag advance grant from RTI."); + read_from_net_fail_on_error(_fed.net_to_RTI, bytes_to_read, buffer, + "Failed to read provisional tag advance grant from RTI."); tag_t PTAG = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1294,8 +1289,7 @@ static void handle_stop_granted_message() { size_t bytes_to_read = MSG_TYPE_STOP_GRANTED_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, - "Failed to read stop granted from RTI."); + read_from_net_fail_on_error(_fed.net_to_RTI, bytes_to_read, buffer, "Failed to read stop granted from RTI."); tag_t received_stop_tag = extract_tag(buffer); @@ -1338,8 +1332,7 @@ static void handle_stop_granted_message() { static void handle_stop_request_message() { size_t bytes_to_read = MSG_TYPE_STOP_REQUEST_LENGTH - 1; unsigned char buffer[bytes_to_read]; - read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, - "Failed to read stop request from RTI."); + read_from_net_fail_on_error(_fed.net_to_RTI, bytes_to_read, buffer, "Failed to read stop request from RTI."); tag_t tag_to_stop = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1367,7 +1360,7 @@ static void handle_stop_request_message() { // is guarded by the outbound network abstraction mutex. // The second is guarded by the global mutex. // Note that the RTI should not send stop requests more than once to federates. - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); if (_fed.received_stop_request_from_rti) { LF_PRINT_LOG("Redundant MSG_TYPE_STOP_REQUEST from RTI. Ignoring it."); already_blocked = true; @@ -1376,7 +1369,7 @@ static void handle_stop_request_message() { // prevent lf_request_stop from sending. _fed.received_stop_request_from_rti = true; } - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); if (already_blocked) { // Either we have sent a stop request to the RTI ourselves, @@ -1410,11 +1403,10 @@ static void handle_stop_request_message() { tracepoint_federate_to_rti(send_STOP_REQ_REP, _lf_my_fed_id, &tag_to_stop); // Send the current logical time to the RTI. - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, - outgoing_buffer, &lf_outbound_net_abstraction_mutex, - "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); + write_to_net_fail_on_error(_fed.net_to_RTI, MSG_TYPE_STOP_REQUEST_REPLY_LENGTH, outgoing_buffer, + &lf_outbound_net_mutex, "Failed to send the answer to MSG_TYPE_STOP_REQUEST to RTI."); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); LF_PRINT_DEBUG("Sent MSG_TYPE_STOP_REQUEST_REPLY to RTI with tag " PRINTF_TAG, tag_to_stop.time, tag_to_stop.microstep); @@ -1426,8 +1418,8 @@ static void handle_stop_request_message() { static void handle_downstream_next_event_tag() { size_t bytes_to_read = sizeof(instant_t) + sizeof(microstep_t); unsigned char buffer[bytes_to_read]; - read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_read, buffer, - "Failed to read downstream next event tag from RTI."); + read_from_net_fail_on_error(_fed.net_to_RTI, bytes_to_read, buffer, + "Failed to read downstream next event tag from RTI."); tag_t DNET = extract_tag(buffer); // Trace the event when tracing is enabled @@ -1457,10 +1449,10 @@ static void send_resign_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_RESIGN; - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_write, &(buffer[0]), - &lf_outbound_net_abstraction_mutex, "Failed to send MSG_TYPE_RESIGN."); - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); + write_to_net_fail_on_error(_fed.net_to_RTI, bytes_to_write, &(buffer[0]), &lf_outbound_net_mutex, + "Failed to send MSG_TYPE_RESIGN."); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); LF_PRINT_LOG("Resigned."); } @@ -1471,8 +1463,7 @@ static void send_failed_signal() { size_t bytes_to_write = 1; unsigned char buffer[bytes_to_write]; buffer[0] = MSG_TYPE_FAILED; - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, bytes_to_write, &(buffer[0]), NULL, - "Failed to send MSG_TYPE_FAILED."); + write_to_net_fail_on_error(_fed.net_to_RTI, bytes_to_write, &(buffer[0]), NULL, "Failed to send MSG_TYPE_FAILED."); LF_PRINT_LOG("Failed."); } @@ -1489,7 +1480,7 @@ static void handle_rti_failed_message(void) { exit(1); } * When messages arrive, this calls the appropriate handler. * @param args Ignored */ -static void* listen_to_rti_net_abstraction(void* args) { +static void* listen_to_rti_net(void* args) { (void)args; initialize_lf_thread_id(); // Buffer for incoming messages. @@ -1500,26 +1491,26 @@ static void* listen_to_rti_net_abstraction(void* args) { // Listen for messages from the federate. while (!_lf_termination_executed) { // Check whether the RTI network abstraction is still valid. - if (_fed.net_abstraction_to_RTI == NULL) { + if (_fed.net_to_RTI == NULL) { lf_print_warning("network abstraction to the RTI unexpectedly closed."); return NULL; } // Read one byte to get the message type. // This will exit if the read fails. - int read_failed = read_from_net_abstraction(_fed.net_abstraction_to_RTI, 1, buffer); + int read_failed = read_from_net(_fed.net_to_RTI, 1, buffer); if (read_failed < 0) { lf_print_error("Connection to the RTI was closed by the RTI with an error. Considering this a soft error."); - shutdown_net_abstraction(_fed.net_abstraction_to_RTI, false); + shutdown_net(_fed.net_to_RTI, false); return NULL; } else if (read_failed > 0) { // EOF received. lf_print("Connection to the RTI closed with an EOF."); - shutdown_net_abstraction(_fed.net_abstraction_to_RTI, false); + shutdown_net(_fed.net_to_RTI, false); return NULL; } switch (buffer[0]) { case MSG_TYPE_TAGGED_MESSAGE: - if (handle_tagged_message(_fed.net_abstraction_to_RTI, -1)) { + if (handle_tagged_message(_fed.net_to_RTI, -1)) { // Failures to complete the read of messages from the RTI are fatal. lf_print_error_and_exit("Failed to complete the reading of a message from the RTI."); } @@ -1537,7 +1528,7 @@ static void* listen_to_rti_net_abstraction(void* args) { handle_stop_granted_message(); break; case MSG_TYPE_PORT_ABSENT: - if (handle_port_absent_message(_fed.net_abstraction_to_RTI, -1)) { + if (handle_port_absent_message(_fed.net_to_RTI, -1)) { // Failures to complete the read of absent messages from the RTI are fatal. lf_print_error_and_exit("Failed to complete the reading of an absent message from the RTI."); } @@ -1626,7 +1617,7 @@ void lf_terminate_execution(environment_t* env) { // For an abnormal termination (e.g. a SIGINT), we need to send a // MSG_TYPE_FAILED message to the RTI, but we should not acquire a mutex. - if (_fed.net_abstraction_to_RTI != NULL) { + if (_fed.net_to_RTI != NULL) { if (_lf_normal_termination) { tracepoint_federate_to_rti(send_RESIGN, _lf_my_fed_id, &env->current_tag); send_resign_signal(); @@ -1639,13 +1630,13 @@ void lf_terminate_execution(environment_t* env) { LF_PRINT_DEBUG("Closing incoming P2P network abstractions."); // Close any incoming P2P network abstractions that are still open. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { - shutdown_net_abstraction(_fed.net_abstractions_for_inbound_p2p_connections[i], false); + shutdown_net(_fed.net_for_inbound_p2p_connections[i], false); // Ignore errors. Mark the network abstraction closed. - _fed.net_abstractions_for_inbound_p2p_connections[i] = NULL; + _fed.net_for_inbound_p2p_connections[i] = NULL; } // Check for all outgoing physical connections in - // _fed.net_abstractions_for_outbound_p2p_connections and + // _fed.net_for_outbound_p2p_connections and // if the network abstraction ID is not NULL, the connection is still open. // Send an EOF by closing the network abstraction here. for (int i = 0; i < NUMBER_OF_FEDERATES; i++) { @@ -1653,28 +1644,28 @@ void lf_terminate_execution(environment_t* env) { // Close outbound connections, in case they have not closed themselves. // This will result in EOF being sent to the remote federate, except for // abnormal termination, in which case it will just close the network abstraction. - close_outbound_net_abstraction(i); + close_outbound_net(i); } LF_PRINT_DEBUG("Waiting for inbound p2p network abstraction listener threads."); // Wait for each inbound network abstraction listener thread to close. - if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_net_abstraction_listeners != NULL) { + if (_fed.number_of_inbound_p2p_connections > 0 && _fed.inbound_net_listeners != NULL) { LF_PRINT_LOG("Waiting for %zu threads listening for incoming messages to exit.", _fed.number_of_inbound_p2p_connections); for (size_t i = 0; i < _fed.number_of_inbound_p2p_connections; i++) { // Ignoring errors here. - lf_thread_join(_fed.inbound_net_abstraction_listeners[i], NULL); + lf_thread_join(_fed.inbound_net_listeners[i], NULL); } } LF_PRINT_DEBUG("Waiting for RTI's network abstraction listener threads."); // Wait for the thread listening for messages from the RTI to close. - lf_thread_join(_fed.RTI_net_abstraction_listener, NULL); + lf_thread_join(_fed.RTI_net_listener, NULL); // For abnormal termination, there is no need to free memory. if (_lf_normal_termination) { LF_PRINT_DEBUG("Freeing memory occupied by the federate."); - free(_fed.inbound_net_abstraction_listeners); + free(_fed.inbound_net_listeners); free(federation_metadata.rti_host); free(federation_metadata.rti_user); } @@ -1703,16 +1694,15 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_ADR_QR, _lf_my_fed_id, NULL); - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, sizeof(uint16_t) + 1, buffer, - &lf_outbound_net_abstraction_mutex, - "Failed to send address query for federate %d to RTI.", remote_federate_id); - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); + write_to_net_fail_on_error(_fed.net_to_RTI, sizeof(uint16_t) + 1, buffer, &lf_outbound_net_mutex, + "Failed to send address query for federate %d to RTI.", remote_federate_id); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); // Read RTI's response. - read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, sizeof(int32_t) + 1, buffer, - "Failed to read the requested port number for federate %d from RTI.", - remote_federate_id); + read_from_net_fail_on_error(_fed.net_to_RTI, sizeof(int32_t) + 1, buffer, + "Failed to read the requested port number for federate %d from RTI.", + remote_federate_id); if (buffer[0] != MSG_TYPE_ADDRESS_QUERY_REPLY) { // Unexpected reply. Could be that RTI has failed and sent a resignation. @@ -1724,9 +1714,8 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } port = extract_int32(&buffer[1]); - read_from_net_abstraction_fail_on_error( - _fed.net_abstraction_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, - "Failed to read the IP address for federate %d from RTI.", remote_federate_id); + read_from_net_fail_on_error(_fed.net_to_RTI, sizeof(host_ip_addr), (unsigned char*)&host_ip_addr, + "Failed to read the IP address for federate %d from RTI.", remote_federate_id); // A reply of -1 for the port means that the RTI does not know // the port number of the remote federate, presumably because the @@ -1748,13 +1737,13 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { inet_ntop(AF_INET, &host_ip_addr, hostname, INET_ADDRSTRLEN); // Create a network abstraction. - net_abstraction_t net_abstraction = initialize_net_abstraction(); + net_abstraction_t net = initialize_net(); // Set the received host name and port to the network abstraction. - set_server_port(net_abstraction, uport); - set_server_hostname(net_abstraction, hostname); + set_server_port(net, uport); + set_server_hostname(net, hostname); // Create the client network abstraction. - create_client(net_abstraction); - if (connect_to_net_abstraction(net_abstraction) < 0) { + create_client(net); + if (connect_to_net(net) < 0) { lf_print_error_and_exit("Failed to connect to federate."); } @@ -1791,20 +1780,19 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { tracepoint_federate_to_federate(send_FED_ID, _lf_my_fed_id, remote_federate_id, NULL); // No need for a mutex because we have the only handle on the network abstraction. - write_to_net_abstraction_fail_on_error(net_abstraction, buffer_length, buffer, NULL, - "Failed to send fed_id to federate %d.", remote_federate_id); - write_to_net_abstraction_fail_on_error(net_abstraction, federation_id_length, - (unsigned char*)federation_metadata.federation_id, NULL, - "Failed to send federation id to federate %d.", remote_federate_id); - - read_from_net_abstraction_fail_on_error( - net_abstraction, 1, (unsigned char*)buffer, - "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", remote_federate_id); + write_to_net_fail_on_error(net, buffer_length, buffer, NULL, "Failed to send fed_id to federate %d.", + remote_federate_id); + write_to_net_fail_on_error(net, federation_id_length, (unsigned char*)federation_metadata.federation_id, NULL, + "Failed to send federation id to federate %d.", remote_federate_id); + + read_from_net_fail_on_error(net, 1, (unsigned char*)buffer, + "Failed to read MSG_TYPE_ACK from federate %d in response to sending fed_id.", + remote_federate_id); if (buffer[0] != MSG_TYPE_ACK) { // Get the error code. - read_from_net_abstraction_fail_on_error( - net_abstraction, 1, (unsigned char*)buffer, - "Failed to read error code from federate %d in response to sending fed_id.", remote_federate_id); + read_from_net_fail_on_error(net, 1, (unsigned char*)buffer, + "Failed to read error code from federate %d in response to sending fed_id.", + remote_federate_id); lf_print_error("Received MSG_TYPE_REJECT message from remote federate (%d).", buffer[0]); result = -1; // Wait ADDRESS_QUERY_RETRY_INTERVAL nanoseconds. @@ -1821,7 +1809,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id) { } // Once we set this variable, then all future calls to close() on this // network abstraction should reset it to NULL within a critical section. - _fed.net_abstractions_for_outbound_p2p_connections[remote_federate_id] = net_abstraction; + _fed.net_for_outbound_p2p_connections[remote_federate_id] = net; } void lf_connect_to_rti(const char* hostname, int port) { @@ -1832,14 +1820,14 @@ void lf_connect_to_rti(const char* hostname, int port) { port = federation_metadata.rti_port >= 0 ? federation_metadata.rti_port : port; // Create a network abstraction. - _fed.net_abstraction_to_RTI = initialize_net_abstraction(); + _fed.net_to_RTI = initialize_net(); // Set the user specified host name and port to the network abstraction. - set_server_port(_fed.net_abstraction_to_RTI, port); - set_server_hostname(_fed.net_abstraction_to_RTI, hostname); + set_server_port(_fed.net_to_RTI, port); + set_server_hostname(_fed.net_to_RTI, hostname); // Create the client network abstraction. - create_client(_fed.net_abstraction_to_RTI); - if (connect_to_net_abstraction(_fed.net_abstraction_to_RTI) < 0) { + create_client(_fed.net_to_RTI); + if (connect_to_net(_fed.net_to_RTI) < 0) { lf_print_error_and_exit("Failed to connect to RTI."); } @@ -1881,13 +1869,12 @@ void lf_connect_to_rti(const char* hostname, int port) { tracepoint_federate_to_rti(send_FED_ID, _lf_my_fed_id, NULL); // No need for a mutex here because no other threads are writing to this network abstraction. - if (write_to_net_abstraction(_fed.net_abstraction_to_RTI, 2 + sizeof(uint16_t), buffer)) { + if (write_to_net(_fed.net_to_RTI, 2 + sizeof(uint16_t), buffer)) { continue; // Try again, possibly on a new port. } // Next send the federation ID itself. - if (write_to_net_abstraction(_fed.net_abstraction_to_RTI, federation_id_length, - (unsigned char*)federation_metadata.federation_id)) { + if (write_to_net(_fed.net_to_RTI, federation_id_length, (unsigned char*)federation_metadata.federation_id)) { continue; // Try again. } @@ -1899,7 +1886,7 @@ void lf_connect_to_rti(const char* hostname, int port) { LF_PRINT_DEBUG("Waiting for response to federation ID from the RTI."); - if (read_from_net_abstraction(_fed.net_abstraction_to_RTI, 1, &response)) { + if (read_from_net(_fed.net_to_RTI, 1, &response)) { continue; // Try again. } if (response == MSG_TYPE_REJECT) { @@ -1907,8 +1894,7 @@ void lf_connect_to_rti(const char* hostname, int port) { tracepoint_federate_from_rti(receive_REJECT, _lf_my_fed_id, NULL); // Read one more byte to determine the cause of rejection. unsigned char cause; - read_from_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, 1, &cause, - "Failed to read the cause of rejection by the RTI."); + read_from_net_fail_on_error(_fed.net_to_RTI, 1, &cause, "Failed to read the cause of rejection by the RTI."); if (cause == FEDERATION_ID_DOES_NOT_MATCH || cause == WRONG_SERVER) { lf_print_warning("Connected to the wrong RTI. Will try again"); continue; @@ -1931,7 +1917,7 @@ void lf_connect_to_rti(const char* hostname, int port) { // about connections between this federate and other federates // where messages are routed through the RTI. // @see MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h - lf_send_neighbor_structure_to_RTI(_fed.net_abstraction_to_RTI); + lf_send_neighbor_structure_to_RTI(_fed.net_to_RTI); uint16_t udp_port = setup_clock_synchronization_with_rti(); @@ -1939,22 +1925,22 @@ void lf_connect_to_rti(const char* hostname, int port) { unsigned char UDP_port_number[1 + sizeof(uint16_t)]; UDP_port_number[0] = MSG_TYPE_UDP_PORT; encode_uint16(udp_port, &(UDP_port_number[1])); - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, - "Failed to send the UDP port number to the RTI."); + write_to_net_fail_on_error(_fed.net_to_RTI, 1 + sizeof(uint16_t), UDP_port_number, NULL, + "Failed to send the UDP port number to the RTI."); } void lf_create_server(int specified_port) { assert(specified_port <= UINT16_MAX && specified_port >= 0); - net_abstraction_t* server_net_abstraction = initialize_net_abstraction(); - set_my_port(server_net_abstraction, specified_port); + net_abstraction_t* server_net = initialize_net(); + set_my_port(server_net, specified_port); - if (create_server(server_net_abstraction, false)) { + if (create_server(server_net, false)) { lf_print_error_system_failure("RTI failed to create server: %s.", strerror(errno)); }; - _fed.server_net_abstraction = server_net_abstraction; + _fed.server_net = server_net; // Get the final server port to send to the RTI on an MSG_TYPE_ADDRESS_ADVERTISEMENT message. - int32_t server_port = get_my_port(server_net_abstraction); + int32_t server_port = get_my_port(server_net); LF_PRINT_LOG("Server for communicating with other federates started using port %d.", server_port); @@ -1968,8 +1954,8 @@ void lf_create_server(int specified_port) { tracepoint_federate_to_rti(send_ADR_AD, _lf_my_fed_id, NULL); // No need for a mutex because we have the only handle on this network abstraction. - write_to_net_abstraction_fail_on_error(_fed.net_abstraction_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, - "Failed to send address advertisement."); + write_to_net_fail_on_error(_fed.net_to_RTI, sizeof(int32_t) + 1, (unsigned char*)buffer, NULL, + "Failed to send address advertisement."); LF_PRINT_DEBUG("Sent port %d to the RTI.", server_port); } @@ -2002,13 +1988,11 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { LF_ASSERT_NON_NULL(env_arg); size_t received_federates = 0; // Allocate memory to store thread IDs. - _fed.inbound_net_abstraction_listeners = - (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); + _fed.inbound_net_listeners = (lf_thread_t*)calloc(_fed.number_of_inbound_p2p_connections, sizeof(lf_thread_t)); while (received_federates < _fed.number_of_inbound_p2p_connections && !_lf_termination_executed) { // Wait for an incoming connection request. - net_abstraction_t net_abstraction = - accept_net_abstraction(_fed.server_net_abstraction, _fed.net_abstraction_to_RTI); - if (net_abstraction == NULL) { + net_abstraction_t net = accept_net(_fed.server_net, _fed.net_to_RTI); + if (net == NULL) { lf_print_warning("Federate failed to accept the network abstraction."); return NULL; } @@ -2016,7 +2000,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { size_t header_length = 1 + sizeof(uint16_t) + 1; unsigned char buffer[header_length]; - int read_failed = read_from_net_abstraction(net_abstraction, header_length, (unsigned char*)&buffer); + int read_failed = read_from_net(net, header_length, (unsigned char*)&buffer); if (read_failed || buffer[0] != MSG_TYPE_P2P_SENDING_FED_ID) { lf_print_warning( "Federate received invalid first message on P2P network abstraction. Closing network abstraction."); @@ -2028,17 +2012,16 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_net_abstraction(net_abstraction, 2, response); + write_to_net(net, 2, response); } - shutdown_net_abstraction(net_abstraction, false); + shutdown_net(net, false); continue; } // Get the federation ID and check it. unsigned char federation_id_length = buffer[header_length - 1]; char remote_federation_id[federation_id_length]; - read_failed = - read_from_net_abstraction(net_abstraction, federation_id_length, (unsigned char*)remote_federation_id); + read_failed = read_from_net(net, federation_id_length, (unsigned char*)remote_federation_id); if (read_failed || (strncmp(federation_metadata.federation_id, remote_federation_id, strnlen(federation_metadata.federation_id, 255)) != 0)) { lf_print_warning("Received invalid federation ID. Closing network abstraction."); @@ -2049,9 +2032,9 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_REJECT, _lf_my_fed_id, -3, NULL); // Ignore errors on this response. - write_to_net_abstraction(net_abstraction, 2, response); + write_to_net(net, 2, response); } - shutdown_net_abstraction(net_abstraction, false); + shutdown_net(net, false); continue; } @@ -2063,11 +2046,11 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { tracepoint_federate_to_federate(receive_FED_ID, _lf_my_fed_id, remote_fed_id, NULL); // Once we record the network abstraction here, all future calls to close() on - // the network abstraction should be done while holding the net_abstraction_mutex, and this array + // the network abstraction should be done while holding the net_mutex, and this array // element should be reset to NULL during that critical section. // Otherwise, there can be race condition where, during termination, // two threads attempt to simultaneously close the network abstraction. - _fed.net_abstractions_for_inbound_p2p_connections[remote_fed_id] = net_abstraction; + _fed.net_for_inbound_p2p_connections[remote_fed_id] = net; // Send an MSG_TYPE_ACK message. unsigned char response = MSG_TYPE_ACK; @@ -2075,23 +2058,22 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_ACK, _lf_my_fed_id, remote_fed_id, NULL); - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - write_to_net_abstraction_fail_on_error(_fed.net_abstractions_for_inbound_p2p_connections[remote_fed_id], 1, - (unsigned char*)&response, &lf_outbound_net_abstraction_mutex, - "Failed to write MSG_TYPE_ACK in response to federate %d.", remote_fed_id); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); + write_to_net_fail_on_error(_fed.net_for_inbound_p2p_connections[remote_fed_id], 1, (unsigned char*)&response, + &lf_outbound_net_mutex, "Failed to write MSG_TYPE_ACK in response to federate %d.", + remote_fed_id); // Start a thread to listen for incoming messages from other federates. // The fed_id is a uint16_t, which we assume can be safely cast to and from void*. void* fed_id_arg = (void*)(uintptr_t)remote_fed_id; - int result = - lf_thread_create(&_fed.inbound_net_abstraction_listeners[received_federates], listen_to_federates, fed_id_arg); + int result = lf_thread_create(&_fed.inbound_net_listeners[received_federates], listen_to_federates, fed_id_arg); if (result != 0) { // Failed to create a listening thread. - shutdown_net_abstraction(_fed.net_abstractions_for_inbound_p2p_connections[remote_fed_id], false); + shutdown_net(_fed.net_for_inbound_p2p_connections[remote_fed_id], false); lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", result); } - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); received_federates++; } @@ -2193,23 +2175,23 @@ int lf_send_message(int message_type, unsigned short port, unsigned short federa const int header_length = 1 + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); // Use a mutex lock to prevent multiple threads from simultaneously sending. - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); - net_abstraction_t net_abstraction = _fed.net_abstractions_for_outbound_p2p_connections[federate]; + net_abstraction_t net = _fed.net_for_outbound_p2p_connections[federate]; // Trace the event when tracing is enabled tracepoint_federate_to_federate(send_P2P_MSG, _lf_my_fed_id, federate, NULL); - int result = write_to_net_abstraction_close_on_error(net_abstraction, header_length, header_buffer); + int result = write_to_net_close_on_error(net, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_net_abstraction_close_on_error(net_abstraction, length, message); + result = write_to_net_close_on_error(net, length, message); } if (result != 0) { // Message did not send. Since this is used for physical connections, this is not critical. lf_print_warning("Failed to send message to %s. Dropping the message.", next_destination_str); } - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); return result; } @@ -2395,21 +2377,21 @@ void lf_send_port_absent_to_federate(environment_t* env, interval_t additional_d #ifdef FEDERATED_CENTRALIZED // Send the absent message through the RTI - net_abstraction_t net_abstraction = _fed.net_abstraction_to_RTI; + net_abstraction_t net = _fed.net_to_RTI; tracepoint_federate_to_rti(send_PORT_ABS, _lf_my_fed_id, ¤t_message_intended_tag); #else // Send the absent message directly to the federate - net_abstraction_t net_abstraction = _fed.net_abstractions_for_outbound_p2p_connections[fed_ID]; + net_abstraction_t net = _fed.net_for_outbound_p2p_connections[fed_ID]; tracepoint_federate_to_federate(send_PORT_ABS, _lf_my_fed_id, fed_ID, ¤t_message_intended_tag); #endif - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); - int result = write_to_net_abstraction_close_on_error(net_abstraction, message_length, buffer); - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); + int result = write_to_net_close_on_error(net, message_length, buffer); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); if (result != 0) { // Write failed. Response depends on whether coordination is centralized. - if (net_abstraction == _fed.net_abstraction_to_RTI) { + if (net == _fed.net_to_RTI) { // Centralized coordination. This is a critical error. lf_print_error_system_failure("Failed to send port absent message for port %hu to federate %hu.", port_ID, fed_ID); @@ -2428,30 +2410,29 @@ int lf_send_stop_request_to_rti(tag_t stop_tag) { stop_tag.microstep++; ENCODE_STOP_REQUEST(buffer, stop_tag.time, stop_tag.microstep); - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); // Do not send a stop request if a stop request has been previously received from the RTI. if (!_fed.received_stop_request_from_rti) { LF_PRINT_LOG("Sending to RTI a MSG_TYPE_STOP_REQUEST message with tag " PRINTF_TAG ".", stop_tag.time - start_time, stop_tag.microstep); - if (_fed.net_abstraction_to_RTI == NULL) { + if (_fed.net_to_RTI == NULL) { lf_print_warning("RTI is no longer connected. Dropping message."); - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); return -1; } // Trace the event when tracing is enabled tracepoint_federate_to_rti(send_STOP_REQ, _lf_my_fed_id, &stop_tag); - write_to_net_abstraction_fail_on_error( - _fed.net_abstraction_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_net_abstraction_mutex, - "Failed to send stop time " PRINTF_TIME " to the RTI.", stop_tag.time - start_time); + write_to_net_fail_on_error(_fed.net_to_RTI, MSG_TYPE_STOP_REQUEST_LENGTH, buffer, &lf_outbound_net_mutex, + "Failed to send stop time " PRINTF_TIME " to the RTI.", stop_tag.time - start_time); // Treat this sending as equivalent to having received a stop request from the RTI. _fed.received_stop_request_from_rti = true; - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); return 0; } else { - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); return 1; } } @@ -2504,14 +2485,14 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int current_message_intended_tag.microstep, next_destination_str); // Use a mutex lock to prevent multiple threads from simultaneously sending. - LF_MUTEX_LOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_LOCK(&lf_outbound_net_mutex); - net_abstraction_t net_abstraction; + net_abstraction_t net; if (message_type == MSG_TYPE_P2P_TAGGED_MESSAGE) { - net_abstraction = _fed.net_abstractions_for_outbound_p2p_connections[federate]; + net = _fed.net_for_outbound_p2p_connections[federate]; tracepoint_federate_to_federate(send_P2P_TAGGED_MSG, _lf_my_fed_id, federate, ¤t_message_intended_tag); } else { - net_abstraction = _fed.net_abstraction_to_RTI; + net = _fed.net_to_RTI; tracepoint_federate_to_rti(send_TAGGED_MSG, _lf_my_fed_id, ¤t_message_intended_tag); } @@ -2519,10 +2500,10 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int _fed.last_DNET = current_message_intended_tag; } - int result = write_to_net_abstraction_close_on_error(net_abstraction, header_length, header_buffer); + int result = write_to_net_close_on_error(net, header_length, header_buffer); if (result == 0) { // Header sent successfully. Send the body. - result = write_to_net_abstraction_close_on_error(net_abstraction, length, message); + result = write_to_net_close_on_error(net, length, message); } if (result != 0) { // Message did not send. Handling depends on message type. @@ -2533,7 +2514,7 @@ int lf_send_tagged_message(environment_t* env, interval_t additional_delay, int next_destination_str, errno, strerror(errno)); } } - LF_MUTEX_UNLOCK(&lf_outbound_net_abstraction_mutex); + LF_MUTEX_UNLOCK(&lf_outbound_net_mutex); return result; } @@ -2579,7 +2560,7 @@ void lf_synchronize_with_other_federates(void) { // @note Up until this point, the federate has been listening for messages // from the RTI in a sequential manner in the main thread. From now on, a // separate thread is created to allow for asynchronous communication. - lf_thread_create(&_fed.RTI_net_abstraction_listener, listen_to_rti_net_abstraction, NULL); + lf_thread_create(&_fed.RTI_net_listener, listen_to_rti_net, NULL); lf_thread_t thread_id; if (create_clock_sync_thread(&thread_id)) { lf_print_warning("Failed to create thread to handle clock synchronization."); diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index 098593b84..71826d166 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -240,9 +240,9 @@ uint16_t setup_clock_synchronization_with_rti(void); * Failing to complete this protocol is treated as a catastrophic * error that causes the federate to exit. * - * @param rti_net_abstraction Pointer to the RTI's network abstraction. + * @param rti_net Pointer to the RTI's network abstraction. */ -void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net_abstraction); +void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net); /** * @brief Handle a clock synchroninzation message T1 coming from the RTI. @@ -258,28 +258,28 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net_abstr * @param use_UDP Boolean to use UDP or the network abstraction. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net_abstraction, instant_t t2, bool use_udp); +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, bool use_udp); /** * @brief Handle a clock synchronization message T4 coming from the RTI. * @ingroup Federated * - * If the socket_or_net_abstraction is a network abstraction, then assume we are in the + * If the socket_or_net is a network abstraction, then assume we are in the * initial clock synchronization phase and set the clock offset * based on the estimated clock synchronization error. - * Otherwise, if the socket_or_net_abstraction is UDP socket, then this looks also for a + * Otherwise, if the socket_or_net is UDP socket, then this looks also for a * subsequent "coded probe" message on the socket. If the delay between * the T4 and the coded probe message is not as expected, then reject * this clock synchronization round. If it is not rejected, then make * an adjustment to the clock offset based on the estimated error. - * This function does not acquire the net_abstraction_mutex lock. + * This function does not acquire the net_mutex lock. * The caller should acquire it unless it is sure there is only one thread running. * @param buffer The buffer containing the message, including the message type. * @param net_abstraction_t The pointer to the network abstraction. * @param r4 The physical time at which this T4 message was received.\ * @param use_UDP Boolean to use UDP or the network abstraction. */ -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net_abstraction, instant_t r4, bool use_udp); +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, bool use_udp); /** * @brief Create the thread responsible for handling clock synchronization diff --git a/include/core/federated/federate.h b/include/core/federated/federate.h index 35c351cb4..e516e2a74 100644 --- a/include/core/federated/federate.h +++ b/include/core/federated/federate.h @@ -43,12 +43,12 @@ typedef struct federate_instance_t { * This is set by lf_connect_to_rti(), which must be called before other * functions that communicate with the rti are called. */ - net_abstraction_t net_abstraction_to_RTI; + net_abstraction_t net_to_RTI; /** * Thread listening for incoming messages from the RTI. */ - lf_thread_t RTI_net_abstraction_listener; + lf_thread_t RTI_net_listener; /** * Number of inbound physical connections to the federate. @@ -62,7 +62,7 @@ typedef struct federate_instance_t { * This is NULL if there are none and otherwise has size given by * number_of_inbound_p2p_connections. */ - lf_thread_t* inbound_net_abstraction_listeners; + lf_thread_t* inbound_net_listeners; /** * Number of outbound peer-to-peer connections from the federate. @@ -84,7 +84,7 @@ typedef struct federate_instance_t { * federate is the destination. Multiple incoming p2p connections from the * same remote federate will use the same network abstraction. */ - net_abstraction_t net_abstractions_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; + net_abstraction_t net_for_inbound_p2p_connections[NUMBER_OF_FEDERATES]; /** * An array that holds the network abstractions for outbound direct @@ -99,7 +99,7 @@ typedef struct federate_instance_t { * program where this federate acts as the source. Multiple outgoing p2p * connections to the same remote federate will use the same network abstractions. */ - net_abstraction_t net_abstractions_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; + net_abstraction_t net_for_outbound_p2p_connections[NUMBER_OF_FEDERATES]; /** * Thread ID for a thread that accepts network abstractions and then supervises @@ -113,9 +113,9 @@ typedef struct federate_instance_t { * This network abstraction is used to listen to incoming physical connections from * remote federates. Once an incoming connection is accepted, the * opened network abstraction will be stored in - * federate_net_abstractions_for_inbound_p2p_connections. + * federate_net_for_inbound_p2p_connections. */ - net_abstraction_t server_net_abstraction; + net_abstraction_t server_net; /** * Most recent tag advance grant (TAG) received from the RTI, or NEVER if none @@ -237,7 +237,7 @@ typedef enum parse_rti_code_t { SUCCESS, INVALID_PORT, INVALID_HOST, INVALID_USE * @brief Mutex lock held while performing outbound network abstraction write and close operations. * @ingroup Federated */ -extern lf_mutex_t lf_outbound_net_abstraction_mutex; +extern lf_mutex_t lf_outbound_net_mutex; /** * @brief Condition variable for blocking on unkonwn federate input ports. @@ -258,7 +258,7 @@ extern lf_cond_t lf_port_status_changed; * the IP address and port number of the specified federate. It then attempts * to establish a network abstraction connection to the specified federate. * If this fails, the program exits. If it succeeds, it sets element [id] of - * the _fed.net_abstractions_for_outbound_p2p_connections global array to + * the _fed.net_for_outbound_p2p_connections global array to * refer to the network abstraction for communicating directly with the federate. * * @param remote_federate_id The ID of the remote federate. @@ -273,7 +273,7 @@ void lf_connect_to_federate(uint16_t remote_federate_id); * If port_number is 0, then start at DEFAULT_PORT and increment * the port number on each attempt. If an attempt fails, wait CONNECT_RETRY_INTERVAL * and try again. If it fails after CONNECT_TIMEOUT, the program exits. - * If it succeeds, it sets the _fed.net_abstraction_to_RTI global variable to refer to + * If it succeeds, it sets the _fed.net_to_RTI global variable to refer to * the network abstraction for communicating with the RTI. * * @param hostname A hostname, such as "localhost". @@ -365,7 +365,7 @@ void lf_reset_status_fields_on_input_port_triggers(void); * between federates. If the connection to the remote federate or the RTI has been broken, * then this returns -1 without sending. Otherwise, it returns 0. * - * This method assumes that the caller does not hold the lf_outbound_net_abstraction_mutex lock, + * This method assumes that the caller does not hold the lf_outbound_net_mutex lock, * which it acquires to perform the send. * * @param message_type The type of the message being sent (currently only MSG_TYPE_P2P_MESSAGE). @@ -494,7 +494,7 @@ int lf_send_stop_request_to_rti(tag_t stop_tag); * to believe that there were no messages forthcoming. In this case, on failure to send * the message, this function returns -11. * - * This method assumes that the caller does not hold the lf_outbound_net_abstraction_mutex lock, + * This method assumes that the caller does not hold the lf_outbound_net_mutex lock, * which it acquires to perform the send. * * @param env The environment from which to get the current tag. @@ -557,7 +557,7 @@ void lf_stall_advance_level_federation_locked(size_t level); * @ingroup Federated * * This assumes that a connection to the RTI is already made - * and net_abstraction_to_RTI is valid. It then sends the current logical + * and net_to_RTI is valid. It then sends the current logical * time to the RTI and waits for the RTI to respond with a specified * time. It starts a thread to listen for messages from the RTI. */ diff --git a/network/api/net_abstraction.h b/network/api/net_abstraction.h index 834cc8497..505d412d0 100644 --- a/network/api/net_abstraction.h +++ b/network/api/net_abstraction.h @@ -26,7 +26,7 @@ typedef void* net_abstraction_t; * Allocate memory for the network abstraction. * @return net_abstraction_t Initialized network abstraction. */ -net_abstraction_t initialize_net_abstraction(); +net_abstraction_t initialize_net(); /** * @brief Create a server network abstraction that will accept incoming connections. @@ -56,7 +56,7 @@ int create_server(net_abstraction_t net_abs, bool increment_port_on_retry); * @param rti_chan The rti's network abstraction to check if it is still open. * @return net_abstraction_t The network abstraction for the newly accepted connection on success, or NULL on failure */ -net_abstraction_t accept_net_abstraction(net_abstraction_t server_chan, net_abstraction_t rti_chan); +net_abstraction_t accept_net(net_abstraction_t server_chan, net_abstraction_t rti_chan); /** * @brief Initialize a client network abstraction for connecting to a server. @@ -78,7 +78,7 @@ void create_client(net_abstraction_t net_abs); * @param net_abs network abstraction to connect. * @return 0 for success, -1 on failure, and `errno` is set to indicate the specific error. */ -int connect_to_net_abstraction(net_abstraction_t net_abs); +int connect_to_net(net_abstraction_t net_abs); /** * @brief Read a fixed number of bytes from a network abstraction. @@ -94,20 +94,20 @@ int connect_to_net_abstraction(net_abstraction_t net_abs); * @param buffer The buffer into which to put the bytes. * @return 0 for success, 1 for EOF, and -1 for an error. */ -int read_from_net_abstraction(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); +int read_from_net(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); /** * @brief Read bytes and close the network abstraction on error. * @ingroup Network * - * Uses read_from_net_abstraction and closes the channel if an error occurs. + * Uses read_from_net and closes the channel if an error occurs. * * @param net_abs The network abstraction. * @param num_bytes The number of bytes to read. * @param buffer The buffer into which to get the bytes. * @return 0 for success, -1 for failure. */ -int read_from_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); +int read_from_net_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); /** * @brief Read bytes from a network abstraction and fail (exit) on error. @@ -126,14 +126,13 @@ int read_from_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t n * @param format A printf-style format string, followed by arguments to * fill the string, or NULL to not exit with an error message. */ -void read_from_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, - char* format, ...); +void read_from_net_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, char* format, ...); /** * @brief Write a fixed number of bytes to a network abstraction. * @ingroup Network * - * Write the specified number of bytes to the specified network abstraction using write_to_net_abstraction + * Write the specified number of bytes to the specified network abstraction using write_to_net * and close the network abstraction if an error occurs. * If an error occurs, return -1 and set errno to indicate the cause. If the write succeeds, return 0. * This function retries until the specified number of bytes have been written or an error occurs. @@ -143,27 +142,27 @@ void read_from_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t n * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. */ -int write_to_net_abstraction(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); +int write_to_net(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); /** * @brief Write bytes to a network abstraction and close on error. * @ingroup Network * - * Uses write_to_net_abstraction and closes the channel if an error occurs. + * Uses write_to_net and closes the channel if an error occurs. * * @param net_abs The network abstraction. * @param num_bytes The number of bytes to write. * @param buffer The buffer from which to get the bytes. * @return 0 for success, -1 for failure. */ -int write_to_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); +int write_to_net_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer); /** * @brief Write bytes to a network abstraction and fail (exit) on error. * @ingroup Network * * Write the specified number of bytes to the specified network abstraction using - * write_to_net_abstraction_close_on_error and exit with an error code if an error occurs. + * write_to_net_close_on_error and exit with an error code if an error occurs. * If the mutex argument is non-NULL, release the mutex before exiting. If the * format argument is non-null, then use it an any additional arguments to form * the error message using printf conventions. Otherwise, print a generic error @@ -176,8 +175,8 @@ int write_to_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t nu * fields that will be used to fill the format string as in printf, or NULL * to print a generic error message. */ -void write_to_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, - lf_mutex_t* mutex, char* format, ...); +void write_to_net_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, + char* format, ...); /** * @brief Check whether the network abstraction is closed. @@ -188,7 +187,7 @@ void write_to_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t nu * @param net_abs The network abstraction. * @return true if closed, false if still open. */ -bool check_net_abstraction_closed(net_abstraction_t net_abs); +bool check_net_closed(net_abstraction_t net_abs); /** * @brief Gracefully shut down and close a network abstraction. @@ -202,7 +201,7 @@ bool check_net_abstraction_closed(net_abstraction_t net_abs); * @param read_before_closing If true, read until EOF before closing the network abstraction. * @return int Returns 0 on success, -1 on failure (errno will indicate the error). */ -int shutdown_net_abstraction(net_abstraction_t net_abs, bool read_before_closing); +int shutdown_net(net_abstraction_t net_abs, bool read_before_closing); /** * @brief Get the server port number of this network abstraction. diff --git a/network/impl/src/lf_socket_support.c b/network/impl/src/lf_socket_support.c index 2ad52b0ef..5e993786c 100644 --- a/network/impl/src/lf_socket_support.c +++ b/network/impl/src/lf_socket_support.c @@ -24,7 +24,7 @@ static socket_priv_t* get_socket_priv_t(net_abstraction_t net_abs) { return (socket_priv_t*)net_abs; } -net_abstraction_t initialize_net_abstraction() { +net_abstraction_t initialize_net() { // Initialize priv. socket_priv_t* priv = malloc(sizeof(socket_priv_t)); if (priv == NULL) { @@ -44,7 +44,7 @@ net_abstraction_t initialize_net_abstraction() { return (net_abstraction_t)priv; } -void free_net_abstraction(net_abstraction_t net_abs) { +void free_net(net_abstraction_t net_abs) { socket_priv_t* priv = get_socket_priv_t(net_abs); free(priv); } @@ -55,23 +55,23 @@ int create_server(net_abstraction_t net_abs, bool increment_port_on_retry) { increment_port_on_retry); } -net_abstraction_t accept_net_abstraction(net_abstraction_t server_chan, net_abstraction_t rti_chan) { +net_abstraction_t accept_net(net_abstraction_t server_chan, net_abstraction_t rti_chan) { socket_priv_t* serv_priv = get_socket_priv_t(server_chan); int rti_socket; if (rti_chan == NULL) { - // Set to -1, to indicate that this accept_net_abstraction() call is not trying to check if the rti_chan is + // Set to -1, to indicate that this accept_net() call is not trying to check if the rti_chan is // available, inside the accept_socket() function. rti_socket = -1; } else { socket_priv_t* rti_priv = get_socket_priv_t(rti_chan); rti_socket = rti_priv->socket_descriptor; } - net_abstraction_t fed_net_abstraction = initialize_net_abstraction(); - socket_priv_t* fed_priv = get_socket_priv_t(fed_net_abstraction); + net_abstraction_t fed_net = initialize_net(); + socket_priv_t* fed_priv = get_socket_priv_t(fed_net); int sock = accept_socket(serv_priv->socket_descriptor, rti_socket); if (sock == -1) { - free_net_abstraction(fed_net_abstraction); + free_net(fed_net); return NULL; } fed_priv->socket_descriptor = sock; @@ -79,7 +79,7 @@ net_abstraction_t accept_net_abstraction(net_abstraction_t server_chan, net_abst if (get_peer_address(fed_priv) != 0) { lf_print_error("RTI failed to get peer address."); }; - return fed_net_abstraction; + return fed_net; } void create_client(net_abstraction_t net_abs) { @@ -87,19 +87,19 @@ void create_client(net_abstraction_t net_abs) { priv->socket_descriptor = create_real_time_tcp_socket_errexit(); } -int connect_to_net_abstraction(net_abstraction_t net_abs) { +int connect_to_net(net_abstraction_t net_abs) { socket_priv_t* priv = get_socket_priv_t(net_abs); return connect_to_socket(priv->socket_descriptor, priv->server_hostname, priv->server_port); } -int read_from_net_abstraction(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { +int read_from_net(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = get_socket_priv_t(net_abs); return read_from_socket(priv->socket_descriptor, num_bytes, buffer); } -int read_from_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { +int read_from_net_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = get_socket_priv_t(net_abs); - int read_failed = read_from_net_abstraction(net_abs, num_bytes, buffer); + int read_failed = read_from_net(net_abs, num_bytes, buffer); if (read_failed) { // Read failed. // Socket has probably been closed from the other side. @@ -110,10 +110,10 @@ int read_from_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t n return 0; } -void read_from_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, - char* format, ...) { +void read_from_net_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, char* format, + ...) { va_list args; - int read_failed = read_from_net_abstraction_close_on_error(net_abs, num_bytes, buffer); + int read_failed = read_from_net_close_on_error(net_abs, num_bytes, buffer); if (read_failed) { // Read failed. if (format != NULL) { @@ -126,14 +126,14 @@ void read_from_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t n } } -int write_to_net_abstraction(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { +int write_to_net(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = get_socket_priv_t(net_abs); return write_to_socket(priv->socket_descriptor, num_bytes, buffer); } -int write_to_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { +int write_to_net_close_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer) { socket_priv_t* priv = get_socket_priv_t(net_abs); - int result = write_to_net_abstraction(net_abs, num_bytes, buffer); + int result = write_to_net(net_abs, num_bytes, buffer); if (result) { // Write failed. // Socket has probably been closed from the other side. @@ -143,10 +143,10 @@ int write_to_net_abstraction_close_on_error(net_abstraction_t net_abs, size_t nu return result; } -void write_to_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, - lf_mutex_t* mutex, char* format, ...) { +void write_to_net_fail_on_error(net_abstraction_t net_abs, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, + char* format, ...) { va_list args; - int result = write_to_net_abstraction_close_on_error(net_abs, num_bytes, buffer); + int result = write_to_net_close_on_error(net_abs, num_bytes, buffer); if (result) { // Write failed. if (mutex != NULL) { @@ -162,19 +162,19 @@ void write_to_net_abstraction_fail_on_error(net_abstraction_t net_abs, size_t nu } } -bool check_net_abstraction_closed(net_abstraction_t net_abs) { +bool check_net_closed(net_abstraction_t net_abs) { socket_priv_t* priv = get_socket_priv_t(net_abs); return check_socket_closed(priv->socket_descriptor); } -int shutdown_net_abstraction(net_abstraction_t net_abs, bool read_before_closing) { +int shutdown_net(net_abstraction_t net_abs, bool read_before_closing) { if (net_abs == NULL) { LF_PRINT_LOG("Socket already closed."); return 0; } socket_priv_t* priv = get_socket_priv_t(net_abs); int ret = shutdown_socket(&priv->socket_descriptor, read_before_closing); - free_net_abstraction(net_abs); + free_net(net_abs); return ret; } From ce1f07b071e94dfe97bb351c9f53a76332510218 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 1 Dec 2025 09:29:13 -0700 Subject: [PATCH 158/167] Minor include fix. --- network/impl/src/socket_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 1e6a0a187..1c14ec0da 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -21,7 +21,8 @@ #include //va_list #include // strerror -#include "util.h" // LF_MUTEX_UNLOCK(), logging.h +#include "util.h" // LF_MUTEX_UNLOCK() +#include "logging.h" #include "net_abstraction.h" /** Number of nanoseconds to sleep before retrying a socket read. */ From 7b42d7e4ed9168ce69295585eb324d08c6c92a1b Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 1 Dec 2025 09:36:39 -0700 Subject: [PATCH 159/167] Fix to use_UDP --- core/federated/clock-sync.c | 10 +++++----- include/core/federated/clock-sync.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index ee4abe5a5..d42446393 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -213,7 +213,7 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net) { LF_PRINT_LOG("Finished initial clock synchronization with the RTI."); } -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, bool use_udp) { +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, bool use_UDP) { // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); @@ -233,7 +233,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, ins // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); - int result = use_udp ? write_to_socket(*(int*)socket_or_net, 1 + sizeof(uint16_t), reply_buffer) + int result = use_UDP ? write_to_socket(*(int*)socket_or_net, 1 + sizeof(uint16_t), reply_buffer) : write_to_net((net_abstraction_t)socket_or_net, 1 + sizeof(uint16_t), reply_buffer); if (result) { @@ -248,7 +248,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, ins return 0; } -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, bool use_udp) { +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, bool use_UDP) { // Increment the number of received T4 messages _lf_rti_socket_stat.received_T4_messages_in_current_sync_window++; @@ -280,7 +280,7 @@ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, in // If the socket is _lf_rti_socket_UDP, then // after sending T4, the RTI sends a "coded probe" message, // which can be used to filter out noise. - if (use_udp) { + if (use_UDP) { // Read the coded probe message. // We can reuse the same buffer. int read_failed = read_from_socket(*(int*)socket_or_net, 1 + sizeof(instant_t), buffer); @@ -322,7 +322,7 @@ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, in // Use of TCP socket means we are in the startup phase, so // rather than adjust the clock offset, we simply set it to the // estimated error. - adjustment = use_udp ? estimated_clock_error / _LF_CLOCK_SYNC_ATTENUATION : estimated_clock_error; + adjustment = use_UDP ? estimated_clock_error / _LF_CLOCK_SYNC_ATTENUATION : estimated_clock_error; #ifdef _LF_CLOCK_SYNC_COLLECT_STATS // Enabled by default // Update RTI's socket stats diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index 71826d166..5816e7294 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -258,7 +258,7 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net); * @param use_UDP Boolean to use UDP or the network abstraction. * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, bool use_udp); +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, bool use_UDP); /** * @brief Handle a clock synchronization message T4 coming from the RTI. @@ -279,7 +279,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, ins * @param r4 The physical time at which this T4 message was received.\ * @param use_UDP Boolean to use UDP or the network abstraction. */ -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, bool use_udp); +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, bool use_UDP); /** * @brief Create the thread responsible for handling clock synchronization From 9ca3b17291b7a517107a4985cfee350d5a222c2a Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 1 Dec 2025 16:45:49 -0700 Subject: [PATCH 160/167] Revert to socket type. --- core/federated/RTI/rti_remote.c | 22 +++++++++++----------- core/federated/RTI/rti_remote.h | 8 ++++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 1fee3b657..fe959cd5a 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -751,7 +751,7 @@ void handle_timestamp(federate_info_t* my_fed) { LF_MUTEX_UNLOCK(&rti_mutex); } -void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP) { +void send_physical_clock(unsigned char message_type, federate_info_t* fed, socket_type_t socket_type) { if (fed->enclave.state == NOT_CONNECTED) { lf_print_warning( "Clock sync: RTI failed to send physical time to federate %d. network abstraction not connected.\n", @@ -763,7 +763,7 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool int64_t current_physical_time = lf_time_physical(); encode_int64(current_physical_time, &(buffer[1])); - if (use_UDP) { + if (socket_type == UDP) { // Send using UDP LF_PRINT_DEBUG("Clock sync: RTI sending UDP message type %u.", buffer[0]); ssize_t bytes_written = sendto(rti_remote->socket_descriptor_UDP, buffer, 1 + sizeof(int64_t), 0, @@ -785,18 +785,18 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool current_physical_time, fed->enclave.id); } -void handle_physical_clock_sync_message(federate_info_t* my_fed, bool use_UDP) { +void handle_physical_clock_sync_message(federate_info_t* my_fed, socket_type_t socket_type) { // Lock the mutex to prevent interference between sending the two // coded probe messages. LF_MUTEX_LOCK(&rti_mutex); - if (!use_UDP) { + if (socket_type == TCP) { // Reply with a T4 type message - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed, false); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed, TCP); // Send the corresponding coded probe immediately after, // but only if this is a UDP channel. } else { - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed, true); - send_physical_clock(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed, true); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T4, my_fed, UDP); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_CODED_PROBE, my_fed, UDP); } LF_MUTEX_UNLOCK(&rti_mutex); } @@ -838,7 +838,7 @@ void* clock_synchronization_thread(void* noargs) { // Send the RTI's current physical time to the federate // Send on UDP. LF_PRINT_DEBUG("RTI sending T1 message to initiate clock sync round."); - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, true); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, TCP); // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); @@ -863,7 +863,7 @@ void* clock_synchronization_thread(void* noargs) { continue; } LF_PRINT_DEBUG("Clock sync: RTI received T3 message from federate %d.", fed_id_2); - handle_physical_clock_sync_message(GET_FED_INFO(fed_id_2), true); + handle_physical_clock_sync_message(GET_FED_INFO(fed_id_2), UDP); break; } else { // The message is not a T3 message. Discard the message and @@ -1292,7 +1292,7 @@ static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net, // Send the required number of messages for clock synchronization for (int i = 0; i < rti_remote->clock_sync_exchanges_per_interval; i++) { // Send the RTI's current physical time T1 to the federate. - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, false); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, UDP); // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); @@ -1302,7 +1302,7 @@ static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net, if (buffer[0] == MSG_TYPE_CLOCK_SYNC_T3) { uint16_t fed_id = extract_uint16(&(buffer[1])); LF_PRINT_DEBUG("RTI received T3 clock sync message from federate %d.", fed_id); - handle_physical_clock_sync_message(fed, false); + handle_physical_clock_sync_message(fed, TCP); } else { lf_print_error("Unexpected message %u from federate %d.", buffer[0], fed_id); send_reject(fed_net, UNEXPECTED_MESSAGE); diff --git a/core/federated/RTI/rti_remote.h b/core/federated/RTI/rti_remote.h index 0ea32c826..58ac3b60a 100644 --- a/core/federated/RTI/rti_remote.h +++ b/core/federated/RTI/rti_remote.h @@ -297,9 +297,9 @@ void handle_timestamp(federate_info_t* my_fed); * * @param message_type The type of the clock sync message (see @ref net_common.h). * @param fed The federate to send the physical time to. - * @param use_UDP Boolean to use UDP or the network abstraction. + * @param socket_type The socket type (TCP or UDP). */ -void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool use_UDP); +void send_physical_clock(unsigned char message_type, federate_info_t* fed, socket_type_t socket_type); /** * @brief Handle clock synchronization T3 messages from federates. @@ -314,9 +314,9 @@ void send_physical_clock(unsigned char message_type, federate_info_t* fed, bool * clock synchronization round. * * @param my_fed The sending federate. - * @param use_UDP Boolean to send a coded probe message (for UDP only). + * @param socket_type The RTI's socket type used for the communication (TCP or UDP) */ -void handle_physical_clock_sync_message(federate_info_t* my_fed, bool use_UDP); +void handle_physical_clock_sync_message(federate_info_t* my_fed, socket_type_t socket_type); /** * @brief A (quasi-)periodic thread that performs clock synchronization with each federate. From d98b3af95e95d52b853ccfbba02f55a64c06a984 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 1 Dec 2025 16:55:07 -0700 Subject: [PATCH 161/167] Fix to use_UDP --- core/federated/clock-sync.c | 11 ++++++----- include/core/federated/clock-sync.h | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index d42446393..1f10771dc 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -213,7 +213,8 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net) { LF_PRINT_LOG("Finished initial clock synchronization with the RTI."); } -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, bool use_UDP) { +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, socket_type_t socket_type) { + if // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); @@ -233,7 +234,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, ins // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); - int result = use_UDP ? write_to_socket(*(int*)socket_or_net, 1 + sizeof(uint16_t), reply_buffer) + int result = (socket_type == UDP) ? write_to_socket(*(int*)socket_or_net, 1 + sizeof(uint16_t), reply_buffer) : write_to_net((net_abstraction_t)socket_or_net, 1 + sizeof(uint16_t), reply_buffer); if (result) { @@ -248,7 +249,7 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, ins return 0; } -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, bool use_UDP) { +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, socket_type_t socket_type) { // Increment the number of received T4 messages _lf_rti_socket_stat.received_T4_messages_in_current_sync_window++; @@ -280,7 +281,7 @@ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, in // If the socket is _lf_rti_socket_UDP, then // after sending T4, the RTI sends a "coded probe" message, // which can be used to filter out noise. - if (use_UDP) { + if (socket_type == UDP) { // Read the coded probe message. // We can reuse the same buffer. int read_failed = read_from_socket(*(int*)socket_or_net, 1 + sizeof(instant_t), buffer); @@ -322,7 +323,7 @@ void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, in // Use of TCP socket means we are in the startup phase, so // rather than adjust the clock offset, we simply set it to the // estimated error. - adjustment = use_UDP ? estimated_clock_error / _LF_CLOCK_SYNC_ATTENUATION : estimated_clock_error; + adjustment = (socket_type == UDP) ? estimated_clock_error / _LF_CLOCK_SYNC_ATTENUATION : estimated_clock_error; #ifdef _LF_CLOCK_SYNC_COLLECT_STATS // Enabled by default // Update RTI's socket stats diff --git a/include/core/federated/clock-sync.h b/include/core/federated/clock-sync.h index 5816e7294..cd5d90068 100644 --- a/include/core/federated/clock-sync.h +++ b/include/core/federated/clock-sync.h @@ -255,10 +255,10 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net); * @param buffer The buffer containing the message, including the message type. * @param net_abstraction_t The pointer to the network abstraction. * @param t2 The physical time at which the T1 message was received. - * @param use_UDP Boolean to use UDP or the network abstraction. + * @param socket_type The socket type (TCP or UDP). * @return 0 if T3 reply is successfully sent, -1 otherwise. */ -int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, bool use_UDP); +int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, socket_type_t socket_type); /** * @brief Handle a clock synchronization message T4 coming from the RTI. @@ -277,9 +277,9 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, ins * @param buffer The buffer containing the message, including the message type. * @param net_abstraction_t The pointer to the network abstraction. * @param r4 The physical time at which this T4 message was received.\ - * @param use_UDP Boolean to use UDP or the network abstraction. + * @param socket_type The socket type (TCP or UDP). */ -void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, bool use_UDP); +void handle_T4_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t r4, socket_type_t socket_type); /** * @brief Create the thread responsible for handling clock synchronization From 26c33d9ce78918171df6479fce548cf520529bcd Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Mon, 1 Dec 2025 17:08:29 -0700 Subject: [PATCH 162/167] Minor fix. --- core/federated/clock-sync.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index 1f10771dc..2ef3d5f29 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -214,7 +214,6 @@ void synchronize_initial_physical_clock_with_rti(net_abstraction_t rti_net) { } int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, instant_t t2, socket_type_t socket_type) { - if // Extract the payload instant_t t1 = extract_int64(&(buffer[1])); From 9296292240cb21d09f7ef9cccbd3efa4c456f8d1 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 2 Dec 2025 11:06:21 -0700 Subject: [PATCH 163/167] Minor fix. --- core/federated/RTI/rti_remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index fe959cd5a..2e88d894d 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -1292,7 +1292,7 @@ static int receive_udp_message_and_set_up_clock_sync(net_abstraction_t fed_net, // Send the required number of messages for clock synchronization for (int i = 0; i < rti_remote->clock_sync_exchanges_per_interval; i++) { // Send the RTI's current physical time T1 to the federate. - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, UDP); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, TCP); // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); From fa86bb59da5ba13ccc0f0264db3800c89e8d8db6 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 2 Dec 2025 13:22:47 -0700 Subject: [PATCH 164/167] Fix on type. --- core/federated/RTI/rti_remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/federated/RTI/rti_remote.c b/core/federated/RTI/rti_remote.c index 2e88d894d..d337166c1 100644 --- a/core/federated/RTI/rti_remote.c +++ b/core/federated/RTI/rti_remote.c @@ -838,7 +838,7 @@ void* clock_synchronization_thread(void* noargs) { // Send the RTI's current physical time to the federate // Send on UDP. LF_PRINT_DEBUG("RTI sending T1 message to initiate clock sync round."); - send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, TCP); + send_physical_clock(MSG_TYPE_CLOCK_SYNC_T1, fed, UDP); // Listen for reply message, which should be T3. size_t message_size = 1 + sizeof(uint16_t); From cb563df405c4701eed573f37595eaffbef4340e3 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 5 Dec 2025 10:07:26 -0700 Subject: [PATCH 165/167] Minor comment fix. --- core/federated/federate.c | 2 +- network/impl/src/socket_common.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/federated/federate.c b/core/federated/federate.c index b1bf08915..6f88ecea4 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -622,7 +622,7 @@ static int handle_tagged_message(net_abstraction_t net, int fed_id) { if (lf_tag_compare(env->current_tag, env->stop_tag) >= 0 && env->execution_started) { lf_print_error("Received message too late. Already at stop tag.\n" " Current tag is " PRINTF_TAG " and intended tag is " PRINTF_TAG ".\n" - " Discarding message and closing the network abstraction.", + " Discarding message and closing the network connection.", env->current_tag.time - start_time, env->current_tag.microstep, intended_tag.time - start_time, intended_tag.microstep); // Free the allocated memory before returning diff --git a/network/impl/src/socket_common.c b/network/impl/src/socket_common.c index 1c14ec0da..b8db3f06c 100644 --- a/network/impl/src/socket_common.c +++ b/network/impl/src/socket_common.c @@ -136,7 +136,7 @@ static int set_socket_bind_option(int socket_descriptor, uint16_t specified_port if (result != 0) { lf_print_error_and_exit("Failed to bind the socket. Port %d is not available. ", used_port); } - lf_print_debug("Socket is binded to port %d.", used_port); + lf_print_debug("Socket is bound to port %d.", used_port); return used_port; } From 6ee5e6a6c948cb73e0d953d7d2aadff5735b87f1 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Fri, 5 Dec 2025 13:15:27 -0700 Subject: [PATCH 166/167] Set net_for_inbound_p2p_connections pointer to null after shutdown. --- core/federated/federate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/federated/federate.c b/core/federated/federate.c index 6f88ecea4..6dabbc9b6 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -2070,6 +2070,7 @@ void* lf_handle_p2p_connections_from_federates(void* env_arg) { if (result != 0) { // Failed to create a listening thread. shutdown_net(_fed.net_for_inbound_p2p_connections[remote_fed_id], false); + _fed.net_for_inbound_p2p_connections[remote_fed_id] = NULL; lf_print_error_and_exit("Failed to create a thread to listen for incoming physical connection. Error code: %d.", result); } From b2d9356d01db4d5023db8046293296bb19d662a0 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 16 Dec 2025 09:27:26 -0700 Subject: [PATCH 167/167] Formatting --- core/federated/clock-sync.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/federated/clock-sync.c b/core/federated/clock-sync.c index 2ef3d5f29..b67a9580a 100644 --- a/core/federated/clock-sync.c +++ b/core/federated/clock-sync.c @@ -233,8 +233,9 @@ int handle_T1_clock_sync_message(unsigned char* buffer, void* socket_or_net, ins // Write the reply to the socket. LF_PRINT_DEBUG("Sending T3 message to RTI."); - int result = (socket_type == UDP) ? write_to_socket(*(int*)socket_or_net, 1 + sizeof(uint16_t), reply_buffer) - : write_to_net((net_abstraction_t)socket_or_net, 1 + sizeof(uint16_t), reply_buffer); + int result = (socket_type == UDP) + ? write_to_socket(*(int*)socket_or_net, 1 + sizeof(uint16_t), reply_buffer) + : write_to_net((net_abstraction_t)socket_or_net, 1 + sizeof(uint16_t), reply_buffer); if (result) { lf_print_error("Clock sync: Failed to send T3 message to RTI.");