Skip to content

Commit 8572bda

Browse files
committed
save 3
1 parent 28ee861 commit 8572bda

File tree

8 files changed

+86
-68
lines changed

8 files changed

+86
-68
lines changed

app/dns/dnscommon.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,15 @@ func (r *IPRecord) getIPs() ([]net.IP, uint32, error) {
4242
if r == nil {
4343
return nil, 0, errRecordNotFound
4444
}
45-
untilExpire := time.Until(r.Expire)
45+
untilExpire := time.Until(r.Expire).Seconds()
4646
if untilExpire <= 0 {
4747
return nil, 0, errRecordNotFound
4848
}
4949

50-
ttl := uint32(untilExpire/time.Second) + uint32(1)
50+
ttl := uint32(untilExpire) + 1
51+
if ttl == 1 {
52+
r.Expire = time.Now().Add(time.Second) // To ensure that two consecutive requests have the same result
53+
}
5154
if r.RCode != dnsmessage.RCodeSuccess {
5255
return nil, ttl, dns_feature.RCodeError(r.RCode)
5356
}

app/proxyman/config.pb.go

Lines changed: 32 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/proxyman/config.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ message SenderConfig {
8484
xray.transport.internet.ProxyConfig proxy_settings = 3;
8585
MultiplexingConfig multiplex_settings = 4;
8686
string via_cidr = 5;
87-
xray.transport.internet.DomainStrategy target_domain_strategy = 6;
87+
xray.transport.internet.DomainStrategy target_strategy = 6;
8888
}
8989

9090
message MultiplexingConfig {

app/proxyman/inbound/worker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
325325

326326
ctx = session.ContextWithInbound(ctx, &session.Inbound{
327327
Source: source,
328-
Local: net.DestinationFromAddr(w.hub.Addr()),
328+
Local: net.DestinationFromAddr(w.hub.Addr()), // Due to some limitations, in UDP connections, localIP is always equal to listen interface IP
329329
Gateway: net.UDPDestination(w.address, w.port),
330330
Tag: w.tag,
331331
})

app/proxyman/outbound/handler.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"context"
55
"crypto/rand"
66
goerrors "errors"
7-
"github.com/xtls/xray-core/features/dns"
7+
"github.com/xtls/xray-core/common/dice"
88
"io"
99
"math/big"
1010
gonet "net"
@@ -70,7 +70,6 @@ type Handler struct {
7070
udp443 string
7171
uplinkCounter stats.Counter
7272
downlinkCounter stats.Counter
73-
dns dns.Client
7473
}
7574

7675
// NewHandler creates a new Handler based on the given configuration.
@@ -80,7 +79,6 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
8079
h := &Handler{
8180
tag: config.Tag,
8281
outboundManager: v.GetFeature(outbound.ManagerType()).(outbound.Manager),
83-
dns: v.GetFeature(dns.ClientType()).(dns.Client),
8482
uplinkCounter: uplinkCounter,
8583
downlinkCounter: downlinkCounter,
8684
}
@@ -180,9 +178,22 @@ func (h *Handler) Tag() string {
180178
func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
181179
outbounds := session.OutboundsFromContext(ctx)
182180
ob := outbounds[len(outbounds)-1]
183-
content := session.ContentFromContext(ctx)
184-
if h.senderSettings.TargetDomainStrategy.HasStrategy() && ob.Target.Address.Family().IsDomain() && (content == nil || !content.SkipDNSResolve) {
185-
// to do
181+
content := session.ContentFromContext(ctx)
182+
if h.senderSettings.TargetStrategy.HasStrategy() && ob.Target.Address.Family().IsDomain() && (content == nil || !content.SkipDNSResolve) {
183+
ips, err := internet.LookupForIP(ob.Target.Address.Domain(), h.senderSettings.TargetStrategy, nil)
184+
if err != nil {
185+
errors.LogInfoInner(ctx, err, "failed to resolve ip for target ", ob.Target.Address.Domain())
186+
if h.senderSettings.TargetStrategy.ForceIP() {
187+
err := errors.New("failed to resolve ip for target ", ob.Target.Address.Domain()).Base(err)
188+
session.SubmitOutboundErrorToOriginator(ctx, err)
189+
common.Interrupt(link.Writer)
190+
common.Interrupt(link.Reader)
191+
return
192+
}
193+
194+
} else {
195+
ob.Target.Address = net.IPAddress(ips[dice.Roll(len(ips))])
196+
}
186197
}
187198
if ob.Target.Network == net.Network_UDP && ob.OriginalTarget.Address != nil && ob.OriginalTarget.Address != ob.Target.Address {
188199
link.Reader = &buf.EndpointOverrideReader{Reader: link.Reader, Dest: ob.Target.Address, OriginalDest: ob.OriginalTarget.Address}
@@ -195,6 +206,7 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
195206
session.SubmitOutboundErrorToOriginator(ctx, err)
196207
errors.LogInfo(ctx, err.Error())
197208
common.Interrupt(link.Writer)
209+
common.Interrupt(link.Reader)
198210
}
199211
}
200212
if ob.Target.Network == net.Network_UDP && ob.Target.Port == 443 {

infra/conf/xray.go

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -260,14 +260,14 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {
260260
}
261261

262262
type OutboundDetourConfig struct {
263-
Protocol string `json:"protocol"`
264-
SendThrough *string `json:"sendThrough"`
265-
Tag string `json:"tag"`
266-
Settings *json.RawMessage `json:"settings"`
267-
StreamSetting *StreamConfig `json:"streamSettings"`
268-
ProxySettings *ProxyConfig `json:"proxySettings"`
269-
MuxSettings *MuxConfig `json:"mux"`
270-
TargetDomainStrategy string `json:"targetDomainStrategy"`
263+
Protocol string `json:"protocol"`
264+
SendThrough *string `json:"sendThrough"`
265+
Tag string `json:"tag"`
266+
Settings *json.RawMessage `json:"settings"`
267+
StreamSetting *StreamConfig `json:"streamSettings"`
268+
ProxySettings *ProxyConfig `json:"proxySettings"`
269+
MuxSettings *MuxConfig `json:"mux"`
270+
TargetStrategy string `json:"targetStrategy"`
271271
}
272272

273273
func (c *OutboundDetourConfig) checkChainProxyConfig() error {
@@ -283,31 +283,31 @@ func (c *OutboundDetourConfig) checkChainProxyConfig() error {
283283
// Build implements Buildable.
284284
func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) {
285285
senderSettings := &proxyman.SenderConfig{}
286-
switch strings.ToLower(c.TargetDomainStrategy) {
286+
switch strings.ToLower(c.TargetStrategy) {
287287
case "asis", "":
288-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_AS_IS
288+
senderSettings.TargetStrategy = internet.DomainStrategy_AS_IS
289289
case "useip":
290-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_USE_IP
290+
senderSettings.TargetStrategy = internet.DomainStrategy_USE_IP
291291
case "useipv4":
292-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_USE_IP4
292+
senderSettings.TargetStrategy = internet.DomainStrategy_USE_IP4
293293
case "useipv6":
294-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_USE_IP6
294+
senderSettings.TargetStrategy = internet.DomainStrategy_USE_IP6
295295
case "useipv4v6":
296-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_USE_IP46
296+
senderSettings.TargetStrategy = internet.DomainStrategy_USE_IP46
297297
case "useipv6v4":
298-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_USE_IP64
298+
senderSettings.TargetStrategy = internet.DomainStrategy_USE_IP64
299299
case "forceip":
300-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_FORCE_IP
300+
senderSettings.TargetStrategy = internet.DomainStrategy_FORCE_IP
301301
case "forceipv4":
302-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_FORCE_IP4
302+
senderSettings.TargetStrategy = internet.DomainStrategy_FORCE_IP4
303303
case "forceipv6":
304-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_FORCE_IP6
304+
senderSettings.TargetStrategy = internet.DomainStrategy_FORCE_IP6
305305
case "forceipv4v6":
306-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_FORCE_IP46
306+
senderSettings.TargetStrategy = internet.DomainStrategy_FORCE_IP46
307307
case "forceipv6v4":
308-
senderSettings.TargetDomainStrategy = internet.DomainStrategy_FORCE_IP64
308+
senderSettings.TargetStrategy = internet.DomainStrategy_FORCE_IP64
309309
default:
310-
return nil, errors.New("unsupported target domain strategy: ", c.TargetDomainStrategy)
310+
return nil, errors.New("unsupported target domain strategy: ", c.TargetStrategy)
311311
}
312312
if err := c.checkChainProxyConfig(); err != nil {
313313
return nil, err

transport/internet/dialer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ var (
8585
obm outbound.Manager
8686
)
8787

88-
func lookupIP(domain string, strategy DomainStrategy, localAddr net.Address) ([]net.IP, error) {
88+
func LookupForIP(domain string, strategy DomainStrategy, localAddr net.Address) ([]net.IP, error) {
8989
if dnsClient == nil {
9090
return nil, errors.New("DNS client not initialized").AtError()
9191
}
@@ -249,7 +249,7 @@ func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig
249249
}
250250

251251
if canLookupIP(dest, sockopt) {
252-
ips, err := lookupIP(dest.Address.String(), sockopt.DomainStrategy, src)
252+
ips, err := LookupForIP(dest.Address.String(), sockopt.DomainStrategy, src)
253253
if err != nil {
254254
errors.LogErrorInner(ctx, err, "failed to resolve ip")
255255
if sockopt.DomainStrategy.ForceIP() {
@@ -259,7 +259,7 @@ func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig
259259
dest.Address = net.IPAddress(ips[dice.Roll(len(ips))])
260260
errors.LogInfo(ctx, "replace destination with "+dest.String())
261261
} else {
262-
return TcpRaceDial(ctx, src, ips, dest.Port, sockopt)
262+
return TcpRaceDial(ctx, src, ips, dest.Port, sockopt, dest.Address.String())
263263
}
264264
}
265265

transport/internet/happy_eyeballs.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package internet
22

33
import (
44
"context"
5+
"github.com/xtls/xray-core/common/errors"
56
"github.com/xtls/xray-core/common/net"
67
"time"
78
)
@@ -12,7 +13,7 @@ type result struct {
1213
index int
1314
}
1415

15-
func TcpRaceDial(ctx context.Context, src net.Address, ips []net.IP, port net.Port, sockopt *SocketConfig) (net.Conn, error) {
16+
func TcpRaceDial(ctx context.Context, src net.Address, ips []net.IP, port net.Port, sockopt *SocketConfig, domain string) (net.Conn, error) {
1617
if len(ips) < 2 {
1718
panic("at least 2 ips is required to race dial")
1819
}
@@ -30,6 +31,7 @@ func TcpRaceDial(ctx context.Context, src net.Address, ips []net.IP, port net.Po
3031
activeNum := uint32(0)
3132
timer := time.NewTimer(0)
3233
var winConn net.Conn
34+
errors.LogDebug(ctx, "happy eyeballs racing dial for ", domain, " with IPs ", ips)
3335
for {
3436
select {
3537
case r := <-resultCh:
@@ -54,6 +56,7 @@ func TcpRaceDial(ctx context.Context, src net.Address, ips []net.IP, port net.Po
5456
timer.Stop()
5557
if winConn == nil {
5658
winConn = r.conn
59+
errors.LogDebug(ctx, "happy eyeballs established connection for ", domain, " with IP ", ips[r.index])
5760
} else {
5861
r.conn.Close()
5962
}
@@ -69,6 +72,7 @@ func TcpRaceDial(ctx context.Context, src net.Address, ips []net.IP, port net.Po
6972
continue
7073
}
7174
if activeNum == 0 {
75+
errors.LogDebugInner(ctx, r.err, "happy eyeballs no connection established for ", domain)
7276
return nil, r.err
7377
}
7478
timer.Stop()

0 commit comments

Comments
 (0)