OpenVPN
Data Structures | Macros
Reliability Layer module

The Reliability Layer is part of OpenVPN's control channel. It provides a reliable and sequential transport mechanism for control channel messages between OpenVPN peers. This module forms the interface between the External Multiplexer and the Control Channel TLS module. More...

Data Structures

struct  reliable_ack
 The acknowledgment structure in which packet IDs are stored for later acknowledgment. More...
 
struct  reliable_entry
 The structure in which the reliability layer stores a single incoming or outgoing packet. More...
 
struct  reliable
 The reliability layer storage structure for one VPN tunnel's control channel in one direction. More...
 

Macros

#define RELIABLE_ACK_SIZE   8
 The maximum number of packet IDs waiting to be acknowledged which can be stored in one reliable_ack structure. More...
 
#define RELIABLE_CAPACITY   12
 The maximum number of packets that the reliability layer for one VPN tunnel in one direction can store. More...
 
#define N_ACK_RETRANSMIT   3
 We retry sending a packet early if this many later packets have been ACKed. More...
 
#define ACK_SIZE(n)   (sizeof(uint8_t) + ((n) ? SID_SIZE : 0) + sizeof(packet_id_type) * (n))
 

Functions for processing incoming acknowledgments

bool reliable_ack_read (struct reliable_ack *ack, struct buffer *buf, const struct session_id *sid)
 Read an acknowledgment record from a received packet. More...
 
bool reliable_ack_parse (struct buffer *buf, struct reliable_ack *ack, struct session_id *session_id_remote)
 Parse an acknowledgment record from a received packet. More...
 
void reliable_send_purge (struct reliable *rel, const struct reliable_ack *ack)
 Remove acknowledged packets from a reliable structure. More...
 

Functions for processing outgoing acknowledgments

static bool reliable_ack_empty (struct reliable_ack *ack)
 Check whether an acknowledgment structure contains any packet IDs to be acknowledged. More...
 
static int reliable_ack_outstanding (struct reliable_ack *ack)
 Returns the number of packets that need to be acked. More...
 
bool reliable_ack_write (struct reliable_ack *ack, struct reliable_ack *ack_mru, struct buffer *buf, const struct session_id *sid, int max, bool prepend)
 Write a packet ID acknowledgment record to a buffer. More...
 

Functions for initialization and cleanup

void reliable_init (struct reliable *rel, int buf_size, int offset, int array_size, bool hold)
 Initialize a reliable structure. More...
 
void reliable_free (struct reliable *rel)
 Free allocated memory associated with a reliable structure and the pointer itself. More...
 

Functions for inserting incoming packets

bool reliable_can_get (const struct reliable *rel)
 Check whether a reliable structure has any free buffers available for use. More...
 
bool reliable_not_replay (const struct reliable *rel, packet_id_type id)
 Check that a received packet's ID is not a replay. More...
 
bool reliable_wont_break_sequentiality (const struct reliable *rel, packet_id_type id)
 Check that a received packet's ID can safely be stored in the reliable structure's processing window. More...
 
bool reliable_ack_read_packet_id (struct buffer *buf, packet_id_type *pid)
 Read the packet ID of a received packet. More...
 
struct bufferreliable_get_buf (struct reliable *rel)
 Get the buffer of a free reliable entry in which to store a packet. More...
 
void reliable_mark_active_incoming (struct reliable *rel, struct buffer *buf, packet_id_type pid, int opcode)
 Mark the reliable entry associated with the given buffer as active incoming. More...
 
bool reliable_ack_acknowledge_packet_id (struct reliable_ack *ack, packet_id_type pid)
 Record a packet ID for later acknowledgment. More...
 

Functions for extracting incoming packets

struct reliable_entryreliable_get_entry_sequenced (struct reliable *rel)
 Get the buffer of the next sequential and active entry. More...
 
void copy_acks_to_mru (struct reliable_ack *ack, struct reliable_ack *ack_mru, int n)
 Copies the first n acks from ack to ack_mru. More...
 
void reliable_mark_deleted (struct reliable *rel, struct buffer *buf)
 Remove an entry from a reliable structure. More...
 

Functions for inserting outgoing packets

struct bufferreliable_get_buf_output_sequenced (struct reliable *rel)
 Get the buffer of free reliable entry and check whether the outgoing acknowledgment sequence is still okay. More...
 
int reliable_get_num_output_sequenced_available (struct reliable *rel)
 Counts the number of free buffers in output that can be potentially used for sending. More...
 
void reliable_mark_active_outgoing (struct reliable *rel, struct buffer *buf, int opcode)
 Mark the reliable entry associated with the given buffer as active outgoing. More...
 

Functions for extracting outgoing packets

bool reliable_can_send (const struct reliable *rel)
 Check whether a reliable structure has any active entries ready to be (re)sent. More...
 
struct bufferreliable_send (struct reliable *rel, int *opcode)
 Get the next packet to send to the remote peer. More...
 

Miscellaneous functions

bool reliable_empty (const struct reliable *rel)
 Check whether a reliable structure is empty. More...
 
interval_t reliable_send_timeout (const struct reliable *rel)
 Determined how many seconds until the earliest resend should be attempted. More...
 
void reliable_schedule_now (struct reliable *rel)
 Reschedule all entries of a reliable structure to be ready for (re)sending immediately. More...
 
void reliable_debug_print (const struct reliable *rel, char *desc)
 
static void reliable_set_timeout (struct reliable *rel, interval_t timeout)
 
const char * reliable_ack_print (struct buffer *buf, bool verbose, struct gc_arena *gc)
 
void reliable_ack_debug_print (const struct reliable_ack *ack, char *desc)
 

Detailed Description

The Reliability Layer is part of OpenVPN's control channel. It provides a reliable and sequential transport mechanism for control channel messages between OpenVPN peers. This module forms the interface between the External Multiplexer and the Control Channel TLS module.

UDP or TCP as VPN tunnel transport

This is especially important when OpenVPN is configured to communicate over UDP, because UDP does not offer a reliable and sequential transport. OpenVPN endpoints can also communicate over TCP which does provide a reliable and sequential transport. In both cases, using UDP or TCP as an external transport, the internal Reliability Layer is active.

Macro Definition Documentation

◆ ACK_SIZE

#define ACK_SIZE (   n)    (sizeof(uint8_t) + ((n) ? SID_SIZE : 0) + sizeof(packet_id_type) * (n))

Definition at line 68 of file reliable.h.

◆ N_ACK_RETRANSMIT

#define N_ACK_RETRANSMIT   3

We retry sending a packet early if this many later packets have been ACKed.

Definition at line 53 of file reliable.h.

◆ RELIABLE_ACK_SIZE

#define RELIABLE_ACK_SIZE   8

The maximum number of packet IDs waiting to be acknowledged which can be stored in one reliable_ack structure.

Definition at line 44 of file reliable.h.

◆ RELIABLE_CAPACITY

#define RELIABLE_CAPACITY   12

The maximum number of packets that the reliability layer for one VPN tunnel in one direction can store.

Definition at line 49 of file reliable.h.

Function Documentation

◆ copy_acks_to_mru()

void copy_acks_to_mru ( struct reliable_ack ack,
struct reliable_ack ack_mru,
int  n 
)

Copies the first n acks from ack to ack_mru.

Parameters
ackThe reliable structure to copy the acks from
ack_mruThe reliable structure to insert the acks into
nThe number of ACKS to copy

Definition at line 211 of file reliable.c.

References ASSERT, reliable_ack::len, reliable_ack::packet_id, and RELIABLE_ACK_SIZE.

Referenced by reliable_ack_write(), and test_copy_acks_to_lru().

◆ reliable_ack_acknowledge_packet_id()

bool reliable_ack_acknowledge_packet_id ( struct reliable_ack ack,
packet_id_type  pid 
)

Record a packet ID for later acknowledgment.

Parameters
ackThe acknowledgment structure which stores this VPN tunnel's packet IDs for later acknowledgment.
pidThe packet ID of the received packet which should be acknowledged.
Returns
  • True, if the packet ID was added to ack.
  • False, if the packet ID was already present in ack or ack has no free space to store any more packet IDs.

Definition at line 132 of file reliable.c.

References D_REL_DEBUG, D_REL_LOW, dmsg, reliable_ack::len, reliable_ack::packet_id, packet_id_format, reliable_ack_packet_id_present(), and RELIABLE_ACK_SIZE.

Referenced by tls_pre_decrypt().

◆ reliable_ack_debug_print()

void reliable_ack_debug_print ( const struct reliable_ack ack,
char *  desc 
)

◆ reliable_ack_empty()

static bool reliable_ack_empty ( struct reliable_ack ack)
inlinestatic

Check whether an acknowledgment structure contains any packet IDs to be acknowledged.

Parameters
ackThe acknowledgment structure to check.
Returns
  • True, if the acknowledgment structure is empty.
  • False, if there are packet IDs to be acknowledged.

Definition at line 176 of file reliable.h.

References reliable_ack::len.

Referenced by tls_process().

◆ reliable_ack_outstanding()

static int reliable_ack_outstanding ( struct reliable_ack ack)
inlinestatic

Returns the number of packets that need to be acked.

Parameters
ackThe acknowledgment structure to check.
Returns
the number of outstanding acks

Definition at line 189 of file reliable.h.

References reliable_ack::len.

Referenced by calc_control_channel_frame_overhead().

◆ reliable_ack_parse()

bool reliable_ack_parse ( struct buffer buf,
struct reliable_ack ack,
struct session_id session_id_remote 
)

Parse an acknowledgment record from a received packet.

This function parses the packet ID acknowledgment record from the packet contained in buf. If the record contains acknowledgments, these are stored in ack. This function also extracts packet's session ID and returns it in session_id_remote

Parameters
ackThe acknowledgment structure in which received acknowledgments are to be stored.
bufThe buffer containing the packet.
session_id_remoteThe parsed remote session id. This field is is only filled if ack->len >= 1
Returns
  • True, if processing was successful.
  • False, if an error occurs during processing.

Definition at line 173 of file reliable.c.

References buf_read(), reliable_ack::len, ntohpid, reliable_ack::packet_id, RELIABLE_ACK_SIZE, and session_id_read().

Referenced by check_session_id_hmac(), reliable_ack_read(), and test_parse_ack().

◆ reliable_ack_print()

const char* reliable_ack_print ( struct buffer buf,
bool  verbose,
struct gc_arena gc 
)

◆ reliable_ack_read()

bool reliable_ack_read ( struct reliable_ack ack,
struct buffer buf,
const struct session_id sid 
)

Read an acknowledgment record from a received packet.

This function reads the packet ID acknowledgment record from the packet contained in buf. If the record contains acknowledgments, these are stored in ack. This function also compares the packet's session ID with the expected session ID sid, which should be equal.

Parameters
ackThe acknowledgment structure in which received acknowledgments are to be stored.
bufThe buffer containing the packet.
sidThe expected session ID to compare to the session ID in the packet.
Returns
  • True, if processing was successful.
  • False, if an error occurs during processing.

Definition at line 149 of file reliable.c.

References D_REL_LOW, dmsg, gc_free(), gc_new(), reliable_ack::len, reliable_ack_parse(), session_id_defined(), session_id_equal(), and session_id_print().

Referenced by tls_pre_decrypt().

◆ reliable_ack_read_packet_id()

bool reliable_ack_read_packet_id ( struct buffer buf,
packet_id_type pid 
)

Read the packet ID of a received packet.

Parameters
bufThe buffer containing the received packet.
pidA pointer where the packet's packet ID will be written.
Returns
  • True, if processing was successful.
  • False, if an error occurs during processing.

Definition at line 114 of file reliable.c.

References buf_read(), D_REL_DEBUG, D_REL_LOW, dmsg, buffer::len, ntohpid, and packet_id_format.

Referenced by tls_pre_decrypt().

◆ reliable_ack_write()

bool reliable_ack_write ( struct reliable_ack ack,
struct reliable_ack ack_mru,
struct buffer buf,
const struct session_id sid,
int  max,
bool  prepend 
)

Write a packet ID acknowledgment record to a buffer.

Parameters
ackThe acknowledgment structure containing packet IDs to be acknowledged.
ack_mruList of packets we have acknowledged before. Packets from ack will be moved here and if there is space in our ack structure we will fill it with packets from this
bufThe buffer into which the acknowledgment record will be written.
sidThe session ID of the VPN tunnel associated with the packet IDs to be acknowledged.
maxThe maximum number of acknowledgments to be written in the record.
prependIf true, prepend the acknowledgment record in the buffer; if false, write into the buffer's current position.
Returns
  • True, if processing was successful.
  • False, if an error occurs during processing.

Definition at line 255 of file reliable.c.

References ACK_SIZE, ASSERT, BDEF, buf_sub(), buf_write(), buf_write_u8(), copy_acks_to_mru(), D_REL_DEBUG, dmsg, htonpid, reliable_ack::len, min_int(), reliable_ack::packet_id, packet_id_format, session_id_defined(), and session_id_write().

Referenced by write_control_auth().

◆ reliable_can_get()

bool reliable_can_get ( const struct reliable rel)

Check whether a reliable structure has any free buffers available for use.

Parameters
relThe reliable structure to check.
Returns
  • True, if at least one buffer is available for use.
  • False, if all the buffers are active.

Definition at line 470 of file reliable.c.

References reliable_entry::active, array, D_REL_LOW, dmsg, gc_free(), gc_new(), and size.

Referenced by tls_pre_decrypt().

◆ reliable_can_send()

bool reliable_can_send ( const struct reliable rel)

Check whether a reliable structure has any active entries ready to be (re)sent.

Parameters
relThe reliable structure to check.
Returns
  • True, if there are active entries ready to be (re)sent president.
  • False, if there are no active entries, or the active entries are not yet ready for resending.

Definition at line 635 of file reliable.c.

References reliable_entry::active, array, D_REL_DEBUG, dmsg, gc_free(), gc_new(), hold, N_ACK_RETRANSMIT, reliable_entry::n_acks, reliable_entry::next_try, now, and size.

Referenced by tls_process_state().

◆ reliable_debug_print()

void reliable_debug_print ( const struct reliable rel,
char *  desc 
)

◆ reliable_empty()

bool reliable_empty ( const struct reliable rel)

Check whether a reliable structure is empty.

Parameters
relThe reliable structure to check.
Returns
  • True, if there are no active entries in the given reliable structure.
  • False, if there is at least one active entry present.

Definition at line 393 of file reliable.c.

References reliable_entry::active, array, and size.

Referenced by tls_process_state().

◆ reliable_free()

void reliable_free ( struct reliable rel)

Free allocated memory associated with a reliable structure and the pointer itself.

Does nothing if rel is NULL.

Parameters
relThe reliable structured to clean up.

Definition at line 376 of file reliable.c.

References array, reliable_entry::buf, free_buf(), and size.

Referenced by key_state_free(), and test_get_num_output_sequenced_available().

◆ reliable_get_buf()

struct buffer* reliable_get_buf ( struct reliable rel)

Get the buffer of a free reliable entry in which to store a packet.

Parameters
relThe reliable structure in which to search for a free entry.
Returns
A pointer to a buffer of a free entry in the rel reliable structure. If there are no free entries available, this function returns NULL.

Definition at line 536 of file reliable.c.

References reliable_entry::active, array, ASSERT, reliable_entry::buf, buf_init, offset, and size.

Referenced by reliable_get_buf_output_sequenced(), and tls_pre_decrypt().

◆ reliable_get_buf_output_sequenced()

struct buffer* reliable_get_buf_output_sequenced ( struct reliable rel)

Get the buffer of free reliable entry and check whether the outgoing acknowledgment sequence is still okay.

Parameters
relThe reliable structure in which to search for a free entry.
Returns
A pointer to a buffer of a free entry in the rel reliable structure. If there are no free entries available, this function returns NULL. If the outgoing acknowledgment sequence is broken, this function also returns NULL.

Definition at line 583 of file reliable.c.

References reliable_entry::active, array, D_REL_LOW, dmsg, gc_free(), gc_new(), reliable_entry::packet_id, packet_id, reliable_get_buf(), reliable_pid_in_range1(), reliable_pid_min(), and size.

Referenced by session_move_pre_start(), tls_process(), tls_process_state(), and write_outgoing_tls_ciphertext().

◆ reliable_get_entry_sequenced()

struct reliable_entry* reliable_get_entry_sequenced ( struct reliable rel)

Get the buffer of the next sequential and active entry.

Parameters
relThe reliable structure from which to retrieve the buffer.
Returns
A pointer to the entry with the next sequential key ID. If no such entry is present, this function returns NULL.

Definition at line 619 of file reliable.c.

References reliable_entry::active, array, reliable_entry::packet_id, packet_id, and size.

Referenced by tls_process_state().

◆ reliable_get_num_output_sequenced_available()

int reliable_get_num_output_sequenced_available ( struct reliable rel)

Counts the number of free buffers in output that can be potentially used for sending.

Parameters
relThe reliable structure in which to search for a free entry.
Returns
the number of buffer that are available for sending without breaking ack sequence

Definition at line 552 of file reliable.c.

References reliable_entry::active, array, gc_free(), gc_new(), reliable_entry::packet_id, packet_id, reliable_pid_min(), size, and subtract_pid().

Referenced by test_get_num_output_sequenced_available(), and write_outgoing_tls_ciphertext().

◆ reliable_init()

void reliable_init ( struct reliable rel,
int  buf_size,
int  offset,
int  array_size,
bool  hold 
)

Initialize a reliable structure.

Parameters
relThe reliable structure to initialize.
buf_sizeThe size of the buffers in which packets will be stored.
offsetThe size of reserved space at the beginning of the buffers to allow efficient header prepending.
array_sizeThe number of packets that this reliable structure can store simultaneously.
holddescription

Definition at line 358 of file reliable.c.

References alloc_buf(), array, ASSERT, reliable_entry::buf, buf_init, CLEAR, hold, buffer::offset, offset, RELIABLE_CAPACITY, and size.

Referenced by key_state_init(), and test_get_num_output_sequenced_available().

◆ reliable_mark_active_incoming()

void reliable_mark_active_incoming ( struct reliable rel,
struct buffer buf,
packet_id_type  pid,
int  opcode 
)

Mark the reliable entry associated with the given buffer as active incoming.

Parameters
relThe reliable structure associated with this packet.
bufThe buffer into which the packet has been copied.
pidThe packet's packet ID.
opcodeThe packet's opcode.

Definition at line 758 of file reliable.c.

References reliable_entry::active, array, ASSERT, reliable_entry::buf, D_REL_DEBUG, dmsg, reliable_entry::n_acks, reliable_entry::next_try, reliable_entry::opcode, reliable_entry::packet_id, packet_id, packet_id_format, reliable_pid_min(), size, and reliable_entry::timeout.

Referenced by tls_pre_decrypt().

◆ reliable_mark_active_outgoing()

void reliable_mark_active_outgoing ( struct reliable rel,
struct buffer buf,
int  opcode 
)

Mark the reliable entry associated with the given buffer as active outgoing.

Parameters
relThe reliable structure for handling this VPN tunnel's outgoing packets.
bufThe buffer previously returned by reliable_get_buf_output_sequenced() into which the packet has been copied.
opcodeThe packet's opcode.

Definition at line 791 of file reliable.c.

References reliable_entry::active, array, ASSERT, reliable_entry::buf, buf_write_prepend(), D_REL_DEBUG, dmsg, htonpid, initial_timeout, reliable_entry::next_try, reliable_entry::opcode, reliable_entry::packet_id, packet_id, packet_id_format, size, and reliable_entry::timeout.

Referenced by session_move_pre_start(), tls_process(), and write_outgoing_tls_ciphertext().

◆ reliable_mark_deleted()

void reliable_mark_deleted ( struct reliable rel,
struct buffer buf 
)

Remove an entry from a reliable structure.

Parameters
relThe reliable structure associated with the given buffer.
bufThe buffer of the reliable entry which is to be removed.

Definition at line 818 of file reliable.c.

References reliable_entry::active, array, ASSERT, reliable_entry::buf, reliable_entry::packet_id, packet_id, and size.

Referenced by parse_early_negotiation_tlvs(), read_incoming_tls_ciphertext(), and session_move_pre_start().

◆ reliable_not_replay()

bool reliable_not_replay ( const struct reliable rel,
packet_id_type  id 
)

Check that a received packet's ID is not a replay.

Parameters
relThe reliable structure for handling this VPN tunnel's received packets.
idThe packet ID of the received packet.
Returns
  • True, if the packet ID is not a replay.
  • False, if the packet ID is a replay.

Definition at line 489 of file reliable.c.

References reliable_entry::active, array, D_REL_DEBUG, dmsg, gc_free(), gc_new(), reliable_entry::packet_id, packet_id, packet_id_format, reliable_pid_min(), and size.

Referenced by tls_pre_decrypt().

◆ reliable_schedule_now()

void reliable_schedule_now ( struct reliable rel)

Reschedule all entries of a reliable structure to be ready for (re)sending immediately.

Parameters
relThe reliable structure of which the entries should be modified.

Definition at line 702 of file reliable.c.

References reliable_entry::active, array, D_REL_DEBUG, dmsg, hold, initial_timeout, reliable_entry::next_try, now, size, and reliable_entry::timeout.

Referenced by tls_pre_decrypt().

◆ reliable_send()

struct buffer* reliable_send ( struct reliable rel,
int *  opcode 
)

Get the next packet to send to the remote peer.

This function looks for the active entry ready for (re)sending with the lowest packet ID, and returns the buffer associated with it. This function also resets the timeout after which that entry will become ready for resending again.

Parameters
relThe reliable structure to check.
opcodeA pointer to an integer in which this function will store the opcode of the next packet to be sent.
Returns
A pointer to the buffer of the next entry to be sent, or NULL if there are no entries ready for (re)sending present in the reliable structure. If a valid pointer is returned, then opcode will point to the opcode of that packet.

Definition at line 663 of file reliable.c.

References reliable_entry::active, array, reliable_entry::buf, D_REL_DEBUG, dmsg, buffer::len, N_ACK_RETRANSMIT, reliable_entry::n_acks, reliable_entry::next_try, now, reliable_entry::opcode, reliable_entry::packet_id, packet_id_format, reliable_pid_min(), size, and reliable_entry::timeout.

Referenced by tls_process_state().

◆ reliable_send_purge()

void reliable_send_purge ( struct reliable rel,
const struct reliable_ack ack 
)

Remove acknowledged packets from a reliable structure.

Parameters
relThe reliable structure storing sent packets.
ackThe acknowledgment structure containing received acknowledgments.

Definition at line 409 of file reliable.c.

References reliable_entry::active, array, D_REL_DEBUG, dmsg, reliable_ack::len, M_INFO, msg, reliable_entry::n_acks, reliable_entry::next_try, now, reliable_ack::packet_id, reliable_entry::packet_id, packet_id_format, and size.

Referenced by tls_pre_decrypt().

◆ reliable_send_timeout()

interval_t reliable_send_timeout ( const struct reliable rel)

Determined how many seconds until the earliest resend should be attempted.

Parameters
relThe reliable structured to check.
Returns
The interval in seconds until the earliest resend attempt of the outgoing packets stored in the rel reliable structure. If the next time for attempting resending of one or more packets has already passed, this function will return 0.

Definition at line 721 of file reliable.c.

References reliable_entry::active, array, BIG_TIMEOUT, D_REL_DEBUG, dmsg, gc_free(), gc_new(), min_int(), reliable_entry::next_try, now, and size.

Referenced by tls_process().

◆ reliable_set_timeout()

static void reliable_set_timeout ( struct reliable rel,
interval_t  timeout 
)
inlinestatic

Definition at line 531 of file reliable.h.

References initial_timeout.

Referenced by key_state_init().

◆ reliable_wont_break_sequentiality()

bool reliable_wont_break_sequentiality ( const struct reliable rel,
packet_id_type  id 
)

Check that a received packet's ID can safely be stored in the reliable structure's processing window.

This function checks the difference between the received packet's ID and the lowest non-acknowledged packet ID in the given reliable structure. If that difference is larger than the total number of packets which can be stored, then this packet cannot be stored safely, because the reliable structure could possibly fill up without leaving room for all intervening packets. In that case, this received packet could break the reliable structure's sequentiality, and must therefore be discarded.

Parameters
relThe reliable structure for handling this VPN tunnel's received packets.
idThe packet ID of the received packet.
Returns
  • True, if the packet can safely be stored.
  • False, if the packet does not fit safely in the reliable structure's processing window.

Definition at line 516 of file reliable.c.

References D_REL_DEBUG, D_REL_LOW, dmsg, gc_free(), gc_new(), packet_id, packet_id_format, reliable_pid_in_range2(), and size.

Referenced by tls_pre_decrypt().