cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

lws-timeout-timer.h (11652B)


      1/*
      2 * libwebsockets - small server side websockets and web server implementation
      3 *
      4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to
      8 * deal in the Software without restriction, including without limitation the
      9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     10 * sell copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     22 * IN THE SOFTWARE.
     23 */
     24
     25/*! \defgroup timeout Connection timeouts
     26
     27    APIs related to setting connection timeouts
     28*/
     29//@{
     30
     31/*
     32 * NOTE: These public enums are part of the abi.  If you want to add one,
     33 * add it at where specified so existing users are unaffected.
     34 */
     35enum pending_timeout {
     36	NO_PENDING_TIMEOUT					=  0,
     37	PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE			=  1,
     38	PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE		=  2,
     39	PENDING_TIMEOUT_ESTABLISH_WITH_SERVER			=  3,
     40	PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE		=  4,
     41	PENDING_TIMEOUT_AWAITING_PING				=  5,
     42	PENDING_TIMEOUT_CLOSE_ACK				=  6,
     43	PENDING_TIMEOUT_UNUSED1					=  7,
     44	PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE			=  8,
     45	PENDING_TIMEOUT_SSL_ACCEPT				=  9,
     46	PENDING_TIMEOUT_HTTP_CONTENT				= 10,
     47	PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND			= 11,
     48	PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE			= 12,
     49	PENDING_TIMEOUT_SHUTDOWN_FLUSH				= 13,
     50	PENDING_TIMEOUT_CGI					= 14,
     51	PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE			= 15,
     52	PENDING_TIMEOUT_WS_PONG_CHECK_SEND_PING			= 16,
     53	PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG			= 17,
     54	PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD			= 18,
     55	PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY	        = 19,
     56	PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY		= 20,
     57	PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY		= 21,
     58	PENDING_TIMEOUT_KILLED_BY_SSL_INFO			= 22,
     59	PENDING_TIMEOUT_KILLED_BY_PARENT			= 23,
     60	PENDING_TIMEOUT_CLOSE_SEND				= 24,
     61	PENDING_TIMEOUT_HOLDING_AH				= 25,
     62	PENDING_TIMEOUT_UDP_IDLE				= 26,
     63	PENDING_TIMEOUT_CLIENT_CONN_IDLE			= 27,
     64	PENDING_TIMEOUT_LAGGING					= 28,
     65	PENDING_TIMEOUT_THREADPOOL				= 29,
     66	PENDING_TIMEOUT_THREADPOOL_TASK				= 30,
     67	PENDING_TIMEOUT_KILLED_BY_PROXY_CLIENT_CLOSE		= 31,
     68	PENDING_TIMEOUT_USER_OK					= 32,
     69
     70	/****** add new things just above ---^ ******/
     71
     72	PENDING_TIMEOUT_USER_REASON_BASE			= 1000
     73};
     74
     75#define lws_time_in_microseconds lws_now_usecs
     76
     77#define LWS_TO_KILL_ASYNC -1
     78/**< If LWS_TO_KILL_ASYNC is given as the timeout sec in a lws_set_timeout()
     79 * call, then the connection is marked to be killed at the next timeout
     80 * check.  This is how you should force-close the wsi being serviced if
     81 * you are doing it outside the callback (where you should close by nonzero
     82 * return).
     83 */
     84#define LWS_TO_KILL_SYNC -2
     85/**< If LWS_TO_KILL_SYNC is given as the timeout sec in a lws_set_timeout()
     86 * call, then the connection is closed before returning (which may delete
     87 * the wsi).  This should only be used where the wsi being closed is not the
     88 * wsi currently being serviced.
     89 */
     90/**
     91 * lws_set_timeout() - marks the wsi as subject to a timeout some seconds hence
     92 *
     93 * \param wsi:	Websocket connection instance
     94 * \param reason:	timeout reason
     95 * \param secs:	how many seconds.  You may set to LWS_TO_KILL_ASYNC to
     96 *		force the connection to timeout at the next opportunity, or
     97 *		LWS_TO_KILL_SYNC to close it synchronously if you know the
     98 *		wsi is not the one currently being serviced.
     99 */
    100LWS_VISIBLE LWS_EXTERN void
    101lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs);
    102
    103/**
    104 * lws_set_timeout_us() - marks the wsi as subject to a timeout some us hence
    105 *
    106 * \param wsi:	Websocket connection instance
    107 * \param reason:	timeout reason
    108 * \param us:	0 removes the timeout, otherwise number of us to wait
    109 *
    110 * Higher-resolution version of lws_set_timeout().  Actual resolution depends
    111 * on platform and load, usually ms.
    112 */
    113void
    114lws_set_timeout_us(struct lws *wsi, enum pending_timeout reason, lws_usec_t us);
    115
    116/* helper for clearer LWS_TO_KILL_ASYNC / LWS_TO_KILL_SYNC usage */
    117#define lws_wsi_close(w, to_kill) lws_set_timeout(w, 1, to_kill)
    118
    119
    120#define LWS_SET_TIMER_USEC_CANCEL ((lws_usec_t)-1ll)
    121#define LWS_USEC_PER_SEC ((lws_usec_t)1000000)
    122
    123/**
    124 * lws_set_timer_usecs() - schedules a callback on the wsi in the future
    125 *
    126 * \param wsi:	Websocket connection instance
    127 * \param usecs:  LWS_SET_TIMER_USEC_CANCEL removes any existing scheduled
    128 *		  callback, otherwise number of microseconds in the future
    129 *		  the callback will occur at.
    130 *
    131 * NOTE: event loop support for this:
    132 *
    133 *  default poll() loop:   yes
    134 *  libuv event loop:      yes
    135 *  libev:    not implemented (patch welcome)
    136 *  libevent: not implemented (patch welcome)
    137 *
    138 * After the deadline expires, the wsi will get a callback of type
    139 * LWS_CALLBACK_TIMER and the timer is exhausted.  The deadline may be
    140 * continuously deferred by further calls to lws_set_timer_usecs() with a later
    141 * deadline, or cancelled by lws_set_timer_usecs(wsi, -1).
    142 *
    143 * If the timer should repeat, lws_set_timer_usecs() must be called again from
    144 * LWS_CALLBACK_TIMER.
    145 *
    146 * Accuracy depends on the platform and the load on the event loop or system...
    147 * all that's guaranteed is the callback will come after the requested wait
    148 * period.
    149 */
    150LWS_VISIBLE LWS_EXTERN void
    151lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs);
    152
    153struct lws_sorted_usec_list;
    154
    155typedef void (*sul_cb_t)(struct lws_sorted_usec_list *sul);
    156
    157typedef struct lws_sorted_usec_list {
    158	struct lws_dll2 list;	/* simplify the code by keeping this at start */
    159	lws_usec_t	us;
    160	sul_cb_t	cb;
    161	uint32_t	latency_us;	/* us it may safely be delayed */
    162} lws_sorted_usec_list_t;
    163
    164/*
    165 * There are multiple sul owners to allow accounting for, a) events that must
    166 * wake from suspend, and b) events that can be missued due to suspend
    167 */
    168#define LWS_COUNT_PT_SUL_OWNERS			2
    169
    170#define LWSSULLI_MISS_IF_SUSPENDED		0
    171#define LWSSULLI_WAKE_IF_SUSPENDED		1
    172
    173/*
    174 * lws_sul2_schedule() - schedule a callback
    175 *
    176 * \param context: the lws_context
    177 * \param tsi: the thread service index (usually 0)
    178 * \param flags: LWSSULLI_...
    179 * \param sul: pointer to the sul element
    180 *
    181 * Generic callback-at-a-later time function.  The callback happens on the
    182 * event loop thread context.
    183 *
    184 * Although the api has us resultion, the actual resolution depends on the
    185 * platform and may be, eg, 1ms.
    186 *
    187 * This doesn't allocate and doesn't fail.
    188 *
    189 * If flags contains LWSSULLI_WAKE_IF_SUSPENDED, the scheduled event is placed
    190 * on a sul owner list that, if the system has entered low power suspend mode,
    191 * tries to arrange that the system should wake from platform suspend just
    192 * before the event is due.  Scheduled events without this flag will be missed
    193 * in the case the system is in suspend and nothing else happens to have woken
    194 * it.
    195 *
    196 * You can call it again with another us value to change the delay or move the
    197 * event to a different owner (ie, wake or miss on suspend).
    198 */
    199LWS_VISIBLE LWS_EXTERN void
    200lws_sul2_schedule(struct lws_context *context, int tsi, int flags,
    201		  lws_sorted_usec_list_t *sul);
    202
    203/*
    204 * lws_sul_cancel() - cancel scheduled callback
    205 *
    206 * \param sul: pointer to the sul element
    207 *
    208 * If it's scheduled, remove the sul from its owning sorted list.
    209 * If not scheduled, it's a NOP.
    210 */
    211LWS_VISIBLE LWS_EXTERN void
    212lws_sul_cancel(lws_sorted_usec_list_t *sul);
    213
    214/*
    215 * lws_sul_earliest_wakeable_event() - get earliest wake-from-suspend event
    216 *
    217 * \param ctx: the lws context
    218 * \param pearliest: pointer to lws_usec_t to take the result
    219 *
    220 * Either returns 1 if no pending event, or 0 and sets *pearliest to the
    221 * MONOTONIC time of the current earliest next expected event.
    222 */
    223LWS_VISIBLE LWS_EXTERN int
    224lws_sul_earliest_wakeable_event(struct lws_context *ctx, lws_usec_t *pearliest);
    225
    226/*
    227 * For backwards compatibility
    228 *
    229 * If us is LWS_SET_TIMER_USEC_CANCEL, the sul is removed from the scheduler.
    230 * New code can use lws_sul_cancel()
    231 */
    232
    233LWS_VISIBLE LWS_EXTERN void
    234lws_sul_schedule(struct lws_context *ctx, int tsi, lws_sorted_usec_list_t *sul,
    235		 sul_cb_t _cb, lws_usec_t _us);
    236LWS_VISIBLE LWS_EXTERN void
    237lws_sul_schedule_wakesuspend(struct lws_context *ctx, int tsi,
    238			     lws_sorted_usec_list_t *sul, sul_cb_t _cb,
    239			     lws_usec_t _us);
    240
    241#if defined(LWS_WITH_SUL_DEBUGGING)
    242/**
    243 * lws_sul_debug_zombies() - assert there are no scheduled sul in a given object
    244 *
    245 * \param ctx: lws_context
    246 * \param po: pointer to the object that is about to be destroyed
    247 * \param len: length of the object that is about to be destroyed
    248 * \param destroy_description: string clue what any failure is related to
    249 *
    250 * This is an optional debugging helper that walks the sul scheduler lists
    251 * confirming that there are no suls scheduled that live inside the object
    252 * footprint described by po and len.  When internal objects are about to be
    253 * destroyed, like wsi / user_data or secure stream handles, if
    254 * LWS_WITH_SUL_DEBUGGING is enabled the scheduler is checked for anything
    255 * in the object being destroyed.  If something found, an error is printed and
    256 * an assert fired.
    257 *
    258 * Internal sul like timeouts should always be cleaned up correctly, but user
    259 * suls in, eg, wsi user_data area, or in secure stream user allocation, may be
    260 * the cause of difficult to find bugs if valgrind not available and the user
    261 * code left a sul in the scheduler after destroying the object the sul was
    262 * living in.
    263 */
    264LWS_VISIBLE LWS_EXTERN void
    265lws_sul_debug_zombies(struct lws_context *ctx, void *po, size_t len,
    266		      const char *destroy_description);
    267#else
    268#define lws_sul_debug_zombies(_a, _b, _c, _d)
    269#endif
    270
    271/*
    272 * lws_validity_confirmed() - reset the validity timer for a network connection
    273 *
    274 * \param wsi: the connection that saw traffic proving the connection valid
    275 *
    276 * Network connections are subject to intervals defined by the context, the
    277 * vhost if server connections, or the client connect info if a client
    278 * connection.  If the connection goes longer than the specified time since
    279 * last observing traffic that can only happen if traffic is passing in both
    280 * directions, then lws will try to create a PING transaction on the network
    281 * connection.
    282 *
    283 * If the connection reaches the specified `.secs_since_valid_hangup` time
    284 * still without any proof of validity, the connection will be closed.
    285 *
    286 * If the PONG comes, or user code observes traffic that satisfies the proof
    287 * that both directions are passing traffic to the peer and calls this api,
    288 * the connection validity timer is reset and the scheme repeats.
    289 */
    290LWS_VISIBLE LWS_EXTERN void
    291lws_validity_confirmed(struct lws *wsi);
    292
    293/*
    294 * These are not normally needed, they're exported for the case there's code
    295 * using lws_sul for which lws is an optional link dependency.
    296 */
    297
    298LWS_VISIBLE LWS_EXTERN int
    299__lws_sul_insert(lws_dll2_owner_t *own, lws_sorted_usec_list_t *sul);
    300
    301LWS_VISIBLE LWS_EXTERN lws_usec_t
    302__lws_sul_service_ripe(lws_dll2_owner_t *own, int own_len, lws_usec_t usnow);
    303
    304///@}