fix: Implement channel-based packet handling for TUI live updates

This commit is contained in:
Jose Luis Montañes Ojados
2026-01-19 15:51:25 +01:00
parent f0911737f4
commit cd9b0db44d

View File

@@ -57,21 +57,25 @@ type Model struct {
// Network map configuration // Network map configuration
networkMap *config.NetworkMap networkMap *config.NetworkMap
// Capture state
captureMode CaptureMode captureMode CaptureMode
sshConfig SSHConfigModel sshConfig SSHConfigModel
capturer *capture.Capturer
localCapturer *capture.LocalCapturer // Capture state
connected bool
capturing bool capturing bool
connected bool
captureIface string
localCapturer *capture.LocalCapturer
capturer *capture.Capturer
captureError string
packetCount int packetCount int
lastPackets []string lastPackets []string
captureError string
captureIface string packetChan chan *sip.Packet // Channel for receiving packets from callbacks
// Data stores
callFlowStore *sip.CallFlowStore
// Call flow analysis // Call flow analysis
callFlowStore *sip.CallFlowStore
selectedFlow int selectedFlow int
flowList list.Model flowList list.Model
@@ -237,6 +241,13 @@ func NewModel() Model {
} }
} }
// waitForPacket waits for a packet on the channel
func waitForPacket(ch chan *sip.Packet) tea.Cmd {
return func() tea.Msg {
return PacketMsg{Packet: <-ch}
}
}
func createNodeInputs() []textinput.Model { func createNodeInputs() []textinput.Model {
inputs := make([]textinput.Model, 4) inputs := make([]textinput.Model, 4)
@@ -310,6 +321,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.height = msg.Height m.height = msg.Height
case PacketMsg: case PacketMsg:
if msg.Packet != nil {
m.packetCount++ m.packetCount++
summary := formatPacketSummary(msg.Packet, m.networkMap) summary := formatPacketSummary(msg.Packet, m.networkMap)
m.lastPackets = append(m.lastPackets, summary) m.lastPackets = append(m.lastPackets, summary)
@@ -317,6 +329,12 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.lastPackets = m.lastPackets[1:] m.lastPackets = m.lastPackets[1:]
} }
m.callFlowStore.AddPacket(msg.Packet) m.callFlowStore.AddPacket(msg.Packet)
}
// Continue waiting if we are still capturing
if m.capturing {
return m, waitForPacket(m.packetChan)
}
case ErrorMsg: case ErrorMsg:
m.captureError = msg.Error.Error() m.captureError = msg.Error.Error()
@@ -560,9 +578,14 @@ func (m *Model) startLocalCapture() tea.Cmd {
m.lastPackets = m.lastPackets[:0] m.lastPackets = m.lastPackets[:0]
m.captureMode = CaptureModeLocal m.captureMode = CaptureModeLocal
// Create a buffered channel for packets
m.packetChan = make(chan *sip.Packet, 100)
m.localCapturer = capture.NewLocalCapturer() m.localCapturer = capture.NewLocalCapturer()
m.localCapturer.OnPacket = func(p *sip.Packet) { m.localCapturer.OnPacket = func(p *sip.Packet) {
// Note: In real implementation, use channel + tea.Cmd if m.capturing {
m.packetChan <- p
}
} }
m.localCapturer.OnError = func(err error) { m.localCapturer.OnError = func(err error) {
m.captureError = err.Error() m.captureError = err.Error()
@@ -576,9 +599,10 @@ func (m *Model) startLocalCapture() tea.Cmd {
if err := m.localCapturer.Start(iface, 5060); err != nil { if err := m.localCapturer.Start(iface, 5060); err != nil {
m.captureError = err.Error() m.captureError = err.Error()
m.capturing = false m.capturing = false
return nil
} }
return nil return waitForPacket(m.packetChan)
} }
func (m *Model) startSSHCapture() tea.Cmd { func (m *Model) startSSHCapture() tea.Cmd {
@@ -587,8 +611,13 @@ func (m *Model) startSSHCapture() tea.Cmd {
m.packetCount = 0 m.packetCount = 0
m.lastPackets = m.lastPackets[:0] m.lastPackets = m.lastPackets[:0]
// Create a buffered channel for packets
m.packetChan = make(chan *sip.Packet, 100)
m.capturer.OnPacket = func(p *sip.Packet) { m.capturer.OnPacket = func(p *sip.Packet) {
// Note: In real implementation, use channel + tea.Cmd if m.capturing {
m.packetChan <- p
}
} }
m.capturer.OnError = func(err error) { m.capturer.OnError = func(err error) {
m.captureError = err.Error() m.captureError = err.Error()
@@ -597,9 +626,10 @@ func (m *Model) startSSHCapture() tea.Cmd {
if err := m.capturer.Start("any", 5060); err != nil { if err := m.capturer.Start("any", 5060); err != nil {
m.captureError = err.Error() m.captureError = err.Error()
m.capturing = false m.capturing = false
return nil
} }
return nil return waitForPacket(m.packetChan)
} }
func (m *Model) stopCapture() { func (m *Model) stopCapture() {
@@ -609,7 +639,16 @@ func (m *Model) stopCapture() {
if m.capturer != nil { if m.capturer != nil {
m.capturer.Stop() m.capturer.Stop()
} }
wasCapturing := m.capturing
m.capturing = false m.capturing = false
// Unblock any waiting waitForPacket command
if wasCapturing && m.packetChan != nil {
go func() {
m.packetChan <- nil
}()
}
} }
func (m *Model) disconnect() { func (m *Model) disconnect() {