Timer

Timer — STUN timer Usage

Stability Level

Stable, unless otherwise indicated

Synopsis

#include <stun/usages/timer.h>

typedef             StunTimer;
enum                StunUsageTimerReturn;
#define             STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS
#define             STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT
#define             STUN_TIMER_DEFAULT_TIMEOUT
void                stun_timer_start                    (StunTimer *timer,
                                                         unsigned int initial_timeout,
                                                         unsigned int max_retransmissions);
void                stun_timer_start_reliable           (StunTimer *timer,
                                                         unsigned int initial_timeout);
StunUsageTimerReturn  stun_timer_refresh                (StunTimer *timer);
unsigned            stun_timer_remainder                (const StunTimer *timer);

Description

The STUN timer usage is a set of helpful utility functions that allows you to easily track when a STUN message should be retransmitted or considered as timed out.

Example 3. Simple example on how to use the timer usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
StunTimer timer;
unsigned remainder;
StunUsageTimerReturn ret;

// Build the message, etc..
...

// Send the message and start the timer
send(socket, request, sizeof(request));
stun_timer_start(&timer, STUN_TIMER_DEFAULT_TIMEOUT,
                 STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS);

// Loop until we get the response
for (;;) {
  remainder = stun_timer_remainder(&timer);

  // Poll the socket until data is received or the timer expires
  if (poll (&pollfd, 1, delay) <= 0) {
    // Time out and no response was received
    ret = stun_timer_refresh (&timer);
    if (ret == STUN_USAGE_TIMER_RETURN_TIMEOUT) {
      // Transaction timed out
      break;
    } else if (ret == STUN_USAGE_TIMER_RETURN_RETRANSMIT) {
      // A retransmission is necessary
      send(socket, request, sizeof(request));
      continue;
    } else if (ret == STUN_USAGE_TIMER_RETURN_SUCCESS) {
      // The refresh succeeded and nothing has to be done, continue polling
      continue;
    }
  } else {
    // We received a response, read it
    recv(socket, response, sizeof(response));
    break;
  }
}

// Check if the transaction timed out or not
if (ret == STUN_USAGE_TIMER_RETURN_TIMEOUT) {
  // do whatever needs to be done in that case
} else {
  // Parse the response
}


Details

StunTimer

typedef struct stun_timer_s StunTimer;

An opaque structure representing a STUN transaction retransmission timer


enum StunUsageTimerReturn

typedef enum {
  STUN_USAGE_TIMER_RETURN_SUCCESS,
  STUN_USAGE_TIMER_RETURN_RETRANSMIT,
  STUN_USAGE_TIMER_RETURN_TIMEOUT
} StunUsageTimerReturn;

Return value of stun_usage_timer_refresh() which provides you with status information on the timer.

STUN_USAGE_TIMER_RETURN_SUCCESS

The timer was refreshed successfully and there is nothing to be done

STUN_USAGE_TIMER_RETURN_RETRANSMIT

The timer expired and the message should be retransmitted now.

STUN_USAGE_TIMER_RETURN_TIMEOUT

The timer expired as well as all the retransmissions, the transaction timed out

STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS

#define STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS 3

The default maximum retransmissions allowed before a timer decides to timeout


STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT

#define STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT 7900

The default intial timeout to use for a reliable timer


STUN_TIMER_DEFAULT_TIMEOUT

#define STUN_TIMER_DEFAULT_TIMEOUT 600

The default intial timeout to use for the timer


stun_timer_start ()

void                stun_timer_start                    (StunTimer *timer,
                                                         unsigned int initial_timeout,
                                                         unsigned int max_retransmissions);

Starts a STUN transaction retransmission timer. This should be called as soon as you send the message for the first time on a UDP socket. The timeout before the next retransmission is set to initial_timeout, then each time a packet is retransmited, that timeout will be doubled, until the max_retransmissions retransmissions limit is reached.

To determine the total timeout value, one can use the following equation :

 total_timeout =  initial_timeout * (2^(max_retransmissions + 1) - 1);
 

See also: STUN_TIMER_DEFAULT_TIMEOUT

See also: STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS

timer :

The StunTimer to start

initial_timeout :

The initial timeout to use before the first retransmission

max_retransmissions :

The maximum number of transmissions before the StunTimer times out

stun_timer_start_reliable ()

void                stun_timer_start_reliable           (StunTimer *timer,
                                                         unsigned int initial_timeout);

Starts a STUN transaction retransmission timer for a reliable transport. This should be called as soon as you send the message for the first time on a TCP socket

timer :

The StunTimer to start

stun_timer_refresh ()

StunUsageTimerReturn  stun_timer_refresh                (StunTimer *timer);

Updates a STUN transaction retransmission timer.

timer :

The StunTimer to refresh

Returns :

A StunUsageTimerReturn telling you what to do next

stun_timer_remainder ()

unsigned            stun_timer_remainder                (const StunTimer *timer);

Query the timer on the time left before the next refresh should be done

timer :

The StunTimer to query

Returns :

The time remaining for the timer to expire in milliseconds