fix: Implement channel-based packet handling for TUI live updates
This commit is contained in:
@@ -56,24 +56,28 @@ type Model struct {
|
|||||||
height int
|
height int
|
||||||
|
|
||||||
// Network map configuration
|
// Network map configuration
|
||||||
networkMap *config.NetworkMap
|
networkMap *config.NetworkMap
|
||||||
|
captureMode CaptureMode
|
||||||
|
sshConfig SSHConfigModel
|
||||||
|
|
||||||
// Capture state
|
// Capture state
|
||||||
captureMode CaptureMode
|
|
||||||
sshConfig SSHConfigModel
|
|
||||||
capturer *capture.Capturer
|
|
||||||
localCapturer *capture.LocalCapturer
|
|
||||||
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
|
|
||||||
|
|
||||||
// File browser for pcap import
|
// File browser for pcap import
|
||||||
fileBrowser FileBrowserModel
|
fileBrowser FileBrowserModel
|
||||||
@@ -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,13 +321,20 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.height = msg.Height
|
m.height = msg.Height
|
||||||
|
|
||||||
case PacketMsg:
|
case PacketMsg:
|
||||||
m.packetCount++
|
if msg.Packet != nil {
|
||||||
summary := formatPacketSummary(msg.Packet, m.networkMap)
|
m.packetCount++
|
||||||
m.lastPackets = append(m.lastPackets, summary)
|
summary := formatPacketSummary(msg.Packet, m.networkMap)
|
||||||
if len(m.lastPackets) > 50 {
|
m.lastPackets = append(m.lastPackets, summary)
|
||||||
m.lastPackets = m.lastPackets[1:]
|
if len(m.lastPackets) > 50 {
|
||||||
|
m.lastPackets = m.lastPackets[1:]
|
||||||
|
}
|
||||||
|
m.callFlowStore.AddPacket(msg.Packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue waiting if we are still capturing
|
||||||
|
if m.capturing {
|
||||||
|
return m, waitForPacket(m.packetChan)
|
||||||
}
|
}
|
||||||
m.callFlowStore.AddPacket(msg.Packet)
|
|
||||||
|
|
||||||
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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user