go-m3ua icon indicating copy to clipboard operation
go-m3ua copied to clipboard

m3ua.Conn is not concurrency-safe / has data-races

Open linouxis9 opened this issue 2 months ago • 1 comments

Hi!

Here are a few issues I found with m3ua.Conn:

  • messages.Data.MarshalBinary will call SetLength on its inner params.Param (eg. RoutingContexts) https://github.com/wmnsk/go-m3ua/blob/3084b69e489f734d959558e1d06699fe967a187a/conn.go#L94-L100 But these params.Param are globals from the cfg, so SetLength will be called concurrently on these params.Param from concurrent Write to the m3ua.Conn. Solution (in order of perf impact):

    • Call SetLength once / only when the params.Param is modified
    • Deep copy the params.Param from cfg before handing it to messages.NewData
    • Call conn.Mu.Lock() in WriteToStreamWithConfig
  • c.cfg.HeartbeatInfo.Data is read and written concurrently without a mutex or an atomic pointer. https://github.com/wmnsk/go-m3ua/blob/3084b69e489f734d959558e1d06699fe967a187a/asptm.go#L135

IMHO, seeing these two issues; Conn.cfg should never be modifed by Conn, and only the user of a m3ua.Conn should be able to change the cfg.

  • c.state is read and written concurrently (eg. in conn.Write and some ASP state updates) without c.state reads not always being protected by a Mutex. Solution (in order of perf impact):
    • Use atomic.Pointer[State] to hold the conn's State, and Load/Store everywhere needed
    • Call conn.Mu.Lock() every time c.state is read

I hope it'll help!

Cheers, Valentin

linouxis9 avatar Apr 22 '24 13:04 linouxis9