Skip to content

Commit 7b53ef0

Browse files
committed
Add support for ethernet
1 parent aa9d9c6 commit 7b53ef0

File tree

5 files changed

+57
-24
lines changed

5 files changed

+57
-24
lines changed

stack_gvisor.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ func (t *GVisor) Start() error {
7070
if err != nil {
7171
return err
7272
}
73-
ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, NewTCPForwarder(t.ctx, ipStack, t.handler).HandlePacket)
74-
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, NewUDPForwarder(t.ctx, ipStack, t.handler, t.udpTimeout).HandlePacket)
73+
ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, NewTCPForwarder(t.ctx, ipStack, false, t.handler).HandlePacket)
74+
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, NewUDPForwarder(t.ctx, ipStack, false, t.handler, t.udpTimeout).HandlePacket)
7575
t.stack = ipStack
7676
t.endpoint = linkEndpoint
7777
return nil

stack_gvisor_lazy.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ import (
1010

1111
"github.com/sagernet/gvisor/pkg/tcpip"
1212
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
13+
"github.com/sagernet/gvisor/pkg/tcpip/header"
1314
"github.com/sagernet/gvisor/pkg/tcpip/stack"
1415
"github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
1516
"github.com/sagernet/gvisor/pkg/waiter"
1617
"github.com/sagernet/sing/common"
1718
)
1819

1920
type gLazyConn struct {
21+
ethernet bool
2022
tcpConn *gonet.TCPConn
2123
parentCtx context.Context
2224
stack *stack.Stack
@@ -35,9 +37,13 @@ func (c *gLazyConn) HandshakeContext(ctx context.Context) error {
3537
c.handshakeDone = true
3638
}()
3739
var (
38-
wq waiter.Queue
39-
endpoint tcpip.Endpoint
40+
wq waiter.Queue
41+
endpoint tcpip.Endpoint
42+
linkAddress tcpip.LinkAddress
4043
)
44+
if c.ethernet {
45+
linkAddress = header.Ethernet(c.request.Packet().LinkHeader().Slice()).DestinationAddress()
46+
}
4147
handshakeCtx, cancel := context.WithCancel(ctx)
4248
go func() {
4349
select {
@@ -54,6 +60,9 @@ func (c *gLazyConn) HandshakeContext(ctx context.Context) error {
5460
c.request.Complete(true)
5561
return gErr
5662
}
63+
if c.ethernet {
64+
endpoint.SetOwner(&EthernetOwner{linkAddress})
65+
}
5766
c.request.Complete(false)
5867
endpoint.SocketOptions().SetKeepAlive(true)
5968
endpoint.SetSockOpt(common.Ptr(tcpip.KeepaliveIdleOption(15 * time.Second)))
@@ -63,6 +72,18 @@ func (c *gLazyConn) HandshakeContext(ctx context.Context) error {
6372
return nil
6473
}
6574

75+
type EthernetOwner struct {
76+
Destination tcpip.LinkAddress
77+
}
78+
79+
func (o *EthernetOwner) KUID() uint32 {
80+
return 0
81+
}
82+
83+
func (o *EthernetOwner) KGID() uint32 {
84+
return 0
85+
}
86+
6687
func (c *gLazyConn) HandshakeFailure(err error) error {
6788
if c.handshakeDone {
6889
return os.ErrInvalid

stack_gvisor_tcp.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ import (
1414
type TCPForwarder struct {
1515
ctx context.Context
1616
stack *stack.Stack
17+
ethernet bool
1718
handler Handler
1819
forwarder *tcp.Forwarder
1920
}
2021

21-
func NewTCPForwarder(ctx context.Context, stack *stack.Stack, handler Handler) *TCPForwarder {
22+
func NewTCPForwarder(ctx context.Context, stack *stack.Stack, ethernet bool, handler Handler) *TCPForwarder {
2223
forwarder := &TCPForwarder{
23-
ctx: ctx,
24-
stack: stack,
25-
handler: handler,
24+
ctx: ctx,
25+
stack: stack,
26+
ethernet: ethernet,
27+
handler: handler,
2628
}
2729
forwarder.forwarder = tcp.NewForwarder(stack, 0, 1024, forwarder.Forward)
2830
return forwarder
@@ -41,6 +43,7 @@ func (f *TCPForwarder) Forward(r *tcp.ForwarderRequest) {
4143
return
4244
}
4345
conn := &gLazyConn{
46+
ethernet: f.ethernet,
4447
parentCtx: f.ctx,
4548
stack: f.stack,
4649
request: r,

stack_gvisor_udp.go

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,19 @@ import (
2525
)
2626

2727
type UDPForwarder struct {
28-
ctx context.Context
29-
stack *stack.Stack
30-
handler Handler
31-
udpNat *udpnat.Service
28+
ctx context.Context
29+
stack *stack.Stack
30+
ethernet bool
31+
handler Handler
32+
udpNat *udpnat.Service
3233
}
3334

34-
func NewUDPForwarder(ctx context.Context, stack *stack.Stack, handler Handler, timeout time.Duration) *UDPForwarder {
35+
func NewUDPForwarder(ctx context.Context, stack *stack.Stack, ethernet bool, handler Handler, timeout time.Duration) *UDPForwarder {
3536
forwarder := &UDPForwarder{
36-
ctx: ctx,
37-
stack: stack,
38-
handler: handler,
37+
ctx: ctx,
38+
stack: stack,
39+
ethernet: ethernet,
40+
handler: handler,
3941
}
4042
forwarder.udpNat = udpnat.New(handler, forwarder.PreparePacketConnection, timeout, true)
4143
return forwarder
@@ -77,16 +79,21 @@ func (f *UDPForwarder) PreparePacketConnection(source M.Socksaddr, destination M
7779
sourcePort: source.Port,
7880
sourceNetwork: sourceNetwork,
7981
}
82+
if f.ethernet {
83+
ethHdr := header.Ethernet(userData.(*stack.PacketBuffer).LinkHeader().Slice())
84+
writer.linkDestination = ethHdr.DestinationAddress()
85+
}
8086
return true, f.ctx, writer, nil
8187
}
8288

8389
type UDPBackWriter struct {
84-
access sync.Mutex
85-
stack *stack.Stack
86-
packet *stack.PacketBuffer
87-
source tcpip.Address
88-
sourcePort uint16
89-
sourceNetwork tcpip.NetworkProtocolNumber
90+
access sync.Mutex
91+
stack *stack.Stack
92+
packet *stack.PacketBuffer
93+
source tcpip.Address
94+
sourcePort uint16
95+
sourceNetwork tcpip.NetworkProtocolNumber
96+
linkDestination tcpip.LinkAddress
9097
}
9198

9299
func (w *UDPBackWriter) HandshakeSuccess() error {
@@ -139,7 +146,9 @@ func (w *UDPBackWriter) WritePacket(packetBuffer *buf.Buffer, destination M.Sock
139146
Payload: buffer.MakeWithData(packetBuffer.Bytes()),
140147
})
141148
defer packet.DecRef()
142-
149+
if w.linkDestination != "" {
150+
route.ResolveWith(w.linkDestination)
151+
}
143152
packet.TransportProtocolNumber = header.UDPProtocolNumber
144153
udpHdr := header.UDP(packet.TransportHeader().Push(header.UDPMinimumSize))
145154
pLen := uint16(packet.Size())

stack_mixed.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (m *Mixed) Start() error {
4242
if err != nil {
4343
return err
4444
}
45-
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, NewUDPForwarder(m.ctx, ipStack, m.handler, m.udpTimeout).HandlePacket)
45+
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, NewUDPForwarder(m.ctx, ipStack, false, m.handler, m.udpTimeout).HandlePacket)
4646
m.stack = ipStack
4747
m.endpoint = endpoint
4848
go m.tunLoop()

0 commit comments

Comments
 (0)