Using tailcat as a library, Server.Status() always returns an empty Peer map, so there is no way for an embedder to tell whether a connected client has a direct path or is going through DERP.
locoBackend.Status() builds its status with the zero value:
func (b *locoBackend) Status() *ipnstate.Status {
mc := b.sys.MagicSock.Get()
eng := b.sys.Engine.Get()
var sb ipnstate.StatusBuilder
mc.UpdateStatus(&sb)
eng.UpdateStatus(&sb)
return sb.Status()
}
ipnstate.StatusBuilder.WantPeers therefore defaults to false, and both producers skip peers in that case: magicsock.(*Conn).UpdateStatus wraps its peerMap.forEachEndpoint loop in if sb.WantPeers, and wgengine's UpdateStatus does the same for st.Peers. So AddPeer is never called and Status().Peer is always empty.
Confirmed against a live server with a connected client: Status().Peer is empty while traffic is flowing.
The useful data is already populated by ep.populatePeerStatus(ps) (CurAddr, Relay), it just never reaches the caller.
Why it matters: I am embedding tailcat in an app that forwards a device's ports, including RTSP. On a relayed path video is effectively unusable, so surfacing direct vs relayed to the operator is the difference between a quick diagnosis and a support ticket. I have worked around it by tracking connections myself from RemoteAddr(), but that cannot distinguish path type.
Happy to send a patch if you will say which shape you would prefer: setting WantPeers: true unconditionally, or a separate opt-in accessor so the default Status() stays cheap.
Related: #39.
Using tailcat as a library,
Server.Status()always returns an emptyPeermap, so there is no way for an embedder to tell whether a connected client has a direct path or is going through DERP.locoBackend.Status()builds its status with the zero value:ipnstate.StatusBuilder.WantPeerstherefore defaults to false, and both producers skip peers in that case:magicsock.(*Conn).UpdateStatuswraps itspeerMap.forEachEndpointloop inif sb.WantPeers, andwgengine'sUpdateStatusdoes the same forst.Peers. SoAddPeeris never called andStatus().Peeris always empty.Confirmed against a live server with a connected client:
Status().Peeris empty while traffic is flowing.The useful data is already populated by
ep.populatePeerStatus(ps)(CurAddr,Relay), it just never reaches the caller.Why it matters: I am embedding tailcat in an app that forwards a device's ports, including RTSP. On a relayed path video is effectively unusable, so surfacing direct vs relayed to the operator is the difference between a quick diagnosis and a support ticket. I have worked around it by tracking connections myself from
RemoteAddr(), but that cannot distinguish path type.Happy to send a patch if you will say which shape you would prefer: setting
WantPeers: trueunconditionally, or a separate opt-in accessor so the defaultStatus()stays cheap.Related: #39.