new tun interface

This commit is contained in:
JackDoan
2026-04-17 10:25:05 -05:00
parent c08ed7d626
commit 7bb5cd477e
4 changed files with 36 additions and 4 deletions

View File

@@ -353,8 +353,7 @@ func (f *Interface) listenOut(i int) {
nb := make([]byte, 12, 12)
listener := func(fromUdpAddr netip.AddrPort, payload []byte, meta udp.RxMeta) {
plaintext := f.batchers[i].Reserve(len(payload))
f.readOutsidePackets(ViaSender{UdpAddr: fromUdpAddr}, plaintext[:0], payload, h, fwPacket, lhh, nb, i, ctCache.Get(), meta)
f.readOutsidePackets(ViaSender{UdpAddr: fromUdpAddr}, payload, h, fwPacket, lhh, nb, i, ctCache.Get(), meta)
}
flusher := func() {

View File

@@ -48,11 +48,15 @@ func (c *pollQueueSet) Add(fd int) error {
func (c *pollQueueSet) wakeForShutdown() error {
var buf [8]byte
binary.NativeEndian.PutUint64(buf[:], 1)
_, err := unix.Write(int(c.shutdownFd), buf[:])
_, err := unix.Write(c.shutdownFd, buf[:])
return err
}
func (c *pollQueueSet) Close() error {
if c.shutdownFd < 0 {
return nil
}
errs := []error{}
if err := c.wakeForShutdown(); err != nil {
@@ -65,5 +69,12 @@ func (c *pollQueueSet) Close() error {
}
}
// All Polls reference shutdownFd in their pollfd arrays, so close it
// only after every Poll.Close has returned.
if err := unix.Close(c.shutdownFd); err != nil {
errs = append(errs, err)
}
c.shutdownFd = -1
return errors.Join(errs...)
}

View File

@@ -117,7 +117,8 @@ func QueueCapabilities(q Queue) Capabilities {
type GSOProto uint8
const (
GSOProtoTCP GSOProto = iota
GSOProtoNone GSOProto = iota
GSOProtoTCP
GSOProtoUDP
)

View File

@@ -80,3 +80,24 @@ func TestPoll_Close_Idempotent(t *testing.T) {
t.Fatalf("second Close should be a no-op, got %v", err)
}
}
func TestPollQueueSet_Close_ClosesEventfd(t *testing.T) {
qs, err := NewPollQueueSet()
require.NoError(t, err)
require.NoError(t, qs.Add(newReadPipe(t)))
fd := qs.(*pollQueueSet).shutdownFd
require.NoError(t, qs.Close())
// Closing the eventfd again should fail with EBADF, proving Close
// actually released it.
if err := unix.Close(fd); err == nil {
t.Fatalf("eventfd %d still open after QueueSet.Close", fd)
}
// Second Close must be a no-op (and must not double-close the eventfd
// in case the kernel handed it out to another caller in the meantime).
if err := qs.Close(); err != nil {
t.Fatalf("second Close: %v", err)
}
}