config.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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.7"
  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. ESTABLISH_TUNNEL_TIMEOUT_SECONDS = 300
  40. ESTABLISH_TUNNEL_PAUSE_PERIOD = 10 * time.Second
  41. PORT_FORWARD_FAILURE_THRESHOLD = 10
  42. HTTP_PROXY_ORIGIN_SERVER_TIMEOUT = 15 * time.Second
  43. HTTP_PROXY_MAX_IDLE_CONNECTIONS_PER_HOST = 50
  44. FETCH_REMOTE_SERVER_LIST_TIMEOUT = 10 * time.Second
  45. FETCH_REMOTE_SERVER_LIST_RETRY_PERIOD = 5 * time.Second
  46. FETCH_REMOTE_SERVER_LIST_STALE_PERIOD = 6 * time.Hour
  47. PSIPHON_API_CLIENT_SESSION_ID_LENGTH = 16
  48. PSIPHON_API_SERVER_TIMEOUT = 20 * time.Second
  49. PSIPHON_API_STATUS_REQUEST_PERIOD_MIN = 5 * time.Minute
  50. PSIPHON_API_STATUS_REQUEST_PERIOD_MAX = 10 * time.Minute
  51. PSIPHON_API_STATUS_REQUEST_PADDING_MAX_BYTES = 256
  52. PSIPHON_API_CONNECTED_REQUEST_PERIOD = 24 * time.Hour
  53. PSIPHON_API_CONNECTED_REQUEST_RETRY_PERIOD = 5 * time.Second
  54. FETCH_ROUTES_TIMEOUT = 10 * time.Second
  55. )
  56. // To distinguish omitted timeout params from explicit 0 value timeout
  57. // params, these params are int pointers. nil means no param was supplied
  58. // so use the default; a non-nil pointer to 0 means no timeout.
  59. type Config struct {
  60. LogFilename string
  61. DataStoreDirectory string
  62. DataStoreTempDirectory string
  63. PropagationChannelId string
  64. SponsorId string
  65. RemoteServerListUrl string
  66. RemoteServerListSignaturePublicKey string
  67. ClientVersion string
  68. ClientPlatform string
  69. TunnelWholeDevice int
  70. EgressRegion string
  71. TunnelProtocol string
  72. EstablishTunnelTimeoutSeconds *int
  73. LocalSocksProxyPort int
  74. LocalHttpProxyPort int
  75. ConnectionWorkerPoolSize int
  76. TunnelPoolSize int
  77. PortForwardFailureThreshold int
  78. UpstreamHttpProxyAddress string
  79. NetworkConnectivityChecker NetworkConnectivityChecker
  80. DeviceBinder DeviceBinder
  81. DnsServerGetter DnsServerGetter
  82. TargetServerEntry string
  83. DisableApi bool
  84. DisableRemoteServerListFetcher bool
  85. SplitTunnelRoutesUrlFormat string
  86. SplitTunnelRoutesSignaturePublicKey string
  87. SplitTunnelDnsServer string
  88. }
  89. // LoadConfig parses and validates a JSON format Psiphon config JSON
  90. // string and returns a Config struct populated with config values.
  91. func LoadConfig(configJson []byte) (*Config, error) {
  92. var config Config
  93. err := json.Unmarshal(configJson, &config)
  94. if err != nil {
  95. return nil, ContextError(err)
  96. }
  97. // These fields are required; the rest are optional
  98. if config.PropagationChannelId == "" {
  99. return nil, ContextError(
  100. errors.New("propagation channel ID is missing from the configuration file"))
  101. }
  102. if config.SponsorId == "" {
  103. return nil, ContextError(
  104. errors.New("sponsor ID is missing from the configuration file"))
  105. }
  106. if config.RemoteServerListUrl == "" {
  107. return nil, ContextError(
  108. errors.New("remote server list URL is missing from the configuration file"))
  109. }
  110. if config.RemoteServerListSignaturePublicKey == "" {
  111. return nil, ContextError(
  112. errors.New("remote server list signature public key is missing from the configuration file"))
  113. }
  114. if config.DataStoreDirectory == "" {
  115. config.DataStoreDirectory, err = os.Getwd()
  116. if err != nil {
  117. return nil, ContextError(err)
  118. }
  119. }
  120. if config.ClientVersion == "" {
  121. config.ClientVersion = "0"
  122. }
  123. if config.TunnelProtocol != "" {
  124. if !Contains(SupportedTunnelProtocols, config.TunnelProtocol) {
  125. return nil, ContextError(
  126. errors.New("invalid tunnel protocol"))
  127. }
  128. }
  129. if config.EstablishTunnelTimeoutSeconds == nil {
  130. defaultEstablishTunnelTimeoutSeconds := ESTABLISH_TUNNEL_TIMEOUT_SECONDS
  131. config.EstablishTunnelTimeoutSeconds = &defaultEstablishTunnelTimeoutSeconds
  132. }
  133. if config.ConnectionWorkerPoolSize == 0 {
  134. config.ConnectionWorkerPoolSize = CONNECTION_WORKER_POOL_SIZE
  135. }
  136. if config.TunnelPoolSize == 0 {
  137. config.TunnelPoolSize = TUNNEL_POOL_SIZE
  138. }
  139. if config.PortForwardFailureThreshold == 0 {
  140. config.PortForwardFailureThreshold = PORT_FORWARD_FAILURE_THRESHOLD
  141. }
  142. if config.NetworkConnectivityChecker != nil {
  143. return nil, ContextError(errors.New("NetworkConnectivityChecker interface must be set at runtime"))
  144. }
  145. if config.DeviceBinder != nil {
  146. return nil, ContextError(errors.New("DeviceBinder interface must be set at runtime"))
  147. }
  148. if config.DnsServerGetter != nil {
  149. return nil, ContextError(errors.New("DnsServerGetter interface must be set at runtime"))
  150. }
  151. return &config, nil
  152. }