@@ -116,22 +116,9 @@ federation_metadata_t federation_metadata = {
116
116
};
117
117
118
118
void create_server (int specified_port , int id ) {
119
- if (specified_port > UINT16_MAX ||
120
- specified_port < 0 ) {
121
- lf_print_error (
122
- "create_server(): The specified port (%d) is out of range."
123
- " Starting with %d instead." ,
124
- specified_port ,
125
- DEFAULT_PORT
126
- );
127
- specified_port = 0 ;
128
- }
119
+ assert (specified_port <= UINT16_MAX && specified_port >= 0 );
129
120
uint16_t port = (uint16_t )specified_port ;
130
- if (specified_port == 0 ) {
131
- // Use the default starting port + 1 + id (to try to get unique ports for each federate)
132
- port = DEFAULT_PORT + 1 + id ;
133
- }
134
- lf_print ("Creating a socket server on port %d." , port );
121
+ LF_PRINT_LOG ("Creating a socket server on port %d." , port );
135
122
// Create an IPv4 socket for TCP (not UDP) communication over IP (0).
136
123
int socket_descriptor = create_real_time_tcp_socket_errexit ();
137
124
@@ -149,40 +136,37 @@ void create_server(int specified_port, int id) {
149
136
socket_descriptor ,
150
137
(struct sockaddr * ) & server_fd ,
151
138
sizeof (server_fd ));
152
- // If the binding fails with this port and no particular port was specified
153
- // in the LF program, then try the next few ports in sequence.
154
139
int count = 0 ;
155
- while (result != 0 && count ++ < PORT_BIND_RETRY_LIMIT ) {
156
- if (specified_port != 0 ) {
157
- port ++ ;
158
- server_fd .sin_port = htons (port );
159
- LF_PRINT_DEBUG ("Failed to get port. Trying %d." , port );
160
- } else {
161
- LF_PRINT_DEBUG ("Failed to get port %d. Will try again after waiting." , port );
162
- lf_sleep (PORT_BIND_RETRY_INTERVAL );
163
- }
164
- server_fd .sin_port = htons (port );
140
+ while (result < 0 && count ++ < PORT_BIND_RETRY_LIMIT ) {
141
+ lf_sleep (PORT_BIND_RETRY_INTERVAL );
165
142
result = bind (
166
143
socket_descriptor ,
167
144
(struct sockaddr * ) & server_fd ,
168
145
sizeof (server_fd ));
169
146
}
170
147
if (result < 0 ) {
171
- if (specified_port == 0 ) {
172
- lf_print_error_and_exit ("Failed to bind socket. Cannot find a usable port." );
173
- } else {
174
- lf_print_error_and_exit ("Failed to bind socket. Specified port is not available." );
148
+ lf_print_error_and_exit ("Failed to bind socket on port %d." , port );
149
+ }
150
+
151
+ // Set the global server port.
152
+ if (specified_port == 0 ) {
153
+ // Need to retrieve the port number assigned by the OS.
154
+ struct sockaddr_in assigned ;
155
+ socklen_t addr_len = sizeof (assigned );
156
+ if (getsockname (socket_descriptor , (struct sockaddr * ) & assigned , & addr_len ) < 0 ) {
157
+ lf_print_error_and_exit ("Failed to retrieve assigned port number." );
175
158
}
159
+ _fed .server_port = ntohs (assigned .sin_port );
160
+ } else {
161
+ _fed .server_port = port ;
176
162
}
177
- LF_PRINT_LOG ("Server for communicating with other federates started using port %d." , port );
178
163
179
164
// Enable listening for socket connections.
180
165
// The second argument is the maximum number of queued socket requests,
181
166
// which according to the Mac man page is limited to 128.
182
167
listen (socket_descriptor , 128 );
183
168
184
- // Set the global server port
185
- _fed .server_port = port ;
169
+ lf_print ("Server for communicating with other federates started using port %d." , _fed .server_port );
186
170
187
171
// Send the server port number to the RTI
188
172
// on an MSG_TYPE_ADDRESS_ADVERTISEMENT message (@see net_common.h).
@@ -2288,6 +2272,7 @@ void terminate_execution(environment_t* env) {
2288
2272
// function should NEVER be called while holding any mutex lock.
2289
2273
lf_mutex_lock (& outbound_socket_mutex );
2290
2274
for (int i = 0 ; i < NUMBER_OF_FEDERATES ; i ++ ) {
2275
+
2291
2276
// Close outbound connections, in case they have not closed themselves.
2292
2277
// This will result in EOF being sent to the remote federate, I think.
2293
2278
_lf_close_outbound_socket (i );
@@ -2319,10 +2304,11 @@ void terminate_execution(environment_t* env) {
2319
2304
2320
2305
LF_PRINT_DEBUG ("Waiting for inbound p2p socket listener threads." );
2321
2306
// Wait for each inbound socket listener thread to close.
2322
- if (_fed .number_of_inbound_p2p_connections > 0 ) {
2307
+ if (_fed .number_of_inbound_p2p_connections > 0 && _fed . inbound_socket_listeners != NULL ) {
2323
2308
LF_PRINT_LOG ("Waiting for %zu threads listening for incoming messages to exit." ,
2324
2309
_fed .number_of_inbound_p2p_connections );
2325
2310
for (int i = 0 ; i < _fed .number_of_inbound_p2p_connections ; i ++ ) {
2311
+ if (_fed .inbound_socket_listeners [i ] == NULL ) continue ;
2326
2312
// Ignoring errors here.
2327
2313
lf_thread_join (_fed .inbound_socket_listeners [i ], NULL );
2328
2314
}
0 commit comments