github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/server/trafficRules.go (about)

     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  
    20  package server
    21  
    22  import (
    23  	"encoding/json"
    24  	"net"
    25  	"time"
    26  
    27  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
    28  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
    29  )
    30  
    31  const (
    32  	DEFAULT_IDLE_TCP_PORT_FORWARD_TIMEOUT_MILLISECONDS        = 30000
    33  	DEFAULT_IDLE_UDP_PORT_FORWARD_TIMEOUT_MILLISECONDS        = 30000
    34  	DEFAULT_DIAL_TCP_PORT_FORWARD_TIMEOUT_MILLISECONDS        = 10000
    35  	DEFAULT_MAX_TCP_DIALING_PORT_FORWARD_COUNT                = 64
    36  	DEFAULT_MAX_TCP_PORT_FORWARD_COUNT                        = 512
    37  	DEFAULT_MAX_UDP_PORT_FORWARD_COUNT                        = 32
    38  	DEFAULT_MEEK_RATE_LIMITER_GARBAGE_COLLECTOR_TRIGGER_COUNT = 5000
    39  	DEFAULT_MEEK_RATE_LIMITER_REAP_HISTORY_FREQUENCY_SECONDS  = 300
    40  	DEFAULT_MEEK_RATE_LIMITER_MAX_ENTRIES                     = 1000000
    41  )
    42  
    43  // TrafficRulesSet represents the various traffic rules to
    44  // apply to Psiphon client tunnels. The Reload function supports
    45  // hot reloading of rules data while the server is running.
    46  //
    47  // For a given client, the traffic rules are determined by starting
    48  // with DefaultRules, then finding the first (if any)
    49  // FilteredTrafficRules match and overriding the defaults with fields
    50  // set in the selected FilteredTrafficRules.
    51  type TrafficRulesSet struct {
    52  	common.ReloadableFile
    53  
    54  	// DefaultRules are the base values to use as defaults for all
    55  	// clients.
    56  	DefaultRules TrafficRules
    57  
    58  	// FilteredTrafficRules is an ordered list of filter/rules pairs.
    59  	// For each client, the first matching Filter in FilteredTrafficRules
    60  	// determines the additional Rules that are selected and applied
    61  	// on top of DefaultRules.
    62  	//
    63  	// When ExceptFilter is present, a client must match Filter and not match
    64  	// ExceptFilter.
    65  	FilteredRules []struct {
    66  		Filter       TrafficRulesFilter
    67  		ExceptFilter *TrafficRulesFilter
    68  		Rules        TrafficRules
    69  	}
    70  
    71  	// MeekRateLimiterHistorySize enables the late-stage meek rate limiter and
    72  	// sets its history size. The late-stage meek rate limiter acts on client
    73  	// IPs relayed in MeekProxyForwardedForHeaders, and so it must wait for
    74  	// the HTTP headers to be read. This rate limiter immediately terminates
    75  	// any client endpoint request or any request to create a new session, but
    76  	// not any meek request for an existing session, if the
    77  	// MeekRateLimiterHistorySize requests occur in
    78  	// MeekRateLimiterThresholdSeconds.
    79  	//
    80  	// A use case for the the meek rate limiter is to mitigate dangling resource
    81  	// usage that results from meek connections that are partially established
    82  	// and then interrupted (e.g, drop packets after allowing up to the initial
    83  	// HTTP request and header lines). In the case of CDN fronted meek, the CDN
    84  	// itself may hold open the interrupted connection.
    85  	//
    86  	// The scope of rate limiting may be
    87  	// limited using LimitMeekRateLimiterTunnelProtocols/Regions/ISPs/ASNs/Cities.
    88  	//
    89  	// Upon hot reload,
    90  	// MeekRateLimiterHistorySize/MeekRateLimiterThresholdSeconds are not
    91  	// changed for currently tracked client IPs; new values will apply to
    92  	// newly tracked client IPs.
    93  	MeekRateLimiterHistorySize int
    94  
    95  	// MeekRateLimiterThresholdSeconds is part of the meek rate limiter
    96  	// specification and must be set when MeekRateLimiterHistorySize is set.
    97  	MeekRateLimiterThresholdSeconds int
    98  
    99  	// MeekRateLimiterTunnelProtocols, if set, limits application of the meek
   100  	// late-stage rate limiter to the specified meek protocols. When omitted or
   101  	// empty, meek rate limiting is applied to all meek protocols.
   102  	MeekRateLimiterTunnelProtocols []string
   103  
   104  	// MeekRateLimiterRegions, if set, limits application of the meek
   105  	// late-stage rate limiter to clients in the specified list of GeoIP
   106  	// countries. When omitted or empty, meek rate limiting, if configured,
   107  	// is applied to any client country.
   108  	MeekRateLimiterRegions []string
   109  
   110  	// MeekRateLimiterISPs, if set, limits application of the meek
   111  	// late-stage rate limiter to clients in the specified list of GeoIP
   112  	// ISPs. When omitted or empty, meek rate limiting, if configured,
   113  	// is applied to any client ISP.
   114  	MeekRateLimiterISPs []string
   115  
   116  	// MeekRateLimiterASNs, if set, limits application of the meek
   117  	// late-stage rate limiter to clients in the specified list of GeoIP
   118  	// ASNs. When omitted or empty, meek rate limiting, if configured,
   119  	// is applied to any client ASN.
   120  	MeekRateLimiterASNs []string
   121  
   122  	// MeekRateLimiterCities, if set, limits application of the meek
   123  	// late-stage rate limiter to clients in the specified list of GeoIP
   124  	// cities. When omitted or empty, meek rate limiting, if configured,
   125  	// is applied to any client city.
   126  	MeekRateLimiterCities []string
   127  
   128  	// MeekRateLimiterGarbageCollectionTriggerCount specifies the number of
   129  	// rate limit events after which garbage collection is manually triggered
   130  	// in order to reclaim memory used by rate limited and other rejected
   131  	// requests.
   132  	//
   133  	// A default of DEFAULT_MEEK_RATE_LIMITER_GARBAGE_COLLECTOR_TRIGGER_COUNT
   134  	// is used when MeekRateLimiterGarbageCollectionTriggerCount is 0.
   135  	MeekRateLimiterGarbageCollectionTriggerCount int
   136  
   137  	// MeekRateLimiterReapHistoryFrequencySeconds specifies a schedule for
   138  	// reaping old records from the rate limit history.
   139  	//
   140  	// A default of DEFAULT_MEEK_RATE_LIMITER_REAP_HISTORY_FREQUENCY_SECONDS
   141  	// is used when MeekRateLimiterReapHistoryFrequencySeconds is 0.
   142  	//
   143  	// MeekRateLimiterReapHistoryFrequencySeconds is not applied upon hot
   144  	// reload.
   145  	MeekRateLimiterReapHistoryFrequencySeconds int
   146  
   147  	// MeekRateLimiterMaxEntries specifies a maximum size for the rate limit
   148  	// history.
   149  	MeekRateLimiterMaxEntries int
   150  }
   151  
   152  // TrafficRulesFilter defines a filter to match against client attributes.
   153  type TrafficRulesFilter struct {
   154  
   155  	// TunnelProtocols is a list of client tunnel protocols that must be
   156  	// in use to match this filter. When omitted or empty, any protocol
   157  	// matches.
   158  	TunnelProtocols []string
   159  
   160  	// Regions is a list of countries that the client must geolocate to in
   161  	// order to match this filter. When omitted or empty, any client country
   162  	// matches.
   163  	Regions []string
   164  
   165  	// ISPs is a list of ISPs that the client must geolocate to in order to
   166  	// match this filter. When omitted or empty, any client ISP matches.
   167  	ISPs []string
   168  
   169  	// ASNs is a list of ASNs that the client must geolocate to in order to
   170  	// match this filter. When omitted or empty, any client ASN matches.
   171  	ASNs []string
   172  
   173  	// Cities is a list of cities that the client must geolocate to in order to
   174  	// match this filter. When omitted or empty, any client city matches.
   175  	Cities []string
   176  
   177  	// APIProtocol specifies whether the client must use the SSH
   178  	// API protocol (when "ssh") or the web API protocol (when "web").
   179  	// When omitted or blank, any API protocol matches.
   180  	APIProtocol string
   181  
   182  	// HandshakeParameters specifies handshake API parameter names and
   183  	// a list of values, one of which must be specified to match this
   184  	// filter. Only scalar string API parameters may be filtered.
   185  	// Values may be patterns containing the '*' wildcard.
   186  	HandshakeParameters map[string][]string
   187  
   188  	// AuthorizedAccessTypes specifies a list of access types, at least
   189  	// one of which the client must have presented an active authorization
   190  	// for and which must not be revoked.
   191  	// AuthorizedAccessTypes is ignored when AuthorizationsRevoked is true.
   192  	AuthorizedAccessTypes []string
   193  
   194  	// ActiveAuthorizationIDs specifies a list of authorization IDs, at least
   195  	// one of which the client must have presented an active authorization
   196  	// for and which must not be revoked.
   197  	// ActiveAuthorizationIDs is ignored when AuthorizationsRevoked is true.
   198  	ActiveAuthorizationIDs []string
   199  
   200  	// AuthorizationsRevoked indicates whether the client's authorizations
   201  	// must have been revoked. When true, authorizations must have been
   202  	// revoked. When omitted or false, this field is ignored.
   203  	AuthorizationsRevoked bool
   204  
   205  	regionLookup                map[string]bool
   206  	ispLookup                   map[string]bool
   207  	asnLookup                   map[string]bool
   208  	cityLookup                  map[string]bool
   209  	activeAuthorizationIDLookup map[string]bool
   210  }
   211  
   212  // TrafficRules specify the limits placed on client traffic.
   213  type TrafficRules struct {
   214  
   215  	// RateLimits specifies data transfer rate limits for the
   216  	// client traffic.
   217  	RateLimits RateLimits
   218  
   219  	// DialTCPPortForwardTimeoutMilliseconds is the timeout period
   220  	// for dialing TCP port forwards. A value of 0 specifies no timeout.
   221  	// When omitted in DefaultRules,
   222  	// DEFAULT_TCP_PORT_FORWARD_DIAL_TIMEOUT_MILLISECONDS is used.
   223  	DialTCPPortForwardTimeoutMilliseconds *int
   224  
   225  	// IdleTCPPortForwardTimeoutMilliseconds is the timeout period
   226  	// after which idle (no bytes flowing in either direction)
   227  	// client TCP port forwards are preemptively closed.
   228  	// A value of 0 specifies no idle timeout. When omitted in
   229  	// DefaultRules, DEFAULT_IDLE_TCP_PORT_FORWARD_TIMEOUT_MILLISECONDS
   230  	// is used.
   231  	IdleTCPPortForwardTimeoutMilliseconds *int
   232  
   233  	// IdleUDPPortForwardTimeoutMilliseconds is the timeout period
   234  	// after which idle (no bytes flowing in either direction)
   235  	// client UDP port forwards are preemptively closed.
   236  	// A value of 0 specifies no idle timeout. When omitted in
   237  	// DefaultRules, DEFAULT_IDLE_UDP_PORT_FORWARD_TIMEOUT_MILLISECONDS
   238  	// is used.
   239  	IdleUDPPortForwardTimeoutMilliseconds *int
   240  
   241  	// MaxTCPDialingPortForwardCount is the maximum number of dialing
   242  	// TCP port forwards each client may have open concurrently. When
   243  	// persistently at the limit, new TCP port forwards are rejected.
   244  	// A value of 0 specifies no maximum. When omitted in
   245  	// DefaultRules, DEFAULT_MAX_TCP_DIALING_PORT_FORWARD_COUNT is used.
   246  	MaxTCPDialingPortForwardCount *int
   247  
   248  	// MaxTCPPortForwardCount is the maximum number of established TCP
   249  	// port forwards each client may have open concurrently. If at the
   250  	// limit when a new TCP port forward is established, the LRU
   251  	// established TCP port forward is closed.
   252  	// A value of 0 specifies no maximum. When omitted in
   253  	// DefaultRules, DEFAULT_MAX_TCP_PORT_FORWARD_COUNT is used.
   254  	MaxTCPPortForwardCount *int
   255  
   256  	// MaxUDPPortForwardCount is the maximum number of UDP port
   257  	// forwards each client may have open concurrently. If at the
   258  	// limit when a new UDP port forward is created, the LRU
   259  	// UDP port forward is closed.
   260  	// A value of 0 specifies no maximum. When omitted in
   261  	// DefaultRules, DEFAULT_MAX_UDP_PORT_FORWARD_COUNT is used.
   262  	MaxUDPPortForwardCount *int
   263  
   264  	// AllowTCPPorts specifies a list of TCP ports that are permitted for port
   265  	// forwarding. When set, only ports in the list are accessible to clients.
   266  	AllowTCPPorts *common.PortList
   267  
   268  	// AllowUDPPorts specifies a list of UDP ports that are permitted for port
   269  	// forwarding. When set, only ports in the list are accessible to clients.
   270  	AllowUDPPorts *common.PortList
   271  
   272  	// DisallowTCPPorts specifies a list of TCP ports that are not permitted for
   273  	// port forwarding. DisallowTCPPorts takes priority over AllowTCPPorts and
   274  	// AllowSubnets.
   275  	DisallowTCPPorts *common.PortList
   276  
   277  	// DisallowUDPPorts specifies a list of UDP ports that are not permitted for
   278  	// port forwarding. DisallowUDPPorts takes priority over AllowUDPPorts and
   279  	// AllowSubnets.
   280  	DisallowUDPPorts *common.PortList
   281  
   282  	// AllowSubnets specifies a list of IP address subnets for which all TCP and
   283  	// UDP ports are allowed. This list is consulted if a port is disallowed by
   284  	// the AllowTCPPorts or AllowUDPPorts configuration. Each entry is a IP
   285  	// subnet in CIDR notation.
   286  	//
   287  	// Limitation: currently, AllowSubnets only matches port forwards where the
   288  	// client sends an IP address. Domain names are not resolved before checking
   289  	// AllowSubnets.
   290  	AllowSubnets []string
   291  
   292  	// DisableDiscovery specifies whether to disable server entry discovery,
   293  	// to manage load on discovery servers.
   294  	DisableDiscovery *bool
   295  }
   296  
   297  // RateLimits is a clone of common.RateLimits with pointers
   298  // to fields to enable distinguishing between zero values and
   299  // omitted values in JSON serialized traffic rules.
   300  // See common.RateLimits for field descriptions.
   301  type RateLimits struct {
   302  	ReadUnthrottledBytes  *int64
   303  	ReadBytesPerSecond    *int64
   304  	WriteUnthrottledBytes *int64
   305  	WriteBytesPerSecond   *int64
   306  	CloseAfterExhausted   *bool
   307  
   308  	// EstablishmentRead/WriteBytesPerSecond are used in place of
   309  	// Read/WriteBytesPerSecond for tunnels in the establishment phase, from the
   310  	// initial network connection up to the completion of the API handshake.
   311  	EstablishmentReadBytesPerSecond  *int64
   312  	EstablishmentWriteBytesPerSecond *int64
   313  
   314  	// UnthrottleFirstTunnelOnly specifies whether any
   315  	// ReadUnthrottledBytes/WriteUnthrottledBytes apply
   316  	// only to the first tunnel in a session.
   317  	UnthrottleFirstTunnelOnly *bool
   318  }
   319  
   320  // CommonRateLimits converts a RateLimits to a common.RateLimits.
   321  func (rateLimits *RateLimits) CommonRateLimits(handshaked bool) common.RateLimits {
   322  	r := common.RateLimits{
   323  		ReadUnthrottledBytes:  *rateLimits.ReadUnthrottledBytes,
   324  		ReadBytesPerSecond:    *rateLimits.ReadBytesPerSecond,
   325  		WriteUnthrottledBytes: *rateLimits.WriteUnthrottledBytes,
   326  		WriteBytesPerSecond:   *rateLimits.WriteBytesPerSecond,
   327  		CloseAfterExhausted:   *rateLimits.CloseAfterExhausted,
   328  	}
   329  	if !handshaked {
   330  		r.ReadBytesPerSecond = *rateLimits.EstablishmentReadBytesPerSecond
   331  		r.WriteBytesPerSecond = *rateLimits.EstablishmentWriteBytesPerSecond
   332  	}
   333  	return r
   334  }
   335  
   336  // NewTrafficRulesSet initializes a TrafficRulesSet with
   337  // the rules data in the specified config file.
   338  func NewTrafficRulesSet(filename string) (*TrafficRulesSet, error) {
   339  
   340  	set := &TrafficRulesSet{}
   341  
   342  	set.ReloadableFile = common.NewReloadableFile(
   343  		filename,
   344  		true,
   345  		func(fileContent []byte, _ time.Time) error {
   346  			var newSet TrafficRulesSet
   347  			err := json.Unmarshal(fileContent, &newSet)
   348  			if err != nil {
   349  				return errors.Trace(err)
   350  			}
   351  			err = newSet.Validate()
   352  			if err != nil {
   353  				return errors.Trace(err)
   354  			}
   355  
   356  			// Modify actual traffic rules only after validation
   357  			set.MeekRateLimiterHistorySize = newSet.MeekRateLimiterHistorySize
   358  			set.MeekRateLimiterThresholdSeconds = newSet.MeekRateLimiterThresholdSeconds
   359  			set.MeekRateLimiterTunnelProtocols = newSet.MeekRateLimiterTunnelProtocols
   360  			set.MeekRateLimiterRegions = newSet.MeekRateLimiterRegions
   361  			set.MeekRateLimiterISPs = newSet.MeekRateLimiterISPs
   362  			set.MeekRateLimiterASNs = newSet.MeekRateLimiterASNs
   363  			set.MeekRateLimiterCities = newSet.MeekRateLimiterCities
   364  			set.MeekRateLimiterGarbageCollectionTriggerCount = newSet.MeekRateLimiterGarbageCollectionTriggerCount
   365  			set.MeekRateLimiterReapHistoryFrequencySeconds = newSet.MeekRateLimiterReapHistoryFrequencySeconds
   366  			set.DefaultRules = newSet.DefaultRules
   367  			set.FilteredRules = newSet.FilteredRules
   368  
   369  			set.initLookups()
   370  
   371  			return nil
   372  		})
   373  
   374  	_, err := set.Reload()
   375  	if err != nil {
   376  		return nil, errors.Trace(err)
   377  	}
   378  
   379  	return set, nil
   380  }
   381  
   382  // Validate checks for correct input formats in a TrafficRulesSet.
   383  func (set *TrafficRulesSet) Validate() error {
   384  
   385  	if set.MeekRateLimiterHistorySize < 0 ||
   386  		set.MeekRateLimiterThresholdSeconds < 0 ||
   387  		set.MeekRateLimiterGarbageCollectionTriggerCount < 0 ||
   388  		set.MeekRateLimiterReapHistoryFrequencySeconds < 0 {
   389  		return errors.TraceNew("MeekRateLimiter values must be >= 0")
   390  	}
   391  
   392  	if set.MeekRateLimiterHistorySize > 0 {
   393  		if set.MeekRateLimiterThresholdSeconds <= 0 {
   394  			return errors.TraceNew("MeekRateLimiterThresholdSeconds must be > 0")
   395  		}
   396  	}
   397  
   398  	validateTrafficRules := func(rules *TrafficRules) error {
   399  
   400  		if (rules.RateLimits.ReadUnthrottledBytes != nil && *rules.RateLimits.ReadUnthrottledBytes < 0) ||
   401  			(rules.RateLimits.ReadBytesPerSecond != nil && *rules.RateLimits.ReadBytesPerSecond < 0) ||
   402  			(rules.RateLimits.WriteUnthrottledBytes != nil && *rules.RateLimits.WriteUnthrottledBytes < 0) ||
   403  			(rules.RateLimits.WriteBytesPerSecond != nil && *rules.RateLimits.WriteBytesPerSecond < 0) ||
   404  			(rules.RateLimits.EstablishmentReadBytesPerSecond != nil && *rules.RateLimits.EstablishmentReadBytesPerSecond < 0) ||
   405  			(rules.RateLimits.EstablishmentWriteBytesPerSecond != nil && *rules.RateLimits.EstablishmentWriteBytesPerSecond < 0) ||
   406  			(rules.DialTCPPortForwardTimeoutMilliseconds != nil && *rules.DialTCPPortForwardTimeoutMilliseconds < 0) ||
   407  			(rules.IdleTCPPortForwardTimeoutMilliseconds != nil && *rules.IdleTCPPortForwardTimeoutMilliseconds < 0) ||
   408  			(rules.IdleUDPPortForwardTimeoutMilliseconds != nil && *rules.IdleUDPPortForwardTimeoutMilliseconds < 0) ||
   409  			(rules.MaxTCPDialingPortForwardCount != nil && *rules.MaxTCPDialingPortForwardCount < 0) ||
   410  			(rules.MaxTCPPortForwardCount != nil && *rules.MaxTCPPortForwardCount < 0) ||
   411  			(rules.MaxUDPPortForwardCount != nil && *rules.MaxUDPPortForwardCount < 0) {
   412  			return errors.TraceNew("TrafficRules values must be >= 0")
   413  		}
   414  
   415  		for _, subnet := range rules.AllowSubnets {
   416  			_, _, err := net.ParseCIDR(subnet)
   417  			if err != nil {
   418  				return errors.Tracef("invalid subnet: %s %s", subnet, err)
   419  			}
   420  		}
   421  
   422  		return nil
   423  	}
   424  
   425  	validateFilter := func(filter *TrafficRulesFilter) error {
   426  		for paramName := range filter.HandshakeParameters {
   427  			validParamName := false
   428  			for _, paramSpec := range handshakeRequestParams {
   429  				if paramSpec.name == paramName {
   430  					validParamName = true
   431  					break
   432  				}
   433  			}
   434  			if !validParamName {
   435  				return errors.Tracef("invalid parameter name: %s", paramName)
   436  			}
   437  		}
   438  		return nil
   439  	}
   440  
   441  	err := validateTrafficRules(&set.DefaultRules)
   442  	if err != nil {
   443  		return errors.Trace(err)
   444  	}
   445  
   446  	for _, filteredRule := range set.FilteredRules {
   447  
   448  		err := validateFilter(&filteredRule.Filter)
   449  		if err != nil {
   450  			return errors.Trace(err)
   451  		}
   452  
   453  		if filteredRule.ExceptFilter != nil {
   454  			err := validateFilter(filteredRule.ExceptFilter)
   455  			if err != nil {
   456  				return errors.Trace(err)
   457  			}
   458  		}
   459  
   460  		err = validateTrafficRules(&filteredRule.Rules)
   461  		if err != nil {
   462  			return errors.Trace(err)
   463  		}
   464  	}
   465  
   466  	return nil
   467  }
   468  
   469  const stringLookupThreshold = 5
   470  const intLookupThreshold = 10
   471  
   472  // initLookups creates map lookups for filters where the number of string/int
   473  // values to compare against exceeds a threshold where benchmarks show maps
   474  // are faster than looping through a string/int slice.
   475  func (set *TrafficRulesSet) initLookups() {
   476  
   477  	initTrafficRulesLookups := func(rules *TrafficRules) {
   478  
   479  		rules.AllowTCPPorts.OptimizeLookups()
   480  		rules.AllowUDPPorts.OptimizeLookups()
   481  		rules.DisallowTCPPorts.OptimizeLookups()
   482  		rules.DisallowUDPPorts.OptimizeLookups()
   483  
   484  	}
   485  
   486  	initTrafficRulesFilterLookups := func(filter *TrafficRulesFilter) {
   487  
   488  		if len(filter.Regions) >= stringLookupThreshold {
   489  			filter.regionLookup = make(map[string]bool)
   490  			for _, region := range filter.Regions {
   491  				filter.regionLookup[region] = true
   492  			}
   493  		}
   494  
   495  		if len(filter.ISPs) >= stringLookupThreshold {
   496  			filter.ispLookup = make(map[string]bool)
   497  			for _, ISP := range filter.ISPs {
   498  				filter.ispLookup[ISP] = true
   499  			}
   500  		}
   501  
   502  		if len(filter.ASNs) >= stringLookupThreshold {
   503  			filter.asnLookup = make(map[string]bool)
   504  			for _, ASN := range filter.ASNs {
   505  				filter.asnLookup[ASN] = true
   506  			}
   507  		}
   508  
   509  		if len(filter.Cities) >= stringLookupThreshold {
   510  			filter.cityLookup = make(map[string]bool)
   511  			for _, city := range filter.Cities {
   512  				filter.cityLookup[city] = true
   513  			}
   514  		}
   515  
   516  		if len(filter.ActiveAuthorizationIDs) >= stringLookupThreshold {
   517  			filter.activeAuthorizationIDLookup = make(map[string]bool)
   518  			for _, ID := range filter.ActiveAuthorizationIDs {
   519  				filter.activeAuthorizationIDLookup[ID] = true
   520  			}
   521  		}
   522  	}
   523  
   524  	initTrafficRulesLookups(&set.DefaultRules)
   525  
   526  	for i := range set.FilteredRules {
   527  		initTrafficRulesFilterLookups(&set.FilteredRules[i].Filter)
   528  		if set.FilteredRules[i].ExceptFilter != nil {
   529  			initTrafficRulesFilterLookups(set.FilteredRules[i].ExceptFilter)
   530  		}
   531  		initTrafficRulesLookups(&set.FilteredRules[i].Rules)
   532  	}
   533  
   534  	// TODO: add lookups for MeekRateLimiter?
   535  }
   536  
   537  // GetTrafficRules determines the traffic rules for a client based on its attributes.
   538  // For the return value TrafficRules, all pointer and slice fields are initialized,
   539  // so nil checks are not required. The caller must not modify the returned TrafficRules.
   540  func (set *TrafficRulesSet) GetTrafficRules(
   541  	isFirstTunnelInSession bool,
   542  	tunnelProtocol string,
   543  	geoIPData GeoIPData,
   544  	state handshakeState) TrafficRules {
   545  
   546  	set.ReloadableFile.RLock()
   547  	defer set.ReloadableFile.RUnlock()
   548  
   549  	// Start with a copy of the DefaultRules, and then select the first
   550  	// matching Rules from FilteredTrafficRules, taking only the explicitly
   551  	// specified fields from that Rules.
   552  	//
   553  	// Notes:
   554  	// - Scalar pointers are used in TrafficRules and RateLimits to distinguish between
   555  	//   omitted fields (in serialized JSON) and default values. For example, if a filtered
   556  	//   Rules specifies a field value of 0, this will override the default; but if the
   557  	//   serialized filtered rule omits the field, the default is to be retained.
   558  	// - We use shallow copies and slices and scalar pointers are shared between the
   559  	//   return value TrafficRules, so callers must treat the return value as immutable.
   560  	//   This also means that these slices and pointers can remain referenced in memory even
   561  	//   after a hot reload.
   562  
   563  	trafficRules := set.DefaultRules
   564  
   565  	// Populate defaults for omitted DefaultRules fields
   566  
   567  	if trafficRules.RateLimits.ReadUnthrottledBytes == nil {
   568  		trafficRules.RateLimits.ReadUnthrottledBytes = new(int64)
   569  	}
   570  
   571  	if trafficRules.RateLimits.ReadBytesPerSecond == nil {
   572  		trafficRules.RateLimits.ReadBytesPerSecond = new(int64)
   573  	}
   574  
   575  	if trafficRules.RateLimits.WriteUnthrottledBytes == nil {
   576  		trafficRules.RateLimits.WriteUnthrottledBytes = new(int64)
   577  	}
   578  
   579  	if trafficRules.RateLimits.WriteBytesPerSecond == nil {
   580  		trafficRules.RateLimits.WriteBytesPerSecond = new(int64)
   581  	}
   582  
   583  	if trafficRules.RateLimits.CloseAfterExhausted == nil {
   584  		trafficRules.RateLimits.CloseAfterExhausted = new(bool)
   585  	}
   586  
   587  	if trafficRules.RateLimits.EstablishmentReadBytesPerSecond == nil {
   588  		trafficRules.RateLimits.EstablishmentReadBytesPerSecond = new(int64)
   589  	}
   590  
   591  	if trafficRules.RateLimits.EstablishmentWriteBytesPerSecond == nil {
   592  		trafficRules.RateLimits.EstablishmentWriteBytesPerSecond = new(int64)
   593  	}
   594  
   595  	if trafficRules.RateLimits.UnthrottleFirstTunnelOnly == nil {
   596  		trafficRules.RateLimits.UnthrottleFirstTunnelOnly = new(bool)
   597  	}
   598  
   599  	intPtr := func(i int) *int {
   600  		return &i
   601  	}
   602  
   603  	if trafficRules.DialTCPPortForwardTimeoutMilliseconds == nil {
   604  		trafficRules.DialTCPPortForwardTimeoutMilliseconds =
   605  			intPtr(DEFAULT_DIAL_TCP_PORT_FORWARD_TIMEOUT_MILLISECONDS)
   606  	}
   607  
   608  	if trafficRules.IdleTCPPortForwardTimeoutMilliseconds == nil {
   609  		trafficRules.IdleTCPPortForwardTimeoutMilliseconds =
   610  			intPtr(DEFAULT_IDLE_TCP_PORT_FORWARD_TIMEOUT_MILLISECONDS)
   611  	}
   612  
   613  	if trafficRules.IdleUDPPortForwardTimeoutMilliseconds == nil {
   614  		trafficRules.IdleUDPPortForwardTimeoutMilliseconds =
   615  			intPtr(DEFAULT_IDLE_UDP_PORT_FORWARD_TIMEOUT_MILLISECONDS)
   616  	}
   617  
   618  	if trafficRules.MaxTCPDialingPortForwardCount == nil {
   619  		trafficRules.MaxTCPDialingPortForwardCount =
   620  			intPtr(DEFAULT_MAX_TCP_DIALING_PORT_FORWARD_COUNT)
   621  	}
   622  
   623  	if trafficRules.MaxTCPPortForwardCount == nil {
   624  		trafficRules.MaxTCPPortForwardCount =
   625  			intPtr(DEFAULT_MAX_TCP_PORT_FORWARD_COUNT)
   626  	}
   627  
   628  	if trafficRules.MaxUDPPortForwardCount == nil {
   629  		trafficRules.MaxUDPPortForwardCount =
   630  			intPtr(DEFAULT_MAX_UDP_PORT_FORWARD_COUNT)
   631  	}
   632  
   633  	if trafficRules.AllowSubnets == nil {
   634  		trafficRules.AllowSubnets = make([]string, 0)
   635  	}
   636  
   637  	if trafficRules.DisableDiscovery == nil {
   638  		trafficRules.DisableDiscovery = new(bool)
   639  	}
   640  
   641  	// matchFilter is used to check both Filter and any ExceptFilter
   642  
   643  	matchFilter := func(filter *TrafficRulesFilter) bool {
   644  
   645  		if len(filter.TunnelProtocols) > 0 {
   646  			if !common.Contains(filter.TunnelProtocols, tunnelProtocol) {
   647  				return false
   648  			}
   649  		}
   650  
   651  		if len(filter.Regions) > 0 {
   652  			if filter.regionLookup != nil {
   653  				if !filter.regionLookup[geoIPData.Country] {
   654  					return false
   655  				}
   656  			} else {
   657  				if !common.Contains(filter.Regions, geoIPData.Country) {
   658  					return false
   659  				}
   660  			}
   661  		}
   662  
   663  		if len(filter.ISPs) > 0 {
   664  			if filter.ispLookup != nil {
   665  				if !filter.ispLookup[geoIPData.ISP] {
   666  					return false
   667  				}
   668  			} else {
   669  				if !common.Contains(filter.ISPs, geoIPData.ISP) {
   670  					return false
   671  				}
   672  			}
   673  		}
   674  
   675  		if len(filter.ASNs) > 0 {
   676  			if filter.asnLookup != nil {
   677  				if !filter.asnLookup[geoIPData.ASN] {
   678  					return false
   679  				}
   680  			} else {
   681  				if !common.Contains(filter.ASNs, geoIPData.ASN) {
   682  					return false
   683  				}
   684  			}
   685  		}
   686  
   687  		if len(filter.Cities) > 0 {
   688  			if filter.cityLookup != nil {
   689  				if !filter.cityLookup[geoIPData.City] {
   690  					return false
   691  				}
   692  			} else {
   693  				if !common.Contains(filter.Cities, geoIPData.City) {
   694  					return false
   695  				}
   696  			}
   697  		}
   698  
   699  		if filter.APIProtocol != "" {
   700  			if !state.completed {
   701  				return false
   702  			}
   703  			if state.apiProtocol != filter.APIProtocol {
   704  				return false
   705  			}
   706  		}
   707  
   708  		if filter.HandshakeParameters != nil {
   709  			if !state.completed {
   710  				return false
   711  			}
   712  
   713  			for name, values := range filter.HandshakeParameters {
   714  				clientValue, err := getStringRequestParam(state.apiParams, name)
   715  				if err != nil || !common.ContainsWildcard(values, clientValue) {
   716  					return false
   717  				}
   718  			}
   719  		}
   720  
   721  		if filter.AuthorizationsRevoked {
   722  			if !state.completed {
   723  				return false
   724  			}
   725  
   726  			if !state.authorizationsRevoked {
   727  				return false
   728  			}
   729  
   730  		} else {
   731  			if len(filter.ActiveAuthorizationIDs) > 0 {
   732  				if !state.completed {
   733  					return false
   734  				}
   735  
   736  				if state.authorizationsRevoked {
   737  					return false
   738  				}
   739  
   740  				if filter.activeAuthorizationIDLookup != nil {
   741  					found := false
   742  					for _, ID := range state.activeAuthorizationIDs {
   743  						if filter.activeAuthorizationIDLookup[ID] {
   744  							found = true
   745  							break
   746  						}
   747  					}
   748  					if !found {
   749  						return false
   750  					}
   751  				} else {
   752  					if !common.ContainsAny(filter.ActiveAuthorizationIDs, state.activeAuthorizationIDs) {
   753  						return false
   754  					}
   755  				}
   756  
   757  			}
   758  			if len(filter.AuthorizedAccessTypes) > 0 {
   759  				if !state.completed {
   760  					return false
   761  				}
   762  
   763  				if state.authorizationsRevoked {
   764  					return false
   765  				}
   766  
   767  				if !common.ContainsAny(filter.AuthorizedAccessTypes, state.authorizedAccessTypes) {
   768  					return false
   769  				}
   770  			}
   771  		}
   772  
   773  		return true
   774  	}
   775  
   776  	// Match filtered rules
   777  	//
   778  	// TODO: faster lookup?
   779  
   780  	for _, filteredRules := range set.FilteredRules {
   781  
   782  		log.WithTraceFields(LogFields{"filter": filteredRules.Filter}).Debug("filter check")
   783  
   784  		match := matchFilter(&filteredRules.Filter)
   785  		if match && filteredRules.ExceptFilter != nil {
   786  			match = !matchFilter(filteredRules.ExceptFilter)
   787  		}
   788  		if !match {
   789  			continue
   790  		}
   791  
   792  		log.WithTraceFields(LogFields{"filter": filteredRules.Filter}).Debug("filter match")
   793  
   794  		// This is the first match. Override defaults using provided fields from selected rules, and return result.
   795  
   796  		if filteredRules.Rules.RateLimits.ReadUnthrottledBytes != nil {
   797  			trafficRules.RateLimits.ReadUnthrottledBytes = filteredRules.Rules.RateLimits.ReadUnthrottledBytes
   798  		}
   799  
   800  		if filteredRules.Rules.RateLimits.ReadBytesPerSecond != nil {
   801  			trafficRules.RateLimits.ReadBytesPerSecond = filteredRules.Rules.RateLimits.ReadBytesPerSecond
   802  		}
   803  
   804  		if filteredRules.Rules.RateLimits.WriteUnthrottledBytes != nil {
   805  			trafficRules.RateLimits.WriteUnthrottledBytes = filteredRules.Rules.RateLimits.WriteUnthrottledBytes
   806  		}
   807  
   808  		if filteredRules.Rules.RateLimits.WriteBytesPerSecond != nil {
   809  			trafficRules.RateLimits.WriteBytesPerSecond = filteredRules.Rules.RateLimits.WriteBytesPerSecond
   810  		}
   811  
   812  		if filteredRules.Rules.RateLimits.CloseAfterExhausted != nil {
   813  			trafficRules.RateLimits.CloseAfterExhausted = filteredRules.Rules.RateLimits.CloseAfterExhausted
   814  		}
   815  
   816  		if filteredRules.Rules.RateLimits.EstablishmentReadBytesPerSecond != nil {
   817  			trafficRules.RateLimits.EstablishmentReadBytesPerSecond = filteredRules.Rules.RateLimits.EstablishmentReadBytesPerSecond
   818  		}
   819  
   820  		if filteredRules.Rules.RateLimits.EstablishmentWriteBytesPerSecond != nil {
   821  			trafficRules.RateLimits.EstablishmentWriteBytesPerSecond = filteredRules.Rules.RateLimits.EstablishmentWriteBytesPerSecond
   822  		}
   823  
   824  		if filteredRules.Rules.RateLimits.UnthrottleFirstTunnelOnly != nil {
   825  			trafficRules.RateLimits.UnthrottleFirstTunnelOnly = filteredRules.Rules.RateLimits.UnthrottleFirstTunnelOnly
   826  		}
   827  
   828  		if filteredRules.Rules.DialTCPPortForwardTimeoutMilliseconds != nil {
   829  			trafficRules.DialTCPPortForwardTimeoutMilliseconds = filteredRules.Rules.DialTCPPortForwardTimeoutMilliseconds
   830  		}
   831  
   832  		if filteredRules.Rules.IdleTCPPortForwardTimeoutMilliseconds != nil {
   833  			trafficRules.IdleTCPPortForwardTimeoutMilliseconds = filteredRules.Rules.IdleTCPPortForwardTimeoutMilliseconds
   834  		}
   835  
   836  		if filteredRules.Rules.IdleUDPPortForwardTimeoutMilliseconds != nil {
   837  			trafficRules.IdleUDPPortForwardTimeoutMilliseconds = filteredRules.Rules.IdleUDPPortForwardTimeoutMilliseconds
   838  		}
   839  
   840  		if filteredRules.Rules.MaxTCPDialingPortForwardCount != nil {
   841  			trafficRules.MaxTCPDialingPortForwardCount = filteredRules.Rules.MaxTCPDialingPortForwardCount
   842  		}
   843  
   844  		if filteredRules.Rules.MaxTCPPortForwardCount != nil {
   845  			trafficRules.MaxTCPPortForwardCount = filteredRules.Rules.MaxTCPPortForwardCount
   846  		}
   847  
   848  		if filteredRules.Rules.MaxUDPPortForwardCount != nil {
   849  			trafficRules.MaxUDPPortForwardCount = filteredRules.Rules.MaxUDPPortForwardCount
   850  		}
   851  
   852  		if filteredRules.Rules.AllowTCPPorts != nil {
   853  			trafficRules.AllowTCPPorts = filteredRules.Rules.AllowTCPPorts
   854  		}
   855  
   856  		if filteredRules.Rules.AllowUDPPorts != nil {
   857  			trafficRules.AllowUDPPorts = filteredRules.Rules.AllowUDPPorts
   858  		}
   859  
   860  		if filteredRules.Rules.DisallowTCPPorts != nil {
   861  			trafficRules.DisallowTCPPorts = filteredRules.Rules.DisallowTCPPorts
   862  		}
   863  
   864  		if filteredRules.Rules.DisallowUDPPorts != nil {
   865  			trafficRules.DisallowUDPPorts = filteredRules.Rules.DisallowUDPPorts
   866  		}
   867  
   868  		if filteredRules.Rules.AllowSubnets != nil {
   869  			trafficRules.AllowSubnets = filteredRules.Rules.AllowSubnets
   870  		}
   871  
   872  		if filteredRules.Rules.DisableDiscovery != nil {
   873  			trafficRules.DisableDiscovery = filteredRules.Rules.DisableDiscovery
   874  		}
   875  
   876  		break
   877  	}
   878  
   879  	if *trafficRules.RateLimits.UnthrottleFirstTunnelOnly && !isFirstTunnelInSession {
   880  		trafficRules.RateLimits.ReadUnthrottledBytes = new(int64)
   881  		trafficRules.RateLimits.WriteUnthrottledBytes = new(int64)
   882  	}
   883  
   884  	log.WithTraceFields(LogFields{"trafficRules": trafficRules}).Debug("selected traffic rules")
   885  
   886  	return trafficRules
   887  }
   888  
   889  func (rules *TrafficRules) AllowTCPPort(remoteIP net.IP, port int) bool {
   890  
   891  	if rules.DisallowTCPPorts.Lookup(port) {
   892  		return false
   893  	}
   894  
   895  	if rules.AllowTCPPorts.IsEmpty() {
   896  		return true
   897  	}
   898  
   899  	if rules.AllowTCPPorts.Lookup(port) {
   900  		return true
   901  	}
   902  
   903  	return rules.allowSubnet(remoteIP)
   904  }
   905  
   906  func (rules *TrafficRules) AllowUDPPort(remoteIP net.IP, port int) bool {
   907  
   908  	if rules.DisallowUDPPorts.Lookup(port) {
   909  		return false
   910  	}
   911  
   912  	if rules.AllowUDPPorts.IsEmpty() {
   913  		return true
   914  	}
   915  
   916  	if rules.AllowUDPPorts.Lookup(port) {
   917  		return true
   918  	}
   919  
   920  	return rules.allowSubnet(remoteIP)
   921  }
   922  
   923  func (rules *TrafficRules) allowSubnet(remoteIP net.IP) bool {
   924  
   925  	for _, subnet := range rules.AllowSubnets {
   926  		// Note: ignoring error as config has been validated
   927  		_, network, _ := net.ParseCIDR(subnet)
   928  		if network.Contains(remoteIP) {
   929  			return true
   930  		}
   931  	}
   932  
   933  	return false
   934  }
   935  
   936  // GetMeekRateLimiterConfig gets a snapshot of the meek rate limiter
   937  // configuration values.
   938  func (set *TrafficRulesSet) GetMeekRateLimiterConfig() (
   939  	int, int, []string, []string, []string, []string, []string, int, int, int) {
   940  
   941  	set.ReloadableFile.RLock()
   942  	defer set.ReloadableFile.RUnlock()
   943  
   944  	GCTriggerCount := set.MeekRateLimiterGarbageCollectionTriggerCount
   945  	if GCTriggerCount <= 0 {
   946  		GCTriggerCount = DEFAULT_MEEK_RATE_LIMITER_GARBAGE_COLLECTOR_TRIGGER_COUNT
   947  	}
   948  
   949  	reapFrequencySeconds := set.MeekRateLimiterReapHistoryFrequencySeconds
   950  	if reapFrequencySeconds <= 0 {
   951  		reapFrequencySeconds = DEFAULT_MEEK_RATE_LIMITER_REAP_HISTORY_FREQUENCY_SECONDS
   952  
   953  	}
   954  
   955  	maxEntries := set.MeekRateLimiterMaxEntries
   956  	if maxEntries <= 0 {
   957  		maxEntries = DEFAULT_MEEK_RATE_LIMITER_MAX_ENTRIES
   958  
   959  	}
   960  
   961  	return set.MeekRateLimiterHistorySize,
   962  		set.MeekRateLimiterThresholdSeconds,
   963  		set.MeekRateLimiterTunnelProtocols,
   964  		set.MeekRateLimiterRegions,
   965  		set.MeekRateLimiterISPs,
   966  		set.MeekRateLimiterASNs,
   967  		set.MeekRateLimiterCities,
   968  		GCTriggerCount,
   969  		reapFrequencySeconds,
   970  		maxEntries
   971  }