feat: recovering preHandleMetadata
failure from sniffing (#769)
This commit is contained in:
parent
e6366f7442
commit
67d7e53f7a
2 changed files with 28 additions and 11 deletions
|
@ -35,7 +35,8 @@ type SnifferDispatcher struct {
|
||||||
parsePureIp bool
|
parsePureIp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata) {
|
// TCPSniff returns true if the connection is sniffed to have a domain
|
||||||
|
func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata) bool {
|
||||||
if (metadata.Host == "" && sd.parsePureIp) || sd.forceDomain.Has(metadata.Host) || (metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping) {
|
if (metadata.Host == "" && sd.parsePureIp) || sd.forceDomain.Has(metadata.Host) || (metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping) {
|
||||||
inWhitelist := false
|
inWhitelist := false
|
||||||
overrideDest := false
|
overrideDest := false
|
||||||
|
@ -50,7 +51,7 @@ func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
if !inWhitelist {
|
if !inWhitelist {
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
sd.rwMux.RLock()
|
sd.rwMux.RLock()
|
||||||
|
@ -58,18 +59,18 @@ func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata
|
||||||
if count, ok := sd.skipList.Get(dst); ok && count > 5 {
|
if count, ok := sd.skipList.Get(dst); ok && count > 5 {
|
||||||
log.Debugln("[Sniffer] Skip sniffing[%s] due to multiple failures", dst)
|
log.Debugln("[Sniffer] Skip sniffing[%s] due to multiple failures", dst)
|
||||||
defer sd.rwMux.RUnlock()
|
defer sd.rwMux.RUnlock()
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
sd.rwMux.RUnlock()
|
sd.rwMux.RUnlock()
|
||||||
|
|
||||||
if host, err := sd.sniffDomain(conn, metadata); err != nil {
|
if host, err := sd.sniffDomain(conn, metadata); err != nil {
|
||||||
sd.cacheSniffFailed(metadata)
|
sd.cacheSniffFailed(metadata)
|
||||||
log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%d] to [%s:%d]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort)
|
log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%d] to [%s:%d]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort)
|
||||||
return
|
return false
|
||||||
} else {
|
} else {
|
||||||
if sd.skipSNI.Has(host) {
|
if sd.skipSNI.Has(host) {
|
||||||
log.Debugln("[Sniffer] Skip sni[%s]", host)
|
log.Debugln("[Sniffer] Skip sni[%s]", host)
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
sd.rwMux.RLock()
|
sd.rwMux.RLock()
|
||||||
|
@ -77,20 +78,23 @@ func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata
|
||||||
sd.rwMux.RUnlock()
|
sd.rwMux.RUnlock()
|
||||||
|
|
||||||
sd.replaceDomain(metadata, host, overrideDest)
|
sd.replaceDomain(metadata, host, overrideDest)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SnifferDispatcher) replaceDomain(metadata *C.Metadata, host string, overrideDest bool) {
|
func (sd *SnifferDispatcher) replaceDomain(metadata *C.Metadata, host string, overrideDest bool) {
|
||||||
|
// show log early, since the following code may mutate `metadata.Host`
|
||||||
|
log.Debugln("[Sniffer] Sniff TCP [%s]-->[%s] success, replace domain [%s]-->[%s]",
|
||||||
|
metadata.SourceDetail(),
|
||||||
|
metadata.RemoteAddress(),
|
||||||
|
metadata.Host, host)
|
||||||
metadata.SniffHost = host
|
metadata.SniffHost = host
|
||||||
if overrideDest {
|
if overrideDest {
|
||||||
metadata.Host = host
|
metadata.Host = host
|
||||||
}
|
}
|
||||||
metadata.DNSMode = C.DNSNormal
|
metadata.DNSMode = C.DNSNormal
|
||||||
log.Debugln("[Sniffer] Sniff TCP [%s]-->[%s] success, replace domain [%s]-->[%s]",
|
|
||||||
metadata.SourceDetail(),
|
|
||||||
metadata.RemoteAddress(),
|
|
||||||
metadata.Host, host)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SnifferDispatcher) Enable() bool {
|
func (sd *SnifferDispatcher) Enable() bool {
|
||||||
|
|
|
@ -419,15 +419,28 @@ func handleTCPConn(connCtx C.ConnContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preHandleFailed := false
|
||||||
if err := preHandleMetadata(metadata); err != nil {
|
if err := preHandleMetadata(metadata); err != nil {
|
||||||
log.Debugln("[Metadata PreHandle] error: %s", err)
|
log.Debugln("[Metadata PreHandle] error: %s", err)
|
||||||
return
|
preHandleFailed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
conn := connCtx.Conn()
|
conn := connCtx.Conn()
|
||||||
conn.ResetPeeked() // reset before sniffer
|
conn.ResetPeeked() // reset before sniffer
|
||||||
if sniffer.Dispatcher.Enable() && sniffingEnable {
|
if sniffer.Dispatcher.Enable() && sniffingEnable {
|
||||||
sniffer.Dispatcher.TCPSniff(conn, metadata)
|
// Try to sniff a domain when `preHandleMetadata` failed, this is usually
|
||||||
|
// caused by a "Fake DNS record missing" error when enhanced-mode is fake-ip.
|
||||||
|
if sniffer.Dispatcher.TCPSniff(conn, metadata) {
|
||||||
|
// we now have a domain name
|
||||||
|
preHandleFailed = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both trials have failed, we can do nothing but give up
|
||||||
|
if preHandleFailed {
|
||||||
|
log.Debugln("[Metadata PreHandle] failed to sniff a domain for connection %s --> %s, give up",
|
||||||
|
metadata.SourceDetail(), metadata.RemoteAddress())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
peekMutex := sync.Mutex{}
|
peekMutex := sync.Mutex{}
|
||||||
|
|
Loading…
Reference in a new issue