Skip to content

Commit

Permalink
Merge pull request #703 from rod-hynes/multi-dest-bytes
Browse files Browse the repository at this point in the history
Add DestinationBytesMetricsASNs
  • Loading branch information
rod-hynes authored Nov 21, 2024
2 parents 50a143a + b5d8572 commit c2ffc7d
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 77 deletions.
4 changes: 3 additions & 1 deletion psiphon/common/parameters/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ const (
RestrictDirectProviderIDsClientProbability = "RestrictDirectProviderIDsClientProbability"
UpstreamProxyAllowAllServerEntrySources = "UpstreamProxyAllowAllServerEntrySources"
DestinationBytesMetricsASN = "DestinationBytesMetricsASN"
DestinationBytesMetricsASNs = "DestinationBytesMetricsASNs"
DNSResolverAttemptsPerServer = "DNSResolverAttemptsPerServer"
DNSResolverAttemptsPerPreferredServer = "DNSResolverAttemptsPerPreferredServer"
DNSResolverRequestTimeout = "DNSResolverRequestTimeout"
Expand Down Expand Up @@ -826,7 +827,8 @@ var defaultParameters = map[string]struct {

UpstreamProxyAllowAllServerEntrySources: {value: false},

DestinationBytesMetricsASN: {value: "", flags: serverSideOnly},
DestinationBytesMetricsASN: {value: "", flags: serverSideOnly},
DestinationBytesMetricsASNs: {value: []string{}, flags: serverSideOnly},

DNSResolverAttemptsPerServer: {value: 2, minimum: 1},
DNSResolverAttemptsPerPreferredServer: {value: 1, minimum: 1},
Expand Down
154 changes: 113 additions & 41 deletions psiphon/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
runServer(t,
&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,
})
}

Expand Down Expand Up @@ -646,34 +661,35 @@ func TestLegacyAPIEncoding(t *testing.T) {
}

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 (
Expand Down Expand Up @@ -776,7 +792,8 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
runConfig.applyPrefix ||
runConfig.forceFragmenting ||
runConfig.doBurstMonitor ||
runConfig.doDestinationBytes
runConfig.doDestinationBytes ||
runConfig.doLegacyDestinationBytes

// All servers require a tactics config with valid keys.
tacticsRequestPublicKey, tacticsRequestPrivateKey, tacticsRequestObfuscatedKey, err :=
Expand Down Expand Up @@ -912,6 +929,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
livenessTestSize,
runConfig.doBurstMonitor,
runConfig.doDestinationBytes,
runConfig.doLegacyDestinationBytes,
runConfig.applyPrefix,
runConfig.forceFragmenting,
"classic",
Expand Down Expand Up @@ -1181,6 +1199,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
livenessTestSize,
runConfig.doBurstMonitor,
runConfig.doDestinationBytes,
runConfig.doLegacyDestinationBytes,
runConfig.applyPrefix,
runConfig.forceFragmenting,
"consistent",
Expand Down Expand Up @@ -1623,7 +1642,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {

if runConfig.doChangeBytesConfig {

if !runConfig.doDestinationBytes {
if !runConfig.doDestinationBytes || !runConfig.doLegacyDestinationBytes {
t.Fatalf("invalid test configuration")
}

Expand All @@ -1649,6 +1668,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
livenessTestSize,
runConfig.doBurstMonitor,
false,
false,
runConfig.applyPrefix,
runConfig.forceFragmenting,
"consistent",
Expand Down Expand Up @@ -1796,6 +1816,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
expectQUICVersion = limitQUICVersions[0]
}
expectDestinationBytesFields := runConfig.doDestinationBytes && !runConfig.doChangeBytesConfig
expectLegacyDestinationBytesFields := runConfig.doLegacyDestinationBytes && !runConfig.doChangeBytesConfig
expectMeekHTTPVersion := ""
if protocol.TunnelProtocolUsesMeek(runConfig.tunnelProtocol) {
if protocol.TunnelProtocolUsesFrontedMeek(runConfig.tunnelProtocol) {
Expand Down Expand Up @@ -1829,6 +1850,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
expectUDPDataTransfer,
expectQUICVersion,
expectDestinationBytesFields,
expectLegacyDestinationBytesFields,
passthroughAddress,
expectMeekHTTPVersion,
inproxyTestConfig,
Expand Down Expand Up @@ -2086,6 +2108,7 @@ func checkExpectedServerTunnelLogFields(
expectUDPDataTransfer bool,
expectQUICVersion string,
expectDestinationBytesFields bool,
expectLegacyDestinationBytesFields bool,
expectPassthroughAddress *string,
expectMeekHTTPVersion string,
inproxyTestConfig *inproxyTestConfig,
Expand Down Expand Up @@ -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{
"dest_bytes_asn",
"dest_bytes_up_tcp",
Expand All @@ -2699,15 +2761,15 @@ func checkExpectedServerTunnelLogFields(
"dest_bytes_down_udp",
"dest_bytes",
} {
if expectDestinationBytesFields && fields[name] == nil {
if expectLegacyDestinationBytesFields && fields[name] == nil {
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)
}
}

if expectDestinationBytesFields {
if expectLegacyDestinationBytesFields {
name := "dest_bytes_asn"
if fields[name].(string) != testGeoIPASN {
return fmt.Errorf("unexpected field value %s: '%v'", name, fields[name])
Expand Down Expand Up @@ -3385,6 +3447,7 @@ func paveTacticsConfigFile(
livenessTestSize int,
doBurstMonitor bool,
doDestinationBytes bool,
doLegacyDestinationBytes bool,
applyOsshPrefix bool,
enableOsshPrefixFragmenting bool,
discoveryStategy string,
Expand All @@ -3406,6 +3469,7 @@ func paveTacticsConfigFile(
%s
%s
%s
%s
"LimitTunnelProtocols" : ["%s"],
"FragmentorLimitProtocols" : ["%s"],
"FragmentorProbability" : 1.0,
Expand Down Expand Up @@ -3490,6 +3554,13 @@ func paveTacticsConfigFile(
destinationBytesParameters := ""
if doDestinationBytes {
destinationBytesParameters = fmt.Sprintf(`
"DestinationBytesMetricsASNs" : ["%s"],
`, testGeoIPASN)
}

legacyDestinationBytesParameters := ""
if doLegacyDestinationBytes {
legacyDestinationBytesParameters = fmt.Sprintf(`
"DestinationBytesMetricsASN" : "%s",
`, testGeoIPASN)
}
Expand All @@ -3513,6 +3584,7 @@ func paveTacticsConfigFile(
tacticsRequestObfuscatedKey,
burstParameters,
destinationBytesParameters,
legacyDestinationBytesParameters,
osshPrefix,
inproxyParametersJSON,
tunnelProtocol,
Expand Down
Loading

0 comments on commit c2ffc7d

Please sign in to comment.