mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-23 00:00:06 +01:00
152 lines
3.5 KiB
C
152 lines
3.5 KiB
C
/*
|
|
* lws System Fault Injection
|
|
*
|
|
* Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include "private-lib-core.h"
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
static lws_fi_priv_t *
|
|
lws_fi_lookup(lws_fi_ctx_t *fic, const char *name)
|
|
{
|
|
lws_start_foreach_dll(struct lws_dll2 *, p, fic->fi_owner.head) {
|
|
lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list);
|
|
|
|
if (!strcmp(pv->fi.name, name))
|
|
return pv;
|
|
|
|
} lws_end_foreach_dll(p);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int
|
|
lws_fi(lws_fi_ctx_t *fic, const char *name)
|
|
{
|
|
lws_fi_priv_t *pv = NULL;
|
|
|
|
do {
|
|
pv = lws_fi_lookup(fic, name);
|
|
|
|
if (pv) {
|
|
int n;
|
|
|
|
switch (pv->fi.type) {
|
|
case LWSFI_ALWAYS:
|
|
goto inject;
|
|
|
|
case LWSFI_DETERMINISTIC:
|
|
pv->fi.times++;
|
|
if (pv->fi.times >= pv->fi.pre)
|
|
if (pv->fi.times < pv->fi.pre + pv->fi.count)
|
|
goto inject;
|
|
return 0;
|
|
|
|
case LWSFI_PROBABILISTIC:
|
|
pv->fi.times = (unsigned long)(pv->fi.times * 3) ^
|
|
(unsigned long)lws_now_usecs();
|
|
if ((uint16_t)pv->fi.times % 101 >= pv->fi.pre)
|
|
goto inject;
|
|
return 0;
|
|
|
|
case LWSFI_PATTERN:
|
|
n = (int)(pv->fi.times % pv->fi.pre);
|
|
if (pv->fi.pattern[n >> 3] & (1 << (n & 7)))
|
|
goto inject;
|
|
|
|
return 0;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
fic = fic->parent;
|
|
} while (fic);
|
|
|
|
return 0;
|
|
|
|
inject:
|
|
lwsl_warn("%s: Injecting fault %s->%s\n", __func__, fic->name,
|
|
pv->fi.name);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
lws_fi_add(lws_fi_ctx_t *fic, const lws_fi_t *fi)
|
|
{
|
|
lws_fi_priv_t *pv;
|
|
size_t n = strlen(fi->name);
|
|
|
|
pv = lws_malloc(sizeof(*pv) + n + 1, __func__);
|
|
if (!pv)
|
|
return 1;
|
|
|
|
lws_dll2_clear(&pv->list);
|
|
|
|
memcpy(&pv->fi, fi, sizeof(*fi));
|
|
pv->fi.name = (const char *)&pv[1];
|
|
memcpy(&pv[1], fi->name, n + 1);
|
|
|
|
lws_dll2_add_tail(&pv->list, &fic->fi_owner);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
lws_fi_remove(lws_fi_ctx_t *fic, const char *name)
|
|
{
|
|
lws_fi_priv_t *pv = lws_fi_lookup(fic, name);
|
|
|
|
if (!pv)
|
|
return;
|
|
|
|
lws_dll2_remove(&pv->list);
|
|
lws_free(pv);
|
|
}
|
|
|
|
void
|
|
lws_fi_import(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src)
|
|
{
|
|
lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1, fic_src->fi_owner.head) {
|
|
lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list);
|
|
|
|
lws_dll2_remove(&pv->list);
|
|
lws_dll2_add_tail(&pv->list, &fic_dest->fi_owner);
|
|
|
|
} lws_end_foreach_dll_safe(p, p1);
|
|
}
|
|
|
|
void
|
|
lws_fi_destroy(lws_fi_ctx_t *fic)
|
|
{
|
|
lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1, fic->fi_owner.head) {
|
|
lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list);
|
|
|
|
lws_dll2_remove(&pv->list);
|
|
lws_free(pv);
|
|
|
|
} lws_end_foreach_dll_safe(p, p1);
|
|
}
|