trafficRules.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Copyright (c) 2016, 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 server
  20. import (
  21. "encoding/json"
  22. "io/ioutil"
  23. "strings"
  24. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon"
  25. )
  26. // TrafficRulesSet represents the various traffic rules to
  27. // apply to Psiphon client tunnels. The Reload function supports
  28. // hot reloading of rules data while the server is running.
  29. type TrafficRulesSet struct {
  30. psiphon.ReloadableFile
  31. // DefaultRules specifies the traffic rules to be used when no
  32. // regional-specific rules are set or apply to a particular
  33. // client.
  34. DefaultRules TrafficRules
  35. // RegionalRules specifies the traffic rules for particular client
  36. // regions (countries) as determined by GeoIP lookup of the client
  37. // IP address. The key for each regional traffic rule entry is one
  38. // or more space delimited ISO 3166-1 alpha-2 country codes.
  39. RegionalRules map[string]TrafficRules
  40. }
  41. // RateLimits specify the rate limits for tunneled data transfer
  42. // between an individual client and the server.
  43. type RateLimits struct {
  44. // DownstreamUnlimitedBytes specifies the number of downstream
  45. // bytes to transfer, approximately, before starting rate
  46. // limiting.
  47. DownstreamUnlimitedBytes int64
  48. // DownstreamBytesPerSecond specifies a rate limit for downstream
  49. // data transfer. The default, 0, is no limit.
  50. DownstreamBytesPerSecond int
  51. // UpstreamUnlimitedBytes specifies the number of upstream
  52. // bytes to transfer, approximately, before starting rate
  53. // limiting.
  54. UpstreamUnlimitedBytes int64
  55. // UpstreamBytesPerSecond specifies a rate limit for upstream
  56. // data transfer. The default, 0, is no limit.
  57. UpstreamBytesPerSecond int
  58. }
  59. // TrafficRules specify the limits placed on client traffic.
  60. type TrafficRules struct {
  61. // DefaultLimits are the rate limits to be applied when
  62. // no protocol-specific rates are set.
  63. DefaultLimits RateLimits
  64. // ProtocolLimits specifies the rate limits for particular
  65. // tunnel protocols. The key for each rate limit entry is one
  66. // or more space delimited Psiphon tunnel protocol names. Valid
  67. // tunnel protocols includes the same list as for
  68. // TunnelProtocolPorts.
  69. ProtocolLimits map[string]RateLimits
  70. // IdleTCPPortForwardTimeoutMilliseconds is the timeout period
  71. // after which idle (no bytes flowing in either direction)
  72. // client TCP port forwards are preemptively closed.
  73. // The default, 0, is no idle timeout.
  74. IdleTCPPortForwardTimeoutMilliseconds int
  75. // IdleUDPPortForwardTimeoutMilliseconds is the timeout period
  76. // after which idle (no bytes flowing in either direction)
  77. // client UDP port forwards are preemptively closed.
  78. // The default, 0, is no idle timeout.
  79. IdleUDPPortForwardTimeoutMilliseconds int
  80. // MaxTCPPortForwardCount is the maximum number of TCP port
  81. // forwards each client may have open concurrently.
  82. // The default, 0, is no maximum.
  83. MaxTCPPortForwardCount int
  84. // MaxUDPPortForwardCount is the maximum number of UDP port
  85. // forwards each client may have open concurrently.
  86. // The default, 0, is no maximum.
  87. MaxUDPPortForwardCount int
  88. // AllowTCPPorts specifies a whitelist of TCP ports that
  89. // are permitted for port forwarding. When set, only ports
  90. // in the list are accessible to clients.
  91. AllowTCPPorts []int
  92. // AllowUDPPorts specifies a whitelist of UDP ports that
  93. // are permitted for port forwarding. When set, only ports
  94. // in the list are accessible to clients.
  95. AllowUDPPorts []int
  96. // DenyTCPPorts specifies a blacklist of TCP ports that
  97. // are not permitted for port forwarding. When set, the
  98. // ports in the list are inaccessible to clients.
  99. DenyTCPPorts []int
  100. // DenyUDPPorts specifies a blacklist of UDP ports that
  101. // are not permitted for port forwarding. When set, the
  102. // ports in the list are inaccessible to clients.
  103. DenyUDPPorts []int
  104. }
  105. // NewTrafficRulesSet initializes a TrafficRulesSet with
  106. // the rules data in the specified config file.
  107. func NewTrafficRulesSet(filename string) (*TrafficRulesSet, error) {
  108. set := &TrafficRulesSet{}
  109. set.ReloadableFile = psiphon.NewReloadableFile(
  110. filename,
  111. func(filename string) error {
  112. configJSON, err := ioutil.ReadFile(filename)
  113. if err != nil {
  114. // On error, state remains the same
  115. return psiphon.ContextError(err)
  116. }
  117. err = json.Unmarshal(configJSON, &set)
  118. if err != nil {
  119. // On error, state remains the same
  120. // (Unmarshal first validates the provided
  121. // JOSN and then populates the interface)
  122. return psiphon.ContextError(err)
  123. }
  124. return nil
  125. })
  126. _, err := set.Reload()
  127. if err != nil {
  128. return nil, psiphon.ContextError(err)
  129. }
  130. return set, nil
  131. }
  132. // GetTrafficRules looks up the traffic rules for the specified country. If there
  133. // are no regional TrafficRules for the country, default TrafficRules are returned.
  134. func (set *TrafficRulesSet) GetTrafficRules(clientCountryCode string) TrafficRules {
  135. set.ReloadableFile.RLock()
  136. defer set.ReloadableFile.RUnlock()
  137. // TODO: faster lookup?
  138. for countryCodes, trafficRules := range set.RegionalRules {
  139. for _, countryCode := range strings.Split(countryCodes, " ") {
  140. if countryCode == clientCountryCode {
  141. return trafficRules
  142. }
  143. }
  144. }
  145. return set.DefaultRules
  146. }
  147. // GetRateLimits looks up the rate limits for the specified tunnel protocol.
  148. // If there are no specific RateLimits for the protocol, default RateLimits are
  149. // returned.
  150. func (rules *TrafficRules) GetRateLimits(clientTunnelProtocol string) RateLimits {
  151. // TODO: faster lookup?
  152. for tunnelProtocols, rateLimits := range rules.ProtocolLimits {
  153. for _, tunnelProtocol := range strings.Split(tunnelProtocols, " ") {
  154. if tunnelProtocol == clientTunnelProtocol {
  155. return rateLimits
  156. }
  157. }
  158. }
  159. return rules.DefaultLimits
  160. }