mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2024-11-16 19:56:51 +08:00
fix: system stack's dns hijack not working
This commit is contained in:
parent
cbec564af9
commit
9ac4738ef9
|
@ -73,7 +73,7 @@ func (h *ListenerHandler) NewConnection(ctx context.Context, conn net.Conn, meta
|
||||||
ctx, cancel := context.WithTimeout(ctx, DefaultDnsRelayTimeout)
|
ctx, cancel := context.WithTimeout(ctx, DefaultDnsRelayTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inData := buff[:n]
|
inData := buff[:n]
|
||||||
msg, err := RelayDnsPacket(ctx, inData)
|
msg, err := RelayDnsPacket(ctx, inData, buff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,9 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||||
conn2 = nil
|
conn2 = nil
|
||||||
}()
|
}()
|
||||||
rwOptions := network.ReadWaitOptions{
|
rwOptions := network.ReadWaitOptions{
|
||||||
MTU: 2 * 1024, // safe size which is 1232 from https://dnsflagday.net/2020/, so 2048 is enough
|
FrontHeadroom: network.CalculateFrontHeadroom(conn),
|
||||||
|
RearHeadroom: network.CalculateRearHeadroom(conn),
|
||||||
|
MTU: 2 * 1024, // safe size which is 1232 from https://dnsflagday.net/2020/, so 2048 is enough
|
||||||
}
|
}
|
||||||
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
||||||
if isReadWaiter {
|
if isReadWaiter {
|
||||||
|
@ -118,24 +120,24 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
var (
|
var (
|
||||||
buff *buf.Buffer
|
readBuff *buf.Buffer
|
||||||
dest M.Socksaddr
|
dest M.Socksaddr
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
_ = conn.SetReadDeadline(time.Now().Add(DefaultDnsReadTimeout))
|
_ = conn.SetReadDeadline(time.Now().Add(DefaultDnsReadTimeout))
|
||||||
buff = nil // clear last loop status, avoid repeat release
|
readBuff = nil // clear last loop status, avoid repeat release
|
||||||
if isReadWaiter {
|
if isReadWaiter {
|
||||||
buff, dest, err = readWaiter.WaitReadPacket()
|
readBuff, dest, err = readWaiter.WaitReadPacket()
|
||||||
} else {
|
} else {
|
||||||
buff = rwOptions.NewPacketBuffer()
|
readBuff = rwOptions.NewPacketBuffer()
|
||||||
dest, err = conn.ReadPacket(buff)
|
dest, err = conn.ReadPacket(readBuff)
|
||||||
if buff != nil {
|
if readBuff != nil {
|
||||||
rwOptions.PostReturn(buff)
|
rwOptions.PostReturn(readBuff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if buff != nil {
|
if readBuff != nil {
|
||||||
buff.Release()
|
readBuff.Release()
|
||||||
}
|
}
|
||||||
if sing.ShouldIgnorePacketError(err) {
|
if sing.ShouldIgnorePacketError(err) {
|
||||||
break
|
break
|
||||||
|
@ -145,26 +147,30 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||||
go func() {
|
go func() {
|
||||||
ctx, cancel := context.WithTimeout(ctx, DefaultDnsRelayTimeout)
|
ctx, cancel := context.WithTimeout(ctx, DefaultDnsRelayTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inData := buff.Bytes()
|
inData := readBuff.Bytes()
|
||||||
msg, err := RelayDnsPacket(ctx, inData)
|
writeBuff := readBuff
|
||||||
|
if writeBuff.Cap() < rwOptions.MTU { // only create a new buffer when space don't enough
|
||||||
|
writeBuff = rwOptions.NewPacketBuffer()
|
||||||
|
}
|
||||||
|
msg, err := RelayDnsPacket(ctx, inData, writeBuff.FreeBytes())
|
||||||
|
if writeBuff != readBuff {
|
||||||
|
readBuff.Release()
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buff.Release()
|
writeBuff.Release()
|
||||||
return
|
|
||||||
}
|
|
||||||
buff.Reset()
|
|
||||||
_, err = buff.Write(msg)
|
|
||||||
if err != nil {
|
|
||||||
buff.Release()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
writeBuff.Truncate(len(msg))
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
conn := conn2
|
conn := conn2
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
|
writeBuff.Release()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = conn.WritePacket(buff, dest) // WritePacket will release buff
|
err = conn.WritePacket(writeBuff, dest) // WritePacket will release writeBuff
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
writeBuff.Release()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -174,7 +180,7 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||||
return h.ListenerHandler.NewPacketConnection(ctx, conn, metadata)
|
return h.ListenerHandler.NewPacketConnection(ctx, conn, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RelayDnsPacket(ctx context.Context, payload []byte) ([]byte, error) {
|
func RelayDnsPacket(ctx context.Context, payload []byte, target []byte) ([]byte, error) {
|
||||||
msg := &D.Msg{}
|
msg := &D.Msg{}
|
||||||
if err := msg.Unpack(payload); err != nil {
|
if err := msg.Unpack(payload); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -184,10 +190,10 @@ func RelayDnsPacket(ctx context.Context, payload []byte) ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m := new(D.Msg)
|
m := new(D.Msg)
|
||||||
m.SetRcode(msg, D.RcodeServerFailure)
|
m.SetRcode(msg, D.RcodeServerFailure)
|
||||||
return m.Pack()
|
return m.PackBuffer(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
r.SetRcode(msg, r.Rcode)
|
r.SetRcode(msg, r.Rcode)
|
||||||
r.Compress = true
|
r.Compress = true
|
||||||
return r.Pack()
|
return r.PackBuffer(target)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user