1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-30 00:00:16 +01:00

ss: server: add foreach client cb api

Server SS maintains a list of accepted client ss, add an api allowing
iterating through the clients via a user callback.
This commit is contained in:
Andy Green 2020-11-10 11:27:28 +00:00
parent 0d31b7a154
commit 3216d4d087
9 changed files with 100 additions and 16 deletions

View file

@ -169,6 +169,13 @@
* (*rx) with the client stream's * (*rx) with the client stream's
*/ */
/** \defgroup secstr Secure Streams
* ##Secure Streams
*
* Secure Streams related apis
*/
///@{
#define LWS_SS_MTU 1540 #define LWS_SS_MTU 1540
struct lws_ss_handle; struct lws_ss_handle;
@ -362,7 +369,7 @@ typedef struct lws_ss_info {
* name from the policy * name from the policy
* *
* Requests a new secure stream described by \p ssi be created. If successful, * Requests a new secure stream described by \p ssi be created. If successful,
* the stream is created, its state callback called with LWSSSCS_CREATING, *ppss * the stream is created, its state callback called with LWSSSCS_CREATING, \p *ppss
* is set to point to the handle, and it returns 0. If it failed, it returns * is set to point to the handle, and it returns 0. If it failed, it returns
* nonzero. * nonzero.
* *
@ -396,7 +403,7 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
* *
* \param ppss: pointer to lws_ss_t pointer to be destroyed * \param ppss: pointer to lws_ss_t pointer to be destroyed
* *
* Destroys the lws_ss_t pointed to by *ppss, and sets *ppss to NULL. * Destroys the lws_ss_t pointed to by \p *ppss, and sets \p *ppss to NULL.
*/ */
LWS_VISIBLE LWS_EXTERN void LWS_VISIBLE LWS_EXTERN void
lws_ss_destroy(struct lws_ss_handle **ppss); lws_ss_destroy(struct lws_ss_handle **ppss);
@ -407,7 +414,7 @@ lws_ss_destroy(struct lws_ss_handle **ppss);
* \param pss: pointer to lws_ss_t representing stream that wants to transmit * \param pss: pointer to lws_ss_t representing stream that wants to transmit
* *
* Schedules a write on the stream represented by \p pss. When it's possible to * Schedules a write on the stream represented by \p pss. When it's possible to
* write on this stream, the *tx callback will occur with an empty buffer for * write on this stream, the \p *tx callback will occur with an empty buffer for
* the stream owner to fill in. * the stream owner to fill in.
* *
* Returns 0 or LWSSSSRET_SS_HANDLE_DESTROYED * Returns 0 or LWSSSSRET_SS_HANDLE_DESTROYED
@ -422,7 +429,7 @@ lws_ss_request_tx(struct lws_ss_handle *pss);
* \param len: the length of the write in bytes * \param len: the length of the write in bytes
* *
* Schedules a write on the stream represented by \p pss. When it's possible to * Schedules a write on the stream represented by \p pss. When it's possible to
* write on this stream, the *tx callback will occur with an empty buffer for * write on this stream, the \p *tx callback will occur with an empty buffer for
* the stream owner to fill in. * the stream owner to fill in.
* *
* This api variant should be used when it's possible the payload will go out * This api variant should be used when it's possible the payload will go out
@ -603,7 +610,7 @@ lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
* when the policy is using h1 is interpreted to add h1 headers of the given * when the policy is using h1 is interpreted to add h1 headers of the given
* name with the value of the metadata on the left. * name with the value of the metadata on the left.
* *
* Return 0 if *value and *len set OK, or nonzero if, eg, metadata name does * Return 0 if \p *value and \p *len set OK, or nonzero if, eg, metadata \p name does
* not exist on the streamtype. * not exist on the streamtype.
* *
* The pointed-to values may only exist until the next time around the event * The pointed-to values may only exist until the next time around the event
@ -613,7 +620,7 @@ LWS_VISIBLE LWS_EXTERN int
lws_ss_get_metadata(struct lws_ss_handle *h, const char *name, lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
const void **value, size_t *len); const void **value, size_t *len);
/* /**
* lws_ss_server_ack() - indicate how we feel about what the server has sent * lws_ss_server_ack() - indicate how we feel about what the server has sent
* *
* \param h: ss handle of accepted connection * \param h: ss handle of accepted connection
@ -635,6 +642,24 @@ lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
LWS_VISIBLE LWS_EXTERN void LWS_VISIBLE LWS_EXTERN void
lws_ss_server_ack(struct lws_ss_handle *h, int nack); lws_ss_server_ack(struct lws_ss_handle *h, int nack);
typedef void (*lws_sssfec_cb)(struct lws_ss_handle *h, void *arg);
/**
* lws_ss_server_foreach_client() - callback for each live client connected to server
*
* \param h: server ss handle
* \param cb: the callback
* \param arg: arg passed to callback
*
* For SERVER secure streams
*
* Call the callback \p cb once for each client ss connected to the server,
* passing \p arg as an additional callback argument each time.
*/
LWS_VISIBLE LWS_EXTERN void
lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb,
void *arg);
/** /**
* lws_ss_change_handlers() - helper for dynamically changing stream handlers * lws_ss_change_handlers() - helper for dynamically changing stream handlers
* *
@ -688,3 +713,6 @@ lws_ss_add_peer_tx_credit(struct lws_ss_handle *h, int32_t add);
*/ */
LWS_VISIBLE LWS_EXTERN int LWS_VISIBLE LWS_EXTERN int
lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h); lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h);
///@}

View file

@ -243,6 +243,8 @@ bail:
int int
lws_adopt_ss_server_accept(struct lws *new_wsi) lws_adopt_ss_server_accept(struct lws *new_wsi)
{ {
struct lws_context_per_thread *pt =
&new_wsi->a.context->pt[(int)new_wsi->tsi];
lws_ss_handle_t *h; lws_ss_handle_t *h;
void *pv, **ppv; void *pv, **ppv;
@ -284,13 +286,22 @@ lws_adopt_ss_server_accept(struct lws *new_wsi)
h->wsi = new_wsi; h->wsi = new_wsi;
new_wsi->a.opaque_user_data = h; new_wsi->a.opaque_user_data = h;
h->info.flags |= LWSSSINFLAGS_ACCEPTED; h->info.flags |= LWSSSINFLAGS_ACCEPTED;
new_wsi->for_ss = 1; /* indicate wsi should invalidate any ss link to it on close */ /* indicate wsi should invalidate any ss link to it on close */
new_wsi->for_ss = 1;
// lwsl_notice("%s: opaq %p, role %s\n", __func__, // lwsl_notice("%s: opaq %p, role %s\n", __func__,
// new_wsi->a.opaque_user_data, new_wsi->role_ops->name); // new_wsi->a.opaque_user_data, new_wsi->role_ops->name);
h->policy = new_wsi->a.vhost->ss_handle->policy; h->policy = new_wsi->a.vhost->ss_handle->policy;
/*
* add us to the list of clients that came in from the server
*/
lws_pt_lock(pt, __func__);
lws_dll2_add_tail(&h->cli_list, &new_wsi->a.vhost->ss_handle->src_list);
lws_pt_unlock(pt);
/* /*
* Let's give it appropriate state notifications * Let's give it appropriate state notifications
*/ */

View file

@ -43,8 +43,12 @@ typedef enum {
typedef struct lws_ss_handle { typedef struct lws_ss_handle {
lws_ss_info_t info; /**< copy of stream creation info */ lws_ss_info_t info; /**< copy of stream creation info */
struct lws_dll2 list; /**< pt lists active ss */ struct lws_dll2 list; /**< pt lists active ss */
struct lws_dll2 to_list; /**< pt lists ss with pending to-s */ struct lws_dll2 to_list; /**< pt lists ss with pending to-s */
#if defined(LWS_WITH_SERVER)
struct lws_dll2 cli_list; /**< same server clients list */
#endif
struct lws_dll2_owner src_list; /**< sink's list of bound sources */ struct lws_dll2_owner src_list; /**< sink's list of bound sources */

View file

@ -344,6 +344,9 @@ int
secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user, secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user,
void *in, size_t len) void *in, size_t len)
{ {
#if defined(LWS_WITH_SERVER)
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
#endif
lws_ss_handle_t *h = (lws_ss_handle_t *)lws_get_opaque_user_data(wsi); lws_ss_handle_t *h = (lws_ss_handle_t *)lws_get_opaque_user_data(wsi);
uint8_t buf[LWS_PRE + 1520], *p = &buf[LWS_PRE], uint8_t buf[LWS_PRE + 1520], *p = &buf[LWS_PRE],
#if defined(LWS_WITH_SERVER) #if defined(LWS_WITH_SERVER)
@ -393,6 +396,12 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user,
h->policy ? h->policy->streamtype : "no policy"); h->policy ? h->policy->streamtype : "no policy");
h->wsi = NULL; h->wsi = NULL;
#if defined(LWS_WITH_SERVER)
lws_pt_lock(pt, __func__);
lws_dll2_remove(&h->cli_list);
lws_pt_unlock(pt);
#endif
if (h->policy && !(h->policy->flags & LWSSSPOLF_OPPORTUNISTIC) && if (h->policy && !(h->policy->flags & LWSSSPOLF_OPPORTUNISTIC) &&
#if defined(LWS_WITH_SERVER) #if defined(LWS_WITH_SERVER)
!(h->info.flags & LWSSSINFLAGS_ACCEPTED) && /* not server */ !(h->info.flags & LWSSSINFLAGS_ACCEPTED) && /* not server */

View file

@ -30,6 +30,9 @@ int
secstream_raw(struct lws *wsi, enum lws_callback_reasons reason, void *user, secstream_raw(struct lws *wsi, enum lws_callback_reasons reason, void *user,
void *in, size_t len) void *in, size_t len)
{ {
#if defined(LWS_WITH_SERVER)
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
#endif
lws_ss_handle_t *h = (lws_ss_handle_t *)lws_get_opaque_user_data(wsi); lws_ss_handle_t *h = (lws_ss_handle_t *)lws_get_opaque_user_data(wsi);
uint8_t buf[LWS_PRE + 1520], *p = &buf[LWS_PRE], uint8_t buf[LWS_PRE + 1520], *p = &buf[LWS_PRE],
*end = &buf[sizeof(buf) - 1]; *end = &buf[sizeof(buf) - 1];
@ -61,6 +64,11 @@ secstream_raw(struct lws *wsi, enum lws_callback_reasons reason, void *user,
__func__, h, __func__, h,
h->policy ? h->policy->streamtype : "no policy"); h->policy ? h->policy->streamtype : "no policy");
h->wsi = NULL; h->wsi = NULL;
#if defined(LWS_WITH_SERVER)
lws_pt_lock(pt, __func__);
lws_dll2_remove(&h->cli_list);
lws_pt_unlock(pt);
#endif
if (h->policy && !(h->policy->flags & LWSSSPOLF_OPPORTUNISTIC) && if (h->policy && !(h->policy->flags & LWSSSPOLF_OPPORTUNISTIC) &&
#if defined(LWS_WITH_SERVER) #if defined(LWS_WITH_SERVER)
!(h->info.flags & LWSSSINFLAGS_ACCEPTED) && /* not server */ !(h->info.flags & LWSSSINFLAGS_ACCEPTED) && /* not server */

View file

@ -28,6 +28,9 @@ static int
secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user,
void *in, size_t len) void *in, size_t len)
{ {
#if defined(LWS_WITH_SERVER)
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
#endif
lws_ss_handle_t *h = (lws_ss_handle_t *)lws_get_opaque_user_data(wsi); lws_ss_handle_t *h = (lws_ss_handle_t *)lws_get_opaque_user_data(wsi);
uint8_t buf[LWS_PRE + 1400]; uint8_t buf[LWS_PRE + 1400];
lws_ss_state_return_t r; lws_ss_state_return_t r;
@ -65,6 +68,12 @@ secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user,
lws_set_opaque_user_data(h->wsi, NULL); lws_set_opaque_user_data(h->wsi, NULL);
h->wsi = NULL; h->wsi = NULL;
#if defined(LWS_WITH_SERVER)
lws_pt_lock(pt, __func__);
lws_dll2_remove(&h->cli_list);
lws_pt_unlock(pt);
#endif
if (reason == LWS_CALLBACK_CLIENT_CLOSED) { if (reason == LWS_CALLBACK_CLIENT_CLOSED) {
if (h->policy && if (h->policy &&
!(h->policy->flags & LWSSSPOLF_OPPORTUNISTIC) && !(h->policy->flags & LWSSSPOLF_OPPORTUNISTIC) &&

View file

@ -841,6 +841,9 @@ lws_ss_destroy(lws_ss_handle_t **ppss)
lws_pt_lock(pt, __func__); lws_pt_lock(pt, __func__);
*ppss = NULL; *ppss = NULL;
lws_dll2_remove(&h->list); lws_dll2_remove(&h->list);
#if defined(LWS_WITH_SERVER)
lws_dll2_remove(&h->cli_list);
#endif
lws_dll2_remove(&h->to_list); lws_dll2_remove(&h->to_list);
lws_sul_cancel(&h->sul_timeout); lws_sul_cancel(&h->sul_timeout);
@ -904,6 +907,19 @@ lws_ss_server_ack(struct lws_ss_handle *h, int nack)
h->txn_resp = nack; h->txn_resp = nack;
h->txn_resp_set = 1; h->txn_resp_set = 1;
} }
void
lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb,
void *arg)
{
lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, h->src_list.head) {
struct lws_ss_handle *h =
lws_container_of(d, struct lws_ss_handle, cli_list);
cb(h, arg);
} lws_end_foreach_dll_safe(d, d1);
}
#endif #endif
lws_ss_state_return_t lws_ss_state_return_t

View file

@ -28,7 +28,6 @@ INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8 TAB_SIZE = 8
ALIASES = ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_FOR_FORTRAN = NO
@ -117,7 +116,6 @@ INPUT = include/libwebsockets.h \
include/libwebsockets/lws-display.h \ include/libwebsockets/lws-display.h \
include/libwebsockets/lws-dll2.h \ include/libwebsockets/lws-dll2.h \
include/libwebsockets/lws-dsh.h \ include/libwebsockets/lws-dsh.h \
include/libwebsockets/lws-esp32.h \
include/libwebsockets/lws-eventlib-exports.h \ include/libwebsockets/lws-eventlib-exports.h \
include/libwebsockets/lws-freertos.h \ include/libwebsockets/lws-freertos.h \
include/libwebsockets/lws-fts.h \ include/libwebsockets/lws-fts.h \
@ -184,8 +182,6 @@ INPUT = include/libwebsockets.h \
./READMEs/README.crypto-apis.md \ ./READMEs/README.crypto-apis.md \
./READMEs/README.detailed-latency.md \ ./READMEs/README.detailed-latency.md \
./READMEs/README.esp32.md \ ./READMEs/README.esp32.md \
./READMEs/README.generic-sessions.md \
./READMEs/README.generic-table.md \
./READMEs/README.h2-long-poll.md \ ./READMEs/README.h2-long-poll.md \
./READMEs/README.http-fallback.md \ ./READMEs/README.http-fallback.md \
./READMEs/README.lws_dll.md \ ./READMEs/README.lws_dll.md \
@ -245,7 +241,7 @@ HTML_FILE_EXTENSION = .html
HTML_HEADER = HTML_HEADER =
HTML_FOOTER = HTML_FOOTER =
HTML_STYLESHEET = HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET = HTML_EXTRA_STYLESHEET = scripts/dox-extra.css
HTML_EXTRA_FILES = HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_SAT = 100
@ -376,12 +372,10 @@ GENERATE_TAGFILE =
ALLEXTERNALS = NO ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES EXTERNAL_PAGES = YES
PERL_PATH = /usr/bin/perl
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the dot tool # Configuration options related to the dot tool
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES CLASS_DIAGRAMS = YES
MSCGEN_PATH =
DIA_PATH = DIA_PATH =
HIDE_UNDOC_RELATIONS = YES HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO HAVE_DOT = NO

5
scripts/dox-extra.css Normal file
View file

@ -0,0 +1,5 @@
code {
text-color: #000000;
background-color: #f0f0a0;
}