@@ -4,12 +4,13 @@ import (
44 "context"
55 "crypto/rand"
66 goerrors "errors"
7- "github.com/xtls/xray-core/common/dice"
87 "io"
98 "math/big"
109 gonet "net"
1110 "os"
1211
12+ "github.com/xtls/xray-core/common/dice"
13+
1314 "github.com/xtls/xray-core/app/proxyman"
1415 "github.com/xtls/xray-core/common"
1516 "github.com/xtls/xray-core/common/buf"
@@ -180,7 +181,11 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
180181 ob := outbounds [len (outbounds )- 1 ]
181182 content := session .ContentFromContext (ctx )
182183 if h .senderSettings != nil && 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+ strategy := h .senderSettings .TargetStrategy
185+ if ob .Target .Network == net .Network_UDP && ob .OriginalTarget .Address != nil {
186+ strategy = strategy .GetDynamicStrategy (ob .OriginalTarget .Address .Family ())
187+ }
188+ ips , err := internet .LookupForIP (ob .Target .Address .Domain (), strategy , nil )
184189 if err != nil {
185190 errors .LogInfoInner (ctx , err , "failed to resolve ip for target " , ob .Target .Address .Domain ())
186191 if h .senderSettings .TargetStrategy .ForceIP () {
@@ -251,14 +256,6 @@ out:
251256 common .Interrupt (link .Reader )
252257}
253258
254- // Address implements internet.Dialer.
255- func (h * Handler ) Address () net.Address {
256- if h .senderSettings == nil || h .senderSettings .Via == nil {
257- return nil
258- }
259- return h .senderSettings .Via .AsAddress ()
260- }
261-
262259func (h * Handler ) DestIpAddress () net.IP {
263260 return internet .DestIpAddress ()
264261}
@@ -293,41 +290,16 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
293290 return h .getStatCouterConnection (conn ), nil
294291 }
295292
296- errors .LogWarning (ctx , "failed to get outbound handler with tag: " , tag )
293+ errors .LogError (ctx , "failed to get outbound handler with tag: " , tag )
294+ return nil , errors .New ("failed to get outbound handler with tag: " + tag )
297295 }
298296
299297 if h .senderSettings .Via != nil {
300-
301298 outbounds := session .OutboundsFromContext (ctx )
302299 ob := outbounds [len (outbounds )- 1 ]
303- var domain string
304- addr := h .senderSettings .Via .AsAddress ()
305- domain = h .senderSettings .Via .GetDomain ()
306- switch {
307- case h .senderSettings .ViaCidr != "" :
308- ob .Gateway = ParseRandomIP (addr , h .senderSettings .ViaCidr )
309-
310- case domain == "origin" :
311- if inbound := session .InboundFromContext (ctx ); inbound != nil {
312- if inbound .Local .IsValid () && inbound .Local .Address .Family ().IsIP () {
313- ob .Gateway = inbound .Local .Address
314- errors .LogDebug (ctx , "use inbound local ip as sendthrough: " , inbound .Local .Address .String ())
315- }
316- }
317- case domain == "srcip" :
318- if inbound := session .InboundFromContext (ctx ); inbound != nil {
319- if inbound .Source .IsValid () && inbound .Source .Address .Family ().IsIP () {
320- ob .Gateway = inbound .Source .Address
321- errors .LogDebug (ctx , "use inbound source ip as sendthrough: " , inbound .Source .Address .String ())
322- }
323- }
324- //case addr.Family().IsDomain():
325- default :
326- ob .Gateway = addr
327-
328- }
329-
300+ h .SetOutboundGateway (ctx , ob )
330301 }
302+
331303 }
332304
333305 if conn , err := h .getUoTConnection (ctx , dest ); err != os .ErrInvalid {
@@ -342,6 +314,38 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
342314 return conn , err
343315}
344316
317+ func (h * Handler ) SetOutboundGateway (ctx context.Context , ob * session.Outbound ) {
318+ if ob .Gateway == nil && h .senderSettings != nil && h .senderSettings .Via != nil && ! h .senderSettings .ProxySettings .HasTag () && (h .streamSettings .SocketSettings == nil || len (h .streamSettings .SocketSettings .DialerProxy ) == 0 ) {
319+ var domain string
320+ addr := h .senderSettings .Via .AsAddress ()
321+ domain = h .senderSettings .Via .GetDomain ()
322+ switch {
323+ case h .senderSettings .ViaCidr != "" :
324+ ob .Gateway = ParseRandomIP (addr , h .senderSettings .ViaCidr )
325+
326+ case domain == "origin" :
327+ if inbound := session .InboundFromContext (ctx ); inbound != nil {
328+ if inbound .Local .IsValid () && inbound .Local .Address .Family ().IsIP () {
329+ ob .Gateway = inbound .Local .Address
330+ errors .LogDebug (ctx , "use inbound local ip as sendthrough: " , inbound .Local .Address .String ())
331+ }
332+ }
333+ case domain == "srcip" :
334+ if inbound := session .InboundFromContext (ctx ); inbound != nil {
335+ if inbound .Source .IsValid () && inbound .Source .Address .Family ().IsIP () {
336+ ob .Gateway = inbound .Source .Address
337+ errors .LogDebug (ctx , "use inbound source ip as sendthrough: " , inbound .Source .Address .String ())
338+ }
339+ }
340+ //case addr.Family().IsDomain():
341+ default :
342+ ob .Gateway = addr
343+
344+ }
345+
346+ }
347+ }
348+
345349func (h * Handler ) getStatCouterConnection (conn stat.Connection ) stat.Connection {
346350 if h .uplinkCounter != nil || h .downlinkCounter != nil {
347351 return & stat.CounterConnection {
0 commit comments