mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 12:42:27 +08:00
chore: tuic-server support disassociate command
This commit is contained in:
parent
551283c16e
commit
562819e3ca
@ -60,13 +60,13 @@ func New(config config.TuicServer, tcpIn chan<- C.ConnContext, udpIn chan<- *inb
|
|||||||
}
|
}
|
||||||
|
|
||||||
option := &tuic.ServerOption{
|
option := &tuic.ServerOption{
|
||||||
HandleTcpFn: func(conn net.Conn, addr string) error {
|
HandleTcpFn: func(conn net.Conn, addr socks5.Addr) error {
|
||||||
tcpIn <- inbound.NewSocket(socks5.ParseAddr(addr), conn, C.TUIC)
|
tcpIn <- inbound.NewSocket(addr, conn, C.TUIC)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
HandleUdpFn: func(addr *net.UDPAddr, packet C.UDPPacket) error {
|
HandleUdpFn: func(addr socks5.Addr, packet C.UDPPacket) error {
|
||||||
select {
|
select {
|
||||||
case udpIn <- inbound.NewPacket(socks5.ParseAddrToSocksAddr(addr), packet, C.TUIC):
|
case udpIn <- inbound.NewPacket(addr, packet, C.TUIC):
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/quic-go"
|
"github.com/metacubex/quic-go"
|
||||||
@ -115,6 +116,7 @@ type quicStreamPacketConn struct {
|
|||||||
|
|
||||||
deferQuicConnFn func(quicConn quic.Connection, err error)
|
deferQuicConnFn func(quicConn quic.Connection, err error)
|
||||||
closeDeferFn func()
|
closeDeferFn func()
|
||||||
|
writeClosed *atomic.Bool
|
||||||
|
|
||||||
closeOnce sync.Once
|
closeOnce sync.Once
|
||||||
closeErr error
|
closeErr error
|
||||||
@ -133,11 +135,11 @@ func (q *quicStreamPacketConn) close() (err error) {
|
|||||||
if q.closeDeferFn != nil {
|
if q.closeDeferFn != nil {
|
||||||
defer q.closeDeferFn()
|
defer q.closeDeferFn()
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
if q.deferQuicConnFn != nil {
|
if q.deferQuicConnFn != nil {
|
||||||
|
defer func() {
|
||||||
q.deferQuicConnFn(q.quicConn, err)
|
q.deferQuicConnFn(q.quicConn, err)
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
}
|
||||||
if q.inputConn != nil {
|
if q.inputConn != nil {
|
||||||
_ = q.inputConn.Close()
|
_ = q.inputConn.Close()
|
||||||
q.inputConn = nil
|
q.inputConn = nil
|
||||||
@ -204,11 +206,15 @@ func (q *quicStreamPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err erro
|
|||||||
if q.closed {
|
if q.closed {
|
||||||
return 0, net.ErrClosed
|
return 0, net.ErrClosed
|
||||||
}
|
}
|
||||||
defer func() {
|
if q.writeClosed != nil && q.writeClosed.Load() {
|
||||||
if q.deferQuicConnFn != nil {
|
_ = q.Close()
|
||||||
q.deferQuicConnFn(q.quicConn, err)
|
return 0, net.ErrClosed
|
||||||
}
|
}
|
||||||
|
if q.deferQuicConnFn != nil {
|
||||||
|
defer func() {
|
||||||
|
q.deferQuicConnFn(q.quicConn, err)
|
||||||
}()
|
}()
|
||||||
|
}
|
||||||
addr.String()
|
addr.String()
|
||||||
buf := pool.GetBuffer()
|
buf := pool.GetBuffer()
|
||||||
defer pool.PutBuffer(buf)
|
defer pool.PutBuffer(buf)
|
||||||
|
@ -554,6 +554,21 @@ func (c Address) String() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Address) SocksAddr() socks5.Addr {
|
||||||
|
addr := make([]byte, 1+len(c.ADDR)+2)
|
||||||
|
switch c.TYPE {
|
||||||
|
case AtypIPv4:
|
||||||
|
addr[0] = socks5.AtypIPv4
|
||||||
|
case AtypIPv6:
|
||||||
|
addr[0] = socks5.AtypIPv6
|
||||||
|
case AtypDomainName:
|
||||||
|
addr[0] = socks5.AtypDomainName
|
||||||
|
}
|
||||||
|
copy(addr[1:], c.ADDR)
|
||||||
|
binary.BigEndian.PutUint16(addr[len(addr)-2:], c.PORT)
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
func (c Address) UDPAddr() *net.UDPAddr {
|
func (c Address) UDPAddr() *net.UDPAddr {
|
||||||
return &net.UDPAddr{
|
return &net.UDPAddr{
|
||||||
IP: c.ADDR,
|
IP: c.ADDR,
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
@ -16,11 +17,12 @@ import (
|
|||||||
N "github.com/Dreamacro/clash/common/net"
|
N "github.com/Dreamacro/clash/common/net"
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
|
"github.com/Dreamacro/clash/transport/socks5"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerOption struct {
|
type ServerOption struct {
|
||||||
HandleTcpFn func(conn net.Conn, addr string) error
|
HandleTcpFn func(conn net.Conn, addr socks5.Addr) error
|
||||||
HandleUdpFn func(addr *net.UDPAddr, packet C.UDPPacket) error
|
HandleUdpFn func(addr socks5.Addr, packet C.UDPPacket) error
|
||||||
|
|
||||||
TlsConfig *tls.Config
|
TlsConfig *tls.Config
|
||||||
QuicConfig *quic.Config
|
QuicConfig *quic.Config
|
||||||
@ -78,6 +80,8 @@ type serverHandler struct {
|
|||||||
authCh chan struct{}
|
authCh chan struct{}
|
||||||
authOk bool
|
authOk bool
|
||||||
authOnce sync.Once
|
authOnce sync.Once
|
||||||
|
|
||||||
|
udpInputMap sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serverHandler) handle() {
|
func (s *serverHandler) handle() {
|
||||||
@ -125,6 +129,13 @@ func (s *serverHandler) parsePacket(packet Packet, udpRelayMode string) (err err
|
|||||||
var assocId uint32
|
var assocId uint32
|
||||||
|
|
||||||
assocId = packet.ASSOC_ID
|
assocId = packet.ASSOC_ID
|
||||||
|
|
||||||
|
v, _ := s.udpInputMap.LoadOrStore(assocId, &atomic.Bool{})
|
||||||
|
writeClosed := v.(*atomic.Bool)
|
||||||
|
if writeClosed.Load() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
pc := &quicStreamPacketConn{
|
pc := &quicStreamPacketConn{
|
||||||
connId: assocId,
|
connId: assocId,
|
||||||
quicConn: s.quicConn,
|
quicConn: s.quicConn,
|
||||||
@ -135,9 +146,10 @@ func (s *serverHandler) parsePacket(packet Packet, udpRelayMode string) (err err
|
|||||||
ref: s,
|
ref: s,
|
||||||
deferQuicConnFn: nil,
|
deferQuicConnFn: nil,
|
||||||
closeDeferFn: nil,
|
closeDeferFn: nil,
|
||||||
|
writeClosed: writeClosed,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.HandleUdpFn(packet.ADDR.UDPAddr(), &serverUDPPacket{
|
return s.HandleUdpFn(packet.ADDR.SocksAddr(), &serverUDPPacket{
|
||||||
pc: pc,
|
pc: pc,
|
||||||
packet: &packet,
|
packet: &packet,
|
||||||
rAddr: s.genServerAssocIdAddr(assocId),
|
rAddr: s.genServerAssocIdAddr(assocId),
|
||||||
@ -175,7 +187,7 @@ func (s *serverHandler) handleStream() (err error) {
|
|||||||
|
|
||||||
buf := pool.GetBuffer()
|
buf := pool.GetBuffer()
|
||||||
defer pool.PutBuffer(buf)
|
defer pool.PutBuffer(buf)
|
||||||
err = s.HandleTcpFn(conn, connect.ADDR.String())
|
err = s.HandleTcpFn(conn, connect.ADDR.SocksAddr())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = NewResponseFailed().WriteTo(buf)
|
err = NewResponseFailed().WriteTo(buf)
|
||||||
}
|
}
|
||||||
@ -245,7 +257,10 @@ func (s *serverHandler) handleUniStream() (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
disassociate.BytesLen()
|
if v, loaded := s.udpInputMap.LoadAndDelete(disassociate.ASSOC_ID); loaded {
|
||||||
|
writeClosed := v.(*atomic.Bool)
|
||||||
|
writeClosed.Store(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}()
|
}()
|
||||||
|
Loading…
Reference in New Issue
Block a user