This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit 9b7d1dcb6523f84b9fbeb0146031c71c315b7f93
Author: Szymon Janc <[email protected]>
AuthorDate: Thu Oct 22 00:38:57 2026 +0200

    nmxact/udp: Fail TxCoap on a closed session
    
    Unlike TxRxMgmt(), UdpSesn.TxCoap() did not check that the session is
    open. On a session that was never opened or was already closed, the
    nil *net.UDPConn was dereferenced in WriteToUDP() and newtmgr crashed
    with a nil pointer panic instead of returning an error.
    
    Return the same error as TxRxMgmt() when the session is not open. Also
    add a test for TxCoap on an open session.
    
    Assisted-by: Claude:claude-opus-5-5
---
 nmxact/udp/udp_sesn.go |  4 ++++
 nmxact/udp/udp_test.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/nmxact/udp/udp_sesn.go b/nmxact/udp/udp_sesn.go
index fdf5358..400ef2b 100644
--- a/nmxact/udp/udp_sesn.go
+++ b/nmxact/udp/udp_sesn.go
@@ -135,6 +135,10 @@ func (s *UdpSesn) AbortRx(seq uint8) error {
 }
 
 func (s *UdpSesn) TxCoap(m coap.Message) error {
+       if !s.IsOpen() {
+               return fmt.Errorf("Attempt to transmit over closed UDP session")
+       }
+
        txRaw := func(b []byte) error {
                frags := nmxutil.Fragment(b, s.MtuOut())
                for _, frag := range frags {
diff --git a/nmxact/udp/udp_test.go b/nmxact/udp/udp_test.go
index 4a9efcc..18f545d 100644
--- a/nmxact/udp/udp_test.go
+++ b/nmxact/udp/udp_test.go
@@ -495,3 +495,62 @@ func TestListenBufferNotReused(t *testing.T) {
                t.Errorf("second datagram = %q", bufs[1])
        }
 }
+
+// TxCoap on a session that is not open must fail rather than dereference
+// the nil connection.
+func TestUdpSesnTxCoapClosed(t *testing.T) {
+       s := newTestSesn(t, sesn.MGMT_PROTO_OMP, "127.0.0.1:1")
+
+       m := coap.NewDgramMessage(coap.MessageParams{
+               Type:  coap.Confirmable,
+               Code:  coap.GET,
+               Token: []byte{1},
+       })
+       m.SetPathString("res")
+
+       if err := s.TxCoap(m); err == nil {
+               t.Errorf("TxCoap on closed session succeeded")
+       }
+}
+
+func TestUdpSesnTxCoap(t *testing.T) {
+       dev, err := net.ListenUDP("udp",
+               &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer dev.Close()
+
+       s := newTestSesn(t, sesn.MGMT_PROTO_OMP, dev.LocalAddr().String())
+       if err := s.Open(); err != nil {
+               t.Fatal(err)
+       }
+       defer s.Close()
+
+       m := coap.NewDgramMessage(coap.MessageParams{
+               Type:    coap.Confirmable,
+               Code:    coap.PUT,
+               Token:   []byte{9},
+               Payload: []byte("coap"),
+       })
+       m.SetPathString("res")
+       if err := s.TxCoap(m); err != nil {
+               t.Fatalf("TxCoap failed: %v", err)
+       }
+
+       if err := dev.SetReadDeadline(time.Now().Add(testTimeout)); err != nil {
+               t.Fatal(err)
+       }
+       buf := make([]byte, 4096)
+       n, _, err := dev.ReadFromUDP(buf)
+       if err != nil {
+               t.Fatalf("device did not receive CoAP request: %v", err)
+       }
+       got, err := coap.ParseDgramMessage(buf[:n])
+       if err != nil {
+               t.Fatalf("invalid CoAP request: %v", err)
+       }
+       if got.PathString() != "res" || string(got.Payload()) != "coap" {
+               t.Errorf("got path %q payload %q", got.PathString(), 
got.Payload())
+       }
+}

Reply via email to