update gvisor
Chore: use "-m mark --mark" instead of "-m owner --uid-owner"
This commit is contained in:
Clash-Mini
2022-02-04 06:11:24 +08:00
parent 176eb3926b
commit 3b277aa8ec
19 changed files with 52 additions and 1981 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/Dreamacro/clash/listener/inner"
"net"
"os"
"runtime"
"strconv"
"sync"
@ -322,23 +323,50 @@ func ReCreateMixed(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.P
log.Infoln("Mixed(http+socks) proxy listening at: %s", mixedListener.Address())
}
func ReCreateTun(conf config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) error {
//func ReCreateTun(conf config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) error {
// tunMux.Lock()
// defer tunMux.Unlock()
//
// if tunAdapter != nil {
// tunAdapter.Close()
// tunAdapter = nil
// }
//
// if !conf.Enable {
// return nil
// }
//
// var err error
// tunAdapter, err = tun.New(conf, tcpIn, udpIn)
//
// return err
//}
func ReCreateTun(conf config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) {
tunMux.Lock()
defer tunMux.Unlock()
var err error
defer func() {
if err != nil {
log.Errorln("Start TUN interface error: %s", err.Error())
os.Exit(2)
}
}()
if tunAdapter != nil {
tunAdapter.Close()
tunAdapter = nil
}
if !conf.Enable {
return nil
return
}
var err error
tunAdapter, err = tun.New(conf, tcpIn, udpIn)
return err
if err != nil {
log.Warnln("Failed to start TUN interface: %s", err.Error())
}
}
// GetPorts return the ports of proxy servers

View File

@ -54,7 +54,7 @@ func NewAdapter(device dev.TunDevice, conf config.Tun, tcpIn chan<- C.ConnContex
NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol},
})
adapter := &gvisorAdapter{
device: device,
ipstack: ipstack,
udpIn: udpIn,
@ -116,7 +116,7 @@ func NewAdapter(device dev.TunDevice, conf config.Tun, tcpIn chan<- C.ConnContex
ipstack.SetTransportProtocolHandler(udp.ProtocolNumber, adapter.udpHandlePacket)
if resolver.DefaultResolver != nil {
err = adapter.ReCreateDNSServer(resolver.DefaultResolver.(*dns.Resolver), resolver.DefaultHostMapper.(*dns.ResolverEnhancer), conf.DNSListen)
err = adapter.ReCreateDNSServer(resolver.DefaultResolver.(*dns.Resolver), resolver.DefaultHostMapper.(*dns.ResolverEnhancer), conf.DnsHijack)
if err != nil {
return nil, err
}

View File

@ -1,87 +0,0 @@
package lwip
import (
"encoding/binary"
"io"
"net"
"time"
"github.com/Dreamacro/clash/component/resolver"
D "github.com/Dreamacro/clash/listener/tun/ipstack/commons"
"github.com/Dreamacro/clash/log"
"github.com/yaling888/go-lwip"
)
const defaultDnsReadTimeout = time.Second * 8
func shouldHijackDns(dnsIP net.IP, targetIp net.IP, targetPort int) bool {
if targetPort != 53 {
return false
}
return dnsIP.Equal(net.IPv4zero) || dnsIP.Equal(targetIp)
}
func hijackUDPDns(conn golwip.UDPConn, pkt []byte, addr *net.UDPAddr) {
go func() {
defer func(conn golwip.UDPConn) {
_ = conn.Close()
}(conn)
answer, err := D.RelayDnsPacket(pkt)
if err != nil {
return
}
_, _ = conn.WriteFrom(answer, addr)
}()
}
func hijackTCPDns(conn net.Conn) {
go func() {
defer func(conn net.Conn) {
_ = conn.Close()
}(conn)
if err := conn.SetDeadline(time.Now().Add(defaultDnsReadTimeout)); err != nil {
return
}
for {
var length uint16
if binary.Read(conn, binary.BigEndian, &length) != nil {
return
}
data := make([]byte, length)
_, err := io.ReadFull(conn, data)
if err != nil {
return
}
rb, err := D.RelayDnsPacket(data)
if err != nil {
continue
}
if binary.Write(conn, binary.BigEndian, uint16(len(rb))) != nil {
return
}
if _, err = conn.Write(rb); err != nil {
return
}
}
}()
}
type dnsHandler struct{}
func newDnsHandler() golwip.DnsHandler {
return &dnsHandler{}
}
func (d dnsHandler) ResolveIP(host string) (net.IP, error) {
log.Debugln("[TUN] lwip resolve ip for host: %s", host)
return resolver.ResolveIP(host)
}

View File

@ -1,61 +0,0 @@
package lwip
import (
"net"
"strconv"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/context"
"github.com/Dreamacro/clash/log"
"github.com/yaling888/go-lwip"
)
type tcpHandler struct {
dnsIP net.IP
tcpIn chan<- C.ConnContext
}
func newTCPHandler(dnsIP net.IP, tcpIn chan<- C.ConnContext) golwip.TCPConnHandler {
return &tcpHandler{dnsIP, tcpIn}
}
func (h *tcpHandler) Handle(conn net.Conn, target *net.TCPAddr) error {
if shouldHijackDns(h.dnsIP, target.IP, target.Port) {
hijackTCPDns(conn)
log.Debugln("[TUN] hijack dns tcp: %s:%d", target.IP.String(), target.Port)
return nil
}
if conn.RemoteAddr() == nil {
_ = conn.Close()
return nil
}
src, _ := conn.LocalAddr().(*net.TCPAddr)
dst, _ := conn.RemoteAddr().(*net.TCPAddr)
addrType := C.AtypIPv4
if dst.IP.To4() == nil {
addrType = C.AtypIPv6
}
metadata := &C.Metadata{
NetWork: C.TCP,
Type: C.TUN,
SrcIP: src.IP,
DstIP: dst.IP,
SrcPort: strconv.Itoa(src.Port),
DstPort: strconv.Itoa(dst.Port),
AddrType: addrType,
Host: "",
}
go func(conn net.Conn, metadata *C.Metadata) {
//if c, ok := conn.(*net.TCPConn); ok {
// c.SetKeepAlive(true)
//}
h.tcpIn <- context.NewConnContext(conn, metadata)
}(conn, metadata)
return nil
}

View File

@ -1,121 +0,0 @@
package lwip
import (
"io"
"net"
"sync"
"github.com/Dreamacro/clash/adapter/inbound"
"github.com/Dreamacro/clash/common/pool"
"github.com/Dreamacro/clash/config"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/tun/dev"
"github.com/Dreamacro/clash/listener/tun/ipstack"
"github.com/Dreamacro/clash/log"
"github.com/yaling888/go-lwip"
)
type lwipAdapter struct {
device dev.TunDevice
lwipStack golwip.LWIPStack
lock sync.Mutex
mtu int
stackName string
dnsListen string
autoRoute bool
}
func NewAdapter(device dev.TunDevice, conf config.Tun, mtu int, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) (ipstack.TunAdapter, error) {
adapter := &lwipAdapter{
device: device,
mtu: mtu,
stackName: conf.Stack,
dnsListen: conf.DNSListen,
autoRoute: conf.AutoRoute,
}
adapter.lock.Lock()
defer adapter.lock.Unlock()
dnsHost, _, err := net.SplitHostPort(conf.DNSListen)
if err != nil {
return nil, err
}
dnsIP := net.ParseIP(dnsHost)
// Register output function, write packets from lwip stack to tun device
golwip.RegisterOutputFn(func(data []byte) (int, error) {
return device.Write(data)
})
// Set custom buffer pool
golwip.SetPoolAllocator(newLWIPPool())
// Setup TCP/IP stack.
lwipStack, err := golwip.NewLWIPStack(mtu)
if err != nil {
return nil, err
}
adapter.lwipStack = lwipStack
golwip.RegisterDnsHandler(newDnsHandler())
golwip.RegisterTCPConnHandler(newTCPHandler(dnsIP, tcpIn))
golwip.RegisterUDPConnHandler(newUDPHandler(dnsIP, udpIn))
// Copy packets from tun device to lwip stack, it's the loop.
go func(lwipStack golwip.LWIPStack, device dev.TunDevice, mtu int) {
_, err := io.CopyBuffer(lwipStack.(io.Writer), device, make([]byte, mtu))
if err != nil {
log.Debugln("copying data failed: %v", err)
}
}(lwipStack, device, mtu)
return adapter, nil
}
func (l *lwipAdapter) Stack() string {
return l.stackName
}
func (l *lwipAdapter) AutoRoute() bool {
return l.autoRoute
}
func (l *lwipAdapter) DNSListen() string {
return l.dnsListen
}
func (l *lwipAdapter) Close() {
l.lock.Lock()
defer l.lock.Unlock()
l.stopLocked()
}
func (l *lwipAdapter) stopLocked() {
if l.lwipStack != nil {
_ = l.lwipStack.Close()
}
if l.device != nil {
_ = l.device.Close()
}
l.lwipStack = nil
l.device = nil
}
type lwipPool struct{}
func (p lwipPool) Get(size int) []byte {
return pool.Get(size)
}
func (p lwipPool) Put(buf []byte) error {
return pool.Put(buf)
}
func newLWIPPool() golwip.LWIPPool {
return &lwipPool{}
}

View File

@ -1,74 +0,0 @@
package lwip
import (
"io"
"net"
"github.com/Dreamacro/clash/adapter/inbound"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/transport/socks5"
"github.com/yaling888/go-lwip"
)
type udpPacket struct {
source *net.UDPAddr
payload []byte
sender golwip.UDPConn
}
func (u *udpPacket) Data() []byte {
return u.payload
}
func (u *udpPacket) WriteBack(b []byte, addr net.Addr) (n int, err error) {
_, ok := addr.(*net.UDPAddr)
if !ok {
return 0, io.ErrClosedPipe
}
return u.sender.WriteFrom(b, u.source)
}
func (u *udpPacket) Drop() {
}
func (u *udpPacket) LocalAddr() net.Addr {
return u.source
}
type udpHandler struct {
dnsIP net.IP
udpIn chan<- *inbound.PacketAdapter
}
func newUDPHandler(dnsIP net.IP, udpIn chan<- *inbound.PacketAdapter) golwip.UDPConnHandler {
return &udpHandler{dnsIP, udpIn}
}
func (h *udpHandler) Connect(golwip.UDPConn, *net.UDPAddr) error {
return nil
}
func (h *udpHandler) ReceiveTo(conn golwip.UDPConn, data []byte, addr *net.UDPAddr) error {
if shouldHijackDns(h.dnsIP, addr.IP, addr.Port) {
hijackUDPDns(conn, data, addr)
log.Debugln("[TUN] hijack dns udp: %s:%d", addr.IP.String(), addr.Port)
return nil
}
packet := &udpPacket{
source: conn.LocalAddr(),
payload: data,
sender: conn,
}
go func(addr *net.UDPAddr, packet *udpPacket) {
select {
case h.udpIn <- inbound.NewPacket(socks5.ParseAddrToSocksAddr(addr), packet, C.TUN):
default:
}
}(addr, packet)
return nil
}