reactor-c
C Runtime for Lingua Franca
Loading...
Searching...
No Matches
socket_common.c File Reference
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdarg.h>
#include <string.h>
#include "util.h"
#include "socket_common.h"

Macros

#define NUMBER_OF_FEDERATES   1
 
#define SOCKET_READ_RETRY_INTERVAL   1000000
 

Functions

int create_real_time_tcp_socket_errexit ()
 Create an IPv4 TCP socket with Nagle's algorithm disabled (TCP_NODELAY) and Delayed ACKs disabled (TCP_QUICKACK). Exits application on any error.
 
int create_server (uint16_t port, int *final_socket, uint16_t *final_port, socket_type_t sock_type, bool increment_port_on_retry)
 Create a TCP server that listens for socket connections.
 
int accept_socket (int socket, int rti_socket)
 
int connect_to_socket (int sock, const char *hostname, int port)
 
int read_from_socket (int socket, size_t num_bytes, unsigned char *buffer)
 
int read_from_socket_close_on_error (int *socket, size_t num_bytes, unsigned char *buffer)
 
void read_from_socket_fail_on_error (int *socket, size_t num_bytes, unsigned char *buffer, lf_mutex_t *mutex, char *format,...)
 
ssize_t peek_from_socket (int socket, unsigned char *result)
 
int write_to_socket (int socket, size_t num_bytes, unsigned char *buffer)
 
int write_to_socket_close_on_error (int *socket, size_t num_bytes, unsigned char *buffer)
 
void write_to_socket_fail_on_error (int *socket, size_t num_bytes, unsigned char *buffer, lf_mutex_t *mutex, char *format,...)
 

Variables

lf_mutex_t socket_mutex
 

Macro Definition Documentation

◆ NUMBER_OF_FEDERATES

#define NUMBER_OF_FEDERATES   1

◆ SOCKET_READ_RETRY_INTERVAL

#define SOCKET_READ_RETRY_INTERVAL   1000000

Number of nanoseconds to sleep before retrying a socket read.

Function Documentation

◆ accept_socket()

int accept_socket ( int socket,
int rti_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 temporary (e.g., EAGAIN or EWOULDBLOCK), it reports the error and exits. Temporary errors cause the function to retry accepting the connection.

If the rti_socket is not -1, this function checks whether the specified socket is still open. If it is not open, then this function returns -1. This is useful for federates to determine whether they are still connected to the federation and to stop waiting when they are not.

Parameters
socketThe server socket file descriptor that is listening for incoming connections.
rti_socketThe rti socket for the federate to check if it is still open.
Returns
The file descriptor for the newly accepted socket on success, or -1 on failure (with an appropriate error message printed).

◆ connect_to_socket()

int connect_to_socket ( int sock,
const char * hostname,
int port )

Attempt to establish a TCP connection to the specified hostname and port. This function uses getaddrinfo to resolve the hostname and retries the connection periodically if it fails. If the specified port is 0, it iterates through a range of default ports starting from DEFAULT_PORT. The function will stop retrying if the CONNECT_TIMEOUT is reached.

Parameters
sockThe socket file descriptor that has already been created (using socket()).
hostnameThe hostname or IP address of the server to connect to.
portThe port number to connect to. If 0 is specified, a default port range will be used.
Returns
0 on success, -1 on failure, and errno is set to indicate the specific error.

◆ create_real_time_tcp_socket_errexit()

int create_real_time_tcp_socket_errexit ( )

Create an IPv4 TCP socket with Nagle's algorithm disabled (TCP_NODELAY) and Delayed ACKs disabled (TCP_QUICKACK). Exits application on any error.

Returns
The socket ID (a file descriptor).

◆ create_server()

int create_server ( uint16_t port,
int * final_socket,
uint16_t * final_port,
socket_type_t sock_type,
bool increment_port_on_retry )

Create a TCP server that listens for socket connections.

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 DEFAULT_PORT. If it fails to acquire DEFAULT_PORT, then it will increment the port number from DEFAULT_PORT on each attempt until it has incremented MAX_NUM_PORT_ADDRESSES times, at which point it will cycle around and begin again with DEFAULT_PORT. If the port number is zero, and the increment_port_on_retry is false, it delegates to the operating system to provide an available port number. If acquiring the port fails, then this function will repeatedly attempt up to PORT_BIND_RETRY_LIMIT times with a delay of PORT_BIND_RETRY_INTERVAL in between each try.

Parameters
portThe port number to use or 0 to let the OS pick or 1 to start trying at DEFAULT_PORT.
final_socketPointer to the returned socket descriptor on which accepting connections will occur.
final_portPointer to the final port the server will use.
sock_typeType of the socket, TCP or UDP.
increment_port_on_retryBoolean to retry port increment.
Returns
0 for success, -1 for failure.

◆ peek_from_socket()

ssize_t peek_from_socket ( int socket,
unsigned char * result )

Without blocking, peek at the specified socket and, 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.

Parameters
socketThe socket ID.
resultPointer to where to put the first byte available on the socket.

◆ read_from_socket()

int read_from_socket ( int socket,
size_t num_bytes,
unsigned char * buffer )

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.

Parameters
socketThe socket ID.
num_bytesThe number of bytes to read.
bufferThe buffer into which to put the bytes.
Returns
0 for success, 1 for EOF, and -1 for an error.

◆ read_from_socket_close_on_error()

int read_from_socket_close_on_error ( int * socket,
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.

Parameters
socketPointer to the socket ID.
num_bytesThe number of bytes to write.
bufferThe buffer from which to get the bytes.
Returns
0 for success, -1 for failure.

◆ read_from_socket_fail_on_error()

void read_from_socket_fail_on_error ( int * socket,
size_t num_bytes,
unsigned char * buffer,
lf_mutex_t * mutex,
char * format,
... )

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.

Parameters
socketThe socket ID.
num_bytesThe number of bytes to read.
bufferThe buffer into which to put the bytes.
formatA printf-style format string, followed by arguments to fill the string, or NULL to not exit with an error message.
Returns
The number of bytes read, or 0 if an EOF is received, or a negative number for an error.

◆ write_to_socket()

int write_to_socket ( int socket,
size_t num_bytes,
unsigned char * buffer )

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.

Parameters
socketThe socket ID.
num_bytesThe number of bytes to write.
bufferThe buffer from which to get the bytes.
Returns
0 for success, -1 for failure.

◆ write_to_socket_close_on_error()

int write_to_socket_close_on_error ( int * socket,
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.

Parameters
socketPointer to the socket ID.
num_bytesThe number of bytes to write.
bufferThe buffer from which to get the bytes.
Returns
0 for success, -1 for failure.

◆ write_to_socket_fail_on_error()

void write_to_socket_fail_on_error ( int * socket,
size_t num_bytes,
unsigned char * buffer,
lf_mutex_t * mutex,
char * format,
... )

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.

Parameters
socketPointer to the socket ID.
num_bytesThe number of bytes to write.
bufferThe buffer from which to get the bytes.
mutexIf non-NULL, the mutex to unlock before exiting.
formatA 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.

Variable Documentation

◆ socket_mutex

lf_mutex_t socket_mutex

Mutex protecting socket close operations.