From f14f5c78a11ae72a1c5d8a167719ad79f15b473d Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Fri, 14 Jul 2023 01:53:57 +0200 Subject: [PATCH 1/2] feat: implement riseupvpn using the DSL Part of https://github.com/ooni/probe/issues/2502 --- pkg/experiment/fbmessenger/measurer.go | 2 +- pkg/experiment/riseupvpn/riseupvpn.go | 101 ++ pkg/ooniprobe/runner/nettest.go | 1 + pkg/ooniprobe/runner/riseupvpn.go | 73 + pkg/x/cmd/riseupvpn/apifetch.go | 62 + pkg/x/cmd/riseupvpn/apimodel.go | 63 + pkg/x/cmd/riseupvpn/dslrules.go | 111 ++ pkg/x/cmd/riseupvpn/main.go | 120 ++ testdata/riseupvpn.jsonc | 2267 ++++++++++++++++++++++++ 9 files changed, 2799 insertions(+), 1 deletion(-) create mode 100644 pkg/experiment/riseupvpn/riseupvpn.go create mode 100644 pkg/ooniprobe/runner/riseupvpn.go create mode 100644 pkg/x/cmd/riseupvpn/apifetch.go create mode 100644 pkg/x/cmd/riseupvpn/apimodel.go create mode 100644 pkg/x/cmd/riseupvpn/dslrules.go create mode 100644 pkg/x/cmd/riseupvpn/main.go create mode 100644 testdata/riseupvpn.jsonc diff --git a/pkg/experiment/fbmessenger/measurer.go b/pkg/experiment/fbmessenger/measurer.go index 361f12e..7907272 100644 --- a/pkg/experiment/fbmessenger/measurer.go +++ b/pkg/experiment/fbmessenger/measurer.go @@ -62,7 +62,7 @@ func (m *Measurer) Run(ctx context.Context, args *model.ExperimentArgs) error { args.Session.Logger(), &dsl.NullMetrics{}, args.Measurement.MeasurementStartTimeSaved) defer rtx.Close() - // evaluate the function and handle exceptions + // evaluate the pipeline and handle exceptions argument0 := dsl.NewValue(&dsl.Void{}) if err := dsl.Try(pipeline.Run(ctx, rtx, argument0.AsGeneric())); err != nil { return err diff --git a/pkg/experiment/riseupvpn/riseupvpn.go b/pkg/experiment/riseupvpn/riseupvpn.go new file mode 100644 index 0000000..acf0694 --- /dev/null +++ b/pkg/experiment/riseupvpn/riseupvpn.go @@ -0,0 +1,101 @@ +// Package riseupvpn implements the riseupvpn experiment. +package riseupvpn + +import ( + "context" + "encoding/json" + + "github.com/ooni/2023-05-richer-input/pkg/dsl" + "github.com/ooni/probe-engine/pkg/model" +) + +// NewMeasurer returns a new [Measurer] instance. +func NewMeasurer(rawOptions json.RawMessage) *Measurer { + return &Measurer{rawOptions} +} + +// Measurer is the riseupvpn measurer. +type Measurer struct { + // RawOptions contains the raw options for this experiment. + RawOptions json.RawMessage +} + +var _ model.ExperimentMeasurer = &Measurer{} + +// ExperimentName implements model.ExperimentMeasurer +func (m *Measurer) ExperimentName() string { + return "riseupvpn" +} + +// ExperimentVersion implements model.ExperimentMeasurer +func (m *Measurer) ExperimentVersion() string { + // TODO(bassosimone): the real experiment is at version 0.2.0 and + // we will _probably_ be fine by saying we're at 0.4.0 since the + // https://github.com/ooni/probe-cli/pull/1125 PR uses 0.3.0. + return "0.4.0" +} + +// TestKeys contains the experiment test keys. +type TestKeys struct { + *dsl.Observations +} + +// Run implements model.ExperimentMeasurer +func (m *Measurer) Run(ctx context.Context, args *model.ExperimentArgs) error { + // parse the targets + var astRoot dsl.LoadableASTNode + if err := json.Unmarshal(m.RawOptions, &astRoot); err != nil { + return err + } + + // create an AST loader + loader := dsl.NewASTLoader() + + // create the testkeys + tk := &TestKeys{} + + // load and make the AST runnable + pipeline, err := loader.Load(&astRoot) + if err != nil { + return err + } + + // TODO(bassosimone): both fbmessenger and riseupvpn lack + // + // 1. an explicit mechanism to report the bytes sent and received, but the + // implicit context-based mechanism probably works; + // + // 2. a DSL-based mechanism to increment the test progress percentage. + + // create the DSL runtime + rtx := dsl.NewMeasurexliteRuntime( + args.Session.Logger(), &dsl.NullMetrics{}, args.Measurement.MeasurementStartTimeSaved) + defer rtx.Close() + + // evaluate the pipeline and handle exceptions + argument0 := dsl.NewValue(&dsl.Void{}) + if err := dsl.Try(pipeline.Run(ctx, rtx, argument0.AsGeneric())); err != nil { + return err + } + + // obtain the observations + tk.Observations = dsl.ReduceObservations(rtx.ExtractObservations()...) + + // save the testkeys + args.Measurement.TestKeys = tk + return nil +} + +// SummaryKeys contains summary keys for this experiment. +// +// Note that this structure is part of the ABI contract with ooniprobe +// therefore we should be careful when changing it. +type SummaryKeys struct { + IsAnomaly bool `json:"-"` +} + +// GetSummaryKeys implements model.ExperimentMeasurer +func (m *Measurer) GetSummaryKeys(*model.Measurement) (any, error) { + sk := SummaryKeys{IsAnomaly: false} + return sk, nil +} diff --git a/pkg/ooniprobe/runner/nettest.go b/pkg/ooniprobe/runner/nettest.go index fb35cf1..469f804 100644 --- a/pkg/ooniprobe/runner/nettest.go +++ b/pkg/ooniprobe/runner/nettest.go @@ -26,6 +26,7 @@ type nettestFactory = func(args *modelx.InterpreterNettestRunArguments, // nettestRegistry maps nettests to their constructors. var nettestRegistry = map[string]nettestFactory{ "facebook_messenger": fbmessengerNew, + "riseupvpn": riseupvpnNew, "signal": signalNew, "telegram": telegramNew, "urlgetter": urlgetterNew, diff --git a/pkg/ooniprobe/runner/riseupvpn.go b/pkg/ooniprobe/runner/riseupvpn.go new file mode 100644 index 0000000..b3aa514 --- /dev/null +++ b/pkg/ooniprobe/runner/riseupvpn.go @@ -0,0 +1,73 @@ +package runner + +// +// riseupvpn.go implements the riseupvpn nettest +// + +import ( + "context" + "time" + + riseupvpnnew "github.com/ooni/2023-05-richer-input/pkg/experiment/riseupvpn" + "github.com/ooni/2023-05-richer-input/pkg/modelx" + "github.com/ooni/probe-engine/pkg/experiment/riseupvpn" + "github.com/ooni/probe-engine/pkg/model" +) + +// riseupvpnNettest is the riseupvpn nettest. +type riseupvpnNettest struct { + args *modelx.InterpreterNettestRunArguments + config *modelx.InterpreterConfig + ix *Interpreter +} + +var _ nettest = &riseupvpnNettest{} + +// riseupvpnNew constructs a new riseupvpn instance. +func riseupvpnNew(args *modelx.InterpreterNettestRunArguments, + config *modelx.InterpreterConfig, ix *Interpreter) (nettest, error) { + // fill the nettest struct + nettest := &riseupvpnNettest{ + args: args, + config: config, + ix: ix, + } + + // return to the caller + return nettest, nil +} + +// Run implements nettest +func (nt *riseupvpnNettest) Run(ctx context.Context) error { + // make sure the location didn't change + if err := nt.ix.location.Refresh(); err != nil { + return err + } + + // save the start time + t0 := time.Now() + + // create a new experiment instance + var exp model.ExperimentMeasurer + if nt.args.ExperimentalFlags["dsl"] { + exp = riseupvpnnew.NewMeasurer(nt.args.Targets) + } else { + exp = riseupvpn.NewExperimentMeasurer(riseupvpn.Config{}) + } + + // run with the given experiment and input + err := runExperiment( + ctx, + nt.args.Annotations, + newProgressEmitterNettest(nt.ix.logger, nt.ix.view), + exp, + "", // input + nt.ix, + nt.args.ReportID, + t0, + nt.config.TestHelpers, + ) + + // handle an immediate error such as a context error + return err +} diff --git a/pkg/x/cmd/riseupvpn/apifetch.go b/pkg/x/cmd/riseupvpn/apifetch.go new file mode 100644 index 0000000..90b3458 --- /dev/null +++ b/pkg/x/cmd/riseupvpn/apifetch.go @@ -0,0 +1,62 @@ +package main + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/json" + "net/http" + + "github.com/apex/log" + "github.com/ooni/probe-engine/pkg/netxlite" + "github.com/ooni/probe-engine/pkg/runtimex" +) + +// apiMustFetchCA fetches, validates and returns the CA or PANICS. +func apiMustFetchCA() string { + log.Info("- fetching the CA") + + resp := runtimex.Try1(http.Get("https://black.riseup.net/ca.crt")) + runtimex.Assert(resp.StatusCode == 200, "unexpected HTTP response status") + defer resp.Body.Close() + + log.Infof("HTTP response: %+v", resp) + + body := string(runtimex.Try1(netxlite.ReadAllContext(context.Background(), resp.Body))) + log.Infof("fetched CA:\n%s\n", string(body)) + return body +} + +// apiMustFetchEIPService fetches and parses the [*apiEIPService] or PANICS. +func apiMustFetchEIPService(caCert string) *apiEIPService { + log.Info("- fetching eip-service.json") + + // create and fill a certificate pool + pool := x509.NewCertPool() + runtimex.Assert(pool.AppendCertsFromPEM([]byte(caCert)), "AppendCertsFromPEM failed") + + // create a client using a transport using the pool + client := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: pool, + }, + }, + } + + // perform the HTTP round trip + resp := runtimex.Try1(client.Get("https://api.black.riseup.net/3/config/eip-service.json")) + runtimex.Assert(resp.StatusCode == 200, "unexpected HTTP response status") + defer resp.Body.Close() + + log.Infof("HTTP response: %+v", resp) + + // read the whole body + body := runtimex.Try1(netxlite.ReadAllContext(context.Background(), resp.Body)) + log.Infof("fetched eip-service.json:\n%s\n", string(body)) + + // parse the response body + var eipService apiEIPService + runtimex.Try0(json.Unmarshal(body, &eipService)) + return &eipService +} diff --git a/pkg/x/cmd/riseupvpn/apimodel.go b/pkg/x/cmd/riseupvpn/apimodel.go new file mode 100644 index 0000000..9f02f9c --- /dev/null +++ b/pkg/x/cmd/riseupvpn/apimodel.go @@ -0,0 +1,63 @@ +package main + +// +// Riseupvpn (and LEAP) API data model +// +// Code adapted from https://github.com/ooni/probe-cli/pull/1125, which was +// originally authored by https://github.com/cyBerta. +// + +import "github.com/ooni/probe-engine/pkg/runtimex" + +// apiEIPService is the main JSON object returned by https://api.black.riseup.net/3/config/eip-service.json. +type apiEIPService struct { + Gateways []apiGatewayV3 +} + +// apiGatewayV3 describes a riseupvpn gateway. +type apiGatewayV3 struct { + Capabilities apiCapabilities + Host string + IPAddress string `json:"ip_address"` + Location string `json:"location"` +} + +// apiCapabilities is a list of transports a gateway supports. +type apiCapabilities struct { + Transport []apiTransportV3 +} + +// apiTransportV3 describes a transport. +type apiTransportV3 struct { + Type string + Protocols []string + Ports []string + Options map[string]string +} + +// supportsTCP returns whether the transport supports TCP. +func (txp *apiTransportV3) supportsTCP() bool { + return txp.supportsTransportProtocol("tcp") +} + +// supportsTransportProtocol returns whether the transport uses the given +// transport protocol, which is one of "tcp" and "udp". +func (txp *apiTransportV3) supportsTransportProtocol(tp string) bool { + runtimex.Assert(tp == "tcp" || tp == "udp", "invalid transport protocol") + for _, protocol := range txp.Protocols { + if tp == protocol { + return true + } + } + return false +} + +// typeIsOneOf returns whether the transport type is one of the given types. +func (txp *apiTransportV3) typeIsOneOf(types ...string) bool { + for _, t := range types { + if txp.Type == t { + return true + } + } + return false +} diff --git a/pkg/x/cmd/riseupvpn/dslrules.go b/pkg/x/cmd/riseupvpn/dslrules.go new file mode 100644 index 0000000..05f1e20 --- /dev/null +++ b/pkg/x/cmd/riseupvpn/dslrules.go @@ -0,0 +1,111 @@ +package main + +// +// DSL rules +// +// Basic building blocks to create the DSL. +// + +import ( + "net" + + "github.com/ooni/2023-05-richer-input/pkg/dsl" +) + +// dslRuleFetchCA returns the DSL stage to fetch https://black.riseup.net/ca.crt. +func dslRuleFetchCA() dsl.Stage[*dsl.Void, *dsl.Void] { + return dsl.Compose4( + dsl.DomainName("black.riseup.net"), + dsl.DNSLookupGetaddrinfo(), + dsl.MakeEndpointsForPort(443), + dsl.NewEndpointPipeline( + dsl.Compose5( + dsl.TCPConnect(), + dsl.TLSHandshake(), + dsl.HTTPConnectionTLS(), + dsl.HTTPTransaction(dsl.HTTPTransactionOptionURLPath("/ca.crt")), + dsl.Discard[*dsl.HTTPResponse](), + ), + ), + ) +} + +// dslRuleFetchProviderURL returns the DSL stage to fetch https://riseup.net/provider.json. +func dslRuleFetchProviderURL() dsl.Stage[*dsl.Void, *dsl.Void] { + return dsl.Compose4( + dsl.DomainName("riseup.net"), + dsl.DNSLookupGetaddrinfo(), + dsl.MakeEndpointsForPort(443), + dsl.NewEndpointPipeline( + dsl.Compose5( + dsl.TCPConnect(), + dsl.TLSHandshake(), + dsl.HTTPConnectionTLS(), + dsl.HTTPTransaction(dsl.HTTPTransactionOptionURLPath("/provider.json")), + dsl.Discard[*dsl.HTTPResponse](), + ), + ), + ) +} + +// dslRuleFetchEIPServiceURL returns the DSL stage to fetch https://api.black.riseup.net/3/config/eip-service.json. +// +// Arguments: +// +// - rootCA contains the rootCA to use in PEM format. +func dslRuleFetchEIPServiceURL(rootCA string) dsl.Stage[*dsl.Void, *dsl.Void] { + return dsl.Compose4( + dsl.DomainName("api.black.riseup.net"), + dsl.DNSLookupGetaddrinfo(), + dsl.MakeEndpointsForPort(443), + dsl.NewEndpointPipeline( + dsl.Compose5( + dsl.TCPConnect(), + dsl.TLSHandshake(dsl.TLSHandshakeOptionX509Certs(rootCA)), + dsl.HTTPConnectionTLS(), + dsl.HTTPTransaction(dsl.HTTPTransactionOptionURLPath("/3/config/eip-service.json")), + dsl.Discard[*dsl.HTTPResponse](), + ), + ), + ) +} + +// dslRuleFetchGeoServiceURL returns the DSL stage to fetch https://api.black.riseup.net:9001/json. +// +// Arguments: +// +// - rootCA contains the rootCA to use in PEM format. +func dslRuleFetchGeoServiceURL(rootCA string) dsl.Stage[*dsl.Void, *dsl.Void] { + return dsl.Compose4( + dsl.DomainName("api.black.riseup.net"), + dsl.DNSLookupGetaddrinfo(), + dsl.MakeEndpointsForPort(9001), + dsl.NewEndpointPipeline( + dsl.Compose5( + dsl.TCPConnect(), + dsl.TLSHandshake(dsl.TLSHandshakeOptionX509Certs(rootCA)), + dsl.HTTPConnectionTLS(), + dsl.HTTPTransaction(dsl.HTTPTransactionOptionURLPath("/json")), + dsl.Discard[*dsl.HTTPResponse](), + ), + ), + ) +} + +// dslRuleMeasureGatewayReachability returns the DSL stage to measure the reachability of a +// riseupvpn gateway by performing a TCP connect. +// +// Arguments: +// +// - ipAddress is the gateway IP address; +// +// - port is the gateway port. +func dslRuleMeasureGatewayReachability(ipAddress, port string) dsl.Stage[*dsl.Void, *dsl.Void] { + return dsl.Compose( + dsl.NewEndpoint(net.JoinHostPort(ipAddress, port)), + dsl.Compose( + dsl.TCPConnect(), + dsl.Discard[*dsl.TCPConnection](), + ), + ) +} diff --git a/pkg/x/cmd/riseupvpn/main.go b/pkg/x/cmd/riseupvpn/main.go new file mode 100644 index 0000000..d461034 --- /dev/null +++ b/pkg/x/cmd/riseupvpn/main.go @@ -0,0 +1,120 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "net" + "reflect" + "time" + + "github.com/apex/log" + "github.com/ooni/2023-05-richer-input/pkg/dsl" + "github.com/ooni/probe-engine/pkg/runtimex" +) + +// isTCPGatewayAccessible returns whether a gateways is accessible. +func isTCPGatewayAccessible(stage dsl.Stage[*dsl.Void, *dsl.Void]) bool { + metrics := dsl.NewAccountingMetrics() + rtx := dsl.NewMeasurexliteRuntime(log.Log, metrics, time.Now()) + input := dsl.NewValue(&dsl.Void{}) + ctx := context.Background() + runtimex.Try0(dsl.Try(stage.Run(ctx, rtx, input))) + expect := map[string]int64{ + "tcp_connect_success_count": 1, + } + return reflect.DeepEqual(expect, metrics.Snapshot()) +} + +// generateGatewaysDSL generates a DSL to measure each gateway listed by eipService. +func generateGatewaysDSL(eipService *apiEIPService) (output []dsl.Stage[*dsl.Void, *dsl.Void]) { + for _, gw := range eipService.Gateways { + for _, txp := range gw.Capabilities.Transport { + if !txp.typeIsOneOf("obfs4", "openvpn") { + continue + } + if !txp.supportsTCP() { + continue + } + for _, port := range txp.Ports { + stage := dslRuleMeasureGatewayReachability(gw.IPAddress, port) + epnt := net.JoinHostPort(gw.IPAddress, port) + log.Infof("- checking whether %s/tcp is accessible", epnt) + if !isTCPGatewayAccessible(stage) { + log.Warnf("gateway %s/tcp IS NOT ACCESSIBLE", epnt) + continue + } + log.Infof("gateway %s/tcp is accessible", epnt) + output = append(output, stage) + } + } + } + return +} + +// mustGenerateDSL generates the DSL for measuring riseupvpn or PANICS on failure. +// +// The returned DSL roughly includes: +// +// - a stage to fetch the CA required by riseupvpn; +// +// - a stage to fetch provider.json; +// +// - a stage to fetch eip-service.json; +// +// - a stage to query the riseupvpn geo service; +// +// - a bunch of stages containing gateways to measure. +// +// The stages will run in parallel with reasonably small parallelism. +func mustGenerateDSL(eipService *apiEIPService, rootCA string) dsl.Stage[*dsl.Void, *dsl.Void] { + // start with a list of stages generated from the reachable gateways + stages := generateGatewaysDSL(eipService) + + // add a stage to measure fetching the CA file + stages = append(stages, dslRuleFetchCA()) + + // add a stage to measure fetching the provider.json file + stages = append(stages, dslRuleFetchProviderURL()) + + // add a stage to measure fetching the eip-services.json file + stages = append(stages, dslRuleFetchEIPServiceURL(rootCA)) + + // add a stage to measure fetching the geo services file + stages = append(stages, dslRuleFetchGeoServiceURL(rootCA)) + + // return the composed pipeline + return dsl.RunStagesInParallel(stages...) +} + +func main() { + // fetch the CA file + rootCA := apiMustFetchCA() + + // fetch the EIP services file + eipServices := apiMustFetchEIPService(rootCA) + + // generate the DSL + DSL := mustGenerateDSL(eipServices, rootCA) + + // serialize to JSON + rawDSL := runtimex.Try1(json.Marshal(DSL.ASTNode())) + + // load the DSL + var loadable dsl.LoadableASTNode + runtimex.Try0(json.Unmarshal(rawDSL, &loadable)) + + // make the DSL runnable + loader := dsl.NewASTLoader() + runnable := runtimex.Try1(loader.Load(&loadable)) + + // make sure we can run the DSL + log.Info("- checking whether we can run the generated DSL") + ctx := context.Background() + input := dsl.NewValue(&dsl.Void{}).AsGeneric() + rtx := dsl.NewMinimalRuntime(log.Log) + runtimex.Try0(dsl.Try(runnable.Run(ctx, rtx, input))) + + // dump the raw DSL on the stdout + fmt.Printf("%s\n", rawDSL) +} diff --git a/testdata/riseupvpn.jsonc b/testdata/riseupvpn.jsonc new file mode 100644 index 0000000..34c40e6 --- /dev/null +++ b/testdata/riseupvpn.jsonc @@ -0,0 +1,2267 @@ +// This file shows how to define riseupvpn in terms of the DSL. +{ + "commands": [ + { + "run_command": "nettest/run", + "with_arguments": { + "experimental_flags": { + "dsl": true + }, + "nettest_name": "riseupvpn", + "report_id": "20230406T142431Z_riseupvpn_IT_30722_n1_nLq4AP3YQWmW8hg6", + "suite_name": "im", + "targets": { + "stage_name": "run_stages_in_parallel", + "arguments": null, + "children": [ + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "204.13.164.252:443", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "204.13.164.252:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "204.13.164.252:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "204.13.164.252:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.211.109:443", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.211.109:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.211.109:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.211.109:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "37.218.244.248:443", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "37.218.244.248:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "37.218.244.248:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "37.218.244.248:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.58.132:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.58.132:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.58.132:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.58.83.11:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.58.83.11:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.58.83.11:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.254.238.55:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.254.238.55:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.254.238.55:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "198.252.153.109:443", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "198.252.153.109:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "198.252.153.109:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "198.252.153.109:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "195.154.106.118:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "195.154.106.118:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "195.154.106.118:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.196.108:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.196.108:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.196.108:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.197.108:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.197.108:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.197.108:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.90.118:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.90.118:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "163.172.90.118:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.15.9.205:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.15.9.205:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.15.9.205:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.55.86:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.55.86:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.159.55.86:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.158.144.32:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.158.144.32:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.158.144.32:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.158.144.31:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.158.144.31:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.158.144.31:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.58.83.9:443", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.58.83.9:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.58.83.9:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "199.58.83.9:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.15.187.53:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.15.187.53:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "51.15.187.53:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "185.220.103.11:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "185.220.103.11:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "185.220.103.11:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "37.218.244.250:53", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "37.218.244.250:80", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "new_endpoint", + "arguments": { + "endpoint": "37.218.244.250:1194", + "domain": "" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "domain_name", + "arguments": { + "domain": "black.riseup.net" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "dns_lookup_getaddrinfo", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "make_endpoints_for_port", + "arguments": { + "port": 443 + }, + "children": [] + }, + { + "stage_name": "new_endpoint_pipeline", + "arguments": null, + "children": [ + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tls_handshake", + "arguments": {}, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "http_connection_tls", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "http_transaction", + "arguments": { + "url_path": "/ca.crt" + }, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "domain_name", + "arguments": { + "domain": "riseup.net" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "dns_lookup_getaddrinfo", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "make_endpoints_for_port", + "arguments": { + "port": 443 + }, + "children": [] + }, + { + "stage_name": "new_endpoint_pipeline", + "arguments": null, + "children": [ + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tls_handshake", + "arguments": {}, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "http_connection_tls", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "http_transaction", + "arguments": { + "url_path": "/provider.json" + }, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "domain_name", + "arguments": { + "domain": "api.black.riseup.net" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "dns_lookup_getaddrinfo", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "make_endpoints_for_port", + "arguments": { + "port": 443 + }, + "children": [] + }, + { + "stage_name": "new_endpoint_pipeline", + "arguments": null, + "children": [ + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tls_handshake", + "arguments": { + "x509_certs": [ + "-----BEGIN CERTIFICATE-----\nMIIFjTCCA3WgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBZMRgwFgYDVQQKDA9SaXNl\ndXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UE\nAwwXUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EwHhcNMTQwNDI4MDAwMDAwWhcNMjQw\nNDI4MDAwMDAwWjBZMRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsM\nEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UEAwwXUmlzZXVwIE5ldHdvcmtzIFJv\nb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC76J4ciMJ8Sg0m\nTP7DF2DT9zNe0Csk4myoMFC57rfJeqsAlJCv1XMzBmXrw8wq/9z7XHv6n/0sWU7a\n7cF2hLR33ktjwODlx7vorU39/lXLndo492ZBhXQtG1INMShyv+nlmzO6GT7ESfNE\nLliFitEzwIegpMqxCIHXFuobGSCWF4N0qLHkq/SYUMoOJ96O3hmPSl1kFDRMtWXY\niw1SEKjUvpyDJpVs3NGxeLCaA7bAWhDY5s5Yb2fA1o8ICAqhowurowJpW7n5ZuLK\n5VNTlNy6nZpkjt1QycYvNycffyPOFm/Q/RKDlvnorJIrihPkyniV3YY5cGgP+Qkx\nHUOT0uLA6LHtzfiyaOqkXwc4b0ZcQD5Vbf6Prd20Ppt6ei0zazkUPwxld3hgyw58\nm/4UIjG3PInWTNf293GngK2Bnz8Qx9e/6TueMSAn/3JBLem56E0WtmbLVjvko+LF\nPM5xA+m0BmuSJtrD1MUCXMhqYTtiOvgLBlUm5zkNxALzG+cXB28k6XikXt6MRG7q\nhzIPG38zwkooM55yy5i1YfcIi5NjMH6A+t4IJxxwb67MSb6UFOwg5kFokdONZcwj\nshczHdG9gLKSBIvrKa03Nd3W2dF9hMbRu//STcQxOailDBQCnXXfAATj9pYzdY4k\nha8VCAREGAKTDAex9oXf1yRuktES4QIDAQABo2AwXjAdBgNVHQ4EFgQUC4tdmLVu\nf9hwfK4AGliaet5KkcgwDgYDVR0PAQH/BAQDAgIEMAwGA1UdEwQFMAMBAf8wHwYD\nVR0jBBgwFoAUC4tdmLVuf9hwfK4AGliaet5KkcgwDQYJKoZIhvcNAQENBQADggIB\nAGzL+GRnYu99zFoy0bXJKOGCF5XUXP/3gIXPRDqQf5g7Cu/jYMID9dB3No4Zmf7v\nqHjiSXiS8jx1j/6/Luk6PpFbT7QYm4QLs1f4BlfZOti2KE8r7KRDPIecUsUXW6P/\n3GJAVYH/+7OjA39za9AieM7+H5BELGccGrM5wfl7JeEz8in+V2ZWDzHQO4hMkiTQ\n4ZckuaL201F68YpiItBNnJ9N5nHr1MRiGyApHmLXY/wvlrOpclh95qn+lG6/2jk7\n3AmihLOKYMlPwPakJg4PYczm3icFLgTpjV5sq2md9bRyAg3oPGfAuWHmKj2Ikqch\nTd5CHKGxEEWbGUWEMP0s1A/JHWiCbDigc4Cfxhy56CWG4q0tYtnc2GMw8OAUO6Wf\nXu5pYKNkzKSEtT/MrNJt44tTZWbKV/Pi/N2Fx36my7TgTUj7g3xcE9eF4JV2H/sg\ntsK3pwE0FEqGnT4qMFbixQmc8bGyuakr23wjMvfO7eZUxBuWYR2SkcP26sozF9PF\ntGhbZHQVGZUTVPyvwahMUEhbPGVerOW0IYpxkm0x/eaWdTc4vPpf/rIlgbAjarnJ\nUN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp+yyUWw8tNsp\n0BuC1b7uW/bBn/xKm319wXVDvBgZgcktMolak39V7DVO\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIBYjCCAQigAwIBAgIBATAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxMRUFQIFJv\nb3QgQ0EwHhcNMjExMTAyMTkwNTM3WhcNMjYxMTAyMTkxMDM3WjAXMRUwEwYDVQQD\nEwxMRUFQIFJvb3QgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQxOXBGu+gf\npjHzVteGTWL6XnFxtEnKMFpKaJkA/VOHmESzoLsZRQxt88GssxaqC01J17idQiqv\nzgNpedmtvFtyo0UwQzAOBgNVHQ8BAf8EBAMCAqQwEgYDVR0TAQH/BAgwBgEB/wIB\nATAdBgNVHQ4EFgQUZdoUlJrCIUNFrpffAq+LQjnwEz4wCgYIKoZIzj0EAwIDSAAw\nRQIgfr3w4tnRG+NdI3LsGPlsRktGK20xHTzsB3orB0yC6cICIQCB+/9y8nmSStfN\nVUMUyk2hNd7/kC8nL222TTD7VZUtsg==\n-----END CERTIFICATE-----\n" + ] + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "http_connection_tls", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "http_transaction", + "arguments": { + "url_path": "/3/config/eip-service.json" + }, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "domain_name", + "arguments": { + "domain": "api.black.riseup.net" + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "dns_lookup_getaddrinfo", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "make_endpoints_for_port", + "arguments": { + "port": 9001 + }, + "children": [] + }, + { + "stage_name": "new_endpoint_pipeline", + "arguments": null, + "children": [ + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tcp_connect", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "tls_handshake", + "arguments": { + "x509_certs": [ + "-----BEGIN CERTIFICATE-----\nMIIFjTCCA3WgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBZMRgwFgYDVQQKDA9SaXNl\ndXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UE\nAwwXUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EwHhcNMTQwNDI4MDAwMDAwWhcNMjQw\nNDI4MDAwMDAwWjBZMRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsM\nEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UEAwwXUmlzZXVwIE5ldHdvcmtzIFJv\nb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC76J4ciMJ8Sg0m\nTP7DF2DT9zNe0Csk4myoMFC57rfJeqsAlJCv1XMzBmXrw8wq/9z7XHv6n/0sWU7a\n7cF2hLR33ktjwODlx7vorU39/lXLndo492ZBhXQtG1INMShyv+nlmzO6GT7ESfNE\nLliFitEzwIegpMqxCIHXFuobGSCWF4N0qLHkq/SYUMoOJ96O3hmPSl1kFDRMtWXY\niw1SEKjUvpyDJpVs3NGxeLCaA7bAWhDY5s5Yb2fA1o8ICAqhowurowJpW7n5ZuLK\n5VNTlNy6nZpkjt1QycYvNycffyPOFm/Q/RKDlvnorJIrihPkyniV3YY5cGgP+Qkx\nHUOT0uLA6LHtzfiyaOqkXwc4b0ZcQD5Vbf6Prd20Ppt6ei0zazkUPwxld3hgyw58\nm/4UIjG3PInWTNf293GngK2Bnz8Qx9e/6TueMSAn/3JBLem56E0WtmbLVjvko+LF\nPM5xA+m0BmuSJtrD1MUCXMhqYTtiOvgLBlUm5zkNxALzG+cXB28k6XikXt6MRG7q\nhzIPG38zwkooM55yy5i1YfcIi5NjMH6A+t4IJxxwb67MSb6UFOwg5kFokdONZcwj\nshczHdG9gLKSBIvrKa03Nd3W2dF9hMbRu//STcQxOailDBQCnXXfAATj9pYzdY4k\nha8VCAREGAKTDAex9oXf1yRuktES4QIDAQABo2AwXjAdBgNVHQ4EFgQUC4tdmLVu\nf9hwfK4AGliaet5KkcgwDgYDVR0PAQH/BAQDAgIEMAwGA1UdEwQFMAMBAf8wHwYD\nVR0jBBgwFoAUC4tdmLVuf9hwfK4AGliaet5KkcgwDQYJKoZIhvcNAQENBQADggIB\nAGzL+GRnYu99zFoy0bXJKOGCF5XUXP/3gIXPRDqQf5g7Cu/jYMID9dB3No4Zmf7v\nqHjiSXiS8jx1j/6/Luk6PpFbT7QYm4QLs1f4BlfZOti2KE8r7KRDPIecUsUXW6P/\n3GJAVYH/+7OjA39za9AieM7+H5BELGccGrM5wfl7JeEz8in+V2ZWDzHQO4hMkiTQ\n4ZckuaL201F68YpiItBNnJ9N5nHr1MRiGyApHmLXY/wvlrOpclh95qn+lG6/2jk7\n3AmihLOKYMlPwPakJg4PYczm3icFLgTpjV5sq2md9bRyAg3oPGfAuWHmKj2Ikqch\nTd5CHKGxEEWbGUWEMP0s1A/JHWiCbDigc4Cfxhy56CWG4q0tYtnc2GMw8OAUO6Wf\nXu5pYKNkzKSEtT/MrNJt44tTZWbKV/Pi/N2Fx36my7TgTUj7g3xcE9eF4JV2H/sg\ntsK3pwE0FEqGnT4qMFbixQmc8bGyuakr23wjMvfO7eZUxBuWYR2SkcP26sozF9PF\ntGhbZHQVGZUTVPyvwahMUEhbPGVerOW0IYpxkm0x/eaWdTc4vPpf/rIlgbAjarnJ\nUN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp+yyUWw8tNsp\n0BuC1b7uW/bBn/xKm319wXVDvBgZgcktMolak39V7DVO\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIBYjCCAQigAwIBAgIBATAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxMRUFQIFJv\nb3QgQ0EwHhcNMjExMTAyMTkwNTM3WhcNMjYxMTAyMTkxMDM3WjAXMRUwEwYDVQQD\nEwxMRUFQIFJvb3QgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQxOXBGu+gf\npjHzVteGTWL6XnFxtEnKMFpKaJkA/VOHmESzoLsZRQxt88GssxaqC01J17idQiqv\nzgNpedmtvFtyo0UwQzAOBgNVHQ8BAf8EBAMCAqQwEgYDVR0TAQH/BAgwBgEB/wIB\nATAdBgNVHQ4EFgQUZdoUlJrCIUNFrpffAq+LQjnwEz4wCgYIKoZIzj0EAwIDSAAw\nRQIgfr3w4tnRG+NdI3LsGPlsRktGK20xHTzsB3orB0yC6cICIQCB+/9y8nmSStfN\nVUMUyk2hNd7/kC8nL222TTD7VZUtsg==\n-----END CERTIFICATE-----\n" + ] + }, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "http_connection_tls", + "arguments": null, + "children": [] + }, + { + "stage_name": "compose", + "arguments": null, + "children": [ + { + "stage_name": "http_transaction", + "arguments": { + "url_path": "/json" + }, + "children": [] + }, + { + "stage_name": "discard", + "arguments": null, + "children": [] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + } + } + ], + "v": 2 +} From ae30e0a45392e078a3bc8f35ef38118559befa6a Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Fri, 14 Jul 2023 02:04:54 +0200 Subject: [PATCH 2/2] take note of more work to do --- pkg/dsl/measurexlite.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/dsl/measurexlite.go b/pkg/dsl/measurexlite.go index d2a8e81..48c724e 100644 --- a/pkg/dsl/measurexlite.go +++ b/pkg/dsl/measurexlite.go @@ -149,6 +149,16 @@ func (t *measurexliteTrace) HTTPTransaction( // mainly going to be I/O events necessary to measure throttling t.runtime.saveNetworkEvents(t.trace.NetworkEvents()...) + // TODO(bassosimone): when we completely omit the body, we should also + // declare that the body has been truncated, otherwise it becomes a bit + // difficult to understand what has actually happened. The best course + // of action here is probably to modify + // + // measurexlite.NewArchivalHTTPRequestResult + // + // to replace the maxBodySnapshotSize with a boolean value telling + // the archival function whether the body has been truncated. + // create and save an HTTP observation t.runtime.saveHTTPRequestResults(measurexlite.NewArchivalHTTPRequestResult( t.trace.Index,