1## Using UDP in lws 2 3UDP is supported in lws... the quickest way is to use the api 4`lws_create_adopt_udp()` which returns a wsi bound to the provided 5vhost, protocol, `lws_retry` struct, dns address and port. 6 7The wsi can be treated normally and `lws_write()` used to write on 8it. 9 10## Implementing UDP retries 11 12Retries are important in udp but there's no standardized ack method 13unlike tcp. Lws allows you to bind an `lws_retry` struct describing 14the policy to the udp wsi, but since one UDP socket may have many 15transactions in flight, the `lws_sul` and `uint16_t` to count the 16retries must live in the user's transaction object like this 17 18``` 19... 20 lws_sorted_usec_list_t sul; 21 uint16_t retry; 22... 23``` 24 25in the `LWS_CALLBACK_RAW_WRITEABLE` callback, before doing the write, 26set up the retry like this 27 28``` 29 if (lws_dll2_is_detached(&transaction->sul_write.list) && 30 lws_retry_sul_schedule_retry_wsi(wsi, &transaction->sul_write, 31 transaction_retry_write_cb, 32 &transaction->retry_count_write)) { 33 /* we have reached the end of our concealed retries */ 34 lwsl_warn("%s: concealed retries done, failing\n", __func__); 35 goto retry_conn; 36 } 37``` 38 39This manages the retry counter in the transaction object, guards against it wrapping, 40selects the timeout using the policy bound to the wsi, and sets the `lws_sul` in the 41transaction object to call the given callback if the sul time expires. 42 43In the callback, it should simply call `lws_callback_on_writable()` for the udp wsi. 44 45## Simulating packetloss 46 47lws now allows you to set the amount of simulated packetloss on udp rx and tx in 48the context creation info struct, using `.udp_loss_sim_tx_pc` and `.udp_loss_sim_rx_pc`, 49the values are percentages between 0 and 100. 0, the default, means no packetloss. 50 51