Chore: merge branch 'with-tun' into plus-pro

This commit is contained in:
yaling888 2022-04-21 04:33:53 +08:00
commit 0d004bf6f3
9 changed files with 41 additions and 37 deletions

View File

@ -33,7 +33,7 @@ func (m *Mitm) DialContext(ctx context.Context, metadata *C.Metadata, _ ...diale
metadata.Type = C.MITM metadata.Type = C.MITM
c, err := dialer.DialContext(ctx, "tcp", m.serverAddr, []dialer.Option{dialer.WithInterface(""), dialer.WithRoutingMark(0)}...) c, err := dialer.DialContext(ctx, "tcp", m.serverAddr, []dialer.Option{dialer.WithInterface(""), dialer.WithRoutingMark(0), dialer.WithDirect()}...)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -88,12 +88,8 @@ type Metadata struct {
} }
func (m *Metadata) RemoteAddress() string { func (m *Metadata) RemoteAddress() string {
if m.DstIP.IsValid() {
return net.JoinHostPort(m.DstIP.String(), m.DstPort)
} else {
return net.JoinHostPort(m.String(), m.DstPort) return net.JoinHostPort(m.String(), m.DstPort)
} }
}
func (m *Metadata) SourceAddress() string { func (m *Metadata) SourceAddress() string {
return net.JoinHostPort(m.SrcIP.String(), m.SrcPort) return net.JoinHostPort(m.SrcIP.String(), m.SrcPort)

View File

@ -48,5 +48,6 @@ func newClient(source net.Addr, userAgent string, in chan<- C.ConnContext) *http
CheckRedirect: func(req *http.Request, via []*http.Request) error { CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse return http.ErrUseLastResponse
}, },
Timeout: 120 * time.Second,
} }
} }

View File

@ -32,10 +32,6 @@ func HandleConn(c net.Conn, opt *Option, in chan<- C.ConnContext, cache *cache.C
}() }()
startOver: startOver:
if tcpConn, ok := c.(*net.TCPConn); ok {
_ = tcpConn.SetKeepAlive(true)
}
var conn *N.BufferedConn var conn *N.BufferedConn
if bufConn, ok := c.(*N.BufferedConn); ok { if bufConn, ok := c.(*N.BufferedConn); ok {
conn = bufConn conn = bufConn
@ -47,8 +43,8 @@ startOver:
readLoop: readLoop:
for { for {
// use SetDeadline instead of Proxy-Connection keep-alive // use SetReadDeadline instead of Proxy-Connection keep-alive
if err := conn.SetDeadline(time.Now().Add(30 * time.Second)); err != nil { if err := conn.SetReadDeadline(time.Now().Add(95 * time.Second)); err != nil {
break readLoop break readLoop
} }
@ -190,7 +186,7 @@ func writeResponse(session *Session, keepAlive bool) error {
if keepAlive { if keepAlive {
session.response.Header.Set("Connection", "keep-alive") session.response.Header.Set("Connection", "keep-alive")
session.response.Header.Set("Keep-Alive", "timeout=25") session.response.Header.Set("Keep-Alive", "timeout=90")
} }
return session.writeResponse() return session.writeResponse()

View File

@ -16,16 +16,17 @@ import (
"github.com/Dreamacro/clash/transport/socks5" "github.com/Dreamacro/clash/transport/socks5"
) )
var _ adapter.Handler = (*GVHandler)(nil) var _ adapter.Handler = (*gvHandler)(nil)
type GVHandler struct { type gvHandler struct {
DNSAdds []netip.AddrPort gateway netip.Addr
dnsHijack []netip.AddrPort
TCPIn chan<- C.ConnContext tcpIn chan<- C.ConnContext
UDPIn chan<- *inbound.PacketAdapter udpIn chan<- *inbound.PacketAdapter
} }
func (gh *GVHandler) HandleTCP(tunConn adapter.TCPConn) { func (gh *gvHandler) HandleTCP(tunConn adapter.TCPConn) {
id := tunConn.ID() id := tunConn.ID()
rAddr := &net.UDPAddr{ rAddr := &net.UDPAddr{
@ -34,11 +35,11 @@ func (gh *GVHandler) HandleTCP(tunConn adapter.TCPConn) {
Zone: "", Zone: "",
} }
addrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), id.LocalPort) rAddrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), id.LocalPort)
if D.ShouldHijackDns(gh.DNSAdds, addrPort) { if D.ShouldHijackDns(gh.dnsHijack, rAddrPort) {
go func() { go func() {
log.Debugln("[TUN] hijack dns tcp: %s", addrPort.String()) log.Debugln("[TUN] hijack dns tcp: %s", rAddrPort.String())
buf := pool.Get(pool.UDPBufferSize) buf := pool.Get(pool.UDPBufferSize)
defer func() { defer func() {
@ -77,10 +78,10 @@ func (gh *GVHandler) HandleTCP(tunConn adapter.TCPConn) {
return return
} }
gh.TCPIn <- inbound.NewSocket(socks5.ParseAddrToSocksAddr(rAddr), tunConn, C.TUN) gh.tcpIn <- inbound.NewSocket(socks5.ParseAddrToSocksAddr(rAddr), tunConn, C.TUN)
} }
func (gh *GVHandler) HandleUDP(tunConn adapter.UDPConn) { func (gh *gvHandler) HandleUDP(tunConn adapter.UDPConn) {
id := tunConn.ID() id := tunConn.ID()
rAddr := &net.UDPAddr{ rAddr := &net.UDPAddr{
@ -89,7 +90,13 @@ func (gh *GVHandler) HandleUDP(tunConn adapter.UDPConn) {
Zone: "", Zone: "",
} }
addrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), id.LocalPort) rAddrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), id.LocalPort)
if rAddrPort.Addr() == gh.gateway {
_ = tunConn.Close()
return
}
target := socks5.ParseAddrToSocksAddr(rAddr) target := socks5.ParseAddrToSocksAddr(rAddr)
go func() { go func() {
@ -104,7 +111,7 @@ func (gh *GVHandler) HandleUDP(tunConn adapter.UDPConn) {
payload := buf[:n] payload := buf[:n]
if D.ShouldHijackDns(gh.DNSAdds, addrPort) { if D.ShouldHijackDns(gh.dnsHijack, rAddrPort) {
go func() { go func() {
defer func() { defer func() {
_ = pool.Put(buf) _ = pool.Put(buf)
@ -130,7 +137,7 @@ func (gh *GVHandler) HandleUDP(tunConn adapter.UDPConn) {
} }
select { select {
case gh.UDPIn <- inbound.NewPacket(target, gvPacket, C.TUN): case gh.udpIn <- inbound.NewPacket(target, gvPacket, C.TUN):
default: default:
} }
} }

View File

@ -2,9 +2,12 @@
package gvisor package gvisor
import ( import (
"net/netip"
"github.com/Dreamacro/clash/adapter/inbound"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/tun/device" "github.com/Dreamacro/clash/listener/tun/device"
"github.com/Dreamacro/clash/listener/tun/ipstack" "github.com/Dreamacro/clash/listener/tun/ipstack"
"github.com/Dreamacro/clash/listener/tun/ipstack/gvisor/adapter"
"github.com/Dreamacro/clash/listener/tun/ipstack/gvisor/option" "github.com/Dreamacro/clash/listener/tun/ipstack/gvisor/option"
"gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip"
@ -34,7 +37,7 @@ func (s *gvStack) Close() error {
} }
// New allocates a new *gvStack with given options. // New allocates a new *gvStack with given options.
func New(device device.Device, handler adapter.Handler, opts ...option.Option) (ipstack.Stack, error) { func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Prefix, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter, opts ...option.Option) (ipstack.Stack, error) {
s := &gvStack{ s := &gvStack{
Stack: stack.New(stack.Options{ Stack: stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ NetworkProtocols: []stack.NetworkProtocolFactory{
@ -52,6 +55,13 @@ func New(device device.Device, handler adapter.Handler, opts ...option.Option) (
device: device, device: device,
} }
handler := &gvHandler{
gateway: tunAddress.Masked().Addr().Next(),
dnsHijack: dnsHijack,
tcpIn: tcpIn,
udpIn: udpIn,
}
// Generate unique NIC id. // Generate unique NIC id.
nicID := tcpip.NICID(s.Stack.UniqueID()) nicID := tcpip.NICID(s.Stack.UniqueID())

View File

@ -169,7 +169,7 @@ func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Pref
rAddrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), uint16(rAddr.Port)) rAddrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), uint16(rAddr.Port))
if rAddrPort.Addr().IsLoopback() { if rAddrPort.Addr().IsLoopback() || rAddrPort.Addr() == gateway {
_ = pool.Put(buf) _ = pool.Put(buf)
continue continue

View File

@ -67,13 +67,7 @@ func New(tunConf *config.Tun, tunAddressPrefix *netip.Prefix, tcpIn chan<- C.Con
return nil, fmt.Errorf("can't attach endpoint to tun: %w", err) return nil, fmt.Errorf("can't attach endpoint to tun: %w", err)
} }
tunStack, err = gvisor.New(tunDevice, tunStack, err = gvisor.New(tunDevice, tunConf.DNSHijack, tunAddress, tcpIn, udpIn, option.WithDefault())
&gvisor.GVHandler{
DNSAdds: tunConf.DNSHijack,
TCPIn: tcpIn, UDPIn: udpIn,
},
option.WithDefault(),
)
if err != nil { if err != nil {
_ = tunDevice.Close() _ = tunDevice.Close()