captured: directly call NextPacket() to prevent hanging reads

Using Packets() spawns off a separate goroutine which calls NextPacket in a loop
until io.EOF is returned. This goroutine will stick around after Close()
returned, resulting in only the first wireshark connection working.
This commit is contained in:
Michael Stapelberg 2018-10-23 09:56:07 +02:00
parent d9f5d95812
commit 7d278289f0
2 changed files with 17 additions and 6 deletions

View File

@ -20,6 +20,7 @@ import (
"container/ring"
"context"
"flag"
"fmt"
"log"
"os"
"os/signal"
@ -47,17 +48,22 @@ func capturePackets(ctx context.Context) (chan gopacket.Packet, error) {
for _, ifname := range []string{"uplink0", "lan0"} {
handle, err := pcapgo.NewEthernetHandle(ifname)
if err != nil {
return nil, err
return nil, fmt.Errorf("pcapgo.NewEthernetHandle(%v): %v", ifname, err)
}
if err := handle.SetBPF(instructions); err != nil {
return nil, err
return nil, fmt.Errorf("SetBPF: %v", err)
}
pkgsrc := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)
go func() {
defer handle.Close()
for packet := range pkgsrc.Packets() {
for {
packet, err := pkgsrc.NextPacket()
if err != nil {
log.Printf("NextPacket: %v", err)
return
}
select {
case packets <- packet:
case <-ctx.Done():

View File

@ -61,20 +61,25 @@ type session struct {
channel ssh.Channel
}
func (s *session) request(req *ssh.Request, prb *packetRingBuffer) error {
func (s *session) request(req *ssh.Request, prb *packetRingBuffer) (err error) {
switch req.Type {
case "exec":
if got, want := len(req.Payload), 4; got < want {
return fmt.Errorf("exec request payload too short: got %d, want >= %d", got, want)
}
log.Printf("exec, wantReply %v, payload %q", req.WantReply, string(req.Payload[4:]))
defer func() {
if err != nil {
log.Printf("exec done: %v", err)
}
}()
ctx, canc := context.WithCancel(context.Background())
defer canc()
pcapw := pcapgo.NewWriter(s.channel)
if err := pcapw.WriteFileHeader(1600, layers.LinkTypeEthernet); err != nil {
return err
return fmt.Errorf("pcapw.WriteFileHeader: %v", err)
}
prb.Lock()
@ -82,7 +87,7 @@ func (s *session) request(req *ssh.Request, prb *packetRingBuffer) error {
buffered := prb.packetsLocked()
prb.Unlock()
if err != nil {
return err
return fmt.Errorf("capturePackets: %v", err)
}
req.Reply(true, nil)