PICloudClient::internalDisconnect() cleared buff without mutex_buff
while the eth read thread appends to it concurrently (close() races
with in-flight Data frames), and bytesAvailable() read buff.size()
lock-free on both PICloudClient and PICloudServer::Client. Take the
lock in both places (mutex_buff made mutable for the const getter).
In the Data case the client pointer was looked up under clients_mutex
but used (pushBuffer) after the unlock; a user-initiated delete() of
the same client raced with the read thread and hit freed memory.
In the Disconnect case the client was stopped/closed and appended to
removed_clients_ (without the lock, unlike every other site) after
the unlock, with the same UAF window and a race on the vector itself.
Do both uses while holding clients_mutex: a concurrent delete() is
serialized with this block by clientDeleted() (the deleted() event),
so the client cannot be freed while it is in use. Setting
is_connected=false first also stops pushBuffer from buffering into a
dying client.
sendStart/sendConnected/sendDisconnected/sendData/sendPing mutated
the shared header.type and serialized the header without holding
mutex_send (it only covered streampacker->send), so concurrent
senders (e.g. ping timer vs app thread on PICloudServer) could mix
type/role bytes of different frames. Snapshot the header into a
local copy under mutex_send in every send* and setRole now takes the
lock as well.
parseDataServer/parseConnect/parseDisconnect read a uint without
checking the payload size; PIByteArray does a partial memcpy on
undersized input, so a short frame produced a garbage client id.
Return the default value when the payload is shorter than sizeof(uint).
piMini(max_size, buff.size()) implicitly narrows size_t to int,
which is UB for large buffers. Replace with explicit piMin<ssize_t>
matching the correct pattern used in picloudclient.cpp.
in almost all methods removed timeouts in milliseconds, replaced to PISystemTime
PITimer rewrite, remove internal impl, now only thread implementation, API similar to PIThread
PITimer API no longer pass void*
PIPeer, PIConnection improved stability on reinit and exit
PISystemTime new methods
pisd now exit without hanging
pipacketextractor Header mode now more flexible
fix splitTime mode
more refactoring
add virtual override to functions
remove piforeach
replace 0 to nullptr
iterate over pimap via iterators
replace CONNECTU to CONNECT# with compile time check