mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-05-02 12:45:10 +02:00
fix: prevent panic on network change during SetSelfIP
SetSelfIP unconditionally accessed t.dhcp, but t.dhcp is only initialized when DHCP discovery is enabled. A network change event can fire SetSelfIP regardless of the discovery configuration, causing a nil pointer dereference. Guard the t.dhcp access with a nil check so the self IP is still updated on the Table even when DHCP discovery is disabled.
This commit is contained in:
committed by
Cuong Manh Le
parent
ed98104384
commit
d1ea70d688
@@ -173,8 +173,10 @@ func (t *Table) SetSelfIP(ip string) {
|
||||
t.selfIPLock.Lock()
|
||||
defer t.selfIPLock.Unlock()
|
||||
t.selfIP = ip
|
||||
t.dhcp.selfIP = t.selfIP
|
||||
t.dhcp.addSelf()
|
||||
if t.dhcp != nil {
|
||||
t.dhcp.selfIP = t.selfIP
|
||||
t.dhcp.addSelf()
|
||||
}
|
||||
}
|
||||
|
||||
// initSelfDiscover initializes necessary client metadata for self query.
|
||||
|
||||
@@ -1,9 +1,64 @@
|
||||
package clientinfo
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestTable_SetSelfIP_NilDHCP ensures SetSelfIP does not panic when t.dhcp is
|
||||
// nil, which happens when DHCP discovery is disabled and the network-change
|
||||
// callback fires before or without initialisation.
|
||||
func TestTable_SetSelfIP_NilDHCP(t *testing.T) {
|
||||
table := &Table{} // dhcp is nil
|
||||
// Must not panic.
|
||||
table.SetSelfIP("192.168.1.1")
|
||||
if got := table.SelfIP(); got != "192.168.1.1" {
|
||||
t.Fatalf("SelfIP() = %q, want %q", got, "192.168.1.1")
|
||||
}
|
||||
}
|
||||
|
||||
// TestTable_SetSelfIP_UpdatesDHCP ensures SetSelfIP propagates the new IP to
|
||||
// the dhcp discover and calls addSelf when dhcp is initialised.
|
||||
func TestTable_SetSelfIP_UpdatesDHCP(t *testing.T) {
|
||||
table := &Table{
|
||||
dhcp: &dhcp{selfIP: "10.0.0.1"},
|
||||
}
|
||||
table.SetSelfIP("10.0.0.2")
|
||||
if got := table.SelfIP(); got != "10.0.0.2" {
|
||||
t.Fatalf("SelfIP() = %q, want %q", got, "10.0.0.2")
|
||||
}
|
||||
if table.dhcp.selfIP != "10.0.0.2" {
|
||||
t.Fatalf("dhcp.selfIP = %q, want %q", table.dhcp.selfIP, "10.0.0.2")
|
||||
}
|
||||
}
|
||||
|
||||
// TestTable_SetSelfIP_Concurrent ensures concurrent calls to SetSelfIP do not
|
||||
// race, regardless of whether dhcp is nil or not.
|
||||
func TestTable_SetSelfIP_Concurrent(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
table *Table
|
||||
}{
|
||||
{"nil dhcp", &Table{}},
|
||||
{"with dhcp", &Table{dhcp: &dhcp{}}},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var wg sync.WaitGroup
|
||||
for range 10 {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
tc.table.SetSelfIP("192.168.1.1")
|
||||
_ = tc.table.SelfIP()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_normalizeIP(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user