lsquic_alarmset.c revision 06b2a236
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_alarmset.c -- A set of alarms
4 */
5
6#include <assert.h>
7#include <string.h>
8
9#include "lsquic_types.h"
10#include "lsquic_packet_common.h"
11#include "lsquic_alarmset.h"
12
13#define LSQUIC_LOGGER_MODULE LSQLM_ALARMSET
14#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(alset->as_conn)
15#include "lsquic_logger.h"
16
17
18void
19lsquic_alarmset_init (lsquic_alarmset_t *alset, const struct lsquic_conn *conn)
20{
21    alset->as_conn      = conn;
22    alset->as_armed_set = 0;
23}
24
25
26void
27lsquic_alarmset_init_alarm (lsquic_alarmset_t *alset, enum alarm_id al_id,
28                            lsquic_alarm_cb_f callback, void *cb_ctx)
29{
30    alset->as_alarms[ al_id ].callback = callback;
31    alset->as_alarms[ al_id ].cb_ctx   = cb_ctx;
32}
33
34
35const char *const lsquic_alid2str[] =
36{
37    [AL_HANDSHAKE]  =  "HANDSHAKE",
38    [AL_RETX_INIT]  =  "RETX_INIT",
39    [AL_RETX_HSK]   =  "RETX_HSK",
40    [AL_RETX_APP]   =  "RETX_APP",
41    [AL_PING]       =  "PING",
42    [AL_IDLE]       =  "IDLE",
43    [AL_ACK_APP]    =  "ACK_APP",
44    [AL_RET_CIDS]   =  "RET_CIDS",
45    [AL_CID_THROT]  =  "CID_THROT",
46    [AL_PATH_CHAL_0] = "PATH_CHAL_0",
47    [AL_PATH_CHAL_1] = "PATH_CHAL_1",
48    [AL_SESS_TICKET] = "SESS_TICKET",
49    [AL_BLOCKED_KA] = "BLOCKED_KA",
50    [AL_MTU_PROBE]  = "MTU_PROBE",
51    [AL_PACK_TOL]   = "PACK_TOL",
52};
53
54
55void
56lsquic_alarmset_ring_expired (lsquic_alarmset_t *alset, lsquic_time_t now)
57{
58    enum alarm_id_bit armed_set;
59    enum alarm_id al_id;
60
61    for (al_id = 0, armed_set = alset->as_armed_set;
62            al_id < MAX_LSQUIC_ALARMS && armed_set;
63                armed_set &= ~(1 << al_id), ++al_id)
64        if (armed_set & (1 << al_id))
65        {
66            if (alset->as_expiry[al_id] < now)
67            {
68                alset->as_armed_set &= ~(1 << al_id);
69                LSQ_INFO("ring expired %s alarm", lsquic_alid2str[al_id]);
70                alset->as_alarms[al_id].callback(al_id,
71                                alset->as_alarms[al_id].cb_ctx,
72                                alset->as_expiry[al_id], now);
73            }
74        }
75}
76
77
78lsquic_time_t
79lsquic_alarmset_mintime (const lsquic_alarmset_t *alset, enum alarm_id *idp)
80{
81    lsquic_time_t expiry;
82    enum alarm_id al_id, ret_id;
83
84    if (alset->as_armed_set)
85    {
86        expiry = UINT64_MAX;
87        for (al_id = 0, ret_id = 0; al_id < MAX_LSQUIC_ALARMS; ++al_id)
88            if ((alset->as_armed_set & (1 << al_id))
89                                && alset->as_expiry[al_id] < expiry)
90            {
91                expiry = alset->as_expiry[al_id];
92                ret_id = al_id;
93            }
94        *idp = ret_id;
95        return expiry;
96    }
97    else
98        return 0;
99}
100