Chore: cleanup code
This commit is contained in:
@@ -31,11 +31,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
allowLan = false
|
||||
bindAddress = "*"
|
||||
lastTunConf *config.Tun
|
||||
lastTunAddressPrefix *netip.Prefix
|
||||
tunAddressPrefix *netip.Prefix
|
||||
allowLan = false
|
||||
bindAddress = "*"
|
||||
lastTunConf *config.Tun
|
||||
|
||||
socksListener *socks.Listener
|
||||
socksUDPListener *socks.UDPListener
|
||||
@@ -109,10 +107,6 @@ func SetBindAddress(host string) {
|
||||
bindAddress = host
|
||||
}
|
||||
|
||||
func SetTunAddressPrefix(tunAddress *netip.Prefix) {
|
||||
tunAddressPrefix = tunAddress
|
||||
}
|
||||
|
||||
func ReCreateHTTP(port int, tcpIn chan<- C.ConnContext) {
|
||||
httpMux.Lock()
|
||||
defer httpMux.Unlock()
|
||||
@@ -363,14 +357,10 @@ func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *
|
||||
}
|
||||
}()
|
||||
|
||||
if tunAddressPrefix == nil {
|
||||
tunAddressPrefix = lastTunAddressPrefix
|
||||
}
|
||||
|
||||
tunConf.DNSHijack = C.RemoveDuplicateDNSUrl(tunConf.DNSHijack)
|
||||
|
||||
if tunStackListener != nil {
|
||||
if !hasTunConfigChange(tunConf, tunAddressPrefix) {
|
||||
if !hasTunConfigChange(tunConf) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -379,7 +369,6 @@ func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *
|
||||
}
|
||||
|
||||
lastTunConf = tunConf
|
||||
lastTunAddressPrefix = tunAddressPrefix
|
||||
|
||||
if !tunConf.Enable {
|
||||
return
|
||||
@@ -391,7 +380,7 @@ func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *
|
||||
udpIn: udpIn,
|
||||
}
|
||||
|
||||
tunStackListener, err = tun.New(tunConf, tunAddressPrefix, tcpIn, udpIn, callback)
|
||||
tunStackListener, err = tun.New(tunConf, tcpIn, udpIn, callback)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -535,7 +524,7 @@ func genAddr(host string, port int, allowLan bool) string {
|
||||
return fmt.Sprintf("127.0.0.1:%d", port)
|
||||
}
|
||||
|
||||
func hasTunConfigChange(tunConf *config.Tun, tunAddressPrefix *netip.Prefix) bool {
|
||||
func hasTunConfigChange(tunConf *config.Tun) bool {
|
||||
if lastTunConf == nil {
|
||||
return true
|
||||
}
|
||||
@@ -558,11 +547,11 @@ func hasTunConfigChange(tunConf *config.Tun, tunAddressPrefix *netip.Prefix) boo
|
||||
return true
|
||||
}
|
||||
|
||||
if (tunAddressPrefix != nil && lastTunAddressPrefix == nil) || (tunAddressPrefix == nil && lastTunAddressPrefix != nil) {
|
||||
if (lastTunConf.TunAddressPrefix != nil && tunConf.TunAddressPrefix == nil) || (lastTunConf.TunAddressPrefix == nil && tunConf.TunAddressPrefix != nil) {
|
||||
return true
|
||||
}
|
||||
|
||||
if tunAddressPrefix != nil && lastTunAddressPrefix != nil && *tunAddressPrefix != *lastTunAddressPrefix {
|
||||
if lastTunConf.TunAddressPrefix != nil && tunConf.TunAddressPrefix != nil && *lastTunConf.TunAddressPrefix != *tunConf.TunAddressPrefix {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,11 @@ func NewUDP(addr string, in chan<- *inbound.PacketAdapter) (*UDPListener, error)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if rAddr.Addr().Is4() {
|
||||
// try to unmap 4in6 address
|
||||
lAddr = netip.AddrPortFrom(lAddr.Addr().Unmap(), lAddr.Port())
|
||||
}
|
||||
handlePacketConn(in, buf[:n], lAddr, rAddr)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -41,6 +41,10 @@ func (f *FD) Name() string {
|
||||
return strconv.Itoa(f.fd)
|
||||
}
|
||||
|
||||
func (f *FD) MTU() uint32 {
|
||||
return f.mtu
|
||||
}
|
||||
|
||||
func (f *FD) Close() error {
|
||||
err := unix.Close(f.fd)
|
||||
if f.file != nil {
|
||||
|
||||
@@ -4,8 +4,48 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/Dreamacro/clash/listener/tun/device"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
func Open(name string, mtu uint32) (device.Device, error) {
|
||||
type FD struct {
|
||||
stack.LinkEndpoint
|
||||
}
|
||||
|
||||
func Open(_ string, _ uint32) (device.Device, error) {
|
||||
return nil, errors.New("not supported")
|
||||
}
|
||||
|
||||
func (f *FD) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *FD) Type() string {
|
||||
return Driver
|
||||
}
|
||||
|
||||
func (f *FD) Read(_ []byte) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (f *FD) Write(_ []byte) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (f *FD) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FD) UseEndpoint() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FD) UseIOBased() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FD) MTU() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var _ device.Device = (*FD)(nil)
|
||||
|
||||
@@ -59,10 +59,13 @@ func Open(name string, mtu uint32) (_ device.Device, err error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get mtu: %w", err)
|
||||
}
|
||||
t.mtu = uint32(tunMTU)
|
||||
|
||||
if t.mtu == 0 {
|
||||
t.mtu = uint32(tunMTU)
|
||||
}
|
||||
|
||||
if t.offset > 0 {
|
||||
t.cache = make([]byte, 65535)
|
||||
t.cache = make([]byte, int(t.mtu)+t.offset)
|
||||
}
|
||||
|
||||
return t, nil
|
||||
@@ -108,6 +111,10 @@ func (t *TUN) Name() string {
|
||||
return name
|
||||
}
|
||||
|
||||
func (t *TUN) MTU() uint32 {
|
||||
return t.mtu
|
||||
}
|
||||
|
||||
func (t *TUN) UseEndpoint() error {
|
||||
ep, err := iobased.New(t, t.mtu, t.offset)
|
||||
if err != nil {
|
||||
|
||||
@@ -5,8 +5,10 @@ import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
dev "github.com/Dreamacro/clash/listener/tun/device"
|
||||
"github.com/Dreamacro/clash/listener/tun/device/fdbased"
|
||||
"github.com/Dreamacro/clash/listener/tun/device/tun"
|
||||
"github.com/Dreamacro/clash/listener/tun/ipstack/system/mars/tcpip"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, *UDP, error) {
|
||||
@@ -19,10 +21,27 @@ func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, *
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
t dev.Device
|
||||
mtu uint32
|
||||
ok bool
|
||||
)
|
||||
if t, ok = device.(*tun.TUN); ok {
|
||||
mtu = t.MTU()
|
||||
} else if t, ok = device.(*fdbased.FD); ok {
|
||||
mtu = t.MTU()
|
||||
}
|
||||
|
||||
bufferSize := int(mtu)
|
||||
|
||||
if bufferSize == 0 {
|
||||
bufferSize = 64 * 1024
|
||||
}
|
||||
|
||||
tab := newTable()
|
||||
udp := &UDP{
|
||||
device: device,
|
||||
buf: [0xffff]byte{},
|
||||
buf: make([]byte, bufferSize),
|
||||
}
|
||||
tcp := &TCP{
|
||||
listener: listener,
|
||||
@@ -38,7 +57,7 @@ func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, *
|
||||
_ = udp.Close()
|
||||
}()
|
||||
|
||||
buf := make([]byte, 0xffff)
|
||||
buf := make([]byte, bufferSize)
|
||||
|
||||
for {
|
||||
n, err := device.Read(buf)
|
||||
@@ -133,11 +152,7 @@ func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, *
|
||||
continue
|
||||
}
|
||||
|
||||
port, err = tab.newConn(tup)
|
||||
if err != nil {
|
||||
log.Warnln("[STACK] drop tcp packet by system stack: %v", err)
|
||||
continue
|
||||
}
|
||||
port = tab.newConn(tup)
|
||||
}
|
||||
|
||||
ip.SetSourceIP(portal)
|
||||
@@ -156,7 +171,7 @@ func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, *
|
||||
continue
|
||||
}
|
||||
|
||||
go udp.handleUDPPacket(ip, u)
|
||||
udp.handleUDPPacket(ip, u)
|
||||
case tcpip.ICMP:
|
||||
i := tcpip.ICMPPacket(ip.Payload())
|
||||
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
package nat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"sync"
|
||||
|
||||
"github.com/Dreamacro/clash/common/generics/list"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -31,8 +27,6 @@ type table struct {
|
||||
tuples map[tuple]*list.Element[*binding]
|
||||
ports [portLength]*list.Element[*binding]
|
||||
available *list.List[*binding]
|
||||
mux sync.Mutex
|
||||
count uint16
|
||||
}
|
||||
|
||||
func (t *table) tupleOf(port uint16) tuple {
|
||||
@@ -49,64 +43,27 @@ func (t *table) tupleOf(port uint16) tuple {
|
||||
}
|
||||
|
||||
func (t *table) portOf(tuple tuple) uint16 {
|
||||
t.mux.Lock()
|
||||
elm := t.tuples[tuple]
|
||||
if elm == nil {
|
||||
t.mux.Unlock()
|
||||
return 0
|
||||
}
|
||||
t.mux.Unlock()
|
||||
|
||||
t.available.MoveToFront(elm)
|
||||
|
||||
return portBegin + elm.Value.offset
|
||||
}
|
||||
|
||||
func (t *table) newConn(tuple tuple) (uint16, error) {
|
||||
t.mux.Lock()
|
||||
elm, err := t.availableConn()
|
||||
if err != nil {
|
||||
t.mux.Unlock()
|
||||
return 0, err
|
||||
}
|
||||
func (t *table) newConn(tuple tuple) uint16 {
|
||||
elm := t.available.Back()
|
||||
b := elm.Value
|
||||
|
||||
elm.Value.tuple = tuple
|
||||
delete(t.tuples, b.tuple)
|
||||
t.tuples[tuple] = elm
|
||||
t.mux.Unlock()
|
||||
b.tuple = tuple
|
||||
|
||||
return portBegin + elm.Value.offset, nil
|
||||
}
|
||||
t.available.MoveToFront(elm)
|
||||
|
||||
func (t *table) availableConn() (*list.Element[*binding], error) {
|
||||
var elm *list.Element[*binding]
|
||||
|
||||
for i := 0; i < portLength; i++ {
|
||||
elm = t.available.Back()
|
||||
t.available.MoveToFront(elm)
|
||||
|
||||
offset := elm.Value.offset
|
||||
tup := t.ports[offset].Value.tuple
|
||||
if t.tuples[tup] != nil && tup.SourceAddr.IsValid() {
|
||||
continue
|
||||
}
|
||||
|
||||
if t.count == portLength { // resize
|
||||
tuples := make(map[tuple]*list.Element[*binding], portLength)
|
||||
maps.Copy(tuples, t.tuples)
|
||||
t.tuples = tuples
|
||||
t.count = 1
|
||||
}
|
||||
return elm, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("too many open files, limits [%d, %d]", portLength, len(t.tuples))
|
||||
}
|
||||
|
||||
func (t *table) closeConn(tuple tuple) {
|
||||
t.mux.Lock()
|
||||
delete(t.tuples, tuple)
|
||||
t.count++
|
||||
t.mux.Unlock()
|
||||
return portBegin + b.offset
|
||||
}
|
||||
|
||||
func newTable() *table {
|
||||
@@ -114,7 +71,6 @@ func newTable() *table {
|
||||
tuples: make(map[tuple]*list.Element[*binding], portLength),
|
||||
ports: [portLength]*list.Element[*binding]{},
|
||||
available: list.New[*binding](),
|
||||
count: 1,
|
||||
}
|
||||
|
||||
for idx := range result.ports {
|
||||
|
||||
@@ -16,8 +16,6 @@ type conn struct {
|
||||
net.Conn
|
||||
|
||||
tuple tuple
|
||||
|
||||
close func()
|
||||
}
|
||||
|
||||
func (t *TCP) Accept() (net.Conn, error) {
|
||||
@@ -41,9 +39,6 @@ func (t *TCP) Accept() (net.Conn, error) {
|
||||
return &conn{
|
||||
Conn: c,
|
||||
tuple: tup,
|
||||
close: func() {
|
||||
t.table.closeConn(tup)
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -60,7 +55,6 @@ func (t *TCP) SetDeadline(time time.Time) error {
|
||||
}
|
||||
|
||||
func (c *conn) Close() error {
|
||||
c.close()
|
||||
return c.Conn.Close()
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ type UDP struct {
|
||||
queueLock sync.Mutex
|
||||
queue []*call
|
||||
bufLock sync.Mutex
|
||||
buf [0xffff]byte
|
||||
buf []byte
|
||||
}
|
||||
|
||||
func (u *UDP) ReadFrom(buf []byte) (int, netip.AddrPort, netip.AddrPort, error) {
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/Dreamacro/clash/adapter/inbound"
|
||||
"github.com/Dreamacro/clash/common/cmd"
|
||||
"github.com/Dreamacro/clash/component/process"
|
||||
"github.com/Dreamacro/clash/config"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/listener/tun/device"
|
||||
@@ -24,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
// New TunAdapter
|
||||
func New(tunConf *config.Tun, tunAddressPrefix *netip.Prefix, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter, tunChangeCallback C.TUNChangeCallback) (ipstack.Stack, error) {
|
||||
func New(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter, tunChangeCallback C.TUNChangeCallback) (ipstack.Stack, error) {
|
||||
var (
|
||||
tunAddress = netip.Prefix{}
|
||||
devName = tunConf.Device
|
||||
@@ -48,16 +47,14 @@ func New(tunConf *config.Tun, tunAddressPrefix *netip.Prefix, tcpIn chan<- C.Con
|
||||
devName = generateDeviceName()
|
||||
}
|
||||
|
||||
if tunAddressPrefix != nil {
|
||||
tunAddress = *tunAddressPrefix
|
||||
if tunConf.TunAddressPrefix != nil {
|
||||
tunAddress = *tunConf.TunAddressPrefix
|
||||
}
|
||||
|
||||
if !tunAddress.IsValid() || !tunAddress.Addr().Is4() {
|
||||
tunAddress = netip.MustParsePrefix("198.18.0.1/16")
|
||||
}
|
||||
|
||||
process.AppendLocalIPs(tunAddress.Masked().Addr().Next())
|
||||
|
||||
// open tun device
|
||||
tunDevice, err = parseDevice(devName, uint32(mtu))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user