default_parallel_interface.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. package dialer
  2. import (
  3. "context"
  4. "net"
  5. "time"
  6. "github.com/sagernet/sing-box/adapter"
  7. C "github.com/sagernet/sing-box/constant"
  8. "github.com/sagernet/sing/common"
  9. "github.com/sagernet/sing/common/control"
  10. E "github.com/sagernet/sing/common/exceptions"
  11. N "github.com/sagernet/sing/common/network"
  12. )
  13. func (d *DefaultDialer) dialParallelInterface(ctx context.Context, dialer net.Dialer, network string, addr string, strategy C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, bool, error) {
  14. primaryInterfaces, fallbackInterfaces := selectInterfaces(d.networkManager, strategy, interfaceType, fallbackInterfaceType)
  15. if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
  16. return nil, false, E.New("no available network interface")
  17. }
  18. if fallbackDelay == 0 {
  19. fallbackDelay = N.DefaultFallbackDelay
  20. }
  21. returned := make(chan struct{})
  22. defer close(returned)
  23. type dialResult struct {
  24. net.Conn
  25. error
  26. primary bool
  27. }
  28. results := make(chan dialResult) // unbuffered
  29. startRacer := func(ctx context.Context, primary bool, iif adapter.NetworkInterface) {
  30. perNetDialer := dialer
  31. perNetDialer.Control = control.Append(perNetDialer.Control, control.BindToInterface(nil, iif.Name, iif.Index))
  32. conn, err := perNetDialer.DialContext(ctx, network, addr)
  33. if err != nil {
  34. select {
  35. case results <- dialResult{error: E.Cause(err, "dial ", iif.Name, " (", iif.Name, ")"), primary: primary}:
  36. case <-returned:
  37. }
  38. } else {
  39. select {
  40. case results <- dialResult{Conn: conn, primary: primary}:
  41. case <-returned:
  42. conn.Close()
  43. }
  44. }
  45. }
  46. primaryCtx, primaryCancel := context.WithCancel(ctx)
  47. defer primaryCancel()
  48. for _, iif := range primaryInterfaces {
  49. go startRacer(primaryCtx, true, iif)
  50. }
  51. var (
  52. fallbackTimer *time.Timer
  53. fallbackChan <-chan time.Time
  54. )
  55. if len(fallbackInterfaces) > 0 {
  56. fallbackTimer = time.NewTimer(fallbackDelay)
  57. defer fallbackTimer.Stop()
  58. fallbackChan = fallbackTimer.C
  59. }
  60. var errors []error
  61. for {
  62. select {
  63. case <-fallbackChan:
  64. fallbackCtx, fallbackCancel := context.WithCancel(ctx)
  65. defer fallbackCancel()
  66. for _, iif := range fallbackInterfaces {
  67. go startRacer(fallbackCtx, false, iif)
  68. }
  69. case res := <-results:
  70. if res.error == nil {
  71. return res.Conn, res.primary, nil
  72. }
  73. errors = append(errors, res.error)
  74. if len(errors) == len(primaryInterfaces)+len(fallbackInterfaces) {
  75. return nil, false, E.Errors(errors...)
  76. }
  77. if res.primary && fallbackTimer != nil && fallbackTimer.Stop() {
  78. fallbackTimer.Reset(0)
  79. }
  80. }
  81. }
  82. }
  83. func (d *DefaultDialer) dialParallelInterfaceFastFallback(ctx context.Context, dialer net.Dialer, network string, addr string, strategy C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration, resetFastFallback func(time.Time)) (net.Conn, bool, error) {
  84. primaryInterfaces, fallbackInterfaces := selectInterfaces(d.networkManager, strategy, interfaceType, fallbackInterfaceType)
  85. if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
  86. return nil, false, E.New("no available network interface")
  87. }
  88. if fallbackDelay == 0 {
  89. fallbackDelay = N.DefaultFallbackDelay
  90. }
  91. returned := make(chan struct{})
  92. defer close(returned)
  93. type dialResult struct {
  94. net.Conn
  95. error
  96. primary bool
  97. }
  98. startAt := time.Now()
  99. results := make(chan dialResult) // unbuffered
  100. startRacer := func(ctx context.Context, primary bool, iif adapter.NetworkInterface) {
  101. perNetDialer := dialer
  102. perNetDialer.Control = control.Append(perNetDialer.Control, control.BindToInterface(nil, iif.Name, iif.Index))
  103. conn, err := perNetDialer.DialContext(ctx, network, addr)
  104. if err != nil {
  105. select {
  106. case results <- dialResult{error: E.Cause(err, "dial ", iif.Name, " (", iif.Name, ")"), primary: primary}:
  107. case <-returned:
  108. }
  109. } else {
  110. select {
  111. case results <- dialResult{Conn: conn, primary: primary}:
  112. case <-returned:
  113. if primary && time.Since(startAt) <= fallbackDelay {
  114. resetFastFallback(time.Time{})
  115. }
  116. conn.Close()
  117. }
  118. }
  119. }
  120. for _, iif := range primaryInterfaces {
  121. go startRacer(ctx, true, iif)
  122. }
  123. fallbackCtx, fallbackCancel := context.WithCancel(ctx)
  124. defer fallbackCancel()
  125. for _, iif := range fallbackInterfaces {
  126. go startRacer(fallbackCtx, false, iif)
  127. }
  128. var errors []error
  129. for {
  130. select {
  131. case res := <-results:
  132. if res.error == nil {
  133. return res.Conn, res.primary, nil
  134. }
  135. errors = append(errors, res.error)
  136. if len(errors) == len(primaryInterfaces)+len(fallbackInterfaces) {
  137. return nil, false, E.Errors(errors...)
  138. }
  139. }
  140. }
  141. }
  142. func (d *DefaultDialer) listenSerialInterfacePacket(ctx context.Context, listener net.ListenConfig, network string, addr string, strategy C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, error) {
  143. primaryInterfaces, fallbackInterfaces := selectInterfaces(d.networkManager, strategy, interfaceType, fallbackInterfaceType)
  144. if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
  145. return nil, E.New("no available network interface")
  146. }
  147. var errors []error
  148. for _, primaryInterface := range primaryInterfaces {
  149. perNetListener := listener
  150. perNetListener.Control = control.Append(perNetListener.Control, control.BindToInterface(nil, primaryInterface.Name, primaryInterface.Index))
  151. conn, err := perNetListener.ListenPacket(ctx, network, addr)
  152. if err == nil {
  153. return conn, nil
  154. }
  155. errors = append(errors, E.Cause(err, "listen ", primaryInterface.Name, " (", primaryInterface.Name, ")"))
  156. }
  157. for _, fallbackInterface := range fallbackInterfaces {
  158. perNetListener := listener
  159. perNetListener.Control = control.Append(perNetListener.Control, control.BindToInterface(nil, fallbackInterface.Name, fallbackInterface.Index))
  160. conn, err := perNetListener.ListenPacket(ctx, network, addr)
  161. if err == nil {
  162. return conn, nil
  163. }
  164. errors = append(errors, E.Cause(err, "listen ", fallbackInterface.Name, " (", fallbackInterface.Name, ")"))
  165. }
  166. return nil, E.Errors(errors...)
  167. }
  168. func selectInterfaces(networkManager adapter.NetworkManager, strategy C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType) (primaryInterfaces []adapter.NetworkInterface, fallbackInterfaces []adapter.NetworkInterface) {
  169. interfaces := networkManager.NetworkInterfaces()
  170. switch strategy {
  171. case C.NetworkStrategyDefault:
  172. if len(interfaceType) == 0 {
  173. defaultIf := networkManager.InterfaceMonitor().DefaultInterface()
  174. if defaultIf != nil {
  175. for _, iif := range interfaces {
  176. if iif.Index == defaultIf.Index {
  177. primaryInterfaces = append(primaryInterfaces, iif)
  178. }
  179. }
  180. } else {
  181. primaryInterfaces = interfaces
  182. }
  183. } else {
  184. primaryInterfaces = common.Filter(interfaces, func(it adapter.NetworkInterface) bool {
  185. return common.Contains(interfaceType, it.Type)
  186. })
  187. }
  188. case C.NetworkStrategyHybrid:
  189. if len(interfaceType) == 0 {
  190. primaryInterfaces = interfaces
  191. } else {
  192. primaryInterfaces = common.Filter(interfaces, func(it adapter.NetworkInterface) bool {
  193. return common.Contains(interfaceType, it.Type)
  194. })
  195. }
  196. case C.NetworkStrategyFallback:
  197. if len(interfaceType) == 0 {
  198. defaultIf := networkManager.InterfaceMonitor().DefaultInterface()
  199. if defaultIf != nil {
  200. for _, iif := range interfaces {
  201. if iif.Index == defaultIf.Index {
  202. primaryInterfaces = append(primaryInterfaces, iif)
  203. break
  204. }
  205. }
  206. } else {
  207. primaryInterfaces = interfaces
  208. }
  209. } else {
  210. primaryInterfaces = common.Filter(interfaces, func(it adapter.NetworkInterface) bool {
  211. return common.Contains(interfaceType, it.Type)
  212. })
  213. }
  214. if len(fallbackInterfaceType) == 0 {
  215. fallbackInterfaces = common.Filter(interfaces, func(it adapter.NetworkInterface) bool {
  216. return !common.Any(primaryInterfaces, func(iif adapter.NetworkInterface) bool {
  217. return it.Index == iif.Index
  218. })
  219. })
  220. } else {
  221. fallbackInterfaces = common.Filter(interfaces, func(iif adapter.NetworkInterface) bool {
  222. return common.Contains(fallbackInterfaceType, iif.Type)
  223. })
  224. }
  225. }
  226. return primaryInterfaces, fallbackInterfaces
  227. }