1*1c60b9acSAndroid Build Coastguard Worker# `lws_fi` Fault Injection 2*1c60b9acSAndroid Build Coastguard Worker 3*1c60b9acSAndroid Build Coastguard WorkerMost efforts during development go towards trying to make the system do what 4*1c60b9acSAndroid Build Coastguard Workerit is supposed to do during normal operation. 5*1c60b9acSAndroid Build Coastguard Worker 6*1c60b9acSAndroid Build Coastguard WorkerBut to provide reliable quality there's a need to not just test the code paths 7*1c60b9acSAndroid Build Coastguard Workerfor normal operation, but also to be able to easily confirm that they act 8*1c60b9acSAndroid Build Coastguard Workercorrectly under various fault conditions that may be difficult to arrange at 9*1c60b9acSAndroid Build Coastguard Workertest-time. It's otherwise very easy for error conditions that are low 10*1c60b9acSAndroid Build Coastguard Workerprobability to be overlooked and turn out to do the wrong thing, eg, try to 11*1c60b9acSAndroid Build Coastguard Workerclean up things they had not actually initialized, or forget to free things etc. 12*1c60b9acSAndroid Build Coastguard Worker 13*1c60b9acSAndroid Build Coastguard WorkerCode handling the operational failures we want to check may be anywhere, 14*1c60b9acSAndroid Build Coastguard Workerincluding during early initialization or in user code before lws intialization. 15*1c60b9acSAndroid Build Coastguard Worker 16*1c60b9acSAndroid Build Coastguard WorkerTo help with this lws has a `LWS_WITH_SYS_FAULT_INJECTION` build option that 17*1c60b9acSAndroid Build Coastguard Workerprovides a simple but powerful api for targeted fault injection in any lws or 18*1c60b9acSAndroid Build Coastguard Workeruser code, and provides a wide range of well-known internal faults inside lws 19*1c60b9acSAndroid Build Coastguard Workeryou can trigger from outside. 20*1c60b9acSAndroid Build Coastguard Worker 21*1c60b9acSAndroid Build Coastguard Worker## Fault contexts and faults 22*1c60b9acSAndroid Build Coastguard Worker 23*1c60b9acSAndroid Build Coastguard WorkerThe basic idea is objects in the user code can choose to initialize "fault 24*1c60b9acSAndroid Build Coastguard Workercontexts" inside objects, that list named, well-known "faults" that the code 25*1c60b9acSAndroid Build Coastguard Workersupoorts and that the user wants to inject. 26*1c60b9acSAndroid Build Coastguard Worker 27*1c60b9acSAndroid Build Coastguard WorkerAlthough these "fault contexts" can be embedded in objects directly at object 28*1c60b9acSAndroid Build Coastguard Workercreation time, eg, for lws in the lws_context creation info struct, or the 29*1c60b9acSAndroid Build Coastguard Workerclient connection info struct, or Secure Stream info struct, it's usually 30*1c60b9acSAndroid Build Coastguard Workerinconvenient to pass the desired faults directly deep into the code and attach 31*1c60b9acSAndroid Build Coastguard Workerthem at creation time. Eg, if you want to cause a fault in a wsi instantiated 32*1c60b9acSAndroid Build Coastguard Workerby a Secure Stream, that is internal lws code one step removed from the Secure 33*1c60b9acSAndroid Build Coastguard WorkerStream object creation making it difficult to arrange. 34*1c60b9acSAndroid Build Coastguard Worker 35*1c60b9acSAndroid Build Coastguard WorkerFor that reason, faults have a targeted inheritance scheme using namespace 36*1c60b9acSAndroid Build Coastguard Workerpaths, it's usually enough to just list the faults you want at context creation 37*1c60b9acSAndroid Build Coastguard Workertime and they will be filter down to the internal objects you want to target 38*1c60b9acSAndroid Build Coastguard Workerwhen they are created later. 39*1c60b9acSAndroid Build Coastguard Worker 40*1c60b9acSAndroid Build Coastguard Worker 41*1c60b9acSAndroid Build Coastguard Worker 42*1c60b9acSAndroid Build Coastguard WorkerA fault injection request is made in `lws_fi_t` objects, specifying the 43*1c60b9acSAndroid Build Coastguard Workerfault name and whether, and how often to inject the fault. 44*1c60b9acSAndroid Build Coastguard Worker 45*1c60b9acSAndroid Build Coastguard WorkerThe "fault context" objects `lws_fi_ctx_t` embedded in the creation info 46*1c60b9acSAndroid Build Coastguard Workerstructs are linked-lists of `lws_fi_t` objects. When Fault Injection is enabled 47*1c60b9acSAndroid Build Coastguard Workerat build-time, the key system objects like the `lws_context`, `lws_vhost`, `wsi` 48*1c60b9acSAndroid Build Coastguard Workerand Secure Stream handles / SSPC handles contain their own `lws_fi_ctx_t` lists 49*1c60b9acSAndroid Build Coastguard Workerthat may have any number of `lws_fi_t` added to them. 50*1c60b9acSAndroid Build Coastguard Worker 51*1c60b9acSAndroid Build Coastguard WorkerWhen downstream objects are created, eg, when an lws_context creates a Secure 52*1c60b9acSAndroid Build Coastguard WorkerStream, in addition to using any faults provided directly in the SS info, 53*1c60b9acSAndroid Build Coastguard Workerthe lws_context faults are consulted to see if any relate to that streamtype 54*1c60b9acSAndroid Build Coastguard Workerand should be applied. 55*1c60b9acSAndroid Build Coastguard Worker 56*1c60b9acSAndroid Build Coastguard WorkerAlthough faults can be added to objects at creation, it is far more convenient 57*1c60b9acSAndroid Build Coastguard Workerto just pass a list of faults you want into the lws_context and have the 58*1c60b9acSAndroid Build Coastguard Workerobjects later match them using namespacing, described later. 59*1c60b9acSAndroid Build Coastguard Worker 60*1c60b9acSAndroid Build Coastguard Worker## Integrating fault injection conditionals into code in private lws code 61*1c60b9acSAndroid Build Coastguard Worker 62*1c60b9acSAndroid Build Coastguard WorkerA simple query api `lws_fi(fi_ctx, "name")` is provided that returns 0 if no 63*1c60b9acSAndroid Build Coastguard Workerfault to be injected, or 1 if the fault should be synthesized. If there is no 64*1c60b9acSAndroid Build Coastguard Workerrule matching "name", the answer is always to not inject a fault, ie, returns 0. 65*1c60b9acSAndroid Build Coastguard Worker 66*1c60b9acSAndroid Build Coastguard WorkerSimilarly for convenience if FAULT_INJECTION is disabled at build, the `lws_fi()` 67*1c60b9acSAndroid Build Coastguard Workercall always returns the constant `0`. 68*1c60b9acSAndroid Build Coastguard Worker 69*1c60b9acSAndroid Build Coastguard WorkerBy default then just enabling Fault Injection at build does not have any impact 70*1c60b9acSAndroid Build Coastguard Workeron code operation since the user must also add the fault injection rules he 71*1c60b9acSAndroid Build Coastguard Workerwants to the objects's Fault Injection context. 72*1c60b9acSAndroid Build Coastguard Worker 73*1c60b9acSAndroid Build Coastguard Worker## Integrating fault injection conditionals into user code with public apis 74*1c60b9acSAndroid Build Coastguard Worker 75*1c60b9acSAndroid Build Coastguard WorkerThese public apis query the fault context in a wsi, lws_context, ss handle, or 76*1c60b9acSAndroid Build Coastguard Workersspc handle (client side of proxy) to find any matching rule, if so they return 77*1c60b9acSAndroid Build Coastguard Worker1 if the conditions (eg, probability) are met and the fault should be injected. 78*1c60b9acSAndroid Build Coastguard Worker 79*1c60b9acSAndroid Build Coastguard WorkerThese allow user code to use the whole Fault Injection system without having to 80*1c60b9acSAndroid Build Coastguard Workerunderstand anything except the common object like a wsi they want to query and 81*1c60b9acSAndroid Build Coastguard Workerthe name of the fault rule they are checking. 82*1c60b9acSAndroid Build Coastguard Worker 83*1c60b9acSAndroid Build Coastguard Worker|FI context owner|Public API| 84*1c60b9acSAndroid Build Coastguard Worker|---|---| 85*1c60b9acSAndroid Build Coastguard Worker|lws_context|`int lws_fi_user_context_fi(struct lws_context *ctx, const char *rule)`| 86*1c60b9acSAndroid Build Coastguard Worker|wsi|`int lws_fi_user_wsi_fi(struct lws *wsi, const char *rule)`| 87*1c60b9acSAndroid Build Coastguard Worker|ss handle|`int lws_fi_user_ss_fi(struct lws_ss_handle *h, const char *rule)`| 88*1c60b9acSAndroid Build Coastguard Worker|sspc handle|`int lws_fi_user_sspc_fi(struct lws_sspc_handle *h, const char *rule)`| 89*1c60b9acSAndroid Build Coastguard Worker 90*1c60b9acSAndroid Build Coastguard WorkerFor example, the minimal-http-client user code example contains this in its 91*1c60b9acSAndroid Build Coastguard WorkerESTABLISHED callback 92*1c60b9acSAndroid Build Coastguard Worker 93*1c60b9acSAndroid Build Coastguard Worker``` 94*1c60b9acSAndroid Build Coastguard Worker if (lws_fi_user_wsi_fi(wsi, "user_reject_at_est")) 95*1c60b9acSAndroid Build Coastguard Worker return -1; 96*1c60b9acSAndroid Build Coastguard Worker``` 97*1c60b9acSAndroid Build Coastguard Worker 98*1c60b9acSAndroid Build Coastguard Workerwhich can be triggered by running it with 99*1c60b9acSAndroid Build Coastguard Worker 100*1c60b9acSAndroid Build Coastguard Worker`lws-minimal-http-client --fault-injection 'wsi/user_reject_at_est'`, causing 101*1c60b9acSAndroid Build Coastguard Worker 102*1c60b9acSAndroid Build Coastguard Worker``` 103*1c60b9acSAndroid Build Coastguard Worker... 104*1c60b9acSAndroid Build Coastguard Worker[2021/03/11 13:41:05:2769] U: Connected to 46.105.127.147, http response: 200 105*1c60b9acSAndroid Build Coastguard Worker[2021/03/11 13:41:05:2776] W: lws_fi: Injecting fault unk->user_reject_at_est 106*1c60b9acSAndroid Build Coastguard Worker[2021/03/11 13:41:05:2789] E: CLIENT_CONNECTION_ERROR: HS: disallowed at ESTABLISHED 107*1c60b9acSAndroid Build Coastguard Worker... 108*1c60b9acSAndroid Build Coastguard Worker``` 109*1c60b9acSAndroid Build Coastguard Worker 110*1c60b9acSAndroid Build Coastguard WorkerWhen `LWS_WITH_SYS_FAULT_INJECTION` is disabled, these public apis become 111*1c60b9acSAndroid Build Coastguard Workerpreprocessor defines to `(0)`, so the related code is removed by the compiler. 112*1c60b9acSAndroid Build Coastguard Worker 113*1c60b9acSAndroid Build Coastguard Worker## Types of fault injection "when" strategy 114*1c60b9acSAndroid Build Coastguard Worker 115*1c60b9acSAndroid Build Coastguard WorkerThe api keeps track of each time the context was asked and uses this information 116*1c60b9acSAndroid Build Coastguard Workerto drive the decision about when to say yes, according to the type of rule 117*1c60b9acSAndroid Build Coastguard Worker 118*1c60b9acSAndroid Build Coastguard Worker|Injection rule type|Description| 119*1c60b9acSAndroid Build Coastguard Worker|---|---| 120*1c60b9acSAndroid Build Coastguard Worker|`LWSFI_ALWAYS`|Unconditionally inject the fault| 121*1c60b9acSAndroid Build Coastguard Worker|`LWSFI_DETERMINISTIC`|after `pre` times without the fault, the next `count` times exhibit the fault`| 122*1c60b9acSAndroid Build Coastguard Worker|`LWSFI_PROBABILISTIC`|exhibit a fault `pre` percentage of the time| 123*1c60b9acSAndroid Build Coastguard Worker|`LWSFI_PATTERN`|Reference `pre` bits pointed to by `pattern` and fault if the bit set, pointing to static array| 124*1c60b9acSAndroid Build Coastguard Worker|`LWSFI_PATTERN_ALLOC`|Reference `pre` bits pointed to by `pattern` and fault if the bit set, pointing to allocated array, freed when fault goes out of scope| 125*1c60b9acSAndroid Build Coastguard Worker 126*1c60b9acSAndroid Build Coastguard WorkerProbabalistic choices are sourced from a PRNG with a seed set in the context 127*1c60b9acSAndroid Build Coastguard Workercreation info Fault Injection Context. By default the lws helper 128*1c60b9acSAndroid Build Coastguard Worker`lws_cmdline_option_handle_builtin()` sets this to the time in us, but it can 129*1c60b9acSAndroid Build Coastguard Workerbe overridden using `--fault-seed <decimal>`, and the effective PRNG seed is 130*1c60b9acSAndroid Build Coastguard Workerlogged when the commandline options are initially parsed. 131*1c60b9acSAndroid Build Coastguard Worker 132*1c60b9acSAndroid Build Coastguard Worker## Addings Fault Injection Rules to `lws_fi_ctx_t` 133*1c60b9acSAndroid Build Coastguard Worker 134*1c60b9acSAndroid Build Coastguard WorkerTypically the lws_context is used as the central, toplevel place to define 135*1c60b9acSAndroid Build Coastguard Workerfaults. This is done by adding prepared `lws_fi_t` objects on the stack one by 136*1c60b9acSAndroid Build Coastguard Workerone to the context creation info struct's `.fic` member, using 137*1c60b9acSAndroid Build Coastguard Worker`lws_fi_add(lws_fi_ctx_t *fic, const lws_fi_t *fi);`, this will allocate and copy 138*1c60b9acSAndroid Build Coastguard Workerthe provided `fi` into the allocation, and attach it to the `lws_fi_ctx_t` list. 139*1c60b9acSAndroid Build Coastguard Worker 140*1c60b9acSAndroid Build Coastguard WorkerWhen the context (or other object using the same scheme) is created, it imports 141*1c60b9acSAndroid Build Coastguard Workerall the faults from the info structure `.fic` and takes ownership of them, 142*1c60b9acSAndroid Build Coastguard Workerleaving the info `.fic` empty and ready to go out of scope. 143*1c60b9acSAndroid Build Coastguard Worker 144*1c60b9acSAndroid Build Coastguard Worker## Passing in fault injection rules 145*1c60b9acSAndroid Build Coastguard Worker 146*1c60b9acSAndroid Build Coastguard WorkerA key requirement is that Fault Injection rules must be availble to the code 147*1c60b9acSAndroid Build Coastguard Workercreating an object before the object has been created. This is why the user 148*1c60b9acSAndroid Build Coastguard Workercode prepares a Fault Injection context listing his rules in the creation info 149*1c60b9acSAndroid Build Coastguard Workerstruct, rather than waiting for the object to be created and then attach Fault 150*1c60b9acSAndroid Build Coastguard WorkerInjection rules... it's too late then to test faults during the creation. 151*1c60b9acSAndroid Build Coastguard Worker 152*1c60b9acSAndroid Build Coastguard Worker## Directly applying fault contexts 153*1c60b9acSAndroid Build Coastguard Worker 154*1c60b9acSAndroid Build Coastguard WorkerYou can pass in a Fault Injection context prepared with lws_fi_t added to it 155*1c60b9acSAndroid Build Coastguard Workerwhen creating the following kinds of objects 156*1c60b9acSAndroid Build Coastguard Worker 157*1c60b9acSAndroid Build Coastguard Worker|Object being created|info struct|Fault injection Context member| 158*1c60b9acSAndroid Build Coastguard Worker|---|---|---| 159*1c60b9acSAndroid Build Coastguard Worker|lws context|struct lws_context_creation_info|`fic`| 160*1c60b9acSAndroid Build Coastguard Worker|vhost|struct lws_context_creation_info|`fic`| 161*1c60b9acSAndroid Build Coastguard Worker|Secure Stream|struct lws_ss_info|`fic`| 162*1c60b9acSAndroid Build Coastguard Worker|client wsi|struct lws_client_connect_info|`fic`| 163*1c60b9acSAndroid Build Coastguard Worker 164*1c60b9acSAndroid Build Coastguard WorkerHowever typically the approach is just provide a list of faults at context 165*1c60b9acSAndroid Build Coastguard Workercreation time, and let the objects match and inherit using namespacing, 166*1c60b9acSAndroid Build Coastguard Workerdescribed next. 167*1c60b9acSAndroid Build Coastguard Worker 168*1c60b9acSAndroid Build Coastguard Worker## Using the namespace to target specific instances 169*1c60b9acSAndroid Build Coastguard Worker 170*1c60b9acSAndroid Build Coastguard WorkerLws objects created by the user can directly have a Fault Injection context 171*1c60b9acSAndroid Build Coastguard Workerattached to them at creation time, so the fault injection objects directly 172*1c60b9acSAndroid Build Coastguard Workerrelate to the object. 173*1c60b9acSAndroid Build Coastguard Worker 174*1c60b9acSAndroid Build Coastguard WorkerBut in other common scenarios, there is no direct visibility of the object that 175*1c60b9acSAndroid Build Coastguard Workerwe want to trigger faults in, it may not exist until some time later. Eg, we 176*1c60b9acSAndroid Build Coastguard Workerwant to trigger faults in the listen socket of a vhost. To allow this, the 177*1c60b9acSAndroid Build Coastguard Workerfault names can be structured with a /path/ type namespace so objects created 178*1c60b9acSAndroid Build Coastguard Workerlater can inherit faults. 179*1c60b9acSAndroid Build Coastguard Worker 180*1c60b9acSAndroid Build Coastguard WorkerNotice that if you are directly creating the vhost, Secure Stream or wsi, you 181*1c60b9acSAndroid Build Coastguard Workercan directly attach the subrule yourself without the namespacing needed. The 182*1c60b9acSAndroid Build Coastguard Workernamespacing is used when you have access to a higher level object at creation- 183*1c60b9acSAndroid Build Coastguard Workertime, like the lws_context, and it will itself create the object you want to 184*1c60b9acSAndroid Build Coastguard Workertarget without your having any direct access to it. 185*1c60b9acSAndroid Build Coastguard Worker 186*1c60b9acSAndroid Build Coastguard Worker|namespace form|effect| 187*1c60b9acSAndroid Build Coastguard Worker|---|---| 188*1c60b9acSAndroid Build Coastguard Worker|**vh=myvhost/**subrule|subrule is inherited by the vhost named "myvhost" when it is created| 189*1c60b9acSAndroid Build Coastguard Worker|**vh/**subrule|subrule is inherited by any vhost when it is created| 190*1c60b9acSAndroid Build Coastguard Worker|**ss=mystream/**subrule|subrule is inherited by SS of streamtype "mystream" (also covers SSPC / proxy client)| 191*1c60b9acSAndroid Build Coastguard Worker|**ss/**subrule|subrule is inherited by all SS of any streamtype (also covers SSPC / proxy client)| 192*1c60b9acSAndroid Build Coastguard Worker|**wsi=myname/**subrule|subrule is inherited by client wsi created with `info->fi_wsi_name` "myname"| 193*1c60b9acSAndroid Build Coastguard Worker|**wsi/**subrule|subrule is inherited by any wsi| 194*1c60b9acSAndroid Build Coastguard Worker 195*1c60b9acSAndroid Build Coastguard WorkerNamespaces can be combined, for example `vh=myvhost/wsi/listenskt` will set the 196*1c60b9acSAndroid Build Coastguard Worker`listenskt` fault on wsi created by the server vhost "myvhost", ie, it will 197*1c60b9acSAndroid Build Coastguard Workercause the listen socket for the vhost to error out on creation. 198*1c60b9acSAndroid Build Coastguard Worker 199*1c60b9acSAndroid Build Coastguard WorkerIn the case of wsi migration when it's the network connection wsi on an h2 200*1c60b9acSAndroid Build Coastguard Workerconnection that is migrated to be SID 1, the attached faults also migrate. 201*1c60b9acSAndroid Build Coastguard Worker 202*1c60b9acSAndroid Build Coastguard WorkerHere is which Fault Injection Contexts each type of object inherits matching 203*1c60b9acSAndroid Build Coastguard WorkerFault Injection rules from: 204*1c60b9acSAndroid Build Coastguard Worker 205*1c60b9acSAndroid Build Coastguard Worker|Object type|Initialized with|Inherit matching faults from| 206*1c60b9acSAndroid Build Coastguard Worker|---|---|---| 207*1c60b9acSAndroid Build Coastguard Worker|context|`struct lws_context_creation_info` .fic|-| 208*1c60b9acSAndroid Build Coastguard Worker|vhost|`struct lws_context_creation_info` .fic|context FIC| 209*1c60b9acSAndroid Build Coastguard Worker|client wsi|`struct lws_client_connect_info` .fic|context FIC, vhost FIC| 210*1c60b9acSAndroid Build Coastguard Worker|ss / sspc|`lws_ss_info_t` .fic|context FIC| 211*1c60b9acSAndroid Build Coastguard Worker|ss / sspc wsi|-|context FIC, vhost FIC, ss / sspc .fic| 212*1c60b9acSAndroid Build Coastguard Worker 213*1c60b9acSAndroid Build Coastguard WorkerSince everything can be reached from the lws_context fault context, directly or 214*1c60b9acSAndroid Build Coastguard Workerby additional inheritence, and that's the most convenient to set from the 215*1c60b9acSAndroid Build Coastguard Workeroutside, that's typically the original source of all injected faults. 216*1c60b9acSAndroid Build Coastguard Worker 217*1c60b9acSAndroid Build Coastguard Worker## Integration with minimal examples 218*1c60b9acSAndroid Build Coastguard Worker 219*1c60b9acSAndroid Build Coastguard WorkerAll the minimal examples that use the `lws_cmdline_option_handle_builtin()` api 220*1c60b9acSAndroid Build Coastguard Workercan take an additional `--fault-injection "...,..."` switch, which automatically 221*1c60b9acSAndroid Build Coastguard Workerparses the comma-separated list in the argument to add faults with the given 222*1c60b9acSAndroid Build Coastguard Workername to the lws_context. For example, 223*1c60b9acSAndroid Build Coastguard Worker 224*1c60b9acSAndroid Build Coastguard Worker`lws-minimal-http-client --fault-injection "wsi/dnsfail"` 225*1c60b9acSAndroid Build Coastguard Worker 226*1c60b9acSAndroid Build Coastguard Workerwill force all wsi dns lookups to fail for that run of the example. 227*1c60b9acSAndroid Build Coastguard Worker 228*1c60b9acSAndroid Build Coastguard Worker### Specifying when to inject the fault 229*1c60b9acSAndroid Build Coastguard Worker 230*1c60b9acSAndroid Build Coastguard WorkerBy default, if you just give the name part, if the namespace is absent or 231*1c60b9acSAndroid Build Coastguard Workermatches an object, the fault will be injected every time. It's also possible 232*1c60b9acSAndroid Build Coastguard Workerto make the fault inject itself at a random probability, or in a cyclic pattern, 233*1c60b9acSAndroid Build Coastguard Workerby giving additional information in brackets, eg 234*1c60b9acSAndroid Build Coastguard Worker 235*1c60b9acSAndroid Build Coastguard Worker|Syntax|Used with|Meaning| 236*1c60b9acSAndroid Build Coastguard Worker|---|---|---| 237*1c60b9acSAndroid Build Coastguard Worker|`wsi/thefault`|lws_fi()|Inject the fault every time| 238*1c60b9acSAndroid Build Coastguard Worker|`wsi/thefault(10%)`|lws_fi()|Randomly inject the fault at 10% probability| 239*1c60b9acSAndroid Build Coastguard Worker|`wsi/thefault(.............X.X)`|lws_fi()|Inject the fault on the 14th and 16th try, every 16 tries| 240*1c60b9acSAndroid Build Coastguard Worker|`wsi/thefault2(123..456)`|lws_fi_range()|Pick a number between 123 and 456| 241*1c60b9acSAndroid Build Coastguard Worker 242*1c60b9acSAndroid Build Coastguard WorkerYou must quote the strings containing these symbols, since they may otherwise be 243*1c60b9acSAndroid Build Coastguard Workerinterpreted by your shell. 244*1c60b9acSAndroid Build Coastguard Worker 245*1c60b9acSAndroid Build Coastguard WorkerThe last example above does not decide whether to inject the fault via `lws_fi()` 246*1c60b9acSAndroid Build Coastguard Workerlike the others. Instead you can use it via `lws_fi_range()` as part of the 247*1c60b9acSAndroid Build Coastguard Workerfault processing, on a secondary fault injection name. For example you may have 248*1c60b9acSAndroid Build Coastguard Workera fault `myfault` you use with `lws_fi()` to decide when to inject the fault, 249*1c60b9acSAndroid Build Coastguard Workerand then a second, related fault name `myfault_delay` to allow you to add code 250*1c60b9acSAndroid Build Coastguard Workerto delay the fault action by some random amount of ms within an externally- 251*1c60b9acSAndroid Build Coastguard Workergiven range. You can get a pseudo-random number within the externally-given 252*1c60b9acSAndroid Build Coastguard Workerrange by calling `lws_fi_range()` on `myfault_delay`, and control the whole 253*1c60b9acSAndroid Build Coastguard Workerthing by giving, eg, `"myfault(10%),myfault_delay(123..456)"` 254*1c60b9acSAndroid Build Coastguard Worker 255*1c60b9acSAndroid Build Coastguard Worker## Well-known fault names in lws 256*1c60b9acSAndroid Build Coastguard Worker 257*1c60b9acSAndroid Build Coastguard Worker|Scope|Namespc|Name|Fault effect| 258*1c60b9acSAndroid Build Coastguard Worker|---|---|---|---| 259*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail1`|Fail context creation immediately at entry| 260*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_plugin_init`|Fail context creation as if a plugin init failed (if plugins enabled)| 261*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_evlib_plugin`|Fail context creation due to event lib plugin failed init (if evlib plugins enabled)| 262*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_evlib_sel`|Fail context creation due to unable to select event lib| 263*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_oom_ctx`|Fail context creation due to OOM on context object| 264*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_privdrop`|Fail context creation due to failure dropping privileges| 265*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_maxfds`|Fail context creation due to unable to determine process fd limit| 266*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_oom_fds`|Fail context creation due to OOM on fds table| 267*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_plat_init`|Fail context creation due to platform init failed| 268*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_evlib_init`|Fail context creation due to event lib init failed| 269*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_evlib_pt`|Fail context creation due to event lib pt init failed| 270*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_sys_vh`|Fail context creation due to system vhost creation failed| 271*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_sys_vh_init`|Fail context creaton due to system vhost init failed| 272*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_def_vh`|Fail context creation due to default vhost creation failed| 273*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_ss_pol1`|Fail context creation due to ss policy parse start failed (if policy enabled)| 274*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_ss_pol2`|Fail context creation due to ss policy parse failed (if policy enabled)| 275*1c60b9acSAndroid Build Coastguard Worker|context||`ctx_createfail_ss_pol3`|Fail context creation due to ss policy set failed (if policy enabled)| 276*1c60b9acSAndroid Build Coastguard Worker|context||`cache_createfail`|Fail `lws_cache` creation due to OOM| 277*1c60b9acSAndroid Build Coastguard Worker|context||`cache_lookup_oom`|Fail `lws_cache` lookup due to OOM| 278*1c60b9acSAndroid Build Coastguard Worker|vhost|`vh`|`vh_create_oom`|Fail vh creation on vh object alloc OOM| 279*1c60b9acSAndroid Build Coastguard Worker|vhost|`vh`|`vh_create_oom`|Fail vh creation on vh object alloc OOM| 280*1c60b9acSAndroid Build Coastguard Worker|vhost|`vh`|`vh_create_pcols_oom`|Fail vh creation at protocols alloc OOM| 281*1c60b9acSAndroid Build Coastguard Worker|vhost|`vh`|`vh_create_access_log_open_fail`|Fail vh creation due to unable to open access log (LWS_WITH_ACCESS_LOG)| 282*1c60b9acSAndroid Build Coastguard Worker|vhost|`vh`|`vh_create_ssl_srv`|Fail server ssl_ctx init| 283*1c60b9acSAndroid Build Coastguard Worker|vhost|`vh`|`vh_create_ssl_cli`|Fail client ssl_ctx init| 284*1c60b9acSAndroid Build Coastguard Worker|vhost|`vh`|`vh_create_srv_init`|Fail server init| 285*1c60b9acSAndroid Build Coastguard Worker|vhost|`vh`|`vh_create_protocol_init`|Fail late protocol init (for late vhost creation)| 286*1c60b9acSAndroid Build Coastguard Worker|srv vhost|`vh=xxx/wsi`|`listenskt`|Causes `socket()` allocation for vhost listen socket to fail| 287*1c60b9acSAndroid Build Coastguard Worker|cli wsi|`wsi`|`dnsfail`|Sync: `getaddrinfo()` is not called and a EAI_FAIL return synthesized, Async: request not started and immediate fail synthesized| 288*1c60b9acSAndroid Build Coastguard Worker|cli wsi|`wsi`|`sendfail`|Attempts to send data on the wsi socket fail| 289*1c60b9acSAndroid Build Coastguard Worker|cli wsi|`wsi`|`connfail`|Attempts to connect on the wsi socket fail| 290*1c60b9acSAndroid Build Coastguard Worker|cli wsi|`wsi`|`createfail`|Creating the client wsi itself fails| 291*1c60b9acSAndroid Build Coastguard Worker|udp wsi|`wsi`|`udp_rx_loss`|Drop UDP RX that was actually received, useful with probabalistic mode| 292*1c60b9acSAndroid Build Coastguard Worker|udp wsi|`wsi`|`udp_tx_loss`|Drop UDP TX so that it's not actually sent, useful with probabalistic mode| 293*1c60b9acSAndroid Build Coastguard Worker|srv ss|`ss`|`ss_srv_vh_fail`|Secure Streams Server vhost creation forced to fail| 294*1c60b9acSAndroid Build Coastguard Worker|cli ss|`ss`|`ss_no_streamtype_policy`|The policy for the streamtype is made to seem as if it is missing| 295*1c60b9acSAndroid Build Coastguard Worker|sspc|`ss`|`sspc_fail_on_linkup`|Reject the connection to the proxy when we hear it has succeeded, it will provoke endless retries| 296*1c60b9acSAndroid Build Coastguard Worker|sspc|`ss`|`sspc_fake_rxparse_disconnect_me`|Force client-proxy link parse to seem to ask to be disconnected, it will provoke endless retries| 297*1c60b9acSAndroid Build Coastguard Worker|sspc|`ss`|`sspc_fake_rxparse_destroy_me`|Force client-proxy link parse to seem to ask to destroy the SS, it will destroy the SS cleanly| 298*1c60b9acSAndroid Build Coastguard Worker|sspc|`ss`|`sspc_link_write_fail`|Force write on the link to fail, it will provoke endless retries| 299*1c60b9acSAndroid Build Coastguard Worker|sspc|`ss`|`sspc_create_oom`|Cause the sspc handle allocation to fail as if OOM at creation time| 300*1c60b9acSAndroid Build Coastguard Worker|sspc|`ss`|`sspc_fail_metadata_set`|Cause the metadata allocation to fail| 301*1c60b9acSAndroid Build Coastguard Worker|sspc|`ss`|`sspc_rx_fake_destroy_me`|Make it seem that client's user code *rx() returned DESTROY_ME| 302*1c60b9acSAndroid Build Coastguard Worker|sspc|`ss`|`sspc_rx_metadata_oom`|Cause metadata from proxy allocation to fail| 303*1c60b9acSAndroid Build Coastguard Worker|ssproxy|`ss`|`ssproxy_dsh_create_oom`|Cause proxy's creation of DSH to fail| 304*1c60b9acSAndroid Build Coastguard Worker|ssproxy|`ss`|`ssproxy_dsh_rx_queue_oom`|Cause proxy's allocation in the onward SS->P[->C] DSH rx direction to fail as if OOM, this causes the onward connection to disconnect| 305*1c60b9acSAndroid Build Coastguard Worker|ssproxy|`wsi`|`ssproxy_client_adopt_oom`|Cause proxy to be unable to allocate for new client - proxy link connection object| 306*1c60b9acSAndroid Build Coastguard Worker|ssproxy|`wsi`|`ssproxy_client_write_fail`|Cause proxy write to client to fail| 307*1c60b9acSAndroid Build Coastguard Worker|ssproxy|`wsi`|`sspc_dsh_ss2p_oom`|Cause ss->proxy dsh allocation to fail| 308*1c60b9acSAndroid Build Coastguard Worker|ssproxy|`ss`|`ssproxy_onward_conn_fail`|Act as if proxy onward client connection failed immediately| 309*1c60b9acSAndroid Build Coastguard Worker|ssproxy|`ss`|`ssproxy_dsh_c2p_pay_oom`|Cause proxy's DSH alloc for C->P payload to fail| 310*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_create_smd`|SMD: ss creation smd registration fail| 311*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_create_vhost`|Server: ss creation acts like no vhost matching typename (only for `!vhost`)| 312*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_create_pcol`|Server: ss creation acts like no protocol given in policy| 313*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_srv_vh_fail`|Server: ss creation acts like unable to create vhost| 314*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_create_destroy_me`|ss creation acts like CREATING state returned DESTROY_ME| 315*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_create_no_ts`|Static Policy: ss creation acts like no trust store| 316*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_create_smd_1`|SMD: ss creation acts like CONNECTING said DESTROY_ME| 317*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_create_smd_2`|SMD: ss creation acts like CONNECTED said DESTROY_ME| 318*1c60b9acSAndroid Build Coastguard Worker|ss|`ss`|`ss_create_conn`|Nailed up: ss creation client connection fails with DESTROY_ME| 319*1c60b9acSAndroid Build Coastguard Worker|wsi|`wsi`|`timedclose`|(see next) Cause wsi to close after some time| 320*1c60b9acSAndroid Build Coastguard Worker|wsi|`wsi`|`timedclose_ms`|Range of ms for timedclose (eg, "timedclose_ms(10..250)"| 321*1c60b9acSAndroid Build Coastguard Worker 322*1c60b9acSAndroid Build Coastguard Worker## Well-known namespace targets 323*1c60b9acSAndroid Build Coastguard Worker 324*1c60b9acSAndroid Build Coastguard WorkerNamespaces can be used to target these more precisely, for example even though 325*1c60b9acSAndroid Build Coastguard Workerwe are only passing the faults we want inject at the lws_context, we can use 326*1c60b9acSAndroid Build Coastguard Workerthe namespace "paths" to target only the wsis created by other things. 327*1c60b9acSAndroid Build Coastguard Worker 328*1c60b9acSAndroid Build Coastguard WorkerTo target wsis from SS-based connections, you can use `ss=stream_type_name/`, 329*1c60b9acSAndroid Build Coastguard Workereg for captive portal detection, to have it unable to find its policy entry: 330*1c60b9acSAndroid Build Coastguard Worker 331*1c60b9acSAndroid Build Coastguard Worker`ss=captive_portal_detect/ss_no_streamtype_policy` (disables CPD from operating) 332*1c60b9acSAndroid Build Coastguard Worker 333*1c60b9acSAndroid Build Coastguard Worker...to force it to fail to resolve the server DNS: 334*1c60b9acSAndroid Build Coastguard Worker 335*1c60b9acSAndroid Build Coastguard Worker`ss=captive_portal_detect/wsi/dnsfail` (this makes CPD feel there is no internet) 336*1c60b9acSAndroid Build Coastguard Worker 337*1c60b9acSAndroid Build Coastguard Worker...to target the connection part of the captive portal testing instead: 338*1c60b9acSAndroid Build Coastguard Worker 339*1c60b9acSAndroid Build Coastguard Worker`ss=captive_portal_detect/wsi/connfail` (this also makes CPD feel there is no internet) 340*1c60b9acSAndroid Build Coastguard Worker 341*1c60b9acSAndroid Build Coastguard Worker### Well-known internal wsi type names 342*1c60b9acSAndroid Build Coastguard Worker 343*1c60b9acSAndroid Build Coastguard WorkerWsi created for internal features like Async DNS processing can also be targeted 344*1c60b9acSAndroid Build Coastguard Worker 345*1c60b9acSAndroid Build Coastguard Worker|wsi target|Meaning| 346*1c60b9acSAndroid Build Coastguard Worker|---|---| 347*1c60b9acSAndroid Build Coastguard Worker|`wsi=asyncdns/`|UDP wsi used by lws Async DNS support to talk to DNS servers| 348*1c60b9acSAndroid Build Coastguard Worker|`wsi=dhcpc/`|UDP wsi used by lws DHCP Client| 349*1c60b9acSAndroid Build Coastguard Worker|`wsi=ntpclient/`|UDP wsi used by lws NTP Client| 350*1c60b9acSAndroid Build Coastguard Worker 351*1c60b9acSAndroid Build Coastguard WorkerFor example, passing in at lws_context level `wsi=asyncdns/udp_tx_loss` 352*1c60b9acSAndroid Build Coastguard Workerwill force async dns to be unable to resolve anything since its UDP tx is 353*1c60b9acSAndroid Build Coastguard Workerbeing suppressed. 354*1c60b9acSAndroid Build Coastguard Worker 355*1c60b9acSAndroid Build Coastguard WorkerAt client connection creation time, user code can also specify their own names 356*1c60b9acSAndroid Build Coastguard Workerto match on these `wsi=xxx/` namespace parts, so the faults only apply to 357*1c60b9acSAndroid Build Coastguard Workerspecific wsi they are creating themselves later. This is done by setting the 358*1c60b9acSAndroid Build Coastguard Workerclient creation info struct `.fi_wsi_name` to the string "xxx". 359