config.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright (c) 2015, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package psiphon
  20. import (
  21. "encoding/json"
  22. "errors"
  23. "os"
  24. "time"
  25. )
  26. // TODO: allow all params to be configured
  27. const (
  28. VERSION = "0.0.9"
  29. DATA_STORE_FILENAME = "psiphon.db"
  30. CONNECTION_WORKER_POOL_SIZE = 10
  31. TUNNEL_POOL_SIZE = 1
  32. TUNNEL_CONNECT_TIMEOUT = 15 * time.Second
  33. TUNNEL_READ_TIMEOUT = 0 * time.Second
  34. TUNNEL_WRITE_TIMEOUT = 5 * time.Second
  35. TUNNEL_OPERATE_SHUTDOWN_TIMEOUT = 2 * time.Second
  36. TUNNEL_SSH_KEEP_ALIVE_PAYLOAD_MAX_BYTES = 256
  37. TUNNEL_SSH_KEEP_ALIVE_PERIOD_MIN = 60 * time.Second
  38. TUNNEL_SSH_KEEP_ALIVE_PERIOD_MAX = 120 * time.Second
  39. TUNNEL_SSH_KEEP_ALIVE_TIMEOUT = 10 * time.Second
  40. ESTABLISH_TUNNEL_TIMEOUT_SECONDS = 300
  41. ESTABLISH_TUNNEL_WORK_TIME_SECONDS = 60 * time.Second
  42. ESTABLISH_TUNNEL_PAUSE_PERIOD = 5 * time.Second
  43. PORT_FORWARD_FAILURE_THRESHOLD = 10
  44. HTTP_PROXY_ORIGIN_SERVER_TIMEOUT = 15 * time.Second
  45. HTTP_PROXY_MAX_IDLE_CONNECTIONS_PER_HOST = 50
  46. FETCH_REMOTE_SERVER_LIST_TIMEOUT = 10 * time.Second
  47. FETCH_REMOTE_SERVER_LIST_RETRY_PERIOD = 5 * time.Second
  48. FETCH_REMOTE_SERVER_LIST_STALE_PERIOD = 6 * time.Hour
  49. PSIPHON_API_CLIENT_SESSION_ID_LENGTH = 16
  50. PSIPHON_API_SERVER_TIMEOUT = 20 * time.Second
  51. PSIPHON_API_STATUS_REQUEST_PERIOD_MIN = 5 * time.Minute
  52. PSIPHON_API_STATUS_REQUEST_PERIOD_MAX = 10 * time.Minute
  53. PSIPHON_API_STATUS_REQUEST_PADDING_MAX_BYTES = 256
  54. PSIPHON_API_CONNECTED_REQUEST_PERIOD = 24 * time.Hour
  55. PSIPHON_API_CONNECTED_REQUEST_RETRY_PERIOD = 5 * time.Second
  56. FETCH_ROUTES_TIMEOUT = 1 * time.Minute
  57. DOWNLOAD_UPGRADE_TIMEOUT = 15 * time.Minute
  58. DOWNLOAD_UPGRADE_RETRY_PAUSE_PERIOD = 5 * time.Second
  59. )
  60. // To distinguish omitted timeout params from explicit 0 value timeout
  61. // params, these params are int pointers. nil means no param was supplied
  62. // so use the default; a non-nil pointer to 0 means no timeout.
  63. type Config struct {
  64. LogFilename string
  65. DataStoreDirectory string
  66. DataStoreTempDirectory string
  67. PropagationChannelId string
  68. SponsorId string
  69. RemoteServerListUrl string
  70. RemoteServerListSignaturePublicKey string
  71. ClientVersion string
  72. ClientPlatform string
  73. TunnelWholeDevice int
  74. EgressRegion string
  75. TunnelProtocol string
  76. EstablishTunnelTimeoutSeconds *int
  77. LocalSocksProxyPort int
  78. LocalHttpProxyPort int
  79. ConnectionWorkerPoolSize int
  80. TunnelPoolSize int
  81. PortForwardFailureThreshold int
  82. UpstreamProxyUrl string
  83. NetworkConnectivityChecker NetworkConnectivityChecker
  84. DeviceBinder DeviceBinder
  85. DnsServerGetter DnsServerGetter
  86. TargetServerEntry string
  87. DisableApi bool
  88. DisableRemoteServerListFetcher bool
  89. SplitTunnelRoutesUrlFormat string
  90. SplitTunnelRoutesSignaturePublicKey string
  91. SplitTunnelDnsServer string
  92. UpgradeDownloadUrl string
  93. UpgradeDownloadFilename string
  94. }
  95. // LoadConfig parses and validates a JSON format Psiphon config JSON
  96. // string and returns a Config struct populated with config values.
  97. func LoadConfig(configJson []byte) (*Config, error) {
  98. var config Config
  99. err := json.Unmarshal(configJson, &config)
  100. if err != nil {
  101. return nil, ContextError(err)
  102. }
  103. // These fields are required; the rest are optional
  104. if config.PropagationChannelId == "" {
  105. return nil, ContextError(
  106. errors.New("propagation channel ID is missing from the configuration file"))
  107. }
  108. if config.SponsorId == "" {
  109. return nil, ContextError(
  110. errors.New("sponsor ID is missing from the configuration file"))
  111. }
  112. if config.DataStoreDirectory == "" {
  113. config.DataStoreDirectory, err = os.Getwd()
  114. if err != nil {
  115. return nil, ContextError(err)
  116. }
  117. }
  118. if config.ClientVersion == "" {
  119. config.ClientVersion = "0"
  120. }
  121. if config.TunnelProtocol != "" {
  122. if !Contains(SupportedTunnelProtocols, config.TunnelProtocol) {
  123. return nil, ContextError(
  124. errors.New("invalid tunnel protocol"))
  125. }
  126. }
  127. if config.EstablishTunnelTimeoutSeconds == nil {
  128. defaultEstablishTunnelTimeoutSeconds := ESTABLISH_TUNNEL_TIMEOUT_SECONDS
  129. config.EstablishTunnelTimeoutSeconds = &defaultEstablishTunnelTimeoutSeconds
  130. }
  131. if config.ConnectionWorkerPoolSize == 0 {
  132. config.ConnectionWorkerPoolSize = CONNECTION_WORKER_POOL_SIZE
  133. }
  134. if config.TunnelPoolSize == 0 {
  135. config.TunnelPoolSize = TUNNEL_POOL_SIZE
  136. }
  137. if config.PortForwardFailureThreshold == 0 {
  138. config.PortForwardFailureThreshold = PORT_FORWARD_FAILURE_THRESHOLD
  139. }
  140. if config.NetworkConnectivityChecker != nil {
  141. return nil, ContextError(errors.New("NetworkConnectivityChecker interface must be set at runtime"))
  142. }
  143. if config.DeviceBinder != nil {
  144. return nil, ContextError(errors.New("DeviceBinder interface must be set at runtime"))
  145. }
  146. if config.DnsServerGetter != nil {
  147. return nil, ContextError(errors.New("DnsServerGetter interface must be set at runtime"))
  148. }
  149. return &config, nil
  150. }