Skip to content

Commit

Permalink
Try to fix #4
Browse files Browse the repository at this point in the history
... by catching TCP RST packets in WritePackets and sending them
during the next WritePackets call where no RST packet is being sent

Signed-off-by: Vasyl Gello <[email protected]>
  • Loading branch information
basilgello committed Jul 19, 2024
1 parent b160b3f commit 69dd1c9
Showing 1 changed file with 50 additions and 10 deletions.
60 changes: 50 additions & 10 deletions src/netstack/yggdrasil.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package netstack
import (
"log"
"net"
"sync"

"github.com/yggdrasil-network/yggdrasil-go/src/core"
"github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc"
Expand All @@ -12,6 +13,7 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
)

type YggdrasilNIC struct {
Expand All @@ -20,15 +22,17 @@ type YggdrasilNIC struct {
dispatcher stack.NetworkDispatcher
readBuf []byte
writeBuf []byte
rstPackets chan *stack.PacketBuffer
}

func (s *YggdrasilNetstack) NewYggdrasilNIC(ygg *core.Core) tcpip.Error {
rwc := ipv6rwc.NewReadWriteCloser(ygg)
mtu := rwc.MTU()
nic := &YggdrasilNIC{
ipv6rwc: rwc,
readBuf: make([]byte, mtu),
writeBuf: make([]byte, mtu),
ipv6rwc: rwc,
readBuf: make([]byte, mtu),
writeBuf: make([]byte, mtu),
rstPackets: make(chan *stack.PacketBuffer, 100),
}
if err := s.stack.CreateNIC(1, nic); err != nil {
return err
Expand All @@ -48,6 +52,15 @@ func (s *YggdrasilNetstack) NewYggdrasilNIC(ygg *core.Core) tcpip.Error {
nic.dispatcher.DeliverNetworkPacket(ipv6.ProtocolNumber, pkb)
}
}()
go func() {
for {
pkt := <- nic.rstPackets
if pkt == nil {
continue
}
_ = nic.writePacket(pkt)
}
}()
_, snet, err := net.ParseCIDR("0200::/7")
if err != nil {
return &tcpip.ErrBadAddress{}
Expand Down Expand Up @@ -93,21 +106,48 @@ func (*YggdrasilNIC) LinkAddress() tcpip.LinkAddress { return "" }

func (*YggdrasilNIC) Wait() {}

func (e *YggdrasilNIC) writePacket(
pkt *stack.PacketBuffer,
) tcpip.Error {
// We need to recover from panic() here because
// parser in ToView() gets confused on some packets
// without payload and panics
defer func() {
r := recover()
if r != nil {
}
}()
vv := pkt.ToView()
n, err := vv.Read(e.writeBuf)
if err != nil {
return &tcpip.ErrAborted{}
}
_, err = e.ipv6rwc.Write(e.writeBuf[:n])
if err != nil {
return &tcpip.ErrAborted{}
}
return nil
}

func (e *YggdrasilNIC) WritePackets(
list stack.PacketBufferList,
) (int, tcpip.Error) {
var i int = 0
var err tcpip.Error = nil
for i, pkt := range list.AsSlice() {
vv := pkt.ToView()
n, err := vv.Read(e.writeBuf)
if err != nil {
log.Println(err)
return i - 1, &tcpip.ErrAborted{}
if pkt.Data().Size() == 0 {
if pkt.Network().TransportProtocol() == tcp.ProtocolNumber {
tcpHeader := header.TCP(pkt.TransportHeader().Slice())
if (tcpHeader.Flags() & header.TCPFlagRst) == header.TCPFlagRst {
e.rstPackets <- pkt
continue
}
}
}
_, err = e.ipv6rwc.Write(e.writeBuf[:n])
err = e.writePacket(pkt)
if err != nil {
log.Println(err)
return i - 1, &tcpip.ErrAborted{}
return i - 1, err
}
}

Expand Down

0 comments on commit 69dd1c9

Please sign in to comment.