mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-21 16:11:32 +00:00
Add tun inbound for linux
This commit is contained in:
parent
c463d0cf80
commit
730144cc26
151
common/tun/gvisor.go
Normal file
151
common/tun/gvisor.go
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
package tun
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/log"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/bufio"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
|
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
|
||||||
|
"gvisor.dev/gvisor/pkg/waiter"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultNIC tcpip.NICID = 1
|
||||||
|
|
||||||
|
var _ adapter.Service = (*GVisorTun)(nil)
|
||||||
|
|
||||||
|
type GVisorTun struct {
|
||||||
|
ctx context.Context
|
||||||
|
tunFd uintptr
|
||||||
|
tunMtu uint32
|
||||||
|
handler Handler
|
||||||
|
stack *stack.Stack
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGVisor(ctx context.Context, tunFd uintptr, tunMtu uint32, handler Handler) *GVisorTun {
|
||||||
|
return &GVisorTun{
|
||||||
|
ctx: ctx,
|
||||||
|
tunFd: tunFd,
|
||||||
|
tunMtu: tunMtu,
|
||||||
|
handler: handler,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GVisorTun) Start() error {
|
||||||
|
linkEndpoint, err := NewEndpoint(t.tunFd, t.tunMtu)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ipStack := stack.New(stack.Options{
|
||||||
|
NetworkProtocols: []stack.NetworkProtocolFactory{
|
||||||
|
ipv4.NewProtocol,
|
||||||
|
ipv6.NewProtocol,
|
||||||
|
},
|
||||||
|
TransportProtocols: []stack.TransportProtocolFactory{
|
||||||
|
tcp.NewProtocol,
|
||||||
|
udp.NewProtocol,
|
||||||
|
icmp.NewProtocol4,
|
||||||
|
icmp.NewProtocol6,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
tErr := ipStack.CreateNIC(defaultNIC, linkEndpoint)
|
||||||
|
if tErr != nil {
|
||||||
|
return E.New("create nic: ", tErr)
|
||||||
|
}
|
||||||
|
ipStack.SetRouteTable([]tcpip.Route{
|
||||||
|
{Destination: header.IPv4EmptySubnet, NIC: defaultNIC},
|
||||||
|
{Destination: header.IPv6EmptySubnet, NIC: defaultNIC},
|
||||||
|
})
|
||||||
|
ipStack.SetSpoofing(defaultNIC, true)
|
||||||
|
ipStack.SetPromiscuousMode(defaultNIC, true)
|
||||||
|
bufSize := 20 * 1024
|
||||||
|
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpip.TCPReceiveBufferSizeRangeOption{
|
||||||
|
Min: 1,
|
||||||
|
Default: bufSize,
|
||||||
|
Max: bufSize,
|
||||||
|
})
|
||||||
|
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpip.TCPSendBufferSizeRangeOption{
|
||||||
|
Min: 1,
|
||||||
|
Default: bufSize,
|
||||||
|
Max: bufSize,
|
||||||
|
})
|
||||||
|
sOpt := tcpip.TCPSACKEnabled(true)
|
||||||
|
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &sOpt)
|
||||||
|
mOpt := tcpip.TCPModerateReceiveBufferOption(true)
|
||||||
|
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &mOpt)
|
||||||
|
tcpForwarder := tcp.NewForwarder(ipStack, 0, 1024, func(r *tcp.ForwarderRequest) {
|
||||||
|
var wq waiter.Queue
|
||||||
|
endpoint, err := r.CreateEndpoint(&wq)
|
||||||
|
if err != nil {
|
||||||
|
r.Complete(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.Complete(false)
|
||||||
|
endpoint.SocketOptions().SetKeepAlive(true)
|
||||||
|
tcpConn := gonet.NewTCPConn(&wq, endpoint)
|
||||||
|
lAddr := tcpConn.RemoteAddr()
|
||||||
|
rAddr := tcpConn.LocalAddr()
|
||||||
|
if lAddr == nil || rAddr == nil {
|
||||||
|
tcpConn.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
var metadata M.Metadata
|
||||||
|
metadata.Source = M.SocksaddrFromNet(lAddr)
|
||||||
|
metadata.Destination = M.SocksaddrFromNet(rAddr)
|
||||||
|
ctx := log.ContextWithID(t.ctx)
|
||||||
|
hErr := t.handler.NewConnection(ctx, tcpConn, metadata)
|
||||||
|
if hErr != nil {
|
||||||
|
t.handler.NewError(ctx, hErr)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
})
|
||||||
|
ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, func(id stack.TransportEndpointID, buffer *stack.PacketBuffer) bool {
|
||||||
|
return tcpForwarder.HandlePacket(id, buffer)
|
||||||
|
})
|
||||||
|
udpForwarder := udp.NewForwarder(ipStack, func(request *udp.ForwarderRequest) {
|
||||||
|
var wq waiter.Queue
|
||||||
|
endpoint, err := request.CreateEndpoint(&wq)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
udpConn := gonet.NewUDPConn(ipStack, &wq, endpoint)
|
||||||
|
lAddr := udpConn.RemoteAddr()
|
||||||
|
rAddr := udpConn.LocalAddr()
|
||||||
|
if lAddr == nil || rAddr == nil {
|
||||||
|
udpConn.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
var metadata M.Metadata
|
||||||
|
metadata.Source = M.SocksaddrFromNet(lAddr)
|
||||||
|
metadata.Destination = M.SocksaddrFromNet(rAddr)
|
||||||
|
ctx := log.ContextWithID(t.ctx)
|
||||||
|
hErr := t.handler.NewPacketConnection(ctx, bufio.NewPacketConn(&bufio.UnbindPacketConn{ExtendedConn: bufio.NewExtendedConn(udpConn), Addr: M.SocksaddrFromNet(rAddr)}), metadata)
|
||||||
|
if hErr != nil {
|
||||||
|
t.handler.NewError(ctx, hErr)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
})
|
||||||
|
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)
|
||||||
|
t.stack = ipStack
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GVisorTun) Close() error {
|
||||||
|
return common.Close(
|
||||||
|
common.PtrOrNil(t.stack),
|
||||||
|
)
|
||||||
|
}
|
16
common/tun/gvisor_linux.go
Normal file
16
common/tun/gvisor_linux.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
//go:build linux
|
||||||
|
|
||||||
|
package tun
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/link/fdbased"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewEndpoint(tunFd uintptr, tunMtu uint32) (stack.LinkEndpoint, error) {
|
||||||
|
return fdbased.New(&fdbased.Options{
|
||||||
|
FDs: []int{int(tunFd)},
|
||||||
|
MTU: tunMtu,
|
||||||
|
PacketDispatchMode: fdbased.PacketMMap,
|
||||||
|
})
|
||||||
|
}
|
9
common/tun/gvisor_nonlinux.go
Normal file
9
common/tun/gvisor_nonlinux.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//go:build !linux
|
||||||
|
|
||||||
|
package tun
|
||||||
|
|
||||||
|
import "gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||||
|
|
||||||
|
func NewEndpoint(tunFd uintptr, tunMtu uint32) (stack.LinkEndpoint, error) {
|
||||||
|
return NewPosixEndpoint(tunFd, tunMtu)
|
||||||
|
}
|
118
common/tun/gvisor_posix.go
Normal file
118
common/tun/gvisor_posix.go
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
package tun
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/buf"
|
||||||
|
"github.com/sagernet/sing/common/rw"
|
||||||
|
|
||||||
|
gBuffer "gvisor.dev/gvisor/pkg/buffer"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ stack.LinkEndpoint = (*PosixEndpoint)(nil)
|
||||||
|
|
||||||
|
type PosixEndpoint struct {
|
||||||
|
fd uintptr
|
||||||
|
mtu uint32
|
||||||
|
file *os.File
|
||||||
|
dispatcher stack.NetworkDispatcher
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPosixEndpoint(tunFd uintptr, tunMtu uint32) (stack.LinkEndpoint, error) {
|
||||||
|
return &PosixEndpoint{
|
||||||
|
fd: tunFd,
|
||||||
|
mtu: tunMtu,
|
||||||
|
file: os.NewFile(tunFd, "tun"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) MTU() uint32 {
|
||||||
|
return e.mtu
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) MaxHeaderLength() uint16 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) LinkAddress() tcpip.LinkAddress {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) Capabilities() stack.LinkEndpointCapabilities {
|
||||||
|
return stack.CapabilityNone
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) Attach(dispatcher stack.NetworkDispatcher) {
|
||||||
|
if dispatcher == nil && e.dispatcher != nil {
|
||||||
|
e.dispatcher = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if dispatcher != nil && e.dispatcher == nil {
|
||||||
|
e.dispatcher = dispatcher
|
||||||
|
go e.dispatchLoop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) dispatchLoop() {
|
||||||
|
_buffer := buf.StackNewPacket()
|
||||||
|
defer common.KeepAlive(_buffer)
|
||||||
|
buffer := common.Dup(_buffer)
|
||||||
|
defer buffer.Release()
|
||||||
|
for {
|
||||||
|
n, err := e.file.Read(buffer.FreeBytes())
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
var view gBuffer.View
|
||||||
|
view.Append(buffer.To(n))
|
||||||
|
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||||
|
Payload: view,
|
||||||
|
IsForwardedPacket: true,
|
||||||
|
})
|
||||||
|
defer pkt.DecRef()
|
||||||
|
var p tcpip.NetworkProtocolNumber
|
||||||
|
ipHeader, ok := pkt.Data().PullUp(1)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch header.IPVersion(ipHeader) {
|
||||||
|
case header.IPv4Version:
|
||||||
|
p = header.IPv4ProtocolNumber
|
||||||
|
case header.IPv6Version:
|
||||||
|
p = header.IPv6ProtocolNumber
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
e.dispatcher.DeliverNetworkPacket(p, pkt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) IsAttached() bool {
|
||||||
|
return e.dispatcher != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) Wait() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) ARPHardwareType() header.ARPHardwareType {
|
||||||
|
return header.ARPHardwareNone
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) AddHeader(buffer *stack.PacketBuffer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PosixEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) {
|
||||||
|
var n int
|
||||||
|
for _, packet := range pkts.AsSlice() {
|
||||||
|
_, err := rw.WriteV(e.fd, packet.Slices())
|
||||||
|
if err != nil {
|
||||||
|
return n, &tcpip.ErrAborted{}
|
||||||
|
}
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
12
common/tun/tun.go
Normal file
12
common/tun/tun.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package tun
|
||||||
|
|
||||||
|
import (
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Handler interface {
|
||||||
|
N.TCPConnectionHandler
|
||||||
|
N.UDPConnectionHandler
|
||||||
|
E.Handler
|
||||||
|
}
|
51
common/tun/tun_linux.go
Normal file
51
common/tun/tun_linux.go
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package tun
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
|
"github.com/vishvananda/netlink"
|
||||||
|
"gvisor.dev/gvisor/pkg/tcpip/link/tun"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Open(name string) (uintptr, error) {
|
||||||
|
tunFd, err := tun.Open(name)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uintptr(tunFd), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Configure(name string, inet4Address netip.Prefix, inet6Address netip.Prefix, mtu uint32) error {
|
||||||
|
tunLink, err := netlink.LinkByName(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if inet4Address.IsValid() {
|
||||||
|
addr4, _ := netlink.ParseAddr(inet4Address.String())
|
||||||
|
err = netlink.AddrAdd(tunLink, addr4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if inet6Address.IsValid() {
|
||||||
|
addr6, _ := netlink.ParseAddr(inet6Address.String())
|
||||||
|
err = netlink.AddrAdd(tunLink, addr6)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = netlink.LinkSetMTU(tunLink, int(mtu))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = netlink.LinkSetUp(tunLink)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
11
common/tun/tun_other.go
Normal file
11
common/tun/tun_other.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
//go:build !linux
|
||||||
|
|
||||||
|
package tun
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Open(name string) (uintptr, error) {
|
||||||
|
return 0, os.ErrInvalid
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build cgo
|
||||||
|
|
||||||
package constant
|
package constant
|
||||||
|
|
||||||
const CGO_ENABLED = true
|
const CGO_ENABLED = true
|
||||||
|
|
|
@ -7,4 +7,5 @@ const (
|
||||||
TypeHTTP = "http"
|
TypeHTTP = "http"
|
||||||
TypeMixed = "mixed"
|
TypeMixed = "mixed"
|
||||||
TypeShadowsocks = "shadowsocks"
|
TypeShadowsocks = "shadowsocks"
|
||||||
|
TypeTun = "tun"
|
||||||
)
|
)
|
||||||
|
|
11
go.mod
11
go.mod
|
@ -7,23 +7,28 @@ require (
|
||||||
github.com/goccy/go-json v0.9.8
|
github.com/goccy/go-json v0.9.8
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||||
github.com/oschwald/maxminddb-golang v1.9.0
|
github.com/oschwald/maxminddb-golang v1.9.0
|
||||||
github.com/sagernet/sing v0.0.0-20220709022704-8843420c7814
|
github.com/sagernet/sing v0.0.0-20220709090827-3e39af603559
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/spf13/cobra v1.5.0
|
github.com/spf13/cobra v1.5.0
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
|
github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
||||||
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129
|
||||||
|
gvisor.dev/gvisor v0.0.0-20220708233959-72bdef768f07
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/google/btree v1.0.1 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
||||||
github.com/kr/pretty v0.1.0 // indirect
|
github.com/kr/pretty v0.1.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b // indirect
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect
|
||||||
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
lukechampine.com/blake3 v1.1.7 // indirect
|
lukechampine.com/blake3 v1.1.7 // indirect
|
||||||
|
|
23
go.sum
23
go.sum
|
@ -6,6 +6,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/goccy/go-json v0.9.8 h1:DxXB6MLd6yyel7CLph8EwNIonUtVZd3Ue5iRcL4DQCE=
|
github.com/goccy/go-json v0.9.8 h1:DxXB6MLd6yyel7CLph8EwNIonUtVZd3Ue5iRcL4DQCE=
|
||||||
github.com/goccy/go-json v0.9.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.9.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
|
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||||
|
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
@ -23,8 +25,8 @@ github.com/oschwald/maxminddb-golang v1.9.0/go.mod h1:TK+s/Z2oZq0rSl4PSeAEoP0bgm
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sagernet/sing v0.0.0-20220709022704-8843420c7814 h1:CqrZT6p8TeMaJfys/0Scl9lO5gu1VccUrBw8fAq3ZIk=
|
github.com/sagernet/sing v0.0.0-20220709090827-3e39af603559 h1:o5/fAARzVV2PkEDzjOct1FRUdWVw7hPDFYY8drulH50=
|
||||||
github.com/sagernet/sing v0.0.0-20220709022704-8843420c7814/go.mod h1:3ZmoGNg/nNJTyHAZFNRSPaXpNIwpDvyIiAUd0KIWV5c=
|
github.com/sagernet/sing v0.0.0-20220709090827-3e39af603559/go.mod h1:3ZmoGNg/nNJTyHAZFNRSPaXpNIwpDvyIiAUd0KIWV5c=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 h1:whNDUGOAX5GPZkSy4G3Gv9QyIgk5SXRyjkRuP7ohF8k=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 h1:whNDUGOAX5GPZkSy4G3Gv9QyIgk5SXRyjkRuP7ohF8k=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649/go.mod h1:MuyT+9fEPjvauAv0fSE0a6Q+l0Tv2ZrAafTkYfnxBFw=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649/go.mod h1:MuyT+9fEPjvauAv0fSE0a6Q+l0Tv2ZrAafTkYfnxBFw=
|
||||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||||
|
@ -39,13 +41,20 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86 h1:7SWt9pGCMaw+N1ZhRsaLKaYNviFhxambdoaoYlDqz1w=
|
||||||
|
github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||||
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60 h1:8NSylCMxLW4JvserAndSgFL7aPli6A68yf0bYFTcWCM=
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
|
||||||
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b h1:2n253B2r0pYSmEV+UNCQoPfU/FiaizQEK5Gu4Bq4JE8=
|
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=
|
||||||
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||||
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
@ -53,5 +62,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gvisor.dev/gvisor v0.0.0-20220708233959-72bdef768f07 h1:EBa4BJfuxvdpvMGq6gw347MDptuFgqDHhuTEKxCCQ5U=
|
||||||
|
gvisor.dev/gvisor v0.0.0-20220708233959-72bdef768f07/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM=
|
||||||
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
||||||
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
||||||
|
|
|
@ -34,6 +34,8 @@ func New(ctx context.Context, router adapter.Router, logger log.Logger, index in
|
||||||
return NewMixed(ctx, router, inboundLogger, options.Tag, options.MixedOptions), nil
|
return NewMixed(ctx, router, inboundLogger, options.Tag, options.MixedOptions), nil
|
||||||
case C.TypeShadowsocks:
|
case C.TypeShadowsocks:
|
||||||
return NewShadowsocks(ctx, router, inboundLogger, options.Tag, options.ShadowsocksOptions)
|
return NewShadowsocks(ctx, router, inboundLogger, options.Tag, options.ShadowsocksOptions)
|
||||||
|
case C.TypeTun:
|
||||||
|
return NewTun(ctx, router, inboundLogger, options.Tag, options.TunOptions)
|
||||||
default:
|
default:
|
||||||
return nil, E.New("unknown inbound type: ", options.Type)
|
return nil, E.New("unknown inbound type: ", options.Type)
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,12 +231,16 @@ func (a *myInboundAdapter) newError(err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *myInboundAdapter) NewError(ctx context.Context, err error) {
|
func (a *myInboundAdapter) NewError(ctx context.Context, err error) {
|
||||||
|
NewError(a.logger, ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewError(logger log.Logger, ctx context.Context, err error) {
|
||||||
common.Close(err)
|
common.Close(err)
|
||||||
if E.IsClosed(err) {
|
if E.IsClosed(err) {
|
||||||
a.logger.WithContext(ctx).Debug("connection closed")
|
logger.WithContext(ctx).Debug("connection closed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
a.logger.WithContext(ctx).Error(err)
|
logger.WithContext(ctx).Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
||||||
|
|
142
inbound/tun.go
Normal file
142
inbound/tun.go
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
//go:build !no_tun
|
||||||
|
|
||||||
|
package inbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/common/tun"
|
||||||
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/log"
|
||||||
|
"github.com/sagernet/sing-box/option"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
F "github.com/sagernet/sing/common/format"
|
||||||
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ adapter.Inbound = (*Tun)(nil)
|
||||||
|
|
||||||
|
type Tun struct {
|
||||||
|
tag string
|
||||||
|
|
||||||
|
ctx context.Context
|
||||||
|
router adapter.Router
|
||||||
|
logger log.Logger
|
||||||
|
options option.TunInboundOptions
|
||||||
|
|
||||||
|
tunFd uintptr
|
||||||
|
tun *tun.GVisorTun
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTun(ctx context.Context, router adapter.Router, logger log.Logger, tag string, options option.TunInboundOptions) (*Tun, error) {
|
||||||
|
return &Tun{
|
||||||
|
tag: tag,
|
||||||
|
ctx: ctx,
|
||||||
|
router: router,
|
||||||
|
logger: logger,
|
||||||
|
options: options,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tun) Type() string {
|
||||||
|
return C.TypeTun
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tun) Tag() string {
|
||||||
|
return t.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tun) Start() error {
|
||||||
|
tunName := t.options.InterfaceName
|
||||||
|
if tunName == "" {
|
||||||
|
tunName = mkInterfaceName()
|
||||||
|
}
|
||||||
|
var mtu uint32
|
||||||
|
if t.options.MTU != 0 {
|
||||||
|
mtu = t.options.MTU
|
||||||
|
} else {
|
||||||
|
mtu = 1500
|
||||||
|
}
|
||||||
|
|
||||||
|
tunFd, err := tun.Open(tunName)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "create tun interface")
|
||||||
|
}
|
||||||
|
err = tun.Configure(tunName, netip.Prefix(t.options.Inet4Address), netip.Prefix(t.options.Inet6Address), mtu)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "configure tun interface")
|
||||||
|
}
|
||||||
|
t.tunFd = tunFd
|
||||||
|
t.tun = tun.NewGVisor(t.ctx, tunFd, mtu, t)
|
||||||
|
err = t.tun.Start()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.logger.Info("started at ", tunName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tun) Close() error {
|
||||||
|
return E.Errors(
|
||||||
|
t.tun.Close(),
|
||||||
|
os.NewFile(t.tunFd, "tun").Close(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error {
|
||||||
|
t.logger.WithContext(ctx).Info("inbound connection from ", upstreamMetadata.Source)
|
||||||
|
t.logger.WithContext(ctx).Info("inbound connection to ", upstreamMetadata.Destination)
|
||||||
|
var metadata adapter.InboundContext
|
||||||
|
metadata.Inbound = t.tag
|
||||||
|
metadata.Network = C.NetworkTCP
|
||||||
|
metadata.Source = upstreamMetadata.Source
|
||||||
|
metadata.Destination = upstreamMetadata.Destination
|
||||||
|
return t.router.RouteConnection(ctx, conn, metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstreamMetadata M.Metadata) error {
|
||||||
|
t.logger.WithContext(ctx).Info("inbound packet connection from ", upstreamMetadata.Source)
|
||||||
|
t.logger.WithContext(ctx).Info("inbound packet connection to ", upstreamMetadata.Destination)
|
||||||
|
var metadata adapter.InboundContext
|
||||||
|
metadata.Inbound = t.tag
|
||||||
|
metadata.Network = C.NetworkUDP
|
||||||
|
metadata.Source = upstreamMetadata.Source
|
||||||
|
metadata.Destination = upstreamMetadata.Destination
|
||||||
|
return t.router.RoutePacketConnection(ctx, conn, metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tun) NewError(ctx context.Context, err error) {
|
||||||
|
NewError(t.logger, ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mkInterfaceName() (tunName string) {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
tunName = "utun"
|
||||||
|
default:
|
||||||
|
tunName = "tun"
|
||||||
|
}
|
||||||
|
interfaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var tunIndex int
|
||||||
|
for _, netInterface := range interfaces {
|
||||||
|
if strings.HasPrefix(netInterface.Name, tunName) {
|
||||||
|
index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16)
|
||||||
|
if parseErr == nil {
|
||||||
|
tunIndex = int(index) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tunName = F.ToString(tunName, tunIndex)
|
||||||
|
return
|
||||||
|
}
|
16
inbound/tun_disabled.go
Normal file
16
inbound/tun_disabled.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
//go:build no_tun
|
||||||
|
|
||||||
|
package inbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/log"
|
||||||
|
"github.com/sagernet/sing-box/option"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewTun(ctx context.Context, router adapter.Router, logger log.Logger, tag string, options option.TunInboundOptions) (adapter.Inbound, error) {
|
||||||
|
return nil, E.New("tun disabled in this build")
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ type _Inbound struct {
|
||||||
HTTPOptions SimpleInboundOptions `json:"-"`
|
HTTPOptions SimpleInboundOptions `json:"-"`
|
||||||
MixedOptions SimpleInboundOptions `json:"-"`
|
MixedOptions SimpleInboundOptions `json:"-"`
|
||||||
ShadowsocksOptions ShadowsocksInboundOptions `json:"-"`
|
ShadowsocksOptions ShadowsocksInboundOptions `json:"-"`
|
||||||
|
TunOptions TunInboundOptions `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Inbound _Inbound
|
type Inbound _Inbound
|
||||||
|
@ -28,7 +29,8 @@ func (h Inbound) Equals(other Inbound) bool {
|
||||||
h.SocksOptions.Equals(other.SocksOptions) &&
|
h.SocksOptions.Equals(other.SocksOptions) &&
|
||||||
h.HTTPOptions.Equals(other.HTTPOptions) &&
|
h.HTTPOptions.Equals(other.HTTPOptions) &&
|
||||||
h.MixedOptions.Equals(other.MixedOptions) &&
|
h.MixedOptions.Equals(other.MixedOptions) &&
|
||||||
h.ShadowsocksOptions.Equals(other.ShadowsocksOptions)
|
h.ShadowsocksOptions.Equals(other.ShadowsocksOptions) &&
|
||||||
|
h.TunOptions == other.TunOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h Inbound) MarshalJSON() ([]byte, error) {
|
func (h Inbound) MarshalJSON() ([]byte, error) {
|
||||||
|
@ -44,6 +46,8 @@ func (h Inbound) MarshalJSON() ([]byte, error) {
|
||||||
v = h.MixedOptions
|
v = h.MixedOptions
|
||||||
case C.TypeShadowsocks:
|
case C.TypeShadowsocks:
|
||||||
v = h.ShadowsocksOptions
|
v = h.ShadowsocksOptions
|
||||||
|
case C.TypeTun:
|
||||||
|
v = h.TunOptions
|
||||||
default:
|
default:
|
||||||
return nil, E.New("unknown inbound type: ", h.Type)
|
return nil, E.New("unknown inbound type: ", h.Type)
|
||||||
}
|
}
|
||||||
|
@ -67,6 +71,8 @@ func (h *Inbound) UnmarshalJSON(bytes []byte) error {
|
||||||
v = &h.MixedOptions
|
v = &h.MixedOptions
|
||||||
case C.TypeShadowsocks:
|
case C.TypeShadowsocks:
|
||||||
v = &h.ShadowsocksOptions
|
v = &h.ShadowsocksOptions
|
||||||
|
case C.TypeTun:
|
||||||
|
v = &h.TunOptions
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -132,3 +138,10 @@ type ShadowsocksDestination struct {
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
ServerOptions
|
ServerOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TunInboundOptions struct {
|
||||||
|
InterfaceName string `json:"interface_name"`
|
||||||
|
MTU uint32 `json:"mtu,omitempty"`
|
||||||
|
Inet4Address ListenPrefix `json:"inet4_address"`
|
||||||
|
Inet6Address ListenPrefix `json:"inet6_address"`
|
||||||
|
}
|
||||||
|
|
|
@ -155,3 +155,27 @@ func (d *Duration) UnmarshalJSON(bytes []byte) error {
|
||||||
*d = Duration(duration)
|
*d = Duration(duration)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListenPrefix netip.Prefix
|
||||||
|
|
||||||
|
func (p ListenPrefix) MarshalJSON() ([]byte, error) {
|
||||||
|
prefix := netip.Prefix(p)
|
||||||
|
if !prefix.IsValid() {
|
||||||
|
return json.Marshal("")
|
||||||
|
}
|
||||||
|
return json.Marshal(prefix.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ListenPrefix) UnmarshalJSON(bytes []byte) error {
|
||||||
|
var value string
|
||||||
|
err := json.Unmarshal(bytes, &value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
prefix, err := netip.ParsePrefix(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*p = ListenPrefix(prefix)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
10
test/go.mod
10
test/go.mod
|
@ -5,11 +5,11 @@ go 1.18
|
||||||
require (
|
require (
|
||||||
github.com/docker/docker v20.10.17+incompatible
|
github.com/docker/docker v20.10.17+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/sagernet/sing v0.0.0-20220709022704-8843420c7814
|
github.com/sagernet/sing v0.0.0-20220709090827-3e39af603559
|
||||||
github.com/sagernet/sing-box v0.0.0
|
github.com/sagernet/sing-box v0.0.0
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/sagernet/sing-box => ../
|
replace github.com/sagernet/sing-box => ../
|
||||||
|
@ -22,6 +22,7 @@ require (
|
||||||
github.com/docker/go-units v0.4.0 // indirect
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
github.com/goccy/go-json v0.9.8 // indirect
|
github.com/goccy/go-json v0.9.8 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/google/btree v1.0.1 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
||||||
|
@ -33,10 +34,13 @@ require (
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 // indirect
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 // indirect
|
||||||
|
github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86 // indirect
|
||||||
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b // indirect
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect
|
||||||
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
|
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
gotest.tools/v3 v3.3.0 // indirect
|
gotest.tools/v3 v3.3.0 // indirect
|
||||||
|
gvisor.dev/gvisor v0.0.0-20220708233959-72bdef768f07 // indirect
|
||||||
lukechampine.com/blake3 v1.1.7 // indirect
|
lukechampine.com/blake3 v1.1.7 // indirect
|
||||||
)
|
)
|
||||||
|
|
23
test/go.sum
23
test/go.sum
|
@ -21,10 +21,12 @@ github.com/goccy/go-json v0.9.8 h1:DxXB6MLd6yyel7CLph8EwNIonUtVZd3Ue5iRcL4DQCE=
|
||||||
github.com/goccy/go-json v0.9.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.9.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
|
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||||
|
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
@ -50,8 +52,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/sagernet/sing v0.0.0-20220709022704-8843420c7814 h1:CqrZT6p8TeMaJfys/0Scl9lO5gu1VccUrBw8fAq3ZIk=
|
github.com/sagernet/sing v0.0.0-20220709090827-3e39af603559 h1:o5/fAARzVV2PkEDzjOct1FRUdWVw7hPDFYY8drulH50=
|
||||||
github.com/sagernet/sing v0.0.0-20220709022704-8843420c7814/go.mod h1:3ZmoGNg/nNJTyHAZFNRSPaXpNIwpDvyIiAUd0KIWV5c=
|
github.com/sagernet/sing v0.0.0-20220709090827-3e39af603559/go.mod h1:3ZmoGNg/nNJTyHAZFNRSPaXpNIwpDvyIiAUd0KIWV5c=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 h1:whNDUGOAX5GPZkSy4G3Gv9QyIgk5SXRyjkRuP7ohF8k=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649 h1:whNDUGOAX5GPZkSy4G3Gv9QyIgk5SXRyjkRuP7ohF8k=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649/go.mod h1:MuyT+9fEPjvauAv0fSE0a6Q+l0Tv2ZrAafTkYfnxBFw=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220701084835-2208da1d8649/go.mod h1:MuyT+9fEPjvauAv0fSE0a6Q+l0Tv2ZrAafTkYfnxBFw=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
@ -64,6 +66,10 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86 h1:7SWt9pGCMaw+N1ZhRsaLKaYNviFhxambdoaoYlDqz1w=
|
||||||
|
github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||||
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
@ -78,20 +84,21 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60 h1:8NSylCMxLW4JvserAndSgFL7aPli6A68yf0bYFTcWCM=
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
|
||||||
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b h1:2n253B2r0pYSmEV+UNCQoPfU/FiaizQEK5Gu4Bq4JE8=
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=
|
||||||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
|
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
|
||||||
|
@ -114,5 +121,7 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||||
gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
|
gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
|
||||||
|
gvisor.dev/gvisor v0.0.0-20220708233959-72bdef768f07 h1:EBa4BJfuxvdpvMGq6gw347MDptuFgqDHhuTEKxCCQ5U=
|
||||||
|
gvisor.dev/gvisor v0.0.0-20220708233959-72bdef768f07/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM=
|
||||||
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
||||||
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
||||||
|
|
Loading…
Reference in a new issue