- wireFileRecv: replace OnMessage/OnClose channel approach with pion
Detach API so SCTP buffers data regardless of callback timing — fixes
0-byte files caused by pion dispatching data goroutines before OnMessage
was registered
- yaw DC: same Detach API treatment for the control channel
- connectTo: use DetachDataChannels SettingEngine, replace stale PCs
(Connecting/Failed/Disconnected state) instead of returning early;
isCurrent guard in OnConnectionStateChange prevents stale-PC close
from firing OnDisconnected
- offerByOrder: gate maybeOffer on peer ID order so only one side
creates the yaw DC and SDP offer — fixes signaling glare causing
triple connected (verified) logs
- pendingRecvs: promote single pendingRecv slot to map[string]*recvState
so concurrent file offers don't overwrite each other
- peer-left: stop calling resetPeer() so active file DCs aren't closed
before data arrives
- signaling ping: wrap conn.Ping with 10s timeout context so a dead TCP
connection is detected within 30s rather than hanging forever
- signaling read: 3-minute read deadline forces reconnect if anchor
silently evicts the peer from the room (idle timeout)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>