|
@@ -578,17 +578,32 @@ func TestBurstMonitorAndDestinationBytes(t *testing.T) {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func TestBurstMonitorAndLegacyDestinationBytes(t *testing.T) {
|
|
|
|
|
+ runServer(t,
|
|
|
|
|
+ &runServerConfig{
|
|
|
|
|
+ tunnelProtocol: "OSSH",
|
|
|
|
|
+ requireAuthorization: true,
|
|
|
|
|
+ doTunneledWebRequest: true,
|
|
|
|
|
+ doTunneledNTPRequest: true,
|
|
|
|
|
+ doDanglingTCPConn: true,
|
|
|
|
|
+ doBurstMonitor: true,
|
|
|
|
|
+ doLegacyDestinationBytes: true,
|
|
|
|
|
+ doLogHostProvider: true,
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func TestChangeBytesConfig(t *testing.T) {
|
|
func TestChangeBytesConfig(t *testing.T) {
|
|
|
runServer(t,
|
|
runServer(t,
|
|
|
&runServerConfig{
|
|
&runServerConfig{
|
|
|
- tunnelProtocol: "OSSH",
|
|
|
|
|
- requireAuthorization: true,
|
|
|
|
|
- doTunneledWebRequest: true,
|
|
|
|
|
- doTunneledNTPRequest: true,
|
|
|
|
|
- doDanglingTCPConn: true,
|
|
|
|
|
- doDestinationBytes: true,
|
|
|
|
|
- doChangeBytesConfig: true,
|
|
|
|
|
- doLogHostProvider: true,
|
|
|
|
|
|
|
+ tunnelProtocol: "OSSH",
|
|
|
|
|
+ requireAuthorization: true,
|
|
|
|
|
+ doTunneledWebRequest: true,
|
|
|
|
|
+ doTunneledNTPRequest: true,
|
|
|
|
|
+ doDanglingTCPConn: true,
|
|
|
|
|
+ doDestinationBytes: true,
|
|
|
|
|
+ doLegacyDestinationBytes: true,
|
|
|
|
|
+ doChangeBytesConfig: true,
|
|
|
|
|
+ doLogHostProvider: true,
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -646,34 +661,35 @@ func TestLegacyAPIEncoding(t *testing.T) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
type runServerConfig struct {
|
|
type runServerConfig struct {
|
|
|
- tunnelProtocol string
|
|
|
|
|
- clientTunnelProtocol string
|
|
|
|
|
- passthrough bool
|
|
|
|
|
- tlsProfile string
|
|
|
|
|
- doHotReload bool
|
|
|
|
|
- doDefaultSponsorID bool
|
|
|
|
|
- denyTrafficRules bool
|
|
|
|
|
- requireAuthorization bool
|
|
|
|
|
- omitAuthorization bool
|
|
|
|
|
- doTunneledWebRequest bool
|
|
|
|
|
- doTunneledNTPRequest bool
|
|
|
|
|
- applyPrefix bool
|
|
|
|
|
- forceFragmenting bool
|
|
|
|
|
- forceLivenessTest bool
|
|
|
|
|
- doPruneServerEntries bool
|
|
|
|
|
- doDanglingTCPConn bool
|
|
|
|
|
- doPacketManipulation bool
|
|
|
|
|
- doBurstMonitor bool
|
|
|
|
|
- doSplitTunnel bool
|
|
|
|
|
- limitQUICVersions bool
|
|
|
|
|
- doDestinationBytes bool
|
|
|
|
|
- doChangeBytesConfig bool
|
|
|
|
|
- doLogHostProvider bool
|
|
|
|
|
- inspectFlows bool
|
|
|
|
|
- doSteeringIP bool
|
|
|
|
|
- doTargetBrokerSpecs bool
|
|
|
|
|
- useLegacyAPIEncoding bool
|
|
|
|
|
- doPersonalPairing bool
|
|
|
|
|
|
|
+ tunnelProtocol string
|
|
|
|
|
+ clientTunnelProtocol string
|
|
|
|
|
+ passthrough bool
|
|
|
|
|
+ tlsProfile string
|
|
|
|
|
+ doHotReload bool
|
|
|
|
|
+ doDefaultSponsorID bool
|
|
|
|
|
+ denyTrafficRules bool
|
|
|
|
|
+ requireAuthorization bool
|
|
|
|
|
+ omitAuthorization bool
|
|
|
|
|
+ doTunneledWebRequest bool
|
|
|
|
|
+ doTunneledNTPRequest bool
|
|
|
|
|
+ applyPrefix bool
|
|
|
|
|
+ forceFragmenting bool
|
|
|
|
|
+ forceLivenessTest bool
|
|
|
|
|
+ doPruneServerEntries bool
|
|
|
|
|
+ doDanglingTCPConn bool
|
|
|
|
|
+ doPacketManipulation bool
|
|
|
|
|
+ doBurstMonitor bool
|
|
|
|
|
+ doSplitTunnel bool
|
|
|
|
|
+ limitQUICVersions bool
|
|
|
|
|
+ doDestinationBytes bool
|
|
|
|
|
+ doLegacyDestinationBytes bool
|
|
|
|
|
+ doChangeBytesConfig bool
|
|
|
|
|
+ doLogHostProvider bool
|
|
|
|
|
+ inspectFlows bool
|
|
|
|
|
+ doSteeringIP bool
|
|
|
|
|
+ doTargetBrokerSpecs bool
|
|
|
|
|
+ useLegacyAPIEncoding bool
|
|
|
|
|
+ doPersonalPairing bool
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
var (
|
|
@@ -776,7 +792,8 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
|
|
|
runConfig.applyPrefix ||
|
|
runConfig.applyPrefix ||
|
|
|
runConfig.forceFragmenting ||
|
|
runConfig.forceFragmenting ||
|
|
|
runConfig.doBurstMonitor ||
|
|
runConfig.doBurstMonitor ||
|
|
|
- runConfig.doDestinationBytes
|
|
|
|
|
|
|
+ runConfig.doDestinationBytes ||
|
|
|
|
|
+ runConfig.doLegacyDestinationBytes
|
|
|
|
|
|
|
|
// All servers require a tactics config with valid keys.
|
|
// All servers require a tactics config with valid keys.
|
|
|
tacticsRequestPublicKey, tacticsRequestPrivateKey, tacticsRequestObfuscatedKey, err :=
|
|
tacticsRequestPublicKey, tacticsRequestPrivateKey, tacticsRequestObfuscatedKey, err :=
|
|
@@ -912,6 +929,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
|
|
|
livenessTestSize,
|
|
livenessTestSize,
|
|
|
runConfig.doBurstMonitor,
|
|
runConfig.doBurstMonitor,
|
|
|
runConfig.doDestinationBytes,
|
|
runConfig.doDestinationBytes,
|
|
|
|
|
+ runConfig.doLegacyDestinationBytes,
|
|
|
runConfig.applyPrefix,
|
|
runConfig.applyPrefix,
|
|
|
runConfig.forceFragmenting,
|
|
runConfig.forceFragmenting,
|
|
|
"classic",
|
|
"classic",
|
|
@@ -1181,6 +1199,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
|
|
|
livenessTestSize,
|
|
livenessTestSize,
|
|
|
runConfig.doBurstMonitor,
|
|
runConfig.doBurstMonitor,
|
|
|
runConfig.doDestinationBytes,
|
|
runConfig.doDestinationBytes,
|
|
|
|
|
+ runConfig.doLegacyDestinationBytes,
|
|
|
runConfig.applyPrefix,
|
|
runConfig.applyPrefix,
|
|
|
runConfig.forceFragmenting,
|
|
runConfig.forceFragmenting,
|
|
|
"consistent",
|
|
"consistent",
|
|
@@ -1623,7 +1642,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
|
|
|
|
|
|
|
|
if runConfig.doChangeBytesConfig {
|
|
if runConfig.doChangeBytesConfig {
|
|
|
|
|
|
|
|
- if !runConfig.doDestinationBytes {
|
|
|
|
|
|
|
+ if !runConfig.doDestinationBytes || !runConfig.doLegacyDestinationBytes {
|
|
|
t.Fatalf("invalid test configuration")
|
|
t.Fatalf("invalid test configuration")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1649,6 +1668,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
|
|
|
livenessTestSize,
|
|
livenessTestSize,
|
|
|
runConfig.doBurstMonitor,
|
|
runConfig.doBurstMonitor,
|
|
|
false,
|
|
false,
|
|
|
|
|
+ false,
|
|
|
runConfig.applyPrefix,
|
|
runConfig.applyPrefix,
|
|
|
runConfig.forceFragmenting,
|
|
runConfig.forceFragmenting,
|
|
|
"consistent",
|
|
"consistent",
|
|
@@ -1796,6 +1816,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
|
|
|
expectQUICVersion = limitQUICVersions[0]
|
|
expectQUICVersion = limitQUICVersions[0]
|
|
|
}
|
|
}
|
|
|
expectDestinationBytesFields := runConfig.doDestinationBytes && !runConfig.doChangeBytesConfig
|
|
expectDestinationBytesFields := runConfig.doDestinationBytes && !runConfig.doChangeBytesConfig
|
|
|
|
|
+ expectLegacyDestinationBytesFields := runConfig.doLegacyDestinationBytes && !runConfig.doChangeBytesConfig
|
|
|
expectMeekHTTPVersion := ""
|
|
expectMeekHTTPVersion := ""
|
|
|
if protocol.TunnelProtocolUsesMeek(runConfig.tunnelProtocol) {
|
|
if protocol.TunnelProtocolUsesMeek(runConfig.tunnelProtocol) {
|
|
|
if protocol.TunnelProtocolUsesFrontedMeek(runConfig.tunnelProtocol) {
|
|
if protocol.TunnelProtocolUsesFrontedMeek(runConfig.tunnelProtocol) {
|
|
@@ -1829,6 +1850,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
|
|
|
expectUDPDataTransfer,
|
|
expectUDPDataTransfer,
|
|
|
expectQUICVersion,
|
|
expectQUICVersion,
|
|
|
expectDestinationBytesFields,
|
|
expectDestinationBytesFields,
|
|
|
|
|
+ expectLegacyDestinationBytesFields,
|
|
|
passthroughAddress,
|
|
passthroughAddress,
|
|
|
expectMeekHTTPVersion,
|
|
expectMeekHTTPVersion,
|
|
|
inproxyTestConfig,
|
|
inproxyTestConfig,
|
|
@@ -2086,6 +2108,7 @@ func checkExpectedServerTunnelLogFields(
|
|
|
expectUDPDataTransfer bool,
|
|
expectUDPDataTransfer bool,
|
|
|
expectQUICVersion string,
|
|
expectQUICVersion string,
|
|
|
expectDestinationBytesFields bool,
|
|
expectDestinationBytesFields bool,
|
|
|
|
|
+ expectLegacyDestinationBytesFields bool,
|
|
|
expectPassthroughAddress *string,
|
|
expectPassthroughAddress *string,
|
|
|
expectMeekHTTPVersion string,
|
|
expectMeekHTTPVersion string,
|
|
|
inproxyTestConfig *inproxyTestConfig,
|
|
inproxyTestConfig *inproxyTestConfig,
|
|
@@ -2691,6 +2714,45 @@ func checkExpectedServerTunnelLogFields(
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ for _, name := range []string{
|
|
|
|
|
+ "asn_dest_bytes",
|
|
|
|
|
+ "asn_dest_bytes_up_tcp",
|
|
|
|
|
+ "asn_dest_bytes_down_tcp",
|
|
|
|
|
+ "asn_dest_bytes_up_udp",
|
|
|
|
|
+ "asn_dest_bytes_down_udp",
|
|
|
|
|
+ } {
|
|
|
|
|
+ if expectDestinationBytesFields && fields[name] == nil {
|
|
|
|
|
+ return fmt.Errorf("missing expected field '%s'", name)
|
|
|
|
|
+
|
|
|
|
|
+ } else if !expectDestinationBytesFields && fields[name] != nil {
|
|
|
|
|
+ return fmt.Errorf("unexpected field '%s'", name)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if expectDestinationBytesFields {
|
|
|
|
|
+ for _, pair := range [][]string{
|
|
|
|
|
+ {"asn_dest_bytes", "bytes"},
|
|
|
|
|
+ {"asn_dest_bytes_up_tcp", "bytes_up_tcp"},
|
|
|
|
|
+ {"asn_dest_bytes_down_tcp", "bytes_down_tcp"},
|
|
|
|
|
+ {"asn_dest_bytes_up_udp", "bytes_up_udp"},
|
|
|
|
|
+ {"asn_dest_bytes_down_udp", "bytes_down_udp"},
|
|
|
|
|
+ } {
|
|
|
|
|
+ if _, ok := fields[pair[0]].(map[string]any)[testGeoIPASN].(float64); !ok {
|
|
|
|
|
+ return fmt.Errorf("missing field entry %s: '%v'", pair[0], testGeoIPASN)
|
|
|
|
|
+ }
|
|
|
|
|
+ value0 := int64(fields[pair[0]].(map[string]any)[testGeoIPASN].(float64))
|
|
|
|
|
+ value1 := int64(fields[pair[1]].(float64))
|
|
|
|
|
+ ok := value0 == value1
|
|
|
|
|
+ if pair[0] == "asn_dest_bytes_up_udp" || pair[0] == "asn_dest_bytes_down_udp" || pair[0] == "asn_dest_bytes" {
|
|
|
|
|
+ // DNS requests are excluded from destination bytes counting
|
|
|
|
|
+ ok = value0 > 0 && value0 < value1
|
|
|
|
|
+ }
|
|
|
|
|
+ if !ok {
|
|
|
|
|
+ return fmt.Errorf("unexpected field value %s: %v != %v", pair[0], fields[pair[0]], fields[pair[1]])
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
for _, name := range []string{
|
|
for _, name := range []string{
|
|
|
"dest_bytes_asn",
|
|
"dest_bytes_asn",
|
|
|
"dest_bytes_up_tcp",
|
|
"dest_bytes_up_tcp",
|
|
@@ -2699,15 +2761,15 @@ func checkExpectedServerTunnelLogFields(
|
|
|
"dest_bytes_down_udp",
|
|
"dest_bytes_down_udp",
|
|
|
"dest_bytes",
|
|
"dest_bytes",
|
|
|
} {
|
|
} {
|
|
|
- if expectDestinationBytesFields && fields[name] == nil {
|
|
|
|
|
|
|
+ if expectLegacyDestinationBytesFields && fields[name] == nil {
|
|
|
return fmt.Errorf("missing expected field '%s'", name)
|
|
return fmt.Errorf("missing expected field '%s'", name)
|
|
|
|
|
|
|
|
- } else if !expectDestinationBytesFields && fields[name] != nil {
|
|
|
|
|
|
|
+ } else if !expectLegacyDestinationBytesFields && fields[name] != nil {
|
|
|
return fmt.Errorf("unexpected field '%s'", name)
|
|
return fmt.Errorf("unexpected field '%s'", name)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if expectDestinationBytesFields {
|
|
|
|
|
|
|
+ if expectLegacyDestinationBytesFields {
|
|
|
name := "dest_bytes_asn"
|
|
name := "dest_bytes_asn"
|
|
|
if fields[name].(string) != testGeoIPASN {
|
|
if fields[name].(string) != testGeoIPASN {
|
|
|
return fmt.Errorf("unexpected field value %s: '%v'", name, fields[name])
|
|
return fmt.Errorf("unexpected field value %s: '%v'", name, fields[name])
|
|
@@ -3385,6 +3447,7 @@ func paveTacticsConfigFile(
|
|
|
livenessTestSize int,
|
|
livenessTestSize int,
|
|
|
doBurstMonitor bool,
|
|
doBurstMonitor bool,
|
|
|
doDestinationBytes bool,
|
|
doDestinationBytes bool,
|
|
|
|
|
+ doLegacyDestinationBytes bool,
|
|
|
applyOsshPrefix bool,
|
|
applyOsshPrefix bool,
|
|
|
enableOsshPrefixFragmenting bool,
|
|
enableOsshPrefixFragmenting bool,
|
|
|
discoveryStategy string,
|
|
discoveryStategy string,
|
|
@@ -3406,6 +3469,7 @@ func paveTacticsConfigFile(
|
|
|
%s
|
|
%s
|
|
|
%s
|
|
%s
|
|
|
%s
|
|
%s
|
|
|
|
|
+ %s
|
|
|
"LimitTunnelProtocols" : ["%s"],
|
|
"LimitTunnelProtocols" : ["%s"],
|
|
|
"FragmentorLimitProtocols" : ["%s"],
|
|
"FragmentorLimitProtocols" : ["%s"],
|
|
|
"FragmentorProbability" : 1.0,
|
|
"FragmentorProbability" : 1.0,
|
|
@@ -3490,6 +3554,13 @@ func paveTacticsConfigFile(
|
|
|
destinationBytesParameters := ""
|
|
destinationBytesParameters := ""
|
|
|
if doDestinationBytes {
|
|
if doDestinationBytes {
|
|
|
destinationBytesParameters = fmt.Sprintf(`
|
|
destinationBytesParameters = fmt.Sprintf(`
|
|
|
|
|
+ "DestinationBytesMetricsASNs" : ["%s"],
|
|
|
|
|
+ `, testGeoIPASN)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ legacyDestinationBytesParameters := ""
|
|
|
|
|
+ if doLegacyDestinationBytes {
|
|
|
|
|
+ legacyDestinationBytesParameters = fmt.Sprintf(`
|
|
|
"DestinationBytesMetricsASN" : "%s",
|
|
"DestinationBytesMetricsASN" : "%s",
|
|
|
`, testGeoIPASN)
|
|
`, testGeoIPASN)
|
|
|
}
|
|
}
|
|
@@ -3513,6 +3584,7 @@ func paveTacticsConfigFile(
|
|
|
tacticsRequestObfuscatedKey,
|
|
tacticsRequestObfuscatedKey,
|
|
|
burstParameters,
|
|
burstParameters,
|
|
|
destinationBytesParameters,
|
|
destinationBytesParameters,
|
|
|
|
|
+ legacyDestinationBytesParameters,
|
|
|
osshPrefix,
|
|
osshPrefix,
|
|
|
inproxyParametersJSON,
|
|
inproxyParametersJSON,
|
|
|
tunnelProtocol,
|
|
tunnelProtocol,
|