setup.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package libbox
  2. import (
  3. "math"
  4. "os"
  5. "path/filepath"
  6. "runtime"
  7. "runtime/debug"
  8. "strings"
  9. "time"
  10. "github.com/sagernet/sing-box/common/networkquality"
  11. "github.com/sagernet/sing-box/common/stun"
  12. C "github.com/sagernet/sing-box/constant"
  13. "github.com/sagernet/sing-box/dns"
  14. "github.com/sagernet/sing-box/experimental/locale"
  15. "github.com/sagernet/sing-box/log"
  16. "github.com/sagernet/sing-box/service/oomkiller"
  17. "github.com/sagernet/sing/common/byteformats"
  18. E "github.com/sagernet/sing/common/exceptions"
  19. )
  20. var (
  21. sBasePath string
  22. sWorkingPath string
  23. sTempPath string
  24. sUserID int
  25. sGroupID int
  26. sFixAndroidStack bool
  27. sCommandServerListenPort uint16
  28. sCommandServerSecret string
  29. sLogMaxLines int
  30. sDebug bool
  31. sCrashReportSource string
  32. sOOMKillerEnabled bool
  33. sOOMKillerDisabled bool
  34. sOOMMemoryLimit int64
  35. )
  36. func init() {
  37. debug.SetPanicOnFault(true)
  38. debug.SetTraceback("all")
  39. }
  40. type SetupOptions struct {
  41. BasePath string
  42. WorkingPath string
  43. TempPath string
  44. FixAndroidStack bool
  45. CommandServerListenPort int32
  46. CommandServerSecret string
  47. LogMaxLines int
  48. Debug bool
  49. CrashReportSource string
  50. OomKillerEnabled bool
  51. OomKillerDisabled bool
  52. OomMemoryLimit int64
  53. }
  54. func applySetupOptions(options *SetupOptions) {
  55. sBasePath = options.BasePath
  56. sWorkingPath = options.WorkingPath
  57. sTempPath = options.TempPath
  58. sUserID = os.Getuid()
  59. sGroupID = os.Getgid()
  60. // TODO: remove after fixed
  61. // https://github.com/golang/go/issues/68760
  62. sFixAndroidStack = options.FixAndroidStack
  63. sCommandServerListenPort = uint16(options.CommandServerListenPort)
  64. sCommandServerSecret = options.CommandServerSecret
  65. sLogMaxLines = options.LogMaxLines
  66. sDebug = options.Debug
  67. sCrashReportSource = options.CrashReportSource
  68. ReloadSetupOptions(options)
  69. }
  70. func ReloadSetupOptions(options *SetupOptions) {
  71. sOOMKillerEnabled = options.OomKillerEnabled
  72. sOOMKillerDisabled = options.OomKillerDisabled
  73. sOOMMemoryLimit = options.OomMemoryLimit
  74. if sOOMKillerEnabled {
  75. if sOOMMemoryLimit == 0 && C.IsIos {
  76. sOOMMemoryLimit = oomkiller.DefaultAppleNetworkExtensionMemoryLimit
  77. }
  78. if sOOMMemoryLimit > 0 {
  79. debug.SetMemoryLimit(sOOMMemoryLimit * 3 / 4)
  80. } else {
  81. debug.SetMemoryLimit(math.MaxInt64)
  82. }
  83. } else {
  84. debug.SetMemoryLimit(math.MaxInt64)
  85. }
  86. }
  87. func Setup(options *SetupOptions) error {
  88. applySetupOptions(options)
  89. os.MkdirAll(sWorkingPath, 0o777)
  90. os.MkdirAll(sTempPath, 0o777)
  91. return redirectStderr(filepath.Join(sWorkingPath, "CrashReport-"+sCrashReportSource+".log"))
  92. }
  93. func SetLocale(localeId string) error {
  94. if strings.Contains(localeId, "@") {
  95. localeId = strings.Split(localeId, "@")[0]
  96. }
  97. if !locale.Set(localeId) {
  98. return E.New("unsupported locale: ", localeId)
  99. }
  100. return nil
  101. }
  102. func Version() string {
  103. return C.Version
  104. }
  105. func GoVersion() string {
  106. return runtime.Version() + ", " + runtime.GOOS + "/" + runtime.GOARCH
  107. }
  108. func FormatBytes(length int64) string {
  109. return byteformats.FormatKBytes(uint64(length))
  110. }
  111. func FormatMemoryBytes(length int64) string {
  112. return byteformats.FormatMemoryKBytes(uint64(length))
  113. }
  114. func FormatDuration(duration int64) string {
  115. return log.FormatDuration(time.Duration(duration) * time.Millisecond)
  116. }
  117. func FormatBitrate(bps int64) string {
  118. return networkquality.FormatBitrate(bps)
  119. }
  120. const NetworkQualityDefaultConfigURL = networkquality.DefaultConfigURL
  121. const NetworkQualityDefaultMaxRuntimeSeconds = int32(networkquality.DefaultMaxRuntime / time.Second)
  122. const (
  123. NetworkQualityAccuracyLow = int32(networkquality.AccuracyLow)
  124. NetworkQualityAccuracyMedium = int32(networkquality.AccuracyMedium)
  125. NetworkQualityAccuracyHigh = int32(networkquality.AccuracyHigh)
  126. )
  127. const (
  128. NetworkQualityPhaseIdle = int32(networkquality.PhaseIdle)
  129. NetworkQualityPhaseDownload = int32(networkquality.PhaseDownload)
  130. NetworkQualityPhaseUpload = int32(networkquality.PhaseUpload)
  131. NetworkQualityPhaseDone = int32(networkquality.PhaseDone)
  132. )
  133. const STUNDefaultServer = stun.DefaultServer
  134. const (
  135. STUNPhaseBinding = int32(stun.PhaseBinding)
  136. STUNPhaseNATMapping = int32(stun.PhaseNATMapping)
  137. STUNPhaseNATFiltering = int32(stun.PhaseNATFiltering)
  138. STUNPhaseDone = int32(stun.PhaseDone)
  139. )
  140. const (
  141. NATMappingEndpointIndependent = int32(stun.NATMappingEndpointIndependent)
  142. NATMappingAddressDependent = int32(stun.NATMappingAddressDependent)
  143. NATMappingAddressAndPortDependent = int32(stun.NATMappingAddressAndPortDependent)
  144. )
  145. const (
  146. NATFilteringEndpointIndependent = int32(stun.NATFilteringEndpointIndependent)
  147. NATFilteringAddressDependent = int32(stun.NATFilteringAddressDependent)
  148. NATFilteringAddressAndPortDependent = int32(stun.NATFilteringAddressAndPortDependent)
  149. )
  150. func FormatNATMapping(value int32) string {
  151. return stun.NATMapping(value).String()
  152. }
  153. func FormatNATFiltering(value int32) string {
  154. return stun.NATFiltering(value).String()
  155. }
  156. func FormatFQDN(fqdn string) string {
  157. return dns.FqdnToDomain(fqdn)
  158. }
  159. func ProxyDisplayType(proxyType string) string {
  160. return C.ProxyDisplayName(proxyType)
  161. }