Timer

## 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
`initial_timeout` : |

### 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