Skip to content

Commit 6e16ff5

Browse files
authored
Merge pull request #88 from Cuthead/dualquery
2 parents e9d629b + 6d50462 commit 6e16ff5

2 files changed

Lines changed: 114 additions & 26 deletions

File tree

phantomtcp/dns.go

Lines changed: 87 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,7 @@ func GetDNSLie(index int) (string, *Outbound) {
10891089

10901090
func (outbound *Outbound) NSLookup(name string) (uint32, []net.IP) {
10911091
hint := outbound.Hint
1092+
dual := outbound.Protocol != NAT64 && outbound.hasIPv6() && hint&HINT_IPV6 == 0 && hint&HINT_IPV4 == 0
10921093
var qtype uint16 = 1
10931094
if hint&HINT_IPV6 != 0 {
10941095
qtype = 28
@@ -1115,24 +1116,37 @@ func (outbound *Outbound) NSLookup(name string) (uint32, []net.IP) {
11151116
offset++
11161117
}
11171118
}
1118-
switch qtype {
1119-
case 1:
1119+
if dual {
1120+
if records.IPv6Hint != nil && len(records.IPv6Hint.Addresses) > 0 {
1121+
logPrintln(3, "cached:", name, qtype, records.IPv6Hint.Addresses)
1122+
return records.Index, records.IPv6Hint.Addresses
1123+
}
11201124
if records.IPv4Hint != nil {
11211125
logPrintln(3, "cached:", name, qtype, records.IPv4Hint.Addresses)
11221126
return records.Index, records.IPv4Hint.Addresses
11231127
}
1124-
case 28:
1125-
if records.IPv6Hint != nil {
1126-
logPrintln(3, "cached:", name, qtype, records.IPv6Hint.Addresses)
1127-
return records.Index, records.IPv6Hint.Addresses
1128+
} else {
1129+
switch qtype {
1130+
case 1:
1131+
if records.IPv4Hint != nil {
1132+
logPrintln(3, "cached:", name, qtype, records.IPv4Hint.Addresses)
1133+
return records.Index, records.IPv4Hint.Addresses
1134+
}
1135+
case 28:
1136+
if records.IPv6Hint != nil {
1137+
logPrintln(3, "cached:", name, qtype, records.IPv6Hint.Addresses)
1138+
return records.Index, records.IPv6Hint.Addresses
1139+
}
1140+
default:
1141+
return 0, nil
11281142
}
1129-
default:
1130-
return 0, nil
11311143
}
11321144

11331145
var request []byte
11341146
var response []byte
11351147
var err error
1148+
var response6 []byte
1149+
var err6 error
11361150

11371151
var options ServerOptions
11381152
u, err := url.Parse(outbound.DNS)
@@ -1151,30 +1165,48 @@ func (outbound *Outbound) NSLookup(name string) (uint32, []net.IP) {
11511165

11521166
if u.Host != "" {
11531167
switch u.Scheme {
1154-
case "udp":
1155-
request = PackRequest(_name, qtype, uint16(0), options.ECS, options.QType2)
1156-
response, err = UDPlookup(request, u.Host)
1157-
case "tcp":
1158-
request = PackRequest(_name, qtype, uint16(0), options.ECS, options.QType2)
1159-
response, err = TCPlookup(request, u.Host)
1160-
case "tls":
1161-
request = PackRequest(_name, qtype, uint16(0), options.ECS, options.QType2)
1162-
response, err = TLSlookup(request, u.Host)
1163-
case "https":
1164-
request = PackRequest(_name, qtype, uint16(0), options.ECS, options.QType2)
1165-
response, err = HTTPSlookup(request, u, options.Domain)
1166-
case "tfo":
1167-
request = PackRequest(_name, qtype, uint16(0), options.ECS, options.QType2)
1168-
response, err = TFOlookup(request, u.Host)
1168+
case "udp", "tcp", "tls", "https", "tfo":
11691169
default:
11701170
records.Index = AddDNSLie(name, outbound)
11711171
records.ALPN = hint
11721172
return records.Index, nil
11731173
}
1174+
doLookup := func(qt uint16) ([]byte, error) {
1175+
request = PackRequest(_name, qt, uint16(0), options.ECS, options.QType2)
1176+
switch u.Scheme {
1177+
case "udp":
1178+
return UDPlookup(request, u.Host)
1179+
case "tcp":
1180+
return TCPlookup(request, u.Host)
1181+
case "tls":
1182+
return TLSlookup(request, u.Host)
1183+
case "https":
1184+
return HTTPSlookup(request, u, options.Domain)
1185+
case "tfo":
1186+
return TFOlookup(request, u.Host)
1187+
}
1188+
return nil, nil
1189+
}
1190+
if dual {
1191+
done := make(chan struct{}, 1)
1192+
go func() { response6, err6 = doLookup(28); done <- struct{}{} }()
1193+
response, err = doLookup(1)
1194+
<-done
1195+
} else {
1196+
response, err = doLookup(qtype)
1197+
}
11741198
}
11751199
if err != nil {
11761200
logPrintln(1, err)
1177-
return 0, nil
1201+
if !dual {
1202+
return 0, nil
1203+
}
1204+
}
1205+
if err6 != nil {
1206+
logPrintln(1, err6)
1207+
if err != nil {
1208+
return 0, nil
1209+
}
11781210
}
11791211

11801212
if (hint&HINT_FAKEIP != 0) && records.Index == 0 {
@@ -1183,9 +1215,40 @@ func (outbound *Outbound) NSLookup(name string) (uint32, []net.IP) {
11831215
}
11841216

11851217
records.GetAnswers(response, options)
1218+
records.GetAnswers(response6, options)
11861219
DNSRecordMutex.Lock()
11871220
defer DNSRecordMutex.Unlock()
11881221

1222+
if dual {
1223+
if records.IPv6Hint == nil && options.Fallback != nil {
1224+
if options.Fallback.To4() == nil {
1225+
records.IPv6Hint = &RecordAddresses{0, []net.IP{options.Fallback}}
1226+
}
1227+
}
1228+
if records.IPv6Hint == nil {
1229+
records.IPv6Hint = &RecordAddresses{0, []net.IP{}}
1230+
}
1231+
logPrintln(3, "nslookup", name, 28, records.IPv6Hint.Addresses)
1232+
if len(records.IPv6Hint.Addresses) > 0 {
1233+
addresses := make([]net.IP, len(records.IPv6Hint.Addresses))
1234+
copy(addresses, records.IPv6Hint.Addresses)
1235+
return records.Index, addresses
1236+
}
1237+
if records.IPv4Hint == nil && options.Fallback != nil {
1238+
if options.Fallback.To4() != nil {
1239+
logPrintln(4, "request:", name, "fallback", options.Fallback)
1240+
records.IPv4Hint = &RecordAddresses{0, []net.IP{options.Fallback}}
1241+
}
1242+
}
1243+
if records.IPv4Hint == nil {
1244+
records.IPv4Hint = &RecordAddresses{0, []net.IP{}}
1245+
}
1246+
logPrintln(3, "nslookup", name, 1, records.IPv4Hint.Addresses)
1247+
addresses := make([]net.IP, len(records.IPv4Hint.Addresses))
1248+
copy(addresses, records.IPv4Hint.Addresses)
1249+
return records.Index, addresses
1250+
}
1251+
11891252
switch qtype {
11901253
case 1:
11911254
if records.IPv4Hint == nil && options.Fallback != nil {

phantomtcp/tcp.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package phantomtcp
22

33
import (
4+
"crypto/rand"
45
"io"
6+
mathrand "math/rand"
57
"net"
68
"os"
7-
"crypto/rand"
89
"strconv"
910
"syscall"
10-
mathrand "math/rand"
1111
)
1212

1313
const domainBytes = "abcdefghijklmnopqrstuvwxyz0123456789-"
@@ -88,6 +88,31 @@ func GetLocalTCPAddr(name string, ipv6 bool) (*net.TCPAddr, error) {
8888
return nil, nil
8989
}
9090

91+
func (outbound *Outbound) hasIPv6() bool {
92+
if outbound.Device != "" {
93+
addr, _ := GetLocalTCPAddr(outbound.Device, true)
94+
return addr != nil
95+
}
96+
ifaces, err := net.Interfaces()
97+
if err != nil {
98+
return false
99+
}
100+
for _, iface := range ifaces {
101+
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
102+
continue
103+
}
104+
addrs, _ := iface.Addrs()
105+
for _, addr := range addrs {
106+
if ipnet, ok := addr.(*net.IPNet); ok {
107+
if ipnet.IP.To4() == nil && !ipnet.IP.IsLinkLocalUnicast() {
108+
return true
109+
}
110+
}
111+
}
112+
}
113+
return false
114+
}
115+
91116
func (outbound *Outbound) GetRemoteAddresses(host string, port int) ([]*net.TCPAddr, error) {
92117
switch outbound.Protocol {
93118
case DIRECT:

0 commit comments

Comments
 (0)