This repository has been archived on 2024-09-06. You can view files and clone it, but cannot push or open issues or pull requests.
Clash.Meta/tunnel/connection.go
2022-06-09 21:16:42 +08:00

78 lines
1.8 KiB
Go

package tunnel
import (
"net"
"time"
cN "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/component/resolver"
C "github.com/Dreamacro/clash/constant"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) error {
defer packet.Data().Release()
// local resolve UDP dns
if !metadata.Resolved() {
ip, err := resolver.ResolveIP(metadata.Host)
if err != nil {
return err
}
metadata.DstIP = ip
}
if err := pc.WritePacket(packet.Data(), metadata.Socksaddr()); err != nil {
return err
}
// reset timeout
pc.SetReadDeadline(time.Now().Add(udpTimeout))
return nil
}
func handleUDPToLocal(packet C.UDPPacket, pc C.PacketConn, key string, fAddr net.Addr) {
defer natTable.Delete(key)
defer pc.Close()
var fSocksaddr M.Socksaddr
if fAddr != nil {
fSocksaddr = M.SocksaddrFromNet(fAddr)
}
_, _ = copyPacketTimeout(packet, pc, udpTimeout, fSocksaddr, fAddr != nil)
}
func handleSocket(ctx C.ConnContext, outbound net.Conn) {
cN.Relay(ctx.Conn(), outbound)
}
func copyPacketTimeout(dst N.PacketWriter, src N.TimeoutPacketReader, timeout time.Duration, fAddr M.Socksaddr, fOverride bool) (n int64, err error) {
_buffer := buf.StackNewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
buffer.IncRef()
defer buffer.DecRef()
var destination M.Socksaddr
for {
buffer.Reset()
err = src.SetReadDeadline(time.Now().Add(timeout))
if err != nil {
return
}
destination, err = src.ReadPacket(buffer)
if err != nil {
return
}
if fOverride {
destination = fAddr
}
dataLen := buffer.Len()
err = dst.WritePacket(buffer, destination)
if err != nil {
return
}
n += int64(dataLen)
}
}