Fix: should prehandle metadata before resolve

This commit is contained in:
Dreamacro 2020-02-07 20:53:43 +08:00
parent 72c0af9739
commit dcf97ff5b4
2 changed files with 38 additions and 13 deletions

View File

@ -75,6 +75,10 @@ func (m *Metadata) SourceAddress() string {
return net.JoinHostPort(m.SrcIP.String(), m.SrcPort)
}
func (m *Metadata) Resolved() bool {
return m.DstIP != nil
}
func (m *Metadata) UDPAddr() *net.UDPAddr {
if m.NetWork != UDP || m.DstIP == nil {
return nil

View File

@ -132,8 +132,8 @@ func (t *Tunnel) needLookupIP(metadata *C.Metadata) bool {
return dns.DefaultResolver != nil && (dns.DefaultResolver.IsMapping() || dns.DefaultResolver.FakeIPEnabled()) && metadata.Host == "" && metadata.DstIP != nil
}
func (t *Tunnel) resolveMetadata(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
// handle host equal IP string
func (t *Tunnel) preHandleMetadata(metadata *C.Metadata) error {
// handle IP string on host
if ip := net.ParseIP(metadata.Host); ip != nil {
metadata.DstIP = ip
}
@ -147,9 +147,15 @@ func (t *Tunnel) resolveMetadata(metadata *C.Metadata) (C.Proxy, C.Rule, error)
if dns.DefaultResolver.FakeIPEnabled() {
metadata.DstIP = nil
}
} else if dns.DefaultResolver.IsFakeIP(metadata.DstIP) {
return fmt.Errorf("fake DNS record %s missing", metadata.DstIP)
}
}
return nil
}
func (t *Tunnel) resolveMetadata(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
var proxy C.Proxy
var rule C.Rule
switch t.mode {
@ -175,21 +181,24 @@ func (t *Tunnel) handleUDPConn(packet *inbound.PacketAdapter) {
return
}
if metadata.DstIP == nil {
ip, err := t.resolveIP(metadata.Host)
if err != nil {
log.Warnln("[UDP] Resolve %s failed: %s, %#v", metadata.Host, err.Error(), metadata)
return
}
metadata.DstIP = ip
if err := t.preHandleMetadata(metadata); err != nil {
log.Debugln("[Metadata PreHandle] error: %s", err)
return
}
key := packet.LocalAddr().String()
pc := t.natTable.Get(key)
addr := metadata.UDPAddr()
if pc != nil {
t.handleUDPToRemote(packet, pc, addr)
if !metadata.Resolved() {
ip, err := t.resolveIP(metadata.Host)
if err != nil {
log.Warnln("[UDP] Resolve %s failed: %s, %#v", metadata.Host, err.Error(), metadata)
return
}
metadata.DstIP = ip
}
t.handleUDPToRemote(packet, pc, metadata.UDPAddr())
return
}
@ -236,7 +245,14 @@ func (t *Tunnel) handleUDPConn(packet *inbound.PacketAdapter) {
wg.Wait()
pc := t.natTable.Get(key)
if pc != nil {
t.handleUDPToRemote(packet, pc, addr)
if !metadata.Resolved() {
ip, err := dns.ResolveIP(metadata.Host)
if err != nil {
return
}
metadata.DstIP = ip
}
t.handleUDPToRemote(packet, pc, metadata.UDPAddr())
}
}()
}
@ -250,6 +266,11 @@ func (t *Tunnel) handleTCPConn(localConn C.ServerAdapter) {
return
}
if err := t.preHandleMetadata(metadata); err != nil {
log.Debugln("[Metadata PreHandle] error: %s", err)
return
}
proxy, rule, err := t.resolveMetadata(metadata)
if err != nil {
log.Warnln("Parse metadata failed: %v", err)