mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2024-09-19 15:12:33 +00:00
75 lines
1.3 KiB
Go
75 lines
1.3 KiB
Go
package system
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"io"
|
|
"net"
|
|
"time"
|
|
|
|
D "github.com/Dreamacro/clash/listener/tun/ipstack/commons"
|
|
"github.com/kr328/tun2socket/binding"
|
|
"github.com/kr328/tun2socket/redirect"
|
|
)
|
|
|
|
const defaultDnsReadTimeout = time.Second * 30
|
|
|
|
func shouldHijackDns(dnsAddr binding.Address, targetAddr binding.Address) bool {
|
|
if targetAddr.Port != 53 {
|
|
return false
|
|
}
|
|
|
|
return dnsAddr.IP.Equal(net.IPv4zero) || dnsAddr.IP.Equal(targetAddr.IP)
|
|
}
|
|
|
|
func hijackUDPDns(pkt []byte, ep *binding.Endpoint, sender redirect.UDPSender) {
|
|
go func() {
|
|
answer, err := D.RelayDnsPacket(pkt)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
_ = sender(answer, &binding.Endpoint{
|
|
Source: ep.Target,
|
|
Target: ep.Source,
|
|
})
|
|
}()
|
|
}
|
|
|
|
func hijackTCPDns(conn net.Conn) {
|
|
go func() {
|
|
defer func(conn net.Conn) {
|
|
_ = conn.Close()
|
|
}(conn)
|
|
|
|
if err := conn.SetReadDeadline(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
|
|
}
|
|
}
|
|
}()
|
|
}
|