Full Code of cloudflare/cfrpki for AI

master 932c7596bb6f cached
1224 files
20.0 MB
5.3M tokens
106713 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (21,261K chars total). Download the full file to get everything.
Repository: cloudflare/cfrpki
Branch: master
Commit: 932c7596bb6f
Files: 1224
Total size: 20.0 MB

Directory structure:
gitextract_hhntx3gl/

├── .dockerignore
├── .github/
│   └── workflows/
│       ├── codeql.yml
│       ├── go.yml
│       └── release.yml
├── .gitignore
├── Dockerfile
├── Dockerfile.prod
├── LICENSE
├── Makefile
├── Monitoring.md
├── README.md
├── api/
│   └── schemas/
│       └── schemas.go
├── ca/
│   └── xml.go
├── cmd/
│   ├── ctrpki/
│   │   └── ctrpki.go
│   ├── localrpki/
│   │   └── localrpki.go
│   └── octorpki/
│       ├── ct.go
│       ├── filter.go
│       ├── filter_test.go
│       ├── octorpki.go
│       ├── rrdp_fetcher.go
│       ├── rsync_fetcher.go
│       └── tals/
│           ├── afrinic.tal
│           ├── apnic.tal
│           ├── arin.tal
│           ├── lacnic.tal
│           └── ripe.tal
├── compose/
│   ├── docker-compose.yml
│   ├── grafana-dashboard-provider.yml
│   ├── grafana-dashboard-rpki.json
│   ├── grafana-datasources.yml
│   ├── private.pem
│   ├── prometheus.yml
│   └── public.pem
├── go.mod
├── go.sum
├── ov/
│   ├── ov.go
│   └── ov_test.go
├── package/
│   ├── after-install-octorpki.sh
│   ├── before-remove-octorpki.sh
│   ├── octorpki.env
│   └── octorpki.service
├── sync/
│   ├── api/
│   │   ├── cfrpki.pb.go
│   │   ├── cfrpki.proto
│   │   └── fetch.go
│   └── lib/
│       ├── errors.go
│       ├── fetch.go
│       ├── fetch_test.go
│       ├── rrdp.go
│       ├── rrdp_struct.go
│       ├── rsync.go
│       ├── rsync_test.go
│       └── utils.go
├── validator/
│   ├── lib/
│   │   ├── ber.go
│   │   ├── cert.go
│   │   ├── cert_test.go
│   │   ├── cms.go
│   │   ├── crl.go
│   │   ├── manifest.go
│   │   ├── manifest_test.go
│   │   ├── roa.go
│   │   ├── roa_test.go
│   │   ├── tal.go
│   │   ├── tal_test.go
│   │   ├── xml.data
│   │   ├── xml.go
│   │   └── xml_test.go
│   └── pki/
│       ├── errors.go
│       ├── pki.go
│       └── pki_test.go
└── vendor/
    ├── github.com/
    │   ├── beorn7/
    │   │   └── perks/
    │   │       ├── LICENSE
    │   │       └── quantile/
    │   │           ├── exampledata.txt
    │   │           └── stream.go
    │   ├── cespare/
    │   │   └── xxhash/
    │   │       └── v2/
    │   │           ├── LICENSE.txt
    │   │           ├── README.md
    │   │           ├── testall.sh
    │   │           ├── xxhash.go
    │   │           ├── xxhash_amd64.s
    │   │           ├── xxhash_arm64.s
    │   │           ├── xxhash_asm.go
    │   │           ├── xxhash_other.go
    │   │           ├── xxhash_safe.go
    │   │           └── xxhash_unsafe.go
    │   ├── cloudflare/
    │   │   └── gortr/
    │   │       ├── LICENSE.txt
    │   │       └── prefixfile/
    │   │           ├── prefixfile.go
    │   │           └── slurm.go
    │   ├── davecgh/
    │   │   └── go-spew/
    │   │       ├── LICENSE
    │   │       └── spew/
    │   │           ├── bypass.go
    │   │           ├── bypasssafe.go
    │   │           ├── common.go
    │   │           ├── config.go
    │   │           ├── doc.go
    │   │           ├── dump.go
    │   │           ├── format.go
    │   │           └── spew.go
    │   ├── getsentry/
    │   │   └── sentry-go/
    │   │       ├── .codecov.yml
    │   │       ├── .craft.yml
    │   │       ├── .gitattributes
    │   │       ├── .gitignore
    │   │       ├── .golangci.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── MIGRATION.md
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── client.go
    │   │       ├── doc.go
    │   │       ├── dsn.go
    │   │       ├── dynamic_sampling_context.go
    │   │       ├── hub.go
    │   │       ├── integrations.go
    │   │       ├── interfaces.go
    │   │       ├── internal/
    │   │       │   ├── debug/
    │   │       │   │   └── transport.go
    │   │       │   ├── otel/
    │   │       │   │   └── baggage/
    │   │       │   │       ├── README.md
    │   │       │   │       ├── baggage.go
    │   │       │   │       └── internal/
    │   │       │   │           └── baggage/
    │   │       │   │               └── baggage.go
    │   │       │   └── ratelimit/
    │   │       │       ├── category.go
    │   │       │       ├── deadline.go
    │   │       │       ├── doc.go
    │   │       │       ├── map.go
    │   │       │       ├── rate_limits.go
    │   │       │       └── retry_after.go
    │   │       ├── scope.go
    │   │       ├── sentry.go
    │   │       ├── sourcereader.go
    │   │       ├── span_recorder.go
    │   │       ├── stacktrace.go
    │   │       ├── traces_sampler.go
    │   │       ├── tracing.go
    │   │       ├── transport.go
    │   │       └── util.go
    │   ├── go-logr/
    │   │   └── logr/
    │   │       ├── .golangci.yaml
    │   │       ├── CHANGELOG.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── discard.go
    │   │       └── logr.go
    │   ├── golang/
    │   │   └── protobuf/
    │   │       ├── AUTHORS
    │   │       ├── CONTRIBUTORS
    │   │       ├── LICENSE
    │   │       ├── jsonpb/
    │   │       │   ├── decode.go
    │   │       │   ├── encode.go
    │   │       │   └── json.go
    │   │       ├── proto/
    │   │       │   ├── buffer.go
    │   │       │   ├── defaults.go
    │   │       │   ├── deprecated.go
    │   │       │   ├── discard.go
    │   │       │   ├── extensions.go
    │   │       │   ├── properties.go
    │   │       │   ├── proto.go
    │   │       │   ├── registry.go
    │   │       │   ├── text_decode.go
    │   │       │   ├── text_encode.go
    │   │       │   ├── wire.go
    │   │       │   └── wrappers.go
    │   │       └── ptypes/
    │   │           ├── any/
    │   │           │   └── any.pb.go
    │   │           ├── any.go
    │   │           ├── doc.go
    │   │           ├── duration/
    │   │           │   └── duration.pb.go
    │   │           ├── duration.go
    │   │           ├── timestamp/
    │   │           │   └── timestamp.pb.go
    │   │           └── timestamp.go
    │   ├── google/
    │   │   └── certificate-transparency-go/
    │   │       ├── .gitignore
    │   │       ├── .golangci.yaml
    │   │       ├── AUTHORS
    │   │       ├── CHANGELOG.md
    │   │       ├── CODEOWNERS
    │   │       ├── CONTRIBUTING.md
    │   │       ├── CONTRIBUTORS
    │   │       ├── LICENSE
    │   │       ├── PULL_REQUEST_TEMPLATE.md
    │   │       ├── README.md
    │   │       ├── asn1/
    │   │       │   ├── README.md
    │   │       │   ├── asn1.go
    │   │       │   ├── common.go
    │   │       │   └── marshal.go
    │   │       ├── client/
    │   │       │   ├── configpb/
    │   │       │   │   ├── multilog.pb.go
    │   │       │   │   └── multilog.proto
    │   │       │   ├── getentries.go
    │   │       │   ├── logclient.go
    │   │       │   └── multilog.go
    │   │       ├── cloudbuild.yaml
    │   │       ├── cloudbuild_master.yaml
    │   │       ├── cloudbuild_tag.yaml
    │   │       ├── codecov.yml
    │   │       ├── jsonclient/
    │   │       │   ├── backoff.go
    │   │       │   └── client.go
    │   │       ├── proto_gen.go
    │   │       ├── serialization.go
    │   │       ├── signatures.go
    │   │       ├── tls/
    │   │       │   ├── signature.go
    │   │       │   ├── tls.go
    │   │       │   └── types.go
    │   │       ├── types.go
    │   │       └── x509/
    │   │           ├── README.md
    │   │           ├── cert_pool.go
    │   │           ├── curves.go
    │   │           ├── error.go
    │   │           ├── errors.go
    │   │           ├── names.go
    │   │           ├── pem_decrypt.go
    │   │           ├── pkcs1.go
    │   │           ├── pkcs8.go
    │   │           ├── pkix/
    │   │           │   └── pkix.go
    │   │           ├── ptr_sysptr_windows.go
    │   │           ├── ptr_uint_windows.go
    │   │           ├── revoked.go
    │   │           ├── root.go
    │   │           ├── root_bsd.go
    │   │           ├── root_cgo_darwin.go
    │   │           ├── root_darwin.go
    │   │           ├── root_darwin_armx.go
    │   │           ├── root_js.go
    │   │           ├── root_linux.go
    │   │           ├── root_nocgo_darwin.go
    │   │           ├── root_plan9.go
    │   │           ├── root_solaris.go
    │   │           ├── root_unix.go
    │   │           ├── root_windows.go
    │   │           ├── rpki.go
    │   │           ├── sec1.go
    │   │           ├── test-dir.crt
    │   │           ├── test-file.crt
    │   │           ├── verify.go
    │   │           └── x509.go
    │   ├── kentik/
    │   │   └── patricia/
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── address_v4.go
    │   │       ├── address_v6.go
    │   │       ├── bits.go
    │   │       ├── init.go
    │   │       ├── int64_tree/
    │   │       │   ├── tree_node_v4.go
    │   │       │   ├── tree_node_v6.go
    │   │       │   ├── tree_v4.go
    │   │       │   ├── tree_v4_manual.go
    │   │       │   ├── tree_v6_generated.go
    │   │       │   ├── tree_v6_manual.go
    │   │       │   └── trees.go
    │   │       ├── net.go
    │   │       └── test_tags.tsv
    │   ├── matttproud/
    │   │   └── golang_protobuf_extensions/
    │   │       ├── LICENSE
    │   │       ├── NOTICE
    │   │       └── pbutil/
    │   │           ├── .gitignore
    │   │           ├── Makefile
    │   │           ├── decode.go
    │   │           ├── doc.go
    │   │           └── encode.go
    │   ├── opentracing/
    │   │   └── opentracing-go/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── ext/
    │   │       │   ├── field.go
    │   │       │   └── tags.go
    │   │       ├── ext.go
    │   │       ├── globaltracer.go
    │   │       ├── gocontext.go
    │   │       ├── log/
    │   │       │   ├── field.go
    │   │       │   └── util.go
    │   │       ├── noop.go
    │   │       ├── propagation.go
    │   │       ├── span.go
    │   │       └── tracer.go
    │   ├── pkg/
    │   │   └── errors/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       ├── errors.go
    │   │       ├── go113.go
    │   │       └── stack.go
    │   ├── pmezard/
    │   │   └── go-difflib/
    │   │       ├── LICENSE
    │   │       └── difflib/
    │   │           └── difflib.go
    │   ├── prometheus/
    │   │   ├── client_golang/
    │   │   │   ├── LICENSE
    │   │   │   ├── NOTICE
    │   │   │   └── prometheus/
    │   │   │       ├── .gitignore
    │   │   │       ├── README.md
    │   │   │       ├── build_info_collector.go
    │   │   │       ├── collector.go
    │   │   │       ├── counter.go
    │   │   │       ├── desc.go
    │   │   │       ├── doc.go
    │   │   │       ├── expvar_collector.go
    │   │   │       ├── fnv.go
    │   │   │       ├── gauge.go
    │   │   │       ├── get_pid.go
    │   │   │       ├── get_pid_gopherjs.go
    │   │   │       ├── go_collector.go
    │   │   │       ├── go_collector_go116.go
    │   │   │       ├── go_collector_latest.go
    │   │   │       ├── histogram.go
    │   │   │       ├── internal/
    │   │   │       │   ├── almost_equal.go
    │   │   │       │   ├── difflib.go
    │   │   │       │   ├── go_collector_options.go
    │   │   │       │   ├── go_runtime_metrics.go
    │   │   │       │   └── metric.go
    │   │   │       ├── labels.go
    │   │   │       ├── metric.go
    │   │   │       ├── num_threads.go
    │   │   │       ├── num_threads_gopherjs.go
    │   │   │       ├── observer.go
    │   │   │       ├── process_collector.go
    │   │   │       ├── process_collector_js.go
    │   │   │       ├── process_collector_other.go
    │   │   │       ├── process_collector_windows.go
    │   │   │       ├── promhttp/
    │   │   │       │   ├── delegator.go
    │   │   │       │   ├── http.go
    │   │   │       │   ├── instrument_client.go
    │   │   │       │   ├── instrument_server.go
    │   │   │       │   └── option.go
    │   │   │       ├── registry.go
    │   │   │       ├── summary.go
    │   │   │       ├── timer.go
    │   │   │       ├── untyped.go
    │   │   │       ├── value.go
    │   │   │       ├── vec.go
    │   │   │       └── wrap.go
    │   │   ├── client_model/
    │   │   │   ├── LICENSE
    │   │   │   ├── NOTICE
    │   │   │   └── go/
    │   │   │       └── metrics.pb.go
    │   │   ├── common/
    │   │   │   ├── LICENSE
    │   │   │   ├── NOTICE
    │   │   │   ├── expfmt/
    │   │   │   │   ├── decode.go
    │   │   │   │   ├── encode.go
    │   │   │   │   ├── expfmt.go
    │   │   │   │   ├── fuzz.go
    │   │   │   │   ├── openmetrics_create.go
    │   │   │   │   ├── text_create.go
    │   │   │   │   └── text_parse.go
    │   │   │   ├── internal/
    │   │   │   │   └── bitbucket.org/
    │   │   │   │       └── ww/
    │   │   │   │           └── goautoneg/
    │   │   │   │               ├── README.txt
    │   │   │   │               └── autoneg.go
    │   │   │   └── model/
    │   │   │       ├── alert.go
    │   │   │       ├── fingerprinting.go
    │   │   │       ├── fnv.go
    │   │   │       ├── labels.go
    │   │   │       ├── labelset.go
    │   │   │       ├── metric.go
    │   │   │       ├── model.go
    │   │   │       ├── signature.go
    │   │   │       ├── silence.go
    │   │   │       ├── time.go
    │   │   │       ├── value.go
    │   │   │       ├── value_float.go
    │   │   │       ├── value_histogram.go
    │   │   │       └── value_type.go
    │   │   └── procfs/
    │   │       ├── .gitignore
    │   │       ├── .golangci.yml
    │   │       ├── CODE_OF_CONDUCT.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── MAINTAINERS.md
    │   │       ├── Makefile
    │   │       ├── Makefile.common
    │   │       ├── NOTICE
    │   │       ├── README.md
    │   │       ├── SECURITY.md
    │   │       ├── arp.go
    │   │       ├── buddyinfo.go
    │   │       ├── cmdline.go
    │   │       ├── cpuinfo.go
    │   │       ├── cpuinfo_armx.go
    │   │       ├── cpuinfo_loong64.go
    │   │       ├── cpuinfo_mipsx.go
    │   │       ├── cpuinfo_others.go
    │   │       ├── cpuinfo_ppcx.go
    │   │       ├── cpuinfo_riscvx.go
    │   │       ├── cpuinfo_s390x.go
    │   │       ├── cpuinfo_x86.go
    │   │       ├── crypto.go
    │   │       ├── doc.go
    │   │       ├── fs.go
    │   │       ├── fscache.go
    │   │       ├── internal/
    │   │       │   ├── fs/
    │   │       │   │   └── fs.go
    │   │       │   └── util/
    │   │       │       ├── parse.go
    │   │       │       ├── readfile.go
    │   │       │       ├── sysreadfile.go
    │   │       │       ├── sysreadfile_compat.go
    │   │       │       └── valueparser.go
    │   │       ├── ipvs.go
    │   │       ├── kernel_random.go
    │   │       ├── loadavg.go
    │   │       ├── mdstat.go
    │   │       ├── meminfo.go
    │   │       ├── mountinfo.go
    │   │       ├── mountstats.go
    │   │       ├── net_conntrackstat.go
    │   │       ├── net_dev.go
    │   │       ├── net_ip_socket.go
    │   │       ├── net_protocols.go
    │   │       ├── net_sockstat.go
    │   │       ├── net_softnet.go
    │   │       ├── net_tcp.go
    │   │       ├── net_udp.go
    │   │       ├── net_unix.go
    │   │       ├── net_xfrm.go
    │   │       ├── netstat.go
    │   │       ├── proc.go
    │   │       ├── proc_cgroup.go
    │   │       ├── proc_cgroups.go
    │   │       ├── proc_environ.go
    │   │       ├── proc_fdinfo.go
    │   │       ├── proc_interrupts.go
    │   │       ├── proc_io.go
    │   │       ├── proc_limits.go
    │   │       ├── proc_maps.go
    │   │       ├── proc_netstat.go
    │   │       ├── proc_ns.go
    │   │       ├── proc_psi.go
    │   │       ├── proc_smaps.go
    │   │       ├── proc_snmp.go
    │   │       ├── proc_snmp6.go
    │   │       ├── proc_stat.go
    │   │       ├── proc_status.go
    │   │       ├── proc_sys.go
    │   │       ├── schedstat.go
    │   │       ├── slab.go
    │   │       ├── softirqs.go
    │   │       ├── stat.go
    │   │       ├── swaps.go
    │   │       ├── thread.go
    │   │       ├── ttar
    │   │       ├── vm.go
    │   │       └── zoneinfo.go
    │   ├── rs/
    │   │   └── cors/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── cors.go
    │   │       └── utils.go
    │   ├── stretchr/
    │   │   └── testify/
    │   │       ├── LICENSE
    │   │       └── assert/
    │   │           ├── assertion_compare.go
    │   │           ├── assertion_compare_can_convert.go
    │   │           ├── assertion_compare_legacy.go
    │   │           ├── assertion_format.go
    │   │           ├── assertion_format.go.tmpl
    │   │           ├── assertion_forward.go
    │   │           ├── assertion_forward.go.tmpl
    │   │           ├── assertion_order.go
    │   │           ├── assertions.go
    │   │           ├── doc.go
    │   │           ├── errors.go
    │   │           ├── forward_assertions.go
    │   │           └── http_assertions.go
    │   └── uber/
    │       └── jaeger-lib/
    │           ├── LICENSE
    │           └── metrics/
    │               ├── counter.go
    │               ├── factory.go
    │               ├── gauge.go
    │               ├── histogram.go
    │               ├── keys.go
    │               ├── metrics.go
    │               ├── stopwatch.go
    │               └── timer.go
    ├── golang.org/
    │   └── x/
    │       ├── crypto/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── cryptobyte/
    │       │   │   ├── asn1/
    │       │   │   │   └── asn1.go
    │       │   │   ├── asn1.go
    │       │   │   ├── builder.go
    │       │   │   └── string.go
    │       │   └── ed25519/
    │       │       └── ed25519.go
    │       ├── net/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── context/
    │       │   │   └── ctxhttp/
    │       │   │       └── ctxhttp.go
    │       │   ├── http/
    │       │   │   └── httpguts/
    │       │   │       ├── guts.go
    │       │   │       └── httplex.go
    │       │   ├── http2/
    │       │   │   ├── .gitignore
    │       │   │   ├── Dockerfile
    │       │   │   ├── Makefile
    │       │   │   ├── ascii.go
    │       │   │   ├── ciphers.go
    │       │   │   ├── client_conn_pool.go
    │       │   │   ├── databuffer.go
    │       │   │   ├── errors.go
    │       │   │   ├── flow.go
    │       │   │   ├── frame.go
    │       │   │   ├── go111.go
    │       │   │   ├── go115.go
    │       │   │   ├── go118.go
    │       │   │   ├── gotrack.go
    │       │   │   ├── headermap.go
    │       │   │   ├── hpack/
    │       │   │   │   ├── encode.go
    │       │   │   │   ├── hpack.go
    │       │   │   │   ├── huffman.go
    │       │   │   │   ├── static_table.go
    │       │   │   │   └── tables.go
    │       │   │   ├── http2.go
    │       │   │   ├── not_go111.go
    │       │   │   ├── not_go115.go
    │       │   │   ├── not_go118.go
    │       │   │   ├── pipe.go
    │       │   │   ├── server.go
    │       │   │   ├── transport.go
    │       │   │   ├── write.go
    │       │   │   ├── writesched.go
    │       │   │   ├── writesched_priority.go
    │       │   │   └── writesched_random.go
    │       │   ├── idna/
    │       │   │   ├── go118.go
    │       │   │   ├── idna10.0.0.go
    │       │   │   ├── idna9.0.0.go
    │       │   │   ├── pre_go118.go
    │       │   │   ├── punycode.go
    │       │   │   ├── tables10.0.0.go
    │       │   │   ├── tables11.0.0.go
    │       │   │   ├── tables12.0.0.go
    │       │   │   ├── tables13.0.0.go
    │       │   │   ├── tables9.0.0.go
    │       │   │   ├── trie.go
    │       │   │   └── trieval.go
    │       │   ├── internal/
    │       │   │   └── timeseries/
    │       │   │       └── timeseries.go
    │       │   └── trace/
    │       │       ├── events.go
    │       │       ├── histogram.go
    │       │       └── trace.go
    │       ├── sys/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── execabs/
    │       │   │   ├── execabs.go
    │       │   │   ├── execabs_go118.go
    │       │   │   └── execabs_go119.go
    │       │   ├── internal/
    │       │   │   └── unsafeheader/
    │       │   │       └── unsafeheader.go
    │       │   ├── unix/
    │       │   │   ├── .gitignore
    │       │   │   ├── README.md
    │       │   │   ├── affinity_linux.go
    │       │   │   ├── aliases.go
    │       │   │   ├── asm_aix_ppc64.s
    │       │   │   ├── asm_bsd_386.s
    │       │   │   ├── asm_bsd_amd64.s
    │       │   │   ├── asm_bsd_arm.s
    │       │   │   ├── asm_bsd_arm64.s
    │       │   │   ├── asm_bsd_ppc64.s
    │       │   │   ├── asm_bsd_riscv64.s
    │       │   │   ├── asm_linux_386.s
    │       │   │   ├── asm_linux_amd64.s
    │       │   │   ├── asm_linux_arm.s
    │       │   │   ├── asm_linux_arm64.s
    │       │   │   ├── asm_linux_loong64.s
    │       │   │   ├── asm_linux_mips64x.s
    │       │   │   ├── asm_linux_mipsx.s
    │       │   │   ├── asm_linux_ppc64x.s
    │       │   │   ├── asm_linux_riscv64.s
    │       │   │   ├── asm_linux_s390x.s
    │       │   │   ├── asm_openbsd_mips64.s
    │       │   │   ├── asm_solaris_amd64.s
    │       │   │   ├── asm_zos_s390x.s
    │       │   │   ├── bluetooth_linux.go
    │       │   │   ├── cap_freebsd.go
    │       │   │   ├── constants.go
    │       │   │   ├── dev_aix_ppc.go
    │       │   │   ├── dev_aix_ppc64.go
    │       │   │   ├── dev_darwin.go
    │       │   │   ├── dev_dragonfly.go
    │       │   │   ├── dev_freebsd.go
    │       │   │   ├── dev_linux.go
    │       │   │   ├── dev_netbsd.go
    │       │   │   ├── dev_openbsd.go
    │       │   │   ├── dev_zos.go
    │       │   │   ├── dirent.go
    │       │   │   ├── endian_big.go
    │       │   │   ├── endian_little.go
    │       │   │   ├── env_unix.go
    │       │   │   ├── epoll_zos.go
    │       │   │   ├── fcntl.go
    │       │   │   ├── fcntl_darwin.go
    │       │   │   ├── fcntl_linux_32bit.go
    │       │   │   ├── fdset.go
    │       │   │   ├── fstatfs_zos.go
    │       │   │   ├── gccgo.go
    │       │   │   ├── gccgo_c.c
    │       │   │   ├── gccgo_linux_amd64.go
    │       │   │   ├── ifreq_linux.go
    │       │   │   ├── ioctl.go
    │       │   │   ├── ioctl_linux.go
    │       │   │   ├── ioctl_zos.go
    │       │   │   ├── mkall.sh
    │       │   │   ├── mkerrors.sh
    │       │   │   ├── pagesize_unix.go
    │       │   │   ├── pledge_openbsd.go
    │       │   │   ├── ptrace_darwin.go
    │       │   │   ├── ptrace_ios.go
    │       │   │   ├── race.go
    │       │   │   ├── race0.go
    │       │   │   ├── readdirent_getdents.go
    │       │   │   ├── readdirent_getdirentries.go
    │       │   │   ├── sockcmsg_dragonfly.go
    │       │   │   ├── sockcmsg_linux.go
    │       │   │   ├── sockcmsg_unix.go
    │       │   │   ├── sockcmsg_unix_other.go
    │       │   │   ├── syscall.go
    │       │   │   ├── syscall_aix.go
    │       │   │   ├── syscall_aix_ppc.go
    │       │   │   ├── syscall_aix_ppc64.go
    │       │   │   ├── syscall_bsd.go
    │       │   │   ├── syscall_darwin.go
    │       │   │   ├── syscall_darwin_amd64.go
    │       │   │   ├── syscall_darwin_arm64.go
    │       │   │   ├── syscall_darwin_libSystem.go
    │       │   │   ├── syscall_dragonfly.go
    │       │   │   ├── syscall_dragonfly_amd64.go
    │       │   │   ├── syscall_freebsd.go
    │       │   │   ├── syscall_freebsd_386.go
    │       │   │   ├── syscall_freebsd_amd64.go
    │       │   │   ├── syscall_freebsd_arm.go
    │       │   │   ├── syscall_freebsd_arm64.go
    │       │   │   ├── syscall_freebsd_riscv64.go
    │       │   │   ├── syscall_hurd.go
    │       │   │   ├── syscall_hurd_386.go
    │       │   │   ├── syscall_illumos.go
    │       │   │   ├── syscall_linux.go
    │       │   │   ├── syscall_linux_386.go
    │       │   │   ├── syscall_linux_alarm.go
    │       │   │   ├── syscall_linux_amd64.go
    │       │   │   ├── syscall_linux_amd64_gc.go
    │       │   │   ├── syscall_linux_arm.go
    │       │   │   ├── syscall_linux_arm64.go
    │       │   │   ├── syscall_linux_gc.go
    │       │   │   ├── syscall_linux_gc_386.go
    │       │   │   ├── syscall_linux_gc_arm.go
    │       │   │   ├── syscall_linux_gccgo_386.go
    │       │   │   ├── syscall_linux_gccgo_arm.go
    │       │   │   ├── syscall_linux_loong64.go
    │       │   │   ├── syscall_linux_mips64x.go
    │       │   │   ├── syscall_linux_mipsx.go
    │       │   │   ├── syscall_linux_ppc.go
    │       │   │   ├── syscall_linux_ppc64x.go
    │       │   │   ├── syscall_linux_riscv64.go
    │       │   │   ├── syscall_linux_s390x.go
    │       │   │   ├── syscall_linux_sparc64.go
    │       │   │   ├── syscall_netbsd.go
    │       │   │   ├── syscall_netbsd_386.go
    │       │   │   ├── syscall_netbsd_amd64.go
    │       │   │   ├── syscall_netbsd_arm.go
    │       │   │   ├── syscall_netbsd_arm64.go
    │       │   │   ├── syscall_openbsd.go
    │       │   │   ├── syscall_openbsd_386.go
    │       │   │   ├── syscall_openbsd_amd64.go
    │       │   │   ├── syscall_openbsd_arm.go
    │       │   │   ├── syscall_openbsd_arm64.go
    │       │   │   ├── syscall_openbsd_libc.go
    │       │   │   ├── syscall_openbsd_mips64.go
    │       │   │   ├── syscall_openbsd_ppc64.go
    │       │   │   ├── syscall_openbsd_riscv64.go
    │       │   │   ├── syscall_solaris.go
    │       │   │   ├── syscall_solaris_amd64.go
    │       │   │   ├── syscall_unix.go
    │       │   │   ├── syscall_unix_gc.go
    │       │   │   ├── syscall_unix_gc_ppc64x.go
    │       │   │   ├── syscall_zos_s390x.go
    │       │   │   ├── sysvshm_linux.go
    │       │   │   ├── sysvshm_unix.go
    │       │   │   ├── sysvshm_unix_other.go
    │       │   │   ├── timestruct.go
    │       │   │   ├── unveil_openbsd.go
    │       │   │   ├── xattr_bsd.go
    │       │   │   ├── zerrors_aix_ppc.go
    │       │   │   ├── zerrors_aix_ppc64.go
    │       │   │   ├── zerrors_darwin_amd64.go
    │       │   │   ├── zerrors_darwin_arm64.go
    │       │   │   ├── zerrors_dragonfly_amd64.go
    │       │   │   ├── zerrors_freebsd_386.go
    │       │   │   ├── zerrors_freebsd_amd64.go
    │       │   │   ├── zerrors_freebsd_arm.go
    │       │   │   ├── zerrors_freebsd_arm64.go
    │       │   │   ├── zerrors_freebsd_riscv64.go
    │       │   │   ├── zerrors_linux.go
    │       │   │   ├── zerrors_linux_386.go
    │       │   │   ├── zerrors_linux_amd64.go
    │       │   │   ├── zerrors_linux_arm.go
    │       │   │   ├── zerrors_linux_arm64.go
    │       │   │   ├── zerrors_linux_loong64.go
    │       │   │   ├── zerrors_linux_mips.go
    │       │   │   ├── zerrors_linux_mips64.go
    │       │   │   ├── zerrors_linux_mips64le.go
    │       │   │   ├── zerrors_linux_mipsle.go
    │       │   │   ├── zerrors_linux_ppc.go
    │       │   │   ├── zerrors_linux_ppc64.go
    │       │   │   ├── zerrors_linux_ppc64le.go
    │       │   │   ├── zerrors_linux_riscv64.go
    │       │   │   ├── zerrors_linux_s390x.go
    │       │   │   ├── zerrors_linux_sparc64.go
    │       │   │   ├── zerrors_netbsd_386.go
    │       │   │   ├── zerrors_netbsd_amd64.go
    │       │   │   ├── zerrors_netbsd_arm.go
    │       │   │   ├── zerrors_netbsd_arm64.go
    │       │   │   ├── zerrors_openbsd_386.go
    │       │   │   ├── zerrors_openbsd_amd64.go
    │       │   │   ├── zerrors_openbsd_arm.go
    │       │   │   ├── zerrors_openbsd_arm64.go
    │       │   │   ├── zerrors_openbsd_mips64.go
    │       │   │   ├── zerrors_openbsd_ppc64.go
    │       │   │   ├── zerrors_openbsd_riscv64.go
    │       │   │   ├── zerrors_solaris_amd64.go
    │       │   │   ├── zerrors_zos_s390x.go
    │       │   │   ├── zptrace_armnn_linux.go
    │       │   │   ├── zptrace_linux_arm64.go
    │       │   │   ├── zptrace_mipsnn_linux.go
    │       │   │   ├── zptrace_mipsnnle_linux.go
    │       │   │   ├── zptrace_x86_linux.go
    │       │   │   ├── zsyscall_aix_ppc.go
    │       │   │   ├── zsyscall_aix_ppc64.go
    │       │   │   ├── zsyscall_aix_ppc64_gc.go
    │       │   │   ├── zsyscall_aix_ppc64_gccgo.go
    │       │   │   ├── zsyscall_darwin_amd64.go
    │       │   │   ├── zsyscall_darwin_amd64.s
    │       │   │   ├── zsyscall_darwin_arm64.go
    │       │   │   ├── zsyscall_darwin_arm64.s
    │       │   │   ├── zsyscall_dragonfly_amd64.go
    │       │   │   ├── zsyscall_freebsd_386.go
    │       │   │   ├── zsyscall_freebsd_amd64.go
    │       │   │   ├── zsyscall_freebsd_arm.go
    │       │   │   ├── zsyscall_freebsd_arm64.go
    │       │   │   ├── zsyscall_freebsd_riscv64.go
    │       │   │   ├── zsyscall_illumos_amd64.go
    │       │   │   ├── zsyscall_linux.go
    │       │   │   ├── zsyscall_linux_386.go
    │       │   │   ├── zsyscall_linux_amd64.go
    │       │   │   ├── zsyscall_linux_arm.go
    │       │   │   ├── zsyscall_linux_arm64.go
    │       │   │   ├── zsyscall_linux_loong64.go
    │       │   │   ├── zsyscall_linux_mips.go
    │       │   │   ├── zsyscall_linux_mips64.go
    │       │   │   ├── zsyscall_linux_mips64le.go
    │       │   │   ├── zsyscall_linux_mipsle.go
    │       │   │   ├── zsyscall_linux_ppc.go
    │       │   │   ├── zsyscall_linux_ppc64.go
    │       │   │   ├── zsyscall_linux_ppc64le.go
    │       │   │   ├── zsyscall_linux_riscv64.go
    │       │   │   ├── zsyscall_linux_s390x.go
    │       │   │   ├── zsyscall_linux_sparc64.go
    │       │   │   ├── zsyscall_netbsd_386.go
    │       │   │   ├── zsyscall_netbsd_amd64.go
    │       │   │   ├── zsyscall_netbsd_arm.go
    │       │   │   ├── zsyscall_netbsd_arm64.go
    │       │   │   ├── zsyscall_openbsd_386.go
    │       │   │   ├── zsyscall_openbsd_386.s
    │       │   │   ├── zsyscall_openbsd_amd64.go
    │       │   │   ├── zsyscall_openbsd_amd64.s
    │       │   │   ├── zsyscall_openbsd_arm.go
    │       │   │   ├── zsyscall_openbsd_arm.s
    │       │   │   ├── zsyscall_openbsd_arm64.go
    │       │   │   ├── zsyscall_openbsd_arm64.s
    │       │   │   ├── zsyscall_openbsd_mips64.go
    │       │   │   ├── zsyscall_openbsd_mips64.s
    │       │   │   ├── zsyscall_openbsd_ppc64.go
    │       │   │   ├── zsyscall_openbsd_ppc64.s
    │       │   │   ├── zsyscall_openbsd_riscv64.go
    │       │   │   ├── zsyscall_openbsd_riscv64.s
    │       │   │   ├── zsyscall_solaris_amd64.go
    │       │   │   ├── zsyscall_zos_s390x.go
    │       │   │   ├── zsysctl_openbsd_386.go
    │       │   │   ├── zsysctl_openbsd_amd64.go
    │       │   │   ├── zsysctl_openbsd_arm.go
    │       │   │   ├── zsysctl_openbsd_arm64.go
    │       │   │   ├── zsysctl_openbsd_mips64.go
    │       │   │   ├── zsysctl_openbsd_ppc64.go
    │       │   │   ├── zsysctl_openbsd_riscv64.go
    │       │   │   ├── zsysnum_darwin_amd64.go
    │       │   │   ├── zsysnum_darwin_arm64.go
    │       │   │   ├── zsysnum_dragonfly_amd64.go
    │       │   │   ├── zsysnum_freebsd_386.go
    │       │   │   ├── zsysnum_freebsd_amd64.go
    │       │   │   ├── zsysnum_freebsd_arm.go
    │       │   │   ├── zsysnum_freebsd_arm64.go
    │       │   │   ├── zsysnum_freebsd_riscv64.go
    │       │   │   ├── zsysnum_linux_386.go
    │       │   │   ├── zsysnum_linux_amd64.go
    │       │   │   ├── zsysnum_linux_arm.go
    │       │   │   ├── zsysnum_linux_arm64.go
    │       │   │   ├── zsysnum_linux_loong64.go
    │       │   │   ├── zsysnum_linux_mips.go
    │       │   │   ├── zsysnum_linux_mips64.go
    │       │   │   ├── zsysnum_linux_mips64le.go
    │       │   │   ├── zsysnum_linux_mipsle.go
    │       │   │   ├── zsysnum_linux_ppc.go
    │       │   │   ├── zsysnum_linux_ppc64.go
    │       │   │   ├── zsysnum_linux_ppc64le.go
    │       │   │   ├── zsysnum_linux_riscv64.go
    │       │   │   ├── zsysnum_linux_s390x.go
    │       │   │   ├── zsysnum_linux_sparc64.go
    │       │   │   ├── zsysnum_netbsd_386.go
    │       │   │   ├── zsysnum_netbsd_amd64.go
    │       │   │   ├── zsysnum_netbsd_arm.go
    │       │   │   ├── zsysnum_netbsd_arm64.go
    │       │   │   ├── zsysnum_openbsd_386.go
    │       │   │   ├── zsysnum_openbsd_amd64.go
    │       │   │   ├── zsysnum_openbsd_arm.go
    │       │   │   ├── zsysnum_openbsd_arm64.go
    │       │   │   ├── zsysnum_openbsd_mips64.go
    │       │   │   ├── zsysnum_openbsd_ppc64.go
    │       │   │   ├── zsysnum_openbsd_riscv64.go
    │       │   │   ├── zsysnum_zos_s390x.go
    │       │   │   ├── ztypes_aix_ppc.go
    │       │   │   ├── ztypes_aix_ppc64.go
    │       │   │   ├── ztypes_darwin_amd64.go
    │       │   │   ├── ztypes_darwin_arm64.go
    │       │   │   ├── ztypes_dragonfly_amd64.go
    │       │   │   ├── ztypes_freebsd_386.go
    │       │   │   ├── ztypes_freebsd_amd64.go
    │       │   │   ├── ztypes_freebsd_arm.go
    │       │   │   ├── ztypes_freebsd_arm64.go
    │       │   │   ├── ztypes_freebsd_riscv64.go
    │       │   │   ├── ztypes_linux.go
    │       │   │   ├── ztypes_linux_386.go
    │       │   │   ├── ztypes_linux_amd64.go
    │       │   │   ├── ztypes_linux_arm.go
    │       │   │   ├── ztypes_linux_arm64.go
    │       │   │   ├── ztypes_linux_loong64.go
    │       │   │   ├── ztypes_linux_mips.go
    │       │   │   ├── ztypes_linux_mips64.go
    │       │   │   ├── ztypes_linux_mips64le.go
    │       │   │   ├── ztypes_linux_mipsle.go
    │       │   │   ├── ztypes_linux_ppc.go
    │       │   │   ├── ztypes_linux_ppc64.go
    │       │   │   ├── ztypes_linux_ppc64le.go
    │       │   │   ├── ztypes_linux_riscv64.go
    │       │   │   ├── ztypes_linux_s390x.go
    │       │   │   ├── ztypes_linux_sparc64.go
    │       │   │   ├── ztypes_netbsd_386.go
    │       │   │   ├── ztypes_netbsd_amd64.go
    │       │   │   ├── ztypes_netbsd_arm.go
    │       │   │   ├── ztypes_netbsd_arm64.go
    │       │   │   ├── ztypes_openbsd_386.go
    │       │   │   ├── ztypes_openbsd_amd64.go
    │       │   │   ├── ztypes_openbsd_arm.go
    │       │   │   ├── ztypes_openbsd_arm64.go
    │       │   │   ├── ztypes_openbsd_mips64.go
    │       │   │   ├── ztypes_openbsd_ppc64.go
    │       │   │   ├── ztypes_openbsd_riscv64.go
    │       │   │   ├── ztypes_solaris_amd64.go
    │       │   │   └── ztypes_zos_s390x.go
    │       │   └── windows/
    │       │       ├── aliases.go
    │       │       ├── dll_windows.go
    │       │       ├── empty.s
    │       │       ├── env_windows.go
    │       │       ├── eventlog.go
    │       │       ├── exec_windows.go
    │       │       ├── memory_windows.go
    │       │       ├── mkerrors.bash
    │       │       ├── mkknownfolderids.bash
    │       │       ├── mksyscall.go
    │       │       ├── race.go
    │       │       ├── race0.go
    │       │       ├── security_windows.go
    │       │       ├── service.go
    │       │       ├── setupapi_windows.go
    │       │       ├── str.go
    │       │       ├── syscall.go
    │       │       ├── syscall_windows.go
    │       │       ├── types_windows.go
    │       │       ├── types_windows_386.go
    │       │       ├── types_windows_amd64.go
    │       │       ├── types_windows_arm.go
    │       │       ├── types_windows_arm64.go
    │       │       ├── zerrors_windows.go
    │       │       ├── zknownfolderids_windows.go
    │       │       └── zsyscall_windows.go
    │       └── text/
    │           ├── LICENSE
    │           ├── PATENTS
    │           ├── cases/
    │           │   ├── cases.go
    │           │   ├── context.go
    │           │   ├── fold.go
    │           │   ├── icu.go
    │           │   ├── info.go
    │           │   ├── map.go
    │           │   ├── tables10.0.0.go
    │           │   ├── tables11.0.0.go
    │           │   ├── tables12.0.0.go
    │           │   ├── tables13.0.0.go
    │           │   ├── tables9.0.0.go
    │           │   └── trieval.go
    │           ├── internal/
    │           │   ├── internal.go
    │           │   ├── language/
    │           │   │   ├── common.go
    │           │   │   ├── compact/
    │           │   │   │   ├── compact.go
    │           │   │   │   ├── language.go
    │           │   │   │   ├── parents.go
    │           │   │   │   ├── tables.go
    │           │   │   │   └── tags.go
    │           │   │   ├── compact.go
    │           │   │   ├── compose.go
    │           │   │   ├── coverage.go
    │           │   │   ├── language.go
    │           │   │   ├── lookup.go
    │           │   │   ├── match.go
    │           │   │   ├── parse.go
    │           │   │   ├── tables.go
    │           │   │   └── tags.go
    │           │   ├── match.go
    │           │   └── tag/
    │           │       └── tag.go
    │           ├── language/
    │           │   ├── coverage.go
    │           │   ├── doc.go
    │           │   ├── language.go
    │           │   ├── match.go
    │           │   ├── parse.go
    │           │   ├── tables.go
    │           │   └── tags.go
    │           ├── secure/
    │           │   └── bidirule/
    │           │       ├── bidirule.go
    │           │       ├── bidirule10.0.0.go
    │           │       └── bidirule9.0.0.go
    │           ├── transform/
    │           │   └── transform.go
    │           └── unicode/
    │               ├── bidi/
    │               │   ├── bidi.go
    │               │   ├── bracket.go
    │               │   ├── core.go
    │               │   ├── prop.go
    │               │   ├── tables10.0.0.go
    │               │   ├── tables11.0.0.go
    │               │   ├── tables12.0.0.go
    │               │   ├── tables13.0.0.go
    │               │   ├── tables9.0.0.go
    │               │   └── trieval.go
    │               └── norm/
    │                   ├── composition.go
    │                   ├── forminfo.go
    │                   ├── input.go
    │                   ├── iter.go
    │                   ├── normalize.go
    │                   ├── readwriter.go
    │                   ├── tables10.0.0.go
    │                   ├── tables11.0.0.go
    │                   ├── tables12.0.0.go
    │                   ├── tables13.0.0.go
    │                   ├── tables9.0.0.go
    │                   ├── transform.go
    │                   └── trie.go
    ├── google.golang.org/
    │   ├── genproto/
    │   │   ├── LICENSE
    │   │   └── googleapis/
    │   │       └── rpc/
    │   │           └── status/
    │   │               └── status.pb.go
    │   ├── grpc/
    │   │   ├── AUTHORS
    │   │   ├── CODE-OF-CONDUCT.md
    │   │   ├── CONTRIBUTING.md
    │   │   ├── GOVERNANCE.md
    │   │   ├── LICENSE
    │   │   ├── MAINTAINERS.md
    │   │   ├── Makefile
    │   │   ├── NOTICE.txt
    │   │   ├── README.md
    │   │   ├── SECURITY.md
    │   │   ├── attributes/
    │   │   │   └── attributes.go
    │   │   ├── backoff/
    │   │   │   └── backoff.go
    │   │   ├── backoff.go
    │   │   ├── balancer/
    │   │   │   ├── balancer.go
    │   │   │   ├── base/
    │   │   │   │   ├── balancer.go
    │   │   │   │   └── base.go
    │   │   │   ├── conn_state_evaluator.go
    │   │   │   ├── grpclb/
    │   │   │   │   └── state/
    │   │   │   │       └── state.go
    │   │   │   └── roundrobin/
    │   │   │       └── roundrobin.go
    │   │   ├── balancer_conn_wrappers.go
    │   │   ├── binarylog/
    │   │   │   └── grpc_binarylog_v1/
    │   │   │       └── binarylog.pb.go
    │   │   ├── call.go
    │   │   ├── channelz/
    │   │   │   └── channelz.go
    │   │   ├── clientconn.go
    │   │   ├── codec.go
    │   │   ├── codegen.sh
    │   │   ├── codes/
    │   │   │   ├── code_string.go
    │   │   │   └── codes.go
    │   │   ├── connectivity/
    │   │   │   └── connectivity.go
    │   │   ├── credentials/
    │   │   │   ├── credentials.go
    │   │   │   ├── insecure/
    │   │   │   │   └── insecure.go
    │   │   │   └── tls.go
    │   │   ├── dialoptions.go
    │   │   ├── doc.go
    │   │   ├── encoding/
    │   │   │   ├── encoding.go
    │   │   │   └── proto/
    │   │   │       └── proto.go
    │   │   ├── grpclog/
    │   │   │   ├── component.go
    │   │   │   ├── grpclog.go
    │   │   │   ├── logger.go
    │   │   │   └── loggerv2.go
    │   │   ├── interceptor.go
    │   │   ├── internal/
    │   │   │   ├── backoff/
    │   │   │   │   └── backoff.go
    │   │   │   ├── balancer/
    │   │   │   │   └── gracefulswitch/
    │   │   │   │       └── gracefulswitch.go
    │   │   │   ├── balancerload/
    │   │   │   │   └── load.go
    │   │   │   ├── binarylog/
    │   │   │   │   ├── binarylog.go
    │   │   │   │   ├── binarylog_testutil.go
    │   │   │   │   ├── env_config.go
    │   │   │   │   ├── method_logger.go
    │   │   │   │   └── sink.go
    │   │   │   ├── buffer/
    │   │   │   │   └── unbounded.go
    │   │   │   ├── channelz/
    │   │   │   │   ├── funcs.go
    │   │   │   │   ├── id.go
    │   │   │   │   ├── logging.go
    │   │   │   │   ├── types.go
    │   │   │   │   ├── types_linux.go
    │   │   │   │   ├── types_nonlinux.go
    │   │   │   │   ├── util_linux.go
    │   │   │   │   └── util_nonlinux.go
    │   │   │   ├── credentials/
    │   │   │   │   ├── credentials.go
    │   │   │   │   ├── spiffe.go
    │   │   │   │   ├── syscallconn.go
    │   │   │   │   └── util.go
    │   │   │   ├── envconfig/
    │   │   │   │   ├── envconfig.go
    │   │   │   │   ├── observability.go
    │   │   │   │   └── xds.go
    │   │   │   ├── grpclog/
    │   │   │   │   ├── grpclog.go
    │   │   │   │   └── prefixLogger.go
    │   │   │   ├── grpcrand/
    │   │   │   │   └── grpcrand.go
    │   │   │   ├── grpcsync/
    │   │   │   │   ├── event.go
    │   │   │   │   └── oncefunc.go
    │   │   │   ├── grpcutil/
    │   │   │   │   ├── compressor.go
    │   │   │   │   ├── encode_duration.go
    │   │   │   │   ├── grpcutil.go
    │   │   │   │   ├── metadata.go
    │   │   │   │   ├── method.go
    │   │   │   │   └── regex.go
    │   │   │   ├── internal.go
    │   │   │   ├── metadata/
    │   │   │   │   └── metadata.go
    │   │   │   ├── pretty/
    │   │   │   │   └── pretty.go
    │   │   │   ├── resolver/
    │   │   │   │   ├── config_selector.go
    │   │   │   │   ├── dns/
    │   │   │   │   │   └── dns_resolver.go
    │   │   │   │   ├── passthrough/
    │   │   │   │   │   └── passthrough.go
    │   │   │   │   └── unix/
    │   │   │   │       └── unix.go
    │   │   │   ├── serviceconfig/
    │   │   │   │   └── serviceconfig.go
    │   │   │   ├── status/
    │   │   │   │   └── status.go
    │   │   │   ├── syscall/
    │   │   │   │   ├── syscall_linux.go
    │   │   │   │   └── syscall_nonlinux.go
    │   │   │   ├── transport/
    │   │   │   │   ├── bdp_estimator.go
    │   │   │   │   ├── controlbuf.go
    │   │   │   │   ├── defaults.go
    │   │   │   │   ├── flowcontrol.go
    │   │   │   │   ├── handler_server.go
    │   │   │   │   ├── http2_client.go
    │   │   │   │   ├── http2_server.go
    │   │   │   │   ├── http_util.go
    │   │   │   │   ├── networktype/
    │   │   │   │   │   └── networktype.go
    │   │   │   │   ├── proxy.go
    │   │   │   │   └── transport.go
    │   │   │   └── xds_handshake_cluster.go
    │   │   ├── keepalive/
    │   │   │   └── keepalive.go
    │   │   ├── metadata/
    │   │   │   └── metadata.go
    │   │   ├── peer/
    │   │   │   └── peer.go
    │   │   ├── picker_wrapper.go
    │   │   ├── pickfirst.go
    │   │   ├── preloader.go
    │   │   ├── regenerate.sh
    │   │   ├── resolver/
    │   │   │   ├── map.go
    │   │   │   └── resolver.go
    │   │   ├── resolver_conn_wrapper.go
    │   │   ├── rpc_util.go
    │   │   ├── server.go
    │   │   ├── service_config.go
    │   │   ├── serviceconfig/
    │   │   │   └── serviceconfig.go
    │   │   ├── stats/
    │   │   │   ├── handlers.go
    │   │   │   └── stats.go
    │   │   ├── status/
    │   │   │   └── status.go
    │   │   ├── stream.go
    │   │   ├── tap/
    │   │   │   └── tap.go
    │   │   ├── trace.go
    │   │   ├── version.go
    │   │   └── vet.sh
    │   └── protobuf/
    │       ├── LICENSE
    │       ├── PATENTS
    │       ├── encoding/
    │       │   ├── protojson/
    │       │   │   ├── decode.go
    │       │   │   ├── doc.go
    │       │   │   ├── encode.go
    │       │   │   └── well_known_types.go
    │       │   ├── prototext/
    │       │   │   ├── decode.go
    │       │   │   ├── doc.go
    │       │   │   └── encode.go
    │       │   └── protowire/
    │       │       └── wire.go
    │       ├── internal/
    │       │   ├── descfmt/
    │       │   │   └── stringer.go
    │       │   ├── descopts/
    │       │   │   └── options.go
    │       │   ├── detrand/
    │       │   │   └── rand.go
    │       │   ├── encoding/
    │       │   │   ├── defval/
    │       │   │   │   └── default.go
    │       │   │   ├── json/
    │       │   │   │   ├── decode.go
    │       │   │   │   ├── decode_number.go
    │       │   │   │   ├── decode_string.go
    │       │   │   │   ├── decode_token.go
    │       │   │   │   └── encode.go
    │       │   │   ├── messageset/
    │       │   │   │   └── messageset.go
    │       │   │   ├── tag/
    │       │   │   │   └── tag.go
    │       │   │   └── text/
    │       │   │       ├── decode.go
    │       │   │       ├── decode_number.go
    │       │   │       ├── decode_string.go
    │       │   │       ├── decode_token.go
    │       │   │       ├── doc.go
    │       │   │       └── encode.go
    │       │   ├── errors/
    │       │   │   ├── errors.go
    │       │   │   ├── is_go112.go
    │       │   │   └── is_go113.go
    │       │   ├── filedesc/
    │       │   │   ├── build.go
    │       │   │   ├── desc.go
    │       │   │   ├── desc_init.go
    │       │   │   ├── desc_lazy.go
    │       │   │   ├── desc_list.go
    │       │   │   ├── desc_list_gen.go
    │       │   │   └── placeholder.go
    │       │   ├── filetype/
    │       │   │   └── build.go
    │       │   ├── flags/
    │       │   │   ├── flags.go
    │       │   │   ├── proto_legacy_disable.go
    │       │   │   └── proto_legacy_enable.go
    │       │   ├── genid/
    │       │   │   ├── any_gen.go
    │       │   │   ├── api_gen.go
    │       │   │   ├── descriptor_gen.go
    │       │   │   ├── doc.go
    │       │   │   ├── duration_gen.go
    │       │   │   ├── empty_gen.go
    │       │   │   ├── field_mask_gen.go
    │       │   │   ├── goname.go
    │       │   │   ├── map_entry.go
    │       │   │   ├── source_context_gen.go
    │       │   │   ├── struct_gen.go
    │       │   │   ├── timestamp_gen.go
    │       │   │   ├── type_gen.go
    │       │   │   ├── wrappers.go
    │       │   │   └── wrappers_gen.go
    │       │   ├── impl/
    │       │   │   ├── api_export.go
    │       │   │   ├── checkinit.go
    │       │   │   ├── codec_extension.go
    │       │   │   ├── codec_field.go
    │       │   │   ├── codec_gen.go
    │       │   │   ├── codec_map.go
    │       │   │   ├── codec_map_go111.go
    │       │   │   ├── codec_map_go112.go
    │       │   │   ├── codec_message.go
    │       │   │   ├── codec_messageset.go
    │       │   │   ├── codec_reflect.go
    │       │   │   ├── codec_tables.go
    │       │   │   ├── codec_unsafe.go
    │       │   │   ├── convert.go
    │       │   │   ├── convert_list.go
    │       │   │   ├── convert_map.go
    │       │   │   ├── decode.go
    │       │   │   ├── encode.go
    │       │   │   ├── enum.go
    │       │   │   ├── extension.go
    │       │   │   ├── legacy_enum.go
    │       │   │   ├── legacy_export.go
    │       │   │   ├── legacy_extension.go
    │       │   │   ├── legacy_file.go
    │       │   │   ├── legacy_message.go
    │       │   │   ├── merge.go
    │       │   │   ├── merge_gen.go
    │       │   │   ├── message.go
    │       │   │   ├── message_reflect.go
    │       │   │   ├── message_reflect_field.go
    │       │   │   ├── message_reflect_gen.go
    │       │   │   ├── pointer_reflect.go
    │       │   │   ├── pointer_unsafe.go
    │       │   │   ├── validate.go
    │       │   │   └── weak.go
    │       │   ├── order/
    │       │   │   ├── order.go
    │       │   │   └── range.go
    │       │   ├── pragma/
    │       │   │   └── pragma.go
    │       │   ├── set/
    │       │   │   └── ints.go
    │       │   ├── strs/
    │       │   │   ├── strings.go
    │       │   │   ├── strings_pure.go
    │       │   │   └── strings_unsafe.go
    │       │   └── version/
    │       │       └── version.go
    │       ├── proto/
    │       │   ├── checkinit.go
    │       │   ├── decode.go
    │       │   ├── decode_gen.go
    │       │   ├── doc.go
    │       │   ├── encode.go
    │       │   ├── encode_gen.go
    │       │   ├── equal.go
    │       │   ├── extension.go
    │       │   ├── merge.go
    │       │   ├── messageset.go
    │       │   ├── proto.go
    │       │   ├── proto_methods.go
    │       │   ├── proto_reflect.go
    │       │   ├── reset.go
    │       │   ├── size.go
    │       │   ├── size_gen.go
    │       │   └── wrappers.go
    │       ├── reflect/
    │       │   ├── protodesc/
    │       │   │   ├── desc.go
    │       │   │   ├── desc_init.go
    │       │   │   ├── desc_resolve.go
    │       │   │   ├── desc_validate.go
    │       │   │   └── proto.go
    │       │   ├── protoreflect/
    │       │   │   ├── methods.go
    │       │   │   ├── proto.go
    │       │   │   ├── source.go
    │       │   │   ├── source_gen.go
    │       │   │   ├── type.go
    │       │   │   ├── value.go
    │       │   │   ├── value_equal.go
    │       │   │   ├── value_pure.go
    │       │   │   ├── value_union.go
    │       │   │   └── value_unsafe.go
    │       │   └── protoregistry/
    │       │       └── registry.go
    │       ├── runtime/
    │       │   ├── protoiface/
    │       │   │   ├── legacy.go
    │       │   │   └── methods.go
    │       │   └── protoimpl/
    │       │       ├── impl.go
    │       │       └── version.go
    │       └── types/
    │           ├── descriptorpb/
    │           │   └── descriptor.pb.go
    │           └── known/
    │               ├── anypb/
    │               │   └── any.pb.go
    │               ├── durationpb/
    │               │   └── duration.pb.go
    │               └── timestamppb/
    │                   └── timestamp.pb.go
    ├── gopkg.in/
    │   └── yaml.v3/
    │       ├── LICENSE
    │       ├── NOTICE
    │       ├── README.md
    │       ├── apic.go
    │       ├── decode.go
    │       ├── emitterc.go
    │       ├── encode.go
    │       ├── parserc.go
    │       ├── readerc.go
    │       ├── resolve.go
    │       ├── scannerc.go
    │       ├── sorter.go
    │       ├── writerc.go
    │       ├── yaml.go
    │       ├── yamlh.go
    │       └── yamlprivateh.go
    ├── k8s.io/
    │   └── klog/
    │       └── v2/
    │           ├── .gitignore
    │           ├── CONTRIBUTING.md
    │           ├── LICENSE
    │           ├── OWNERS
    │           ├── README.md
    │           ├── RELEASE.md
    │           ├── SECURITY.md
    │           ├── SECURITY_CONTACTS
    │           ├── code-of-conduct.md
    │           ├── contextual.go
    │           ├── exit.go
    │           ├── imports.go
    │           ├── internal/
    │           │   ├── buffer/
    │           │   │   └── buffer.go
    │           │   ├── clock/
    │           │   │   ├── README.md
    │           │   │   └── clock.go
    │           │   ├── dbg/
    │           │   │   └── dbg.go
    │           │   ├── serialize/
    │           │   │   └── keyvalues.go
    │           │   └── severity/
    │           │       └── severity.go
    │           ├── k8s_references.go
    │           ├── klog.go
    │           ├── klog_file.go
    │           ├── klog_file_others.go
    │           ├── klog_file_windows.go
    │           └── klogr.go
    └── modules.txt

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
cmd/octorpki/cache


================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ master ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ master ]
  schedule:
    - cron: '25 17 * * 2'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'go' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
        # Learn more:
        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v1
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v1

    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v1


================================================
FILE: .github/workflows/go.yml
================================================
name: Go

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:

    - name: Set up Go 1.x
      uses: actions/setup-go@v2
      with:
        go-version: ^1.20

    - name: Check out code into the Go module directory
      uses: actions/checkout@v2
      with:
        fetch-depth: '0'

    - name: Test & Vet
      run: make test vet
      
    - name: Build
      run: |
        GOOS=linux make build-octorpki
        GOOS=darwin make build-octorpki
        GOOS=windows EXTENSION=.exe make build-octorpki
          
    - name: Install fpm
      run: |
        sudo apt-get update
        sudo apt-get install -y rpm ruby ruby-dev
        sudo gem install fpm
        
    - name: Package
      run: make package-deb-octorpki package-rpm-octorpki

    - name: Upload Artifact
      uses: actions/upload-artifact@v2
      with:
        name: dist
        path: dist/*
        retention-days: 14


================================================
FILE: .github/workflows/release.yml
================================================
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:

    - name: Set up Go 1.x
      uses: actions/setup-go@v2
      with:
        go-version: ^1.14

    - name: Check out code into the Go module directory
      uses: actions/checkout@v2
      with:
        fetch-depth: '0'

    - name: Set env
      run: echo "OCTORPKI_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV

    - name: Build
      run: |
        GOOS=linux make build-octorpki
        GOOS=darwin make build-octorpki
        GOOS=windows EXTENSION=.exe make build-octorpki
          
    - name: Install fpm
      run: |
        sudo apt-get update
        sudo apt-get install -y rpm ruby ruby-dev
        sudo gem install fpm
        
    - name: Package
      run: make package-deb-octorpki package-rpm-octorpki

    - name: Create Release
      id: create_release
      uses: actions/create-release@v1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        tag_name: ${{ github.ref }}
        release_name: Release ${{ github.ref }}
        draft: false
        prerelease: false
        
    - name: Upload Release Asset
      uses: actions/github-script@v2
      with:
        github-token: ${{secrets.GITHUB_TOKEN}}
        script: |
          const fs = require('fs').promises;
          const upload_url = '${{ steps.create_release.outputs.upload_url }}';
          for (let file of await fs.readdir('./dist')) {
            console.log('uploading', file);
            await github.repos.uploadReleaseAsset({
              url: upload_url,
              name: file,
              data: await fs.readFile(`./dist/${file}`)
            }); 
          }
 


================================================
FILE: .gitignore
================================================
cmd/**/cache/*
cmd/**/*.pem


================================================
FILE: Dockerfile
================================================
ARG src_dir="/octorpki"

FROM golang:alpine as builder
ARG src_dir
ARG LDFLAGS=""

RUN apk --update --no-cache add git && \
    mkdir -p ${src_dir}

WORKDIR ${src_dir}
COPY . .

RUN go build -o octorpki -ldflags "${LDFLAGS}" cmd/octorpki/*.go

FROM alpine:latest
ARG src_dir

RUN apk --update --no-cache add ca-certificates rsync && \
    adduser -S -D -H -h / rpki && \
    mkdir /cache && chmod 770 /cache && chown rpki:root /cache && \
    touch rrdp.json && chown rpki rrdp.json
USER rpki

COPY --from=builder ${src_dir}/octorpki ${src_dir}/cmd/octorpki/private.pem /
COPY --from=builder ${src_dir}/cmd/octorpki/tals /tals

VOLUME ["/cache"]

ENTRYPOINT ["./octorpki"]


================================================
FILE: Dockerfile.prod
================================================
ARG src_uri=github.com/cloudflare/cfrpki/cmd/octorpki

FROM golang:alpine as builder
ARG src_uri

RUN apk --update --no-cache add git && \
    go get -u $src_uri

FROM alpine:latest
ARG src_uri

RUN apk --update --no-cache add ca-certificates rsync && \
    adduser -S -D -H -h / rpki && \
    mkdir /cache && chmod 770 /cache && chown rpki:root /cache && \
    touch rrdp.json && chown rpki rrdp.json
USER rpki

COPY --from=builder /go/bin/octorpki /
COPY cmd/octorpki/private.pem /
COPY cmd/octorpki/tals /tals

VOLUME ["/cache"]

ENTRYPOINT ["./octorpki"]


================================================
FILE: LICENSE
================================================
Copyright (c) 2019, Cloudflare. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: Makefile
================================================
EXTENSION ?= 
DIST_DIR ?= dist/
GOOS ?= linux
ARCH ?= $(shell uname -m)
BUILDINFOSDET ?= 

DOCKER_REPO   := cloudflare/
OCTORPKI_NAME    := octorpki
OCTORPKI_VERSION ?= $(shell git describe)
VERSION_PKG   := $(shell echo $(OCTORPKI_VERSION) | sed 's/^v//g')
ARCH          := x86_64
LICENSE       := BSD-3
URL           := https://github.com/cloudflare/octorpki
DESCRIPTION   := OctoRPKI: a RPKI validator
BUILDINFOS    :=  ($(shell date +%FT%T%z)$(BUILDINFOSDET))
LDFLAGS       := '-X main.version=$(OCTORPKI_VERSION) -X main.buildinfos=$(BUILDINFOS)'

OUTPUT_OCTORPKI := $(DIST_DIR)octorpki-$(OCTORPKI_VERSION)-$(GOOS)-$(ARCH)$(EXTENSION)

.PHONY: vet
vet:
	go vet -v ./...

.PHONY: test
test:
	go test -v ./...

.PHONY: prepare
prepare:
	mkdir -p $(DIST_DIR)

.PHONY: clean
clean:
	rm -rf $(DIST_DIR)

.PHONY: build-octorpki
build-octorpki: prepare
	go build -ldflags $(LDFLAGS) -o $(OUTPUT_OCTORPKI) cmd/octorpki/*.go

.PHONY: docker-octorpki
docker-octorpki:
	docker build -t $(DOCKER_REPO)$(OCTORPKI_NAME):$(OCTORPKI_VERSION) --build-arg LDFLAGS=$(LDFLAGS) -f Dockerfile .

.PHONY: package-deb-octorpki
package-deb-octorpki: prepare
	fpm -s dir -t deb -n $(OCTORPKI_NAME) -v $(VERSION_PKG) \
        --description "$(DESCRIPTION)"  \
        --after-install package/after-install-octorpki.sh \
        --before-remove package/before-remove-octorpki.sh \
        --url "$(URL)" \
        --architecture $(ARCH) \
        --license "$(LICENSE)" \
        --package $(DIST_DIR) \
        $(OUTPUT_OCTORPKI)=/usr/bin/octorpki \
        package/octorpki.service=/lib/systemd/system/octorpki.service \
        package/octorpki.env=/etc/default/octorpki \
        cmd/octorpki/tals/afrinic.tal=/usr/share/octorpki/tals/afrinic.tal \
        cmd/octorpki/tals/apnic.tal=/usr/share/octorpki/tals/apnic.tal \
        cmd/octorpki/tals/lacnic.tal=/usr/share/octorpki/tals/lacnic.tal \
        cmd/octorpki/tals/ripe.tal=/usr/share/octorpki/tals/ripe.tal

.PHONY: package-rpm-octorpki
package-rpm-octorpki: prepare
	fpm -s dir -t rpm -n $(OCTORPKI_NAME) -v $(VERSION_PKG) \
        --description "$(DESCRIPTION)" \
        --after-install package/after-install-octorpki.sh \
        --before-remove package/before-remove-octorpki.sh \
        --url "$(URL)" \
        --architecture $(ARCH) \
        --license "$(LICENSE) "\
        --package $(DIST_DIR) \
        $(OUTPUT_OCTORPKI)=/usr/bin/octorpki \
        package/octorpki.service=/lib/systemd/system/octorpki.service \
        package/octorpki.env=/etc/default/octorpki \
        cmd/octorpki/tals/afrinic.tal=/usr/share/octorpki/tals/afrinic.tal \
        cmd/octorpki/tals/apnic.tal=/usr/share/octorpki/tals/apnic.tal \
        cmd/octorpki/tals/lacnic.tal=/usr/share/octorpki/tals/lacnic.tal \
        cmd/octorpki/tals/ripe.tal=/usr/share/octorpki/tals/ripe.tal

================================================
FILE: Monitoring.md
================================================
# Monitoring

The most requested feature is visibility into the validation data.
This document covers basic monitoring and health of the toolings
(OctoRPKI and GoRTR) but also advanced features like distributed tracing
and extended logging systems.

While all the tools are optional, we recommend to setup mininmal
monitoring with Prometheus.
The sections below will go from a simple general use-case to
more specific, development-centric data.

You can usually find the tools listed here in use inside many tech companies.
While it may feel superfluous and complex to set them up _just_
for the use of RPKI, it may be fruitful to reach out to development-focused
teams and use previously installed software.

A quick note on the Cloudflare RPKI Dashboard and API as it also
fits in the *monitoring* part of RPKI.
A custom version of OctoRPKI is providing the data behind
[rpki.cloudflare.com](https://rpki.cloudflare.com) and its GraphQL API.
It includes fingerprints, file-specific information, historical data
and also validation status of the BGP data collected.
Unfortunately, the setup is too specific to Cloudflare to be made open-source.
Work is being done in that direction to provide a limited feature-set plug and play
dashboard. A section will be added later on.

## Play with docker-compose

In the `compose` folder, there is a configuration file that can be used
to start a RPKI validation environment with monitoring.
Make sure [docker](https://docs.docker.com/get-docker/) and 
[docker-compose](https://docs.docker.com/compose/install/) are installed on your machine.

This should provide an effortless demo of all the pieces fitting together:
- 2 GoRTR (one connected to the local OctoRPKI)
- 1 OctoRPKI
- 1 Prometheus
- 1 Grafana (provisions RPKI dashboard)
- 1 Jaeger

You can start with `docker-compose up`.
The Grafana is available on http://localhost:3000 (user/pass: admin/admin).
Jaeger interface is on http://localhost:16686.
You can connect RTR clients to localhost:8282 and localhost:8283.

## Graphs with Prometheus and Grafana

[Prometheus](https://prometheus.io/docs/introduction/overview/#what-is-prometheus) is an
open-source monitoring and alerting system widely used in the devops community.

Its configuration file indicates HTTP endpoints that Prometheus will scrape on a periodic
basis.

Both OctoRPKI and GoRTR have Prometheus-scrappable endpoints.
If you are running them on your local machine:
* GoRTR http://localhost:8080/metrics
* OctoRPKI http://localhost:8081/metrics

If you look at the data returned, you can find metrics like:
```
rpki_roas{filtered="filtered",ip_version="ipv4",path="https://rpki.cloudflare.com/rpki.json"} 132204
rpki_roas{filtered="filtered",ip_version="ipv6",path="https://rpki.cloudflare.com/rpki.json"} 21923
```

The metric name is `rpki_roas`, the labels are `filtered,ip_version,path` and the value is the last number.
Once Prometheus has scraped it, it's inserted in its database timestampped with the query time.

You can access the data from Grafana using the Prometheus data source.
Grafana is an open-source visualization and analytics software.
The pre-made [dashboard 12501](https://grafana.com/grafana/dashboards/12501)
can be imported and used .

<p align="center">
  <img src="resources/monitoring_grafana.png" alt="OctoRPKI Grafana Dashboard" width="600px"/>
</p>

## Error logging with Sentry

[Sentry](https://sentry.io/) is an open-source application that provides
a error and events monitoring. It is also available as a cloud-service.

The advantage of this tool is to provide an interface and search engine for logs.
Stacktrace, URIs or even tags can be used to enrich log events and help sorting and grouping.
It is more flexible than exploring console stdout/stderr messages.
This was shown to be particularly useful when investigating a cryptographically invalid resource
and troubleshoot reachability issues.

It requires Sentry-specific software code in order to provide more information.
OctoRPKI is compatible and uses the official library that wrap the errors.
When a validation error happens, information like file path and certificate key id are
added to the log before being sent to Sentry.

By passing the environment variable `SENTRY_DSN=https://<key>@<organization>.<server>/<project>`,
or the CLI argument `-sentry.dsn https://...` OctoRPKI will connect to the Sentry instance and send its messages.
It alsos include validation failures and fetching informmation (RRDP, rsync).

<p align="center">
  <img src="resources/monitoring_sentry_1.png" alt="OctoRPKI Sentry Dashboard Events List" width="600px"/>
</p>

<p align="center">
  <img src="resources/monitoring_sentry_2.png" alt="OctoRPKI Sentry Dashboard Detail Page" width="600px"/>
</p>

If you are new to Sentry, to get started, you can setup
[sentry/onpremise](https://github.com/getsentry/onpremise),
which uses docker-compose.

Another solution is to create a account on [sentry.io](https://sentry.io/pricing/).
The free/developer account should allow you to run a validator
within the quotas.

Proceed by creating a Project and obtain DSN to pass to the application.
You can use it with the docker-compose provided:
`SENTRY_DSN=https://... docker-compose up`.

## Distributed tracing with Jaeger

[Distributed tracing](https://opentracing.io/docs/overview/what-is-tracing/)
allows visualization of events with relational graphs and waterfal charts.
It is heavily used for microservices and complex distributed environments.
While a RPKI validator is a monolithic application, it fetches data from
many endpoints. Timing visualizations can help discovering issues
and possible optimizations.

The tracer front-end and library used in this project is
[Jaeger](https://www.jaegertracing.io/), an application developed by Uber.

To enable tracing, pass the flag `-trace=true` to enable Jaeger tracing.
The following [environment variables](https://github.com/jaegertracing/jaeger-client-go#environment-variables)
are required:
- `JAEGER_ENDPOINT=http://jaeger:14268/api/traces`
- `JAEGER_SERVICE_NAME=octorpki`
- `JAEGER_SAMPLER_TYPE=const`
- `JAEGER_SAMPLER_PARAM=1`
- `JAEGER_REPORTER_LOG_SPANS=true`

Once you connect to the dashboard, you will be able to see the status of the validation
and steps/iterations with errors.

<p align="center">
  <img src="resources/monitoring_tracing.png" alt="OctoRPKI Jaeger Distributed Tracing" width="600px"/>
</p>

_Please note that some installations may use a specific flavor of open-tracing (eg: different protocols).
Some code changes may be required in order to be made compatible. This is unfortunately not possible
with configuration flags._

## Profiling usage with Pprof

This last part is more focused on the software development than proper operational
monitoring. It can be helpful identifying an issue with the code.

Profiling gives information about resource usage per function calls.

To enable profiling, pass the CLI argument `-pprof=true`.
OctoRPKI web interface will now provide new information on http://localhost:8081/debug/pprof/.

Use `go tool pprof` to connect remotely and open a web interface with charts

```bash
$ go tool pprof -http :8084 http://localhost:8081/debug/pprof/profile
```

<p align="center">
  <img src="resources/monitoring_pprof_1.png" alt="OctoRPKI Pprof Heap Memory Graph" width="600px"/>
</p>
<p align="center">
  <img src="resources/monitoring_pprof_2.png" alt="OctoRPKI Pprof CPU Flame Graph" width="600px"/>
</p>

================================================
FILE: README.md
================================================
# Cloudflare RPKI Validator Tools and Libraries

## DEPRECATION NOTICE
**This software is no longer maintained. We advise replacing your production use of this software with the swap-in replacement [rpki-client](https://rpki-client.org/)**

[![Build Status](https://github.com/cloudflare/cfrpki/workflows/Go/badge.svg)](https://github.com/cloudflare/cfrpki/actions?query=workflow%3AGo)

<img align="left" src="resources/octorpki.png" alt="Cloudflare OctoRPKI logo">

_cfrpki_ is a collection of tools and libraries to perform RPKI relying party software
operations.

This is the home of the **OctoRPKI validator**.

To get started with Cloudflare's Relying Party software, go to the section **[OctoRPKI](#octorpki)** 🐙.

<br>

## Disclaimer

_This software comes with no warranties._

## Getting started

### Introduction

A RPKI validator performs cryptographic validation on the RPKI data provided
by the Regional Internet Registries (RIR).
Every network can verify that the routing information data (prefixes and ASN)
was not tampered with.

Cloudflare develops and uses OctoRPKI. It is the data provider behind
<https://rpki.cloudflare.com/> (including the [rpki.json](https://rpki.cloudflare.com/rpki.json)).
It is also used in production by multiple networks.

<p align="center">
  <a href="https://rpki.cloudflare.com/?view=bgp&prefix=1.1.1.0%2F24">
    <img src="resources/rpki_dashboard.png" alt="Cloudflare RPKI Dashboard" width="600px">
  </a>
</p>

### OctoRPKI

OctoRPKI requires bootstrap file in order to fetch the RPKI data.
The Trust Anchor Location (TAL) indicates endpoints (rsync/https) hosted
by Internet Resources holders (IP addresses and ASN), the RIRs.
By default, ARIN, _Afrinic, APNIC, LACNIC and RIPE_ TALs are [shipped with this
software](https://github.com/cloudflare/cfrpki/tree/master/cmd/octorpki/tals).

This application periodically refreshes the data provided by the RIRs and the delegated organizations.
It keeps exploring the RPKI repositories until it reaches a stable state (no new endpoints added).
By default, when unstable, the server will return `503` in order to avoid distributing partial data.

The initial cold start require a few iterations which take 5 to 10 minutes (around 500MB are downloaded).
A refresh is much faster.

- Fetching root certificate listed in TAL
- Fetching repositories listed in the root certificates (RRDP and rsync)
- Fetching sub-repositories (National Internet Registries and delegated organizations)

Once it reaches a stable state, it generates a JSON list of Route Object Authorization (ROA).
A ROA associates an IP prefix with an ASN that is allowed to announce the route via BGP.
By default it is available on `http://localhost:8081/output.json`.
The current file size is around 20MB.

To use this tool with your network devices, you need to connect a RTR server
which will read the JSON.
It is officially supported by [GoRTR](https://github.com/cloudflare/gortr).

The list can be signed using ECDSA signatures to be redistributed more securely
(via a CDN or caches).

Metrics are provided on `/metrics` Prometheus endpoint.

To install the validator, you have multiple options:

- Fetch a binary/packages on the [Releases page](https://github.com/cloudflare/cfrpki/releases)
- Use Docker
- Compile it

#### Binaries/packages

First, go to the [Releases](https://github.com/cloudflare/cfrpki/releases) tab,
download the latest version matching your platform.

To install the Linux deb package and start it:

```bash
$ sudo dpkg -i octorpki_1.1.4_amd64.deb
$ sudo systemctl start octorpki
```

You can get the logs using:

```bash
$ sudo journalctl -fu octorpki
```

Please note the configuration parameters are in `/etc/default/octorpki`.
They match the CLI arguments (`$ octorpki -h` to list them).

For instance, if you want to change the port:

```bash
sudo echo OCTORPKI_ARGS=-http.addr :8081 | sudo tee /etc/default/octorpki
```

Do not forget to add the ARIN TAL: `/usr/share/octorpki/tals/arin.tal`

If you fetch a standalone binary (eg: `octorpki-v1.1.4-linux-x86_64`),
by default, it will fetch the TALs in `./tals` folder and use `./cache`
to store the RPKI repository data.
Make sure you download put all the TALs in the correct folder.

Once OctoRPKI completed its first validation, you can access the
ROAs list at the following address: <http://localhost:8081/output.json>.

By default, the validator is configured to sign the output.
We advise that you generate an ECDSA key. Follow the instructions in the
[GoRTR](#GoRTR) section.
You can disable the signature by passing `-output.sign=false` to the program.

#### Docker

OctoRPKI is available a docker container. Add the TAL files in the `tals/` folder.

```bash
$ mkdir tals && mkdir cache && touch cache/rrdp.json
$ chmod 770 -R tals && chmod 770 -R cache && chmod 770 cache/rrdp.json
$ docker run -ti --net=host -v $PWD/tals:/tals -v $PWD/cache:/cache -p 8081:8081 cloudflare/octorpki
```

Depending on your Docker configuration, you may need to specify `--net=host`
and set permissions for the files in order to avoid errors.

Using the default settings, you can access the generated ROAs list on
<http://localhost:8081/output.json>.

#### Compile

The source of OctoRPKI is in the folder `cmd/octorpki`.
Make sure you have the [Go toolkit installed](https://golang.org/doc/install).

You can then build using `go build`

```
$ cd cmd/octorpki && go build
```

The binary is now available in the same directory.

Have a look at the Makefile for more targets
to compile or generate a Docker image.

#### [GoRTR](https://github.com/cloudflare/gortr)

In order to send the computed list of ROAs to the router, the router must be
connected to a cache using RTR protocol.

OctoRPKI does not embed a RTR server. Since generating list of ROAs takes a lot of compute time,
it was designed separate the distribution of files from the cryptographic operations.

[GoRTR](https://github.com/cloudflare/gortr) was created by Cloudflare to use a list of ROAs
from either OctoRPKI or similar validators able to produce a JSON file.

To connect with GoRTR **securely**, you will need to setup a private key.

```bash
$ openssl ecparam -genkey -name prime256v1 -noout -outform pem > private.pem
```

You can force OctoRPKI to use the key by passing `-output.sign.key private.pem`.

Then extract the public key

```bash
$ openssl ec -in private.pem -pubout -outform pem > public.pem
```

If OctoRPKI is running locally using the default port and file (<http://localhost:8081/output.json>), you can connect GoRTR:

```bash
$ gortr -verify.key public.pem -cache http://localhost:8081/output.json
```

To disable signing, use the following flag on OctoRPKI `-output.sign=false` and `-verify=false` on GoRTR.

The [repository's page](https://github.com/cloudflare/gortr) gives more details on how to configure network devices to use GoRTR.

## Monitor

Check [Monitoring.md](Monitoring.md) page to see how you can setup dashboards, distributed tracing and error logging.

## Develop

### Libraries

`ov` origin validation library. You can pass prefixes and it will match against ROAs.

`sync/lib` can synchronize RRDP and rsync repositories.

`validator/pki` maintains a certificate store and performs validation.

`validator/lib` decode and encode RPKI resources.

### Applications

`cmd/localrpki` performs validation against locally stored files
and generate a JSON prefix list.

`cmd/ctrpki` performs simple validation against files and send them
to a [Certificate Transparency Log](https://ct.cloudflare.com/logs/cirrus).

`cmd/octorpki` complete validator software, with RRDP and rsync.
See the section below for more information.


================================================
FILE: api/schemas/schemas.go
================================================
package schemas

type OutputROA struct {
	Prefix    string `json:"prefix"`
	MaxLength int    `json:"max-length"`
}

type OutputASN struct {
	ASN     uint32   `json:"asn,omitempty"`
	Range   []uint32 `json:"asn-range,omitempty"`
	Inherit bool     `json:"inherit,omitempty"`
}

type OutputIP struct {
	Prefix  string   `json:"prefix,omitempty"`
	Range   []string `json:"ip-range,omitempty"`
	Inherit int      `json:"inherit,omitempty"`
}

// Generating rest of data
type OutputRes struct {
	Type           string `json:"type"`
	Name           string `json:"name,omitempty"`
	SubjectKeyId   string `json:"subject-key-id,omitempty"`
	AuthorityKeyId string `json:"authority-key-id,omitempty"`
	Path           string `json:"path"`

	Hash string `json:"hash"`

	TA string `json:"ta"`

	SIAs      []string     `json:"sia,omitempty"`
	IPs       []*OutputIP  `json:"ips,omitempty"`
	ASNs      []*OutputASN `json:"asns,omitempty"`
	ROAs      []*OutputROA `json:"roas,omitempty"`
	ASN       uint32       `json:"asn,omitempty"`
	Emitted   int          `json:"emitted,omitempty"`
	ValidFrom int          `json:"validfrom,omitempty"`
	ValidTo   int          `json:"validto,omitempty"`
	Serial    string       `json:"serial,omitempty"`

	FileList       []string `json:"mft-files,omitempty"`
	ManifestNumber string   `json:"mft-number,omitempty"`
	ThisUpdate     int      `json:"mft-thisupdate,omitempty"`
	NextUpdate     int      `json:"mft-nextupdate,omitempty"`

	State   int `json:"state,omitempty"`
	Visible int `json:"visible,omitempty"`
}

type ResourcesJSON struct {
	Metadata struct {
		Generated int `json:"generated"`
	} `json:"metadata"`
	Resources []*OutputRes `json:"resources"`
}


================================================
FILE: ca/xml.go
================================================
package ca

import (
	"bytes"
	"encoding/xml"
	"io"
)

const (
	XML_VERSION_RFC8181 = 4
	XML_VERSION_RFC8183 = 1
)

type XMLMessage struct {
	XMLName xml.Name `xml:"http://www.hactrn.net/uris/rpki/publication-spec/ msg"`
	Version int      `xml:"version,attr"`
	Type    string   `xml:"type,attr"`
	Inner   string   `xml:",innerxml"`
}

type XMLMessageChildRequest struct {
	XMLName     xml.Name `xml:"http://www.hactrn.net/uris/rpki/rpki-setup/ child_request"`
	Version     int      `xml:"version,attr"`
	ChildHandle string   `xml:"child_handle,attr"`
	Tag         string   `xml:"tag,attr"`
	Inner       string   `xml:",innerxml"`
}

type XMLMessageParentResponse struct {
	XMLName      xml.Name `xml:"http://www.hactrn.net/uris/rpki/rpki-setup/ parent_response"`
	Version      int      `xml:"version,attr"`
	Tag          string   `xml:"tag,attr"`
	ServiceURI   string   `xml:"service_uri,attr"`
	ChildHandle  string   `xml:"child_handle,attr"`
	ParentHandle string   `xml:"parent_handle,attr"`
	Inner        string   `xml:",innerxml"`
}

type XMLMessagePublisherRequest struct {
	XMLName         xml.Name `xml:"http://www.hactrn.net/uris/rpki/rpki-setup/ publisher_request"`
	Version         int      `xml:"version,attr"`
	Tag             string   `xml:"tag,attr"`
	PublisherHandle string   `xml:"publisher_handle,attr"`
	Inner           string   `xml:",innerxml"`
}

type XMLMessageRepositoryResponse struct {
	XMLName             xml.Name `xml:"http://www.hactrn.net/uris/rpki/rpki-setup/ repository_response"`
	Version             int      `xml:"version,attr"`
	Tag                 string   `xml:"tag,attr"`
	ServiceURI          string   `xml:"service_uri,attr"`
	SIABase             string   `xml:"sia_base,attr"`
	RRDPNotificationURI string   `xml:"rrdp_notification_uri,attr"`
	PublisherHandle     string   `xml:"publisher_handle,attr"`
	Inner               string   `xml:",innerxml"`
}

func NewXMLList() *XMLMessage {
	return &XMLMessage{
		Version: XML_VERSION_RFC8181,
		Type:    "query",
		Inner:   "<list/>",
	}
}

type Content struct {
	XMLName   xml.Name
	Hash      string `xml:"hash,attr"`
	ErrorCode string `xml:"error_code,attr"`
	Tag       string `xml:"tag,attr"`
	URI       string `xml:"uri,attr"`
	Inner     string `xml:",innerxml"`
}

func DecodeInner(inner []byte) ([]Content, error) {
	var innerContent []Content
	var err error
	if len(inner) > 0 {
		buf := bytes.NewBuffer(inner)
		dec := xml.NewDecoder(buf)
		for err == nil {
			err = dec.Decode(&innerContent)
		}
		if err == io.EOF {
			err = nil
		}
	}
	return innerContent, err
}

func DecodeXML(message []byte) (*XMLMessage, error) {
	var msg XMLMessage
	buf := bytes.NewBuffer(message)
	dec := xml.NewDecoder(buf)
	err := dec.Decode(&msg)
	return &msg, err
}

func DecodeXMLFull(message []byte) (*XMLMessage, []Content, error) {
	var msg XMLMessage
	buf := bytes.NewBuffer(message)
	dec := xml.NewDecoder(buf)
	err := dec.Decode(&msg)
	if err != nil {
		return nil, nil, err
	}
	innerContent, err := DecodeInner([]byte(msg.Inner))
	return &msg, innerContent, err
}

func DecodeXMLCRFull(message []byte) (*XMLMessageChildRequest, []Content, error) {
	var msg XMLMessageChildRequest
	buf := bytes.NewBuffer(message)
	dec := xml.NewDecoder(buf)
	err := dec.Decode(&msg)
	if err != nil {
		return nil, nil, err
	}
	innerContent, err := DecodeInner([]byte(msg.Inner))
	return &msg, innerContent, err
}

func DecodeXMLPRFull(message []byte) (*XMLMessageParentResponse, []Content, error) {
	var msg XMLMessageParentResponse
	buf := bytes.NewBuffer(message)
	dec := xml.NewDecoder(buf)
	err := dec.Decode(&msg)
	if err != nil {
		return nil, nil, err
	}
	innerContent, err := DecodeInner([]byte(msg.Inner))
	return &msg, innerContent, err
}


================================================
FILE: cmd/ctrpki/ctrpki.go
================================================
package main

import (
	"context"
	"encoding/hex"
	"flag"
	"net/http"
	"runtime"
	"strconv"
	"strings"
	"time"

	syncpki "github.com/cloudflare/cfrpki/sync/lib"
	librpki "github.com/cloudflare/cfrpki/validator/lib"
	"github.com/cloudflare/cfrpki/validator/pki"
	ct "github.com/google/certificate-transparency-go"
	"github.com/google/certificate-transparency-go/client"
	"github.com/google/certificate-transparency-go/jsonclient"
	log "github.com/sirupsen/logrus"
)

var (
	RootTAL                        = flag.String("tal.root", "tals/apnic.tal", "List of TAL separated by comma")
	MapDir                         = flag.String("map.dir", "rsync://rpki.ripe.net/repository/=./rpki.ripe.net/repository/", "Map of the paths separated by commas")
	UseManifest                    = flag.Bool("manifest.use", true, "Use manifests file to explore instead of going into the repository")
	ValidTime                      = flag.String("valid.time", "now", "Validation time (now/timestamp/RFC3339)")
	LogLevel                       = flag.String("loglevel", "info", "Log level")
	CertificateTransparency        = flag.String("ct", "https://ct.cloudflare.com/logs/cirrus", "Certificate Transparency Log address")
	CertificateTransparencyThreads = flag.Int("ct.threads", 50, "Number of threads to send to the CT Log")
)

func BatchCertificateTransparency(ctclient *client.LogClient, chain chan []ct.ASN1Cert, q chan bool) {
	log.Debugf("Starting BatchCertificateTransparency")
	for {
		select {
		case msg := <-chain:
			_, err := ctclient.AddChain(context.Background(), msg)
			if err != nil {
				log.Error(err)
			}
		case <-q:
			log.Debugf("Closing thread")
			return
		}
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Parse()
	lvl, _ := log.ParseLevel(*LogLevel)
	log.SetLevel(lvl)
	log.Infof("Validator started")

	mapDir := syncpki.ParseMapDirectory(*MapDir)

	s := syncpki.LocalFetch{
		MapDirectory: mapDir,
	}

	validator := pki.NewValidator()

	if *ValidTime == "now" {
		validator.Time = time.Now().UTC()
	} else if ts, err := strconv.ParseInt(*ValidTime, 10, 64); err == nil {
		vt := time.Unix(int64(ts), 0)
		log.Infof("Setting time to %v (timestamp)", vt)
		validator.Time = vt
	} else if vt, err := time.Parse(time.RFC3339, *ValidTime); err == nil {
		log.Infof("Setting time to %v (RFC3339)", vt)
		validator.Time = vt
	}

	ctclient, err := client.New(*CertificateTransparency, http.DefaultClient, jsonclient.Options{
		Logger:    log.StandardLogger(),
		UserAgent: "Cloudflare-RPKI-CT/1.0 (+https://github.com/cloudflare/cfrpki)",
	})
	if err != nil {
		log.Fatal(err)
	}

	threads := *CertificateTransparencyThreads

	qList := make([]chan bool, threads)
	dataChan := make(chan []ct.ASN1Cert, threads)
	if threads > 0 {
		for i := 0; i < threads; i++ {
			q := make(chan bool)
			qList[i] = q
			go BatchCertificateTransparency(ctclient, dataChan, q)
		}
	}

	defer func() {
		if threads > 0 {
			for i := 0; i < threads; i++ {
				qList[i] <- true
			}
		}
	}()

	rootTALs := strings.Split(*RootTAL, ",")
	ctData := make([][]*pki.PKIFile, 0)
	for _, tal := range rootTALs {
		manager := pki.NewSimpleManager()
		manager.Validator = validator
		manager.FileSeeker = &s
		manager.Log = log.StandardLogger()

		manager.AddInitial([]*pki.PKIFile{
			&pki.PKIFile{
				Path: tal,
				Type: pki.TYPE_TAL,
			},
		})

		manager.Explore(!*UseManifest, false)

		skiToAki := make(map[string]string)
		skiToPath := make(map[string]*pki.PKIFile)
		for _, obj := range manager.Validator.ValidObjects {
			res := obj.Resource.(*librpki.RPKICertificate)
			ski := hex.EncodeToString(res.Certificate.SubjectKeyId)
			aki := hex.EncodeToString(res.Certificate.AuthorityKeyId)
			skiToAki[ski] = aki
			skiToPath[ski] = obj.File
		}

		pathCT := make([][]*pki.PKIFile, 0)
		for ski, aki := range skiToAki {
			skiDone := make(map[string]bool)
			skiDone[ski] = true

			curAki := aki
			curPath := skiToPath[ski]
			curPathCT := make([]*pki.PKIFile, 1)
			curPathCT[0] = curPath

			var ok bool
			for curAki != "" && !ok {
				ok = skiDone[curAki]
				skiDone[curAki] = true

				curPath = skiToPath[curAki]
				if curAki != "" {
					curPathCT = append(curPathCT, curPath)
				}
				curAki = skiToAki[curAki]
			}
			pathCT = append(pathCT, curPathCT)
		}

		ctData = append(ctData, pathCT...)
	}

	log.Infof("Sending %v certificate chains to log %v using %v threads", len(ctData), *CertificateTransparency, *CertificateTransparencyThreads)
	var itera int
	for _, certs := range ctData {
		chain := make([]ct.ASN1Cert, 0)

		for _, cert := range certs {
			var dataBytes []byte
			data, err := s.GetFile(cert)
			if cert.Type == pki.TYPE_ROA || cert.Type == pki.TYPE_MFT {
				cms, err := librpki.DecodeCMS(data.Data)
				if err != nil {
					log.Error(err)
					continue
				}
				dataBytes = cms.SignedData.Certificates.Bytes
			} else {
				dataBytes = data.Data
			}

			if err != nil {
				log.Error(err)
				continue
			}
			chain = append(chain, ct.ASN1Cert{Data: dataBytes})
		}

		if threads > 0 {
			dataChan <- chain
		} else {
			_, err := ctclient.AddChain(context.Background(), chain)
			if err != nil {
				log.Error(err)
			}
		}
		itera++
		if len(ctData) >= 20 && itera%(len(ctData)/20) == 0 {
			log.Infof("Sent %v/%v (%v%%)", itera, len(ctData), itera*100/len(ctData))
		}
	}
}


================================================
FILE: cmd/localrpki/localrpki.go
================================================
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"os"
	"runtime"
	"strconv"
	"strings"
	"time"

	syncpki "github.com/cloudflare/cfrpki/sync/lib"
	librpki "github.com/cloudflare/cfrpki/validator/lib"
	"github.com/cloudflare/cfrpki/validator/pki"
	log "github.com/sirupsen/logrus"
)

var (
	RootTAL         = flag.String("tal.root", "tals/apnic.tal", "List of TAL separated by comma")
	MapDir          = flag.String("map.dir", "rsync://rpki.ripe.net/repository/=./rpki.ripe.net/repository/", "Map of the paths separated by commas")
	UseManifest     = flag.Bool("manifest.use", true, "Use manifests file to explore instead of going into the repository")
	StrictManifests = flag.Bool("strict.manifests", true, "Manifests must be complete or invalidate CA")
	StrictHash      = flag.Bool("strict.hash", true, "Check the hash of files")
	StrictCms       = flag.Bool("strict.cms", false, "Decode CMS with strict settings")
	ValidTime       = flag.String("valid.time", "now", "Validation time (now/timestamp/RFC3339)")
	LogLevel        = flag.String("loglevel", "info", "Log level")
	Output          = flag.String("output", "output.json", "Output file")
)

type OutputROA struct {
	ASN       string `json:"asn"`
	Prefix    string `json:"prefix"`
	MaxLength int    `json:"maxLength"`
	Path      string `json:"path"`
}

type OutputROAs struct {
	ROAs []OutputROA `json:"roas"`
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Parse()
	lvl, _ := log.ParseLevel(*LogLevel)
	log.SetLevel(lvl)
	log.Infof("Validator started")

	mapDir := syncpki.ParseMapDirectory(*MapDir)

	s := syncpki.LocalFetch{
		MapDirectory: mapDir,
	}

	var vt time.Time
	if *ValidTime == "now" {
		vt = time.Now().UTC()
	} else if ts, err := strconv.ParseInt(*ValidTime, 10, 64); err == nil {
		vt = time.Unix(int64(ts), 0)
		log.Infof("Setting time to %v (timestamp)", vt)
	} else if vttmp, err := time.Parse(time.RFC3339, *ValidTime); err == nil {
		vt = vttmp
		log.Infof("Setting time to %v (RFC3339)", vt)
	}

	rootTALs := strings.Split(*RootTAL, ",")
	ors := OutputROAs{
		ROAs: make([]OutputROA, 0),
	}
	for _, tal := range rootTALs {
		validator := pki.NewValidator()
		validator.Time = vt

		validator.DecoderConfig.ValidateStrict = *StrictCms

		manager := pki.NewSimpleManager()
		manager.Validator = validator
		manager.FileSeeker = &s
		manager.ReportErrors = true
		manager.Log = log.StandardLogger()
		manager.StrictHash = *StrictHash
		manager.StrictManifests = *StrictManifests

		go func(sm *pki.SimpleManager) {
			for err := range sm.Errors {
				log.Error(err)
			}
		}(manager)

		manager.AddInitial([]*pki.PKIFile{
			&pki.PKIFile{
				Path: tal,
				Type: pki.TYPE_TAL,
			},
		})

		manager.Explore(!*UseManifest, false)

		for _, roa := range manager.Validator.ValidROA {
			d := roa.Resource.(*librpki.RPKIROA)
			for _, entry := range d.Valids {
				oroa := OutputROA{
					ASN:       fmt.Sprintf("AS%v", d.ASN),
					Prefix:    entry.IPNet.String(),
					MaxLength: entry.MaxLength,
					Path:      manager.PathOfResource[roa].ComputePath(),
				}
				ors.ROAs = append(ors.ROAs, oroa)
			}
		}
	}

	var buf io.Writer
	var err error
	if *Output != "" {
		buf, err = os.Create(*Output)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		buf = os.Stdout
	}

	enc := json.NewEncoder(buf)
	enc.Encode(ors)
}


================================================
FILE: cmd/octorpki/ct.go
================================================
package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"net/http"
	"time"

	"github.com/cloudflare/cfrpki/validator/pki"
	"github.com/opentracing/opentracing-go"

	librpki "github.com/cloudflare/cfrpki/validator/lib"
	ct "github.com/google/certificate-transparency-go"
	log "github.com/sirupsen/logrus"
)

var (
	// Certificate Transparency
	CertTransparency        = flag.Bool("ct", false, "Enable Certificate Transparency")
	CertTransparencyAddr    = flag.String("ct.addr", "https://ct.cloudflare.com/logs/cirrus", "Path of CT")
	CertTransparencyThreads = flag.Int("ct.threads", 50, "Threads to send to CT")
	CertTransparencyTimeout = flag.Int("ct.timeout", 50, "CT timeout in seconds")
)

func SingleSendCertificateTransparency(httpclient *http.Client, path string, msg *ct.AddChainRequest) error {
	buf := bytes.NewBuffer([]byte{})
	enc := json.NewEncoder(buf)
	enc.Encode(msg)

	resp, err := httpclient.Post(fmt.Sprintf("%v/ct/v1/add-chain", path), "application/json", buf)
	if err == nil {
		respStr, _ := io.ReadAll(resp.Body)
		log.Debugf("Sent %v certs %v %v %v", len(msg.Chain), path, string(respStr), err)
	}

	return err
}

func BatchCertificateTransparency(httpclient *http.Client, path string, d chan *ct.AddChainRequest) {
	log.Debugf("Starting BatchCertificateTransparency")

	for msg := range d {
		err := SingleSendCertificateTransparency(httpclient, path, msg)
		if err != nil {
			log.Error(err)
		}
	}
}

func (s *OctoRPKI) SendCertificateTransparency(pSpan opentracing.Span, ctData [][]*pki.PKIFile, threads int, timeout int) {
	tracer := opentracing.GlobalTracer()
	span := tracer.StartSpan(
		"ct",
		opentracing.ChildOf(pSpan.Context()),
	)
	defer span.Finish()

	log.Infof("Sending Certificate Transparency (threads=%v)", threads)

	httpclient := &http.Client{
		Timeout: time.Duration(timeout) * time.Second,
	}

	dataChan := make(chan *ct.AddChainRequest)
	defer close(dataChan)

	for i := 0; i < threads; i++ {
		go BatchCertificateTransparency(httpclient, s.CTPath, dataChan)
	}

	var iterations int
	for _, certs := range ctData {
		chain := make([][]byte, 0)

		for _, cert := range certs {
			var dataBytes []byte
			data, err := s.Fetcher.GetFile(cert)
			if cert.Type == pki.TYPE_ROA || cert.Type == pki.TYPE_MFT {
				cms, err := librpki.DecodeCMS(data.Data)
				if err != nil {
					log.Error(err)
					continue
				}
				dataBytes = cms.SignedData.Certificates.Bytes
			} else {
				dataBytes = data.Data
			}

			if err != nil {
				log.Error(err)
				continue
			}

			chain = append(chain, dataBytes)
		}

		dataChan <- &ct.AddChainRequest{
			Chain: chain,
		}

		iterations++
		if len(ctData) > 0 && len(ctData) >= 20 && iterations%(len(ctData)/20) == 0 {
			log.Infof("Sent %v/%v (%v percent) certificates chains to CT %v", iterations, len(ctData), iterations*100/len(ctData), s.CTPath)
		}
	}

	log.Infof("Sent %v chains to Certificate Transparency %v", len(ctData), s.CTPath)
}


================================================
FILE: cmd/octorpki/filter.go
================================================
package main

import "github.com/cloudflare/gortr/prefixfile"

func FilterInvalidPrefixLen(roalist []prefixfile.ROAJson) []prefixfile.ROAJson {
	validROAs := make([]prefixfile.ROAJson, 0)
	for _, roa := range roalist {
		prefix := roa.GetPrefix()
		prefixLen, _ := prefix.Mask.Size()
		if prefix.IP.To4() != nil {
			if prefixLen <= 24 {
				validROAs = append(validROAs, roa)
			}

			continue
		}

		if prefixLen <= 48 {
			validROAs = append(validROAs, roa)
		}
	}

	return validROAs
}

func FilterDuplicates(roalist []prefixfile.ROAJson) []prefixfile.ROAJson {
	roalistNodup := make([]prefixfile.ROAJson, 0)
	existingsROAs := make(map[string]struct{})
	for _, roa := range roalist {
		k := roa.String()
		_, present := existingsROAs[k]
		if !present {
			roalistNodup = append(roalistNodup, roa)
			existingsROAs[k] = struct{}{}
		}
	}

	return roalistNodup
}


================================================
FILE: cmd/octorpki/filter_test.go
================================================
package main

import (
	"testing"

	"github.com/cloudflare/gortr/prefixfile"
	"github.com/stretchr/testify/assert"
)

func TestFilter(t *testing.T) {
	tests := []struct {
		name     string
		input    []prefixfile.ROAJson
		expected []prefixfile.ROAJson
	}{
		{
			name: "Invalid IPv4 prefix",
			input: []prefixfile.ROAJson{
				{
					Prefix: "1.1.1.0/25",
					ASN:    13335,
					Length: 32,
				},
			},
			expected: []prefixfile.ROAJson{},
		},
		{
			name: "Invalid IPv6 prefix",
			input: []prefixfile.ROAJson{
				{
					Prefix: "2001:db8::/64",
					ASN:    13335,
					Length: 128,
				},
			},
			expected: []prefixfile.ROAJson{},
		},
		{
			name: "All valid",
			input: []prefixfile.ROAJson{
				{
					Prefix: "2001:db8::/48",
					ASN:    13335,
					Length: 48,
				},
				{
					Prefix: "1.1.1.0/24",
					ASN:    13335,
					Length: 32,
				},
			},
			expected: []prefixfile.ROAJson{
				{
					Prefix: "2001:db8::/48",
					ASN:    13335,
					Length: 48,
				},
				{
					Prefix: "1.1.1.0/24",
					ASN:    13335,
					Length: 32,
				},
			},
		},
	}

	for _, test := range tests {
		res := FilterInvalidPrefixLen(test.input)
		assert.Equal(t, test.expected, res, test.name)
	}
}


================================================
FILE: cmd/octorpki/octorpki.go
================================================
package main

import (
	"context"
	"crypto/ecdsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/asn1"
	"encoding/hex"
	"encoding/json"
	"encoding/pem"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/pprof"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/cloudflare/cfrpki/api/schemas"
	"github.com/cloudflare/cfrpki/validator/pki"
	"github.com/cloudflare/gortr/prefixfile"
	"github.com/getsentry/sentry-go"
	"github.com/opentracing/opentracing-go"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/rs/cors"

	syncpki "github.com/cloudflare/cfrpki/sync/lib"
	librpki "github.com/cloudflare/cfrpki/validator/lib"
	log "github.com/sirupsen/logrus"
	jcfg "github.com/uber/jaeger-client-go/config"
)

var (
	version    = ""
	buildinfos = ""
	AppVersion = "OctoRPKI " + version + " " + buildinfos
	AllowRoot  = flag.Bool("allow.root", false, "Allow starting as root")

	// Validator Options
	RootTAL       = flag.String("tal.root", "tals/afrinic.tal,tals/apnic.tal,tals/arin.tal,tals/lacnic.tal,tals/ripe.tal", "List of TAL separated by comma")
	TALNames      = flag.String("tal.name", "AFRINIC,APNIC,ARIN,LACNIC,RIPE", "Name of the TALs")
	UseManifest   = flag.Bool("manifest.use", true, "Use manifests file to explore instead of going into the repository")
	Basepath      = flag.String("cache", "cache/", "Base directory to store certificates")
	LogLevel      = flag.String("loglevel", "info", "Log level")
	Refresh       = flag.Duration("refresh", time.Minute*20, "Revalidation interval")
	MaxIterations = flag.Int("max.iterations", 32, "Specify the max number of iterations octorpki will make before failing to generate output.json")
	Filter        = flag.Bool("filter", true, "Filter out non accessible prefixes and duplicates")

	StrictManifests = flag.Bool("strict.manifests", true, "Manifests must be complete or invalidate CA")
	StrictHash      = flag.Bool("strict.hash", true, "Check the hash of files")
	StrictCms       = flag.Bool("strict.cms", false, "Decode CMS with strict settings")

	// Rsync Options
	RsyncTimeout = flag.Duration("rsync.timeout", time.Minute*20, "Rsync command timeout")
	RsyncBin     = flag.String("rsync.bin", DefaultBin(), "The rsync binary to use")

	// RRDP Options
	RRDP         = flag.Bool("rrdp", true, "Enable RRDP fetching")
	RRDPFile     = flag.String("rrdp.file", "cache/rrdp.json", "Save RRDP state")
	RRDPFailover = flag.Bool("rrdp.failover", true, "Failover to rsync when RRDP fails")
	UserAgent    = flag.String("useragent", fmt.Sprintf("Cloudflare-RRDP-%v (+https://github.com/cloudflare/cfrpki)", AppVersion), "User-Agent header")

	Mode       = flag.String("mode", "server", "Select output mode (server/oneoff)")
	WaitStable = flag.Bool("output.wait", true, "Wait until stable state to create the file (returns 503 when unstable on HTTP)")

	// Serving Options
	Addr        = flag.String("http.addr", ":8081", "Listening address")
	CacheHeader = flag.Bool("http.cache", true, "Enable cache header")
	MetricsPath = flag.String("http.metrics", "/metrics", "Prometheus metrics endpoint")
	InfoPath    = flag.String("http.info", "/infos", "Information URL")
	HealthPath  = flag.String("http.health", "/health", "Health URL")

	CorsOrigins = flag.String("cors.origins", "*", "Cors origins separated by comma")
	CorsCreds   = flag.Bool("cors.creds", false, "Cors enable credentials")

	// File option
	Output           = flag.String("output.roa", "output.json", "Output ROA file or URL")
	Sign             = flag.Bool("output.sign", true, "Sign output (GoRTR compatible)")
	SignKey          = flag.String("output.sign.key", "private.pem", "ECDSA signing key")
	ValidityDuration = flag.Duration("output.sign.validity", time.Hour, "Validity")

	// Debugging options
	Pprof     = flag.Bool("pprof", false, "Enable pprof endpoint")
	Tracer    = flag.Bool("tracer", false, "Enable tracer")
	SentryDSN = flag.String("sentry.dsn", "", "Send errors to Sentry")

	MaxConcurrentRetrievals = flag.Uint("max_concurrent_retrievals", 100, "Maximum amount of concurrent retrievals (rsync + RRDP)")

	Version = flag.Bool("version", false, "Print version")

	CertRepository = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 5}
	CertRRDP       = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 13}
)

var (
	MetricSIACounts = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "file_count_sia",
			Help: "Counts of file per SIA.",
		},
		[]string{"address", "type"},
	)
	MetricRsyncErrors = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "rsync_errors",
			Help: "Rsync error count.",
		},
		[]string{"address"},
	)
	MetricRRDPErrors = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "rrdp_errors",
			Help: "RRDP error count.",
		},
		[]string{"address"},
	)
	MetricRRDPSerial = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "rrdp_serial",
			Help: "RRDP serial number.",
		},
		[]string{"address"},
	)
	MetricROAsCount = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "roas",
			Help: "Bytes received by the application.",
		},
		[]string{"ta"},
	)
	MetricState = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "state",
			Help: "State of the Relying party (1 = stable, 0 = unstable).",
		},
	)
	MetricLastStableValidation = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "last_stable_validation",
			Help: "Timestamp of last stable validation.",
		},
	)
	MetricLastValidation = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "last_validation",
			Help: "Timestamp of last validation.",
		},
	)
	MetricOperationTime = prometheus.NewSummaryVec(
		prometheus.SummaryOpts{
			Name:       "operation_time",
			Help:       "Time to run an operation.",
			Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
		},
		[]string{"type"},
	)
	MetricLastFetch = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "last_fetch",
			Help: "RRDP/Rsync last timestamp.",
		},
		[]string{"address", "type"},
	)
)

func DefaultBin() string {
	path, _ := exec.LookPath("rsync")
	return path
}

type RRDPInfo struct {
	RsyncURL  string `json:"rsync"`
	Path      string `json:"path"`
	SessionID string `json:"sessionid"`
	Serial    int64  `json:"serial"`
}

var errKeyNotParsed = fmt.Errorf("Failed to PEM decode key")

func ReadKey(key []byte, isPem bool) (*ecdsa.PrivateKey, error) {
	if isPem {
		block, _ := pem.Decode(key)
		if block == nil {
			return nil, errKeyNotParsed
		}
		key = block.Bytes
	}

	k, err := x509.ParseECPrivateKey(key)
	if err != nil {
		return nil, err
	}
	return k, nil
}

type OctoRPKI struct {
	Tals         []*pki.PKIFile
	TalsFetch    map[string]*librpki.RPKITAL
	TalNames     []string
	LastComputed time.Time
	Key          *ecdsa.PrivateKey

	Stable            atomic.Bool // Indicates something has been added to the fetch list (rsync or rrdp)
	HasPreviousStable atomic.Bool
	Fetcher           *syncpki.LocalFetch
	HTTPFetcher       *syncpki.HTTPFetcher

	PrevRepos    map[string]time.Time
	CurrentRepos map[string]time.Time

	rrdpFetch         map[string]string // maps from RRDP Url to rsync URL
	rrdpFetchMu       sync.RWMutex
	rrdpFetchDomain   map[string]string
	rrdpFetchDomainMu sync.RWMutex

	rsyncFetchJobManager *rsyncFetchJobManager

	RRDPInfo   map[string]RRDPInfo
	RRDPInfoMu sync.RWMutex

	ROAList   *prefixfile.ROAList
	ROAListMu sync.RWMutex

	InfoAuthorities     [][]SIA
	InfoAuthoritiesLock sync.RWMutex

	stats  *octoRPKIStats
	tracer opentracing.Tracer

	Resources   *schemas.ResourcesJSON
	ResourcesMu sync.RWMutex

	DoCT   bool
	CTPath string
	Filter bool
}

func (s *OctoRPKI) getRRDPFetch() map[string]string {
	s.rrdpFetchMu.RLock()
	defer s.rrdpFetchMu.RUnlock()

	ret := make(map[string]string, len(s.rrdpFetch))
	for k, v := range s.rrdpFetch {
		ret[k] = v
	}

	return ret
}

func (s *OctoRPKI) setRRDPFetch(key, value string) {
	s.rrdpFetchMu.Lock()
	defer s.rrdpFetchMu.Unlock()

	s.rrdpFetch[key] = value
}

func (s *OctoRPKI) getRRDPDomain(path string) (string, bool) {
	s.rrdpFetchDomainMu.RLock()
	defer s.rrdpFetchDomainMu.RUnlock()

	domain, exists := s.rrdpFetchDomain[path]
	return domain, exists
}

func (s *OctoRPKI) setRRDPDomain(path string, domain string) {
	s.rrdpFetchDomainMu.Lock()
	defer s.rrdpFetchDomainMu.Unlock()

	s.rrdpFetchDomain[path] = domain
}

type octoRPKIStats struct {
	ValidationDuration time.Duration
	iterations         atomic.Uint64
	ROAsTALsCount      []ROAsTAL
}

func newOctoRPKIStats() *octoRPKIStats {
	return &octoRPKIStats{
		ROAsTALsCount: make([]ROAsTAL, 0),
	}
}

func (s *OctoRPKI) MainReduce() bool {
	t1 := time.Now()
	defer func() {
		t2 := time.Now()
		MetricOperationTime.With(prometheus.Labels{"type": "reduce"}).Observe(float64(t2.Sub(t1).Seconds()))
	}()

	var hasChanged bool
	for rsync, ts := range s.CurrentRepos {
		if _, ok := s.PrevRepos[rsync]; !ok {
			s.PrevRepos[rsync] = ts
			hasChanged = true
			log.Debugf("Repository %s has appeared at %v", rsync, ts)
		}
	}

	// Init deletion of folder if missing from current
	s.Fetcher.SetRepositories(s.CurrentRepos)

	if len(s.PrevRepos) != len(s.CurrentRepos) {
		return true
	}

	return hasChanged
}

func ExtractRsyncDomain(rsyncURL string) (string, error) {
	if !strings.HasPrefix(rsyncURL, syncpki.RsyncProtoPrefix) {
		return "", fmt.Errorf("%q is not an rsync URL", rsyncURL)
	}

	return strings.Split(strings.TrimPrefix(rsyncURL, syncpki.RsyncProtoPrefix), "/")[0], nil
}

func (s *OctoRPKI) WriteRsyncFileOnDisk(rsyncURL string, data []byte) error {
	fPath := mustExtractFoldersPathFromRsyncURL(rsyncURL)
	mustMkdirAll(fPath)
	filePath := mustExtractFilePathFromRsyncURL(rsyncURL)

	// GHSA-8459-6rc9-8vf8: Prevent parent directory writes outside of Basepath
	if strings.Contains(filePath, "../") || strings.Contains(filePath, "..\\") {
		return fmt.Errorf("Path %q contains illegal path element", filePath)
	}

	fp := filepath.Join(*Basepath, filePath)
	err := ioutil.WriteFile(fp, data, 0600)
	if err != nil {
		return fmt.Errorf("Unable to write file %q: %v", fp, err)
	}

	return nil
}

func mustMkdirAll(fPath string) {
	err := os.MkdirAll(filepath.Join(*Basepath, fPath), os.ModePerm)
	if err != nil {
		log.Fatalf("Failed to create directories: %v", err)
	}
}

func (s *OctoRPKI) ReceiveRRDPFileCallback(main string, url string, path string, data []byte, withdraw bool, snapshot bool, serial int64, args ...interface{}) error {
	if len(args) > 0 {
		rsync, ok := args[0].(string)
		if ok && !strings.Contains(path, rsync) {
			log.Errorf("rrdp: %s is outside directory %s", path, rsync)
			return nil
		}
	}

	err := s.WriteRsyncFileOnDisk(path, data)
	if err != nil {
		return fmt.Errorf("Unable to write sync file %q on disk: %v", path, err)
	}

	MetricSIACounts.With(prometheus.Labels{"address": main, "type": "rrdp"}).Inc()
	return nil
}

func (s *OctoRPKI) LoadRRDPInfo(file string) error {
	fc, err := ioutil.ReadFile(file)
	if err != nil {
		return fmt.Errorf("Unable to read file %q: %v", file, err)
	}

	s.RRDPInfoMu.Lock()
	defer s.RRDPInfoMu.Unlock()

	s.RRDPInfo = make(map[string]RRDPInfo)
	err = json.Unmarshal(fc, &s.RRDPInfo)
	if err != nil {
		return fmt.Errorf("JSON unmarshal failed: %v", err)
	}

	return nil
}

func (s *OctoRPKI) saveRRDPInfo(file string) error {
	fc, err := json.Marshal(s.getRRDPInfo())
	if err != nil {
		return fmt.Errorf("JSON marshal failed: %v", err)
	}

	err = ioutil.WriteFile(file, fc, 0600)
	if err != nil {
		return fmt.Errorf("Unable to write file %q: %v", file, err)
	}

	return nil
}

func (s *OctoRPKI) getRRDPInfo() map[string]RRDPInfo {
	s.RRDPInfoMu.RLock()
	defer s.RRDPInfoMu.RUnlock()

	ret := make(map[string]RRDPInfo, len(s.RRDPInfo))
	for k, v := range s.RRDPInfo {
		ret[k] = v
	}

	return ret
}

func (s *OctoRPKI) mainRRDP(pSpan opentracing.Span) {
	span := s.tracer.StartSpan("rrdp", opentracing.ChildOf(pSpan.Context()))
	defer span.Finish()

	fetcher := newRRDPFetcher(s, int(*MaxConcurrentRetrievals), span)
	for path, rsync := range s.getRRDPFetch() {
		fetcher.fetch(path, rsync)
	}

	fetcher.done()
	fetcher.wait()
}

func (s *OctoRPKI) fetchRRDP(path string, rsyncURL string, span opentracing.Span) {
	rSpan := s.tracer.StartSpan("sync", opentracing.ChildOf(span.Context()))
	defer rSpan.Finish()

	rSpan.SetTag("rrdp", path)
	rSpan.SetTag("rsync", rsyncURL)
	rSpan.SetTag("type", "rrdp")
	log.Infof("RRDP sync %v", path)

	MetricSIACounts.With(prometheus.Labels{"address": path, "type": "rrdp"}).Set(0)

	rrdpSystem := s.newRRDPSystem(path, rsyncURL)

	domain, _ := s.getRRDPDomain(path)
	err := rrdpSystem.FetchRRDP(domain)
	if err != nil {
		s.rrdpError(rsyncURL, path, err, rSpan, rrdpSystem)
		return
	}

	log.Debugf("Success fetching %s, removing rsync %s", path, rsyncURL)
	s.rsyncFetchJobManager.delete(rsyncURL)

	rSpan.LogKV("event", "rrdp", "type", "success", "message", "rrdp successfully fetched")
	sentry.WithScope(func(scope *sentry.Scope) {
		scope.SetLevel(sentry.LevelInfo)
		scope.SetTag("Rsync", rsyncURL)
		scope.SetTag("RRDP", path)
		rrdpSystem.SetSentryScope(scope)
		sentry.CaptureMessage("fetched rrdp successfully")
	})

	MetricRRDPSerial.With(prometheus.Labels{"address": path}).Set(float64(rrdpSystem.Serial))
	MetricLastFetch.With(prometheus.Labels{"address": path, "type": "rrdp"}).Set(float64(time.Now().Unix()))

	s.RRDPInfoMu.Lock()
	defer s.RRDPInfoMu.Unlock()

	s.RRDPInfo[rsyncURL] = RRDPInfo{
		RsyncURL:  rsyncURL,
		Path:      path,
		SessionID: rrdpSystem.SessionID,
		Serial:    rrdpSystem.Serial,
	}
}

func (s *OctoRPKI) newRRDPSystem(path string, rsync string) *syncpki.RRDPSystem {
	s.RRDPInfoMu.RLock()
	defer s.RRDPInfoMu.RUnlock()

	return &syncpki.RRDPSystem{
		Callback:  s.ReceiveRRDPFileCallback,
		Path:      path,
		Fetcher:   s.HTTPFetcher,
		SessionID: s.RRDPInfo[rsync].SessionID,
		Serial:    s.RRDPInfo[rsync].Serial,
		Log:       log.StandardLogger(),
	}
}

func (s *OctoRPKI) rrdpError(rsyncURL string, path string, err error, rSpan opentracing.Span, rrdp *syncpki.RRDPSystem) {
	rSpan.SetTag("error", true)
	sentry.WithScope(func(scope *sentry.Scope) {
		if errC, ok := err.(interface{ SetURL(string, string) }); ok {
			errC.SetURL(path, rsyncURL)
		}
		if errC, ok := err.(interface{ SetSentryScope(*sentry.Scope) }); ok {
			errC.SetSentryScope(scope)
		}
		rrdp.SetSentryScope(scope)
		scope.SetTag("Rsync", rsyncURL)
		scope.SetTag("RRDP", path)
		sentry.CaptureException(err)
	})

	// GHSA-g9wh-3vrx-r7hg: Do not process responses that are too large
	if *RRDPFailover && err.Error() != "http: request body too large" {
		log.Errorf("Error when processing %v (for %v): %v. Will add to rsync.", path, rsyncURL, err)
		rSpan.LogKV("event", "rrdp failure", "type", "failover to rsync", "message", err)
	} else {
		log.Errorf("Error when processing %v (for %v): %v.Skipping failover to rsync.", path, rsyncURL, err)
		rSpan.LogKV("event", "rrdp failure", "type", "skipping failover to rsync", "message", err)
		s.rsyncFetchJobManager.delete(rsyncURL)
	}

	MetricRRDPErrors.With(prometheus.Labels{"address": path}).Inc()
}

func (s *OctoRPKI) mainRsync(pSpan opentracing.Span) {
	t1 := time.Now()
	span := s.tracer.StartSpan("rsync", opentracing.ChildOf(pSpan.Context()))
	defer span.Finish()

	fetcher := newRsyncFetcher(s, int(*MaxConcurrentRetrievals), span)
	for rsyncURL := range s.rsyncFetchJobManager.get() {
		fetcher.fetch(rsyncURL)
	}

	fetcher.done()
	fetcher.wait()

	t2 := time.Now()
	MetricOperationTime.With(prometheus.Labels{"type": "rsync"}).Observe(float64(t2.Sub(t1).Seconds()))
}

func mustExtractFoldersPathFromRsyncURL(rsyncURL string) string {
	downloadPath, err := syncpki.ExtractFoldersPathFromRsyncURL(rsyncURL)
	if err != nil {
		log.Fatalf("Failed to extract folder path from rsync URL: %v", err)
	}

	return downloadPath
}

func mustExtractFilePathFromRsyncURL(rsyncURL string) string {
	fPath, err := syncpki.ExtractFilePathFromRsyncURL(rsyncURL)
	if err != nil {
		log.Fatalf("Unable to extract file path from rsync url: %v", err)
	}

	return fPath
}

func (s *OctoRPKI) fetchRsync(uri string, span opentracing.Span) {
	rSpan := s.tracer.StartSpan("sync", opentracing.ChildOf(span.Context()))
	defer rSpan.Finish()
	rSpan.SetTag("rsync", uri)
	rSpan.SetTag("type", "rsync")

	log.Infof("Rsync sync %v", uri)
	downloadPath := mustExtractFilePathFromRsyncURL(uri)

	path := filepath.Join(*Basepath, downloadPath)
	ctxRsync, cancelRsync := context.WithTimeout(context.Background(), *RsyncTimeout)
	defer cancelRsync()

	files, err := syncpki.RunRsync(ctxRsync, uri, *RsyncBin, path)
	if err != nil {
		s.rsyncError(uri, path, err, rSpan)
	} else {
		rSpan.LogKV("event", "rsync", "type", "success", "message", "rsync successfully fetched")
		sentry.WithScope(func(scope *sentry.Scope) {
			scope.SetLevel(sentry.LevelInfo)
			scope.SetTag("Rsync", uri)
			sentry.CaptureMessage("fetched rsync successfully")
		})
	}

	MetricSIACounts.With(prometheus.Labels{"address": uri, "type": "rsync"}).Set(float64(len(files)))
	MetricLastFetch.With(prometheus.Labels{"address": uri, "type": "rsync"}).Set(float64(time.Now().Unix()))
}

func (s *OctoRPKI) rsyncError(uri string, path string, err error, rSpan opentracing.Span) {
	rSpan.SetTag("error", true)
	rSpan.LogKV("event", "rsync failure", "message", err)
	log.Errorf("Error when processing %v: %v. Will add to rsync.", path, err)
	sentry.WithScope(func(scope *sentry.Scope) {
		if errC, ok := err.(interface{ SetRsync(string) }); ok {
			errC.SetRsync(uri)
		}
		if errC, ok := err.(interface{ SetSentryScope(*sentry.Scope) }); ok {
			errC.SetSentryScope(scope)
		}
		scope.SetTag("Rsync", uri)
		sentry.CaptureException(err)
	})

	MetricRsyncErrors.With(prometheus.Labels{"address": uri}).Inc()
}

func filterDuplicates(roalist []prefixfile.ROAJson) []prefixfile.ROAJson {
	roaListNoDup := make([]prefixfile.ROAJson, 0)
	hmap := make(map[string]bool)
	for _, roa := range roalist {
		k := roa.String()
		_, present := hmap[k]
		if !present {
			hmap[k] = true
			roaListNoDup = append(roaListNoDup, roa)
		}
	}
	return roaListNoDup
}

func setJaegerError(l []interface{}, err error) []interface{} {
	return append(l, "error", true, "message", err)
}

// Fetches RFC8630-type TAL
func (s *OctoRPKI) mainTAL(pSpan opentracing.Span) {
	t1 := time.Now()
	span := s.tracer.StartSpan("tal", opentracing.ChildOf(pSpan.Context()))
	defer span.Finish()

	for path, tal := range s.TalsFetch {
		s.fetchTAL(path, tal, span)
	}

	t2 := time.Now()
	MetricOperationTime.With(prometheus.Labels{"type": "tal"}).Observe(float64(t2.Sub(t1).Seconds()))
}

func (s *OctoRPKI) fetchTAL(path string, tal *librpki.RPKITAL, span opentracing.Span) {
	tSpan := s.tracer.StartSpan("tal-fetch", opentracing.ChildOf(span.Context()))
	defer tSpan.Finish()
	tSpan.SetTag("tal", path)

	success, successURL := s._fetchTAL(tal, path, span)
	if success {
		log.Infof("Successfully downloaded root certificate for %s at %s", path, successURL)
		return
	}

	// Fail over to rsync
	if *RRDPFailover && tal.HasRsync() {
		rsync := tal.GetRsyncURI()
		log.Infof("Root certificate for %s will be downloaded using rsync: %s", path, rsync)
		s.rsyncFetchJobManager.set(rsync, "")
		tSpan.SetTag("failover-rsync", true)
		return
	}

	log.Errorf("Could not download root certificate for %s", path)
	tSpan.SetTag("error", true)

}

func (s *OctoRPKI) _fetchTAL(tal *librpki.RPKITAL, path string, tSpan opentracing.Span) (success bool, successURL string) {
	for _, uri := range tal.URI {
		success, successURL := s.fetchTALurl(tal, uri, path, tSpan)
		if success {
			return success, successURL
		}
	}

	return false, ""
}

func (s *OctoRPKI) getHTTP(uri string, tfSpan opentracing.Span, sHub *sentry.Hub) ([]byte, error) {
	req, err := http.NewRequest("GET", uri, nil)
	if err != nil {
		return nil, fmt.Errorf("error while trying to fetch: %s: %v", uri, err)
	}
	req.Header.Set("User-Agent", s.HTTPFetcher.UserAgent)

	sHub.ConfigureScope(func(scope *sentry.Scope) {
		scope.SetRequest(req)
	})

	sbc := &sentry.Breadcrumb{
		Message:  fmt.Sprintf("GET | %s", uri),
		Category: "http",
	}

	// maybe add a limit in the client? To avoid downloading huge files (that wouldn't be certs)
	resp, err := s.HTTPFetcher.Client.Do(req)
	if err != nil {
		sbc.Level = sentry.LevelError
		sHub.AddBreadcrumb(sbc, nil)
		sHub.CaptureException(err)
		return nil, fmt.Errorf("error while trying to fetch: %s: %v", uri, err)
	}

	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		sHub.ConfigureScope(func(scope *sentry.Scope) {
			scope.SetLevel(sentry.LevelError)
		})
		sbc.Level = sentry.LevelError
		sHub.AddBreadcrumb(sbc, nil)
		sHub.CaptureMessage(fmt.Sprintf("http server replied: %s", resp.Status))
		return nil, fmt.Errorf("http server replied: %s while trying to fetch %s", resp.Status, uri)
	}

	sHub.AddBreadcrumb(sbc, nil)

	data, err := ioutil.ReadAll(resp.Body)
	tfSpan.LogKV("size", len(data))
	if err != nil {
		sHub.CaptureException(err)
		return nil, fmt.Errorf("error while trying to fetch: %s: %v", uri, err)
	}

	return data, nil
}

func (s *OctoRPKI) fetchTALurl(tal *librpki.RPKITAL, uri string, path string, tSpan opentracing.Span) (success bool, successURL string) {
	if !strings.HasPrefix(uri, "http://") && !strings.HasPrefix(uri, "https://") {
		return false, ""
	}

	tfSpan := s.tracer.StartSpan("tal-fetch-uri", opentracing.ChildOf(tSpan.Context()))
	defer tfSpan.Finish()
	tfSpan.SetTag("uri", uri)

	sHub := sentry.CurrentHub().Clone()
	sHub.ConfigureScope(func(scope *sentry.Scope) {
		scope.SetTag("tal.uri", uri)
		scope.SetTag("tal.path", path)
	})

	data, err := s.getHTTP(uri, tfSpan, sHub)
	if err != nil {
		tfSpan.SetTag("error", true)
		tfSpan.SetTag("message", err)
		log.Errorf("error while trying to download: %s: %v", uri, err)
		return false, ""
	}

	// Plan option to store everything in memory
	err = s.WriteRsyncFileOnDisk(tal.GetRsyncURI(), data)
	if err != nil {
		tfSpan.SetTag("error", true)
		tfSpan.SetTag("message", err)

		log.Errorf("error while trying to fetch: %s: %v", uri, err)
		sHub.CaptureException(err)
		return false, ""
	}

	sHub.WithScope(func(scope *sentry.Scope) {
		scope.SetLevel(sentry.LevelInfo)
		sHub.CaptureMessage("fetched http tal cert successfully")
	})

	return true, uri
}

func logCollector(sm *pki.SimpleManager, tal *pki.PKIFile, tSpan opentracing.Span) {
	for err := range sm.Errors {
		tSpan.SetTag("error", true)
		tSpan.LogKV("event", "resource issue", "type", "skipping resource", "message", err)
		log.Error(err)
		sentry.WithScope(func(scope *sentry.Scope) {
			if errC, ok := err.(interface{ SetSentryScope(*sentry.Scope) }); ok {
				errC.SetSentryScope(scope)
			}
			scope.SetTag("TrustAnchor", tal.Path)
			sentry.CaptureException(err)
		})
	}
}

func (s *OctoRPKI) generateROAList(pkiManagers []*pki.SimpleManager, span opentracing.Span) *prefixfile.ROAList {
	roalist := &prefixfile.ROAList{
		Data: make([]prefixfile.ROAJson, 0),
	}
	var counts int
	resourcesjson := &schemas.ResourcesJSON{
		Resources: make([]*schemas.OutputRes, 0),
	}
	resourcesMap := make(map[string]*schemas.OutputRes)
	resourcesjson.Metadata.Generated = int(time.Now().UTC().UnixNano() / 1000000000)
	s.stats.ROAsTALsCount = make([]ROAsTAL, 0)
	for i, tal := range s.Tals {
		eSpan := s.tracer.StartSpan("extract", opentracing.ChildOf(span.Context()))
		eSpan.SetTag("tal", tal.Path)
		talname := tal.Path
		if len(s.TalNames) == len(s.Tals) {
			talname = s.TalNames[i]
		}

		for _, obj := range pkiManagers[i].Validator.ValidObjects {
			switch obj.Type {
			case pki.TYPE_CER:
				cer := obj.Resource.(*librpki.RPKICertificate)

				ski := hex.EncodeToString(cer.Certificate.SubjectKeyId)
				aki := hex.EncodeToString(cer.Certificate.AuthorityKeyId)

				var path string
				var hash string
				if obj.File != nil {
					path = obj.File.ComputePath()
					resData, err := s.Fetcher.GetFileConv(obj.File, false)
					if err == nil {
						hashBytes := sha256.Sum256(resData.Data)
						hash = hex.EncodeToString(hashBytes[:])
					}
				}

				na := int(cer.Certificate.NotAfter.UnixNano() / 1000000000)
				nb := int(cer.Certificate.NotBefore.UnixNano() / 1000000000)
				curResource := &schemas.OutputRes{
					Type:           "certificate",
					SubjectKeyId:   ski,
					AuthorityKeyId: aki,
					Name:           cer.Certificate.Subject.CommonName,
					Serial:         cer.Certificate.SerialNumber.String(),
					ASNs:           make([]*schemas.OutputASN, 0),
					IPs:            make([]*schemas.OutputIP, 0),
					Path:           path,
					SIAs:           make([]string, 0),
					ValidFrom:      nb,
					ValidTo:        na,
					TA:             talname,
					Hash:           hash,
				}

				resourcesMap[hash] = curResource

				for _, sia := range cer.SubjectInformationAccess {
					curResource.SIAs = append(curResource.SIAs, string(sia.GeneralName))
				}
				for _, asn := range cer.ASNums {
					var asnRes *schemas.OutputASN
					switch asnc := asn.(type) {
					case *librpki.ASNRange:
						asnRes = &schemas.OutputASN{
							Range: []uint32{
								uint32(asnc.Min),
								uint32(asnc.Max),
							},
						}
					case *librpki.ASNull:
						asnRes = &schemas.OutputASN{
							Inherit: true,
						}
					case *librpki.ASN:
						asnRes = &schemas.OutputASN{
							ASN: uint32(asnc.ASN),
						}
					}
					if asnRes != nil {
						curResource.ASNs = append(curResource.ASNs, asnRes)
					}
				}
				for _, ips := range cer.IPAddresses {
					var ipRes *schemas.OutputIP
					switch ipc := ips.(type) {
					case *librpki.IPAddressRange:
						ipRes = &schemas.OutputIP{
							Range: []string{
								ipc.Min.String(),
								ipc.Max.String(),
							},
						}
					case *librpki.IPNet:
						ipRes = &schemas.OutputIP{
							Prefix: ipc.IPNet.String(),
						}
					case *librpki.IPAddressNull:
						ipRes = &schemas.OutputIP{
							Inherit: int(ipc.Family),
						}
					}
					if ipRes != nil {
						curResource.IPs = append(curResource.IPs, ipRes)
					}
				}
				resourcesjson.Resources = append(resourcesjson.Resources, curResource)
			}
		}

		var counttal int
		for _, obj := range pkiManagers[i].Validator.ValidROA {
			roa := obj.Resource.(*librpki.RPKIROA)

			var path string
			var hash string
			if obj.File != nil {
				path = obj.File.ComputePath()
				resData, err := s.Fetcher.GetFileConv(obj.File, false)
				if err == nil {
					hashBytes := sha256.Sum256(resData.Data)
					hash = hex.EncodeToString(hashBytes[:])
				}
			}

			cer := roa.Certificate

			ski := hex.EncodeToString(cer.Certificate.SubjectKeyId)
			aki := hex.EncodeToString(cer.Certificate.AuthorityKeyId)

			em := int(roa.SigningTime.UnixNano() / 1000000000)
			na := int(cer.Certificate.NotAfter.UnixNano() / 1000000000)
			nb := int(cer.Certificate.NotBefore.UnixNano() / 1000000000)

			curResource := &schemas.OutputRes{
				Type:           "roa",
				SubjectKeyId:   ski,
				AuthorityKeyId: aki,
				Name:           cer.Certificate.Subject.CommonName,
				Serial:         cer.Certificate.SerialNumber.String(),
				ROAs:           make([]*schemas.OutputROA, 0),
				Path:           path,
				Emitted:        em,
				ASN:            uint32(roa.ASN),
				ValidFrom:      nb,
				ValidTo:        na,
				TA:             talname,
				Hash:           hash,
			}

			resourcesMap[hash] = curResource

			for _, entry := range roa.Valids {
				oroa := prefixfile.ROAJson{
					ASN:    fmt.Sprintf("AS%v", roa.ASN),
					Prefix: entry.IPNet.String(),
					Length: uint8(entry.MaxLength),
					TA:     talname,
				}
				roalist.Data = append(roalist.Data, oroa)
				counts++
				counttal++

				curResource.ROAs = append(curResource.ROAs, &schemas.OutputROA{
					Prefix:    entry.IPNet.String(),
					MaxLength: entry.MaxLength,
				})
			}

			resourcesjson.Resources = append(resourcesjson.Resources, curResource)
		}

		s.stats.ROAsTALsCount = append(s.stats.ROAsTALsCount, ROAsTAL{TA: talname, Count: counttal})
		MetricROAsCount.With(prometheus.Labels{"ta": talname}).Set(float64(counttal))

		// Complete: Manifests
		for _, obj := range pkiManagers[i].Validator.ValidManifest {
			mft := obj.Resource.(*librpki.RPKIManifest)

			var path string
			var hash string
			if obj.File != nil {
				path = obj.File.ComputePath()
				resData, err := s.Fetcher.GetFileConv(obj.File, false)
				if err == nil {
					hashBytes := sha256.Sum256(resData.Data)
					hash = hex.EncodeToString(hashBytes[:])
				}
			}

			cer := mft.Certificate

			ski := hex.EncodeToString(cer.Certificate.SubjectKeyId)
			aki := hex.EncodeToString(cer.Certificate.AuthorityKeyId)
			tu := int(mft.Content.ThisUpdate.UnixNano() / 1000000000)
			nu := int(mft.Content.NextUpdate.UnixNano() / 1000000000)
			na := int(cer.Certificate.NotAfter.UnixNano() / 1000000000)
			nb := int(cer.Certificate.NotBefore.UnixNano() / 1000000000)

			curResource := &schemas.OutputRes{
				Type:           "manifest",
				SubjectKeyId:   ski,
				AuthorityKeyId: aki,
				Name:           cer.Certificate.Subject.CommonName,
				Serial:         cer.Certificate.SerialNumber.String(),
				FileList:       make([]string, 0),
				ThisUpdate:     tu,
				NextUpdate:     nu,
				ManifestNumber: mft.Content.ManifestNumber.String(),
				Path:           path,
				ValidFrom:      nb,
				ValidTo:        na,
				TA:             talname,
				Hash:           hash,
			}

			resourcesMap[hash] = curResource

			for _, entry := range mft.Content.FileList {
				curResource.FileList = append(curResource.FileList, entry.Name)
			}

			resourcesjson.Resources = append(resourcesjson.Resources, curResource)
		}

		eSpan.Finish()
	}
	curTime := time.Now()
	s.LastComputed = curTime
	validTime := curTime.Add(*ValidityDuration)
	roalist.Metadata = prefixfile.MetaData{
		Counts:    counts,
		Generated: int(curTime.Unix()),
		Valid:     int(validTime.Unix()),
	}

	if s.Filter {
		roalist.Data = FilterInvalidPrefixLen(FilterDuplicates(roalist.Data))
	}

	roalist.Data = filterDuplicates(roalist.Data)
	if *Sign {
		s.signROAList(roalist, span)
	}

	s.ResourcesMu.Lock()
	defer s.ResourcesMu.Unlock()
	s.Resources = resourcesjson

	return roalist
}

func (s *OctoRPKI) signROAList(roaList *prefixfile.ROAList, span opentracing.Span) {
	sSpan := s.tracer.StartSpan("sign", opentracing.ChildOf(span.Context()))
	defer sSpan.Finish()

	signdate, sign, err := roaList.Sign(s.Key)
	if err != nil {
		log.Error(err)
		sentry.CaptureException(err)
	}
	roaList.Metadata.Signature = sign
	roaList.Metadata.SignatureDate = signdate
}

func (s *OctoRPKI) mainValidation(pSpan opentracing.Span) [][]*pki.PKIFile {
	t1 := time.Now()
	ia := make([][]SIA, len(s.Tals))
	for i := 0; i < len(ia); i++ {
		ia[i] = make([]SIA, 0)
	}
	iatmp := make(map[string]*SIA)

	span := s.tracer.StartSpan("validation", opentracing.ChildOf(pSpan.Context()))
	defer span.Finish()

	ctData := make([][]*pki.PKIFile, 0)

	pkiManagers := make([]*pki.SimpleManager, len(s.Tals))
	for i, tal := range s.Tals {
		tSpan := s.tracer.StartSpan("explore", opentracing.ChildOf(span.Context()))
		tSpan.SetTag("tal", tal.Path)

		validator := pki.NewValidator()
		validator.DecoderConfig.ValidateStrict = *StrictCms

		sm := pki.NewSimpleManager()
		pkiManagers[i] = sm
		pkiManagers[i].ReportErrors = true
		pkiManagers[i].Validator = validator
		pkiManagers[i].FileSeeker = s.Fetcher
		pkiManagers[i].Log = log.StandardLogger()
		pkiManagers[i].StrictHash = *StrictHash
		pkiManagers[i].StrictManifests = *StrictManifests

		go logCollector(sm, tal, tSpan)

		pkiManagers[i].AddInitial([]*pki.PKIFile{tal})
		countExplore := pkiManagers[i].Explore(!*UseManifest, false)

		// Insertion of SIAs in db to allow rsync to update the repos
		var count int
		for _, obj := range pkiManagers[i].Validator.TALs {
			tal := obj.Resource.(*librpki.RPKITAL)
			if !obj.CertTALValid {
				s.TalsFetch[obj.File.Path] = tal
			}
			count++
		}

		for _, pkiResource := range pkiManagers[i].Validator.ValidObjects {
			if pkiResource.Type != pki.TYPE_CER {
				continue
			}

			cer := pkiResource.Resource.(*librpki.RPKICertificate)
			rsyncGeneralName := cer.GetRsyncGeneralName()
			rrdpGeneralName := cer.GetRRDPGeneralName()

			gnExtracted, gnExtractedDomain, err := syncpki.ExtractRsyncDomainModule(rsyncGeneralName)
			if err != nil {
				log.Errorf("Could not add cert rsync %s due to %v", rsyncGeneralName, err)
				continue
			}

			if cer.HasRRDP() {
				prev, ok := s.getRRDPDomain(rrdpGeneralName)
				if ok && prev != gnExtractedDomain {
					log.Errorf("rrdp %s tries to override %s with %s", rrdpGeneralName, prev, gnExtractedDomain)
					continue
				}
				s.setRRDPDomain(rrdpGeneralName, gnExtractedDomain)
				s.setRRDPFetch(rrdpGeneralName, gnExtracted)
			}
			s.rsyncFetchJobManager.set(gnExtracted, rrdpGeneralName)
			s.CurrentRepos[gnExtracted] = time.Now()
			count++

			// map the rrdp and rsync by TAL for info page
			sia, ok := iatmp[gnExtracted]
			if !ok {
				tmpSIA := SIA{
					gnExtracted,
					rrdpGeneralName,
				}
				ia[i] = append(ia[i], tmpSIA)
				sia = &(ia[i][len(ia[i])-1])
				iatmp[gnExtracted] = sia
			}
			sia.Rsync = gnExtracted
			sia.RRDP = rrdpGeneralName
		}
		sm.Close()
		tSpan.LogKV("count-valid", count, "count-total", countExplore)
		tSpan.Finish()

		if s.DoCT {
			ctData = append(ctData, s.ct(pkiManagers, i)...)
		}
	}

	s.setInfoAuthorities(ia)
	s.setROAList(s.generateROAList(pkiManagers, span))

	t2 := time.Now()
	s.stats.ValidationDuration = t2.Sub(t1)
	MetricOperationTime.With(prometheus.Labels{"type": "validation"}).Observe(float64(s.stats.ValidationDuration.Seconds()))
	MetricLastValidation.Set(float64(s.LastComputed.Unix()))

	return ctData
}

func (s *OctoRPKI) ct(pkiManagers []*pki.SimpleManager, i int) [][]*pki.PKIFile {
	skiToAki := make(map[string]string)
	skiToPath := make(map[string]*pki.PKIFile)
	for _, obj := range pkiManagers[i].Validator.ValidObjects {
		res := obj.Resource.(*librpki.RPKICertificate)
		ski := hex.EncodeToString(res.Certificate.SubjectKeyId)
		aki := hex.EncodeToString(res.Certificate.AuthorityKeyId)
		skiToAki[ski] = aki
		skiToPath[ski] = obj.File
	}

	pathCT := make([][]*pki.PKIFile, 0)
	for ski, aki := range skiToAki {
		skiDone := make(map[string]bool)
		skiDone[ski] = true

		curAki := aki
		curPath := skiToPath[ski]
		curPathCT := make([]*pki.PKIFile, 1)
		curPathCT[0] = curPath

		var ok bool
		for curAki != "" && !ok {
			ok = skiDone[curAki]
			skiDone[curAki] = true

			curPath = skiToPath[curAki]
			if curAki != "" {
				curPathCT = append(curPathCT, curPath)
			}
			curAki = skiToAki[curAki]
		}
		pathCT = append(pathCT, curPathCT)
	}

	return pathCT
}

func (s *OctoRPKI) setInfoAuthorities(ia [][]SIA) {
	s.InfoAuthoritiesLock.Lock()
	defer s.InfoAuthoritiesLock.Unlock()

	s.InfoAuthorities = ia
}

func (s *OctoRPKI) setROAList(roaList *prefixfile.ROAList) {
	s.ROAListMu.Lock()
	defer s.ROAListMu.Unlock()

	s.ROAList = roaList
}

func (s *OctoRPKI) getROAList() *prefixfile.ROAList {
	s.ROAListMu.RLock()
	defer s.ROAListMu.RUnlock()

	return s.ROAList
}

func (s *OctoRPKI) ServeROAs(w http.ResponseWriter, r *http.Request) {
	if !s.Stable.Load() && *WaitStable && !s.HasPreviousStable.Load() {
		w.WriteHeader(http.StatusServiceUnavailable)
		w.Write([]byte("File not ready yet"))
		return
	}

	upTo := s.LastComputed.Add(*ValidityDuration)
	maxAge := int(upTo.Sub(time.Now()).Seconds())

	w.Header().Set("Content-Type", "application/json")

	if maxAge > 0 && *CacheHeader {
		w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v", maxAge))
	}

	roaList := s.getROAList()

	etag := sha256.New()
	etag.Write([]byte(fmt.Sprintf("%v/%v", roaList.Metadata.Generated, roaList.Metadata.Counts)))
	etagSum := etag.Sum(nil)
	etagSumHex := hex.EncodeToString(etagSum)

	if match := r.Header.Get("If-None-Match"); match != "" {
		if match == etagSumHex {
			w.WriteHeader(http.StatusNotModified)
			return
		}
	}

	w.Header().Set("Etag", etagSumHex)
	enc := json.NewEncoder(w)
	enc.Encode(roaList)
}

func (s *OctoRPKI) ServeResources(w http.ResponseWriter, r *http.Request) {
	if !s.Stable.Load() && *WaitStable && !s.HasPreviousStable.Load() {
		w.WriteHeader(http.StatusServiceUnavailable)
		w.Write([]byte("File not ready yet"))
		return
	}

	w.Header().Set("Content-Type", "application/json")
	enc := json.NewEncoder(w)

	s.ResourcesMu.RLock()
	defer s.ResourcesMu.RUnlock()
	enc.Encode(s.Resources)
}

func (s *OctoRPKI) ServeHealth(w http.ResponseWriter, r *http.Request) {
	if s.Stable.Load() || s.HasPreviousStable.Load() {
		w.WriteHeader(http.StatusOK)
		return
	}
	w.WriteHeader(http.StatusServiceUnavailable)
	w.Write([]byte("Not ready yet"))
}

type SIA struct {
	Rsync string `json:"rsync"`
	RRDP  string `json:"rrdp,omitempty"`
}

type ROAsTAL struct {
	TA    string `json:"ta,omitempty"`
	Count int    `json:"count,omitempty"`
}

type InfoAuthorities struct {
	TA  string `json:"name"`
	Sia []SIA  `json:"sia"`
}

type InfoResult struct {
	Stable             bool              `json:"stable"`
	TAs                []InfoAuthorities `json:"tas"`
	Iteration          int               `json:"iteration"`
	LastValidation     int               `json:"validation-last"`
	ValidationDuration float64           `json:"validation-duration"`
	ROAsTALs           []ROAsTAL         `json:"roas-tal-count"`
	ROACount           int               `json:"roas-count"`
}

func (s *OctoRPKI) ServeInfo(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")

	s.InfoAuthoritiesLock.RLock()
	ia := s.InfoAuthorities
	s.InfoAuthoritiesLock.RUnlock()

	ias := make([]InfoAuthorities, 0)
	for i, tal := range s.Tals {

		if len(ia) <= i {
			break
		}
		if ia[i] == nil {
			continue
		}

		talname := tal.Path
		if len(s.TalNames) == len(s.Tals) {
			talname = s.TalNames[i]
		}

		ias = append(ias, InfoAuthorities{
			TA:  talname,
			Sia: ia[i],
		})
	}

	ir := InfoResult{
		TAs:                ias,
		ROACount:           len(s.ROAList.Data),
		ROAsTALs:           s.stats.ROAsTALsCount,
		Stable:             s.Stable.Load(),
		LastValidation:     int(s.LastComputed.Unix()),
		ValidationDuration: s.stats.ValidationDuration.Seconds(),
		Iteration:          int(s.stats.iterations.Load()),
	}
	enc := json.NewEncoder(w)
	enc.Encode(ir)
}

func (s *OctoRPKI) Serve(addr string, roaPath string, metricsPath string, infoPath string, healthPath string, corsOrigin string, corsCreds bool) {
	// Note(Erica): fix https://github.com/cloudflare/cfrpki/issues/8
	fullPath := roaPath
	if len(roaPath) > 0 && string(roaPath[0]) != "/" {
		fullPath = "/" + roaPath
	}
	log.Infof("Serving HTTP on %v%v", addr, fullPath)

	r := http.NewServeMux()

	r.HandleFunc(fullPath, s.ServeROAs)
	r.HandleFunc("/resources.json", s.ServeResources)
	r.HandleFunc(infoPath, s.ServeInfo)
	r.HandleFunc(healthPath, s.ServeHealth)
	r.Handle(metricsPath, promhttp.Handler())

	if *Pprof {
		r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
		r.HandleFunc("/debug/pprof/profile", pprof.Profile)
		r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
		r.HandleFunc("/debug/pprof/trace", pprof.Trace)
		r.HandleFunc("/debug/pprof/", pprof.Index)
	}

	corsReq := cors.New(cors.Options{
		AllowedOrigins:   strings.Split(corsOrigin, ","),
		AllowedMethods:   []string{"GET", "POST", "OPTIONS"},
		AllowCredentials: corsCreds,
	}).Handler(r)

	log.Fatal(http.ListenAndServe(addr, corsReq))
}

func init() {
	prometheus.MustRegister(MetricSIACounts)
	prometheus.MustRegister(MetricRsyncErrors)
	prometheus.MustRegister(MetricRRDPErrors)
	prometheus.MustRegister(MetricRRDPSerial)
	prometheus.MustRegister(MetricROAsCount)
	prometheus.MustRegister(MetricState)
	prometheus.MustRegister(MetricLastStableValidation)
	prometheus.MustRegister(MetricLastValidation)
	prometheus.MustRegister(MetricOperationTime)
	prometheus.MustRegister(MetricLastFetch)
}

func runningAsRoot() bool {
	return os.Geteuid() == 0 || os.Getegid() == 0
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Parse()
	if *Version {
		fmt.Println(AppVersion)
		os.Exit(0)
	}

	if !*AllowRoot && runningAsRoot() {
		panic("Running as root is not allowed by default")
	}

	lvl, _ := log.ParseLevel(*LogLevel)
	log.SetLevel(lvl)

	sentryDsn := *SentryDSN
	if sentryDsn == "" {
		sentryDsn = os.Getenv("SENTRY_DSN")
	}
	if sentryDsn != "" {
		err := sentry.Init(sentry.ClientOptions{
			Dsn: sentryDsn,
		})
		if err != nil {
			log.Fatalf("failed initializing sentry: %s", err)
		}
		defer sentry.Flush(2 * time.Second)
	}

	log.Info("Validator started")

	if *Tracer {
		cfg, err := jcfg.FromEnv()
		if err != nil {
			log.Fatal(err)
		}
		tracer, closer, err := cfg.NewTracer()
		if err != nil {
			log.Fatal(err)
		}
		defer closer.Close()
		opentracing.SetGlobalTracer(tracer)
	}

	rootTALs := strings.Split(*RootTAL, ",")
	talNames := strings.Split(*TALNames, ",")
	tals := make([]*pki.PKIFile, 0)
	for _, tal := range rootTALs {
		tals = append(tals, &pki.PKIFile{
			Path: tal,
			Type: pki.TYPE_TAL,
		})
	}

	err := os.MkdirAll(*Basepath, os.ModePerm)
	if err != nil {
		log.Fatalf("Failed to create directories %q: %v", *Basepath, err)
	}

	s := NewOctoRPKI(tals, talNames)

	if *Sign {
		keyFile, err := os.Open(*SignKey)
		if err != nil {
			log.Fatal(err)
		}
		keyBytes, err := ioutil.ReadAll(keyFile)
		if err != nil {
			log.Fatal(err)
		}
		keyFile.Close()
		keyDec, err := ReadKey(keyBytes, true)
		if err != nil {
			log.Fatal(err)
		}
		s.Key = keyDec
	}

	if *Mode == "server" {
		go s.Serve(*Addr, *Output, *MetricsPath, *InfoPath, *HealthPath, *CorsOrigins, *CorsCreds)
	} else if *Mode != "oneoff" {
		log.Fatalf("Mode %v is not specified. Choose either server or oneoff", *Mode)
	}

	if *CertTransparencyThreads < 1 {
		*CertTransparencyThreads = 1
	}

	s.validationLoop()
}

func NewOctoRPKI(tals []*pki.PKIFile, talNames []string) *OctoRPKI {
	return &OctoRPKI{
		TalsFetch:            make(map[string]*librpki.RPKITAL),
		Tals:                 tals,
		TalNames:             talNames,
		RRDPInfo:             make(map[string]RRDPInfo),
		PrevRepos:            make(map[string]time.Time),
		CurrentRepos:         make(map[string]time.Time),
		rsyncFetchJobManager: newRsyncFetchJobManager(),
		rrdpFetch:            make(map[string]string),
		rrdpFetchDomain:      make(map[string]string),
		Fetcher:              syncpki.NewLocalFetch(*Basepath),
		HTTPFetcher:          syncpki.NewHTTPFetcher(*UserAgent),
		ROAList:              newROAList(),
		stats:                newOctoRPKIStats(),
		InfoAuthorities:      make([][]SIA, 0),
		tracer:               opentracing.GlobalTracer(),
		DoCT:                 *CertTransparency,
		CTPath:               *CertTransparencyAddr,
		Filter:               *Filter,
	}
}

type rsyncFetchJobManager struct {
	rsyncFetchJobs   map[string]string
	rsyncFetchJobsMu sync.RWMutex
}

func newRsyncFetchJobManager() *rsyncFetchJobManager {
	return &rsyncFetchJobManager{
		rsyncFetchJobs: make(map[string]string),
	}
}

func (r *rsyncFetchJobManager) delete(job string) {
	r.rsyncFetchJobsMu.Lock()
	defer r.rsyncFetchJobsMu.Unlock()

	delete(r.rsyncFetchJobs, job)
}

func (r *rsyncFetchJobManager) get() map[string]string {
	r.rsyncFetchJobsMu.RLock()
	defer r.rsyncFetchJobsMu.RUnlock()

	ret := make(map[string]string, len(r.rsyncFetchJobs))
	for k, v := range r.rsyncFetchJobs {
		ret[k] = v
	}

	return ret
}

func (r *rsyncFetchJobManager) set(key, value string) {
	r.rsyncFetchJobsMu.Lock()
	defer r.rsyncFetchJobsMu.Unlock()

	r.rsyncFetchJobs[key] = value
}

func newROAList() *prefixfile.ROAList {
	return &prefixfile.ROAList{
		Data: make([]prefixfile.ROAJson, 0),
	}
}

func (s *OctoRPKI) validationLoop() {
	var spanActive bool
	var pSpan opentracing.Span
	var iterationsUntilStable int
	for {
		if !spanActive {
			pSpan = s.tracer.StartSpan("multoperation")
			spanActive = true
			iterationsUntilStable = 0
		}

		span := s.tracer.StartSpan("operation", opentracing.ChildOf(pSpan.Context()))

		s.stats.iterations.Add(1)
		iterationsUntilStable++
		span.SetTag("iteration", s.stats.iterations.Load())

		if *RRDP {
			s.doRRDP(span)
		}

		// HTTPs TAL
		s.mainTAL(span)
		s.TalsFetch = make(map[string]*librpki.RPKITAL) // clear decoded TAL for next iteration

		s.mainRsync(span)

		ctData := s.mainValidation(span)

		// Reduce
		changed := s.MainReduce()
		s.Stable.Store(!changed && s.stats.iterations.Load() > 1)
		s.HasPreviousStable.Store(s.Stable.Load())

		if *Mode == "oneoff" && (s.Stable.Load() || !*WaitStable) {
			s.mustOutput()
		}

		span.SetTag("stable", s.Stable.Load())
		span.Finish()

		// GHSA-g5gj-9ggf-9vmq: Prevent infinite repository traversal
		if iterationsUntilStable > *MaxIterations {
			// GHSA-pmw9-567p-68pc: Do not crash when MaxIterations is reached
			log.Warning("Max iterations has been reached. Defining current state as stable and stoppping deeper validation. This number can be adjusted with -max.iterations")
			s.Stable.Store(true)
		}

		if *Mode == "oneoff" && s.Stable.Load() {
			log.Info("Stable, terminating")
			break
		}

		// Certificate Transparency
		if s.DoCT && (s.Stable.Load() || !*WaitStable) {
			t1 := time.Now().UTC()

			s.SendCertificateTransparency(span, ctData, *CertTransparencyThreads, *CertTransparencyTimeout)

			t2 := time.Now().UTC()
			MetricOperationTime.With(
				prometheus.Labels{
					"type": "ct",
				}).
				Observe(float64(t2.Sub(t1).Seconds()))
		}

		if s.Stable.Load() {
			MetricLastStableValidation.Set(float64(s.LastComputed.Unix()))
			MetricState.Set(float64(1))

			pSpan.SetTag("iterations", iterationsUntilStable)
			pSpan.Finish()
			spanActive = false

			log.Infof("Stable state. Revalidating in %v", *Refresh)
			<-time.After(*Refresh)
			s.Stable.Store(false)
			continue
		}

		MetricState.Set(float64(0))
		log.Info("Still exploring. Revalidating now")
	}
}

func (s *OctoRPKI) mustOutput() {
	err := s.output()
	if err != nil {
		log.Fatalf("Output failed: %v", err)
	}
}

func (s *OctoRPKI) output() error {
	fc, err := json.Marshal(s.ROAList)
	if err != nil {
		return fmt.Errorf("unable to marshal ROA list: %v", err)
	}

	if *Output == "" {
		fmt.Println(string(fc))
	} else {
		err := ioutil.WriteFile(*Output, fc, 0600)
		if err != nil {
			return fmt.Errorf("Unable to write ROA list to %q: %v", *Output, err)
		}
	}

	return nil
}

func (s *OctoRPKI) doRRDP(span opentracing.Span) {
	t1 := time.Now()
	defer func() {
		t2 := time.Now()
		MetricOperationTime.With(prometheus.Labels{"type": "rrdp"}).Observe(float64(t2.Sub(t1).Seconds()))
	}()

	if *RRDPFile != "" {
		err := s.LoadRRDPInfo(*RRDPFile)
		if err != nil {
			sentry.CaptureException(err)
		}
	}

	s.mainRRDP(span)

	if *RRDPFile != "" {
		err := s.saveRRDPInfo(*RRDPFile)
		if err != nil {
			sentry.CaptureException(err)
		}
	}
}


================================================
FILE: cmd/octorpki/rrdp_fetcher.go
================================================
package main

import (
	"sync"

	"github.com/opentracing/opentracing-go"
)

type rrdpFetchJob struct {
	path  string
	rsync string
}

type rrdpFetcher struct {
	octoRPKI *OctoRPKI
	jobsCh   chan rrdpFetchJob
	wg       sync.WaitGroup
	span     opentracing.Span
}

func newRRDPFetcher(octoRPKI *OctoRPKI, workers int, span opentracing.Span) *rrdpFetcher {
	rf := &rrdpFetcher{
		octoRPKI: octoRPKI,
		jobsCh:   make(chan rrdpFetchJob),
		span:     span,
	}

	for i := 0; i < workers; i++ {
		rf.wg.Add(1)
		go rf.worker()
	}

	return rf
}

func (r *rrdpFetcher) worker() {
	defer r.wg.Done()

	for job := range r.jobsCh {
		r.octoRPKI.fetchRRDP(job.path, job.rsync, r.span)
	}
}

func (r *rrdpFetcher) done() {
	close(r.jobsCh)
}

func (r *rrdpFetcher) wait() {
	r.wg.Wait()
}

func (r *rrdpFetcher) fetch(path string, rsync string) {
	r.jobsCh <- rrdpFetchJob{
		path:  path,
		rsync: rsync,
	}
}


================================================
FILE: cmd/octorpki/rsync_fetcher.go
================================================
package main

import (
	"sync"

	"github.com/opentracing/opentracing-go"
)

type rsyncFetcher struct {
	octoRPKI *OctoRPKI
	jobsCh   chan string
	wg       sync.WaitGroup
	span     opentracing.Span
}

func newRsyncFetcher(octoRPKI *OctoRPKI, workers int, span opentracing.Span) *rsyncFetcher {
	rf := &rsyncFetcher{
		octoRPKI: octoRPKI,
		jobsCh:   make(chan string),
		span:     span,
	}

	for i := 0; i < workers; i++ {
		rf.wg.Add(1)
		go rf.worker()
	}

	return rf
}

func (r *rsyncFetcher) worker() {
	defer r.wg.Done()

	for rsyncURL := range r.jobsCh {
		r.octoRPKI.fetchRsync(rsyncURL, r.span)
	}
}

func (r *rsyncFetcher) done() {
	close(r.jobsCh)
}

func (r *rsyncFetcher) wait() {
	r.wg.Wait()
}

func (r *rsyncFetcher) fetch(rsync string) {
	r.jobsCh <- rsync
}


================================================
FILE: cmd/octorpki/tals/afrinic.tal
================================================
rsync://rpki.afrinic.net/repository/AfriNIC.cer
https://rpki.afrinic.net/repository/AfriNIC.cer

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxsAqAhWIO+ON2Ef9oRDM
pKxv+AfmSLIdLWJtjrvUyDxJPBjgR+kVrOHUeTaujygFUp49tuN5H2C1rUuQavTH
vve6xNF5fU3OkTcqEzMOZy+ctkbde2SRMVdvbO22+TH9gNhKDc9l7Vu01qU4LeJH
k3X0f5uu5346YrGAOSv6AaYBXVgXxa0s9ZvgqFpim50pReQe/WI3QwFKNgpPzfQL
6Y7fDPYdYaVOXPXSKtx7P4s4KLA/ZWmRL/bobw/i2fFviAGhDrjqqqum+/9w1hEl
L/vqihVnV18saKTnLvkItA/Bf5i11Yhw2K7qv573YWxyuqCknO/iYLTR1DToBZcZ
UQIDAQAB

================================================
FILE: cmd/octorpki/tals/apnic.tal
================================================
rsync://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer
http://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx9RWSL61YAAYumEiU8z8
qH2ETVIL01ilxZlzIL9JYSORMN5Cmtf8V2JblIealSqgOTGjvSjEsiV73s67zYQI
7C/iSOb96uf3/s86NqbxDiFQGN8qG7RNcdgVuUlAidl8WxvLNI8VhqbAB5uSg/Mr
LeSOvXRja041VptAxIhcGzDMvlAJRwkrYK/Mo8P4E2rSQgwqCgae0ebY1CsJ3Cjf
i67C1nw7oXqJJovvXJ4apGmEv8az23OLC6Ki54Ul/E6xk227BFttqFV3YMtKx42H
cCcDVZZy01n7JjzvO8ccaXmHIgR7utnqhBRNNq5Xc5ZhbkrUsNtiJmrZzVlgU6Ou
0wIDAQAB


================================================
FILE: cmd/octorpki/tals/arin.tal
================================================
rsync://rpki.arin.net/repository/arin-rpki-ta.cer
https://rrdp.arin.net/arin-rpki-ta.cer

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3lZPjbHvMRV5sDDqfLc/685th5FnreHMJjg8
pEZUbG8Y8TQxSBsDebbsDpl3Ov3Cj1WtdrJ3CIfQODCPrrJdOBSrMATeUbPC+JlNf2SRP3UB+VJFgtTj
0RN8cEYIuhBW5t6AxQbHhdNQH+A1F/OJdw0q9da2U29Lx85nfFxvnC1EpK9CbLJS4m37+RlpNbT1cba+
b+loXpx0Qcb1C4UpJCGDy7uNf5w6/+l7RpATAHqqsX4qCtwwDYlbHzp2xk9owF3mkCxzl0HwncO+sEHH
eaL3OjtwdIGrRGeHi2Mpt+mvWHhtQqVG+51MHTyg+nIjWFKKGx1Q9+KDx4wJStwveQIDAQAB


================================================
FILE: cmd/octorpki/tals/lacnic.tal
================================================
https://rrdp.lacnic.net/ta/rta-lacnic-rpki.cer
rsync://repository.lacnic.net/rpki/lacnic/rta-lacnic-rpki.cer

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZEzhYK0+PtDOPfub/KRc3MeWx3ne
Xx4/wbnJWGbNAtbYqXg3uU5J4HFzPgk/VIppgSKAhlO0H60DRP48by9gr5/yDHu2KXhOmnMg4
6sYsUIpfgtBS9+VtrqWziJfb+pkGtuOWeTnj6zBmBNZKK+5AlMCW1WPhrylIcB+XSZx8tk9GS
/3SMQ+YfMVwwAyYjsex14Uzto4GjONALE5oh1M3+glRQduD6vzSwOD+WahMbc9vCOTED+2McL
HRKgNaQf0YJ9a1jG9oJIvDkKXEqdfqDRktwyoD74cV57bW3tBAexB7GglITbInyQAsmdngtfg
2LUMrcROHHP86QPZINjDQIDAQAB


================================================
FILE: cmd/octorpki/tals/ripe.tal
================================================
rsync://rpki.ripe.net/ta/ripe-ncc-ta.cer
https://rpki.ripe.net/ta/ripe-ncc-ta.cer

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0URYSGqUz2myBsOzeW1j
Q6NsxNvlLMyhWknvnl8NiBCs/T/S2XuNKQNZ+wBZxIgPPV2pFBFeQAvoH/WK83Hw
A26V2siwm/MY2nKZ+Olw+wlpzlZ1p3Ipj2eNcKrmit8BwBC8xImzuCGaV0jkRB0G
Z0hoH6Ml03umLprRsn6v0xOP0+l6Qc1ZHMFVFb385IQ7FQQTcVIxrdeMsoyJq9eM
kE6DoclHhF/NlSllXubASQ9KUWqJ0+Ot3QCXr4LXECMfkpkVR2TZT+v5v658bHVs
6ZxRD1b6Uk1uQKAyHUbn/tXvP8lrjAibGzVsXDT2L0x4Edx+QdixPgOji3gBMyL2
VwIDAQAB


================================================
FILE: compose/docker-compose.yml
================================================
version: "3"
services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
  grafana:
    image: grafana/grafana
    ports:
      - 3000:3000
    volumes:
      - ./grafana-datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml
      - ./grafana-dashboard-provider.yml:/etc/grafana/provisioning/dashboards/provider.yml
      - ./grafana-dashboard-rpki.json:/var/lib/grafana/dashboards/rpki.json
  gortr-cf:
    image: cloudflare/gortr
    command: -bind :8283 -metrics.addr :8082
    ports:
      - 8283:8283
  gortr:
    image: cloudflare/gortr
    command: -bind :8282 -metrics.addr :8080 -cache http://octorpki:8081/output.json -verify.key /public.pem -refresh 60
    ports:
      - 8282:8282
    volumes:
      - ./public.pem:/public.pem:ro
  octorpki:
    image: cloudflare/octorpki
    # build:
    #   context: ../
    command: -http.addr :8081 -output.sign.key /private.pem -tracer=true -pprof=true
    environment:
      - JAEGER_ENDPOINT=http://jaeger:14268/api/traces
      - JAEGER_SERVICE_NAME=octorpki
      - JAEGER_SAMPLER_TYPE=const
      - JAEGER_SAMPLER_PARAM=1
      - JAEGER_REPORTER_LOG_SPANS=true
      - SENTRY_DSN
    ports:
      - 8081:8081
    volumes:
      - ./cache:/cache
      - ./private.pem:/private.pem:ro
      - ../cmd/octorpki/tals:/tals:ro
  jaeger:
    image: jaegertracing/all-in-one:1.18
    ports:
      - 16686:16686

================================================
FILE: compose/grafana-dashboard-provider.yml
================================================
apiVersion: 1

providers:
  - name: 'Provider'
    orgId: 1
    folder: ''
    folderUid: ''
    type: file
    disableDeletion: false
    editable: true
    updateIntervalSeconds: 10
    allowUiUpdates: false
    options:
      path: /var/lib/grafana/dashboards

================================================
FILE: compose/grafana-dashboard-rpki.json
================================================
{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      }
    ]
  },
  "description": "Shows the status of RPKI validation and the RTR server health.",
  "editable": true,
  "gnetId": 12501,
  "graphTooltip": 0,
  "id": 1,
  "iteration": 1592675948663,
  "links": [],
  "panels": [
    {
      "collapsed": false,
      "datasource": "Prometheus",
      "gridPos": {
        "h": 1,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "id": 6,
      "panels": [],
      "title": "RTR server",
      "type": "row"
    },
    {
      "datasource": "Prometheus",
      "description": "",
      "fieldConfig": {
        "defaults": {
          "custom": {},
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "rgb(191, 191, 191)",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 5,
        "w": 6,
        "x": 0,
        "y": 1
      },
      "id": 2,
      "options": {
        "colorMode": "value",
        "graphMode": "none",
        "justifyMode": "auto",
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "last"
          ],
          "fields": "",
          "values": false
        }
      },
      "pluginVersion": "7.0.3",
      "targets": [
        {
          "expr": "min(rpki_roas{filtered=\"filtered\",ip_version=\"ipv4\", instance=\"$node_rtr\"}) by (ip_version)",
          "instant": false,
          "interval": "",
          "legendFormat": "{{ ip_version }}",
          "refId": "A"
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "IPv4 ROAs",
      "type": "stat"
    },
    {
      "datasource": "Prometheus",
      "description": "",
      "fieldConfig": {
        "defaults": {
          "custom": {},
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "rgb(191, 191, 191)",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 5,
        "w": 6,
        "x": 6,
        "y": 1
      },
      "id": 11,
      "options": {
        "colorMode": "value",
        "graphMode": "none",
        "justifyMode": "auto",
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "last"
          ],
          "fields": "",
          "values": false
        }
      },
      "pluginVersion": "7.0.3",
      "targets": [
        {
          "expr": "min(rpki_roas{filtered=\"filtered\",ip_version=\"ipv6\", instance=\"$node_rtr\"}) by (ip_version)",
          "instant": false,
          "interval": "",
          "legendFormat": "{{ ip_version }}",
          "refId": "A"
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "IPv6 ROAs",
      "type": "stat"
    },
    {
      "datasource": "Prometheus",
      "description": "",
      "fieldConfig": {
        "defaults": {
          "custom": {},
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "rgb(191, 191, 191)",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 5,
        "w": 6,
        "x": 12,
        "y": 1
      },
      "id": 12,
      "options": {
        "colorMode": "value",
        "graphMode": "none",
        "justifyMode": "auto",
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "last"
          ],
          "fields": "",
          "values": false
        }
      },
      "pluginVersion": "7.0.3",
      "targets": [
        {
          "expr": "sum(rtr_clients{instance=\"$node_rtr\"})",
          "instant": false,
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "Connected clients",
      "type": "stat"
    },
    {
      "datasource": "Prometheus",
      "fieldConfig": {
        "defaults": {
          "custom": {},
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "super-light-yellow",
                "value": 300
              },
              {
                "color": "super-light-red",
                "value": 600
              }
            ]
          },
          "unit": "s"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 5,
        "w": 6,
        "x": 18,
        "y": 1
      },
      "id": 18,
      "options": {
        "colorMode": "value",
        "graphMode": "none",
        "justifyMode": "auto",
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "last"
          ],
          "fields": "",
          "values": false
        }
      },
      "pluginVersion": "7.0.3",
      "targets": [
        {
          "expr": "avg(time() - rpki_refresh{instance=\"$node_rtr\"})",
          "instant": false,
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "Last fetch",
      "type": "stat"
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": "Prometheus",
      "decimals": 0,
      "description": "",
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 2,
      "fillGradient": 5,
      "gridPos": {
        "h": 8,
        "w": 18,
        "x": 0,
        "y": 6
      },
      "hiddenSeries": false,
      "id": 16,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": true,
        "max": false,
        "min": false,
        "rightSide": true,
        "show": true,
        "sort": "current",
        "sortDesc": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "dataLinks": []
      },
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": true,
      "steppedLine": false,
      "targets": [
        {
          "expr": "sum(rate(rtr_pdus{instance=\"$node_rtr\"}[1m])) by (type)",
          "interval": "",
          "legendFormat": "{{ type }}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "RTR PDU",
      "tooltip": {
        "shared": true,
        "sort": 1,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "decimals": 0,
          "format": "none",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": "0",
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": false
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "datasource": "Prometheus",
      "description": "",
      "fieldConfig": {
        "defaults": {
          "custom": {},
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "rgb(191, 191, 191)",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 8,
        "w": 6,
        "x": 18,
        "y": 6
      },
      "id": 17,
      "options": {
        "colorMode": "value",
        "graphMode": "none",
        "justifyMode": "auto",
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "last"
          ],
          "fields": "",
          "values": false
        }
      },
      "pluginVersion": "7.0.3",
      "targets": [
        {
          "expr": "sum(rtr_pdus{instance=\"$node_rtr\"}) by (type)",
          "interval": "",
          "legendFormat": "{{ type }}",
          "refId": "A"
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "Message count",
      "type": "stat"
    },
    {
      "collapsed": false,
      "datasource": "Prometheus",
      "gridPos": {
        "h": 1,
        "w": 24,
        "x": 0,
        "y": 14
      },
      "id": 10,
      "panels": [],
      "title": "Validator",
      "type": "row"
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": "Prometheus",
      "decimals": 0,
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 2,
      "fillGradient": 5,
      "gridPos": {
        "h": 8,
        "w": 17,
        "x": 0,
        "y": 15
      },
      "hiddenSeries": false,
      "id": 15,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": true,
        "max": false,
        "min": false,
        "rightSide": true,
        "show": true,
        "sort": "current",
        "sortDesc": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "dataLinks": []
      },
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": true,
      "steppedLine": false,
      "targets": [
        {
          "expr": "avg(roas{ta!=\"\",instance=\"$node_validator\"}) by (ta) > 0",
          "interval": "",
          "legendFormat": "{{ ta }}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "ROAs per TAL",
      "tooltip": {
        "shared": true,
        "sort": 1,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "decimals": 0,
          "format": "none",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": "0",
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": false
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "datasource": "Prometheus",
      "fieldConfig": {
        "defaults": {
          "custom": {},
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "super-light-yellow",
                "value": 600
              },
              {
                "color": "super-light-red",
                "value": 900
              }
            ]
          },
          "unit": "s"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 8,
        "w": 7,
        "x": 17,
        "y": 15
      },
      "id": 14,
      "options": {
        "colorMode": "value",
        "graphMode": "none",
        "justifyMode": "auto",
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "last"
          ],
          "fields": "",
          "values": false
        }
      },
      "pluginVersion": "7.0.3",
      "targets": [
        {
          "expr": "max(time()-last_stable_validation{instance=\"$node_validator\"}) < 1000000",
          "instant": false,
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "Last validation",
      "type": "stat"
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": "Prometheus",
      "fieldConfig": {
        "defaults": {
          "custom": {}
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 4,
      "gridPos": {
        "h": 8,
        "w": 24,
        "x": 0,
        "y": 23
      },
      "hiddenSeries": false,
      "id": 13,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": true,
        "max": false,
        "min": false,
        "rightSide": true,
        "show": true,
        "sort": "current",
        "sortDesc": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "dataLinks": []
      },
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "sum(file_count_sia{instance=\"$node_validator\"}) by (address, type)",
          "interval": "",
          "legendFormat": "{{ type }} {{ address }}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "Endpoints",
      "tooltip": {
        "shared": false,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    }
  ],
  "refresh": false,
  "schemaVersion": 25,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": [
      {
        "allValue": null,
        "current": {
          "selected": false,
          "text": "octorpki:8081",
          "value": "octorpki:8081"
        },
        "datasource": "Prometheus",
        "definition": "label_values(last_stable_validation, instance)",
        "hide": 0,
        "includeAll": false,
        "label": "Validator node",
        "multi": false,
        "name": "node_validator",
        "options": [],
        "query": "label_values(last_stable_validation, instance)",
        "refresh": 2,
        "regex": "",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": null,
        "current": {
          "selected": false,
          "text": "gortr-cf:8082",
          "value": "gortr-cf:8082"
        },
        "datasource": "Prometheus",
        "definition": "label_values(rpki_roas, instance)",
        "hide": 0,
        "includeAll": false,
        "label": "RTR node",
        "multi": false,
        "name": "node_rtr",
        "options": [],
        "query": "label_values(rpki_roas, instance)",
        "refresh": 2,
        "regex": "",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      }
    ]
  },
  "time": {
    "from": "now-3h",
    "to": "now"
  },
  "timepicker": {
    "refresh_intervals": [
      "10s",
      "30s",
      "1m",
      "5m",
      "15m",
      "30m",
      "1h",
      "2h",
      "1d"
    ]
  },
  "timezone": "",
  "title": "OctoRPKI - GoRTR",
  "uid": "rpki",
  "version": 1
}

================================================
FILE: compose/grafana-datasources.yml
================================================
apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    url: http://prometheus:9090
    access: proxy


================================================
FILE: compose/private.pem
================================================
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJ/JtiRkVppbKPH1LVm8dqc1DxgfBAqnkqwwUn2zit4eoAoGCCqGSM49
AwEHoUQDQgAEn7QdFabWI12YqsGadC+XLZq1Jlqed33aaZuLX+3UV86opBux4QhU
qz69Tqf6NtE76lQernEXoN4t1FHbzAERNw==
-----END EC PRIVATE KEY-----


================================================
FILE: compose/prometheus.yml
================================================
global:
  scrape_interval:     15s
  evaluation_interval: 15s
alerting:
  alertmanagers:
  - static_configs:
    - targets:
rule_files:
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']
  - job_name: 'gortr'
    static_configs:
    - targets: ['gortr:8080', 'gortr-cf:8082']
  - job_name: 'octorpki'
    static_configs:
    - targets: ['octorpki:8081']


================================================
FILE: compose/public.pem
================================================
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEn7QdFabWI12YqsGadC+XLZq1Jlqe
d33aaZuLX+3UV86opBux4QhUqz69Tqf6NtE76lQernEXoN4t1FHbzAERNw==
-----END PUBLIC KEY-----


================================================
FILE: go.mod
================================================
module github.com/cloudflare/cfrpki

go 1.19

require (
	github.com/cloudflare/gortr v0.14.7
	github.com/getsentry/sentry-go v0.19.0
	github.com/golang/protobuf v1.5.3
	github.com/google/certificate-transparency-go v1.1.4
	github.com/kentik/patricia v1.2.0
	github.com/opentracing/opentracing-go v1.2.0
	github.com/prometheus/client_golang v1.14.0
	github.com/rs/cors v1.8.3
	github.com/sirupsen/logrus v1.9.0
	github.com/stretchr/testify v1.8.2
	github.com/uber/jaeger-client-go v2.30.0+incompatible
	google.golang.org/grpc v1.54.0
)

require (
	github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
	github.com/beorn7/perks v1.0.1 // indirect
	github.com/cespare/xxhash/v2 v2.2.0 // indirect
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/go-logr/logr v1.2.3 // indirect
	github.com/kr/pretty v0.2.1 // indirect
	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
	github.com/pkg/errors v0.9.1 // indirect
	github.com/pmezard/go-difflib v1.0.0 // indirect
	github.com/prometheus/client_model v0.3.0 // indirect
	github.com/prometheus/common v0.42.0 // indirect
	github.com/prometheus/procfs v0.9.0 // indirect
	github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
	go.uber.org/atomic v1.10.0 // indirect
	golang.org/x/crypto v0.7.0 // indirect
	golang.org/x/net v0.8.0 // indirect
	golang.org/x/sys v0.6.0 // indirect
	golang.org/x/text v0.8.0 // indirect
	google.golang.org/genproto v0.0.0-20230327215041-6ac7f18bb9d5 // indirect
	google.golang.org/protobuf v1.30.0 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
	k8s.io/klog/v2 v2.90.1 // indirect
)

replace github.com/codahale/hdrhistogram => github.com/HdrHistogram/hdrhistogram-go v0.9.0


================================================
FILE: go.sum
================================================
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudflare/gortr v0.14.7 h1:QlZRNa1O7heqgLk9ijwKtPigjzqvDHdPSwmSqSbiPaE=
github.com/cloudflare/gortr v0.14.7/go.mod h1:yoHGJMn0B2FNVfONrd1SnAV2fc0Z/DZFxXVU3jagN7k=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM=
github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY=
github.com/google/certificate-transparency-go v1.1.4/go.mod h1:D6lvbfwckhNrbM9WVl1EVeMOyzC19mpIjMOI4nxBHtQ=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kentik/patricia v1.2.0 h1:WZcp8V8GQhsya0bMZuXktEH/Wz+aBlhiMle4tExkj6M=
github.com/kentik/patricia v1.2.0/go.mod h1:6jY40ESetsbfi04/S12iJlsiS6DYL2B2W+WAcqoDHtw=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo=
github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
google.golang.org/genproto v0.0.0-20230327215041-6ac7f18bb9d5 h1:Kd6tRRHXw8z4TlPlWi+NaK10gsePL6GdZBQChptOLGA=
google.golang.org/genproto v0.0.0-20230327215041-6ac7f18bb9d5/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=


================================================
FILE: ov/ov.go
================================================
// Origin validator

package ov

import (
	"errors"
	"net"

	"github.com/kentik/patricia"
	"github.com/kentik/patricia/int64_tree"
)

const (
	STATE_UNKNOWN = iota
	STATE_INVALID
	STATE_VALID
)

var (
	StateToName = map[int]string{
		STATE_UNKNOWN: "NotFound",
		STATE_INVALID: "Invalid",
		STATE_VALID:   "Valid",
	}
)

type AbstractROA interface {
	GetASN() uint32
	GetMaxLen() int
	GetPrefix() *net.IPNet
}

type AbstractRoute interface {
	GetPrefix() *net.IPNet
	GetASN() uint32
}

type OriginValidator struct {
	vrp []AbstractROA
	t4  *int64_tree.TreeV4
	t6  *int64_tree.TreeV6
}

// vrp: Validated ROA Payload https://tools.ietf.org/html/rfc6811
func NewOV(vrp []AbstractROA) *OriginValidator {
	t4 := int64_tree.NewTreeV4()
	t6 := int64_tree.NewTreeV6()

	for i, r := range vrp {
		ip4, ip6, _ := patricia.ParseFromIPAddr(r.GetPrefix())
		if ip4 != nil {
			t4.Add(*ip4, int64(i), nil)
		} else if ip6 != nil {
			t6.Add(*ip6, int64(i), nil)
		}
	}

	return &OriginValidator{vrp: vrp, t4: t4, t6: t6}
}

type curValidation struct {
	state    int
	route    AbstractRoute
	ov       *OriginValidator
	matching []AbstractROA
}

func (cv *curValidation) Filter(payload int64) bool {
	roa := cv.ov.vrp[payload]
	// Specs https://tools.ietf.org/html/rfc6811
	if cv.state != STATE_VALID {
		mask, _ := cv.route.GetPrefix().Mask.Size()
		if cv.route.GetASN() == roa.GetASN() && mask <= roa.GetMaxLen() {
			cv.state = STATE_VALID
		} else {
			cv.state = STATE_INVALID
		}
	}
	cv.matching = append(cv.matching, roa)
	return true
}

func (ov *OriginValidator) Validate(route AbstractRoute) ([]AbstractROA, int, error) {
	matching := make([]AbstractROA, 0)
	ip4, ip6, err := patricia.ParseFromIPAddr(route.GetPrefix())

	if err != nil {
		return matching, STATE_UNKNOWN, err
	}

	cv := curValidation{
		route:    route,
		ov:       ov,
		state:    STATE_UNKNOWN,
		matching: matching,
	}
	if ip4 != nil {
		ov.t4.FindTagsWithFilter(*ip4, cv.Filter)
	} else if ip6 != nil {
		ov.t6.FindTagsWithFilter(*ip6, cv.Filter)
	} else {
		return cv.matching, cv.state, errors.New("Unknown IP type")
	}

	return cv.matching, cv.state, nil
}


================================================
FILE: ov/ov_test.go
================================================
package ov

import (
	"github.com/stretchr/testify/assert"
	"net"
	"testing"
)

type TestROA struct {
	ASN       uint32
	Prefix    *net.IPNet
	MaxLength int
}

func (r *TestROA) GetPrefix() *net.IPNet {
	return r.Prefix
}

func (r *TestROA) GetASN() uint32 {
	return r.ASN
}

func (r *TestROA) GetMaxLen() int {
	return r.MaxLength
}

type TestRoute struct {
	ASN    uint32
	Prefix *net.IPNet
}

func (r *TestRoute) GetPrefix() *net.IPNet {
	return r.Prefix
}

func (r *TestRoute) GetASN() uint32 {
	return r.ASN
}

func MakeData() ([]AbstractROA, AbstractRoute) {
	_, ip1, _ := net.ParseCIDR("10.0.0.0/16")
	_, ip2, _ := net.ParseCIDR("10.0.0.0/22")
	_, ip3, _ := net.ParseCIDR("10.0.0.0/24")
	_, ip4, _ := net.ParseCIDR("10.0.0.0/25")

	vrp := []AbstractROA{
		&TestROA{
			65001,
			ip1,
			24,
		},
		&TestROA{
			65002,
			ip2,
			23,
		},
		&TestROA{
			65003,
			ip3,
			24,
		},
		&TestROA{
			65004,
			ip4,
			26,
		},
	}
	_, ip5, _ := net.ParseCIDR("10.0.0.0/24")
	route := &TestRoute{
		65003,
		ip5,
	}
	return vrp, route
}

func TestValid(t *testing.T) {
	vrp, route := MakeData()
	ov := NewOV(vrp)
	matching, state, err := ov.Validate(route)
	assert.Nil(t, err)
	assert.Equal(t, 3, len(matching))
	assert.Equal(t, STATE_VALID, state)
}

func TestInvalid(t *testing.T) {
	vrp, route := MakeData()
	ov := NewOV(vrp[0:2])
	matching, state, err := ov.Validate(route)
	assert.Nil(t, err)
	assert.Equal(t, 2, len(matching))
	assert.Equal(t, STATE_INVALID, state)
}

func TestUnknown(t *testing.T) {
	vrp, route := MakeData()
	ov := NewOV(vrp[3:3])
	matching, state, err := ov.Validate(route)
	assert.Nil(t, err)
	assert.Equal(t, 0, len(matching))
	assert.Equal(t, STATE_UNKNOWN, state)
}


================================================
FILE: package/after-install-octorpki.sh
================================================
#!/bin/bash

set -x

addgroup --system octorpki
adduser --system --home /var/lib/octorpki --shell /usr/sbin/nologin --disabled-login --group octorpki

systemctl daemon-reload
systemctl enable octorpki.service
systemctl start octorpki

exit 0


================================================
FILE: package/before-remove-octorpki.sh
================================================
#!/bin/bash

set -x

systemctl stop octorpki
systemctl disable octorpki

deluser octorpki
delgroup octorpki

exit 0


================================================
FILE: package/octorpki.env
================================================
OCTORPKI_ARGS=-output.sign=false

================================================
FILE: package/octorpki.service
================================================
[Unit]
Description=OctoRPKI
After=network.target

[Service]
Type=simple
EnvironmentFile=/etc/default/octorpki
WorkingDirectory=/usr/share/octorpki
ExecStart=/usr/bin/octorpki $OCTORPKI_ARGS
User=octorpki
Group=octorpki

[Install]
WantedBy=multi-user.target

================================================
FILE: sync/api/cfrpki.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: cfrpki.proto

package cfrpki

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	grpc "google.golang.org/grpc"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type RRDPInfoQuery struct {
	RRDP                 string   `protobuf:"bytes,1,opt,name=RRDP,proto3" json:"RRDP,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *RRDPInfoQuery) Reset()         { *m = RRDPInfoQuery{} }
func (m *RRDPInfoQuery) String() string { return proto.CompactTextString(m) }
func (*RRDPInfoQuery) ProtoMessage()    {}
func (*RRDPInfoQuery) Descriptor() ([]byte, []int) {
	return fileDescriptor_0b755a2b9c60ee6c, []int{0}
}

func (m *RRDPInfoQuery) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_RRDPInfoQuery.Unmarshal(m, b)
}
func (m *RRDPInfoQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_RRDPInfoQuery.Marshal(b, m, deterministic)
}
func (m *RRDPInfoQuery) XXX_Merge(src proto.Message) {
	xxx_messageInfo_RRDPInfoQuery.Merge(m, src)
}
func (m *RRDPInfoQuery) XXX_Size() int {
	return xxx_messageInfo_RRDPInfoQuery.Size(m)
}
func (m *RRDPInfoQuery) XXX_DiscardUnknown() {
	xxx_messageInfo_RRDPInfoQuery.DiscardUnknown(m)
}

var xxx_messageInfo_RRDPInfoQuery proto.InternalMessageInfo

func (m *RRDPInfoQuery) GetRRDP() string {
	if m != nil {
		return m.RRDP
	}
	return ""
}

type RRDPInfo struct {
	RRDP                 string   `protobuf:"bytes,1,opt,name=RRDP,proto3" json:"RRDP,omitempty"`
	SessionID            string   `protobuf:"bytes,2,opt,name=SessionID,proto3" json:"SessionID,omitempty"`
	Serial               int64    `protobuf:"varint,3,opt,name=Serial,proto3" json:"Serial,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *RRDPInfo) Reset()         { *m = RRDPInfo{} }
func (m *RRDPInfo) String() string { return proto.CompactTextString(m) }
func (*RRDPInfo) ProtoMessage()    {}
func (*RRDPInfo) Descriptor() ([]byte, []int) {
	return fileDescriptor_0b755a2b9c60ee6c, []int{1}
}

func (m *RRDPInfo) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_RRDPInfo.Unmarshal(m, b)
}
func (m *RRDPInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_RRDPInfo.Marshal(b, m, deterministic)
}
func (m *RRDPInfo) XXX_Merge(src proto.Message) {
	xxx_messageInfo_RRDPInfo.Merge(m, src)
}
func (m *RRDPInfo) XXX_Size() int {
	return xxx_messageInfo_RRDPInfo.Size(m)
}
func (m *RRDPInfo) XXX_DiscardUnknown() {
	xxx_messageInfo_RRDPInfo.DiscardUnknown(m)
}

var xxx_messageInfo_RRDPInfo proto.InternalMessageInfo

func (m *RRDPInfo) GetRRDP() string {
	if m != nil {
		return m.RRDP
	}
	return ""
}

func (m *RRDPInfo) GetSessionID() string {
	if m != nil {
		return m.SessionID
	}
	return ""
}

func (m *RRDPInfo) GetSerial() int64 {
	if m != nil {
		return m.Serial
	}
	return 0
}

type ResourceQuery struct {
	Path                 string   `protobuf:"bytes,1,opt,name=Path,proto3" json:"Path,omitempty"`
	RRDP                 string   `protobuf:"bytes,2,opt,name=RRDP,proto3" json:"RRDP,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *ResourceQuery) Reset()         { *m = ResourceQuery{} }
func (m *ResourceQuery) String() string { return proto.CompactTextString(m) }
func (*ResourceQuery) ProtoMessage()    {}
func (*ResourceQuery) Descriptor() ([]byte, []int) {
	return fileDescriptor_0b755a2b9c60ee6c, []int{2}
}

func (m *ResourceQuery) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_ResourceQuery.Unmarshal(m, b)
}
func (m *ResourceQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_ResourceQuery.Marshal(b, m, deterministic)
}
func (m *ResourceQuery) XXX_Merge(src proto.Message) {
	xxx_messageInfo_ResourceQuery.Merge(m, src)
}
func (m *ResourceQuery) XXX_Size() int {
	return xxx_messageInfo_ResourceQuery.Size(m)
}
func (m *ResourceQuery) XXX_DiscardUnknown() {
	xxx_messageInfo_ResourceQuery.DiscardUnknown(m)
}

var xxx_messageInfo_ResourceQuery proto.InternalMessageInfo

func (m *ResourceQuery) GetPath() string {
	if m != nil {
		return m.Path
	}
	return ""
}

func (m *ResourceQuery) GetRRDP() string {
	if m != nil {
		return m.RRDP
	}
	return ""
}

type ResourceData struct {
	Path                 string   `protobuf:"bytes,1,opt,name=Path,proto3" json:"Path,omitempty"`
	Data                 []byte   `protobuf:"bytes,2,opt,name=Data,proto3" json:"Data,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *ResourceData) Reset()         { *m = ResourceData{} }
func (m *ResourceData) String() string { return proto.CompactTextString(m) }
func (*ResourceData) ProtoMessage()    {}
func (*ResourceData) Descriptor() ([]byte, []int) {
	return fileDescriptor_0b755a2b9c60ee6c, []int{3}
}

func (m *ResourceData) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_ResourceData.Unmarshal(m, b)
}
func (m *ResourceData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_ResourceData.Marshal(b, m, deterministic)
}
func (m *ResourceData) XXX_Merge(src proto.Message) {
	xxx_messageInfo_ResourceData.Merge(m, src)
}
func (m *ResourceData) XXX_Size() int {
	return xxx_messageInfo_ResourceData.Size(m)
}
func (m *ResourceData) XXX_DiscardUnknown() {
	xxx_messageInfo_ResourceData.DiscardUnknown(m)
}

var xxx_messageInfo_ResourceData proto.InternalMessageInfo

func (m *ResourceData) GetPath() string {
	if m != nil {
		return m.Path
	}
	return ""
}

func (m *ResourceData) GetData() []byte {
	if m != nil {
		return m.Data
	}
	return nil
}

type FetchQuery struct {
	Path                 string   `protobuf:"bytes,1,opt,name=Path,proto3" json:"Path,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *FetchQuery) Reset()         { *m = FetchQuery{} }
func (m *FetchQuery) String() string { return proto.CompactTextString(m) }
func (*FetchQuery) ProtoMessage()    {}
func (*FetchQuery) Descriptor() ([]byte, []int) {
	return fileDescriptor_0b755a2b9c60ee6c, []int{4}
}

func (m *FetchQuery) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_FetchQuery.Unmarshal(m, b)
}
func (m *FetchQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_FetchQuery.Marshal(b, m, deterministic)
}
func (m *FetchQuery) XXX_Merge(src proto.Message) {
	xxx_messageInfo_FetchQuery.Merge(m, src)
}
func (m *FetchQuery) XXX_Size() int {
	return xxx_messageInfo_FetchQuery.Size(m)
}
func (m *FetchQuery) XXX_DiscardUnknown() {
	xxx_messageInfo_FetchQuery.DiscardUnknown(m)
}

var xxx_messageInfo_FetchQuery proto.InternalMessageInfo

func (m *FetchQuery) GetPath() string {
	if m != nil {
		return m.Path
	}
	return ""
}

type SIA struct {
	RSYNC                string   `protobuf:"bytes,1,opt,name=RSYNC,proto3" json:"RSYNC,omitempty"`
	RRDP                 string   `protobuf:"bytes,2,opt,name=RRDP,proto3" json:"RRDP,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *SIA) Reset()         { *m = SIA{} }
func (m *SIA) String() string { return proto.CompactTextString(m) }
func (*SIA) ProtoMessage()    {}
func (*SIA) Descriptor() ([]byte, []int) {
	return fileDescriptor_0b755a2b9c60ee6c, []int{5}
}

func (m *SIA) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_SIA.Unmarshal(m, b)
}
func (m *SIA) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_SIA.Marshal(b, m, deterministic)
}
func (m *SIA) XXX_Merge(src proto.Message) {
	xxx_messageInfo_SIA.Merge(m, src)
}
func (m *SIA) XXX_Size() int {
	return xxx_messageInfo_SIA.Size(m)
}
func (m *SIA) XXX_DiscardUnknown() {
	xxx_messageInfo_SIA.DiscardUnknown(m)
}

var xxx_messageInfo_SIA proto.InternalMessageInfo

func (m *SIA) GetRSYNC() string {
	if m != nil {
		return m.RSYNC
	}
	return ""
}

func (m *SIA) GetRRDP() string {
	if m != nil {
		return m.RRDP
	}
	return ""
}

type OperationResponse struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *OperationResponse) Reset()         { *m = OperationResponse{} }
func (m *OperationResponse) String() string { return proto.CompactTextString(m) }
func (*OperationResponse) ProtoMessage()    {}
func (*OperationResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_0b755a2b9c60ee6c, []int{6}
}

func (m *OperationResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_OperationResponse.Unmarshal(m, b)
}
func (m *OperationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_OperationResponse.Marshal(b, m, deterministic)
}
func (m *OperationResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_OperationResponse.Merge(m, src)
}
func (m *OperationResponse) XXX_Size() int {
	return xxx_messageInfo_OperationResponse.Size(m)
}
func (m *OperationResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_OperationResponse.DiscardUnknown(m)
}

var xxx_messageInfo_OperationResponse proto.InternalMessageInfo

func init() {
	proto.RegisterType((*RRDPInfoQuery)(nil), "RRDPInfoQuery")
	proto.RegisterType((*RRDPInfo)(nil), "RRDPInfo")
	proto.RegisterType((*ResourceQuery)(nil), "ResourceQuery")
	proto.RegisterType((*ResourceData)(nil), "ResourceData")
	proto.RegisterType((*FetchQuery)(nil), "FetchQuery")
	proto.RegisterType((*SIA)(nil), "SIA")
	proto.RegisterType((*OperationResponse)(nil), "OperationResponse")
}

func init() { proto.RegisterFile("cfrpki.proto", fileDescriptor_0b755a2b9c60ee6c) }

var fileDescriptor_0b755a2b9c60ee6c = []byte{
	// 364 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x4d, 0x4b, 0xfb, 0x40,
	0x10, 0xc6, 0x9b, 0xa6, 0xff, 0xbe, 0x4c, 0x93, 0xc2, 0x7f, 0x15, 0x29, 0xc1, 0x43, 0x5d, 0x29,
	0x14, 0x85, 0x55, 0x2b, 0xe8, 0xb9, 0x18, 0x5a, 0x82, 0xa0, 0x71, 0xe3, 0xc5, 0x63, 0x5a, 0xa6,
	0x34, 0x18, 0xb2, 0x21, 0xbb, 0x3d, 0xf4, 0xcb, 0xf8, 0x59, 0x25, 0xdb, 0xa6, 0x2f, 0xd8, 0xa0,
	0xb7, 0xd9, 0x9d, 0xdf, 0x93, 0x67, 0x9e, 0xcd, 0x80, 0x35, 0x9b, 0x67, 0xe9, 0x67, 0xc4, 0xd2,
	0x4c, 0x28, 0x41, 0x2f, 0xc1, 0xe6, 0xdc, 0xf5, 0xbd, 0x64, 0x2e, 0xde, 0x96, 0x98, 0xad, 0x08,
	0x81, 0x5a, 0x7e, 0xd1, 0x35, 0x7a, 0xc6, 0xa0, 0xc5, 0x75, 0x4d, 0xdf, 0xa1, 0x59, 0x40, 0xc7,
	0xfa, 0xe4, 0x1c, 0x5a, 0x01, 0x4a, 0x19, 0x89, 0xc4, 0x73, 0xbb, 0x55, 0xdd, 0xd8, 0x5d, 0x90,
	0x33, 0xa8, 0x07, 0x98, 0x45, 0x61, 0xdc, 0x35, 0x7b, 0xc6, 0xc0, 0xe4, 0x9b, 0x13, 0x7d, 0x04,
	0x9b, 0xa3, 0x14, 0xcb, 0x6c, 0x86, 0x5b, 0x6b, 0x3f, 0x54, 0x8b, 0xe2, 0xd3, 0x79, 0xbd, 0xb5,
	0xab, 0xee, 0x8d, 0xf3, 0x00, 0x56, 0x21, 0x74, 0x43, 0x15, 0x96, 0xe9, 0xf2, 0x9e, 0xd6, 0x59,
	0x5c, 0xd7, 0xb4, 0x07, 0x30, 0x46, 0x35, 0x5b, 0x94, 0xba, 0xd1, 0x1b, 0x30, 0x03, 0x6f, 0x44,
	0x4e, 0xe1, 0x1f, 0x0f, 0x3e, 0x5e, 0x9e, 0x36, 0xbd, 0xf5, 0xe1, 0xe8, 0x28, 0x27, 0xf0, 0xff,
	0x35, 0xc5, 0x2c, 0x54, 0x91, 0x48, 0x38, 0xca, 0x54, 0x24, 0x12, 0x87, 0x5f, 0x26, 0x34, 0xb8,
	0xff, 0xec, 0x8d, 0x7c, 0x8f, 0x30, 0x68, 0x4f, 0x50, 0x15, 0xe3, 0x92, 0x0e, 0x3b, 0x88, 0xec,
	0xd8, 0x6c, 0x3f, 0x09, 0xad, 0x90, 0x21, 0xd8, 0x9a, 0x4f, 0x85, 0x8c, 0x94, 0xc8, 0x56, 0xbf,
	0x2a, 0x6e, 0x0d, 0xd2, 0x07, 0x6b, 0x82, 0x4a, 0x47, 0xd3, 0xbf, 0xa3, 0xcd, 0x76, 0x31, 0x9d,
	0x1a, 0x0b, 0xbc, 0x91, 0xc6, 0x2e, 0xa0, 0x59, 0x60, 0x65, 0xc8, 0x10, 0xda, 0xfe, 0x72, 0x1a,
	0x47, 0x72, 0x31, 0x8e, 0x62, 0x24, 0x87, 0x5e, 0x0e, 0x61, 0x3f, 0xb2, 0xd2, 0x0a, 0xb9, 0x03,
	0x70, 0x31, 0x46, 0x85, 0x7f, 0x97, 0xf4, 0xa1, 0xe1, 0x0b, 0xa9, 0xf2, 0xa7, 0xd6, 0xde, 0x25,
	0xd8, 0x35, 0x34, 0x73, 0x4c, 0x67, 0x6a, 0xb1, 0x62, 0x03, 0x4b, 0xe0, 0xab, 0xf5, 0x43, 0x17,
	0x6b, 0xda, 0x61, 0x07, 0x6b, 0xed, 0xec, 0xf4, 0xb4, 0x32, 0xad, 0xeb, 0xdd, 0xbf, 0xff, 0x0e,
	0x00, 0x00, 0xff, 0xff, 0xa9, 0x80, 0x24, 0x14, 0x0b, 0x03, 0x00, 0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4

// RPKIAPIClient is the client API for RPKIAPI service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type RPKIAPIClient interface {
	GetResource(ctx context.Context, in *ResourceQuery, opts ...grpc.CallOption) (*ResourceData, error)
	GetRepository(ctx context.Context, in *ResourceQuery, opts ...grpc.CallOption) (RPKIAPI_GetRepositoryClient, error)
	GetFetchRRDP(ctx context.Context, in *FetchQuery, opts ...grpc.CallOption) (RPKIAPI_GetFetchRRDPClient, error)
	GetFetch(ctx context.Context, in *FetchQuery, opts ...grpc.CallOption) (RPKIAPI_GetFetchClient, error)
	PublishFile(ctx context.Context, in *ResourceData, opts ...grpc.CallOption) (*OperationResponse, error)
	DeleteFile(ctx context.Context, in *ResourceData, opts ...grpc.CallOption) (*OperationResponse, error)
	PostSIA(ctx context.Context, in *SIA, opts ...grpc.CallOption) (*OperationResponse, error)
	PostRRDP(ctx context.Context, in *RRDPInfo, opts ...grpc.CallOption) (*OperationResponse, error)
	GetRRDPInfo(ctx context.Context, in *RRDPInfoQuery, opts ...grpc.CallOption) (*RRDPInfo, error)
}

type rPKIAPIClient struct {
	cc *grpc.ClientConn
}

func NewRPKIAPIClient(cc *grpc.ClientConn) RPKIAPIClient {
	return &rPKIAPIClient{cc}
}

func (c *rPKIAPIClient) GetResource(ctx context.Context, in *ResourceQuery, opts ...grpc.CallOption) (*ResourceData, error) {
	out := new(ResourceData)
	err := c.cc.Invoke(ctx, "/RPKIAPI/GetResource", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *rPKIAPIClient) GetRepository(ctx context.Context, in *ResourceQuery, opts ...grpc.CallOption) (RPKIAPI_GetRepositoryClient, error) {
	stream, err := c.cc.NewStream(ctx, &_RPKIAPI_serviceDesc.Streams[0], "/RPKIAPI/GetRepository", opts...)
	if err != nil {
		return nil, err
	}
	x := &rPKIAPIGetRepositoryClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type RPKIAPI_GetRepositoryClient interface {
	Recv() (*ResourceData, error)
	grpc.ClientStream
}

type rPKIAPIGetRepositoryClient struct {
	grpc.ClientStream
}

func (x *rPKIAPIGetRepositoryClient) Recv() (*ResourceData, error) {
	m := new(ResourceData)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *rPKIAPIClient) GetFetchRRDP(ctx context.Context, in *FetchQuery, opts ...grpc.CallOption) (RPKIAPI_GetFetchRRDPClient, error) {
	stream, err := c.cc.NewStream(ctx, &_RPKIAPI_serviceDesc.Streams[1], "/RPKIAPI/GetFetchRRDP", opts...)
	if err != nil {
		return nil, err
	}
	x := &rPKIAPIGetFetchRRDPClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type RPKIAPI_GetFetchRRDPClient interface {
	Recv() (*SIA, error)
	grpc.ClientStream
}

type rPKIAPIGetFetchRRDPClient struct {
	grpc.ClientStream
}

func (x *rPKIAPIGetFetchRRDPClient) Recv() (*SIA, error) {
	m := new(SIA)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *rPKIAPIClient) GetFetch(ctx context.Context, in *FetchQuery, opts ...grpc.CallOption) (RPKIAPI_GetFetchClient, error) {
	stream, err := c.cc.NewStream(ctx, &_RPKIAPI_serviceDesc.Streams[2], "/RPKIAPI/GetFetch", opts...)
	if err != nil {
		return nil, err
	}
	x := &rPKIAPIGetFetchClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type RPKIAPI_GetFetchClient interface {
	Recv() (*SIA, error)
	grpc.ClientStream
}

type rPKIAPIGetFetchClient struct {
	grpc.ClientStream
}

func (x *rPKIAPIGetFetchClient) Recv() (*SIA, error) {
	m := new(SIA)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *rPKIAPIClient) PublishFile(ctx context.Context, in *ResourceData, opts ...grpc.CallOption) (*OperationResponse, error) {
	out := new(OperationResponse)
	err := c.cc.Invoke(ctx, "/RPKIAPI/PublishFile", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *rPKIAPIClient) DeleteFile(ctx context.Context, in *ResourceData, opts ...grpc.CallOption) (*OperationResponse, error) {
	out := new(OperationResponse)
	err := c.cc.Invoke(ctx, "/RPKIAPI/DeleteFile", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *rPKIAPIClient) PostSIA(ctx context.Context, in *SIA, opts ...grpc.CallOption) (*OperationResponse, error) {
	out := new(OperationResponse)
	err := c.cc.Invoke(ctx, "/RPKIAPI/PostSIA", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *rPKIAPIClient) PostRRDP(ctx context.Context, in *RRDPInfo, opts ...grpc.CallOption) (*OperationResponse, error) {
	out := new(OperationResponse)
	err := c.cc.Invoke(ctx, "/RPKIAPI/PostRRDP", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *rPKIAPIClient) GetRRDPInfo(ctx context.Context, in *RRDPInfoQuery, opts ...grpc.CallOption) (*RRDPInfo, error) {
	out := new(RRDPInfo)
	err := c.cc.Invoke(ctx, "/RPKIAPI/GetRRDPInfo", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// RPKIAPIServer is the server API for RPKIAPI service.
type RPKIAPIServer interface {
	GetResource(context.Context, *ResourceQuery) (*ResourceData, error)
	GetRepository(*ResourceQuery, RPKIAPI_GetRepositoryServer) error
	GetFetchRRDP(*FetchQuery, RPKIAPI_GetFetchRRDPServer) error
	GetFetch(*FetchQuery, RPKIAPI_GetFetchServer) error
	PublishFile(context.Context, *ResourceData) (*OperationResponse, error)
	DeleteFile(context.Context, *ResourceData) (*OperationResponse, error)
	PostSIA(context.Context, *SIA) (*OperationResponse, error)
	PostRRDP(context.Context, *RRDPInfo) (*OperationResponse, error)
	GetRRDPInfo(context.Context, *RRDPInfoQuery) (*RRDPInfo, error)
}

func RegisterRPKIAPIServer(s *grpc.Server, srv RPKIAPIServer) {
	s.RegisterService(&_RPKIAPI_serviceDesc, srv)
}

func _RPKIAPI_GetResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ResourceQuery)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(RPKIAPIServer).GetResource(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/RPKIAPI/GetResource",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(RPKIAPIServer).GetResource(ctx, req.(*ResourceQuery))
	}
	return interceptor(ctx, in, info, handler)
}

func _RPKIAPI_GetRepository_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(ResourceQuery)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(RPKIAPIServer).GetRepository(m, &rPKIAPIGetRepositoryServer{stream})
}

type RPKIAPI_GetRepositoryServer interface {
	Send(*ResourceData) error
	grpc.ServerStream
}

type rPKIAPIGetRepositoryServer struct {
	grpc.ServerStream
}

func (x *rPKIAPIGetRepositoryServer) Send(m *ResourceData) error {
	return x.ServerStream.SendMsg(m)
}

func _RPKIAPI_GetFetchRRDP_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(FetchQuery)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(RPKIAPIServer).GetFetchRRDP(m, &rPKIAPIGetFetchRRDPServer{stream})
}

type RPKIAPI_GetFetchRRDPServer interface {
	Send(*SIA) error
	grpc.ServerStream
}

type rPKIAPIGetFetchRRDPServer struct {
	grpc.ServerStream
}

func (x *rPKIAPIGetFetchRRDPServer) Send(m *SIA) error {
	return x.ServerStream.SendMsg(m)
}

func _RPKIAPI_GetFetch_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(FetchQuery)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(RPKIAPIServer).GetFetch(m, &rPKIAPIGetFetchServer{stream})
}

type RPKIAPI_GetFetchServer interface {
	Send(*SIA) error
	grpc.ServerStream
}

type rPKIAPIGetFetchServer struct {
	grpc.ServerStream
}

func (x *rPKIAPIGetFetchServer) Send(m *SIA) error {
	return x.ServerStream.SendMsg(m)
}

func _RPKIAPI_PublishFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ResourceData)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(RPKIAPIServer).PublishFile(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/RPKIAPI/PublishFile",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(RPKIAPIServer).PublishFile(ctx, req.(*ResourceData))
	}
	return interceptor(ctx, in, info, handler)
}

func _RPKIAPI_DeleteFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ResourceData)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(RPKIAPIServer).DeleteFile(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/RPKIAPI/DeleteFile",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(RPKIAPIServer).DeleteFile(ctx, req.(*ResourceData))
	}
	return interceptor(ctx, in, info, handler)
}

func _RPKIAPI_PostSIA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SIA)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(RPKIAPIServer).PostSIA(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/RPKIAPI/PostSIA",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(RPKIAPIServer).PostSIA(ctx, req.(*SIA))
	}
	return interceptor(ctx, in, info, handler)
}

func _RPKIAPI_PostRRDP_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(RRDPInfo)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(RPKIAPIServer).PostRRDP(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/RPKIAPI/PostRRDP",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(RPKIAPIServer).PostRRDP(ctx, req.(*RRDPInfo))
	}
	return interceptor(ctx, in, info, handler)
}

func _RPKIAPI_GetRRDPInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(RRDPInfoQuery)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(RPKIAPIServer).GetRRDPInfo(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/RPKIAPI/GetRRDPInfo",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(RPKIAPIServer).GetRRDPInfo(ctx, req.(*RRDPInfoQuery))
	}
	return interceptor(ctx, in, info, handler)
}

var _RPKIAPI_serviceDesc = grpc.ServiceDesc{
	ServiceName: "RPKIAPI",
	HandlerType: (*RPKIAPIServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetResource",
			Handler:    _RPKIAPI_GetResource_Handler,
		},
		{
			MethodName: "PublishFile",
			Handler:    _RPKIAPI_PublishFile_Handler,
		},
		{
			MethodName: "DeleteFile",
			Handler:    _RPKIAPI_DeleteFile_Handler,
		},
		{
			MethodName: "PostSIA",
			Handler:    _RPKIAPI_PostSIA_Handler,
		},
		{
			MethodName: "PostRRDP",
			Handler:    _RPKIAPI_PostRRDP_Handler,
		},
		{
			MethodName: "GetRRDPInfo",
			Handler:    _RPKIAPI_GetRRDPInfo_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "GetRepository",
			Handler:       _RPKIAPI_GetRepository_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "GetFetchRRDP",
			Handler:       _RPKIAPI_GetFetchRRDP_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "GetFetch",
			Handler:       _RPKIAPI_GetFetch_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "cfrpki.proto",
}


================================================
FILE: sync/api/cfrpki.proto
================================================
syntax = "proto3";

service RPKIAPI {
    rpc GetResource (ResourceQuery) returns (ResourceData) {}
    rpc GetRepository (ResourceQuery) returns (stream ResourceData) {}
    rpc GetFetchRRDP(FetchQuery) returns (stream SIA) {}
    rpc GetFetch(FetchQuery) returns (stream SIA) {}
    rpc PublishFile(ResourceData) returns (OperationResponse) {}
    rpc DeleteFile(ResourceData) returns (OperationResponse) {}
    rpc DeleteDirectory(ResourceData) returns (OperationResponse) {}
    rpc PostSIA(SIA) returns (OperationResponse) {}
    rpc PostRRDP(RRDPInfo) returns (OperationResponse) {}
    rpc GetRRDPInfo(RRDPInfoQuery) returns (RRDPInfo) {}
}

message RRDPInfoQuery {
    string RRDP = 1;
}

message RRDPInfo {
    string RRDP = 1;
    string SessionID = 2;
    int64 Serial = 3;
}

message ResourceQuery {
    string Path = 1;
    string RRDP = 2;
}

message ResourceData {
    string Path = 1;
    bytes Data = 2;
}

message FetchQuery {
    string Path = 1;
}

message SIA {
    string RSYNC = 1;
    string RRDP = 2;
}

message OperationResponse {
    
}


================================================
FILE: sync/api/fetch.go
================================================
package cfrpki

import (
	"context"
	"fmt"
	"io/ioutil"
	"strings"

	librpki "github.com/cloudflare/cfrpki/validator/lib"
	"github.com/cloudflare/cfrpki/validator/pki"
)

type APIFetch struct {
	Client RPKIAPIClient
	Ctx    context.Context
}

func FetchFile(client RPKIAPIClient, ctx context.Context, path string) ([]byte, error) {
	resource, err := client.GetResource(ctx, &ResourceQuery{
		Path: path,
	})

	if err != nil {
		return nil, err
	}
	data, err := librpki.BER2DER(resource.Data)
	if err != nil {
		return resource.Data, err
	}
	return data, err
}

func (s *APIFetch) GetFile(file *pki.PKIFile) (*pki.SeekFile, error) {
	if file.Type == pki.TYPE_TAL {
		data, err := ioutil.ReadFile(file.Path)
		if err != nil {
			return nil, fmt.Errorf("Unable to read file %q: %v", file.Path, err)
		}

		return &pki.SeekFile{
			File: file.Path,
			Data: data,
		}, nil
	}

	path := file.ComputePath()

	data, err := FetchFile(s.Client, s.Ctx, path)
	if err != nil {
		return nil, fmt.Errorf("FetchFile failed: %v", err)
	}

	return &pki.SeekFile{
		File: path,
		Data: data,
	}, nil
}

func (s *APIFetch) GetRepository(file *pki.PKIFile, callback pki.CallbackExplore) error {
	resources, err := s.Client.GetRepository(s.Ctx, &ResourceQuery{
		Path: file.Repo,
	})
	if err != nil {
		return err
	}

	resource, err := resources.Recv()
	for resource != nil && err == nil {
		fullnameSplit := strings.Split(resource.Path, ".")
		extension := pki.TYPE_UNKNOWN
		if len(fullnameSplit) > 0 {
			switch fullnameSplit[len(fullnameSplit)-1] {
			case "crl":
				extension = pki.TYPE_CRL
			case "cer":
				extension = pki.TYPE_CER
			case "mft":
				extension = pki.TYPE_MFT
			case "roa":
				extension = pki.TYPE_ROA
			}
		}

		data, _ := librpki.BER2DER(resource.Data)

		callback(
			&pki.PKIFile{
				Parent: file,
				Type:   extension,
				Repo:   file.Repo,
				Path:   resource.Path,
			},
			&pki.SeekFile{
				File: resource.Path,
				Data: data,
			}, false)

		resource, err = resources.Recv()
	}
	return nil
}


================================================
FILE: sync/lib/errors.go
================================================
package syncpki

import (
	"fmt"
	"github.com/getsentry/sentry-go"
	"net/http"
	"runtime"
)

const (
	ERROR_RRDP_UNKNOWN = iota
	ERROR_RRDP_FETCH
)

type stack []uintptr
type Frame uintptr

var (
	ErrorTypeToName = map[int]string{
		ERROR_RRDP_UNKNOWN: "unknown",
		ERROR_RRDP_FETCH:   "fetch",
	}
)

type RRDPError struct {
	EType int

	InnerErr error
	Message  string

	Request *http.Request

	URL, Rsync string

	Stack *stack
}

func callers() *stack {
	const depth = 32
	var pcs [depth]uintptr
	n := runtime.Callers(3, pcs[:])
	var st stack = pcs[0:n]
	return &st
}

// This function returns the Stacktrace of the error.
// The naming scheme corresponds to what Sentry fetches
// https://github.com/getsentry/sentry-go/blob/master/stacktrace.go#L49
func StackTrace(s *stack) []Frame {
	f := make([]Frame, len(*s))
	for i := 0; i < len(f); i++ {
		f[i] = Frame((*s)[i])
	}
	return f
}

func (e *RRDPError) StackTrace() []Frame {
	return StackTrace(e.Stack)
}

func (e *RRDPError) Error() string {
	repoinfo := "for repo"
	if e.URL != "" {
		repoinfo = fmt.Sprintf("for repo rrdp:%s (rsync:%s)", e.URL, e.Rsync)
	}

	var err string
	if e.InnerErr != nil {
		err = fmt.Sprintf(": %s", e.InnerErr.Error())
	}

	return fmt.Sprintf("%s %s%v", e.Message, repoinfo, err)
}

func (e *RRDPError) SetSentryScope(scope *sentry.Scope) {
	scope.SetTag("Type", ErrorTypeToName[e.EType])
	if e.URL != "" {
		scope.SetTag("Repository.RRDP", e.URL)
	}
	if e.Rsync != "" {
		scope.SetTag("Repository.rsync", e.Rsync)
	}
	if e.Request != nil {
		scope.SetRequest(e.Request)
	}
}

func (e *RRDPError) SetURL(rrdp, rsync string) {
	e.URL = rrdp
	e.Rsync = rsync
}

func NewRRDPErrorFetch(request *http.Request, err error) *RRDPError {
	return &RRDPError{
		EType:    ERROR_RRDP_FETCH,
		Request:  request,
		InnerErr: err,
		Message:  "error fetching",
		Stack:    callers(),
	}
}


================================================
FILE: sync/lib/fetch.go
================================================
package syncpki

import (
	"crypto/sha256"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"time"

	librpki "github.com/cloudflare/cfrpki/validator/lib"
	"github.com/cloudflare/cfrpki/validator/pki"

	log "github.com/sirupsen/logrus"
)

type LocalFetch struct {
	Basepath     string
	MapDirectory map[string]string
	repositories map[string]time.Time
}

func NewLocalFetch(basepath string) *LocalFetch {
	return &LocalFetch{
		Basepath:     basepath,
		MapDirectory: map[string]string{RsyncProtoPrefix: basepath},
		repositories: make(map[string]time.Time),
	}
}

func (s *LocalFetch) SetRepositories(repositories map[string]time.Time) {
	s.repositories = repositories
}

func GetLocalPath(pathRep string, replace map[string]string) string {
	sep := fmt.Sprintf("%c", os.PathSeparator)

	for repKey, repVal := range replace {
		if !strings.HasSuffix(repVal, sep) {
			repVal += sep
		}

		pathRep = strings.Replace(pathRep, repKey, repVal, -1)
	}
	return pathRep
}

func ReplacePath(file *pki.PKIFile, replace map[string]string) string {
	pathRep := file.ComputePath()
	pathRep = GetLocalPath(pathRep, replace)
	return pathRep
}

func FetchFile(path string, derEncoding bool) ([]byte, []byte, error) {
	fc, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, nil, fmt.Errorf("Unable to read file %q: %v", path, err)
	}

	tmpSha265 := sha256.Sum256(fc)
	sha256 := tmpSha265[:]

	if !derEncoding {
		return fc, sha256, nil
	}

	fc, err = librpki.BER2DER(fc)
	if err != nil {
		return nil, nil, fmt.Errorf("librpki.BER2DER failed: %v", err)
	}

	return fc, sha256, nil
}

func ParseMapDirectory(mapdir string) map[string]string {
	mapDirectoryFinal := make(map[string]string)
	mapdirsSplit := strings.Split(mapdir, ",")
	for _, mapdirU := range mapdirsSplit {
		mapdirUSplit := strings.Split(mapdirU, "=")
		if len(mapdirUSplit) == 2 {
			mapDirectoryFinal[mapdirUSplit[0]] = mapdirUSplit[1]
		}
	}
	return mapDirectoryFinal
}

func (s *LocalFetch) GetFile(file *pki.PKIFile) (*pki.SeekFile, error) {
	return s.GetFileConv(file, file.Type != pki.TYPE_TAL)
}

func (s *LocalFetch) GetFileConv(file *pki.PKIFile, derEncoding bool) (*pki.SeekFile, error) {
	newPath := ReplacePath(file, s.MapDirectory)
	log.Debugf("Fetching %v->%v", file.Path, newPath)

	data, sha256, err := FetchFile(newPath, derEncoding)
	if os.IsNotExist(err) {
		return nil, nil
	}

	if err != nil {
		rsyncBase, _, errExtract := ExtractRsyncDomainModule(file.Path)
		if errExtract != nil {
			log.Errorf("error extracting rsync of %s: %v", file.Path, errExtract)
		}

		if _, ok := s.repositories[rsyncBase]; !ok {
			log.Debugf("Got %v but repository not yet synchronized", err)
			return nil, nil
		}
	}

	return &pki.SeekFile{
		File:   file.Path,
		Data:   data,
		Sha256: sha256,
	}, err
}

func (s *LocalFetch) GetRepository(file *pki.PKIFile, callback pki.CallbackExplore) error {
	newPath := GetLocalPath(file.Repo, s.MapDirectory)
	files, err := ioutil.ReadDir(file.Repo)
	if err != nil {
		return fmt.Errorf("Unable to read dir %q: %v", file.Repo, err)
	}

	for _, fileDir := range files {
		if fileDir == nil || fileDir.IsDir() {
			continue
		}

		data, sha256, err := FetchFile(newPath+fileDir.Name(), true)
		if err != nil {
			return fmt.Errorf("FetchFile failed: %v", err)
		}

		fullnameSplit := strings.Split(fileDir.Name(), ".")

		extension := pki.TYPE_UNKNOWN
		if len(fullnameSplit) > 0 {
			switch fullnameSplit[len(fullnameSplit)-1] {
			case "crl":
				extension = pki.TYPE_CRL
			case "cer":
				extension = pki.TYPE_CER
			case "mft":
				extension = pki.TYPE_MFT
			case "roa":
				extension = pki.TYPE_ROA
			}
		}

		callback(
			&pki.PKIFile{
				Parent: file,
				Type:   extension,
				Repo:   file.Repo,
				Path:   file.Repo + fileDir.Name(),
			},
			&pki.SeekFile{
				File:   file.Path,
				Data:   data,
				Sha256: sha256,
			}, false)

	}

	return nil
}


================================================
FILE: sync/lib/fetch_test.go
================================================
package syncpki

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestGetLocalPath(t *testing.T) {
	tests := []struct {
		name     string
		pathRep  string
		replace  map[string]string
		expected string
	}{
		{
			name:    "With trailing slash",
			pathRep: "rsync://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer",
			replace: map[string]string{
				"rsync://": "cache/",
			},
			expected: "cache/rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer",
		},
		{
			name:    "Without trailing slash (this is a regresion test)",
			pathRep: "rsync://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer",
			replace: map[string]string{
				"rsync://": "cache",
			},
			expected: "cache/rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer",
		},
	}

	for _, test := range tests {
		res := GetLocalPath(test.pathRep, test.replace)
		assert.Equal(t, test.expected, res, test.name)
	}
}


================================================
FILE: sync/lib/rrdp.go
================================================
package syncpki

import (
	"bytes"
	"encoding/base64"
	"encoding/xml"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/getsentry/sentry-go"
)

const ResponseLimit int64 = 1000000000 // (5Gb)

type RRDPFetcher interface {
	GetXML(string) (string, error)
}

type HTTPFetcher struct {
	UserAgent string
	Client    *http.Client
}

func NewHTTPFetcher(userAgent string) *HTTPFetcher {
	return &HTTPFetcher{
		UserAgent: userAgent,
		Client: &http.Client{
			// GHSA-8cvr-4rrf-f244: Prevent infinite open connections
			Timeout: time.Second * 60,
		},
	}
}

func (f *HTTPFetcher) GetXML(url string) (string, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", NewRRDPErrorFetch(req, err)
	}

	// Set recommended header
	req.Header.Set("User-Agent", f.UserAgent)

	res, err := f.Client.Do(req)
	if err != nil {
		return "", NewRRDPErrorFetch(req, err)
	}
	defer res.Body.Close()

	if res.StatusCode != http.StatusOK {
		return "", NewRRDPErrorFetch(req, errors.New(fmt.Sprintf("status is %d", res.StatusCode)))
	}

	// GHSA-g9wh-3vrx-r7hg: Do not process responses that are excessively large
	r := http.MaxBytesReader(nil, res.Body, ResponseLimit)
	data, err := ioutil.ReadAll(r)

	if err != nil {
		return "", err
	}
	res.Body.Close()
	return string(data), nil
}

func ParseRoot(data string) (Notification, error) {
	n := Notification{}

	r := bytes.NewBufferString(data)
	decoder := xml.NewDecoder(r)

	for {
		t, _ := decoder.Token()
		if t == nil {
			// EOF
			break
		}

		switch se := t.(type) {
		case xml.StartElement:
			name := se.Name.Local
			switch name {
			case "notification":
				err := decoder.DecodeElement(&n, &se)
				if err != nil {
					return n, errors.New("XML does not conform to schema")
				}
			}
		}
	}
	return n, nil
}

func ParseNode(data string) ([]Cert, []Cert, error) {
	var publish []Cert
	var withdraw []Cert
	d := Delta{}
	s := Snapshot{}

	byteStr := bytes.NewBufferString(data)
	decoder := xml.NewDecoder(byteStr)

	for {
		t, _ := decoder.Token()
		if t == nil {
			break
		}

		switch se := t.(type) {
		case xml.StartElement:
			name := se.Name.Local
			switch name {
			case "delta":
				err := decoder.DecodeElement(&d, &se)

				for _, v := range d.Publish {
					publish = append(publish, v)
				}

				if (len(d.Withdraw)) > 0 {
					for _, v := range d.Withdraw {
						withdraw = append(withdraw, v)
					}
				}

				if err != nil {
					return publish, withdraw, errors.New("XML does not conform to schema")
				}
			case "snapshot":
				err := decoder.DecodeElement(&s, &se)

				for _, v := range s.Publish {
					publish = append(publish, v)
				}

				if (len(s.Withdraw)) > 0 {
					for _, v := range s.Withdraw {
						withdraw = append(withdraw, v)
					}
				}

				if err != nil {
					return publish, withdraw, errors.New("XML does not conform to schema")
				}
			}
		}
	}
	return publish, withdraw, nil
}

type RRDPFile func(main string, url string, path string, data []byte, withdraw bool, snapshot bool, curId int64, args ...interface{}) error

type RRDPSystem struct {
	Log     Logger
	Fetcher RRDPFetcher

	Callback RRDPFile

	Path      string
	SessionID string
	Serial    int64

	fetches []string
}

func (s *RRDPSystem) SetSentryScope(scope *sentry.Scope) {
	scope.SetTag("RRDP.Serial", fmt.Sprintf("%d", s.Serial))
	scope.SetTag("RRDP.SessionID", fmt.Sprintf("%s", s.SessionID))
	scope.SetTag("RRDP.Path", fmt.Sprintf("%s", s.Path))
	scope.SetExtra("RRDP.Deltas", s.fetches)
}

func DecodeRRDPBase64(value string) ([]byte, error) {
	value = strings.Replace(value, " ", "", -1)
	value = strings.Replace(value, "\n", "", -1)
	value = strings.Replace(value, "\r", "", -1)
	return base64.StdEncoding.DecodeString(value)
}

func (s *RRDPSystem) FetchRRDP(cbArgs ...interface{}) error {
	s.fetches = make([]string, 0)

	sHub := sentry.CurrentHub().Clone()
	sHub.ConfigureScope(func(scope *sentry.Scope) {
		scope.SetTag("type", "rrdp")
		scope.SetTag("root", s.Path)
	})

	if s.Log != nil {
		s.Log.Infof("RRDP: Downloading root notification %v", s.Path)
	}
	data, err := s.Fetcher.GetXML(s.Path)

	if err != nil {
		sHub.CaptureException(err)
		return err
	}
	sHub.AddBreadcrumb(&sentry.Breadcrumb{
		Level:    sentry.LevelInfo,
		Message:  fmt.Sprintf("GET | %s", s.Path),
		Category: "http",
	}, nil)

	root, err := ParseRoot(data)
	if err != nil {
		sHub.CaptureException(err)
		return err
	}

	sHub.AddBreadcrumb(&sentry.Breadcrumb{
		Level:    sentry.LevelInfo,
		Message:  "Parse Root",
		Category: "default",
	}, nil)

	curSessionID := root.SessionID
	lastSessionID := s.SessionID
	curSerial := int64(root.RootNode.Serial)
	lastSerial := s.Serial

	deltasMap := make(map[int64]ElNode)

	for _, v := range root.Deltas {
		deltasMap[int64(v.Serial)] = v
	}

	// If the last downloaded Delta is not in the map, the
	// whole notification.xml file has gone stale
	var missingFiles bool
	serial := lastSerial
	for serial = lastSerial; serial <= curSerial; serial++ {
		if _, ok := deltasMap[serial]; !ok {
			missingFiles = true
			break
		}
	}

	if lastSerial == 0 || lastSessionID != curSessionID || missingFiles {
		if s.Log != nil {
			s.Log.Infof("RRDP: %s downloading snapshot at: %s", s.Path, root.Snapshot.URI)
		}

		data, err := s.Fetcher.GetXML(root.Snapshot.URI)
		if err != nil {
			sHub.CaptureException(err)
			return err
		}
		sHub.AddBreadcrumb(&sentry.Breadcrumb{
			Level:    sentry.LevelInfo,
			Message:  fmt.Sprintf("GET | %s", root.Snapshot.URI),
			Category: "http",
		}, nil)

		publish, withdraw, err := ParseNode(data)
		if err != nil {
			sHub.CaptureException(err)
			return err
		}

		sHub.AddBreadcrumb(&sentry.Breadcrumb{
			Level:    sentry.LevelInfo,
			Message:  "Parse Node",
			Category: "default",
		}, nil)

		if s.Callback != nil {
			for _, v := range publish {
				vdec, err := DecodeRRDPBase64(v.Value)
				if err != nil {
					return err
				}
				err = s.Callback(s.Path, root.Snapshot.URI, v.URI, vdec, false, true, curSerial, cbArgs...)
				if err != nil {
					return err
				}
			}
			for _, v := range withdraw {
				vdec, err := DecodeRRDPBase64(v.Value)
				if err != nil {
					return err
				}
				err = s.Callback(s.Path, root.Snapshot.URI, v.URI, vdec, true, true, curSerial, cbArgs...)
				if err != nil {
					return err
				}
			}
		}
	} else {
		msg := fmt.Sprintf("RRDP: %s has %d deltas to parse (cur: %d, last: %d)", s.Path, curSerial-lastSerial, curSerial, lastSerial)
		if s.Log != nil {
			s.Log.Info(msg)
		}

		sHub.AddBreadcrumb(&sentry.Breadcrumb{
			Level:    sentry.LevelInfo,
			Message:  msg,
			Category: "default",
		}, nil)

		tmpCurSerial := lastSerial
		var processed int
		for serial = lastSerial + 1; serial <= curSerial && curSerial-lastSerial > 0; serial++ {
			elNode, ok := deltasMap[serial]
			if !ok {
				return errors.New(fmt.Sprintf("Could not find delta with serial %d", serial))
			}
			if s.Log != nil {
				s.Log.Debugf("RRDP: Fetching serial: %d (%s) for %s", serial, elNode.URI, s.Path)
			}
			s.fetches = append(s.fetches, elNode.URI)
			data, err := s.Fetcher.GetXML(elNode.URI)
			if err != nil {
				sHub.CaptureException(err)
				return err
			}

			sHub.AddBreadcrumb(&sentry.Breadcrumb{
				Level:    sentry.LevelInfo,
				Message:  fmt.Sprintf("GET | %s", elNode.URI),
				Category: "http",
			}, nil)

			deltaPublish, deltaWithdraw, err := ParseNode(data)
			if err != nil {
				sHub.CaptureException(err)
				return err
			}

			sHub.AddBreadcrumb(&sentry.Breadcrumb{
				Level:    sentry.LevelInfo,
				Message:  "Parse node",
				Category: "default",
			}, nil)

			// Before inserting: check hash
			if s.Callback != nil {
				for _, v := range deltaPublish {
					vdec, err := DecodeRRDPBase64(v.Value)
					if err != nil {
						return err
					}
					err = s.Callback(s.Path, root.Snapshot.URI, v.URI, vdec, false, false, elNode.Serial, cbArgs...)
					if err != nil {
						return err
					}
				}
				for _, v := range deltaWithdraw {
					vdec, err := DecodeRRDPBase64(v.Value)
					if err != nil {
						return err
					}
					s.Callback(s.Path, root.Snapshot.URI, v.URI, vdec, true, false, elNode.Serial, cbArgs...)
					if err != nil {
						return err
					}
				}
			}
			tmpCurSerial = serial
			processed++
		}
		curSerial = tmpCurSerial
		msg = fmt.Sprintf("RRDP: finished processing notifications (%d). Last serial %d", processed, curSerial)
		if s.Log != nil {
			s.Log.Info(msg)
		}
		sHub.ConfigureScope(func(scope *sentry.Scope) {
			scope.SetTag("count", fmt.Sprintf("%d", processed))
			scope.SetTag("serial", fmt.Sprintf("%d", curSerial))
		})
		sHub.CaptureMessage("RRDP: finished processing notifications")
	}
	s.Serial = curSerial
	s.SessionID = curSessionID
	return nil
}


================================================
FILE: sync/lib/rrdp_struct.go
================================================
package syncpki

import (
	"encoding/xml"
)

type RootNode struct {
	Xmlns     string `xml:"xmlns,attr"`
	Version   string `xml:"version,attr"`
	SessionID string `xml:"session_id,attr"`
	Serial    int64  `xml:"serial,attr"`
}

type ElNode struct {
	Serial int64  `xml:"serial,attr"`
	URI    string `xml:"uri,attr"`
	Hash   string `xml:"hash,attr"`
}

type Cert struct {
	URI   string `xml:"uri,attr"`
	Value string `xml:",chardata"`
}

type Notification struct {
	RootNode
	XMLName  xml.Name `xml:"notification"`
	Snapshot ElNode   `xml:"snapshot"`
	Deltas   []ElNode `xml:"delta"`
}

type Delta struct {
	RootNode
	XMLName  xml.Name `xml:"delta"`
	Publish  []Cert   `xml:"publish"`
	Withdraw []Cert   `xml:"withdraw"`
}

type Snapshot struct {
	RootNode
	XMLName  xml.Name `xml:"snapshot"`
	Publish  []Cert   `xml:"publish"`
	Withdraw []Cert   `xml:"withdraw"`
}


================================================
FILE: sync/lib/rsync.go
================================================
package syncpki

import (
	"bufio"
	"context"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"regexp"
	"strings"

	log "github.com/sirupsen/logrus"
)

const (
	RsyncProtoPrefix = "rsync://"
)

var (
	reDeletion            = regexp.MustCompile("^deleting (.*)")
	wantedFileExtensionRE = regexp.MustCompile("(.*\\.(cer|mft|crl|roa|gbr))$")
)

func ExtractFoldersPathFromRsyncURL(url string) (string, error) {
	if !isRsyncURL(url) {
		return "", fmt.Errorf("%q is not an rsync URL", url)
	}

	filePath := strings.TrimPrefix(url, RsyncProtoPrefix)
	parts := strings.Split(filePath, "/")
	return strings.Join(parts[0:len(parts)-1], "/"), nil
}

func ExtractFilePathFromRsyncURL(url string) (string, error) {
	if !isRsyncURL(url) {
		return "", fmt.Errorf("%q is not an rsync URL", url)
	}

	return strings.TrimPrefix(url, RsyncProtoPrefix), nil
}

func isRsyncURL(url string) bool {
	return strings.HasPrefix(url, RsyncProtoPrefix)
}

// Determines if file has been deleted
func FilterMatch(line string) (string, bool, error) {
	results := reDeletion.FindAllStringSubmatch(line, -1)
	if len(results) > 0 {
		return results[0][1], true, nil
	}
	return line, false, nil
}

type FileStat struct {
	Path    string
	Deleted bool
}

// Runs the rsync binary on a URL
func RunRsync(ctx context.Context, uri string, bin string, dirPath string) ([]*FileStat, error) {
	if bin == "" {
		return nil, errors.New("rsync binary missing")
	}

	err := os.MkdirAll(dirPath, os.ModePerm)
	if err != nil {
		return nil, err
	}

	cmd := exec.CommandContext(ctx, bin, "-vrlt", uri, dirPath)
	log.Debugf("Command ran: %v", cmd)

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return nil, err
	}

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	go func() {
		scanner := bufio.NewScanner(stderr)
		for scanner.Scan() {
			errorStr := scanner.Text()
			log.Error(errorStr)

			err := scanner.Err()
			if err != nil {
				log.Errorf("%v: %v", uri, err)
				return
			}
		}
	}()

	newuri := uri
	uriSplit := strings.Split(newuri[8:], "/")
	if uri[len(uri)-1] != '/' && len(uriSplit) > 2 {
		newuri = "rsync://" + strings.Join(uriSplit[0:len(uriSplit)-1], "/")
	} else {
		newuri = strings.TrimSuffix(newuri, "/")
	}

	files := make([]*FileStat, 0)

	scanner := bufio.NewScanner(stdout)
	for scanner.Scan() {
		line := scanner.Text()

		match := wantedFileExtensionRE.MatchString(line)
		log.Debugf("Rsync received from %v: %v (match=%v)", uri, line, match)

		if match {
			file, deleted, err := FilterMatch(line)
			if err != nil {
				return nil, err
			}

			files = append(files, &FileStat{
				Path:    fmt.Sprintf("%v/%v", newuri, file),
				Deleted: deleted,
			})
		}

		if err != nil {
			return files, err
		}
	}

	err = scanner.Err()
	err = cmd.Wait()
	return files, err
}


================================================
FILE: sync/lib/rsync_test.go
================================================
package syncpki

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestExtractFoldersPathFromRsyncURL(t *testing.T) {
	tests := []struct {
		name     string
		url      string
		wantFail bool
		expected string
	}{
		{
			name:     "Valid URL",
			url:      "rsync://r.magellan.ipxo.com/repo/foo",
			wantFail: false,
			expected: "r.magellan.ipxo.com/repo",
		},
		{
			name:     "Invalid URL",
			url:      "xxxx://r.magellan.ipxo.com/repo",
			wantFail: true,
		},
	}

	for _, test := range tests {
		res, err := ExtractFoldersPathFromRsyncURL(test.url)
		if test.wantFail && err == nil {
			t.Errorf("unexpected success for %q", test.name)
			continue
		}

		if !test.wantFail && err != nil {
			t.Errorf("unexpected error for %q: %v", test.name, err)
			continue
		}

		assert.Equal(t, test.expected, res, test.name)
	}
}


================================================
FILE: sync/lib/utils.go
================================================
package syncpki

import (
	"errors"
	"fmt"
	"strings"
)

type Logger interface {
	Infof(string, ...interface{})
	Info(...interface{})
	Debugf(string, ...interface{})
	Debug(...interface{})
	Errorf(string, ...interface{})
	Error(...interface{})
}

type SubMap struct {
	Subitem map[string]SubMap
	Count   int
}

func ExtractRsyncDomainModule(rsync string) (string, string, error) {
	if len(rsync) > len("rsync://") {
		rsyncDomain := strings.Split(rsync[8:], "/")
		if len(rsyncDomain) < 2 {
			return "", "", errors.New("rsync url does not contain module")
		}
		return fmt.Sprintf("rsync://%s/%s", rsyncDomain[0], rsyncDomain[1]), fmt.Sprintf("rsync://%s/", rsyncDomain[0]), nil
	} else {
		return "", "", errors.New("Wrong size")
	}
}

func AddInMap(item string, m map[string]SubMap) {
	if !(len(item) > 8 && item[0:8] == "rsync://") {
		return
	}
	itemSplit := strings.Split(item[8:len(item)], "/")
	curm := m
	for i, s := range itemSplit {
		mm, ok := curm[s]

		if i == len(itemSplit)-1 {
			mm.Count++
		}
		if !ok {
			mm.Subitem = make(map[string]SubMap)
			curm[s] = mm
		}
		curm = mm.Subitem
	}
}

func ReduceMap(m map[string]SubMap) []string {
	explore := make([]map[string]SubMap, 1)
	explore[0] = m
	explorePath := make([]string, 1)
	explorePath[0] = "rsync:/"
	exploreDepth := make([]int, 1)
	exploreDepth[0] = 0

	final := make([]string, 0)

	for len(explore) > 0 {
		curExplore := explore[0]
		explore = explore[1:len(explore)]
		curPath := explorePath[0]
		explorePath = explorePath[1:len(explorePath)]
		curDepth := exploreDepth[0]
		exploreDepth = exploreDepth[1:len(exploreDepth)]
		for pathItem, pathMap := range curExplore {
			pathMapC := pathMap.Subitem

			curPathComputed := curPath + "/" + pathItem

			if len(pathMapC) == 1 && pathMap.Count == 0 || curDepth < 1 {
				explorePath = append(explorePath, curPathComputed)
				explore = append(explore, pathMapC)
				exploreDepth = append(exploreDepth, curDepth+1)
			} else {
				final = append(final, curPathComputed)
			}
		}
	}
	return final
}


================================================
FILE: validator/lib/ber.go
================================================
package librpki

import (
	"bytes"
	"errors"
)

/*
  The BER to DER ASN.1 conversion has been implemented from:
  https://github.com/fullsailor/pkcs7/blob/master/ber.go
*/

var encodeIndent = 0

type asn1Object interface {
	encodeTo(writer *bytes.Buffer) error
}

type asn1Structured struct {
	tagBytes []byte
	content  []asn1Object
}

func (s asn1Structured) encodeTo(out *bytes.Buffer) error {
	encodeIndent++
	inner := new(bytes.Buffer)
	for _, obj := range s.content {
		err := obj.encodeTo(inner)
		if err != nil {
			return err
		}
	}
	encodeIndent--
	out.Write(s.tagBytes)
	encodeLength(out, inner.Len())
	out.Write(inner.Bytes())
	return nil
}

type asn1Primitive struct {
	tagBytes []byte
	length   int
	content  []byte
}

func (p asn1Primitive) encodeTo(out *bytes.Buffer) error {
	_, err := out.Write(p.tagBytes)
	if err != nil {
		return err
	}
	if err = encodeLength(out, p.length); err != nil {
		return err
	}
	out.Write(p.content)

	return nil
}

// BER2DER attempts to convert BER encoded data to DER encoding.
func BER2DER(ber []byte) ([]byte, error) {
	if len(ber) == 0 {
		return nil, errors.New("ber2der: input ber is empty")
	}
	//fmt.Printf("--> ber2der: Transcoding %d bytes\n", len(ber))
	out := new(bytes.Buffer)

	obj, _, err := readObject(ber, 0)
	if err != nil {
		return nil, err
	}
	obj.encodeTo(out)

	// if offset < len(ber) {
	//  return nil, fmt.Errorf("ber2der: Content longer than expected. Got %d, expected %d", offset, len(ber))
	//}

	return out.Bytes(), nil
}

// encodes lengths that are longer than 127 into string of bytes
func marshalLongLength(out *bytes.Buffer, i int) (err error) {
	n := lengthLength(i)

	for ; n > 0; n-- {
		err = out.WriteByte(byte(i >> uint((n-1)*8)))
		if err != nil {
			return
		}
	}

	return nil
}

// computes the byte length of an encoded length value
func lengthLength(i int) (numBytes int) {
	numBytes = 1
	for i > 255 {
		numBytes++
		i >>= 8
	}
	return
}

// encodes the length in DER format
// If the length fits in 7 bits, the value is encoded directly.
//
// Otherwise, the number of bytes to encode the length is first determined.
// This number is likely to be 4 or less for a 32bit length. This number is
// added to 0x80. The length is encoded in big endian encoding follow after
//
// Examples:
//  length | byte 1 | bytes n
//  0      | 0x00   | -
//  120    | 0x78   | -
//  200    | 0x81   | 0xC8
//  500    | 0x82   | 0x01 0xF4
//
func encodeLength(out *bytes.Buffer, length int) (err error) {
	if length >= 128 {
		l := lengthLength(length)
		err = out.WriteByte(0x80 | byte(l))
		if err != nil {
			return
		}
		err = marshalLongLength(out, length)
		if err != nil {
			return
		}
	} else {
		err = out.WriteByte(byte(length))
		if err != nil {
			return
		}
	}
	return
}

func readObject(ber []byte, offset int) (asn1Object, int, error) {
	//fmt.Printf("\n====> Starting readObject at offset: %d\n\n", offset)
	tagStart := offset
	b := ber[offset]
	offset++
	tag := b & 0x1F // last 5 bits
	if tag == 0x1F {
		tag = 0
		for ber[offset] >= 0x80 {
			tag = tag*128 + ber[offset] - 0x80
			offset++
		}
		tag = tag*128 + ber[offset] - 0x80
		offset++
	}
	tagEnd := offset

	kind := b & 0x20
	/*
		if kind == 0 {
			fmt.Print("--> Primitive\n")
		} else {
			fmt.Print("--> Constructed\n")
		}
	*/
	// read length
	var length int
	// GHSA-5mxh-2qfv-4g7j: Prevent a BER w/ NUL contents from being processed
	if len(ber) <= offset {
		return nil, 0, errors.New("ber2der: invalid BER tag length")
	}
	l := ber[offset]
	offset++
	indefinite := false
	if l > 0x80 {
		numberOfBytes := (int)(l & 0x7F)
		if numberOfBytes > 4 { // int is only guaranteed to be 32bit
			return nil, 0, errors.New("ber2der: BER tag length too long")
		}
		if numberOfBytes == 4 && (int)(ber[offset]) > 0x7F {
			return nil, 0, errors.New("ber2der: BER tag length is negative")
		}
		if 0x0 == (int)(ber[offset]) {
			return nil, 0, errors.New("ber2der: BER tag length has leading zero")
		}
		//fmt.Printf("--> (compute length) indicator byte: %x\n", l)
		//fmt.Printf("--> (compute length) length bytes: % X\n", ber[offset:offset+numberOfBytes])
		for i := 0; i < numberOfBytes; i++ {
			length = length*256 + (int)(ber[offset])
			offset++
		}
	} else if l == 0x80 {
		indefinite = true
	} else {
		length = (int)(l)
	}

	//fmt.Printf("--> length        : %d\n", length)
	contentEnd := offset + length
	if contentEnd > len(ber) {
		return nil, 0, errors.New("ber2der: BER tag length is more than available data")
	}
	//fmt.Printf("--> content start : %d\n", offset)
	//fmt.Printf("--> content end   : %d\n", contentEnd)
	//fmt.Printf("--> content       : % X\n", ber[offset:contentEnd])
	var obj asn1Object
	if indefinite && kind == 0 {
		return nil, 0, errors.New("ber2der: Indefinite form tag must have constructed encoding")
	}
	if kind == 0 {
		obj = asn1Primitive{
			tagBytes: ber[tagStart:tagEnd],
			length:   length,
			content:  ber[offset:contentEnd],
		}
	} else {
		var subObjects []asn1Object
		for (offset < contentEnd) || indefinite {
			var subObj asn1Object
			var err error
			subObj, offset, err = readObject(ber, offset)
			if err != nil {
				return nil, 0, err
			}
			subObjects = append(subObjects, subObj)

			if indefinite {
				terminated, err := isIndefiniteTermination(ber, offset)
				if err != nil {
					return nil, 0, err
				}

				if terminated {
					break
				}
			}
		}
		obj = asn1Structured{
			tagBytes: ber[tagStart:tagEnd],
			content:  subObjects,
		}
	}

	// Apply indefinite form length with 0x0000 terminator.
	if indefinite {
		contentEnd = offset + 2
	}

	return obj, contentEnd, nil
}

func isIndefiniteTermination(ber []byte, offset int) (bool, error) {
	if len(ber)-offset < 2 {
		return false, errors.New("ber2der: Invalid BER format")
	}

	return bytes.Index(ber[offset:], []byte{0x0, 0x0}) == 0, nil
}


================================================
FILE: validator/lib/cert.go
================================================
package librpki

import (
	"bytes"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/hex"
	"errors"
	"fmt"
	"net"
	"sort"
	"time"
)

// https://tools.ietf.org/html/rfc6487
// https://tools.ietf.org/html/rfc3779

var (
	IpAddrBlock      = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 7}
	AutonomousSysIds = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 8}

	IpAddrBlockV2      = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 28}
	AutonomousSysIdsV2 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 29}
	IpAddrAndASIdent   = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30}

	CertPolicy         = asn1.ObjectIdentifier{2, 5, 29, 32}
	ResourceCertPolicy = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 14, 2}
	CPS                = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 1}

	SubjectInfoAccess   = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 11}
	AuthorityInfoAccess = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1}
	CAIssuer            = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
	SignedObject        = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 11}

	SubjectKeyIdentifier   = asn1.ObjectIdentifier{2, 5, 29, 14}
	AuthorityKeyIdentifier = asn1.ObjectIdentifier{2, 5, 29, 35}

	CertRepository = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48,
Download .txt
gitextract_hhntx3gl/

├── .dockerignore
├── .github/
│   └── workflows/
│       ├── codeql.yml
│       ├── go.yml
│       └── release.yml
├── .gitignore
├── Dockerfile
├── Dockerfile.prod
├── LICENSE
├── Makefile
├── Monitoring.md
├── README.md
├── api/
│   └── schemas/
│       └── schemas.go
├── ca/
│   └── xml.go
├── cmd/
│   ├── ctrpki/
│   │   └── ctrpki.go
│   ├── localrpki/
│   │   └── localrpki.go
│   └── octorpki/
│       ├── ct.go
│       ├── filter.go
│       ├── filter_test.go
│       ├── octorpki.go
│       ├── rrdp_fetcher.go
│       ├── rsync_fetcher.go
│       └── tals/
│           ├── afrinic.tal
│           ├── apnic.tal
│           ├── arin.tal
│           ├── lacnic.tal
│           └── ripe.tal
├── compose/
│   ├── docker-compose.yml
│   ├── grafana-dashboard-provider.yml
│   ├── grafana-dashboard-rpki.json
│   ├── grafana-datasources.yml
│   ├── private.pem
│   ├── prometheus.yml
│   └── public.pem
├── go.mod
├── go.sum
├── ov/
│   ├── ov.go
│   └── ov_test.go
├── package/
│   ├── after-install-octorpki.sh
│   ├── before-remove-octorpki.sh
│   ├── octorpki.env
│   └── octorpki.service
├── sync/
│   ├── api/
│   │   ├── cfrpki.pb.go
│   │   ├── cfrpki.proto
│   │   └── fetch.go
│   └── lib/
│       ├── errors.go
│       ├── fetch.go
│       ├── fetch_test.go
│       ├── rrdp.go
│       ├── rrdp_struct.go
│       ├── rsync.go
│       ├── rsync_test.go
│       └── utils.go
├── validator/
│   ├── lib/
│   │   ├── ber.go
│   │   ├── cert.go
│   │   ├── cert_test.go
│   │   ├── cms.go
│   │   ├── crl.go
│   │   ├── manifest.go
│   │   ├── manifest_test.go
│   │   ├── roa.go
│   │   ├── roa_test.go
│   │   ├── tal.go
│   │   ├── tal_test.go
│   │   ├── xml.data
│   │   ├── xml.go
│   │   └── xml_test.go
│   └── pki/
│       ├── errors.go
│       ├── pki.go
│       └── pki_test.go
└── vendor/
    ├── github.com/
    │   ├── beorn7/
    │   │   └── perks/
    │   │       ├── LICENSE
    │   │       └── quantile/
    │   │           ├── exampledata.txt
    │   │           └── stream.go
    │   ├── cespare/
    │   │   └── xxhash/
    │   │       └── v2/
    │   │           ├── LICENSE.txt
    │   │           ├── README.md
    │   │           ├── testall.sh
    │   │           ├── xxhash.go
    │   │           ├── xxhash_amd64.s
    │   │           ├── xxhash_arm64.s
    │   │           ├── xxhash_asm.go
    │   │           ├── xxhash_other.go
    │   │           ├── xxhash_safe.go
    │   │           └── xxhash_unsafe.go
    │   ├── cloudflare/
    │   │   └── gortr/
    │   │       ├── LICENSE.txt
    │   │       └── prefixfile/
    │   │           ├── prefixfile.go
    │   │           └── slurm.go
    │   ├── davecgh/
    │   │   └── go-spew/
    │   │       ├── LICENSE
    │   │       └── spew/
    │   │           ├── bypass.go
    │   │           ├── bypasssafe.go
    │   │           ├── common.go
    │   │           ├── config.go
    │   │           ├── doc.go
    │   │           ├── dump.go
    │   │           ├── format.go
    │   │           └── spew.go
    │   ├── getsentry/
    │   │   └── sentry-go/
    │   │       ├── .codecov.yml
    │   │       ├── .craft.yml
    │   │       ├── .gitattributes
    │   │       ├── .gitignore
    │   │       ├── .golangci.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── MIGRATION.md
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── client.go
    │   │       ├── doc.go
    │   │       ├── dsn.go
    │   │       ├── dynamic_sampling_context.go
    │   │       ├── hub.go
    │   │       ├── integrations.go
    │   │       ├── interfaces.go
    │   │       ├── internal/
    │   │       │   ├── debug/
    │   │       │   │   └── transport.go
    │   │       │   ├── otel/
    │   │       │   │   └── baggage/
    │   │       │   │       ├── README.md
    │   │       │   │       ├── baggage.go
    │   │       │   │       └── internal/
    │   │       │   │           └── baggage/
    │   │       │   │               └── baggage.go
    │   │       │   └── ratelimit/
    │   │       │       ├── category.go
    │   │       │       ├── deadline.go
    │   │       │       ├── doc.go
    │   │       │       ├── map.go
    │   │       │       ├── rate_limits.go
    │   │       │       └── retry_after.go
    │   │       ├── scope.go
    │   │       ├── sentry.go
    │   │       ├── sourcereader.go
    │   │       ├── span_recorder.go
    │   │       ├── stacktrace.go
    │   │       ├── traces_sampler.go
    │   │       ├── tracing.go
    │   │       ├── transport.go
    │   │       └── util.go
    │   ├── go-logr/
    │   │   └── logr/
    │   │       ├── .golangci.yaml
    │   │       ├── CHANGELOG.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── discard.go
    │   │       └── logr.go
    │   ├── golang/
    │   │   └── protobuf/
    │   │       ├── AUTHORS
    │   │       ├── CONTRIBUTORS
    │   │       ├── LICENSE
    │   │       ├── jsonpb/
    │   │       │   ├── decode.go
    │   │       │   ├── encode.go
    │   │       │   └── json.go
    │   │       ├── proto/
    │   │       │   ├── buffer.go
    │   │       │   ├── defaults.go
    │   │       │   ├── deprecated.go
    │   │       │   ├── discard.go
    │   │       │   ├── extensions.go
    │   │       │   ├── properties.go
    │   │       │   ├── proto.go
    │   │       │   ├── registry.go
    │   │       │   ├── text_decode.go
    │   │       │   ├── text_encode.go
    │   │       │   ├── wire.go
    │   │       │   └── wrappers.go
    │   │       └── ptypes/
    │   │           ├── any/
    │   │           │   └── any.pb.go
    │   │           ├── any.go
    │   │           ├── doc.go
    │   │           ├── duration/
    │   │           │   └── duration.pb.go
    │   │           ├── duration.go
    │   │           ├── timestamp/
    │   │           │   └── timestamp.pb.go
    │   │           └── timestamp.go
    │   ├── google/
    │   │   └── certificate-transparency-go/
    │   │       ├── .gitignore
    │   │       ├── .golangci.yaml
    │   │       ├── AUTHORS
    │   │       ├── CHANGELOG.md
    │   │       ├── CODEOWNERS
    │   │       ├── CONTRIBUTING.md
    │   │       ├── CONTRIBUTORS
    │   │       ├── LICENSE
    │   │       ├── PULL_REQUEST_TEMPLATE.md
    │   │       ├── README.md
    │   │       ├── asn1/
    │   │       │   ├── README.md
    │   │       │   ├── asn1.go
    │   │       │   ├── common.go
    │   │       │   └── marshal.go
    │   │       ├── client/
    │   │       │   ├── configpb/
    │   │       │   │   ├── multilog.pb.go
    │   │       │   │   └── multilog.proto
    │   │       │   ├── getentries.go
    │   │       │   ├── logclient.go
    │   │       │   └── multilog.go
    │   │       ├── cloudbuild.yaml
    │   │       ├── cloudbuild_master.yaml
    │   │       ├── cloudbuild_tag.yaml
    │   │       ├── codecov.yml
    │   │       ├── jsonclient/
    │   │       │   ├── backoff.go
    │   │       │   └── client.go
    │   │       ├── proto_gen.go
    │   │       ├── serialization.go
    │   │       ├── signatures.go
    │   │       ├── tls/
    │   │       │   ├── signature.go
    │   │       │   ├── tls.go
    │   │       │   └── types.go
    │   │       ├── types.go
    │   │       └── x509/
    │   │           ├── README.md
    │   │           ├── cert_pool.go
    │   │           ├── curves.go
    │   │           ├── error.go
    │   │           ├── errors.go
    │   │           ├── names.go
    │   │           ├── pem_decrypt.go
    │   │           ├── pkcs1.go
    │   │           ├── pkcs8.go
    │   │           ├── pkix/
    │   │           │   └── pkix.go
    │   │           ├── ptr_sysptr_windows.go
    │   │           ├── ptr_uint_windows.go
    │   │           ├── revoked.go
    │   │           ├── root.go
    │   │           ├── root_bsd.go
    │   │           ├── root_cgo_darwin.go
    │   │           ├── root_darwin.go
    │   │           ├── root_darwin_armx.go
    │   │           ├── root_js.go
    │   │           ├── root_linux.go
    │   │           ├── root_nocgo_darwin.go
    │   │           ├── root_plan9.go
    │   │           ├── root_solaris.go
    │   │           ├── root_unix.go
    │   │           ├── root_windows.go
    │   │           ├── rpki.go
    │   │           ├── sec1.go
    │   │           ├── test-dir.crt
    │   │           ├── test-file.crt
    │   │           ├── verify.go
    │   │           └── x509.go
    │   ├── kentik/
    │   │   └── patricia/
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── address_v4.go
    │   │       ├── address_v6.go
    │   │       ├── bits.go
    │   │       ├── init.go
    │   │       ├── int64_tree/
    │   │       │   ├── tree_node_v4.go
    │   │       │   ├── tree_node_v6.go
    │   │       │   ├── tree_v4.go
    │   │       │   ├── tree_v4_manual.go
    │   │       │   ├── tree_v6_generated.go
    │   │       │   ├── tree_v6_manual.go
    │   │       │   └── trees.go
    │   │       ├── net.go
    │   │       └── test_tags.tsv
    │   ├── matttproud/
    │   │   └── golang_protobuf_extensions/
    │   │       ├── LICENSE
    │   │       ├── NOTICE
    │   │       └── pbutil/
    │   │           ├── .gitignore
    │   │           ├── Makefile
    │   │           ├── decode.go
    │   │           ├── doc.go
    │   │           └── encode.go
    │   ├── opentracing/
    │   │   └── opentracing-go/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── ext/
    │   │       │   ├── field.go
    │   │       │   └── tags.go
    │   │       ├── ext.go
    │   │       ├── globaltracer.go
    │   │       ├── gocontext.go
    │   │       ├── log/
    │   │       │   ├── field.go
    │   │       │   └── util.go
    │   │       ├── noop.go
    │   │       ├── propagation.go
    │   │       ├── span.go
    │   │       └── tracer.go
    │   ├── pkg/
    │   │   └── errors/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       ├── errors.go
    │   │       ├── go113.go
    │   │       └── stack.go
    │   ├── pmezard/
    │   │   └── go-difflib/
    │   │       ├── LICENSE
    │   │       └── difflib/
    │   │           └── difflib.go
    │   ├── prometheus/
    │   │   ├── client_golang/
    │   │   │   ├── LICENSE
    │   │   │   ├── NOTICE
    │   │   │   └── prometheus/
    │   │   │       ├── .gitignore
    │   │   │       ├── README.md
    │   │   │       ├── build_info_collector.go
    │   │   │       ├── collector.go
    │   │   │       ├── counter.go
    │   │   │       ├── desc.go
    │   │   │       ├── doc.go
    │   │   │       ├── expvar_collector.go
    │   │   │       ├── fnv.go
    │   │   │       ├── gauge.go
    │   │   │       ├── get_pid.go
    │   │   │       ├── get_pid_gopherjs.go
    │   │   │       ├── go_collector.go
    │   │   │       ├── go_collector_go116.go
    │   │   │       ├── go_collector_latest.go
    │   │   │       ├── histogram.go
    │   │   │       ├── internal/
    │   │   │       │   ├── almost_equal.go
    │   │   │       │   ├── difflib.go
    │   │   │       │   ├── go_collector_options.go
    │   │   │       │   ├── go_runtime_metrics.go
    │   │   │       │   └── metric.go
    │   │   │       ├── labels.go
    │   │   │       ├── metric.go
    │   │   │       ├── num_threads.go
    │   │   │       ├── num_threads_gopherjs.go
    │   │   │       ├── observer.go
    │   │   │       ├── process_collector.go
    │   │   │       ├── process_collector_js.go
    │   │   │       ├── process_collector_other.go
    │   │   │       ├── process_collector_windows.go
    │   │   │       ├── promhttp/
    │   │   │       │   ├── delegator.go
    │   │   │       │   ├── http.go
    │   │   │       │   ├── instrument_client.go
    │   │   │       │   ├── instrument_server.go
    │   │   │       │   └── option.go
    │   │   │       ├── registry.go
    │   │   │       ├── summary.go
    │   │   │       ├── timer.go
    │   │   │       ├── untyped.go
    │   │   │       ├── value.go
    │   │   │       ├── vec.go
    │   │   │       └── wrap.go
    │   │   ├── client_model/
    │   │   │   ├── LICENSE
    │   │   │   ├── NOTICE
    │   │   │   └── go/
    │   │   │       └── metrics.pb.go
    │   │   ├── common/
    │   │   │   ├── LICENSE
    │   │   │   ├── NOTICE
    │   │   │   ├── expfmt/
    │   │   │   │   ├── decode.go
    │   │   │   │   ├── encode.go
    │   │   │   │   ├── expfmt.go
    │   │   │   │   ├── fuzz.go
    │   │   │   │   ├── openmetrics_create.go
    │   │   │   │   ├── text_create.go
    │   │   │   │   └── text_parse.go
    │   │   │   ├── internal/
    │   │   │   │   └── bitbucket.org/
    │   │   │   │       └── ww/
    │   │   │   │           └── goautoneg/
    │   │   │   │               ├── README.txt
    │   │   │   │               └── autoneg.go
    │   │   │   └── model/
    │   │   │       ├── alert.go
    │   │   │       ├── fingerprinting.go
    │   │   │       ├── fnv.go
    │   │   │       ├── labels.go
    │   │   │       ├── labelset.go
    │   │   │       ├── metric.go
    │   │   │       ├── model.go
    │   │   │       ├── signature.go
    │   │   │       ├── silence.go
    │   │   │       ├── time.go
    │   │   │       ├── value.go
    │   │   │       ├── value_float.go
    │   │   │       ├── value_histogram.go
    │   │   │       └── value_type.go
    │   │   └── procfs/
    │   │       ├── .gitignore
    │   │       ├── .golangci.yml
    │   │       ├── CODE_OF_CONDUCT.md
    │   │       ├── CONTRIBUTING.md
    │   │       ├── LICENSE
    │   │       ├── MAINTAINERS.md
    │   │       ├── Makefile
    │   │       ├── Makefile.common
    │   │       ├── NOTICE
    │   │       ├── README.md
    │   │       ├── SECURITY.md
    │   │       ├── arp.go
    │   │       ├── buddyinfo.go
    │   │       ├── cmdline.go
    │   │       ├── cpuinfo.go
    │   │       ├── cpuinfo_armx.go
    │   │       ├── cpuinfo_loong64.go
    │   │       ├── cpuinfo_mipsx.go
    │   │       ├── cpuinfo_others.go
    │   │       ├── cpuinfo_ppcx.go
    │   │       ├── cpuinfo_riscvx.go
    │   │       ├── cpuinfo_s390x.go
    │   │       ├── cpuinfo_x86.go
    │   │       ├── crypto.go
    │   │       ├── doc.go
    │   │       ├── fs.go
    │   │       ├── fscache.go
    │   │       ├── internal/
    │   │       │   ├── fs/
    │   │       │   │   └── fs.go
    │   │       │   └── util/
    │   │       │       ├── parse.go
    │   │       │       ├── readfile.go
    │   │       │       ├── sysreadfile.go
    │   │       │       ├── sysreadfile_compat.go
    │   │       │       └── valueparser.go
    │   │       ├── ipvs.go
    │   │       ├── kernel_random.go
    │   │       ├── loadavg.go
    │   │       ├── mdstat.go
    │   │       ├── meminfo.go
    │   │       ├── mountinfo.go
    │   │       ├── mountstats.go
    │   │       ├── net_conntrackstat.go
    │   │       ├── net_dev.go
    │   │       ├── net_ip_socket.go
    │   │       ├── net_protocols.go
    │   │       ├── net_sockstat.go
    │   │       ├── net_softnet.go
    │   │       ├── net_tcp.go
    │   │       ├── net_udp.go
    │   │       ├── net_unix.go
    │   │       ├── net_xfrm.go
    │   │       ├── netstat.go
    │   │       ├── proc.go
    │   │       ├── proc_cgroup.go
    │   │       ├── proc_cgroups.go
    │   │       ├── proc_environ.go
    │   │       ├── proc_fdinfo.go
    │   │       ├── proc_interrupts.go
    │   │       ├── proc_io.go
    │   │       ├── proc_limits.go
    │   │       ├── proc_maps.go
    │   │       ├── proc_netstat.go
    │   │       ├── proc_ns.go
    │   │       ├── proc_psi.go
    │   │       ├── proc_smaps.go
    │   │       ├── proc_snmp.go
    │   │       ├── proc_snmp6.go
    │   │       ├── proc_stat.go
    │   │       ├── proc_status.go
    │   │       ├── proc_sys.go
    │   │       ├── schedstat.go
    │   │       ├── slab.go
    │   │       ├── softirqs.go
    │   │       ├── stat.go
    │   │       ├── swaps.go
    │   │       ├── thread.go
    │   │       ├── ttar
    │   │       ├── vm.go
    │   │       └── zoneinfo.go
    │   ├── rs/
    │   │   └── cors/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── cors.go
    │   │       └── utils.go
    │   ├── stretchr/
    │   │   └── testify/
    │   │       ├── LICENSE
    │   │       └── assert/
    │   │           ├── assertion_compare.go
    │   │           ├── assertion_compare_can_convert.go
    │   │           ├── assertion_compare_legacy.go
    │   │           ├── assertion_format.go
    │   │           ├── assertion_format.go.tmpl
    │   │           ├── assertion_forward.go
    │   │           ├── assertion_forward.go.tmpl
    │   │           ├── assertion_order.go
    │   │           ├── assertions.go
    │   │           ├── doc.go
    │   │           ├── errors.go
    │   │           ├── forward_assertions.go
    │   │           └── http_assertions.go
    │   └── uber/
    │       └── jaeger-lib/
    │           ├── LICENSE
    │           └── metrics/
    │               ├── counter.go
    │               ├── factory.go
    │               ├── gauge.go
    │               ├── histogram.go
    │               ├── keys.go
    │               ├── metrics.go
    │               ├── stopwatch.go
    │               └── timer.go
    ├── golang.org/
    │   └── x/
    │       ├── crypto/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── cryptobyte/
    │       │   │   ├── asn1/
    │       │   │   │   └── asn1.go
    │       │   │   ├── asn1.go
    │       │   │   ├── builder.go
    │       │   │   └── string.go
    │       │   └── ed25519/
    │       │       └── ed25519.go
    │       ├── net/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── context/
    │       │   │   └── ctxhttp/
    │       │   │       └── ctxhttp.go
    │       │   ├── http/
    │       │   │   └── httpguts/
    │       │   │       ├── guts.go
    │       │   │       └── httplex.go
    │       │   ├── http2/
    │       │   │   ├── .gitignore
    │       │   │   ├── Dockerfile
    │       │   │   ├── Makefile
    │       │   │   ├── ascii.go
    │       │   │   ├── ciphers.go
    │       │   │   ├── client_conn_pool.go
    │       │   │   ├── databuffer.go
    │       │   │   ├── errors.go
    │       │   │   ├── flow.go
    │       │   │   ├── frame.go
    │       │   │   ├── go111.go
    │       │   │   ├── go115.go
    │       │   │   ├── go118.go
    │       │   │   ├── gotrack.go
    │       │   │   ├── headermap.go
    │       │   │   ├── hpack/
    │       │   │   │   ├── encode.go
    │       │   │   │   ├── hpack.go
    │       │   │   │   ├── huffman.go
    │       │   │   │   ├── static_table.go
    │       │   │   │   └── tables.go
    │       │   │   ├── http2.go
    │       │   │   ├── not_go111.go
    │       │   │   ├── not_go115.go
    │       │   │   ├── not_go118.go
    │       │   │   ├── pipe.go
    │       │   │   ├── server.go
    │       │   │   ├── transport.go
    │       │   │   ├── write.go
    │       │   │   ├── writesched.go
    │       │   │   ├── writesched_priority.go
    │       │   │   └── writesched_random.go
    │       │   ├── idna/
    │       │   │   ├── go118.go
    │       │   │   ├── idna10.0.0.go
    │       │   │   ├── idna9.0.0.go
    │       │   │   ├── pre_go118.go
    │       │   │   ├── punycode.go
    │       │   │   ├── tables10.0.0.go
    │       │   │   ├── tables11.0.0.go
    │       │   │   ├── tables12.0.0.go
    │       │   │   ├── tables13.0.0.go
    │       │   │   ├── tables9.0.0.go
    │       │   │   ├── trie.go
    │       │   │   └── trieval.go
    │       │   ├── internal/
    │       │   │   └── timeseries/
    │       │   │       └── timeseries.go
    │       │   └── trace/
    │       │       ├── events.go
    │       │       ├── histogram.go
    │       │       └── trace.go
    │       ├── sys/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── execabs/
    │       │   │   ├── execabs.go
    │       │   │   ├── execabs_go118.go
    │       │   │   └── execabs_go119.go
    │       │   ├── internal/
    │       │   │   └── unsafeheader/
    │       │   │       └── unsafeheader.go
    │       │   ├── unix/
    │       │   │   ├── .gitignore
    │       │   │   ├── README.md
    │       │   │   ├── affinity_linux.go
    │       │   │   ├── aliases.go
    │       │   │   ├── asm_aix_ppc64.s
    │       │   │   ├── asm_bsd_386.s
    │       │   │   ├── asm_bsd_amd64.s
    │       │   │   ├── asm_bsd_arm.s
    │       │   │   ├── asm_bsd_arm64.s
    │       │   │   ├── asm_bsd_ppc64.s
    │       │   │   ├── asm_bsd_riscv64.s
    │       │   │   ├── asm_linux_386.s
    │       │   │   ├── asm_linux_amd64.s
    │       │   │   ├── asm_linux_arm.s
    │       │   │   ├── asm_linux_arm64.s
    │       │   │   ├── asm_linux_loong64.s
    │       │   │   ├── asm_linux_mips64x.s
    │       │   │   ├── asm_linux_mipsx.s
    │       │   │   ├── asm_linux_ppc64x.s
    │       │   │   ├── asm_linux_riscv64.s
    │       │   │   ├── asm_linux_s390x.s
    │       │   │   ├── asm_openbsd_mips64.s
    │       │   │   ├── asm_solaris_amd64.s
    │       │   │   ├── asm_zos_s390x.s
    │       │   │   ├── bluetooth_linux.go
    │       │   │   ├── cap_freebsd.go
    │       │   │   ├── constants.go
    │       │   │   ├── dev_aix_ppc.go
    │       │   │   ├── dev_aix_ppc64.go
    │       │   │   ├── dev_darwin.go
    │       │   │   ├── dev_dragonfly.go
    │       │   │   ├── dev_freebsd.go
    │       │   │   ├── dev_linux.go
    │       │   │   ├── dev_netbsd.go
    │       │   │   ├── dev_openbsd.go
    │       │   │   ├── dev_zos.go
    │       │   │   ├── dirent.go
    │       │   │   ├── endian_big.go
    │       │   │   ├── endian_little.go
    │       │   │   ├── env_unix.go
    │       │   │   ├── epoll_zos.go
    │       │   │   ├── fcntl.go
    │       │   │   ├── fcntl_darwin.go
    │       │   │   ├── fcntl_linux_32bit.go
    │       │   │   ├── fdset.go
    │       │   │   ├── fstatfs_zos.go
    │       │   │   ├── gccgo.go
    │       │   │   ├── gccgo_c.c
    │       │   │   ├── gccgo_linux_amd64.go
    │       │   │   ├── ifreq_linux.go
    │       │   │   ├── ioctl.go
    │       │   │   ├── ioctl_linux.go
    │       │   │   ├── ioctl_zos.go
    │       │   │   ├── mkall.sh
    │       │   │   ├── mkerrors.sh
    │       │   │   ├── pagesize_unix.go
    │       │   │   ├── pledge_openbsd.go
    │       │   │   ├── ptrace_darwin.go
    │       │   │   ├── ptrace_ios.go
    │       │   │   ├── race.go
    │       │   │   ├── race0.go
    │       │   │   ├── readdirent_getdents.go
    │       │   │   ├── readdirent_getdirentries.go
    │       │   │   ├── sockcmsg_dragonfly.go
    │       │   │   ├── sockcmsg_linux.go
    │       │   │   ├── sockcmsg_unix.go
    │       │   │   ├── sockcmsg_unix_other.go
    │       │   │   ├── syscall.go
    │       │   │   ├── syscall_aix.go
    │       │   │   ├── syscall_aix_ppc.go
    │       │   │   ├── syscall_aix_ppc64.go
    │       │   │   ├── syscall_bsd.go
    │       │   │   ├── syscall_darwin.go
    │       │   │   ├── syscall_darwin_amd64.go
    │       │   │   ├── syscall_darwin_arm64.go
    │       │   │   ├── syscall_darwin_libSystem.go
    │       │   │   ├── syscall_dragonfly.go
    │       │   │   ├── syscall_dragonfly_amd64.go
    │       │   │   ├── syscall_freebsd.go
    │       │   │   ├── syscall_freebsd_386.go
    │       │   │   ├── syscall_freebsd_amd64.go
    │       │   │   ├── syscall_freebsd_arm.go
    │       │   │   ├── syscall_freebsd_arm64.go
    │       │   │   ├── syscall_freebsd_riscv64.go
    │       │   │   ├── syscall_hurd.go
    │       │   │   ├── syscall_hurd_386.go
    │       │   │   ├── syscall_illumos.go
    │       │   │   ├── syscall_linux.go
    │       │   │   ├── syscall_linux_386.go
    │       │   │   ├── syscall_linux_alarm.go
    │       │   │   ├── syscall_linux_amd64.go
    │       │   │   ├── syscall_linux_amd64_gc.go
    │       │   │   ├── syscall_linux_arm.go
    │       │   │   ├── syscall_linux_arm64.go
    │       │   │   ├── syscall_linux_gc.go
    │       │   │   ├── syscall_linux_gc_386.go
    │       │   │   ├── syscall_linux_gc_arm.go
    │       │   │   ├── syscall_linux_gccgo_386.go
    │       │   │   ├── syscall_linux_gccgo_arm.go
    │       │   │   ├── syscall_linux_loong64.go
    │       │   │   ├── syscall_linux_mips64x.go
    │       │   │   ├── syscall_linux_mipsx.go
    │       │   │   ├── syscall_linux_ppc.go
    │       │   │   ├── syscall_linux_ppc64x.go
    │       │   │   ├── syscall_linux_riscv64.go
    │       │   │   ├── syscall_linux_s390x.go
    │       │   │   ├── syscall_linux_sparc64.go
    │       │   │   ├── syscall_netbsd.go
    │       │   │   ├── syscall_netbsd_386.go
    │       │   │   ├── syscall_netbsd_amd64.go
    │       │   │   ├── syscall_netbsd_arm.go
    │       │   │   ├── syscall_netbsd_arm64.go
    │       │   │   ├── syscall_openbsd.go
    │       │   │   ├── syscall_openbsd_386.go
    │       │   │   ├── syscall_openbsd_amd64.go
    │       │   │   ├── syscall_openbsd_arm.go
    │       │   │   ├── syscall_openbsd_arm64.go
    │       │   │   ├── syscall_openbsd_libc.go
    │       │   │   ├── syscall_openbsd_mips64.go
    │       │   │   ├── syscall_openbsd_ppc64.go
    │       │   │   ├── syscall_openbsd_riscv64.go
    │       │   │   ├── syscall_solaris.go
    │       │   │   ├── syscall_solaris_amd64.go
    │       │   │   ├── syscall_unix.go
    │       │   │   ├── syscall_unix_gc.go
    │       │   │   ├── syscall_unix_gc_ppc64x.go
    │       │   │   ├── syscall_zos_s390x.go
    │       │   │   ├── sysvshm_linux.go
    │       │   │   ├── sysvshm_unix.go
    │       │   │   ├── sysvshm_unix_other.go
    │       │   │   ├── timestruct.go
    │       │   │   ├── unveil_openbsd.go
    │       │   │   ├── xattr_bsd.go
    │       │   │   ├── zerrors_aix_ppc.go
    │       │   │   ├── zerrors_aix_ppc64.go
    │       │   │   ├── zerrors_darwin_amd64.go
    │       │   │   ├── zerrors_darwin_arm64.go
    │       │   │   ├── zerrors_dragonfly_amd64.go
    │       │   │   ├── zerrors_freebsd_386.go
    │       │   │   ├── zerrors_freebsd_amd64.go
    │       │   │   ├── zerrors_freebsd_arm.go
    │       │   │   ├── zerrors_freebsd_arm64.go
    │       │   │   ├── zerrors_freebsd_riscv64.go
    │       │   │   ├── zerrors_linux.go
    │       │   │   ├── zerrors_linux_386.go
    │       │   │   ├── zerrors_linux_amd64.go
    │       │   │   ├── zerrors_linux_arm.go
    │       │   │   ├── zerrors_linux_arm64.go
    │       │   │   ├── zerrors_linux_loong64.go
    │       │   │   ├── zerrors_linux_mips.go
    │       │   │   ├── zerrors_linux_mips64.go
    │       │   │   ├── zerrors_linux_mips64le.go
    │       │   │   ├── zerrors_linux_mipsle.go
    │       │   │   ├── zerrors_linux_ppc.go
    │       │   │   ├── zerrors_linux_ppc64.go
    │       │   │   ├── zerrors_linux_ppc64le.go
    │       │   │   ├── zerrors_linux_riscv64.go
    │       │   │   ├── zerrors_linux_s390x.go
    │       │   │   ├── zerrors_linux_sparc64.go
    │       │   │   ├── zerrors_netbsd_386.go
    │       │   │   ├── zerrors_netbsd_amd64.go
    │       │   │   ├── zerrors_netbsd_arm.go
    │       │   │   ├── zerrors_netbsd_arm64.go
    │       │   │   ├── zerrors_openbsd_386.go
    │       │   │   ├── zerrors_openbsd_amd64.go
    │       │   │   ├── zerrors_openbsd_arm.go
    │       │   │   ├── zerrors_openbsd_arm64.go
    │       │   │   ├── zerrors_openbsd_mips64.go
    │       │   │   ├── zerrors_openbsd_ppc64.go
    │       │   │   ├── zerrors_openbsd_riscv64.go
    │       │   │   ├── zerrors_solaris_amd64.go
    │       │   │   ├── zerrors_zos_s390x.go
    │       │   │   ├── zptrace_armnn_linux.go
    │       │   │   ├── zptrace_linux_arm64.go
    │       │   │   ├── zptrace_mipsnn_linux.go
    │       │   │   ├── zptrace_mipsnnle_linux.go
    │       │   │   ├── zptrace_x86_linux.go
    │       │   │   ├── zsyscall_aix_ppc.go
    │       │   │   ├── zsyscall_aix_ppc64.go
    │       │   │   ├── zsyscall_aix_ppc64_gc.go
    │       │   │   ├── zsyscall_aix_ppc64_gccgo.go
    │       │   │   ├── zsyscall_darwin_amd64.go
    │       │   │   ├── zsyscall_darwin_amd64.s
    │       │   │   ├── zsyscall_darwin_arm64.go
    │       │   │   ├── zsyscall_darwin_arm64.s
    │       │   │   ├── zsyscall_dragonfly_amd64.go
    │       │   │   ├── zsyscall_freebsd_386.go
    │       │   │   ├── zsyscall_freebsd_amd64.go
    │       │   │   ├── zsyscall_freebsd_arm.go
    │       │   │   ├── zsyscall_freebsd_arm64.go
    │       │   │   ├── zsyscall_freebsd_riscv64.go
    │       │   │   ├── zsyscall_illumos_amd64.go
    │       │   │   ├── zsyscall_linux.go
    │       │   │   ├── zsyscall_linux_386.go
    │       │   │   ├── zsyscall_linux_amd64.go
    │       │   │   ├── zsyscall_linux_arm.go
    │       │   │   ├── zsyscall_linux_arm64.go
    │       │   │   ├── zsyscall_linux_loong64.go
    │       │   │   ├── zsyscall_linux_mips.go
    │       │   │   ├── zsyscall_linux_mips64.go
    │       │   │   ├── zsyscall_linux_mips64le.go
    │       │   │   ├── zsyscall_linux_mipsle.go
    │       │   │   ├── zsyscall_linux_ppc.go
    │       │   │   ├── zsyscall_linux_ppc64.go
    │       │   │   ├── zsyscall_linux_ppc64le.go
    │       │   │   ├── zsyscall_linux_riscv64.go
    │       │   │   ├── zsyscall_linux_s390x.go
    │       │   │   ├── zsyscall_linux_sparc64.go
    │       │   │   ├── zsyscall_netbsd_386.go
    │       │   │   ├── zsyscall_netbsd_amd64.go
    │       │   │   ├── zsyscall_netbsd_arm.go
    │       │   │   ├── zsyscall_netbsd_arm64.go
    │       │   │   ├── zsyscall_openbsd_386.go
    │       │   │   ├── zsyscall_openbsd_386.s
    │       │   │   ├── zsyscall_openbsd_amd64.go
    │       │   │   ├── zsyscall_openbsd_amd64.s
    │       │   │   ├── zsyscall_openbsd_arm.go
    │       │   │   ├── zsyscall_openbsd_arm.s
    │       │   │   ├── zsyscall_openbsd_arm64.go
    │       │   │   ├── zsyscall_openbsd_arm64.s
    │       │   │   ├── zsyscall_openbsd_mips64.go
    │       │   │   ├── zsyscall_openbsd_mips64.s
    │       │   │   ├── zsyscall_openbsd_ppc64.go
    │       │   │   ├── zsyscall_openbsd_ppc64.s
    │       │   │   ├── zsyscall_openbsd_riscv64.go
    │       │   │   ├── zsyscall_openbsd_riscv64.s
    │       │   │   ├── zsyscall_solaris_amd64.go
    │       │   │   ├── zsyscall_zos_s390x.go
    │       │   │   ├── zsysctl_openbsd_386.go
    │       │   │   ├── zsysctl_openbsd_amd64.go
    │       │   │   ├── zsysctl_openbsd_arm.go
    │       │   │   ├── zsysctl_openbsd_arm64.go
    │       │   │   ├── zsysctl_openbsd_mips64.go
    │       │   │   ├── zsysctl_openbsd_ppc64.go
    │       │   │   ├── zsysctl_openbsd_riscv64.go
    │       │   │   ├── zsysnum_darwin_amd64.go
    │       │   │   ├── zsysnum_darwin_arm64.go
    │       │   │   ├── zsysnum_dragonfly_amd64.go
    │       │   │   ├── zsysnum_freebsd_386.go
    │       │   │   ├── zsysnum_freebsd_amd64.go
    │       │   │   ├── zsysnum_freebsd_arm.go
    │       │   │   ├── zsysnum_freebsd_arm64.go
    │       │   │   ├── zsysnum_freebsd_riscv64.go
    │       │   │   ├── zsysnum_linux_386.go
    │       │   │   ├── zsysnum_linux_amd64.go
    │       │   │   ├── zsysnum_linux_arm.go
    │       │   │   ├── zsysnum_linux_arm64.go
    │       │   │   ├── zsysnum_linux_loong64.go
    │       │   │   ├── zsysnum_linux_mips.go
    │       │   │   ├── zsysnum_linux_mips64.go
    │       │   │   ├── zsysnum_linux_mips64le.go
    │       │   │   ├── zsysnum_linux_mipsle.go
    │       │   │   ├── zsysnum_linux_ppc.go
    │       │   │   ├── zsysnum_linux_ppc64.go
    │       │   │   ├── zsysnum_linux_ppc64le.go
    │       │   │   ├── zsysnum_linux_riscv64.go
    │       │   │   ├── zsysnum_linux_s390x.go
    │       │   │   ├── zsysnum_linux_sparc64.go
    │       │   │   ├── zsysnum_netbsd_386.go
    │       │   │   ├── zsysnum_netbsd_amd64.go
    │       │   │   ├── zsysnum_netbsd_arm.go
    │       │   │   ├── zsysnum_netbsd_arm64.go
    │       │   │   ├── zsysnum_openbsd_386.go
    │       │   │   ├── zsysnum_openbsd_amd64.go
    │       │   │   ├── zsysnum_openbsd_arm.go
    │       │   │   ├── zsysnum_openbsd_arm64.go
    │       │   │   ├── zsysnum_openbsd_mips64.go
    │       │   │   ├── zsysnum_openbsd_ppc64.go
    │       │   │   ├── zsysnum_openbsd_riscv64.go
    │       │   │   ├── zsysnum_zos_s390x.go
    │       │   │   ├── ztypes_aix_ppc.go
    │       │   │   ├── ztypes_aix_ppc64.go
    │       │   │   ├── ztypes_darwin_amd64.go
    │       │   │   ├── ztypes_darwin_arm64.go
    │       │   │   ├── ztypes_dragonfly_amd64.go
    │       │   │   ├── ztypes_freebsd_386.go
    │       │   │   ├── ztypes_freebsd_amd64.go
    │       │   │   ├── ztypes_freebsd_arm.go
    │       │   │   ├── ztypes_freebsd_arm64.go
    │       │   │   ├── ztypes_freebsd_riscv64.go
    │       │   │   ├── ztypes_linux.go
    │       │   │   ├── ztypes_linux_386.go
    │       │   │   ├── ztypes_linux_amd64.go
    │       │   │   ├── ztypes_linux_arm.go
    │       │   │   ├── ztypes_linux_arm64.go
    │       │   │   ├── ztypes_linux_loong64.go
    │       │   │   ├── ztypes_linux_mips.go
    │       │   │   ├── ztypes_linux_mips64.go
    │       │   │   ├── ztypes_linux_mips64le.go
    │       │   │   ├── ztypes_linux_mipsle.go
    │       │   │   ├── ztypes_linux_ppc.go
    │       │   │   ├── ztypes_linux_ppc64.go
    │       │   │   ├── ztypes_linux_ppc64le.go
    │       │   │   ├── ztypes_linux_riscv64.go
    │       │   │   ├── ztypes_linux_s390x.go
    │       │   │   ├── ztypes_linux_sparc64.go
    │       │   │   ├── ztypes_netbsd_386.go
    │       │   │   ├── ztypes_netbsd_amd64.go
    │       │   │   ├── ztypes_netbsd_arm.go
    │       │   │   ├── ztypes_netbsd_arm64.go
    │       │   │   ├── ztypes_openbsd_386.go
    │       │   │   ├── ztypes_openbsd_amd64.go
    │       │   │   ├── ztypes_openbsd_arm.go
    │       │   │   ├── ztypes_openbsd_arm64.go
    │       │   │   ├── ztypes_openbsd_mips64.go
    │       │   │   ├── ztypes_openbsd_ppc64.go
    │       │   │   ├── ztypes_openbsd_riscv64.go
    │       │   │   ├── ztypes_solaris_amd64.go
    │       │   │   └── ztypes_zos_s390x.go
    │       │   └── windows/
    │       │       ├── aliases.go
    │       │       ├── dll_windows.go
    │       │       ├── empty.s
    │       │       ├── env_windows.go
    │       │       ├── eventlog.go
    │       │       ├── exec_windows.go
    │       │       ├── memory_windows.go
    │       │       ├── mkerrors.bash
    │       │       ├── mkknownfolderids.bash
    │       │       ├── mksyscall.go
    │       │       ├── race.go
    │       │       ├── race0.go
    │       │       ├── security_windows.go
    │       │       ├── service.go
    │       │       ├── setupapi_windows.go
    │       │       ├── str.go
    │       │       ├── syscall.go
    │       │       ├── syscall_windows.go
    │       │       ├── types_windows.go
    │       │       ├── types_windows_386.go
    │       │       ├── types_windows_amd64.go
    │       │       ├── types_windows_arm.go
    │       │       ├── types_windows_arm64.go
    │       │       ├── zerrors_windows.go
    │       │       ├── zknownfolderids_windows.go
    │       │       └── zsyscall_windows.go
    │       └── text/
    │           ├── LICENSE
    │           ├── PATENTS
    │           ├── cases/
    │           │   ├── cases.go
    │           │   ├── context.go
    │           │   ├── fold.go
    │           │   ├── icu.go
    │           │   ├── info.go
    │           │   ├── map.go
    │           │   ├── tables10.0.0.go
    │           │   ├── tables11.0.0.go
    │           │   ├── tables12.0.0.go
    │           │   ├── tables13.0.0.go
    │           │   ├── tables9.0.0.go
    │           │   └── trieval.go
    │           ├── internal/
    │           │   ├── internal.go
    │           │   ├── language/
    │           │   │   ├── common.go
    │           │   │   ├── compact/
    │           │   │   │   ├── compact.go
    │           │   │   │   ├── language.go
    │           │   │   │   ├── parents.go
    │           │   │   │   ├── tables.go
    │           │   │   │   └── tags.go
    │           │   │   ├── compact.go
    │           │   │   ├── compose.go
    │           │   │   ├── coverage.go
    │           │   │   ├── language.go
    │           │   │   ├── lookup.go
    │           │   │   ├── match.go
    │           │   │   ├── parse.go
    │           │   │   ├── tables.go
    │           │   │   └── tags.go
    │           │   ├── match.go
    │           │   └── tag/
    │           │       └── tag.go
    │           ├── language/
    │           │   ├── coverage.go
    │           │   ├── doc.go
    │           │   ├── language.go
    │           │   ├── match.go
    │           │   ├── parse.go
    │           │   ├── tables.go
    │           │   └── tags.go
    │           ├── secure/
    │           │   └── bidirule/
    │           │       ├── bidirule.go
    │           │       ├── bidirule10.0.0.go
    │           │       └── bidirule9.0.0.go
    │           ├── transform/
    │           │   └── transform.go
    │           └── unicode/
    │               ├── bidi/
    │               │   ├── bidi.go
    │               │   ├── bracket.go
    │               │   ├── core.go
    │               │   ├── prop.go
    │               │   ├── tables10.0.0.go
    │               │   ├── tables11.0.0.go
    │               │   ├── tables12.0.0.go
    │               │   ├── tables13.0.0.go
    │               │   ├── tables9.0.0.go
    │               │   └── trieval.go
    │               └── norm/
    │                   ├── composition.go
    │                   ├── forminfo.go
    │                   ├── input.go
    │                   ├── iter.go
    │                   ├── normalize.go
    │                   ├── readwriter.go
    │                   ├── tables10.0.0.go
    │                   ├── tables11.0.0.go
    │                   ├── tables12.0.0.go
    │                   ├── tables13.0.0.go
    │                   ├── tables9.0.0.go
    │                   ├── transform.go
    │                   └── trie.go
    ├── google.golang.org/
    │   ├── genproto/
    │   │   ├── LICENSE
    │   │   └── googleapis/
    │   │       └── rpc/
    │   │           └── status/
    │   │               └── status.pb.go
    │   ├── grpc/
    │   │   ├── AUTHORS
    │   │   ├── CODE-OF-CONDUCT.md
    │   │   ├── CONTRIBUTING.md
    │   │   ├── GOVERNANCE.md
    │   │   ├── LICENSE
    │   │   ├── MAINTAINERS.md
    │   │   ├── Makefile
    │   │   ├── NOTICE.txt
    │   │   ├── README.md
    │   │   ├── SECURITY.md
    │   │   ├── attributes/
    │   │   │   └── attributes.go
    │   │   ├── backoff/
    │   │   │   └── backoff.go
    │   │   ├── backoff.go
    │   │   ├── balancer/
    │   │   │   ├── balancer.go
    │   │   │   ├── base/
    │   │   │   │   ├── balancer.go
    │   │   │   │   └── base.go
    │   │   │   ├── conn_state_evaluator.go
    │   │   │   ├── grpclb/
    │   │   │   │   └── state/
    │   │   │   │       └── state.go
    │   │   │   └── roundrobin/
    │   │   │       └── roundrobin.go
    │   │   ├── balancer_conn_wrappers.go
    │   │   ├── binarylog/
    │   │   │   └── grpc_binarylog_v1/
    │   │   │       └── binarylog.pb.go
    │   │   ├── call.go
    │   │   ├── channelz/
    │   │   │   └── channelz.go
    │   │   ├── clientconn.go
    │   │   ├── codec.go
    │   │   ├── codegen.sh
    │   │   ├── codes/
    │   │   │   ├── code_string.go
    │   │   │   └── codes.go
    │   │   ├── connectivity/
    │   │   │   └── connectivity.go
    │   │   ├── credentials/
    │   │   │   ├── credentials.go
    │   │   │   ├── insecure/
    │   │   │   │   └── insecure.go
    │   │   │   └── tls.go
    │   │   ├── dialoptions.go
    │   │   ├── doc.go
    │   │   ├── encoding/
    │   │   │   ├── encoding.go
    │   │   │   └── proto/
    │   │   │       └── proto.go
    │   │   ├── grpclog/
    │   │   │   ├── component.go
    │   │   │   ├── grpclog.go
    │   │   │   ├── logger.go
    │   │   │   └── loggerv2.go
    │   │   ├── interceptor.go
    │   │   ├── internal/
    │   │   │   ├── backoff/
    │   │   │   │   └── backoff.go
    │   │   │   ├── balancer/
    │   │   │   │   └── gracefulswitch/
    │   │   │   │       └── gracefulswitch.go
    │   │   │   ├── balancerload/
    │   │   │   │   └── load.go
    │   │   │   ├── binarylog/
    │   │   │   │   ├── binarylog.go
    │   │   │   │   ├── binarylog_testutil.go
    │   │   │   │   ├── env_config.go
    │   │   │   │   ├── method_logger.go
    │   │   │   │   └── sink.go
    │   │   │   ├── buffer/
    │   │   │   │   └── unbounded.go
    │   │   │   ├── channelz/
    │   │   │   │   ├── funcs.go
    │   │   │   │   ├── id.go
    │   │   │   │   ├── logging.go
    │   │   │   │   ├── types.go
    │   │   │   │   ├── types_linux.go
    │   │   │   │   ├── types_nonlinux.go
    │   │   │   │   ├── util_linux.go
    │   │   │   │   └── util_nonlinux.go
    │   │   │   ├── credentials/
    │   │   │   │   ├── credentials.go
    │   │   │   │   ├── spiffe.go
    │   │   │   │   ├── syscallconn.go
    │   │   │   │   └── util.go
    │   │   │   ├── envconfig/
    │   │   │   │   ├── envconfig.go
    │   │   │   │   ├── observability.go
    │   │   │   │   └── xds.go
    │   │   │   ├── grpclog/
    │   │   │   │   ├── grpclog.go
    │   │   │   │   └── prefixLogger.go
    │   │   │   ├── grpcrand/
    │   │   │   │   └── grpcrand.go
    │   │   │   ├── grpcsync/
    │   │   │   │   ├── event.go
    │   │   │   │   └── oncefunc.go
    │   │   │   ├── grpcutil/
    │   │   │   │   ├── compressor.go
    │   │   │   │   ├── encode_duration.go
    │   │   │   │   ├── grpcutil.go
    │   │   │   │   ├── metadata.go
    │   │   │   │   ├── method.go
    │   │   │   │   └── regex.go
    │   │   │   ├── internal.go
    │   │   │   ├── metadata/
    │   │   │   │   └── metadata.go
    │   │   │   ├── pretty/
    │   │   │   │   └── pretty.go
    │   │   │   ├── resolver/
    │   │   │   │   ├── config_selector.go
    │   │   │   │   ├── dns/
    │   │   │   │   │   └── dns_resolver.go
    │   │   │   │   ├── passthrough/
    │   │   │   │   │   └── passthrough.go
    │   │   │   │   └── unix/
    │   │   │   │       └── unix.go
    │   │   │   ├── serviceconfig/
    │   │   │   │   └── serviceconfig.go
    │   │   │   ├── status/
    │   │   │   │   └── status.go
    │   │   │   ├── syscall/
    │   │   │   │   ├── syscall_linux.go
    │   │   │   │   └── syscall_nonlinux.go
    │   │   │   ├── transport/
    │   │   │   │   ├── bdp_estimator.go
    │   │   │   │   ├── controlbuf.go
    │   │   │   │   ├── defaults.go
    │   │   │   │   ├── flowcontrol.go
    │   │   │   │   ├── handler_server.go
    │   │   │   │   ├── http2_client.go
    │   │   │   │   ├── http2_server.go
    │   │   │   │   ├── http_util.go
    │   │   │   │   ├── networktype/
    │   │   │   │   │   └── networktype.go
    │   │   │   │   ├── proxy.go
    │   │   │   │   └── transport.go
    │   │   │   └── xds_handshake_cluster.go
    │   │   ├── keepalive/
    │   │   │   └── keepalive.go
    │   │   ├── metadata/
    │   │   │   └── metadata.go
    │   │   ├── peer/
    │   │   │   └── peer.go
    │   │   ├── picker_wrapper.go
    │   │   ├── pickfirst.go
    │   │   ├── preloader.go
    │   │   ├── regenerate.sh
    │   │   ├── resolver/
    │   │   │   ├── map.go
    │   │   │   └── resolver.go
    │   │   ├── resolver_conn_wrapper.go
    │   │   ├── rpc_util.go
    │   │   ├── server.go
    │   │   ├── service_config.go
    │   │   ├── serviceconfig/
    │   │   │   └── serviceconfig.go
    │   │   ├── stats/
    │   │   │   ├── handlers.go
    │   │   │   └── stats.go
    │   │   ├── status/
    │   │   │   └── status.go
    │   │   ├── stream.go
    │   │   ├── tap/
    │   │   │   └── tap.go
    │   │   ├── trace.go
    │   │   ├── version.go
    │   │   └── vet.sh
    │   └── protobuf/
    │       ├── LICENSE
    │       ├── PATENTS
    │       ├── encoding/
    │       │   ├── protojson/
    │       │   │   ├── decode.go
    │       │   │   ├── doc.go
    │       │   │   ├── encode.go
    │       │   │   └── well_known_types.go
    │       │   ├── prototext/
    │       │   │   ├── decode.go
    │       │   │   ├── doc.go
    │       │   │   └── encode.go
    │       │   └── protowire/
    │       │       └── wire.go
    │       ├── internal/
    │       │   ├── descfmt/
    │       │   │   └── stringer.go
    │       │   ├── descopts/
    │       │   │   └── options.go
    │       │   ├── detrand/
    │       │   │   └── rand.go
    │       │   ├── encoding/
    │       │   │   ├── defval/
    │       │   │   │   └── default.go
    │       │   │   ├── json/
    │       │   │   │   ├── decode.go
    │       │   │   │   ├── decode_number.go
    │       │   │   │   ├── decode_string.go
    │       │   │   │   ├── decode_token.go
    │       │   │   │   └── encode.go
    │       │   │   ├── messageset/
    │       │   │   │   └── messageset.go
    │       │   │   ├── tag/
    │       │   │   │   └── tag.go
    │       │   │   └── text/
    │       │   │       ├── decode.go
    │       │   │       ├── decode_number.go
    │       │   │       ├── decode_string.go
    │       │   │       ├── decode_token.go
    │       │   │       ├── doc.go
    │       │   │       └── encode.go
    │       │   ├── errors/
    │       │   │   ├── errors.go
    │       │   │   ├── is_go112.go
    │       │   │   └── is_go113.go
    │       │   ├── filedesc/
    │       │   │   ├── build.go
    │       │   │   ├── desc.go
    │       │   │   ├── desc_init.go
    │       │   │   ├── desc_lazy.go
    │       │   │   ├── desc_list.go
    │       │   │   ├── desc_list_gen.go
    │       │   │   └── placeholder.go
    │       │   ├── filetype/
    │       │   │   └── build.go
    │       │   ├── flags/
    │       │   │   ├── flags.go
    │       │   │   ├── proto_legacy_disable.go
    │       │   │   └── proto_legacy_enable.go
    │       │   ├── genid/
    │       │   │   ├── any_gen.go
    │       │   │   ├── api_gen.go
    │       │   │   ├── descriptor_gen.go
    │       │   │   ├── doc.go
    │       │   │   ├── duration_gen.go
    │       │   │   ├── empty_gen.go
    │       │   │   ├── field_mask_gen.go
    │       │   │   ├── goname.go
    │       │   │   ├── map_entry.go
    │       │   │   ├── source_context_gen.go
    │       │   │   ├── struct_gen.go
    │       │   │   ├── timestamp_gen.go
    │       │   │   ├── type_gen.go
    │       │   │   ├── wrappers.go
    │       │   │   └── wrappers_gen.go
    │       │   ├── impl/
    │       │   │   ├── api_export.go
    │       │   │   ├── checkinit.go
    │       │   │   ├── codec_extension.go
    │       │   │   ├── codec_field.go
    │       │   │   ├── codec_gen.go
    │       │   │   ├── codec_map.go
    │       │   │   ├── codec_map_go111.go
    │       │   │   ├── codec_map_go112.go
    │       │   │   ├── codec_message.go
    │       │   │   ├── codec_messageset.go
    │       │   │   ├── codec_reflect.go
    │       │   │   ├── codec_tables.go
    │       │   │   ├── codec_unsafe.go
    │       │   │   ├── convert.go
    │       │   │   ├── convert_list.go
    │       │   │   ├── convert_map.go
    │       │   │   ├── decode.go
    │       │   │   ├── encode.go
    │       │   │   ├── enum.go
    │       │   │   ├── extension.go
    │       │   │   ├── legacy_enum.go
    │       │   │   ├── legacy_export.go
    │       │   │   ├── legacy_extension.go
    │       │   │   ├── legacy_file.go
    │       │   │   ├── legacy_message.go
    │       │   │   ├── merge.go
    │       │   │   ├── merge_gen.go
    │       │   │   ├── message.go
    │       │   │   ├── message_reflect.go
    │       │   │   ├── message_reflect_field.go
    │       │   │   ├── message_reflect_gen.go
    │       │   │   ├── pointer_reflect.go
    │       │   │   ├── pointer_unsafe.go
    │       │   │   ├── validate.go
    │       │   │   └── weak.go
    │       │   ├── order/
    │       │   │   ├── order.go
    │       │   │   └── range.go
    │       │   ├── pragma/
    │       │   │   └── pragma.go
    │       │   ├── set/
    │       │   │   └── ints.go
    │       │   ├── strs/
    │       │   │   ├── strings.go
    │       │   │   ├── strings_pure.go
    │       │   │   └── strings_unsafe.go
    │       │   └── version/
    │       │       └── version.go
    │       ├── proto/
    │       │   ├── checkinit.go
    │       │   ├── decode.go
    │       │   ├── decode_gen.go
    │       │   ├── doc.go
    │       │   ├── encode.go
    │       │   ├── encode_gen.go
    │       │   ├── equal.go
    │       │   ├── extension.go
    │       │   ├── merge.go
    │       │   ├── messageset.go
    │       │   ├── proto.go
    │       │   ├── proto_methods.go
    │       │   ├── proto_reflect.go
    │       │   ├── reset.go
    │       │   ├── size.go
    │       │   ├── size_gen.go
    │       │   └── wrappers.go
    │       ├── reflect/
    │       │   ├── protodesc/
    │       │   │   ├── desc.go
    │       │   │   ├── desc_init.go
    │       │   │   ├── desc_resolve.go
    │       │   │   ├── desc_validate.go
    │       │   │   └── proto.go
    │       │   ├── protoreflect/
    │       │   │   ├── methods.go
    │       │   │   ├── proto.go
    │       │   │   ├── source.go
    │       │   │   ├── source_gen.go
    │       │   │   ├── type.go
    │       │   │   ├── value.go
    │       │   │   ├── value_equal.go
    │       │   │   ├── value_pure.go
    │       │   │   ├── value_union.go
    │       │   │   └── value_unsafe.go
    │       │   └── protoregistry/
    │       │       └── registry.go
    │       ├── runtime/
    │       │   ├── protoiface/
    │       │   │   ├── legacy.go
    │       │   │   └── methods.go
    │       │   └── protoimpl/
    │       │       ├── impl.go
    │       │       └── version.go
    │       └── types/
    │           ├── descriptorpb/
    │           │   └── descriptor.pb.go
    │           └── known/
    │               ├── anypb/
    │               │   └── any.pb.go
    │               ├── durationpb/
    │               │   └── duration.pb.go
    │               └── timestamppb/
    │                   └── timestamp.pb.go
    ├── gopkg.in/
    │   └── yaml.v3/
    │       ├── LICENSE
    │       ├── NOTICE
    │       ├── README.md
    │       ├── apic.go
    │       ├── decode.go
    │       ├── emitterc.go
    │       ├── encode.go
    │       ├── parserc.go
    │       ├── readerc.go
    │       ├── resolve.go
    │       ├── scannerc.go
    │       ├── sorter.go
    │       ├── writerc.go
    │       ├── yaml.go
    │       ├── yamlh.go
    │       └── yamlprivateh.go
    ├── k8s.io/
    │   └── klog/
    │       └── v2/
    │           ├── .gitignore
    │           ├── CONTRIBUTING.md
    │           ├── LICENSE
    │           ├── OWNERS
    │           ├── README.md
    │           ├── RELEASE.md
    │           ├── SECURITY.md
    │           ├── SECURITY_CONTACTS
    │           ├── code-of-conduct.md
    │           ├── contextual.go
    │           ├── exit.go
    │           ├── imports.go
    │           ├── internal/
    │           │   ├── buffer/
    │           │   │   └── buffer.go
    │           │   ├── clock/
    │           │   │   ├── README.md
    │           │   │   └── clock.go
    │           │   ├── dbg/
    │           │   │   └── dbg.go
    │           │   ├── serialize/
    │           │   │   └── keyvalues.go
    │           │   └── severity/
    │           │       └── severity.go
    │           ├── k8s_references.go
    │           ├── klog.go
    │           ├── klog_file.go
    │           ├── klog_file_others.go
    │           ├── klog_file_windows.go
    │           └── klogr.go
    └── modules.txt
Download .txt
Showing preview only (9,063K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (106713 symbols across 978 files)

FILE: api/schemas/schemas.go
  type OutputROA (line 3) | type OutputROA struct
  type OutputASN (line 8) | type OutputASN struct
  type OutputIP (line 14) | type OutputIP struct
  type OutputRes (line 21) | type OutputRes struct
  type ResourcesJSON (line 51) | type ResourcesJSON struct

FILE: ca/xml.go
  constant XML_VERSION_RFC8181 (line 10) | XML_VERSION_RFC8181 = 4
  constant XML_VERSION_RFC8183 (line 11) | XML_VERSION_RFC8183 = 1
  type XMLMessage (line 14) | type XMLMessage struct
  type XMLMessageChildRequest (line 21) | type XMLMessageChildRequest struct
  type XMLMessageParentResponse (line 29) | type XMLMessageParentResponse struct
  type XMLMessagePublisherRequest (line 39) | type XMLMessagePublisherRequest struct
  type XMLMessageRepositoryResponse (line 47) | type XMLMessageRepositoryResponse struct
  function NewXMLList (line 58) | func NewXMLList() *XMLMessage {
  type Content (line 66) | type Content struct
  function DecodeInner (line 75) | func DecodeInner(inner []byte) ([]Content, error) {
  function DecodeXML (line 91) | func DecodeXML(message []byte) (*XMLMessage, error) {
  function DecodeXMLFull (line 99) | func DecodeXMLFull(message []byte) (*XMLMessage, []Content, error) {
  function DecodeXMLCRFull (line 111) | func DecodeXMLCRFull(message []byte) (*XMLMessageChildRequest, []Content...
  function DecodeXMLPRFull (line 123) | func DecodeXMLPRFull(message []byte) (*XMLMessageParentResponse, []Conte...

FILE: cmd/ctrpki/ctrpki.go
  function BatchCertificateTransparency (line 32) | func BatchCertificateTransparency(ctclient *client.LogClient, chain chan...
  function main (line 48) | func main() {

FILE: cmd/localrpki/localrpki.go
  type OutputROA (line 32) | type OutputROA struct
  type OutputROAs (line 39) | type OutputROAs struct
  function main (line 43) | func main() {

FILE: cmd/octorpki/ct.go
  function SingleSendCertificateTransparency (line 28) | func SingleSendCertificateTransparency(httpclient *http.Client, path str...
  function BatchCertificateTransparency (line 42) | func BatchCertificateTransparency(httpclient *http.Client, path string, ...
  method SendCertificateTransparency (line 53) | func (s *OctoRPKI) SendCertificateTransparency(pSpan opentracing.Span, c...

FILE: cmd/octorpki/filter.go
  function FilterInvalidPrefixLen (line 5) | func FilterInvalidPrefixLen(roalist []prefixfile.ROAJson) []prefixfile.R...
  function FilterDuplicates (line 26) | func FilterDuplicates(roalist []prefixfile.ROAJson) []prefixfile.ROAJson {

FILE: cmd/octorpki/filter_test.go
  function TestFilter (line 10) | func TestFilter(t *testing.T) {

FILE: cmd/octorpki/octorpki.go
  function DefaultBin (line 174) | func DefaultBin() string {
  type RRDPInfo (line 179) | type RRDPInfo struct
  function ReadKey (line 188) | func ReadKey(key []byte, isPem bool) (*ecdsa.PrivateKey, error) {
  type OctoRPKI (line 204) | type OctoRPKI struct
    method getRRDPFetch (line 246) | func (s *OctoRPKI) getRRDPFetch() map[string]string {
    method setRRDPFetch (line 258) | func (s *OctoRPKI) setRRDPFetch(key, value string) {
    method getRRDPDomain (line 265) | func (s *OctoRPKI) getRRDPDomain(path string) (string, bool) {
    method setRRDPDomain (line 273) | func (s *OctoRPKI) setRRDPDomain(path string, domain string) {
    method MainReduce (line 292) | func (s *OctoRPKI) MainReduce() bool {
    method WriteRsyncFileOnDisk (line 326) | func (s *OctoRPKI) WriteRsyncFileOnDisk(rsyncURL string, data []byte) ...
    method ReceiveRRDPFileCallback (line 352) | func (s *OctoRPKI) ReceiveRRDPFileCallback(main string, url string, pa...
    method LoadRRDPInfo (line 370) | func (s *OctoRPKI) LoadRRDPInfo(file string) error {
    method saveRRDPInfo (line 388) | func (s *OctoRPKI) saveRRDPInfo(file string) error {
    method getRRDPInfo (line 402) | func (s *OctoRPKI) getRRDPInfo() map[string]RRDPInfo {
    method mainRRDP (line 414) | func (s *OctoRPKI) mainRRDP(pSpan opentracing.Span) {
    method fetchRRDP (line 427) | func (s *OctoRPKI) fetchRRDP(path string, rsyncURL string, span opentr...
    method newRRDPSystem (line 473) | func (s *OctoRPKI) newRRDPSystem(path string, rsync string) *syncpki.R...
    method rrdpError (line 487) | func (s *OctoRPKI) rrdpError(rsyncURL string, path string, err error, ...
    method mainRsync (line 515) | func (s *OctoRPKI) mainRsync(pSpan opentracing.Span) {
    method fetchRsync (line 550) | func (s *OctoRPKI) fetchRsync(uri string, span opentracing.Span) {
    method rsyncError (line 579) | func (s *OctoRPKI) rsyncError(uri string, path string, err error, rSpa...
    method mainTAL (line 616) | func (s *OctoRPKI) mainTAL(pSpan opentracing.Span) {
    method fetchTAL (line 629) | func (s *OctoRPKI) fetchTAL(path string, tal *librpki.RPKITAL, span op...
    method _fetchTAL (line 654) | func (s *OctoRPKI) _fetchTAL(tal *librpki.RPKITAL, path string, tSpan ...
    method getHTTP (line 665) | func (s *OctoRPKI) getHTTP(uri string, tfSpan opentracing.Span, sHub *...
    method fetchTALurl (line 714) | func (s *OctoRPKI) fetchTALurl(tal *librpki.RPKITAL, uri string, path ...
    method generateROAList (line 771) | func (s *OctoRPKI) generateROAList(pkiManagers []*pki.SimpleManager, s...
    method signROAList (line 1024) | func (s *OctoRPKI) signROAList(roaList *prefixfile.ROAList, span opent...
    method mainValidation (line 1037) | func (s *OctoRPKI) mainValidation(pSpan opentracing.Span) [][]*pki.PKI...
    method ct (line 1144) | func (s *OctoRPKI) ct(pkiManagers []*pki.SimpleManager, i int) [][]*pk...
    method setInfoAuthorities (line 1182) | func (s *OctoRPKI) setInfoAuthorities(ia [][]SIA) {
    method setROAList (line 1189) | func (s *OctoRPKI) setROAList(roaList *prefixfile.ROAList) {
    method getROAList (line 1196) | func (s *OctoRPKI) getROAList() *prefixfile.ROAList {
    method ServeROAs (line 1203) | func (s *OctoRPKI) ServeROAs(w http.ResponseWriter, r *http.Request) {
    method ServeResources (line 1238) | func (s *OctoRPKI) ServeResources(w http.ResponseWriter, r *http.Reque...
    method ServeHealth (line 1253) | func (s *OctoRPKI) ServeHealth(w http.ResponseWriter, r *http.Request) {
    method ServeInfo (line 1287) | func (s *OctoRPKI) ServeInfo(w http.ResponseWriter, r *http.Request) {
    method Serve (line 1328) | func (s *OctoRPKI) Serve(addr string, roaPath string, metricsPath stri...
    method validationLoop (line 1536) | func (s *OctoRPKI) validationLoop() {
    method mustOutput (line 1622) | func (s *OctoRPKI) mustOutput() {
    method output (line 1629) | func (s *OctoRPKI) output() error {
    method doRRDP (line 1647) | func (s *OctoRPKI) doRRDP(span opentracing.Span) {
  type octoRPKIStats (line 280) | type octoRPKIStats struct
  function newOctoRPKIStats (line 286) | func newOctoRPKIStats() *octoRPKIStats {
  function ExtractRsyncDomain (line 318) | func ExtractRsyncDomain(rsyncURL string) (string, error) {
  function mustMkdirAll (line 345) | func mustMkdirAll(fPath string) {
  function mustExtractFoldersPathFromRsyncURL (line 532) | func mustExtractFoldersPathFromRsyncURL(rsyncURL string) string {
  function mustExtractFilePathFromRsyncURL (line 541) | func mustExtractFilePathFromRsyncURL(rsyncURL string) string {
  function filterDuplicates (line 597) | func filterDuplicates(roalist []prefixfile.ROAJson) []prefixfile.ROAJson {
  function setJaegerError (line 611) | func setJaegerError(l []interface{}, err error) []interface{} {
  function logCollector (line 756) | func logCollector(sm *pki.SimpleManager, tal *pki.PKIFile, tSpan opentra...
  type SIA (line 1262) | type SIA struct
  type ROAsTAL (line 1267) | type ROAsTAL struct
  type InfoAuthorities (line 1272) | type InfoAuthorities struct
  type InfoResult (line 1277) | type InfoResult struct
  function init (line 1361) | func init() {
  function runningAsRoot (line 1374) | func runningAsRoot() bool {
  function main (line 1378) | func main() {
  function NewOctoRPKI (line 1470) | func NewOctoRPKI(tals []*pki.PKIFile, talNames []string) *OctoRPKI {
  type rsyncFetchJobManager (line 1493) | type rsyncFetchJobManager struct
    method delete (line 1504) | func (r *rsyncFetchJobManager) delete(job string) {
    method get (line 1511) | func (r *rsyncFetchJobManager) get() map[string]string {
    method set (line 1523) | func (r *rsyncFetchJobManager) set(key, value string) {
  function newRsyncFetchJobManager (line 1498) | func newRsyncFetchJobManager() *rsyncFetchJobManager {
  function newROAList (line 1530) | func newROAList() *prefixfile.ROAList {

FILE: cmd/octorpki/rrdp_fetcher.go
  type rrdpFetchJob (line 9) | type rrdpFetchJob struct
  type rrdpFetcher (line 14) | type rrdpFetcher struct
    method worker (line 36) | func (r *rrdpFetcher) worker() {
    method done (line 44) | func (r *rrdpFetcher) done() {
    method wait (line 48) | func (r *rrdpFetcher) wait() {
    method fetch (line 52) | func (r *rrdpFetcher) fetch(path string, rsync string) {
  function newRRDPFetcher (line 21) | func newRRDPFetcher(octoRPKI *OctoRPKI, workers int, span opentracing.Sp...

FILE: cmd/octorpki/rsync_fetcher.go
  type rsyncFetcher (line 9) | type rsyncFetcher struct
    method worker (line 31) | func (r *rsyncFetcher) worker() {
    method done (line 39) | func (r *rsyncFetcher) done() {
    method wait (line 43) | func (r *rsyncFetcher) wait() {
    method fetch (line 47) | func (r *rsyncFetcher) fetch(rsync string) {
  function newRsyncFetcher (line 16) | func newRsyncFetcher(octoRPKI *OctoRPKI, workers int, span opentracing.S...

FILE: ov/ov.go
  constant STATE_UNKNOWN (line 14) | STATE_UNKNOWN = iota
  constant STATE_INVALID (line 15) | STATE_INVALID
  constant STATE_VALID (line 16) | STATE_VALID
  type AbstractROA (line 27) | type AbstractROA interface
  type AbstractRoute (line 33) | type AbstractRoute interface
  type OriginValidator (line 38) | type OriginValidator struct
    method Validate (line 83) | func (ov *OriginValidator) Validate(route AbstractRoute) ([]AbstractRO...
  function NewOV (line 45) | func NewOV(vrp []AbstractROA) *OriginValidator {
  type curValidation (line 61) | type curValidation struct
    method Filter (line 68) | func (cv *curValidation) Filter(payload int64) bool {

FILE: ov/ov_test.go
  type TestROA (line 9) | type TestROA struct
    method GetPrefix (line 15) | func (r *TestROA) GetPrefix() *net.IPNet {
    method GetASN (line 19) | func (r *TestROA) GetASN() uint32 {
    method GetMaxLen (line 23) | func (r *TestROA) GetMaxLen() int {
  type TestRoute (line 27) | type TestRoute struct
    method GetPrefix (line 32) | func (r *TestRoute) GetPrefix() *net.IPNet {
    method GetASN (line 36) | func (r *TestRoute) GetASN() uint32 {
  function MakeData (line 40) | func MakeData() ([]AbstractROA, AbstractRoute) {
  function TestValid (line 76) | func TestValid(t *testing.T) {
  function TestInvalid (line 85) | func TestInvalid(t *testing.T) {
  function TestUnknown (line 94) | func TestUnknown(t *testing.T) {

FILE: sync/api/cfrpki.pb.go
  constant _ (line 23) | _ = proto.ProtoPackageIsVersion3
  type RRDPInfoQuery (line 25) | type RRDPInfoQuery struct
    method Reset (line 32) | func (m *RRDPInfoQuery) Reset()         { *m = RRDPInfoQuery{} }
    method String (line 33) | func (m *RRDPInfoQuery) String() string { return proto.CompactTextStri...
    method ProtoMessage (line 34) | func (*RRDPInfoQuery) ProtoMessage()    {}
    method Descriptor (line 35) | func (*RRDPInfoQuery) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 39) | func (m *RRDPInfoQuery) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 42) | func (m *RRDPInfoQuery) XXX_Marshal(b []byte, deterministic bool) ([]b...
    method XXX_Merge (line 45) | func (m *RRDPInfoQuery) XXX_Merge(src proto.Message) {
    method XXX_Size (line 48) | func (m *RRDPInfoQuery) XXX_Size() int {
    method XXX_DiscardUnknown (line 51) | func (m *RRDPInfoQuery) XXX_DiscardUnknown() {
    method GetRRDP (line 57) | func (m *RRDPInfoQuery) GetRRDP() string {
  type RRDPInfo (line 64) | type RRDPInfo struct
    method Reset (line 73) | func (m *RRDPInfo) Reset()         { *m = RRDPInfo{} }
    method String (line 74) | func (m *RRDPInfo) String() string { return proto.CompactTextString(m) }
    method ProtoMessage (line 75) | func (*RRDPInfo) ProtoMessage()    {}
    method Descriptor (line 76) | func (*RRDPInfo) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 80) | func (m *RRDPInfo) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 83) | func (m *RRDPInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, ...
    method XXX_Merge (line 86) | func (m *RRDPInfo) XXX_Merge(src proto.Message) {
    method XXX_Size (line 89) | func (m *RRDPInfo) XXX_Size() int {
    method XXX_DiscardUnknown (line 92) | func (m *RRDPInfo) XXX_DiscardUnknown() {
    method GetRRDP (line 98) | func (m *RRDPInfo) GetRRDP() string {
    method GetSessionID (line 105) | func (m *RRDPInfo) GetSessionID() string {
    method GetSerial (line 112) | func (m *RRDPInfo) GetSerial() int64 {
  type ResourceQuery (line 119) | type ResourceQuery struct
    method Reset (line 127) | func (m *ResourceQuery) Reset()         { *m = ResourceQuery{} }
    method String (line 128) | func (m *ResourceQuery) String() string { return proto.CompactTextStri...
    method ProtoMessage (line 129) | func (*ResourceQuery) ProtoMessage()    {}
    method Descriptor (line 130) | func (*ResourceQuery) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 134) | func (m *ResourceQuery) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 137) | func (m *ResourceQuery) XXX_Marshal(b []byte, deterministic bool) ([]b...
    method XXX_Merge (line 140) | func (m *ResourceQuery) XXX_Merge(src proto.Message) {
    method XXX_Size (line 143) | func (m *ResourceQuery) XXX_Size() int {
    method XXX_DiscardUnknown (line 146) | func (m *ResourceQuery) XXX_DiscardUnknown() {
    method GetPath (line 152) | func (m *ResourceQuery) GetPath() string {
    method GetRRDP (line 159) | func (m *ResourceQuery) GetRRDP() string {
  type ResourceData (line 166) | type ResourceData struct
    method Reset (line 174) | func (m *ResourceData) Reset()         { *m = ResourceData{} }
    method String (line 175) | func (m *ResourceData) String() string { return proto.CompactTextStrin...
    method ProtoMessage (line 176) | func (*ResourceData) ProtoMessage()    {}
    method Descriptor (line 177) | func (*ResourceData) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 181) | func (m *ResourceData) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 184) | func (m *ResourceData) XXX_Marshal(b []byte, deterministic bool) ([]by...
    method XXX_Merge (line 187) | func (m *ResourceData) XXX_Merge(src proto.Message) {
    method XXX_Size (line 190) | func (m *ResourceData) XXX_Size() int {
    method XXX_DiscardUnknown (line 193) | func (m *ResourceData) XXX_DiscardUnknown() {
    method GetPath (line 199) | func (m *ResourceData) GetPath() string {
    method GetData (line 206) | func (m *ResourceData) GetData() []byte {
  type FetchQuery (line 213) | type FetchQuery struct
    method Reset (line 220) | func (m *FetchQuery) Reset()         { *m = FetchQuery{} }
    method String (line 221) | func (m *FetchQuery) String() string { return proto.CompactTextString(...
    method ProtoMessage (line 222) | func (*FetchQuery) ProtoMessage()    {}
    method Descriptor (line 223) | func (*FetchQuery) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 227) | func (m *FetchQuery) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 230) | func (m *FetchQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte...
    method XXX_Merge (line 233) | func (m *FetchQuery) XXX_Merge(src proto.Message) {
    method XXX_Size (line 236) | func (m *FetchQuery) XXX_Size() int {
    method XXX_DiscardUnknown (line 239) | func (m *FetchQuery) XXX_DiscardUnknown() {
    method GetPath (line 245) | func (m *FetchQuery) GetPath() string {
  type SIA (line 252) | type SIA struct
    method Reset (line 260) | func (m *SIA) Reset()         { *m = SIA{} }
    method String (line 261) | func (m *SIA) String() string { return proto.CompactTextString(m) }
    method ProtoMessage (line 262) | func (*SIA) ProtoMessage()    {}
    method Descriptor (line 263) | func (*SIA) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 267) | func (m *SIA) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 270) | func (m *SIA) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
    method XXX_Merge (line 273) | func (m *SIA) XXX_Merge(src proto.Message) {
    method XXX_Size (line 276) | func (m *SIA) XXX_Size() int {
    method XXX_DiscardUnknown (line 279) | func (m *SIA) XXX_DiscardUnknown() {
    method GetRSYNC (line 285) | func (m *SIA) GetRSYNC() string {
    method GetRRDP (line 292) | func (m *SIA) GetRRDP() string {
  type OperationResponse (line 299) | type OperationResponse struct
    method Reset (line 305) | func (m *OperationResponse) Reset()         { *m = OperationResponse{} }
    method String (line 306) | func (m *OperationResponse) String() string { return proto.CompactText...
    method ProtoMessage (line 307) | func (*OperationResponse) ProtoMessage()    {}
    method Descriptor (line 308) | func (*OperationResponse) Descriptor() ([]byte, []int) {
    method XXX_Unmarshal (line 312) | func (m *OperationResponse) XXX_Unmarshal(b []byte) error {
    method XXX_Marshal (line 315) | func (m *OperationResponse) XXX_Marshal(b []byte, deterministic bool) ...
    method XXX_Merge (line 318) | func (m *OperationResponse) XXX_Merge(src proto.Message) {
    method XXX_Size (line 321) | func (m *OperationResponse) XXX_Size() int {
    method XXX_DiscardUnknown (line 324) | func (m *OperationResponse) XXX_DiscardUnknown() {
  function init (line 330) | func init() {
  function init (line 340) | func init() { proto.RegisterFile("cfrpki.proto", fileDescriptor_0b755a2b...
  constant _ (line 375) | _ = grpc.SupportPackageIsVersion4
  type RPKIAPIClient (line 380) | type RPKIAPIClient interface
  type rPKIAPIClient (line 392) | type rPKIAPIClient struct
    method GetResource (line 400) | func (c *rPKIAPIClient) GetResource(ctx context.Context, in *ResourceQ...
    method GetRepository (line 409) | func (c *rPKIAPIClient) GetRepository(ctx context.Context, in *Resourc...
    method GetFetchRRDP (line 441) | func (c *rPKIAPIClient) GetFetchRRDP(ctx context.Context, in *FetchQue...
    method GetFetch (line 473) | func (c *rPKIAPIClient) GetFetch(ctx context.Context, in *FetchQuery, ...
    method PublishFile (line 505) | func (c *rPKIAPIClient) PublishFile(ctx context.Context, in *ResourceD...
    method DeleteFile (line 514) | func (c *rPKIAPIClient) DeleteFile(ctx context.Context, in *ResourceDa...
    method PostSIA (line 523) | func (c *rPKIAPIClient) PostSIA(ctx context.Context, in *SIA, opts ......
    method PostRRDP (line 532) | func (c *rPKIAPIClient) PostRRDP(ctx context.Context, in *RRDPInfo, op...
    method GetRRDPInfo (line 541) | func (c *rPKIAPIClient) GetRRDPInfo(ctx context.Context, in *RRDPInfoQ...
  function NewRPKIAPIClient (line 396) | func NewRPKIAPIClient(cc *grpc.ClientConn) RPKIAPIClient {
  type RPKIAPI_GetRepositoryClient (line 424) | type RPKIAPI_GetRepositoryClient interface
  type rPKIAPIGetRepositoryClient (line 429) | type rPKIAPIGetRepositoryClient struct
    method Recv (line 433) | func (x *rPKIAPIGetRepositoryClient) Recv() (*ResourceData, error) {
  type RPKIAPI_GetFetchRRDPClient (line 456) | type RPKIAPI_GetFetchRRDPClient interface
  type rPKIAPIGetFetchRRDPClient (line 461) | type rPKIAPIGetFetchRRDPClient struct
    method Recv (line 465) | func (x *rPKIAPIGetFetchRRDPClient) Recv() (*SIA, error) {
  type RPKIAPI_GetFetchClient (line 488) | type RPKIAPI_GetFetchClient interface
  type rPKIAPIGetFetchClient (line 493) | type rPKIAPIGetFetchClient struct
    method Recv (line 497) | func (x *rPKIAPIGetFetchClient) Recv() (*SIA, error) {
  type RPKIAPIServer (line 551) | type RPKIAPIServer interface
  function RegisterRPKIAPIServer (line 563) | func RegisterRPKIAPIServer(s *grpc.Server, srv RPKIAPIServer) {
  function _RPKIAPI_GetResource_Handler (line 567) | func _RPKIAPI_GetResource_Handler(srv interface{}, ctx context.Context, ...
  function _RPKIAPI_GetRepository_Handler (line 585) | func _RPKIAPI_GetRepository_Handler(srv interface{}, stream grpc.ServerS...
  type RPKIAPI_GetRepositoryServer (line 593) | type RPKIAPI_GetRepositoryServer interface
  type rPKIAPIGetRepositoryServer (line 598) | type rPKIAPIGetRepositoryServer struct
    method Send (line 602) | func (x *rPKIAPIGetRepositoryServer) Send(m *ResourceData) error {
  function _RPKIAPI_GetFetchRRDP_Handler (line 606) | func _RPKIAPI_GetFetchRRDP_Handler(srv interface{}, stream grpc.ServerSt...
  type RPKIAPI_GetFetchRRDPServer (line 614) | type RPKIAPI_GetFetchRRDPServer interface
  type rPKIAPIGetFetchRRDPServer (line 619) | type rPKIAPIGetFetchRRDPServer struct
    method Send (line 623) | func (x *rPKIAPIGetFetchRRDPServer) Send(m *SIA) error {
  function _RPKIAPI_GetFetch_Handler (line 627) | func _RPKIAPI_GetFetch_Handler(srv interface{}, stream grpc.ServerStream...
  type RPKIAPI_GetFetchServer (line 635) | type RPKIAPI_GetFetchServer interface
  type rPKIAPIGetFetchServer (line 640) | type rPKIAPIGetFetchServer struct
    method Send (line 644) | func (x *rPKIAPIGetFetchServer) Send(m *SIA) error {
  function _RPKIAPI_PublishFile_Handler (line 648) | func _RPKIAPI_PublishFile_Handler(srv interface{}, ctx context.Context, ...
  function _RPKIAPI_DeleteFile_Handler (line 666) | func _RPKIAPI_DeleteFile_Handler(srv interface{}, ctx context.Context, d...
  function _RPKIAPI_PostSIA_Handler (line 684) | func _RPKIAPI_PostSIA_Handler(srv interface{}, ctx context.Context, dec ...
  function _RPKIAPI_PostRRDP_Handler (line 702) | func _RPKIAPI_PostRRDP_Handler(srv interface{}, ctx context.Context, dec...
  function _RPKIAPI_GetRRDPInfo_Handler (line 720) | func _RPKIAPI_GetRRDPInfo_Handler(srv interface{}, ctx context.Context, ...

FILE: sync/api/fetch.go
  type APIFetch (line 13) | type APIFetch struct
    method GetFile (line 33) | func (s *APIFetch) GetFile(file *pki.PKIFile) (*pki.SeekFile, error) {
    method GetRepository (line 59) | func (s *APIFetch) GetRepository(file *pki.PKIFile, callback pki.Callb...
  function FetchFile (line 18) | func FetchFile(client RPKIAPIClient, ctx context.Context, path string) (...

FILE: sync/lib/errors.go
  constant ERROR_RRDP_UNKNOWN (line 11) | ERROR_RRDP_UNKNOWN = iota
  constant ERROR_RRDP_FETCH (line 12) | ERROR_RRDP_FETCH
  type stack (line 15) | type stack
  type Frame (line 16) | type Frame
  type RRDPError (line 25) | type RRDPError struct
    method StackTrace (line 57) | func (e *RRDPError) StackTrace() []Frame {
    method Error (line 61) | func (e *RRDPError) Error() string {
    method SetSentryScope (line 75) | func (e *RRDPError) SetSentryScope(scope *sentry.Scope) {
    method SetURL (line 88) | func (e *RRDPError) SetURL(rrdp, rsync string) {
  function callers (line 38) | func callers() *stack {
  function StackTrace (line 49) | func StackTrace(s *stack) []Frame {
  function NewRRDPErrorFetch (line 93) | func NewRRDPErrorFetch(request *http.Request, err error) *RRDPError {

FILE: sync/lib/fetch.go
  type LocalFetch (line 17) | type LocalFetch struct
    method SetRepositories (line 31) | func (s *LocalFetch) SetRepositories(repositories map[string]time.Time) {
    method GetFile (line 87) | func (s *LocalFetch) GetFile(file *pki.PKIFile) (*pki.SeekFile, error) {
    method GetFileConv (line 91) | func (s *LocalFetch) GetFileConv(file *pki.PKIFile, derEncoding bool) ...
    method GetRepository (line 119) | func (s *LocalFetch) GetRepository(file *pki.PKIFile, callback pki.Cal...
  function NewLocalFetch (line 23) | func NewLocalFetch(basepath string) *LocalFetch {
  function GetLocalPath (line 35) | func GetLocalPath(pathRep string, replace map[string]string) string {
  function ReplacePath (line 48) | func ReplacePath(file *pki.PKIFile, replace map[string]string) string {
  function FetchFile (line 54) | func FetchFile(path string, derEncoding bool) ([]byte, []byte, error) {
  function ParseMapDirectory (line 75) | func ParseMapDirectory(mapdir string) map[string]string {

FILE: sync/lib/fetch_test.go
  function TestGetLocalPath (line 9) | func TestGetLocalPath(t *testing.T) {

FILE: sync/lib/rrdp.go
  constant ResponseLimit (line 17) | ResponseLimit int64 = 1000000000
  type RRDPFetcher (line 19) | type RRDPFetcher interface
  type HTTPFetcher (line 23) | type HTTPFetcher struct
    method GetXML (line 38) | func (f *HTTPFetcher) GetXML(url string) (string, error) {
  function NewHTTPFetcher (line 28) | func NewHTTPFetcher(userAgent string) *HTTPFetcher {
  function ParseRoot (line 68) | func ParseRoot(data string) (Notification, error) {
  function ParseNode (line 96) | func ParseNode(data string) ([]Cert, []Cert, error) {
  type RRDPFile (line 153) | type RRDPFile
  type RRDPSystem (line 155) | type RRDPSystem struct
    method SetSentryScope (line 168) | func (s *RRDPSystem) SetSentryScope(scope *sentry.Scope) {
    method FetchRRDP (line 182) | func (s *RRDPSystem) FetchRRDP(cbArgs ...interface{}) error {
  function DecodeRRDPBase64 (line 175) | func DecodeRRDPBase64(value string) ([]byte, error) {

FILE: sync/lib/rrdp_struct.go
  type RootNode (line 7) | type RootNode struct
  type ElNode (line 14) | type ElNode struct
  type Cert (line 20) | type Cert struct
  type Notification (line 25) | type Notification struct
  type Delta (line 32) | type Delta struct
  type Snapshot (line 39) | type Snapshot struct

FILE: sync/lib/rsync.go
  constant RsyncProtoPrefix (line 17) | RsyncProtoPrefix = "rsync://"
  function ExtractFoldersPathFromRsyncURL (line 25) | func ExtractFoldersPathFromRsyncURL(url string) (string, error) {
  function ExtractFilePathFromRsyncURL (line 35) | func ExtractFilePathFromRsyncURL(url string) (string, error) {
  function isRsyncURL (line 43) | func isRsyncURL(url string) bool {
  function FilterMatch (line 48) | func FilterMatch(line string) (string, bool, error) {
  type FileStat (line 56) | type FileStat struct
  function RunRsync (line 62) | func RunRsync(ctx context.Context, uri string, bin string, dirPath strin...

FILE: sync/lib/rsync_test.go
  function TestExtractFoldersPathFromRsyncURL (line 9) | func TestExtractFoldersPathFromRsyncURL(t *testing.T) {

FILE: sync/lib/utils.go
  type Logger (line 9) | type Logger interface
  type SubMap (line 18) | type SubMap struct
  function ExtractRsyncDomainModule (line 23) | func ExtractRsyncDomainModule(rsync string) (string, string, error) {
  function AddInMap (line 35) | func AddInMap(item string, m map[string]SubMap) {
  function ReduceMap (line 55) | func ReduceMap(m map[string]SubMap) []string {

FILE: validator/lib/ber.go
  type asn1Object (line 15) | type asn1Object interface
  type asn1Structured (line 19) | type asn1Structured struct
    method encodeTo (line 24) | func (s asn1Structured) encodeTo(out *bytes.Buffer) error {
  type asn1Primitive (line 40) | type asn1Primitive struct
    method encodeTo (line 46) | func (p asn1Primitive) encodeTo(out *bytes.Buffer) error {
  function BER2DER (line 60) | func BER2DER(ber []byte) ([]byte, error) {
  function marshalLongLength (line 81) | func marshalLongLength(out *bytes.Buffer, i int) (err error) {
  function lengthLength (line 95) | func lengthLength(i int) (numBytes int) {
  function encodeLength (line 118) | func encodeLength(out *bytes.Buffer, length int) (err error) {
  function readObject (line 138) | func readObject(ber []byte, offset int) (asn1Object, int, error) {
  function isIndefiniteTermination (line 249) | func isIndefiniteTermination(ber []byte, offset int) (bool, error) {

FILE: validator/lib/cert.go
  type IPNet (line 43) | type IPNet struct
    method String (line 47) | func (ipn *IPNet) String() string {
    method IsIPInRange (line 51) | func (ipn *IPNet) IsIPInRange(ip net.IP) (bool, bool) {
    method GetAfi (line 55) | func (ipn *IPNet) GetAfi() uint8 {
    method GetRange (line 64) | func (ipn *IPNet) GetRange() (net.IP, net.IP, bool) {
    method ASN1 (line 72) | func (ipn *IPNet) ASN1() ([]byte, error) {
  type IPAddressRange (line 76) | type IPAddressRange struct
    method String (line 81) | func (ipr *IPAddressRange) String() string {
    method IsIPInRange (line 85) | func (ipr *IPAddressRange) IsIPInRange(ip net.IP) (bool, bool) {
    method GetAfi (line 94) | func (ipr *IPAddressRange) GetAfi() uint8 {
    method GetRange (line 103) | func (ipr *IPAddressRange) GetRange() (net.IP, net.IP, bool) {
    method ASN1 (line 137) | func (ipr *IPAddressRange) ASN1() ([]byte, error) {
  function IPToBitString (line 107) | func IPToBitString(ip net.IP) asn1.BitString {
  function IPNetToBitString (line 120) | func IPNetToBitString(ipnet net.IPNet) asn1.BitString {
  type IPAddressNull (line 143) | type IPAddressNull struct
    method String (line 147) | func (ipan *IPAddressNull) String() string {
    method IsIPInRange (line 151) | func (ipan *IPAddressNull) IsIPInRange(ip net.IP) (bool, bool) {
    method GetAfi (line 160) | func (ipan *IPAddressNull) GetAfi() uint8 {
    method GetRange (line 164) | func (ipan *IPAddressNull) GetRange() (net.IP, net.IP, bool) {
    method ASN1 (line 168) | func (ipan *IPAddressNull) ASN1() ([]byte, error) {
  type IPCertificateInformation (line 172) | type IPCertificateInformation interface
  type ASNCertificateInformation (line 181) | type ASNCertificateInformation interface
  type ASNRange (line 189) | type ASNRange struct
    method String (line 194) | func (ar *ASNRange) String() string {
    method IsASNInRange (line 198) | func (ar *ASNRange) IsASNInRange(asn int) (bool, bool) {
    method GetRange (line 202) | func (ar *ASNRange) GetRange() (int, int, bool) {
    method ASN1 (line 206) | func (ar *ASNRange) ASN1() ([]byte, error) {
  type ASN (line 210) | type ASN struct
    method String (line 214) | func (a *ASN) String() string {
    method IsASNInRange (line 218) | func (a *ASN) IsASNInRange(asn int) (bool, bool) {
    method GetRange (line 222) | func (a *ASN) GetRange() (int, int, bool) {
    method ASN1 (line 226) | func (a *ASN) ASN1() ([]byte, error) {
  type ASNull (line 230) | type ASNull struct
    method String (line 233) | func (an *ASNull) String() string {
    method IsASNInRange (line 237) | func (an *ASNull) IsASNInRange(asn int) (bool, bool) {
    method GetRange (line 241) | func (an *ASNull) GetRange() (int, int, bool) {
    method ASN1 (line 245) | func (an *ASNull) ASN1() ([]byte, error) {
  function DecodeIP (line 249) | func DecodeIP(addrfamily []byte, addr asn1.BitString) (*net.IPNet, error) {
  function DecodeIPMinMax (line 268) | func DecodeIPMinMax(addrfamily []byte, addr asn1.BitString, max bool) (n...
  function DecodeIPAddressBlock (line 293) | func DecodeIPAddressBlock(data []byte) ([]IPCertificateInformation, erro...
  function DecodeASIdentifier (line 360) | func DecodeASIdentifier(data asn1.RawValue) ([]ASNCertificateInformation...
  function DecodeASN (line 401) | func DecodeASN(data []byte) ([]ASNCertificateInformation, []ASNCertifica...
  type RPKICertificate (line 428) | type RPKICertificate struct
    method HasRRDP (line 437) | func (cert *RPKICertificate) HasRRDP() bool {
    method GetRRDPGeneralName (line 447) | func (cert *RPKICertificate) GetRRDPGeneralName() string {
    method GetRsyncGeneralName (line 457) | func (cert *RPKICertificate) GetRsyncGeneralName() string {
    method IsIPRangeInCertificate (line 467) | func (cert *RPKICertificate) IsIPRangeInCertificate(min net.IP, max ne...
    method IsASRangeInCertificate (line 482) | func (cert *RPKICertificate) IsASRangeInCertificate(min int, max int) ...
    method ValidateIPCertificate (line 519) | func (cert *RPKICertificate) ValidateIPCertificate(parent *RPKICertifi...
    method ValidateASNCertificate (line 545) | func (cert *RPKICertificate) ValidateASNCertificate(parent *RPKICertif...
    method Validate (line 549) | func (cert *RPKICertificate) Validate(parent *RPKICertificate) error {
    method ValidateTime (line 563) | func (cert *RPKICertificate) ValidateTime(comp time.Time) error {
    method String (line 576) | func (cert *RPKICertificate) String() string {
  function ValidateIPCertificateList (line 497) | func ValidateIPCertificateList(list []IPCertificateInformation, parent *...
  function ValidateASNCertificateList (line 523) | func ValidateASNCertificateList(list []ASNCertificateInformation, parent...
  type SIA (line 609) | type SIA struct
    method String (line 614) | func (sia *SIA) String() string {
  function DecodeSubjectInformationAccess (line 618) | func DecodeSubjectInformationAccess(data []byte) ([]SIA, error) {
  function DecodeKeyAuthority (line 628) | func DecodeKeyAuthority(data []byte) ([]byte, error) {
  function DecodeKeyIdentifier (line 640) | func DecodeKeyIdentifier(data []byte) ([]byte, error) {
  function GroupIPAddressBlock (line 651) | func GroupIPAddressBlock(ips []IPCertificateInformation) map[byte][]IPCe...
  function EncodeInfoAccess (line 666) | func EncodeInfoAccess(authority bool, path string) (*pkix.Extension, err...
  function EncodePolicyInformation (line 696) | func EncodePolicyInformation(cps string) (*pkix.Extension, error) {
  function EncodeIPAddressBlock (line 731) | func EncodeIPAddressBlock(ips []IPCertificateInformation) (*pkix.Extensi...
  function EncodeIPAddressBlockVersion (line 762) | func EncodeIPAddressBlockVersion(version byte, ips []IPCertificateInform...
  function EncodeASNSeq (line 802) | func EncodeASNSeq(asns []ASNCertificateInformation) ([]asn1.RawValue, er...
  function EncodeASN (line 832) | func EncodeASN(nums []ASNCertificateInformation, rdi []ASNCertificateInf...
  function EncodeSIA (line 864) | func EncodeSIA(sias []*SIA) (*pkix.Extension, error) {
  function DecodeCertificate (line 889) | func DecodeCertificate(data []byte) (*RPKICertificate, error) {

FILE: validator/lib/cert_test.go
  function MakeSIA (line 17) | func MakeSIA() []*SIA {
  function MakeIPs (line 34) | func MakeIPs(null bool) []IPCertificateInformation {
  function MakeASN (line 63) | func MakeASN(null bool) []ASNCertificateInformation {
  function TestEncodeSIA (line 87) | func TestEncodeSIA(t *testing.T) {
  function TestEncodeIPBlocks (line 96) | func TestEncodeIPBlocks(t *testing.T) {
  function TestEncodeASN (line 112) | func TestEncodeASN(t *testing.T) {
  function TestMakeCertificate (line 131) | func TestMakeCertificate(t *testing.T) {

FILE: validator/lib/cms.go
  type Attribute (line 27) | type Attribute struct
  type SignerInfo (line 32) | type SignerInfo struct
  type CmsSignedData (line 43) | type CmsSignedData struct
  type CMS (line 52) | type CMS struct
    method Sign (line 214) | func (cms *CMS) Sign(rand io.Reader, ski []byte, encap []byte, priv in...
    method AddCRLs (line 271) | func (cms *CMS) AddCRLs(crls []byte) error {
    method CheckSignaturesMatch (line 282) | func (cms *CMS) CheckSignaturesMatch() (bool, error) {
    method Validate (line 332) | func (cms *CMS) Validate(encap []byte, cert *x509.Certificate) error {
    method GetRPKICertificate (line 410) | func (cms *CMS) GetRPKICertificate() (*RPKICertificate, error) {
    method GetSigningTime (line 418) | func (cms *CMS) GetSigningTime() (time.Time, error) {
  function RSAPublicDecrypt (line 58) | func RSAPublicDecrypt(pubKey *rsa.PublicKey, data []byte) []byte {
  function PrivateEncrypt (line 78) | func PrivateEncrypt(priv *rsa.PrivateKey, data []byte) (enc []byte, err ...
  type SignatureInner (line 138) | type SignatureInner struct
  type SignatureDecoded (line 143) | type SignatureDecoded struct
  type SignedAttributesDigest (line 148) | type SignedAttributesDigest struct
  function DecryptSignatureRSA (line 152) | func DecryptSignatureRSA(signature []byte, pubKey *rsa.PublicKey) ([]byt...
  function EncryptSignatureRSA (line 162) | func EncryptSignatureRSA(rand io.Reader, signature []byte, privKey *rsa....
  function EContentToEncap (line 191) | func EContentToEncap(econtent []byte) ([]byte, error) {
  function EContentToEncapBF (line 195) | func EContentToEncapBF(econtent []byte, skipbf bool) ([]byte, error) {
  function BadFormatGroup (line 381) | func BadFormatGroup(data []byte) ([]byte, bool, error) {
  function EncodeCMS (line 430) | func EncodeCMS(certificate []byte, encapContent interface{}, signingTime...
  function DecodeCMS (line 565) | func DecodeCMS(data []byte) (*CMS, error) {

FILE: validator/lib/crl.go
  type CRLAuthKeyId (line 19) | type CRLAuthKeyId struct
  function CreateCRL (line 24) | func CreateCRL(c *x509.Certificate, rand io.Reader, priv interface{}, re...

FILE: validator/lib/manifest.go
  type File (line 15) | type File struct
    method GetHash (line 20) | func (f File) GetHash() []byte {
  type ManifestContent (line 24) | type ManifestContent struct
  type Manifest (line 32) | type Manifest struct
  type RPKIManifest (line 37) | type RPKIManifest struct
  function ManifestToEncap (line 45) | func ManifestToEncap(mft *Manifest) ([]byte, error) {
  function EncodeManifestContent (line 49) | func EncodeManifestContent(eContent ManifestContent) (*Manifest, error) {
  function DecodeManifest (line 67) | func DecodeManifest(data []byte) (*RPKIManifest, error) {
  method DecodeManifest (line 71) | func (cf *DecoderConfig) DecodeManifest(data []byte) (*RPKIManifest, err...

FILE: validator/lib/manifest_test.go
  function MakeMFTContent (line 16) | func MakeMFTContent() ManifestContent {
  function TestEncodeMFTContent (line 44) | func TestEncodeMFTContent(t *testing.T) {

FILE: validator/lib/roa.go
  type ROAIPAddresses (line 16) | type ROAIPAddresses struct
  type ROAAddressFamily (line 21) | type ROAAddressFamily struct
  type ROAContent (line 26) | type ROAContent struct
  type ROA (line 31) | type ROA struct
  type ROAEntry (line 36) | type ROAEntry struct
    method Validate (line 156) | func (entry *ROAEntry) Validate() error {
  type RPKIROA (line 41) | type RPKIROA struct
    method ValidateTime (line 175) | func (roa *RPKIROA) ValidateTime(comp time.Time) error {
    method ValidateEntries (line 183) | func (roa *RPKIROA) ValidateEntries() error {
    method ValidateIPRoaCertificate (line 214) | func (roa *RPKIROA) ValidateIPRoaCertificate(cert *RPKICertificate) ([...
  function ROAToEncap (line 56) | func ROAToEncap(roa *ROA) ([]byte, error) {
  function GroupEntries (line 60) | func GroupEntries(entries []*ROAEntry) map[byte][]*ROAEntry {
  function EncodeROAEntries (line 79) | func EncodeROAEntries(asn int, entries []*ROAEntry) (*ROA, error) {
  function GetRangeIP (line 136) | func GetRangeIP(ipnet *net.IPNet) (error, net.IP, net.IP) {
  function ValidateIPRoaCertificateList (line 193) | func ValidateIPRoaCertificateList(entries []*ROAEntry, cert *RPKICertifi...
  function ConvertROAEntries (line 218) | func ConvertROAEntries(roacontent ROAContent) ([]*ROAEntry, int, error) {
  type DecoderConfig (line 244) | type DecoderConfig struct
    method DecodeROA (line 258) | func (cf *DecoderConfig) DecodeROA(data []byte) (*RPKIROA, error) {
  function DecodeROA (line 254) | func DecodeROA(data []byte) (*RPKIROA, error) {

FILE: validator/lib/roa_test.go
  function MakeROAEntries (line 16) | func MakeROAEntries() []*ROAEntry {
  function TestEncodeROAEntries (line 26) | func TestEncodeROAEntries(t *testing.T) {
  function TestEncodeROA (line 35) | func TestEncodeROA(t *testing.T) {
  function TestValidateROAEntry (line 76) | func TestValidateROAEntry(t *testing.T) {

FILE: validator/lib/tal.go
  type RPKITAL (line 20) | type RPKITAL struct
    method HasRsync (line 27) | func (tal *RPKITAL) HasRsync() bool {
    method GetRsyncURI (line 38) | func (tal *RPKITAL) GetRsyncURI() string {
    method GetURI (line 54) | func (tal *RPKITAL) GetURI() string {
    method CheckCertificate (line 62) | func (tal *RPKITAL) CheckCertificate(cert *x509.Certificate) bool {
  function DeleteLineEnd (line 76) | func DeleteLineEnd(line string) string {
  function CreateTAL (line 86) | func CreateTAL(uri []string, pubkey interface{}) (*RPKITAL, error) {
  function EncodeTAL (line 104) | func EncodeTAL(tal *RPKITAL) ([]byte, error) {
  function HashPublicKey (line 108) | func HashPublicKey(key interface{}) ([]byte, error) {
  function HashRSAPublicKey (line 119) | func HashRSAPublicKey(key rsa.PublicKey) ([]byte, error) {
  function BundleRSAPublicKey (line 129) | func BundleRSAPublicKey(key rsa.PublicKey) (asn1.BitString, error) {
  function EncodeTALSize (line 138) | func EncodeTALSize(tal *RPKITAL, split int) ([]byte, error) {
  function DecodeTAL (line 189) | func DecodeTAL(data []byte) (*RPKITAL, error) {

FILE: validator/lib/tal_test.go
  function TestEncodeTAL (line 13) | func TestEncodeTAL(t *testing.T) {
  function TestDecodeTAL (line 23) | func TestDecodeTAL(t *testing.T) {

FILE: validator/lib/xml.go
  type XML (line 13) | type XML struct
  type XMLContent (line 18) | type XMLContent struct
  type RPKIXML (line 22) | type RPKIXML struct
  function EncodeXMLContent (line 30) | func EncodeXMLContent(content interface{}) (*XML, error) {
  function EncodeXMLData (line 40) | func EncodeXMLData(message []byte) (*XML, error) {
  function DecodeXML (line 53) | func DecodeXML(data []byte) (*RPKIXML, error) {

FILE: validator/lib/xml_test.go
  function TestEncodeXMLContent (line 17) | func TestEncodeXMLContent(t *testing.T) {

FILE: validator/pki/errors.go
  constant ERROR_CERTIFICATE_UNKNOWN (line 13) | ERROR_CERTIFICATE_UNKNOWN = iota
  constant ERROR_CERTIFICATE_EXPIRATION (line 14) | ERROR_CERTIFICATE_EXPIRATION
  constant ERROR_CERTIFICATE_PARENT (line 15) | ERROR_CERTIFICATE_PARENT
  constant ERROR_CERTIFICATE_REVOCATION (line 16) | ERROR_CERTIFICATE_REVOCATION
  constant ERROR_CERTIFICATE_RESOURCE (line 17) | ERROR_CERTIFICATE_RESOURCE
  constant ERROR_CERTIFICATE_CONFLICT (line 18) | ERROR_CERTIFICATE_CONFLICT
  constant ERROR_FILE (line 19) | ERROR_FILE
  constant ERROR_CERTIFICATE_MANIFEST (line 20) | ERROR_CERTIFICATE_MANIFEST
  constant ERROR_CERTIFICATE_HASH (line 21) | ERROR_CERTIFICATE_HASH
  constant ERROR_CERTIFICATE_CRL (line 22) | ERROR_CERTIFICATE_CRL
  type stack (line 25) | type stack
  type Frame (line 26) | type Frame
  type CertificateError (line 43) | type CertificateError struct
    method StackTrace (line 83) | func (e *CertificateError) StackTrace() []Frame {
    method AddFileErrorInfo (line 87) | func (e *CertificateError) AddFileErrorInfo(file *PKIFile, seek *SeekF...
    method Error (line 92) | func (e *CertificateError) Error() string {
    method SetSentryScope (line 127) | func (e *CertificateError) SetSentryScope(scope *sentry.Scope) {
  function callers (line 64) | func callers() *stack {
  function StackTrace (line 75) | func StackTrace(s *stack) []Frame {
  function NewCertificateErrorValidity (line 200) | func NewCertificateErrorValidity(cert *librpki.RPKICertificate, err erro...
  function NewCertificateErrorParent (line 210) | func NewCertificateErrorParent(cert, parent *librpki.RPKICertificate, er...
  function NewCertificateErrorRevocation (line 221) | func NewCertificateErrorRevocation(cert *librpki.RPKICertificate) *Certi...
  function NewCertificateErrorResource (line 230) | func NewCertificateErrorResource(cert *librpki.RPKICertificate, ips []li...
  function NewCertificateErrorConflict (line 241) | func NewCertificateErrorConflict(cert *librpki.RPKICertificate, conflict...
  function NewCertificateErrorManifestRevocation (line 251) | func NewCertificateErrorManifestRevocation(cert *librpki.RPKICertificate...
  function NewCertificateErrorCRLRevocation (line 262) | func NewCertificateErrorCRLRevocation(cert *librpki.RPKICertificate, err...
  type FileError (line 273) | type FileError
    method Error (line 275) | func (e *FileError) Error() string {
    method StackTrace (line 278) | func (e *FileError) StackTrace() []Frame {
    method SetSentryScope (line 281) | func (e *FileError) SetSentryScope(scope *sentry.Scope) {
    method AddFileErrorInfo (line 284) | func (e *FileError) AddFileErrorInfo(file *PKIFile, seek *SeekFile) {
  function NewFileError (line 288) | func NewFileError(err error) *FileError {
  type ResourceError (line 297) | type ResourceError struct
    method StackTrace (line 311) | func (e *ResourceError) StackTrace() []Frame {
    method Error (line 320) | func (e *ResourceError) Error() string {
    method SetSentryScope (line 324) | func (e *ResourceError) SetSentryScope(scope *sentry.Scope) {
    method AddFileErrorInfo (line 351) | func (e *ResourceError) AddFileErrorInfo(file *PKIFile, seek *SeekFile) {
  function NewResourceErrorWrap (line 356) | func NewResourceErrorWrap(wrapper interface{}, err error) *ResourceError {
  function NewResourceErrorHash (line 372) | func NewResourceErrorHash(hashFile, hashExpected []byte) *ResourceError {

FILE: validator/pki/pki.go
  constant TYPE_UNKNOWN (line 17) | TYPE_UNKNOWN = iota
  constant TYPE_CER (line 18) | TYPE_CER
  constant TYPE_MFT (line 19) | TYPE_MFT
  constant TYPE_ROA (line 20) | TYPE_ROA
  constant TYPE_CRL (line 21) | TYPE_CRL
  constant TYPE_ROACER (line 22) | TYPE_ROACER
  constant TYPE_MFTCER (line 23) | TYPE_MFTCER
  constant TYPE_CAREPO (line 24) | TYPE_CAREPO
  constant TYPE_TAL (line 25) | TYPE_TAL
  type Resource (line 45) | type Resource struct
    method GetIdentifier (line 55) | func (res *Resource) GetIdentifier() (bool, []byte) {
  type SeekFile (line 67) | type SeekFile struct
  type FileSeeker (line 74) | type FileSeeker interface
  type Log (line 79) | type Log interface
  type SimpleManager (line 86) | type SimpleManager struct
    method Close (line 115) | func (sm *SimpleManager) Close() {
    method reportError (line 119) | func (sm *SimpleManager) reportError(err error) {
    method reportErrorFile (line 124) | func (sm *SimpleManager) reportErrorFile(err error, file *PKIFile, see...
    method PutFiles (line 131) | func (sm *SimpleManager) PutFiles(fileList []*PKIFile) {
    method HasMore (line 147) | func (sm *SimpleManager) HasMore() bool {
    method GetNextExplore (line 151) | func (sm *SimpleManager) GetNextExplore() (*PKIFile, bool, error) {
    method GetNextFile (line 160) | func (sm *SimpleManager) GetNextFile(curExplore *PKIFile) (*SeekFile, ...
    method GetNextRepository (line 178) | func (sm *SimpleManager) GetNextRepository(curExplore *PKIFile, callba...
    method AddInitial (line 768) | func (sm *SimpleManager) AddInitial(fileList []*PKIFile) {
    method InvalidateManifestParent (line 773) | func (sm *SimpleManager) InvalidateManifestParent(file *PKIFile, mftEr...
    method InvalidateCRLParent (line 794) | func (sm *SimpleManager) InvalidateCRLParent(file *PKIFile, crlError e...
    method ExploreAdd (line 815) | func (sm *SimpleManager) ExploreAdd(file *PKIFile, data *SeekFile, add...
    method Explore (line 850) | func (sm *SimpleManager) Explore(notMFT bool, addInvalidChilds bool) i...
  function NewSimpleManager (line 103) | func NewSimpleManager() *SimpleManager {
  type CallbackExplore (line 176) | type CallbackExplore
  type Validator (line 190) | type Validator struct
    method AddResource (line 277) | func (v *Validator) AddResource(pkifile *PKIFile, data []byte) (bool, ...
    method InvalidateObject (line 373) | func (v *Validator) InvalidateObject(keyid []byte) {
    method AddTAL (line 407) | func (v *Validator) AddTAL(tal *librpki.RPKITAL) ([]*PKIFile, *Resourc...
    method AddCert (line 424) | func (v *Validator) AddCert(cert *librpki.RPKICertificate, trust bool)...
    method ValidateCertificate (line 466) | func (v *Validator) ValidateCertificate(cert *librpki.RPKICertificate,...
    method AddROA (line 550) | func (v *Validator) AddROA(pkifile *PKIFile, roa *librpki.RPKIROA) (bo...
    method ValidateROA (line 590) | func (v *Validator) ValidateROA(roa *librpki.RPKIROA) error {
    method AddManifest (line 598) | func (v *Validator) AddManifest(pkifile *PKIFile, mft *librpki.RPKIMan...
    method AddCRL (line 636) | func (v *Validator) AddCRL(crl *pkix.CertificateList) (bool, *Resource...
    method GetRepositories (line 691) | func (v *Validator) GetRepositories() {
    method GetValidROAs (line 695) | func (v *Validator) GetValidROAs() {
  function NewValidator (line 220) | func NewValidator() *Validator {
  type PKIFile (line 247) | type PKIFile struct
    method ComputePath (line 257) | func (f *PKIFile) ComputePath() string {
  function ObjectToResource (line 269) | func ObjectToResource(data interface{}) *Resource {
  function DetermineType (line 699) | func DetermineType(path string) int {
  function ExtractPathCert (line 714) | func ExtractPathCert(cert *librpki.RPKICertificate) []*PKIFile {
  function ExtractPathManifest (line 748) | func ExtractPathManifest(mft *librpki.RPKIManifest) ([]*PKIFile, error) {

FILE: validator/pki/pki_test.go
  function CreateKeys (line 24) | func CreateKeys() []*rsa.PrivateKey {
  type TestingFileSeeker (line 41) | type TestingFileSeeker struct
    method GetFile (line 52) | func (fs *TestingFileSeeker) GetFile(file *PKIFile) (*SeekFile, error) {
    method GetRepository (line 68) | func (fs *TestingFileSeeker) GetRepository(*PKIFile, CallbackExplore) ...
    method AddFile (line 74) | func (fs *TestingFileSeeker) AddFile(path string, payload []byte) {
  function NewFileSeeker (line 46) | func NewFileSeeker() *TestingFileSeeker {
  function Validate (line 78) | func Validate(talPath string, fs FileSeeker) int {
  function TestPKI (line 107) | func TestPKI(t *testing.T) {

FILE: vendor/github.com/beorn7/perks/quantile/stream.go
  type Sample (line 24) | type Sample struct
  type Samples (line 31) | type Samples
    method Len (line 33) | func (a Samples) Len() int           { return len(a) }
    method Less (line 34) | func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value }
    method Swap (line 35) | func (a Samples) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
  type invariant (line 37) | type invariant
  function NewLowBiased (line 49) | func NewLowBiased(epsilon float64) *Stream {
  function NewHighBiased (line 66) | func NewHighBiased(epsilon float64) *Stream {
  function NewTargeted (line 80) | func NewTargeted(targetMap map[float64]float64) *Stream {
  type target (line 104) | type target struct
  function targetMapToSlice (line 109) | func targetMapToSlice(targetMap map[float64]float64) []target {
  type Stream (line 125) | type Stream struct
    method Insert (line 137) | func (s *Stream) Insert(v float64) {
    method insert (line 141) | func (s *Stream) insert(sample Sample) {
    method Query (line 152) | func (s *Stream) Query(q float64) float64 {
    method Merge (line 176) | func (s *Stream) Merge(samples Samples) {
    method Reset (line 182) | func (s *Stream) Reset() {
    method Samples (line 188) | func (s *Stream) Samples() Samples {
    method Count (line 198) | func (s *Stream) Count() int {
    method flush (line 202) | func (s *Stream) flush() {
    method maybeSort (line 208) | func (s *Stream) maybeSort() {
    method flushed (line 215) | func (s *Stream) flushed() bool {
  function newStream (line 131) | func newStream(ƒ invariant) *Stream {
  type stream (line 219) | type stream struct
    method reset (line 225) | func (s *stream) reset() {
    method insert (line 230) | func (s *stream) insert(v float64) {
    method merge (line 234) | func (s *stream) merge(samples Samples) {
    method count (line 268) | func (s *stream) count() int {
    method query (line 272) | func (s *stream) query(q float64) float64 {
    method compress (line 287) | func (s *stream) compress() {
    method samples (line 312) | func (s *stream) samples() Samples {

FILE: vendor/github.com/cespare/xxhash/v2/xxhash.go
  constant prime1 (line 12) | prime1 uint64 = 11400714785074694791
  constant prime2 (line 13) | prime2 uint64 = 14029467366897019727
  constant prime3 (line 14) | prime3 uint64 = 1609587929392839161
  constant prime4 (line 15) | prime4 uint64 = 9650029242287828579
  constant prime5 (line 16) | prime5 uint64 = 2870177450012600261
  type Digest (line 26) | type Digest struct
    method Reset (line 44) | func (d *Digest) Reset() {
    method Size (line 54) | func (d *Digest) Size() int { return 8 }
    method BlockSize (line 57) | func (d *Digest) BlockSize() int { return 32 }
    method Write (line 60) | func (d *Digest) Write(b []byte) (n int, err error) {
    method Sum (line 98) | func (d *Digest) Sum(b []byte) []byte {
    method Sum64 (line 114) | func (d *Digest) Sum64() uint64 {
    method MarshalBinary (line 161) | func (d *Digest) MarshalBinary() ([]byte, error) {
    method UnmarshalBinary (line 175) | func (d *Digest) UnmarshalBinary(b []byte) error {
  function New (line 37) | func New() *Digest {
  constant magic (line 156) | magic         = "xxh\x06"
  constant marshaledSize (line 157) | marshaledSize = len(magic) + 8*5 + 32
  function appendUint64 (line 193) | func appendUint64(b []byte, x uint64) []byte {
  function consumeUint64 (line 199) | func consumeUint64(b []byte) ([]byte, uint64) {
  function u64 (line 204) | func u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) }
  function u32 (line 205) | func u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }
  function round (line 207) | func round(acc, input uint64) uint64 {
  function mergeRound (line 214) | func mergeRound(acc, val uint64) uint64 {
  function rol1 (line 221) | func rol1(x uint64) uint64  { return bits.RotateLeft64(x, 1) }
  function rol7 (line 222) | func rol7(x uint64) uint64  { return bits.RotateLeft64(x, 7) }
  function rol11 (line 223) | func rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) }
  function rol12 (line 224) | func rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) }
  function rol18 (line 225) | func rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) }
  function rol23 (line 226) | func rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) }
  function rol27 (line 227) | func rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) }
  function rol31 (line 228) | func rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) }

FILE: vendor/github.com/cespare/xxhash/v2/xxhash_asm.go
  function Sum64 (line 12) | func Sum64(b []byte) uint64
  function writeBlocks (line 15) | func writeBlocks(d *Digest, b []byte) int

FILE: vendor/github.com/cespare/xxhash/v2/xxhash_other.go
  function Sum64 (line 7) | func Sum64(b []byte) uint64 {
  function writeBlocks (line 64) | func writeBlocks(d *Digest, b []byte) int {

FILE: vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
  function Sum64String (line 9) | func Sum64String(s string) uint64 {
  method WriteString (line 14) | func (d *Digest) WriteString(s string) (n int, err error) {

FILE: vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
  function Sum64String (line 38) | func Sum64String(s string) uint64 {
  method WriteString (line 45) | func (d *Digest) WriteString(s string) (n int, err error) {
  type sliceHeader (line 55) | type sliceHeader struct

FILE: vendor/github.com/cloudflare/gortr/prefixfile/prefixfile.go
  type ecdsaSignature (line 31) | type ecdsaSignature struct
  type ROAJson (line 80) | type ROAJson struct
    method GetASN2 (line 101) | func (roa *ROAJson) GetASN2() (uint32, error) {
    method GetASN (line 120) | func (roa *ROAJson) GetASN() uint32 {
    method SetASN (line 125) | func (roa *ROAJson) SetASN(asn uint32) {
    method GetPrefix2 (line 129) | func (roa *ROAJson) GetPrefix2() (*net.IPNet, error) {
    method GetPrefix (line 137) | func (roa *ROAJson) GetPrefix() *net.IPNet {
    method GetMaxLen (line 142) | func (roa *ROAJson) GetMaxLen() int {
    method String (line 146) | func (roa *ROAJson) String() string {
  type MetaData (line 87) | type MetaData struct
  type ROAList (line 96) | type ROAList struct
    method GenerateDigest (line 18) | func (roalist *ROAList) GenerateDigest() ([]byte, []byte, error) {
    method CheckFile (line 35) | func (roalist *ROAList) CheckFile(key *ecdsa.PublicKey) (bool, bool, e...
    method Sign (line 63) | func (roalist *ROAList) Sign(privkey *ecdsa.PrivateKey) (string, strin...
  function GetIPBroadcast (line 150) | func GetIPBroadcast(ipnet net.IPNet) net.IP {

FILE: vendor/github.com/cloudflare/gortr/prefixfile/slurm.go
  type SlurmPrefixFilter (line 10) | type SlurmPrefixFilter struct
    method GetASN (line 16) | func (pf *SlurmPrefixFilter) GetASN() (uint32, bool) {
    method GetPrefix (line 32) | func (pf *SlurmPrefixFilter) GetPrefix() *net.IPNet {
  type SlurmValidationOutputFilters (line 37) | type SlurmValidationOutputFilters struct
    method FilterOnROAs (line 82) | func (s *SlurmValidationOutputFilters) FilterOnROAs(roas []ROAJson) ([...
  type SlurmPrefixAssertion (line 41) | type SlurmPrefixAssertion struct
    method GetASN (line 48) | func (pa *SlurmPrefixAssertion) GetASN() uint32 {
    method GetPrefix (line 52) | func (pa *SlurmPrefixAssertion) GetPrefix() *net.IPNet {
    method GetMaxLen (line 57) | func (pa *SlurmPrefixAssertion) GetMaxLen() int {
  type SlurmLocallyAddedAssertions (line 61) | type SlurmLocallyAddedAssertions struct
    method AssertROAs (line 131) | func (s *SlurmLocallyAddedAssertions) AssertROAs() []ROAJson {
  type SlurmConfig (line 65) | type SlurmConfig struct
    method FilterOnROAs (line 127) | func (s *SlurmConfig) FilterOnROAs(roas []ROAJson) ([]ROAJson, []ROAJs...
    method AssertROAs (line 156) | func (s *SlurmConfig) AssertROAs() []ROAJson {
    method FilterAssert (line 160) | func (s *SlurmConfig) FilterAssert(roas []ROAJson) []ROAJson {
  function DecodeJSONSlurm (line 71) | func DecodeJSONSlurm(buf io.Reader) (*SlurmConfig, error) {

FILE: vendor/github.com/davecgh/go-spew/spew/bypass.go
  constant UnsafeDisabled (line 33) | UnsafeDisabled = false
  constant ptrSize (line 36) | ptrSize = unsafe.Sizeof((*byte)(nil))
  type flag (line 39) | type flag
  constant flagKindMask (line 54) | flagKindMask = flag(0x1f)
  function flagField (line 80) | func flagField(v *reflect.Value) *flag {
  function unsafeReflectValue (line 93) | func unsafeReflectValue(v reflect.Value) reflect.Value {
  function init (line 105) | func init() {

FILE: vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
  constant UnsafeDisabled (line 28) | UnsafeDisabled = true
  function unsafeReflectValue (line 36) | func unsafeReflectValue(v reflect.Value) reflect.Value {

FILE: vendor/github.com/davecgh/go-spew/spew/common.go
  function catchPanic (line 72) | func catchPanic(w io.Writer, v reflect.Value) {
  function handleMethods (line 85) | func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handl...
  function printBool (line 144) | func printBool(w io.Writer, val bool) {
  function printInt (line 153) | func printInt(w io.Writer, val int64, base int) {
  function printUint (line 158) | func printUint(w io.Writer, val uint64, base int) {
  function printFloat (line 164) | func printFloat(w io.Writer, val float64, precision int) {
  function printComplex (line 170) | func printComplex(w io.Writer, c complex128, floatPrecision int) {
  function printHexPtr (line 185) | func printHexPtr(w io.Writer, p uintptr) {
  type valuesSorter (line 219) | type valuesSorter struct
    method Len (line 279) | func (s *valuesSorter) Len() int {
    method Swap (line 285) | func (s *valuesSorter) Swap(i, j int) {
    method Less (line 326) | func (s *valuesSorter) Less(i, j int) bool {
  function newValuesSorter (line 228) | func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Inter...
  function canSortSimply (line 256) | func canSortSimply(kind reflect.Kind) bool {
  function valueSortLess (line 295) | func valueSortLess(a, b reflect.Value) bool {
  function sortValues (line 336) | func sortValues(values []reflect.Value, cs *ConfigState) {

FILE: vendor/github.com/davecgh/go-spew/spew/config.go
  type ConfigState (line 37) | type ConfigState struct
    method Errorf (line 115) | func (c *ConfigState) Errorf(format string, a ...interface{}) (err err...
    method Fprint (line 127) | func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, er...
    method Fprintf (line 139) | func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interfa...
    method Fprintln (line 150) | func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, ...
    method Print (line 162) | func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
    method Printf (line 174) | func (c *ConfigState) Printf(format string, a ...interface{}) (n int, ...
    method Println (line 186) | func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
    method Sprint (line 197) | func (c *ConfigState) Sprint(a ...interface{}) string {
    method Sprintf (line 208) | func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
    method Sprintln (line 219) | func (c *ConfigState) Sprintln(a ...interface{}) string {
    method NewFormatter (line 240) | func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
    method Fdump (line 246) | func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
    method Dump (line 273) | func (c *ConfigState) Dump(a ...interface{}) {
    method Sdump (line 279) | func (c *ConfigState) Sdump(a ...interface{}) string {
    method convertArgs (line 288) | func (c *ConfigState) convertArgs(args []interface{}) (formatters []in...
  function NewDefaultConfig (line 304) | func NewDefaultConfig() *ConfigState {

FILE: vendor/github.com/davecgh/go-spew/spew/dump.go
  type dumpState (line 51) | type dumpState struct
    method indent (line 62) | func (d *dumpState) indent() {
    method unpackValue (line 73) | func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
    method dumpPtr (line 81) | func (d *dumpState) dumpPtr(v reflect.Value) {
    method dumpSlice (line 161) | func (d *dumpState) dumpSlice(v reflect.Value) {
    method dump (line 251) | func (d *dumpState) dump(v reflect.Value) {
  function fdump (line 453) | func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
  function Fdump (line 472) | func Fdump(w io.Writer, a ...interface{}) {
  function Sdump (line 478) | func Sdump(a ...interface{}) string {
  function Dump (line 507) | func Dump(a ...interface{}) {

FILE: vendor/github.com/davecgh/go-spew/spew/format.go
  constant supportedFlags (line 28) | supportedFlags = "0-+# "
  type formatState (line 34) | type formatState struct
    method buildDefaultFormat (line 47) | func (f *formatState) buildDefaultFormat() (format string) {
    method constructOrigFormat (line 65) | func (f *formatState) constructOrigFormat(verb rune) (format string) {
    method unpackValue (line 94) | func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
    method formatPtr (line 105) | func (f *formatState) formatPtr(v reflect.Value) {
    method format (line 201) | func (f *formatState) format(v reflect.Value) {
    method Format (line 371) | func (f *formatState) Format(fs fmt.State, verb rune) {
  function newFormatter (line 394) | func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
  function NewFormatter (line 417) | func NewFormatter(v interface{}) fmt.Formatter {

FILE: vendor/github.com/davecgh/go-spew/spew/spew.go
  function Errorf (line 32) | func Errorf(format string, a ...interface{}) (err error) {
  function Fprint (line 44) | func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
  function Fprintf (line 56) | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err e...
  function Fprintln (line 67) | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
  function Print (line 79) | func Print(a ...interface{}) (n int, err error) {
  function Printf (line 91) | func Printf(format string, a ...interface{}) (n int, err error) {
  function Println (line 103) | func Println(a ...interface{}) (n int, err error) {
  function Sprint (line 114) | func Sprint(a ...interface{}) string {
  function Sprintf (line 125) | func Sprintf(format string, a ...interface{}) string {
  function Sprintln (line 136) | func Sprintln(a ...interface{}) string {
  function convertArgs (line 142) | func convertArgs(args []interface{}) (formatters []interface{}) {

FILE: vendor/github.com/getsentry/sentry-go/client.go
  constant maxErrorDepth (line 28) | maxErrorDepth = 10
  constant defaultMaxSpans (line 33) | defaultMaxSpans = 1000
  type lockedRand (line 46) | type lockedRand struct
    method Float64 (line 52) | func (r *lockedRand) Float64() float64 {
  type usageError (line 74) | type usageError struct
  type EventProcessor (line 84) | type EventProcessor
  type EventModifier (line 90) | type EventModifier interface
  function AddGlobalEventProcessor (line 102) | func AddGlobalEventProcessor(processor EventProcessor) {
  type Integration (line 107) | type Integration interface
  type ClientOptions (line 113) | type ClientOptions struct
  type Client (line 223) | type Client struct
    method setupTransport (line 312) | func (client *Client) setupTransport() {
    method setupIntegrations (line 336) | func (client *Client) setupIntegrations() {
    method AddEventProcessor (line 370) | func (client *Client) AddEventProcessor(processor EventProcessor) {
    method Options (line 375) | func (client Client) Options() ClientOptions {
    method CaptureMessage (line 380) | func (client *Client) CaptureMessage(message string, hint *EventHint, ...
    method CaptureException (line 386) | func (client *Client) CaptureException(exception error, hint *EventHin...
    method CaptureEvent (line 396) | func (client *Client) CaptureEvent(event *Event, hint *EventHint, scop...
    method Recover (line 402) | func (client *Client) Recover(err interface{}, hint *EventHint, scope ...
    method RecoverWithContext (line 417) | func (client *Client) RecoverWithContext(
    method Flush (line 462) | func (client *Client) Flush(timeout time.Duration) bool {
    method eventFromMessage (line 466) | func (client *Client) eventFromMessage(message string, level Level) *E...
    method eventFromException (line 486) | func (client *Client) eventFromException(exception error, level Level)...
    method processEvent (line 533) | func (client *Client) processEvent(event *Event, hint *EventHint, scop...
    method prepareEvent (line 598) | func (client *Client) prepareEvent(event *Event, hint *EventHint, scop...
    method listIntegrations (line 670) | func (client Client) listIntegrations() []string {
    method integrationAlreadyInstalled (line 678) | func (client Client) integrationAlreadyInstalled(name string) bool {
  function NewClient (line 240) | func NewClient(options ClientOptions) (*Client, error) {
  function reverse (line 526) | func reverse(a []Exception) {
  function sample (line 689) | func sample(probability float64) bool {

FILE: vendor/github.com/getsentry/sentry-go/dsn.go
  type scheme (line 12) | type scheme
    method defaultPort (line 19) | func (scheme scheme) defaultPort() int {
  constant schemeHTTP (line 15) | schemeHTTP  scheme = "http"
  constant schemeHTTPS (line 16) | schemeHTTPS scheme = "https"
  type DsnParseError (line 32) | type DsnParseError struct
    method Error (line 36) | func (e DsnParseError) Error() string {
  type Dsn (line 41) | type Dsn struct
    method String (line 131) | func (dsn Dsn) String() string {
    method GetScheme (line 149) | func (dsn Dsn) GetScheme() string {
    method GetPublicKey (line 154) | func (dsn Dsn) GetPublicKey() string {
    method GetSecretKey (line 159) | func (dsn Dsn) GetSecretKey() string {
    method GetHost (line 164) | func (dsn Dsn) GetHost() string {
    method GetPort (line 169) | func (dsn Dsn) GetPort() int {
    method GetPath (line 174) | func (dsn Dsn) GetPath() string {
    method GetProjectID (line 179) | func (dsn Dsn) GetProjectID() string {
    method StoreAPIURL (line 185) | func (dsn Dsn) StoreAPIURL() *url.URL {
    method EnvelopeAPIURL (line 191) | func (dsn Dsn) EnvelopeAPIURL() *url.URL {
    method getAPIURL (line 195) | func (dsn Dsn) getAPIURL(s string) *url.URL {
    method RequestHeaders (line 210) | func (dsn Dsn) RequestHeaders() map[string]string {
    method MarshalJSON (line 225) | func (dsn Dsn) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 230) | func (dsn *Dsn) UnmarshalJSON(data []byte) error {
  function NewDsn (line 54) | func NewDsn(rawURL string) (*Dsn, error) {

FILE: vendor/github.com/getsentry/sentry-go/dynamic_sampling_context.go
  constant sentryPrefix (line 11) | sentryPrefix = "sentry-"
  type DynamicSamplingContext (line 15) | type DynamicSamplingContext struct
    method HasEntries (line 93) | func (d DynamicSamplingContext) HasEntries() bool {
    method IsFrozen (line 97) | func (d DynamicSamplingContext) IsFrozen() bool {
    method String (line 101) | func (d DynamicSamplingContext) String() string {
  function DynamicSamplingContextFromHeader (line 20) | func DynamicSamplingContextFromHeader(header []byte) (DynamicSamplingCon...
  function DynamicSamplingContextFromTransaction (line 41) | func DynamicSamplingContextFromTransaction(span *Span) DynamicSamplingCo...

FILE: vendor/github.com/getsentry/sentry-go/hub.go
  type contextKey (line 9) | type contextKey
  constant HubContextKey (line 15) | HubContextKey = contextKey(1)
  constant RequestContextKey (line 17) | RequestContextKey = contextKey(2)
  constant defaultMaxBreadcrumbs (line 22) | defaultMaxBreadcrumbs = 30
  constant maxBreadcrumbs (line 26) | maxBreadcrumbs = 100
  type Hub (line 41) | type Hub struct
    method LastEventID (line 99) | func (hub *Hub) LastEventID() EventID {
    method stackTop (line 108) | func (hub *Hub) stackTop() *layer {
    method Clone (line 119) | func (hub *Hub) Clone() *Hub {
    method Scope (line 129) | func (hub *Hub) Scope() *Scope {
    method Client (line 135) | func (hub *Hub) Client() *Client {
    method PushScope (line 141) | func (hub *Hub) PushScope() *Scope {
    method PopScope (line 169) | func (hub *Hub) PopScope() {
    method BindClient (line 183) | func (hub *Hub) BindClient(client *Client) {
    method WithScope (line 197) | func (hub *Hub) WithScope(f func(scope *Scope)) {
    method ConfigureScope (line 211) | func (hub *Hub) ConfigureScope(f func(scope *Scope)) {
    method CaptureEvent (line 219) | func (hub *Hub) CaptureEvent(event *Event) *EventID {
    method CaptureMessage (line 237) | func (hub *Hub) CaptureMessage(message string) *EventID {
    method CaptureException (line 255) | func (hub *Hub) CaptureException(exception error) *EventID {
    method AddBreadcrumb (line 274) | func (hub *Hub) AddBreadcrumb(breadcrumb *Breadcrumb, hint *Breadcrumb...
    method Recover (line 311) | func (hub *Hub) Recover(err interface{}) *EventID {
    method RecoverWithContext (line 325) | func (hub *Hub) RecoverWithContext(ctx context.Context, err interface{...
    method Flush (line 347) | func (hub *Hub) Flush(timeout time.Duration) bool {
  type layer (line 47) | type layer struct
    method Client (line 56) | func (l *layer) Client() *Client {
    method SetClient (line 63) | func (l *layer) SetClient(c *Client) {
  type stack (line 69) | type stack
  function NewHub (line 72) | func NewHub(client *Client, scope *Scope) *Hub {
  function CurrentHub (line 83) | func CurrentHub() *Hub {
  function HasHubOnContext (line 358) | func HasHubOnContext(ctx context.Context) bool {
  function GetHubFromContext (line 365) | func GetHubFromContext(ctx context.Context) *Hub {
  function hubFromContext (line 374) | func hubFromContext(ctx context.Context) *Hub {
  function SetHubOnContext (line 382) | func SetHubOnContext(ctx context.Context, hub *Hub) context.Context {

FILE: vendor/github.com/getsentry/sentry-go/integrations.go
  type modulesIntegration (line 16) | type modulesIntegration struct
    method Name (line 21) | func (mi *modulesIntegration) Name() string {
    method SetupOnce (line 25) | func (mi *modulesIntegration) SetupOnce(client *Client) {
    method processor (line 29) | func (mi *modulesIntegration) processor(event *Event, hint *EventHint)...
  function extractModules (line 44) | func extractModules(info *debug.BuildInfo) map[string]string {
  type environmentIntegration (line 62) | type environmentIntegration struct
    method Name (line 64) | func (ei *environmentIntegration) Name() string {
    method SetupOnce (line 68) | func (ei *environmentIntegration) SetupOnce(client *Client) {
    method processor (line 72) | func (ei *environmentIntegration) processor(event *Event, hint *EventH...
  type ignoreErrorsIntegration (line 124) | type ignoreErrorsIntegration struct
    method Name (line 128) | func (iei *ignoreErrorsIntegration) Name() string {
    method SetupOnce (line 132) | func (iei *ignoreErrorsIntegration) SetupOnce(client *Client) {
    method processor (line 137) | func (iei *ignoreErrorsIntegration) processor(event *Event, hint *Even...
  function transformStringsIntoRegexps (line 153) | func transformStringsIntoRegexps(strings []string) []*regexp.Regexp {
  function getIgnoreErrorsSuspects (line 166) | func getIgnoreErrorsSuspects(event *Event) []string {
  type contextifyFramesIntegration (line 184) | type contextifyFramesIntegration struct
    method Name (line 190) | func (cfi *contextifyFramesIntegration) Name() string {
    method SetupOnce (line 194) | func (cfi *contextifyFramesIntegration) SetupOnce(client *Client) {
    method processor (line 201) | func (cfi *contextifyFramesIntegration) processor(event *Event, hint *...
    method contextify (line 227) | func (cfi *contextifyFramesIntegration) contextify(frames []Frame) []F...
    method findNearbySourceCodeLocation (line 263) | func (cfi *contextifyFramesIntegration) findNearbySourceCodeLocation(o...
    method addContextLinesToFrame (line 281) | func (cfi *contextifyFramesIntegration) addContextLinesToFrame(frame F...

FILE: vendor/github.com/getsentry/sentry-go/interfaces.go
  constant transactionType (line 17) | transactionType = "transaction"
  type Level (line 20) | type Level
  constant LevelDebug (line 24) | LevelDebug   Level = "debug"
  constant LevelInfo (line 25) | LevelInfo    Level = "info"
  constant LevelWarning (line 26) | LevelWarning Level = "warning"
  constant LevelError (line 27) | LevelError   Level = "error"
  constant LevelFatal (line 28) | LevelFatal   Level = "fatal"
  function getSensitiveHeaders (line 31) | func getSensitiveHeaders() map[string]bool {
  type SdkInfo (line 41) | type SdkInfo struct
  type SdkPackage (line 49) | type SdkPackage struct
  type BreadcrumbHint (line 59) | type BreadcrumbHint
  type Breadcrumb (line 63) | type Breadcrumb struct
    method MarshalJSON (line 76) | func (b *Breadcrumb) MarshalJSON() ([]byte, error) {
  type User (line 104) | type User struct
    method IsEmpty (line 114) | func (u User) IsEmpty() bool {
  type Request (line 147) | type Request struct
  function NewRequest (line 161) | func NewRequest(r *http.Request) *Request {
  type Mechanism (line 208) | type Mechanism struct
    method SetUnhandled (line 218) | func (m *Mechanism) SetUnhandled() {
  type Exception (line 224) | type Exception struct
  type SDKMetaData (line 235) | type SDKMetaData struct
  type TransactionInfo (line 240) | type TransactionInfo struct
  type EventID (line 246) | type EventID
  type Event (line 251) | type Event struct
    method MarshalJSON (line 294) | func (e *Event) MarshalJSON() ([]byte, error) {
    method defaultMarshalJSON (line 308) | func (e *Event) defaultMarshalJSON() ([]byte, error) {
    method transactionMarshalJSON (line 343) | func (e *Event) transactionMarshalJSON() ([]byte, error) {
  function NewEvent (line 379) | func NewEvent() *Event {
  type Thread (line 390) | type Thread struct
  type EventHint (line 399) | type EventHint struct

FILE: vendor/github.com/getsentry/sentry-go/internal/debug/transport.go
  type Transport (line 14) | type Transport struct
    method RoundTrip (line 23) | func (t *Transport) RoundTrip(req *http.Request) (*http.Response, erro...
  function ensureTrailingNewline (line 74) | func ensureTrailingNewline(b []byte) []byte {

FILE: vendor/github.com/getsentry/sentry-go/internal/otel/baggage/baggage.go
  constant maxMembers (line 29) | maxMembers               = 180
  constant maxBytesPerMembers (line 30) | maxBytesPerMembers       = 4096
  constant maxBytesPerBaggageString (line 31) | maxBytesPerBaggageString = 8192
  constant listDelimiter (line 33) | listDelimiter     = ","
  constant keyValueDelimiter (line 34) | keyValueDelimiter = "="
  constant propertyDelimiter (line 35) | propertyDelimiter = ";"
  constant keyDef (line 37) | keyDef      = `([\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5a\x5e-\x7...
  constant valueDef (line 38) | valueDef    = `([\x21\x23-\x2b\x2d-\x3a\x3c-\x5B\x5D-\x7e]*)`
  constant keyValueDef (line 39) | keyValueDef = `\s*` + keyDef + `\s*` + keyValueDelimiter + `\s*` + value...
  type Property (line 59) | type Property struct
    method validate (line 135) | func (p Property) validate() error {
    method Key (line 157) | func (p Property) Key() string {
    method Value (line 164) | func (p Property) Value() (string, bool) {
    method String (line 170) | func (p Property) String() string {
  function NewKeyProperty (line 75) | func NewKeyProperty(key string) (Property, error) {
  function NewKeyValueProperty (line 87) | func NewKeyValueProperty(key, value string) (Property, error) {
  function newInvalidProperty (line 104) | func newInvalidProperty() Property {
  function parseProperty (line 111) | func parseProperty(property string) (Property, error) {
  type properties (line 177) | type properties
    method asInternal (line 195) | func (p properties) asInternal() []baggage.Property {
    method Copy (line 211) | func (p properties) Copy() properties {
    method validate (line 223) | func (p properties) validate() error {
    method String (line 234) | func (p properties) String() string {
  function fromInternalProperties (line 179) | func fromInternalProperties(iProps []baggage.Property) properties {
  type Member (line 244) | type Member struct
    method validate (line 343) | func (m Member) validate() error {
    method Key (line 359) | func (m Member) Key() string { return m.key }
    method Value (line 362) | func (m Member) Value() string { return m.value }
    method Properties (line 365) | func (m Member) Properties() []Property { return m.properties.Copy() }
    method String (line 369) | func (m Member) String() string {
  function NewMember (line 258) | func NewMember(key, value string, props ...Property) (Member, error) {
  function newInvalidMember (line 277) | func newInvalidMember() Member {
  function parseMember (line 284) | func parseMember(member string) (Member, error) {
  function percentEncodeValue (line 380) | func percentEncodeValue(s string) string {
  type Baggage (line 407) | type Baggage struct
    method Member (line 492) | func (b Baggage) Member(key string) Member {
    method Members (line 515) | func (b Baggage) Members() []Member {
    method SetMember (line 538) | func (b Baggage) SetMember(member Member) (Baggage, error) {
    method DeleteMember (line 567) | func (b Baggage) DeleteMember(key string) Baggage {
    method Len (line 585) | func (b Baggage) Len() int {
    method String (line 592) | func (b Baggage) String() string {
  function New (line 415) | func New(members ...Member) (Baggage, error) {
  function Parse (line 454) | func Parse(bStr string) (Baggage, error) {

FILE: vendor/github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage/baggage.go
  type List (line 31) | type List
  type Item (line 34) | type Item struct
  type Property (line 40) | type Property struct

FILE: vendor/github.com/getsentry/sentry-go/internal/ratelimit/category.go
  type Category (line 15) | type Category
    method String (line 34) | func (c Category) String() string {
  constant CategoryAll (line 20) | CategoryAll         Category = ""
  constant CategoryError (line 21) | CategoryError       Category = "error"
  constant CategoryTransaction (line 22) | CategoryTransaction Category = "transaction"

FILE: vendor/github.com/getsentry/sentry-go/internal/ratelimit/deadline.go
  type Deadline (line 6) | type Deadline
    method After (line 9) | func (d Deadline) After(other Deadline) bool {
    method Equal (line 14) | func (d Deadline) Equal(e Deadline) bool {
    method String (line 19) | func (d Deadline) String() string {

FILE: vendor/github.com/getsentry/sentry-go/internal/ratelimit/map.go
  type Map (line 14) | type Map
    method IsRateLimited (line 17) | func (m Map) IsRateLimited(c Category) bool {
    method isRateLimited (line 21) | func (m Map) isRateLimited(c Category, now time.Time) bool {
    method Deadline (line 27) | func (m Map) Deadline(c Category) Deadline {
    method Merge (line 40) | func (m Map) Merge(other Map) {
  function FromResponse (line 49) | func FromResponse(r *http.Response) Map {
  function fromResponse (line 53) | func fromResponse(r *http.Response, now time.Time) Map {

FILE: vendor/github.com/getsentry/sentry-go/internal/ratelimit/rate_limits.go
  function parseXSentryRateLimits (line 24) | func parseXSentryRateLimits(s string, now time.Time) Map {
  function parseXSRLRetryAfter (line 65) | func parseXSRLRetryAfter(s string, now time.Time) (Deadline, error) {

FILE: vendor/github.com/getsentry/sentry-go/internal/ratelimit/retry_after.go
  constant defaultRetryAfter (line 9) | defaultRetryAfter = 1 * time.Minute
  function parseRetryAfter (line 24) | func parseRetryAfter(s string, now time.Time) (Deadline, error) {

FILE: vendor/github.com/getsentry/sentry-go/scope.go
  type Scope (line 25) | type Scope struct
    method AddBreadcrumb (line 63) | func (scope *Scope) AddBreadcrumb(breadcrumb *Breadcrumb, limit int) {
    method ClearBreadcrumbs (line 78) | func (scope *Scope) ClearBreadcrumbs() {
    method SetUser (line 86) | func (scope *Scope) SetUser(user User) {
    method SetRequest (line 94) | func (scope *Scope) SetRequest(r *http.Request) {
    method SetRequestBody (line 125) | func (scope *Scope) SetRequestBody(b []byte) {
    method SetTag (line 185) | func (scope *Scope) SetTag(key, value string) {
    method SetTags (line 193) | func (scope *Scope) SetTags(tags map[string]string) {
    method RemoveTag (line 203) | func (scope *Scope) RemoveTag(key string) {
    method SetContext (line 211) | func (scope *Scope) SetContext(key string, value Context) {
    method SetContexts (line 219) | func (scope *Scope) SetContexts(contexts map[string]Context) {
    method RemoveContext (line 229) | func (scope *Scope) RemoveContext(key string) {
    method SetExtra (line 237) | func (scope *Scope) SetExtra(key string, value interface{}) {
    method SetExtras (line 245) | func (scope *Scope) SetExtras(extra map[string]interface{}) {
    method RemoveExtra (line 255) | func (scope *Scope) RemoveExtra(key string) {
    method SetFingerprint (line 263) | func (scope *Scope) SetFingerprint(fingerprint []string) {
    method SetLevel (line 271) | func (scope *Scope) SetLevel(level Level) {
    method SetTransaction (line 279) | func (scope *Scope) SetTransaction(name string) {
    method Transaction (line 287) | func (scope *Scope) Transaction() (name string) {
    method Clone (line 295) | func (scope *Scope) Clone() *Scope {
    method Clear (line 323) | func (scope *Scope) Clear() {
    method AddEventProcessor (line 328) | func (scope *Scope) AddEventProcessor(processor EventProcessor) {
    method ApplyToEvent (line 336) | func (scope *Scope) ApplyToEvent(event *Event, hint *EventHint) *Event {
  function NewScope (line 49) | func NewScope() *Scope {
  constant maxRequestBodyBytes (line 144) | maxRequestBodyBytes = 10 * 1024
  type limitedBuffer (line 149) | type limitedBuffer struct
    method Write (line 157) | func (b *limitedBuffer) Write(p []byte) (n int, err error) {
    method Overflow (line 174) | func (b *limitedBuffer) Overflow() bool {
  type readCloser (line 179) | type readCloser struct

FILE: vendor/github.com/getsentry/sentry-go/sentry.go
  constant Version (line 9) | Version = SDKVersion
  constant SDKVersion (line 12) | SDKVersion = "0.19.0"
  constant SDKIdentifier (line 15) | SDKIdentifier = "sentry.go"
  constant apiVersion (line 19) | apiVersion = "7"
  constant userAgent (line 22) | userAgent = "sentry-go/" + SDKVersion
  function Init (line 26) | func Init(options ClientOptions) error {
  function AddBreadcrumb (line 40) | func AddBreadcrumb(breadcrumb *Breadcrumb) {
  function CaptureMessage (line 46) | func CaptureMessage(message string) *EventID {
  function CaptureException (line 52) | func CaptureException(exception error) *EventID {
  function CaptureEvent (line 62) | func CaptureEvent(event *Event) *EventID {
  function Recover (line 68) | func Recover() *EventID {
  function RecoverWithContext (line 77) | func RecoverWithContext(ctx context.Context) *EventID {
  function WithScope (line 93) | func WithScope(f func(scope *Scope)) {
  function ConfigureScope (line 99) | func ConfigureScope(f func(scope *Scope)) {
  function PushScope (line 105) | func PushScope() {
  function PopScope (line 111) | func PopScope() {
  function Flush (line 127) | func Flush(timeout time.Duration) bool {
  function LastEventID (line 133) | func LastEventID() EventID {

FILE: vendor/github.com/getsentry/sentry-go/sourcereader.go
  type sourceReader (line 9) | type sourceReader struct
    method readContextLines (line 20) | func (sr *sourceReader) readContextLines(filename string, line, contex...
    method calculateContextLines (line 39) | func (sr *sourceReader) calculateContextLines(lines [][]byte, line, co...
  function newSourceReader (line 14) | func newSourceReader() sourceReader {

FILE: vendor/github.com/getsentry/sentry-go/span_recorder.go
  type spanRecorder (line 9) | type spanRecorder struct
    method record (line 17) | func (r *spanRecorder) record(s *Span) {
    method root (line 38) | func (r *spanRecorder) root() *Span {
    method children (line 49) | func (r *spanRecorder) children() []*Span {

FILE: vendor/github.com/getsentry/sentry-go/stacktrace.go
  constant unknown (line 11) | unknown string = "unknown"
  type Stacktrace (line 21) | type Stacktrace struct
  function NewStacktrace (line 27) | func NewStacktrace() *Stacktrace {
  function ExtractStacktrace (line 50) | func ExtractStacktrace(err error) *Stacktrace {
  function extractReflectedStacktraceMethod (line 75) | func extractReflectedStacktraceMethod(err error) reflect.Value {
  function extractPcs (line 104) | func extractPcs(method reflect.Value) []uintptr {
  function extractXErrorsPC (line 141) | func extractXErrorsPC(err error) []uintptr {
  type Frame (line 164) | type Frame struct
  function NewFrame (line 188) | func NewFrame(f runtime.Frame) Frame {
  function splitQualifiedFunctionName (line 240) | func splitQualifiedFunctionName(name string) (pkg string, fun string) {
  function extractFrames (line 246) | func extractFrames(pcs []uintptr) []Frame {
  function filterFrames (line 270) | func filterFrames(frames []Frame) []Frame {
  function isInAppFrame (line 295) | func isInAppFrame(frame Frame) bool {
  function callerFunctionName (line 305) | func callerFunctionName() string {
  function packageName (line 317) | func packageName(name string) string {
  function baseName (line 338) | func baseName(name string) string {

FILE: vendor/github.com/getsentry/sentry-go/traces_sampler.go
  type SamplingContext (line 8) | type SamplingContext struct
  type TracesSampler (line 15) | type TracesSampler
    method Sample (line 17) | func (f TracesSampler) Sample(ctx SamplingContext) float64 {

FILE: vendor/github.com/getsentry/sentry-go/tracing.go
  constant SentryTraceHeader (line 16) | SentryTraceHeader   = "sentry-trace"
  constant SentryBaggageHeader (line 17) | SentryBaggageHeader = "baggage"
  type Span (line 25) | type Span struct
    method Finish (line 183) | func (s *Span) Finish() {
    method Context (line 209) | func (s *Span) Context() context.Context { return s.ctx }
    method StartChild (line 215) | func (s *Span) StartChild(operation string, options ...SpanOption) *Sp...
    method SetTag (line 222) | func (s *Span) SetTag(name, value string) {
    method SetData (line 232) | func (s *Span) SetData(name, value string) {
    method IsTransaction (line 240) | func (s *Span) IsTransaction() bool {
    method GetTransaction (line 248) | func (s *Span) GetTransaction() *Span {
    method ToSentryTrace (line 276) | func (s *Span) ToSentryTrace() string {
    method ToBaggage (line 293) | func (s *Span) ToBaggage() string {
    method SetDynamicSamplingContext (line 309) | func (s *Span) SetDynamicSamplingContext(dsc DynamicSamplingContext) {
    method updateFromSentryTrace (line 330) | func (s *Span) updateFromSentryTrace(header []byte) (updated bool) {
    method updateFromBaggage (line 349) | func (s *Span) updateFromBaggage(header []byte) {
    method MarshalJSON (line 360) | func (s *Span) MarshalJSON() ([]byte, error) {
    method sample (line 377) | func (s *Span) sample() Sampled {
    method toEvent (line 465) | func (s *Span) toEvent() *Event {
    method traceContext (line 507) | func (s *Span) traceContext() *TraceContext {
    method spanRecorder (line 519) | func (s *Span) spanRecorder() *spanRecorder { return s.recorder }
  type TraceParentContext (line 66) | type TraceParentContext struct
  function StartSpan (line 98) | func StartSpan(ctx context.Context, operation string, options ...SpanOpt...
  function ParseTraceParentContext (line 525) | func ParseTraceParentContext(header []byte) (traceParentContext TracePar...
  type TraceID (line 539) | type TraceID
    method Hex (line 541) | func (id TraceID) Hex() []byte {
    method String (line 547) | func (id TraceID) String() string {
    method MarshalText (line 551) | func (id TraceID) MarshalText() ([]byte, error) {
  type SpanID (line 556) | type SpanID
    method Hex (line 558) | func (id SpanID) Hex() []byte {
    method String (line 564) | func (id SpanID) String() string {
    method MarshalText (line 568) | func (id SpanID) MarshalText() ([]byte, error) {
  type TransactionSource (line 579) | type TransactionSource
  constant SourceCustom (line 582) | SourceCustom    TransactionSource = "custom"
  constant SourceURL (line 583) | SourceURL       TransactionSource = "url"
  constant SourceRoute (line 584) | SourceRoute     TransactionSource = "route"
  constant SourceView (line 585) | SourceView      TransactionSource = "view"
  constant SourceComponent (line 586) | SourceComponent TransactionSource = "component"
  constant SourceTask (line 587) | SourceTask      TransactionSource = "task"
  type SpanStatus (line 591) | type SpanStatus
    method String (line 631) | func (ss SpanStatus) String() string {
    method MarshalJSON (line 658) | func (ss SpanStatus) MarshalJSON() ([]byte, error) {
  constant SpanStatusUndefined (line 610) | SpanStatusUndefined SpanStatus = iota
  constant SpanStatusOK (line 611) | SpanStatusOK
  constant SpanStatusCanceled (line 612) | SpanStatusCanceled
  constant SpanStatusUnknown (line 613) | SpanStatusUnknown
  constant SpanStatusInvalidArgument (line 614) | SpanStatusInvalidArgument
  constant SpanStatusDeadlineExceeded (line 615) | SpanStatusDeadlineExceeded
  constant SpanStatusNotFound (line 616) | SpanStatusNotFound
  constant SpanStatusAlreadyExists (line 617) | SpanStatusAlreadyExists
  constant SpanStatusPermissionDenied (line 618) | SpanStatusPermissionDenied
  constant SpanStatusResourceExhausted (line 619) | SpanStatusResourceExhausted
  constant SpanStatusFailedPrecondition (line 620) | SpanStatusFailedPrecondition
  constant SpanStatusAborted (line 621) | SpanStatusAborted
  constant SpanStatusOutOfRange (line 622) | SpanStatusOutOfRange
  constant SpanStatusUnimplemented (line 623) | SpanStatusUnimplemented
  constant SpanStatusInternalError (line 624) | SpanStatusInternalError
  constant SpanStatusUnavailable (line 625) | SpanStatusUnavailable
  constant SpanStatusDataLoss (line 626) | SpanStatusDataLoss
  constant SpanStatusUnauthenticated (line 627) | SpanStatusUnauthenticated
  constant maxSpanStatus (line 628) | maxSpanStatus
  type TraceContext (line 668) | type TraceContext struct
    method MarshalJSON (line 677) | func (tc *TraceContext) MarshalJSON() ([]byte, error) {
    method Map (line 695) | func (tc TraceContext) Map() map[string]interface{} {
  type Sampled (line 721) | type Sampled
    method String (line 731) | func (s Sampled) String() string {
    method Bool (line 745) | func (s Sampled) Bool() bool {
  constant SampledFalse (line 726) | SampledFalse     Sampled = -1
  constant SampledUndefined (line 727) | SampledUndefined Sampled = 0
  constant SampledTrue (line 728) | SampledTrue      Sampled = 1
  type SpanOption (line 750) | type SpanOption
  function TransactionName (line 757) | func TransactionName(name string) SpanOption {
  function OpName (line 764) | func OpName(name string) SpanOption {
  function TransctionSource (line 772) | func TransctionSource(source TransactionSource) SpanOption {
  function SpanSampled (line 779) | func SpanSampled(sampled Sampled) SpanOption {
  function ContinueFromRequest (line 792) | func ContinueFromRequest(r *http.Request) SpanOption {
  function ContinueFromHeaders (line 798) | func ContinueFromHeaders(trace, baggage string) SpanOption {
  function ContinueFromTrace (line 819) | func ContinueFromTrace(trace string) SpanOption {
  type spanContextKey (line 829) | type spanContextKey struct
  function TransactionFromContext (line 833) | func TransactionFromContext(ctx context.Context) *Span {
  function spanFromContext (line 860) | func spanFromContext(ctx context.Context) *Span {
  function StartTransaction (line 869) | func StartTransaction(ctx context.Context, name string, options ...SpanO...

FILE: vendor/github.com/getsentry/sentry-go/transport.go
  constant defaultBufferSize (line 18) | defaultBufferSize = 30
  constant defaultTimeout (line 19) | defaultTimeout = time.Second * 30
  constant maxDrainResponseBytes (line 30) | maxDrainResponseBytes = 16 << 10
  type Transport (line 33) | type Transport interface
  function getProxyConfig (line 39) | func getProxyConfig(options ClientOptions) func(*http.Request) (*url.URL...
  function getTLSConfig (line 55) | func getTLSConfig(options ClientOptions) *tls.Config {
  function getRequestBodyFromEvent (line 67) | func getRequestBodyFromEvent(event *Event) []byte {
  function transactionEnvelopeFromBody (line 97) | func transactionEnvelopeFromBody(event *Event, dsn *Dsn, sentAt time.Tim...
  function getRequestFromEvent (line 150) | func getRequestFromEvent(event *Event, dsn *Dsn) (r *http.Request, err e...
  function categoryFor (line 178) | func categoryFor(eventType string) ratelimit.Category {
  type batch (line 194) | type batch struct
  type batchItem (line 200) | type batchItem struct
  type HTTPTransport (line 210) | type HTTPTransport struct
    method Configure (line 241) | func (t *HTTPTransport) Configure(options ClientOptions) {
    method SendEvent (line 283) | func (t *HTTPTransport) SendEvent(event *Event) {
    method Flush (line 351) | func (t *HTTPTransport) Flush(timeout time.Duration) bool {
    method worker (line 400) | func (t *HTTPTransport) worker() {
    method disabled (line 434) | func (t *HTTPTransport) disabled(c ratelimit.Category) bool {
  function NewHTTPTransport (line 231) | func NewHTTPTransport() *HTTPTransport {
  type HTTPSyncTransport (line 459) | type HTTPSyncTransport struct
    method Configure (line 482) | func (t *HTTPSyncTransport) Configure(options ClientOptions) {
    method SendEvent (line 510) | func (t *HTTPSyncTransport) SendEvent(event *Event) {
    method Flush (line 558) | func (t *HTTPSyncTransport) Flush(_ time.Duration) bool {
    method disabled (line 562) | func (t *HTTPSyncTransport) disabled(c ratelimit.Category) bool {
  function NewHTTPSyncTransport (line 472) | func NewHTTPSyncTransport() *HTTPSyncTransport {
  type noopTransport (line 578) | type noopTransport struct
    method Configure (line 582) | func (noopTransport) Configure(ClientOptions) {
    method SendEvent (line 586) | func (noopTransport) SendEvent(*Event) {
    method Flush (line 590) | func (noopTransport) Flush(time.Duration) bool {

FILE: vendor/github.com/getsentry/sentry-go/util.go
  function uuid (line 15) | func uuid() string {
  function fileExists (line 26) | func fileExists(fileName string) bool {
  function monotonicTimeSince (line 34) | func monotonicTimeSince(start time.Time) (end time.Time) {
  function prettyPrint (line 39) | func prettyPrint(data interface{}) {
  function defaultRelease (line 46) | func defaultRelease() (release string) {

FILE: vendor/github.com/go-logr/logr/discard.go
  function Discard (line 22) | func Discard() Logger {
  type discardLogSink (line 30) | type discardLogSink struct
    method Init (line 35) | func (l discardLogSink) Init(RuntimeInfo) {
    method Enabled (line 38) | func (l discardLogSink) Enabled(int) bool {
    method Info (line 42) | func (l discardLogSink) Info(int, string, ...interface{}) {
    method Error (line 45) | func (l discardLogSink) Error(error, string, ...interface{}) {
    method WithValues (line 48) | func (l discardLogSink) WithValues(...interface{}) LogSink {
    method WithName (line 52) | func (l discardLogSink) WithName(string) LogSink {

FILE: vendor/github.com/go-logr/logr/logr.go
  function New (line 205) | func New(sink LogSink) Logger {
  type Logger (line 239) | type Logger struct
    method setSink (line 215) | func (l *Logger) setSink(sink LogSink) {
    method GetSink (line 220) | func (l Logger) GetSink() LogSink {
    method WithSink (line 225) | func (l Logger) WithSink(sink LogSink) Logger {
    method Enabled (line 246) | func (l Logger) Enabled() bool {
    method Info (line 256) | func (l Logger) Info(msg string, keysAndValues ...interface{}) {
    method Error (line 275) | func (l Logger) Error(err error, msg string, keysAndValues ...interfac...
    method V (line 286) | func (l Logger) V(level int) Logger {
    method WithValues (line 296) | func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
    method WithName (line 306) | func (l Logger) WithName(name string) Logger {
    method WithCallDepth (line 326) | func (l Logger) WithCallDepth(depth int) Logger {
    method WithCallStackHelper (line 347) | func (l Logger) WithCallStackHelper() (func(), Logger) {
  type contextKey (line 361) | type contextKey struct
  function FromContext (line 364) | func FromContext(ctx context.Context) (Logger, error) {
  type notFoundError (line 373) | type notFoundError struct
    method Error (line 375) | func (notFoundError) Error() string {
    method IsNotFound (line 379) | func (notFoundError) IsNotFound() bool {
  function FromContextOrDiscard (line 385) | func FromContextOrDiscard(ctx context.Context) Logger {
  function NewContext (line 395) | func NewContext(ctx context.Context, logger Logger) context.Context {
  type RuntimeInfo (line 401) | type RuntimeInfo struct
  type LogSink (line 416) | type LogSink interface
  type CallDepthLogSink (line 455) | type CallDepthLogSink interface
  type CallStackHelperLogSink (line 487) | type CallStackHelperLogSink interface
  type Marshaler (line 498) | type Marshaler interface

FILE: vendor/github.com/golang/protobuf/jsonpb/decode.go
  constant wrapJSONUnmarshalV2 (line 25) | wrapJSONUnmarshalV2 = false
  function UnmarshalNext (line 28) | func UnmarshalNext(d *json.Decoder, m proto.Message) error {
  function Unmarshal (line 33) | func Unmarshal(r io.Reader, m proto.Message) error {
  function UnmarshalString (line 38) | func UnmarshalString(s string, m proto.Message) error {
  type Unmarshaler (line 44) | type Unmarshaler struct
    method Unmarshal (line 67) | func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error {
    method UnmarshalNext (line 72) | func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) ...
    method unmarshalMessage (line 134) | func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []by...
    method unmarshalValue (line 409) | func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, ...
    method unmarshalSingularValue (line 463) | func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in ...
  type JSONPBUnmarshaler (line 62) | type JSONPBUnmarshaler interface
  function isSingularWellKnownValue (line 388) | func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
  function isSingularJSONPBUnmarshaler (line 401) | func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.F...
  function unmarshalValue (line 506) | func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) {
  function unquoteString (line 511) | func unquoteString(in string) (out string, err error) {
  function hasPrefixAndSuffix (line 516) | func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool {
  function trimQuote (line 525) | func trimQuote(in []byte) []byte {

FILE: vendor/github.com/golang/protobuf/jsonpb/encode.go
  constant wrapJSONMarshalV2 (line 26) | wrapJSONMarshalV2 = false
  type Marshaler (line 30) | type Marshaler struct
    method Marshal (line 66) | func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error {
    method MarshalToString (line 77) | func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) {
    method marshal (line 85) | func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) {
  type JSONPBMarshaler (line 61) | type JSONPBMarshaler interface
  type jsonWriter (line 121) | type jsonWriter struct
    method write (line 126) | func (w *jsonWriter) write(s string) {
    method marshalMessage (line 130) | func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, ty...
    method writeComma (line 305) | func (w *jsonWriter) writeComma() {
    method marshalAny (line 313) | func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string)...
    method marshalTypeURL (line 371) | func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error {
    method marshalField (line 389) | func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v p...
    method marshalValue (line 420) | func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v p...
    method marshalSingularValue (line 513) | func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescrip...

FILE: vendor/github.com/golang/protobuf/jsonpb/json.go
  type AnyResolver (line 25) | type AnyResolver interface
  type anyResolver (line 29) | type anyResolver struct
    method FindMessageByName (line 31) | func (r anyResolver) FindMessageByName(message protoreflect.FullName) ...
    method FindMessageByURL (line 35) | func (r anyResolver) FindMessageByURL(url string) (protoreflect.Messag...
    method FindExtensionByName (line 43) | func (r anyResolver) FindExtensionByName(field protoreflect.FullName) ...
    method FindExtensionByNumber (line 47) | func (r anyResolver) FindExtensionByNumber(message protoreflect.FullNa...
  function wellKnownType (line 51) | func wellKnownType(s protoreflect.FullName) string {
  function isMessageSet (line 66) | func isMessageSet(md protoreflect.MessageDescriptor) bool {

FILE: vendor/github.com/golang/protobuf/proto/buffer.go
  constant WireVarint (line 17) | WireVarint     = 0
  constant WireFixed32 (line 18) | WireFixed32    = 5
  constant WireFixed64 (line 19) | WireFixed64    = 1
  constant WireBytes (line 20) | WireBytes      = 2
  constant WireStartGroup (line 21) | WireStartGroup = 3
  constant WireEndGroup (line 22) | WireEndGroup   = 4
  function EncodeVarint (line 26) | func EncodeVarint(v uint64) []byte {
  function SizeVarint (line 32) | func SizeVarint(v uint64) int {
  function DecodeVarint (line 39) | func DecodeVarint(b []byte) (uint64, int) {
  type Buffer (line 49) | type Buffer struct
    method SetDeterministic (line 81) | func (b *Buffer) SetDeterministic(deterministic bool) {
    method SetBuf (line 87) | func (b *Buffer) SetBuf(buf []byte) {
    method Reset (line 93) | func (b *Buffer) Reset() {
    method Bytes (line 99) | func (b *Buffer) Bytes() []byte {
    method Unread (line 104) | func (b *Buffer) Unread() []byte {
    method Marshal (line 109) | func (b *Buffer) Marshal(m Message) error {
    method Unmarshal (line 118) | func (b *Buffer) Unmarshal(m Message) error {
    method DebugPrint (line 132) | func (*Buffer) DebugPrint(s string, b []byte) {
    method EncodeVarint (line 140) | func (b *Buffer) EncodeVarint(v uint64) error {
    method EncodeZigzag32 (line 146) | func (b *Buffer) EncodeZigzag32(v uint64) error {
    method EncodeZigzag64 (line 151) | func (b *Buffer) EncodeZigzag64(v uint64) error {
    method EncodeFixed32 (line 156) | func (b *Buffer) EncodeFixed32(v uint64) error {
    method EncodeFixed64 (line 162) | func (b *Buffer) EncodeFixed64(v uint64) error {
    method EncodeRawBytes (line 168) | func (b *Buffer) EncodeRawBytes(v []byte) error {
    method EncodeStringBytes (line 175) | func (b *Buffer) EncodeStringBytes(v string) error {
    method EncodeMessage (line 181) | func (b *Buffer) EncodeMessage(m Message) error {
    method DecodeVarint (line 189) | func (b *Buffer) DecodeVarint() (uint64, error) {
    method DecodeZigzag32 (line 199) | func (b *Buffer) DecodeZigzag32() (uint64, error) {
    method DecodeZigzag64 (line 208) | func (b *Buffer) DecodeZigzag64() (uint64, error) {
    method DecodeFixed32 (line 217) | func (b *Buffer) DecodeFixed32() (uint64, error) {
    method DecodeFixed64 (line 227) | func (b *Buffer) DecodeFixed64() (uint64, error) {
    method DecodeRawBytes (line 239) | func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) {
    method DecodeStringBytes (line 253) | func (b *Buffer) DecodeStringBytes() (string, error) {
    method DecodeMessage (line 264) | func (b *Buffer) DecodeMessage(m Message) error {
    method DecodeGroup (line 276) | func (b *Buffer) DecodeGroup(m Message) error {
  function NewBuffer (line 57) | func NewBuffer(buf []byte) *Buffer {
  type unknownFields (line 124) | type unknownFields struct
    method String (line 126) | func (m *unknownFields) String() string { panic("not implemented") }
    method Reset (line 127) | func (m *unknownFields) Reset()         { panic("not implemented") }
    method ProtoMessage (line 128) | func (m *unknownFields) ProtoMessage()  { panic("not implemented") }
  function consumeGroup (line 288) | func consumeGroup(b []byte) ([]byte, int, error) {

FILE: vendor/github.com/golang/protobuf/proto/defaults.go
  function SetDefaults (line 14) | func SetDefaults(m Message) {
  function setDefaults (line 20) | func setDefaults(m protoreflect.Message) {

FILE: vendor/github.com/golang/protobuf/proto/deprecated.go
  type Stats (line 28) | type Stats struct
  function GetStats (line 31) | func GetStats() Stats { return Stats{} }
  function MarshalMessageSet (line 34) | func MarshalMessageSet(interface{}) ([]byte, error) {
  function UnmarshalMessageSet (line 39) | func UnmarshalMessageSet([]byte, interface{}) error {
  function MarshalMessageSetJSON (line 44) | func MarshalMessageSetJSON(interface{}) ([]byte, error) {
  function UnmarshalMessageSetJSON (line 49) | func UnmarshalMessageSetJSON([]byte, interface{}) error {
  function RegisterMessageSetType (line 54) | func RegisterMessageSetType(Message, int32, string) {}
  function EnumName (line 57) | func EnumName(m map[int32]string, v int32) string {
  function UnmarshalJSONEnum (line 66) | func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string)...
  type InternalMessageInfo (line 88) | type InternalMessageInfo struct
    method DiscardUnknown (line 91) | func (*InternalMessageInfo) DiscardUnknown(m Message) {
    method Marshal (line 96) | func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic...
    method Merge (line 101) | func (*InternalMessageInfo) Merge(dst, src Message) {
    method Size (line 106) | func (*InternalMessageInfo) Size(m Message) int {
    method Unmarshal (line 111) | func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error {

FILE: vendor/github.com/golang/protobuf/proto/discard.go
  function DiscardUnknown (line 19) | func DiscardUnknown(m Message) {
  function discardUnknown (line 25) | func discardUnknown(m protoreflect.Message) {

FILE: vendor/github.com/golang/protobuf/proto/extensions.go
  function HasExtension (line 45) | func HasExtension(m Message, xt *ExtensionDesc) (has bool) {
  function ClearExtension (line 73) | func ClearExtension(m Message, xt *ExtensionDesc) {
  function ClearAllExtensions (line 96) | func ClearAllExtensions(m Message) {
  function GetExtension (line 120) | func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) {
  type extensionResolver (line 183) | type extensionResolver struct
    method FindExtensionByName (line 185) | func (r extensionResolver) FindExtensionByName(field protoreflect.Full...
    method FindExtensionByNumber (line 192) | func (r extensionResolver) FindExtensionByNumber(message protoreflect....
  function GetExtensions (line 202) | func GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, erro...
  function SetExtension (line 223) | func SetExtension(m Message, xt *ExtensionDesc, v interface{}) error {
  function SetRawExtension (line 254) | func SetRawExtension(m Message, fnum int32, b []byte) {
  function ExtensionDescs (line 279) | func ExtensionDescs(m Message) ([]*ExtensionDesc, error) {
  function isValidExtension (line 319) | func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflec...
  function isScalarKind (line 326) | func isScalarKind(k reflect.Kind) bool {
  function clearUnknown (line 336) | func clearUnknown(m protoreflect.Message, remover interface {
  type fieldNum (line 352) | type fieldNum
    method Has (line 354) | func (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool {

FILE: vendor/github.com/golang/protobuf/proto/properties.go
  type StructProperties (line 22) | type StructProperties struct
    method Len (line 304) | func (sp *StructProperties) Len() int           { return len(sp.Prop) }
    method Less (line 305) | func (sp *StructProperties) Less(i, j int) bool { return false }
    method Swap (line 306) | func (sp *StructProperties) Swap(i, j int)      { return }
  type Properties (line 41) | type Properties struct
    method String (line 99) | func (p *Properties) String() string {
    method Parse (line 137) | func (p *Properties) Parse(tag string) {
    method Init (line 196) | func (p *Properties) Init(typ reflect.Type, name, tag string, f *refle...
  type OneofProperties (line 88) | type OneofProperties struct
  function GetProperties (line 219) | func GetProperties(t reflect.Type) *StructProperties {
  function newProperties (line 227) | func newProperties(t reflect.Type) *StructProperties {

FILE: vendor/github.com/golang/protobuf/proto/proto.go
  constant ProtoPackageIsVersion1 (line 23) | ProtoPackageIsVersion1 = true
  constant ProtoPackageIsVersion2 (line 24) | ProtoPackageIsVersion2 = true
  constant ProtoPackageIsVersion3 (line 25) | ProtoPackageIsVersion3 = true
  constant ProtoPackageIsVersion4 (line 26) | ProtoPackageIsVersion4 = true
  type GeneratedEnum (line 32) | type GeneratedEnum interface
  type GeneratedMessage (line 37) | type GeneratedMessage interface
  function MessageV1 (line 54) | func MessageV1(m GeneratedMessage) protoiface.MessageV1 {
  function MessageV2 (line 60) | func MessageV2(m GeneratedMessage) protoV2.Message {
  function MessageReflect (line 66) | func MessageReflect(m Message) protoreflect.Message {
  type Marshaler (line 75) | type Marshaler interface
  type Unmarshaler (line 87) | type Unmarshaler interface
  type Merger (line 98) | type Merger interface
  type RequiredNotSetError (line 107) | type RequiredNotSetError struct
    method Error (line 111) | func (e *RequiredNotSetError) Error() string {
    method RequiredNotSet (line 117) | func (e *RequiredNotSetError) RequiredNotSet() bool {
  function checkRequiredNotSet (line 121) | func checkRequiredNotSet(m protoV2.Message) error {
  function Clone (line 129) | func Clone(src Message) Message {
  function Merge (line 141) | func Merge(dst, src Message) {
  function Equal (line 160) | func Equal(x, y Message) bool {
  function isMessageSet (line 164) | func isMessageSet(md protoreflect.MessageDescriptor) bool {

FILE: vendor/github.com/golang/protobuf/proto/registry.go
  function RegisterFile (line 34) | func RegisterFile(s filePath, d fileDescGZIP) {
  function FileDescriptor (line 58) | func FileDescriptor(s filePath) fileDescGZIP {
  function RegisterEnum (line 96) | func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) {
  function EnumValueMap (line 110) | func EnumValueMap(s enumName) enumsByName {
  function walkEnums (line 156) | func walkEnums(d interface {
  function RegisterType (line 179) | func RegisterType(m Message, s messageName) {
  function RegisterMapType (line 191) | func RegisterMapType(m interface{}, s messageName) {
  function MessageType (line 206) | func MessageType(s messageName) reflect.Type {
  function goTypeForField (line 236) | func goTypeForField(fd protoreflect.FieldDescriptor) reflect.Type {
  function enumGoType (line 253) | func enumGoType(et protoreflect.EnumType) reflect.Type {
  function messageGoType (line 257) | func messageGoType(mt protoreflect.MessageType) reflect.Type {
  function MessageName (line 264) | func MessageName(m Message) messageName {
  function RegisterExtension (line 278) | func RegisterExtension(d *ExtensionDesc) {
  function RegisteredExtensions (line 292) | func RegisteredExtensions(m Message) extensionsByNumber {

FILE: vendor/github.com/golang/protobuf/proto/text_decode.go
  constant wrapTextUnmarshalV2 (line 22) | wrapTextUnmarshalV2 = false
  type ParseError (line 25) | type ParseError struct
    method Error (line 32) | func (e *ParseError) Error() string {
  function UnmarshalText (line 43) | func UnmarshalText(s string, m Message) error {
  type textParser (line 67) | type textParser struct
    method unmarshalMessage (line 91) | func (p *textParser) unmarshalMessage(m protoreflect.Message, terminat...
    method unmarshalExtensionOrAny (line 171) | func (p *textParser) unmarshalExtensionOrAny(m protoreflect.Message, s...
    method unmarshalValue (line 258) | func (p *textParser) unmarshalValue(v protoreflect.Value, fd protorefl...
    method unmarshalSingularValue (line 368) | func (p *textParser) unmarshalSingularValue(v protoreflect.Value, fd p...
    method checkForColon (line 475) | func (p *textParser) checkForColon(fd protoreflect.FieldDescriptor) *P...
    method consumeExtensionOrAnyName (line 491) | func (p *textParser) consumeExtensionOrAnyName() (string, error) {
    method consumeOptionalSeparator (line 523) | func (p *textParser) consumeOptionalSeparator() error {
    method errorf (line 534) | func (p *textParser) errorf(format string, a ...interface{}) *ParseErr...
    method skipWhitespace (line 541) | func (p *textParser) skipWhitespace() {
    method advance (line 565) | func (p *textParser) advance() {
    method back (line 617) | func (p *textParser) back() { p.backed = true }
    method next (line 620) | func (p *textParser) next() *token {
    method consumeToken (line 650) | func (p *textParser) consumeToken(s string) error {
  type token (line 75) | type token struct
  function newTextParser (line 83) | func newTextParser(s string) *textParser {
  function unquoteC (line 664) | func unquoteC(s string, quote rune) (string, error) {
  function unescape (line 707) | func unescape(s string) (ch string, tail string, err error) {
  function isIdentOrNumberChar (line 773) | func isIdentOrNumberChar(c byte) bool {
  function isWhitespace (line 787) | func isWhitespace(c byte) bool {
  function isQuote (line 795) | func isQuote(c byte) bool {

FILE: vendor/github.com/golang/protobuf/proto/text_encode.go
  constant wrapTextMarshalV2 (line 23) | wrapTextMarshalV2 = false
  type TextMarshaler (line 26) | type TextMarshaler struct
    method Marshal (line 32) | func (tm *TextMarshaler) Marshal(w io.Writer, m Message) error {
    method Text (line 43) | func (tm *TextMarshaler) Text(m Message) string {
    method marshal (line 48) | func (tm *TextMarshaler) marshal(m Message) ([]byte, error) {
  function MarshalText (line 97) | func MarshalText(w io.Writer, m Message) error { return defaultTextMarsh...
  function MarshalTextString (line 100) | func MarshalTextString(m Message) string { return defaultTextMarshaler.T...
  function CompactText (line 103) | func CompactText(w io.Writer, m Message) error { return compactTextMarsh...
  function CompactTextString (line 106) | func CompactTextString(m Message) string { return compactTextMarshaler.T...
  type textWriter (line 117) | type textWriter struct
    method Write (line 125) | func (w *textWriter) Write(p []byte) (n int, _ error) {
    method WriteByte (line 164) | func (w *textWriter) WriteByte(c byte) error {
    method writeName (line 176) | func (w *textWriter) writeName(fd protoreflect.FieldDescriptor) {
    method writeProto3Any (line 221) | func (w *textWriter) writeProto3Any(m protoreflect.Message) (bool, err...
    method writeMessage (line 261) | func (w *textWriter) writeMessage(m protoreflect.Message) error {
    method writeSingularValue (line 354) | func (w *textWriter) writeSingularValue(v protoreflect.Value, fd proto...
    method writeQuotedString (line 407) | func (w *textWriter) writeQuotedString(s string) {
    method writeUnknownFields (line 432) | func (w *textWriter) writeUnknownFields(b []byte) {
    method writeExtensions (line 496) | func (w *textWriter) writeExtensions(m protoreflect.Message) error {
    method writeSingularExtension (line 540) | func (w *textWriter) writeSingularExtension(name string, v protoreflec...
    method writeIndent (line 552) | func (w *textWriter) writeIndent() {
  function requiresQuotes (line 195) | func requiresQuotes(u string) bool {

FILE: vendor/github.com/golang/protobuf/proto/wire.go
  function Size (line 13) | func Size(m Message) int {
  function Marshal (line 22) | func Marshal(m Message) ([]byte, error) {
  function marshalAppend (line 32) | func marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, e...
  function Unmarshal (line 56) | func Unmarshal(b []byte, m Message) error {
  function UnmarshalMerge (line 62) | func UnmarshalMerge(b []byte, m Message) error {

FILE: vendor/github.com/golang/protobuf/proto/wrappers.go
  function Bool (line 8) | func Bool(v bool) *bool { return &v }
  function Int (line 13) | func Int(v int) *int32 { return Int32(int32(v)) }
  function Int32 (line 16) | func Int32(v int32) *int32 { return &v }
  function Int64 (line 19) | func Int64(v int64) *int64 { return &v }
  function Uint32 (line 22) | func Uint32(v uint32) *uint32 { return &v }
  function Uint64 (line 25) | func Uint64(v uint64) *uint64 { return &v }
  function Float32 (line 28) | func Float32(v float32) *float32 { return &v }
  function Float64 (line 31) | func Float64(v float64) *float64 { return &v }
  function String (line 34) | func String(v string) *string { return &v }

FILE: vendor/github.com/golang/protobuf/ptypes/any.go
  constant urlPrefix (line 18) | urlPrefix = "type.googleapis.com/"
  function AnyMessageName (line 24) | func AnyMessageName(any *anypb.Any) (string, error) {
  function anyMessageName (line 28) | func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) {
  function MarshalAny (line 45) | func MarshalAny(m proto.Message) (*anypb.Any, error) {
  function Empty (line 68) | func Empty(any *anypb.Any) (proto.Message, error) {
  function UnmarshalAny (line 88) | func UnmarshalAny(any *anypb.Any, m proto.Message) error {
  function Is (line 114) | func Is(any *anypb.Any, m proto.Message) bool {
  type DynamicAny (line 136) | type DynamicAny struct
    method String (line 138) | func (m DynamicAny) String() string {
    method Reset (line 144) | func (m DynamicAny) Reset() {
    method ProtoMessage (line 150) | func (m DynamicAny) ProtoMessage() {
    method ProtoReflect (line 153) | func (m DynamicAny) ProtoReflect() protoreflect.Message {
  type dynamicAny (line 160) | type dynamicAny struct
    method Type (line 162) | func (m dynamicAny) Type() protoreflect.MessageType {
    method New (line 165) | func (m dynamicAny) New() protoreflect.Message {
    method Interface (line 168) | func (m dynamicAny) Interface() protoreflect.ProtoMessage {
  type dynamicAnyType (line 172) | type dynamicAnyType struct
    method New (line 174) | func (t dynamicAnyType) New() protoreflect.Message {
    method Zero (line 177) | func (t dynamicAnyType) Zero() protoreflect.Message {

FILE: vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
  function init (line 40) | func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() }
  function file_github_com_golang_protobuf_ptypes_any_any_proto_init (line 41) | func file_github_com_golang_protobuf_ptypes_any_any_proto_init() {

FILE: vendor/github.com/golang/protobuf/ptypes/duration.go
  constant maxSeconds (line 18) | maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
  constant minSeconds (line 19) | minSeconds = -maxSeconds
  function Duration (line 26) | func Duration(dur *durationpb.Duration) (time.Duration, error) {
  function DurationProto (line 46) | func DurationProto(d time.Duration) *durationpb.Duration {
  function validateDuration (line 61) | func validateDuration(dur *durationpb.Duration) error {

FILE: vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go
  function init (line 41) | func init() { file_github_com_golang_protobuf_ptypes_duration_duration_p...
  function file_github_com_golang_protobuf_ptypes_duration_duration_proto_init (line 42) | func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init...

FILE: vendor/github.com/golang/protobuf/ptypes/timestamp.go
  constant minValidSeconds (line 19) | minValidSeconds = -62135596800
  constant maxValidSeconds (line 22) | maxValidSeconds = 253402300800
  function Timestamp (line 38) | func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) {
  function TimestampNow (line 53) | func TimestampNow() *timestamppb.Timestamp {
  function TimestampProto (line 65) | func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) {
  function TimestampString (line 81) | func TimestampString(ts *timestamppb.Timestamp) string {
  function validateTimestamp (line 98) | func validateTimestamp(ts *timestamppb.Timestamp) error {

FILE: vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go
  function init (line 42) | func init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp...
  function file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init (line 43) | func file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_in...

FILE: vendor/github.com/google/certificate-transparency-go/asn1/asn1.go
  type StructuralError (line 52) | type StructuralError struct
    method Error (line 57) | func (e StructuralError) Error() string {
  type SyntaxError (line 66) | type SyntaxError struct
    method Error (line 71) | func (e SyntaxError) Error() string {
  function parseBool (line 83) | func parseBool(bytes []byte, fieldName string) (ret bool, err error) {
  function checkInteger (line 108) | func checkInteger(bytes []byte, lax bool, fieldName string) error {
  function parseInt64 (line 126) | func parseInt64(bytes []byte, lax bool, fieldName string) (ret int64, er...
  function parseInt32 (line 149) | func parseInt32(bytes []byte, lax bool, fieldName string) (int32, error) {
  function parseBigInt (line 167) | func parseBigInt(bytes []byte, lax bool, fieldName string) (*big.Int, er...
  type BitString (line 192) | type BitString struct
    method At (line 199) | func (b BitString) At(i int) int {
    method RightAlign (line 210) | func (b BitString) RightAlign() []byte {
  function parseBitString (line 227) | func parseBitString(bytes []byte, fieldName string) (ret BitString, err ...
  type ObjectIdentifier (line 255) | type ObjectIdentifier
    method Equal (line 258) | func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
    method String (line 271) | func (oi ObjectIdentifier) String() string {
  function parseObjectIdentifier (line 287) | func parseObjectIdentifier(bytes []byte, lax bool, fieldName string) (s ...
  type Enumerated (line 331) | type Enumerated
  type Flag (line 336) | type Flag
  function parseBase128Int (line 340) | func parseBase128Int(bytes []byte, initOffset int, fieldName string) (re...
  function parseUTCTime (line 369) | func parseUTCTime(bytes []byte) (ret time.Time, err error) {
  function parseGeneralizedTime (line 397) | func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
  function parseNumericString (line 416) | func parseNumericString(bytes []byte, fieldName string) (ret string, err...
  function isNumeric (line 426) | func isNumeric(b byte) bool {
  function parsePrintableString (line 435) | func parsePrintableString(bytes []byte, lax bool, fieldName string) (ret...
  type asteriskFlag (line 461) | type asteriskFlag
  type ampersandFlag (line 462) | type ampersandFlag
  constant allowAsterisk (line 465) | allowAsterisk  asteriskFlag = true
  constant rejectAsterisk (line 466) | rejectAsterisk asteriskFlag = false
  constant allowAmpersand (line 468) | allowAmpersand  ampersandFlag = true
  constant rejectAmpersand (line 469) | rejectAmpersand ampersandFlag = false
  function isPrintable (line 475) | func isPrintable(b byte, asterisk asteriskFlag, ampersand ampersandFlag)...
  function parseIA5String (line 500) | func parseIA5String(bytes []byte, fieldName string) (ret string, err err...
  function parseT61String (line 515) | func parseT61String(bytes []byte) (ret string, err error) {
  function parseUTF8String (line 523) | func parseUTF8String(bytes []byte) (ret string, err error) {
  function parseBMPString (line 534) | func parseBMPString(bmpString []byte) (string, error) {
  type RawValue (line 554) | type RawValue struct
  type RawContent (line 564) | type RawContent
  function parseTagAndLength (line 572) | func parseTagAndLength(bytes []byte, initOffset int, fieldName string) (...
  function parseSequenceOf (line 650) | func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType refl...
  function invalidLength (line 713) | func invalidLength(offset, length, sliceLength int) bool {
  function couldBeISO8859_1 (line 721) | func couldBeISO8859_1(bytes []byte) bool {
  function couldBeT61 (line 734) | func couldBeT61(bytes []byte) bool {
  function iso8859_1ToUTF8 (line 754) | func iso8859_1ToUTF8(bytes []byte) string {
  function parseField (line 765) | func parseField(v reflect.Value, bytes []byte, initOffset int, params fi...
  function canHaveDefaultValue (line 1102) | func canHaveDefaultValue(k reflect.Kind) bool {
  function setDefaultValue (line 1114) | func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
  function Unmarshal (line 1182) | func Unmarshal(b []byte, val interface{}) (rest []byte, err error) {
  function UnmarshalWithParams (line 1188) | func UnmarshalWithParams(b []byte, val interface{}, params string) (rest...

FILE: vendor/github.com/google/certificate-transparency-go/asn1/common.go
  constant TagBoolean (line 23) | TagBoolean         = 1
  constant TagInteger (line 24) | TagInteger         = 2
  constant TagBitString (line 25) | TagBitString       = 3
  constant TagOctetString (line 26) | TagOctetString     = 4
  constant TagNull (line 27) | TagNull            = 5
  constant TagOID (line 28) | TagOID             = 6
  constant TagEnum (line 29) | TagEnum            = 10
  constant TagUTF8String (line 30) | TagUTF8String      = 12
  constant TagSequence (line 31) | TagSequence        = 16
  constant TagSet (line 32) | TagSet             = 17
  constant TagNumericString (line 33) | TagNumericString   = 18
  constant TagPrintableString (line 34) | TagPrintableString = 19
  constant TagT61String (line 35) | TagT61String       = 20
  constant TagIA5String (line 36) | TagIA5String       = 22
  constant TagUTCTime (line 37) | TagUTCTime         = 23
  constant TagGeneralizedTime (line 38) | TagGeneralizedTime = 24
  constant TagGeneralString (line 39) | TagGeneralString   = 27
  constant TagBMPString (line 40) | TagBMPString       = 30
  constant ClassUniversal (line 45) | ClassUniversal       = 0
  constant ClassApplication (line 46) | ClassApplication     = 1
  constant ClassContextSpecific (line 47) | ClassContextSpecific = 2
  constant ClassPrivate (line 48) | ClassPrivate         = 3
  type tagAndLength (line 51) | type tagAndLength struct
  type fieldParameters (line 75) | type fieldParameters struct
  function parseFieldParameters (line 96) | func parseFieldParameters(str string) (ret fieldParameters) {
  function getUniversalType (line 153) | func getUniversalType(t reflect.Type) (matchAny bool, tagNumber int, isC...

FILE: vendor/github.com/google/certificate-transparency-go/asn1/marshal.go
  type encoder (line 22) | type encoder interface
  type byteEncoder (line 29) | type byteEncoder
    method Len (line 31) | func (c byteEncoder) Len() int {
    method Encode (line 35) | func (c byteEncoder) Encode(dst []byte) {
  type bytesEncoder (line 39) | type bytesEncoder
    method Len (line 41) | func (b bytesEncoder) Len() int {
    method Encode (line 45) | func (b bytesEncoder) Encode(dst []byte) {
  type stringEncoder (line 51) | type stringEncoder
    method Len (line 53) | func (s stringEncoder) Len() int {
    method Encode (line 57) | func (s stringEncoder) Encode(dst []byte) {
  type multiEncoder (line 63) | type multiEncoder
    method Len (line 65) | func (m multiEncoder) Len() int {
    method Encode (line 73) | func (m multiEncoder) Encode(dst []byte) {
  type taggedEncoder (line 81) | type taggedEncoder struct
    method Len (line 89) | func (t *taggedEncoder) Len() int {
    method Encode (line 93) | func (t *taggedEncoder) Encode(dst []byte) {
  type int64Encoder (line 98) | type int64Encoder
    method Len (line 100) | func (i int64Encoder) Len() int {
    method Encode (line 116) | func (i int64Encoder) Encode(dst []byte) {
  function base128IntLength (line 124) | func base128IntLength(n int64) int {
  function appendBase128Int (line 137) | func appendBase128Int(dst []byte, n int64) []byte {
  function makeBigInt (line 153) | func makeBigInt(n *big.Int, fieldName string) (encoder, error) {
  function appendLength (line 187) | func appendLength(dst []byte, i int) []byte {
  function lengthLength (line 197) | func lengthLength(i int) (numBytes int) {
  function appendTagAndLength (line 206) | func appendTagAndLength(dst []byte, t tagAndLength) []byte {
  type bitStringEncoder (line 231) | type bitStringEncoder
    method Len (line 233) | func (b bitStringEncoder) Len() int {
    method Encode (line 237) | func (b bitStringEncoder) Encode(dst []byte) {
  type oidEncoder (line 244) | type oidEncoder
    method Len (line 246) | func (oid oidEncoder) Len() int {
    method Encode (line 254) | func (oid oidEncoder) Encode(dst []byte) {
  function makeObjectIdentifier (line 261) | func makeObjectIdentifier(oid []int, fieldName string) (e encoder, err e...
  function makePrintableString (line 269) | func makePrintableString(s, fieldName string) (e encoder, err error) {
  function makeIA5String (line 285) | func makeIA5String(s, fieldName string) (e encoder, err error) {
  function makeNumericString (line 295) | func makeNumericString(s string, fieldName string) (e encoder, err error) {
  function makeUTF8String (line 305) | func makeUTF8String(s string) encoder {
  function appendTwoDigits (line 309) | func appendTwoDigits(dst []byte, v int) []byte {
  function appendFourDigits (line 313) | func appendFourDigits(dst []byte, v int) []byte {
  function outsideUTCRange (line 322) | func outsideUTCRange(t time.Time) bool {
  function makeUTCTime (line 327) | func makeUTCTime(t time.Time, fieldName string) (e encoder, err error) {
  function makeGeneralizedTime (line 338) | func makeGeneralizedTime(t time.Time, fieldName string) (e encoder, err ...
  function appendUTCTime (line 349) | func appendUTCTime(dst []byte, t time.Time, fieldName string) (ret []byt...
  function appendGeneralizedTime (line 364) | func appendGeneralizedTime(dst []byte, t time.Time, fieldName string) (r...
  function appendTimeCommon (line 375) | func appendTimeCommon(dst []byte, t time.Time) []byte {
  function stripTagAndLength (line 409) | func stripTagAndLength(in []byte) []byte {
  function makeBody (line 417) | func makeBody(value reflect.Value, params fieldParameters) (e encoder, e...
  function makeField (line 532) | func makeField(v reflect.Value, params fieldParameters) (e encoder, err ...
  function Marshal (line 677) | func Marshal(val interface{}) ([]byte, error) {
  function MarshalWithParams (line 683) | func MarshalWithParams(val interface{}, params string) ([]byte, error) {

FILE: vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.pb.go
  constant _ (line 33) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 35) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type TemporalLogConfig (line 40) | type TemporalLogConfig struct
    method Reset (line 48) | func (x *TemporalLogConfig) Reset() {
    method String (line 57) | func (x *TemporalLogConfig) String() string {
    method ProtoMessage (line 61) | func (*TemporalLogConfig) ProtoMessage() {}
    method ProtoReflect (line 63) | func (x *TemporalLogConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 76) | func (*TemporalLogConfig) Descriptor() ([]byte, []int) {
    method GetShard (line 80) | func (x *TemporalLogConfig) GetShard() []*LogShardConfig {
  type LogShardConfig (line 89) | type LogShardConfig struct
    method Reset (line 107) | func (x *LogShardConfig) Reset() {
    method String (line 116) | func (x *LogShardConfig) String() string {
    method ProtoMessage (line 120) | func (*LogShardConfig) ProtoMessage() {}
    method ProtoReflect (line 122) | func (x *LogShardConfig) ProtoReflect() protoreflect.Message {
    method Descriptor (line 135) | func (*LogShardConfig) Descriptor() ([]byte, []int) {
    method GetUri (line 139) | func (x *LogShardConfig) GetUri() string {
    method GetPublicKeyDer (line 146) | func (x *LogShardConfig) GetPublicKeyDer() []byte {
    method GetNotAfterStart (line 153) | func (x *LogShardConfig) GetNotAfterStart() *timestamppb.Timestamp {
    method GetNotAfterLimit (line 160) | func (x *LogShardConfig) GetNotAfterLimit() *timestamppb.Timestamp {
  function file_client_configpb_multilog_proto_rawDescGZIP (line 205) | func file_client_configpb_multilog_proto_rawDescGZIP() []byte {
  function init (line 229) | func init() { file_client_configpb_multilog_proto_init() }
  function file_client_configpb_multilog_proto_init (line 230) | func file_client_configpb_multilog_proto_init() {

FILE: vendor/github.com/google/certificate-transparency-go/client/getentries.go
  method GetRawEntries (line 27) | func (c *LogClient) GetRawEntries(ctx context.Context, start, end int64)...
  method GetEntries (line 53) | func (c *LogClient) GetEntries(ctx context.Context, start, end int64) ([...

FILE: vendor/github.com/google/certificate-transparency-go/client/logclient.go
  type LogClient (line 33) | type LogClient struct
    method addChainWithRetry (line 65) | func (c *LogClient) addChainWithRetry(ctx context.Context, ctype ct.Lo...
    method AddChain (line 113) | func (c *LogClient) AddChain(ctx context.Context, chain []ct.ASN1Cert)...
    method AddPreChain (line 118) | func (c *LogClient) AddPreChain(ctx context.Context, chain []ct.ASN1Ce...
    method GetSTH (line 125) | func (c *LogClient) GetSTH(ctx context.Context) (*ct.SignedTreeHead, e...
    method VerifySTHSignature (line 145) | func (c *LogClient) VerifySTHSignature(sth ct.SignedTreeHead) error {
    method VerifySCTSignature (line 154) | func (c *LogClient) VerifySCTSignature(sct ct.SignedCertificateTimesta...
    method GetSTHConsistency (line 168) | func (c *LogClient) GetSTHConsistency(ctx context.Context, first, seco...
    method GetProofByHash (line 182) | func (c *LogClient) GetProofByHash(ctx context.Context, hash []byte, t...
    method GetAcceptedRoots (line 197) | func (c *LogClient) GetAcceptedRoots(ctx context.Context) ([]ct.ASN1Ce...
    method GetEntryAndProof (line 215) | func (c *LogClient) GetEntryAndProof(ctx context.Context, index, treeS...
  type CheckLogClient (line 38) | type CheckLogClient interface
  function New (line 51) | func New(uri string, hc *http.Client, opts jsonclient.Options) (*LogClie...

FILE: vendor/github.com/google/certificate-transparency-go/client/multilog.go
  type interval (line 34) | type interval struct
  function TemporalLogConfigFromFile (line 41) | func TemporalLogConfigFromFile(filename string) (*configpb.TemporalLogCo...
  type AddLogClient (line 67) | type AddLogClient interface
  type TemporalLogClient (line 74) | type TemporalLogClient struct
    method GetAcceptedRoots (line 128) | func (tlc *TemporalLogClient) GetAcceptedRoots(ctx context.Context) ([...
    method AddChain (line 162) | func (tlc *TemporalLogClient) AddChain(ctx context.Context, chain []ct...
    method AddPreChain (line 167) | func (tlc *TemporalLogClient) AddPreChain(ctx context.Context, chain [...
    method addChain (line 171) | func (tlc *TemporalLogClient) addChain(ctx context.Context, ctype ct.L...
    method IndexByDate (line 189) | func (tlc *TemporalLogClient) IndexByDate(when time.Time) (int, error) {
  function NewTemporalLogClient (line 81) | func NewTemporalLogClient(cfg *configpb.TemporalLogConfig, hc *http.Clie...
  function shardInterval (line 202) | func shardInterval(cfg *configpb.LogShardConfig) (interval, error) {

FILE: vendor/github.com/google/certificate-transparency-go/jsonclient/backoff.go
  type backoff (line 22) | type backoff struct
    method set (line 33) | func (b *backoff) set(override *time.Duration) time.Duration {
    method decreaseMultiplier (line 60) | func (b *backoff) decreaseMultiplier() {
    method until (line 68) | func (b *backoff) until() time.Time {
  constant maxMultiplier (line 30) | maxMultiplier = 8

FILE: vendor/github.com/google/certificate-transparency-go/jsonclient/client.go
  constant maxJitter (line 39) | maxJitter = 250 * time.Millisecond
  type backoffer (line 41) | type backoffer interface
  type JSONClient (line 56) | type JSONClient struct
    method BaseURI (line 161) | func (c *JSONClient) BaseURI() string {
    method GetAndParse (line 169) | func (c *JSONClient) GetAndParse(ctx context.Context, path string, par...
    method PostAndParse (line 215) | func (c *JSONClient) PostAndParse(ctx context.Context, path string, re...
    method waitForBackoff (line 260) | func (c *JSONClient) waitForBackoff(ctx context.Context) error {
    method PostAndParseWithRetry (line 277) | func (c *JSONClient) PostAndParseWithRetry(ctx context.Context, path s...
  type Logger (line 66) | type Logger interface
  type Options (line 72) | type Options struct
    method ParsePublicKey (line 87) | func (opts *Options) ParsePublicKey() (crypto.PublicKey, error) {
  type basicLogger (line 106) | type basicLogger struct
    method Printf (line 108) | func (bl *basicLogger) Printf(msg string, args ...interface{}) {
  type RspError (line 114) | type RspError struct
    method Error (line 121) | func (e RspError) Error() string {
  function New (line 128) | func New(uri string, hc *http.Client, opts Options) (*JSONClient, error) {

FILE: vendor/github.com/google/certificate-transparency-go/serialization.go
  function SerializeSCTSignatureInput (line 29) | func SerializeSCTSignatureInput(sct SignedCertificateTimestamp, entry Lo...
  function SerializeSTHSignatureInput (line 58) | func SerializeSTHSignatureInput(sth SignedTreeHead) ([]byte, error) {
  function CreateX509MerkleTreeLeaf (line 79) | func CreateX509MerkleTreeLeaf(cert ASN1Cert, timestamp uint64) *MerkleTr...
  function MerkleTreeLeafFromRawChain (line 92) | func MerkleTreeLeafFromRawChain(rawChain []ASN1Cert, etype LogEntryType,...
  function MerkleTreeLeafFromChain (line 110) | func MerkleTreeLeafFromChain(chain []*x509.Certificate, etype LogEntryTy...
  function MerkleTreeLeafForEmbeddedSCT (line 167) | func MerkleTreeLeafForEmbeddedSCT(chain []*x509.Certificate, timestamp u...
  function LeafHashForLeaf (line 199) | func LeafHashForLeaf(leaf *MerkleTreeLeaf) ([sha256.Size]byte, error) {
  function IsPreIssuer (line 212) | func IsPreIssuer(issuer *x509.Certificate) bool {
  function RawLogEntryFromLeaf (line 223) | func RawLogEntryFromLeaf(index int64, entry *LeafEntry) (*RawLogEntry, e...
  method ToLogEntry (line 266) | func (rle *RawLogEntry) ToLogEntry() (*LogEntry, error) {
  function LogEntryFromLeaf (line 303) | func LogEntryFromLeaf(index int64, leaf *LeafEntry) (*LogEntry, error) {
  function TimestampToTime (line 313) | func TimestampToTime(ts uint64) time.Time {

FILE: vendor/github.com/google/certificate-transparency-go/signatures.go
  function PublicKeyFromPEM (line 38) | func PublicKeyFromPEM(b []byte) (crypto.PublicKey, SHA256Hash, []byte, e...
  function PublicKeyFromB64 (line 48) | func PublicKeyFromB64(b64PubKey string) (crypto.PublicKey, error) {
  type SignatureVerifier (line 57) | type SignatureVerifier struct
    method VerifySignature (line 90) | func (s SignatureVerifier) VerifySignature(data []byte, sig tls.Digita...
    method VerifySCTSignature (line 95) | func (s SignatureVerifier) VerifySCTSignature(sct SignedCertificateTim...
    method VerifySTHSignature (line 104) | func (s SignatureVerifier) VerifySTHSignature(sth SignedTreeHead) error {
  function NewSignatureVerifier (line 62) | func NewSignatureVerifier(pk crypto.PublicKey) (*SignatureVerifier, erro...

FILE: vendor/github.com/google/certificate-transparency-go/tls/signature.go
  type dsaSig (line 35) | type dsaSig struct
  function generateHash (line 39) | func generateHash(algo HashAlgorithm, data []byte) ([]byte, crypto.Hash,...
  function VerifySignature (line 66) | func VerifySignature(pubKey crypto.PublicKey, data []byte, sig Digitally...
  function CreateSignature (line 127) | func CreateSignature(privKey crypto.PrivateKey, hashAlgo HashAlgorithm, ...

FILE: vendor/github.com/google/certificate-transparency-go/tls/tls.go
  type structuralError (line 35) | type structuralError struct
    method Error (line 40) | func (e structuralError) Error() string {
  type syntaxError (line 49) | type syntaxError struct
    method Error (line 54) | func (e syntaxError) Error() string {
  type Uint24 (line 63) | type Uint24
  type Enum (line 66) | type Enum
  function Unmarshal (line 146) | func Unmarshal(b []byte, val interface{}) ([]byte, error) {
  function UnmarshalWithParams (line 152) | func UnmarshalWithParams(b []byte, val interface{}, params string) ([]by...
  function byteCount (line 169) | func byteCount(x uint64) uint {
  type fieldInfo (line 190) | type fieldInfo struct
    method fieldName (line 200) | func (i *fieldInfo) fieldName() string {
    method check (line 277) | func (i fieldInfo) check(val uint64, fldName string) error {
  function fieldTagToFieldInfo (line 208) | func fieldTagToFieldInfo(str string, name string) (*fieldInfo, error) {
  function readVarUint (line 294) | func readVarUint(data []byte, info *fieldInfo) (uint64, error) {
  function parseField (line 314) | func parseField(v reflect.Value, data []byte, initOffset int, info *fiel...
  function Marshal (line 505) | func Marshal(val interface{}) ([]byte, error) {
  function MarshalWithParams (line 512) | func MarshalWithParams(val interface{}, params string) ([]byte, error) {
  function marshalField (line 525) | func marshalField(out *bytes.Buffer, v reflect.Value, info *fieldInfo) e...

FILE: vendor/github.com/google/certificate-transparency-go/tls/types.go
  type DigitallySigned (line 27) | type DigitallySigned struct
    method String (line 32) | func (d DigitallySigned) String() string {
  type SignatureAndHashAlgorithm (line 38) | type SignatureAndHashAlgorithm struct
  type HashAlgorithm (line 44) | type HashAlgorithm
    method String (line 57) | func (h HashAlgorithm) String() string {
  constant None (line 48) | None   HashAlgorithm = 0
  constant MD5 (line 49) | MD5    HashAlgorithm = 1
  constant SHA1 (line 50) | SHA1   HashAlgorithm = 2
  constant SHA224 (line 51) | SHA224 HashAlgorithm = 3
  constant SHA256 (line 52) | SHA256 HashAlgorithm = 4
  constant SHA384 (line 53) | SHA384 HashAlgorithm = 5
  constant SHA512 (line 54) | SHA512 HashAlgorithm = 6
  type SignatureAlgorithm (line 79) | type SignatureAlgorithm
    method String (line 89) | func (s SignatureAlgorithm) String() string {
  constant Anonymous (line 83) | Anonymous SignatureAlgorithm = 0
  constant RSA (line 84) | RSA       SignatureAlgorithm = 1
  constant DSA (line 85) | DSA       SignatureAlgorithm = 2
  constant ECDSA (line 86) | ECDSA     SignatureAlgorithm = 3
  function SignatureAlgorithmFromPubKey (line 106) | func SignatureAlgorithmFromPubKey(k crypto.PublicKey) SignatureAlgorithm {

FILE: vendor/github.com/google/certificate-transparency-go/types.go
  type LogEntryType (line 36) | type LogEntryType
    method String (line 44) | func (e LogEntryType) String() string {
  constant X509LogEntryType (line 40) | X509LogEntryType    LogEntryType = 0
  constant PrecertLogEntryType (line 41) | PrecertLogEntryType LogEntryType = 1
  constant TreeLeafPrefix (line 57) | TreeLeafPrefix = byte(0x00)
  constant TreeNodePrefix (line 58) | TreeNodePrefix = byte(0x01)
  type MerkleLeafType (line 64) | type MerkleLeafType
    method String (line 69) | func (m MerkleLeafType) String() string {
  constant TimestampedEntryLeafType (line 67) | TimestampedEntryLeafType MerkleLeafType = 0
  type Version (line 81) | type Version
    method String (line 88) | func (v Version) String() string {
  constant V1 (line 85) | V1 Version = 0
  type SignatureType (line 100) | type SignatureType
    method String (line 108) | func (st SignatureType) String() string {
  constant CertificateTimestampSignatureType (line 104) | CertificateTimestampSignatureType SignatureType = 0
  constant TreeHashSignatureType (line 105) | TreeHashSignatureType             SignatureType = 1
  type ASN1Cert (line 121) | type ASN1Cert struct
  type LogID (line 127) | type LogID struct
  type PreCert (line 132) | type PreCert struct
  type CTExtensions (line 140) | type CTExtensions
  type MerkleTreeNode (line 143) | type MerkleTreeNode
  type ConsistencyProof (line 147) | type ConsistencyProof
  type AuditPath (line 150) | type AuditPath
  type LeafInput (line 153) | type LeafInput
  type DigitallySigned (line 157) | type DigitallySigned
    method FromBase64String (line 161) | func (d *DigitallySigned) FromBase64String(b64 string) error {
    method Base64String (line 177) | func (d DigitallySigned) Base64String() (string, error) {
    method MarshalJSON (line 186) | func (d DigitallySigned) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 195) | func (d *DigitallySigned) UnmarshalJSON(b []byte) error {
  type RawLogEntry (line 204) | type RawLogEntry struct
  type LogEntry (line 225) | type LogEntry struct
  type PrecertChainEntry (line 240) | type PrecertChainEntry struct
  type CertificateChain (line 247) | type CertificateChain struct
  type JSONDataEntry (line 252) | type JSONDataEntry struct
  type SHA256Hash (line 257) | type SHA256Hash
    method FromBase64String (line 260) | func (s *SHA256Hash) FromBase64String(b64 string) error {
    method Base64String (line 273) | func (s SHA256Hash) Base64String() string {
    method MarshalJSON (line 278) | func (s SHA256Hash) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 283) | func (s *SHA256Hash) UnmarshalJSON(b []byte) error {
  type SignedTreeHead (line 293) | type SignedTreeHead struct
    method String (line 302) | func (s SignedTreeHead) String() string {
  type TreeHeadSignature (line 321) | type TreeHeadSignature struct
  type SignedCertificateTimestamp (line 332) | type SignedCertificateTimestamp struct
    method String (line 353) | func (s SignedCertificateTimestamp) String() string {
  type CertificateTimestamp (line 342) | type CertificateTimestamp struct
  type TimestampedEntry (line 362) | type TimestampedEntry struct
  type MerkleTreeLeaf (line 373) | type MerkleTreeLeaf struct
    method X509Certificate (line 394) | func (m *MerkleTreeLeaf) X509Certificate() (*x509.Certificate, error) {
    method Precertificate (line 407) | func (m *MerkleTreeLeaf) Precertificate() (*x509.Certificate, error) {
  type Precertificate (line 380) | type Precertificate struct
  type APIEndpoint (line 416) | type APIEndpoint
  constant AddChainStr (line 422) | AddChainStr          APIEndpoint = "add-chain"
  constant AddPreChainStr (line 423) | AddPreChainStr       APIEndpoint = "add-pre-chain"
  constant GetSTHStr (line 424) | GetSTHStr            APIEndpoint = "get-sth"
  constant GetEntriesStr (line 425) | GetEntriesStr        APIEndpoint = "get-entries"
  constant GetProofByHashStr (line 426) | GetProofByHashStr    APIEndpoint = "get-proof-by-hash"
  constant GetSTHConsistencyStr (line 427) | GetSTHConsistencyStr APIEndpoint = "get-sth-consistency"
  constant GetRootsStr (line 428) | GetRootsStr          APIEndpoint = "get-roots"
  constant GetEntryAndProofStr (line 429) | GetEntryAndProofStr  APIEndpoint = "get-entry-and-proof"
  constant AddChainPath (line 436) | AddChainPath          = "/ct/v1/add-chain"
  constant AddPreChainPath (line 437) | AddPreChainPath       = "/ct/v1/add-pre-chain"
  constant GetSTHPath (line 438) | GetSTHPath            = "/ct/v1/get-sth"
  constant GetEntriesPath (line 439) | GetEntriesPath        = "/ct/v1/get-entries"
  constant GetProofByHashPath (line 440) | GetProofByHashPath    = "/ct/v1/get-proof-by-hash"
  constant GetSTHConsistencyPath (line 441) | GetSTHConsistencyPath = "/ct/v1/get-sth-consistency"
  constant GetRootsPath (line 442) | GetRootsPath          = "/ct/v1/get-roots"
  constant GetEntryAndProofPath (line 443) | GetEntryAndProofPath  = "/ct/v1/get-entry-and-proof"
  constant AddJSONPath (line 445) | AddJSONPath = "/ct/v1/add-json"
  type AddChainRequest (line 450) | type AddChainRequest struct
  type AddChainResponse (line 458) | type AddChainResponse struct
    method ToSignedCertificateTimestamp (line 468) | func (r *AddChainResponse) ToSignedCertificateTimestamp() (*SignedCert...
  type AddJSONRequest (line 499) | type AddJSONRequest struct
  type GetSTHResponse (line 504) | type GetSTHResponse struct
    method ToSignedTreeHead (line 512) | func (r *GetSTHResponse) ToSignedTreeHead() (*SignedTreeHead, error) {
  type GetSTHConsistencyResponse (line 537) | type GetSTHConsistencyResponse struct
  type GetProofByHashResponse (line 544) | type GetProofByHashResponse struct
  type LeafEntry (line 551) | type LeafEntry struct
  type GetEntriesResponse (line 560) | type GetEntriesResponse struct
  type GetRootsResponse (line 565) | type GetRootsResponse struct
  type GetEntryAndProofResponse (line 572) | type GetEntryAndProofResponse struct

FILE: vendor/github.com/google/certificate-transparency-go/x509/cert_pool.go
  type CertPool (line 14) | type CertPool struct
    method copy (line 28) | func (s *CertPool) copy() *CertPool {
    method findPotentialParents (line 70) | func (s *CertPool) findPotentialParents(cert *Certificate) []int {
    method contains (line 85) | func (s *CertPool) contains(cert *Certificate) bool {
    method AddCert (line 101) | func (s *CertPool) AddCert(cert *Certificate) {
    method AppendCertsFromPEM (line 128) | func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
    method Subjects (line 153) | func (s *CertPool) Subjects() [][]byte {
  function NewCertPool (line 21) | func NewCertPool() *CertPool {
  function SystemCertPool (line 55) | func SystemCertPool() (*CertPool, error) {

FILE: vendor/github.com/google/certificate-transparency-go/x509/curves.go
  function initAllCurves (line 19) | func initAllCurves() {
  function initSECP192R1 (line 23) | func initSECP192R1() {
  function secp192r1 (line 34) | func secp192r1() elliptic.Curve {

FILE: vendor/github.com/google/certificate-transparency-go/x509/error.go
  type Error (line 11) | type Error struct
    method Error (line 22) | func (err Error) Error() string {
    method VerboseError (line 37) | func (err Error) VerboseError() string {
  type ErrCategory (line 80) | type ErrCategory
    method String (line 106) | func (category ErrCategory) String() string {
  constant UnknownCategory (line 84) | UnknownCategory ErrCategory = iota
  constant InvalidASN1Encoding (line 86) | InvalidASN1Encoding
  constant InvalidASN1Content (line 87) | InvalidASN1Content
  constant InvalidASN1DER (line 88) | InvalidASN1DER
  constant InvalidValueRange (line 90) | InvalidValueRange
  constant InvalidASN1Type (line 91) | InvalidASN1Type
  constant UnexpectedAdditionalData (line 92) | UnexpectedAdditionalData
  constant PoorlyFormedCertificate (line 94) | PoorlyFormedCertificate
  constant MalformedCertificate (line 95) | MalformedCertificate
  constant PoorlyFormedCRL (line 96) | PoorlyFormedCRL
  constant MalformedCRL (line 97) | MalformedCRL
  constant BaselineRequirementsFailure (line 99) | BaselineRequirementsFailure
  constant EVRequirementsFailure (line 100) | EVRequirementsFailure
  constant InsecureAlgorithm (line 102) | InsecureAlgorithm
  constant UnrecognizedValue (line 103) | UnrecognizedValue
  type ErrorID (line 142) | type ErrorID
  type Errors (line 145) | type Errors struct
    method Error (line 150) | func (e *Errors) Error() string {
    method VerboseError (line 155) | func (e *Errors) VerboseError() string {
    method Fatal (line 160) | func (e *Errors) Fatal() bool {
    method Empty (line 165) | func (e *Errors) Empty() bool {
    method FirstFatal (line 174) | func (e *Errors) FirstFatal() error {
    method AddID (line 188) | func (e *Errors) AddID(id ErrorID, args ...interface{}) {
    method combineErrors (line 192) | func (e Errors) combineErrors(errfn func(Error) string) string {
    method Filter (line 210) | func (e Errors) Filter(filtered []ErrorID) Errors {
  function ErrorFilter (line 225) | func ErrorFilter(ignore string) []ErrorID {

FILE: vendor/github.com/google/certificate-transparency-go/x509/errors.go
  constant ErrInvalidID (line 7) | ErrInvalidID ErrorID = iota
  constant ErrInvalidCertList (line 8) | ErrInvalidCertList
  constant ErrTrailingCertList (line 9) | ErrTrailingCertList
  constant ErrUnexpectedlyCriticalCertListExtension (line 10) | ErrUnexpectedlyCriticalCertListExtension
  constant ErrUnexpectedlyNonCriticalCertListExtension (line 11) | ErrUnexpectedlyNonCriticalCertListExtension
  constant ErrInvalidCertListAuthKeyID (line 12) | ErrInvalidCertListAuthKeyID
  constant ErrTrailingCertListAuthKeyID (line 13) | ErrTrailingCertListAuthKeyID
  constant ErrInvalidCertListIssuerAltName (line 14) | ErrInvalidCertListIssuerAltName
  constant ErrInvalidCertListCRLNumber (line 15) | ErrInvalidCertListCRLNumber
  constant ErrTrailingCertListCRLNumber (line 16) | ErrTrailingCertListCRLNumber
  constant ErrNegativeCertListCRLNumber (line 17) | ErrNegativeCertListCRLNumber
  constant ErrInvalidCertListDeltaCRL (line 18) | ErrInvalidCertListDeltaCRL
  constant ErrTrailingCertListDeltaCRL (line 19) | ErrTrailingCertListDeltaCRL
  constant ErrNegativeCertListDeltaCRL (line 20) | ErrNegativeCertListDeltaCRL
  constant ErrInvalidCertListIssuingDP (line 21) | ErrInvalidCertListIssuingDP
  constant ErrTrailingCertListIssuingDP (line 22) | ErrTrailingCertListIssuingDP
  constant ErrCertListIssuingDPMultipleTypes (line 23) | ErrCertListIssuingDPMultipleTypes
  constant ErrCertListIssuingDPInvalidFullName (line 24) | ErrCertListIssuingDPInvalidFullName
  constant ErrInvalidCertListFreshestCRL (line 25) | ErrInvalidCertListFreshestCRL
  constant ErrInvalidCertListAuthInfoAccess (line 26) | ErrInvalidCertListAuthInfoAccess
  constant ErrTrailingCertListAuthInfoAccess (line 27) | ErrTrailingCertListAuthInfoAccess
  constant ErrUnhandledCriticalCertListExtension (line 28) | ErrUnhandledCriticalCertListExtension
  constant ErrUnexpectedlyCriticalRevokedCertExtension (line 29) | ErrUnexpectedlyCriticalRevokedCertExtension
  constant ErrUnexpectedlyNonCriticalRevokedCertExtension (line 30) | ErrUnexpectedlyNonCriticalRevokedCertExtension
  constant ErrInvalidRevocationReason (line 31) | ErrInvalidRevocationReason
  constant ErrTrailingRevocationReason (line 32) | ErrTrailingRevocationReason
  constant ErrInvalidRevocationInvalidityDate (line 33) | ErrInvalidRevocationInvalidityDate
  constant ErrTrailingRevocationInvalidityDate (line 34) | ErrTrailingRevocationInvalidityDate
  constant ErrInvalidRevocationIssuer (line 35) | ErrInvalidRevocationIssuer
  constant ErrUnhandledCriticalRevokedCertExtension (line 36) | ErrUnhandledCriticalRevokedCertExtension
  constant ErrMaxID (line 38) | ErrMaxID
  function init (line 283) | func init() {
  function NewError (line 291) | func NewError(id ErrorID, args ...interface{}) Error {

FILE: vendor/github.com/google/certificate-transparency-go/x509/names.go
  constant tagOtherName (line 17) | tagOtherName     = 0
  constant tagRFC822Name (line 18) | tagRFC822Name    = 1
  constant tagDNSName (line 19) | tagDNSName       = 2
  constant tagX400Address (line 20) | tagX400Address   = 3
  constant tagDirectoryName (line 21) | tagDirectoryName = 4
  constant tagEDIPartyName (line 22) | tagEDIPartyName  = 5
  constant tagURI (line 23) | tagURI           = 6
  constant tagIPAddress (line 24) | tagIPAddress     = 7
  constant tagRegisteredID (line 25) | tagRegisteredID  = 8
  type OtherName (line 34) | type OtherName struct
  type GeneralNames (line 40) | type GeneralNames struct
    method Len (line 51) | func (gn GeneralNames) Len() int {
    method Empty (line 57) | func (gn GeneralNames) Empty() bool {
  function parseGeneralNames (line 61) | func parseGeneralNames(value []byte, gname *GeneralNames) error {
  function parseGeneralName (line 97) | func parseGeneralName(data []byte, gname *GeneralNames, withMask bool) (...

FILE: vendor/github.com/google/certificate-transparency-go/x509/pem_decrypt.go
  type PEMCipher (line 23) | type PEMCipher
  constant _ (line 27) | _ PEMCipher = iota
  constant PEMCipherDES (line 28) | PEMCipherDES
  constant PEMCipher3DES (line 29) | PEMCipher3DES
  constant PEMCipherAES128 (line 30) | PEMCipherAES128
  constant PEMCipherAES192 (line 31) | PEMCipherAES192
  constant PEMCipherAES256 (line 32) | PEMCipherAES256
  type rfc1423Algo (line 36) | type rfc1423Algo struct
    method deriveKey (line 82) | func (c rfc1423Algo) deriveKey(password, salt []byte) []byte {
  function IsEncryptedPEMBlock (line 99) | func IsEncryptedPEMBlock(b *pem.Block) bool {
  function DecryptPEMBlock (line 115) | func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) {
  function EncryptPEMBlock (line 183) | func EncryptPEMBlock(rand io.Reader, blockType string, data, password []...
  function cipherByName (line 222) | func cipherByName(name string) *rfc1423Algo {
  function cipherByKey (line 232) | func cipherByKey(key PEMCipher) *rfc1423Algo {

FILE: vendor/github.com/google/certificate-transparency-go/x509/pkcs1.go
  type pkcs1PrivateKey (line 16) | type pkcs1PrivateKey struct
  type pkcs1AdditionalRSAPrime (line 31) | type pkcs1AdditionalRSAPrime struct
  type pkcs1PublicKey (line 40) | type pkcs1PublicKey struct
  function ParsePKCS1PrivateKey (line 48) | func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
  function MarshalPKCS1PrivateKey (line 105) | func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte {
  function ParsePKCS1PublicKey (line 139) | func ParsePKCS1PublicKey(der []byte) (*rsa.PublicKey, error) {
  function MarshalPKCS1PublicKey (line 168) | func MarshalPKCS1PublicKey(key *rsa.PublicKey) []byte {

FILE: vendor/github.com/google/certificate-transparency-go/x509/pkcs8.go
  type pkcs8 (line 23) | type pkcs8 struct
  function ParsePKCS8PrivateKey (line 36) | func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
  function MarshalPKCS8PrivateKey (line 91) | func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) {

FILE: vendor/github.com/google/certificate-transparency-go/x509/pkix/pkix.go
  type AlgorithmIdentifier (line 20) | type AlgorithmIdentifier struct
  type RDNSequence (line 25) | type RDNSequence
    method String (line 41) | func (r RDNSequence) String() string {
  type RelativeDistinguishedNameSET (line 96) | type RelativeDistinguishedNameSET
  type AttributeTypeAndValue (line 100) | type AttributeTypeAndValue struct
  type AttributeTypeAndValueSET (line 107) | type AttributeTypeAndValueSET struct
  type Extension (line 114) | type Extension struct
  type Name (line 124) | type Name struct
    method FillFromRDNSequence (line 134) | func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
    method appendRDNs (line 200) | func (n Name) appendRDNs(in RDNSequence, values []string, oid asn1.Obj...
    method ToRDNSequence (line 214) | func (n Name) ToRDNSequence() (ret RDNSequence) {
    method String (line 237) | func (n Name) String() string {
  function oidInAttributeTypeAndValue (line 243) | func oidInAttributeTypeAndValue(oid asn1.ObjectIdentifier, atv []Attribu...
  type CertificateList (line 255) | type CertificateList struct
    method HasExpired (line 262) | func (certList *CertificateList) HasExpired(now time.Time) bool {
  type TBSCertificateList (line 268) | type TBSCertificateList struct
  type RevokedCertificate (line 282) | type RevokedCertificate struct

FILE: vendor/github.com/google/certificate-transparency-go/x509/ptr_sysptr_windows.go
  function convertToPolicyParaType (line 19) | func convertToPolicyParaType(p unsafe.Pointer) syscall.Pointer {

FILE: vendor/github.com/google/certificate-transparency-go/x509/ptr_uint_windows.go
  function convertToPolicyParaType (line 16) | func convertToPolicyParaType(p unsafe.Pointer) uintptr {

FILE: vendor/github.com/google/certificate-transparency-go/x509/revoked.go
  type RevocationReasonCode (line 32) | type RevocationReasonCode
  type ReasonFlag (line 49) | type ReasonFlag
  constant UnusedFlag (line 53) | UnusedFlag ReasonFlag = 1 << iota
  constant KeyCompromiseFlag (line 54) | KeyCompromiseFlag
  constant CACompromiseFlag (line 55) | CACompromiseFlag
  constant AffiliationChangedFlag (line 56) | AffiliationChangedFlag
  constant SupersededFlag (line 57) | SupersededFlag
  constant CessationOfOperationFlag (line 58) | CessationOfOperationFlag
  constant CertificateHoldFlag (line 59) | CertificateHoldFlag
  constant PrivilegeWithdrawnFlag (line 60) | PrivilegeWithdrawnFlag
  constant AACompromiseFlag (line 61) | AACompromiseFlag
  type CertificateList (line 67) | type CertificateList struct
    method ExpiredAt (line 75) | func (certList *CertificateList) ExpiredAt(now time.Time) bool {
  type IssuingDistributionPoint (line 101) | type IssuingDistributionPoint struct
  type TBSCertList (line 113) | type TBSCertList struct
  function ParseCertificateList (line 138) | func ParseCertificateList(clBytes []byte) (*CertificateList, error) {
  function ParseCertificateListDER (line 151) | func ParseCertificateListDER(derBytes []byte) (*CertificateList, error) {
  function parseIssuingDistributionPoint (line 280) | func parseIssuingDistributionPoint(data []byte, idp *IssuingDistribution...
  type RevokedCertificate (line 312) | type RevokedCertificate struct
  function parseRevokedCertificate (line 320) | func parseRevokedCertificate(pkixRevoked pkix.RevokedCertificate, errs *...
  method CheckCertificateListSignature (line 362) | func (c *Certificate) CheckCertificateListSignature(crl *CertificateList...

FILE: vendor/github.com/google/certificate-transparency-go/x509/root.go
  function systemRootsPool (line 15) | func systemRootsPool() *CertPool {
  function initSystemRoots (line 20) | func initSystemRoots() {

FILE: vendor/github.com/google/certificate-transparency-go/x509/root_cgo_darwin.go
  function loadSystemRoots (line 287) | func loadSystemRoots() (*CertPool, error) {

FILE: vendor/github.com/google/certificate-transparency-go/x509/root_darwin.go
  method systemVerify (line 26) | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Cer...
  function execSecurityRoots (line 55) | func execSecurityRoots() (*CertPool, error) {
  function forEachCertInKeychains (line 157) | func forEachCertInKeychains(paths []string, f func(*Certificate)) error {
  function verifyCertWithSystem (line 182) | func verifyCertWithSystem(cert *Certificate) bool {
  function getCertsWithTrustPolicy (line 224) | func getCertsWithTrustPolicy() (map[string]bool, error) {

FILE: vendor/github.com/google/certificate-transparency-go/x509/root_darwin_armx.go
  function loadSystemRoots (line 14) | func loadSystemRoots() (*CertPool, error) {
  constant systemRootsPEM (line 20) | systemRootsPEM = `

FILE: vendor/github.com/google/certificate-transparency-go/x509/root_js.go
  function loadSystemRoots (line 13) | func loadSystemRoots() (*CertPool, error) {
  method systemVerify (line 17) | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Cer...

FILE: vendor/github.com/google/certificate-transparency-go/x509/root_nocgo_darwin.go
  function loadSystemRoots (line 10) | func loadSystemRoots() (*CertPool, error) {

FILE: vendor/github.com/google/certificate-transparency-go/x509/root_plan9.go
  method systemVerify (line 19) | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Cer...
  function loadSystemRoots (line 23) | func loadSystemRoots() (*CertPool, error) {

FILE: vendor/github.com/google/certificate-transparency-go/x509/root_unix.go
  constant certFileEnv (line 27) | certFileEnv = "SSL_CERT_FILE"
  constant certDirEnv (line 31) | certDirEnv = "SSL_CERT_DIR"
  method systemVerify (line 34) | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Cer...
  function loadSystemRoots (line 38) | func loadSystemRoots() (*CertPool, error) {

FILE: vendor/github.com/google/certificate-transparency-go/x509/root_windows.go
  function createStoreContext (line 20) | func createStoreContext(leaf *Certificate, opts *VerifyOptions) (*syscal...
  function extractSimpleChain (line 59) | func extractSimpleChain(simpleChain **syscall.CertSimpleChain, count int...
  function checkChainTrustStatus (line 85) | func checkChainTrustStatus(c *Certificate, chainCtx *syscall.CertChainCo...
  function checkChainSSLServerPolicy (line 100) | func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertCha...
  method systemVerify (line 143) | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Cer...
  function loadSystemRoots (line 244) | func loadSystemRoots() (*CertPool, error) {

FILE: vendor/github.com/google/certificate-transparency-go/x509/rpki.go
  type IPAddressPrefix (line 18) | type IPAddressPrefix
  type IPAddressRange (line 21) | type IPAddressRange struct
  constant IPv4AddressFamilyIndicator (line 29) | IPv4AddressFamilyIndicator = uint16(1)
  constant IPv6AddressFamilyIndicator (line 30) | IPv6AddressFamilyIndicator = uint16(2)
  type IPAddressFamilyBlocks (line 34) | type IPAddressFamilyBlocks struct
  type ipAddressFamily (line 51) | type ipAddressFamily struct
  type ipAddressRange (line 58) | type ipAddressRange struct
  function parseRPKIAddrBlocks (line 63) | func parseRPKIAddrBlocks(data []byte, nfe *NonFatalErrors) []*IPAddressF...
  type ASIDRange (line 150) | type ASIDRange struct
  type ASIdentifiers (line 157) | type ASIdentifiers struct
  type asIdentifiers (line 167) | type asIdentifiers struct
  function parseASIDChoice (line 172) | func parseASIDChoice(val asn1.RawValue, nfe *NonFatalErrors) *ASIdentifi...
  function parseRPKIASIdentifiers (line 228) | func parseRPKIASIdentifiers(data []byte, nfe *NonFatalErrors) (*ASIdenti...

FILE: vendor/github.com/google/certificate-transparency-go/x509/sec1.go
  constant ecPrivKeyVersion (line 17) | ecPrivKeyVersion = 1
  type ecPrivateKey (line 27) | type ecPrivateKey struct
  function ParseECPrivateKey (line 37) | func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) {
  function MarshalECPrivateKey (line 46) | func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
  function marshalECPrivateKeyWithOID (line 57) | func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectId...
  function parseECPrivateKey (line 74) | func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte)...

FILE: vendor/github.com/google/certificate-transparency-go/x509/verify.go
  type InvalidReason (line 24) | type InvalidReason
  constant NotAuthorizedToSign (line 29) | NotAuthorizedToSign InvalidReason = iota
  constant Expired (line 32) | Expired
  constant CANotAuthorizedForThisName (line 36) | CANotAuthorizedForThisName
  constant TooManyIntermediates (line 39) | TooManyIntermediates
  constant IncompatibleUsage (line 42) | IncompatibleUsage
  constant NameMismatch (line 45) | NameMismatch
  constant NameConstraintsWithoutSANs (line 54) | NameConstraintsWithoutSANs
  constant UnconstrainedName (line 58) | UnconstrainedName
  constant TooManyConstraints (line 64) | TooManyConstraints
  constant CANotAuthorizedForExtKeyUsage (line 67) | CANotAuthorizedForExtKeyUsage
  type CertificateInvalidError (line 72) | type CertificateInvalidError struct
    method Error (line 78) | func (e CertificateInvalidError) Error() string {
  type HostnameError (line 104) | type HostnameError struct
    method Error (line 109) | func (h HostnameError) Error() string {
  type UnknownAuthorityError (line 145) | type UnknownAuthorityError struct
    method Error (line 155) | func (e UnknownAuthorityError) Error() string {
  type SystemRootsError (line 172) | type SystemRootsError struct
    method Error (line 176) | func (se SystemRootsError) Error() string {
  type VerifyOptions (line 190) | type VerifyOptions struct
  constant leafCertificate (line 219) | leafCertificate = iota
  constant intermediateCertificate (line 220) | intermediateCertificate
  constant rootCertificate (line 221) | rootCertificate
  type rfc2821Mailbox (line 227) | type rfc2821Mailbox struct
  function parseRFC2821Mailbox (line 235) | func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
  function domainToReverseLabels (line 373) | func domainToReverseLabels(domain string) (reverseLabels []string, ok bo...
  function matchEmailConstraint (line 406) | func matchEmailConstraint(mailbox rfc2821Mailbox, constraint string) (bo...
  function matchURIConstraint (line 422) | func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
  function matchIPConstraint (line 452) | func matchIPConstraint(ip net.IP, constraint *net.IPNet) (bool, error) {
  function matchDomainConstraint (line 466) | func matchDomainConstraint(domain, constraint string) (bool, error) {
  method checkNameConstraints (line 513) | func (c *Certificate) checkNameConstraints(count *int,
  method isValid (line 570) | func (c *Certificate) isValid(certType int, currentChain []*Certificate,...
  method Verify (line 743) | func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificat...
  function appendToFreshChain (line 815) | func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Cert...
  constant maxChainSignatureChecks (line 826) | maxChainSignatureChecks = 100
  method buildChains (line 828) | func (c *Certificate) buildChains(cache map[*Certificate][][]*Certificat...
  function validHostname (line 899) | func validHostname(host string) bool {
  method commonNameAsHostname (line 950) | func (c *Certificate) commonNameAsHostname() bool {
  function matchHostnames (line 954) | func matchHostnames(pattern, host string) bool {
  function toLowerCaseASCII (line 984) | func toLowerCaseASCII(in string) string {
  method VerifyHostname (line 1015) | func (c *Certificate) VerifyHostname(h string) error {
  function checkChainForKeyUsage (line 1049) | func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage...

FILE: vendor/github.com/google/certificate-transparency-go/x509/x509.go
  type pkixPublicKey (line 83) | type pkixPublicKey struct
  function ParsePKIXPublicKey (line 94) | func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) {
  function marshalPublicKey (line 117) | func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKey...
  function MarshalPKIXPublicKey (line 160) | func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) {
  type certificate (line 183) | type certificate struct
  type tbsCertificate (line 190) | type tbsCertificate struct
  type rsaesoaepAlgorithmParameters (line 207) | type rsaesoaepAlgorithmParameters struct
  type dsaAlgorithmParameters (line 213) | type dsaAlgorithmParameters struct
  type dsaSignature (line 217) | type dsaSignature struct
  type ecdsaSignature (line 221) | type ecdsaSignature
  type validity (line 223) | type validity struct
  type publicKeyInfo (line 227) | type publicKeyInfo struct
  type authKeyId (line 234) | type authKeyId struct
  type SignatureAlgorithm (line 239) | type SignatureAlgorithm
    method isRSAPSS (line 295) | func (algo SignatureAlgorithm) isRSAPSS() bool {
    method String (line 304) | func (algo SignatureAlgorithm) String() string {
  constant UnknownSignatureAlgorithm (line 243) | UnknownSignatureAlgorithm SignatureAlgorithm = iota
  constant MD2WithRSA (line 244) | MD2WithRSA
  constant MD5WithRSA (line 245) | MD5WithRSA
  constant SHA1WithRSA (line 246) | SHA1WithRSA
  constant SHA256WithRSA (line 247) | SHA256WithRSA
  constant SHA384WithRSA (line 248) | SHA384WithRSA
  constant SHA512WithRSA (line 249) | SHA512WithRSA
  constant DSAWithSHA1 (line 250) | DSAWithSHA1
  constant DSAWithSHA256 (line 251) | DSAWithSHA256
  constant ECDSAWithSHA1 (line 252) | ECDSAWithSHA1
  constant ECDSAWithSHA256 (line 253) | ECDSAWithSHA256
  constant ECDSAWithSHA384 (line 254) | ECDSAWithSHA384
  constant ECDSAWithSHA512 (line 255) | ECDSAWithSHA512
  constant SHA256WithRSAPSS (line 256) | SHA256WithRSAPSS
  constant SHA384WithRSAPSS (line 257) | SHA384WithRSAPSS
  constant SHA512WithRSAPSS (line 258) | SHA512WithRSAPSS
  constant PureEd25519 (line 259) | PureEd25519
  type PublicKeyAlgorithm (line 314) | type PublicKeyAlgorithm
    method String (line 334) | func (algo PublicKeyAlgorithm) String() string {
  constant UnknownPublicKeyAlgorithm (line 318) | UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
  constant RSA (line 319) | RSA
  constant DSA (line 320) | DSA
  constant ECDSA (line 321) | ECDSA
  constant Ed25519 (line 322) | Ed25519
  constant RSAESOAEP (line 323) | RSAESOAEP
  type pssParameters (line 453) | type pssParameters struct
  function rsaPSSParameters (line 465) | func rsaPSSParameters(hashFunc crypto.Hash) asn1.RawValue {
  function SignatureAlgorithmFromAI (line 510) | func SignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgo...
  function getPublicKeyAlgorithmFromOID (line 591) | func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAl...
  function namedCurveFromOID (line 636) | func namedCurveFromOID(oid asn1.ObjectIdentifier, nfe *NonFatalErrors) e...
  function OIDFromNamedCurve (line 655) | func OIDFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, boo...
  type KeyUsage (line 674) | type KeyUsage
  constant KeyUsageDigitalSignature (line 678) | KeyUsageDigitalSignature KeyUsage = 1 << iota
  constant KeyUsageContentCommitment (line 679) | KeyUsageContentCommitment
  constant KeyUsageKeyEncipherment (line 680) | KeyUsageKeyEncipherment
  constant KeyUsageDataEncipherment (line 681) | KeyUsageDataEncipherment
  constant KeyUsageKeyAgreement (line 682) | KeyUsageKeyAgreement
  constant KeyUsageCertSign (line 683) | KeyUsageCertSign
  constant KeyUsageCRLSign (line 684) | KeyUsageCRLSign
  constant KeyUsageEncipherOnly (line 685) | KeyUsageEncipherOnly
  constant KeyUsageDecipherOnly (line 686) | KeyUsageDecipherOnly
  type ExtKeyUsage (line 722) | type ExtKeyUsage
  constant ExtKeyUsageAny (line 726) | ExtKeyUsageAny ExtKeyUsage = iota
  constant ExtKeyUsageServerAuth (line 727) | ExtKeyUsageServerAuth
  constant ExtKeyUsageClientAuth (line 728) | ExtKeyUsageClientAuth
  constant ExtKeyUsageCodeSigning (line 729) | ExtKeyUsageCodeSigning
  constant ExtKeyUsageEmailProtection (line 730) | ExtKeyUsageEmailProtection
  constant ExtKeyUsageIPSECEndSystem (line 731) | ExtKeyUsageIPSECEndSystem
  constant ExtKeyUsageIPSECTunnel (line 732) | ExtKeyUsageIPSECTunnel
  constant ExtKeyUsageIPSECUser (line 733) | ExtKeyUsageIPSECUser
  constant ExtKeyUsageTimeStamping (line 734) | ExtKeyUsageTimeStamping
  constant ExtKeyUsageOCSPSigning (line 735) | ExtKeyUsageOCSPSigning
  constant ExtKeyUsageMicrosoftServerGatedCrypto (line 736) | ExtKeyUsageMicrosoftServerGatedCrypto
  constant ExtKeyUsageNetscapeServerGatedCrypto (line 737) | ExtKeyUsageNetscapeServerGatedCrypto
  constant ExtKeyUsageMicrosoftCommercialCodeSigning (line 738) | ExtKeyUsageMicrosoftCommercialCodeSigning
  constant ExtKeyUsageMicrosoftKernelCodeSigning (line 739) | ExtKeyUsageMicrosoftKernelCodeSigning
  constant ExtKeyUsageCertificateTransparency (line 740) | ExtKeyUsageCertificateTransparency
  function extKeyUsageFromOID (line 765) | func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok ...
  function oidFromExtKeyUsage (line 774) | func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok ...
  type SerializedSCT (line 784) | type SerializedSCT struct
  type SignedCertificateTimestampList (line 789) | type SignedCertificateTimestampList struct
  type Certificate (line 794) | type Certificate struct
    method Equal (line 930) | func (c *Certificate) Equal(other *Certificate) bool {
    method IsPrecertificate (line 939) | func (c *Certificate) IsPrecertificate() bool {
    method hasSANExtension (line 951) | func (c *Certificate) hasSANExtension() bool {
    method CheckSignatureFrom (line 1006) | func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
    method CheckSignature (line 1034) | func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, ...
    method hasNameConstraints (line 1038) | func (c *Certificate) hasNameConstraints() bool {
    method getSANExtension (line 1042) | func (c *Certificate) getSANExtension() []byte {
    method CheckCRLSignature (line 1147) | func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) err...
    method CreateCRL (line 2840) | func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revo...
  type InsecureAlgorithmError (line 913) | type InsecureAlgorithmError
    method Error (line 915) | func (e InsecureAlgorithmError) Error() string {
  type ConstraintViolationError (line 922) | type ConstraintViolationError struct
    method Error (line 924) | func (ConstraintViolationError) Error() string {
  function signaturePublicKeyAlgoMismatchError (line 1052) | func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlg...
  function checkSignature (line 1058) | func checkSignature(algo SignatureAlgorithm, signed, signature []byte, p...
  type UnhandledCriticalExtension (line 1154) | type UnhandledCriticalExtension struct
    method Error (line 1158) | func (h UnhandledCriticalExtension) Error() string {
  function removeExtension (line 1166) | func removeExtension(tbsData []byte, oid asn1.ObjectIdentifier) ([]byte,...
  function RemoveSCTList (line 1202) | func RemoveSCTList(tbsData []byte) ([]byte, error) {
  function RemoveCTPoison (line 1210) | func RemoveCTPoison(tbsData []byte) ([]byte, error) {
  function BuildPrecertTBS (line 1229) | func BuildPrecertTBS(tbsData []byte, preIssuer *Certificate) ([]byte, er...
  type basicConstraints (line 1307) | type basicConstraints struct
  type policyInformation (line 1313) | type policyInformation struct
  constant nameTypeEmail (line 1319) | nameTypeEmail = 1
  constant nameTypeDNS (line 1320) | nameTypeDNS   = 2
  constant nameTypeURI (line 1321) | nameTypeURI   = 6
  constant nameTypeIP (line 1322) | nameTypeIP    = 7
  type accessDescription (line 1326) | type accessDescription struct
  type distributionPoint (line 1332) | type distributionPoint struct
  type distributionPointName (line 1338) | type distributionPointName struct
  function parsePublicKey (line 1343) | func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo, nfe...
  type NonFatalErrors (line 1465) | type NonFatalErrors struct
    method AddError (line 1470) | func (e *NonFatalErrors) AddError(err error) {
    method Error (line 1476) | func (e NonFatalErrors) Error() string {
    method HasError (line 1485) | func (e *NonFatalErrors) HasError() bool {
    method Append (line 1493) | func (e *NonFatalErrors) Append(more *NonFatalErrors) *NonFatalErrors {
  function IsFatal (line 1507) | func IsFatal(err error) bool {
  function parseDistributionPoints (line 1520) | func parseDistributionPoints(data []byte, crldp *[]string) error {
  function forEachSAN (line 1554) | func forEachSAN(extension []byte, callback func(tag int, data []byte) er...
  function parseSANExtension (line 1598) | func parseSANExtension(value []byte, nfe *NonFatalErrors) (dnsNames, ema...
  function isValidIPMask (line 1632) | func isValidIPMask(mask []byte) bool {
  function parseNameConstraintsExtension (line 1656) | func parseNameConstraintsExtension(out *Certificate, e pkix.Extension, n...
  function parseCertificate (line 1816) | func parseCertificate(in *certificate) (*Certificate, error) {
  function ParseTBSCertificate (line 2081) | func ParseTBSCertificate(asn1Data []byte) (*Certificate, error) {
  function ParseCertificate (line 2115) | func ParseCertificate(asn1Data []byte) (*Certificate, error) {
  function ParseCertificates (line 2148) | func ParseCertificates(asn1Data []byte) ([]*Certificate, error) {
  function reverseBitsInAByte (line 2186) | func reverseBitsInAByte(in byte) byte {
  function asn1BitLength (line 2196) | func asn1BitLength(bitString []byte) int {
  function oidInExtensions (line 2255) | func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extens...
  function marshalSANs (line 2266) | func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP...
  function isIA5String (line 2288) | func isIA5String(s string) error {
  function buildExtensions (line 2298) | func buildExtensions(template *Certificate, subjectIsEmpty bool, authori...
  function subjectBytes (line 2599) | func subjectBytes(cert *Certificate) ([]byte, error) {
  function signingParamsForPublicKey (line 2610) | func signingParamsForPublicKey(pub interface{}, requestedSigAlgo Signatu...
  function CreateCertificate (line 2719) | func CreateCertificate(rand io.Reader, template, parent *Certificate, pu...
  function ParseCRL (line 2817) | func ParseCRL(crlBytes []byte) (*pkix.CertificateList, error) {
  function ParseDERCRL (line 2828) | func ParseDERCRL(derBytes []byte) (*pkix.CertificateList, error) {
  type CertificateRequest (line 2904) | type CertificateRequest struct
    method CheckSignature (line 3289) | func (c *CertificateRequest) CheckSignature() error {
  type tbsCertificateRequest (line 2950) | type tbsCertificateRequest struct
  type certificateRequest (line 2958) | type certificateRequest struct
  function newRawAttributes (line 2971) | func newRawAttributes(attributes []pkix.AttributeTypeAndValueSET) ([]asn...
  function parseRawAttributes (line 2988) | func parseRawAttributes(rawAttributes []asn1.RawValue) []pkix.AttributeT...
  function parseCSRExtensions (line 3004) | func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension...
  function CreateCertificateRequest (line 3052) | func CreateCertificateRequest(rand io.Reader, template *CertificateReque...
  function ParseCertificateRequest (line 3223) | func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, erro...
  function parseCertificateRequest (line 3236) | func parseCertificateRequest(in *certificateRequest) (*CertificateReques...

FILE: vendor/github.com/kentik/patricia/address_v4.go
  constant _leftmost32Bit (line 8) | _leftmost32Bit = uint32(1 << 31)
  type IPv4Address (line 11) | type IPv4Address struct
    method ShiftLeft (line 38) | func (i *IPv4Address) ShiftLeft(shiftCount uint) {
    method IsLeftBitSet (line 44) | func (i *IPv4Address) IsLeftBitSet() bool {
    method String (line 50) | func (i IPv4Address) String() string {
  function NewIPv4Address (line 17) | func NewIPv4Address(address uint32, length uint) IPv4Address {
  function NewIPv4AddressFromBytes (line 26) | func NewIPv4AddressFromBytes(address []byte, length uint) IPv4Address {

FILE: vendor/github.com/kentik/patricia/address_v6.go
  constant _leftmost64Bit (line 8) | _leftmost64Bit = uint64(1 << 63)
  type IPv6Address (line 11) | type IPv6Address struct
    method ShiftLeft (line 34) | func (ip *IPv6Address) ShiftLeft(bitCount uint) {
    method String (line 40) | func (ip IPv6Address) String() string {
    method IsLeftBitSet (line 82) | func (ip *IPv6Address) IsLeftBitSet() bool {
  function NewIPv6Address (line 18) | func NewIPv6Address(address []byte, length uint) IPv6Address {
  function ShiftLeftIPv6 (line 53) | func ShiftLeftIPv6(left uint64, right uint64, length uint, bitCount uint...
  function ShiftRightIPv6 (line 69) | func ShiftRightIPv6(left uint64, right uint64, bitCount uint) (uint64, u...

FILE: vendor/github.com/kentik/patricia/bits.go
  function initBuildLeftMasks (line 6) | func initBuildLeftMasks() {
  function MergePrefixes32 (line 19) | func MergePrefixes32(left uint32, leftLength uint, right uint32, rightLe...
  function MergePrefixes64 (line 24) | func MergePrefixes64(leftLeft uint64, leftRight uint64, leftLength uint,...

FILE: vendor/github.com/kentik/patricia/init.go
  function init (line 3) | func init() {

FILE: vendor/github.com/kentik/patricia/int64_tree/tree_node_v4.go
  constant _leftmost32Bit (line 11) | _leftmost32Bit = uint32(1 << 31)
  type treeNodeV4 (line 13) | type treeNodeV4 struct
    method MatchCount (line 22) | func (n *treeNodeV4) MatchCount(address patricia.IPv4Address) uint {
    method ShiftPrefix (line 38) | func (n *treeNodeV4) ShiftPrefix(shiftCount uint) {
    method IsLeftBitSet (line 44) | func (n *treeNodeV4) IsLeftBitSet() bool {
    method MergeFromNodes (line 49) | func (n *treeNodeV4) MergeFromNodes(left *treeNodeV4, right *treeNodeV...

FILE: vendor/github.com/kentik/patricia/int64_tree/tree_node_v6.go
  constant _leftmost64Bit (line 11) | _leftmost64Bit = uint64(1 << 63)
  type treeNodeV6 (line 13) | type treeNodeV6 struct
    method MatchCount (line 22) | func (n *treeNodeV6) MatchCount(address patricia.IPv6Address) uint {
    method ShiftPrefix (line 39) | func (n *treeNodeV6) ShiftPrefix(shiftCount uint) {
    method IsLeftBitSet (line 44) | func (n *treeNodeV6) IsLeftBitSet() bool {
    method MergeFromNodes (line 49) | func (n *treeNodeV6) MergeFromNodes(left *treeNodeV6, right *treeNodeV...

FILE: vendor/github.com/kentik/patricia/int64_tree/tree_v4.go
  type TreeV4 (line 12) | type TreeV4 struct
    method Clone (line 29) | func (t *TreeV4) Clone() *TreeV4 {
    method CountTags (line 46) | func (t *TreeV4) CountTags() int {
    method addTag (line 57) | func (t *TreeV4) addTag(tag int64, nodeIndex uint, matchFunc MatchesFu...
    method tagsForNode (line 86) | func (t *TreeV4) tagsForNode(ret []int64, nodeIndex uint, filterFunc F...
    method moveTags (line 104) | func (t *TreeV4) moveTags(fromIndex uint, toIndex uint) {
    method firstTagForNode (line 116) | func (t *TreeV4) firstTagForNode(nodeIndex uint) int64 {
    method deleteTag (line 122) | func (t *TreeV4) deleteTag(buf []int64, nodeIndex uint, matchTag int64...
    method Set (line 154) | func (t *TreeV4) Set(address patricia.IPv4Address, tag int64) (bool, i...
    method Add (line 161) | func (t *TreeV4) Add(address patricia.IPv4Address, tag int64, matchFun...
    method add (line 168) | func (t *TreeV4) add(address patricia.IPv4Address, tag int64, matchFun...
    method Delete (line 327) | func (t *TreeV4) Delete(address patricia.IPv4Address, matchFunc Matche...
    method DeleteWithBuffer (line 333) | func (t *TreeV4) DeleteWithBuffer(buf []int64, address patricia.IPv4Ad...
    method FindTagsWithFilter (line 478) | func (t *TreeV4) FindTagsWithFilter(address patricia.IPv4Address, filt...
    method FindTagsAppend (line 484) | func (t *TreeV4) FindTagsAppend(ret []int64, address patricia.IPv4Addr...
    method FindTags (line 490) | func (t *TreeV4) FindTags(address patricia.IPv4Address) []int64 {
    method FindTagsWithFilterAppend (line 497) | func (t *TreeV4) FindTagsWithFilterAppend(ret []int64, address patrici...
    method FindDeepestTag (line 552) | func (t *TreeV4) FindDeepestTag(address patricia.IPv4Address) (bool, i...
    method FindDeepestTags (line 610) | func (t *TreeV4) FindDeepestTags(address patricia.IPv4Address) (bool, ...
    method FindDeepestTagsAppend (line 617) | func (t *TreeV4) FindDeepestTagsAppend(ret []int64, address patricia.I...
    method Iterate (line 683) | func (t *TreeV4) Iterate() *TreeIteratorV4 {
    method countNodes (line 752) | func (t *TreeV4) countNodes(nodeIndex uint) int {
    method countTags (line 767) | func (t *TreeV4) countTags(nodeIndex uint) int {
  function NewTreeV4 (line 19) | func NewTreeV4() *TreeV4 {
  type TreeIteratorV4 (line 674) | type TreeIteratorV4 struct
    method Next (line 694) | func (iter *TreeIteratorV4) Next() bool {
    method Tags (line 745) | func (iter *TreeIteratorV4) Tags() []int64 {

FILE: vendor/github.com/kentik/patricia/int64_tree/tree_v4_manual.go
  method newNode (line 14) | func (t *TreeV4) newNode(address patricia.IPv4Address, prefixLength uint...
  method Address (line 28) | func (iter *TreeIteratorV4) Address() patricia.IPv4Address {
  method print (line 41) | func (t *TreeV4) print() {

FILE: vendor/github.com/kentik/patricia/int64_tree/tree_v6_generated.go
  type TreeV6 (line 12) | type TreeV6 struct
    method Clone (line 29) | func (t *TreeV6) Clone() *TreeV6 {
    method CountTags (line 46) | func (t *TreeV6) CountTags() int {
    method addTag (line 57) | func (t *TreeV6) addTag(tag int64, nodeIndex uint, matchFunc MatchesFu...
    method tagsForNode (line 86) | func (t *TreeV6) tagsForNode(ret []int64, nodeIndex uint, filterFunc F...
    method moveTags (line 104) | func (t *TreeV6) moveTags(fromIndex uint, toIndex uint) {
    method firstTagForNode (line 116) | func (t *TreeV6) firstTagForNode(nodeIndex uint) int64 {
    method deleteTag (line 122) | func (t *TreeV6) deleteTag(buf []int64, nodeIndex uint, matchTag int64...
    method Set (line 154) | func (t *TreeV6) Set(address patricia.IPv6Address, tag int64) (bool, i...
    method Add (line 161) | func (t *TreeV6) Add(address patricia.IPv6Address, tag int64, matchFun...
    method add (line 168) | func (t *TreeV6) add(address patricia.IPv6Address, tag int64, matchFun...
    method Delete (line 327) | func (t *TreeV6) Delete(address patricia.IPv6Address, matchFunc Matche...
    method DeleteWithBuffer (line 333) | func (t *TreeV6) DeleteWithBuffer(buf []int64, address patricia.IPv6Ad...
    method FindTagsWithFilter (line 478) | func (t *TreeV6) FindTagsWithFilter(address patricia.IPv6Address, filt...
    method FindTagsAppend (line 484) | func (t *TreeV6) FindTagsAppend(ret []int64, address patricia.IPv6Addr...
    method FindTags (line 490) | func (t *TreeV6) FindTags(address patricia.IPv6Address) []int64 {
    method FindTagsWithFilterAppend (line 497) | func (t *TreeV6) FindTagsWithFilterAppend(ret []int64, address patrici...
    method FindDeepestTag (line 552) | func (t *TreeV6) FindDeepestTag(address patricia.IPv6Address) (bool, i...
    method FindDeepestTags (line 610) | func (t *TreeV6) FindDeepestTags(address patricia.IPv6Address) (bool, ...
    method FindDeepestTagsAppend (line 617) | func (t *TreeV6) FindDeepestTagsAppend(ret []int64, address patricia.I...
    method Iterate (line 683) | func (t *TreeV6) Iterate() *TreeIteratorV6 {
    method countNodes (line 752) | func (t *TreeV6) countNodes(nodeIndex uint) int {
    method countTags (line 767) | func (t *TreeV6) countTags(nodeIndex uint) int {
  function NewTreeV6 (line 19) | func NewTreeV6() *TreeV6 {
  type TreeIteratorV6 (line 674) | type TreeIteratorV6 struct
    method Next (line 694) | func (iter *TreeIteratorV6) Next() bool {
    method Tags (line 745) | func (iter *TreeIteratorV6) Tags() []int64 {

FILE: vendor/github.com/kentik/patricia/int64_tree/tree_v6_manual.go
  method newNode (line 14) | func (t *TreeV6) newNode(address patricia.IPv6Address, prefixLength uint...
  method Address (line 28) | func (iter *TreeIteratorV6) Address() patricia.IPv6Address {
  method print (line 46) | func (t *TreeV6) print() {

FILE: vendor/github.com/kentik/patricia/int64_tree/trees.go
  type MatchesFunc (line 8) | type MatchesFunc
  type FilterFunc (line 11) | type FilterFunc
  type treeIteratorNext (line 15) | type treeIteratorNext
  constant nextSelf (line 18) | nextSelf treeIteratorNext = iota
  constant nextLeft (line 19) | nextLeft
  constant nextRight (line 20) | nextRight
  constant nextUp (line 21) | nextUp

FILE: vendor/github.com/kentik/patricia/net.go
  function ParseIPFromString (line 13) | func ParseIPFromString(address string) (*IPv4Address, *IPv6Address, erro...
  function ParseFromIP (line 64) | func ParseFromIP(ip *net.IP) (*IPv4Address, *IPv6Address, error) {
  function ParseFromIPAddr (line 82) | func ParseFromIPAddr(ipNet *net.IPNet) (*IPv4Address, *IPv6Address, erro...

FILE: vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go
  function ReadDelimited (line 38) | func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) {

FILE: vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go
  function WriteDelimited (line 30) | func WriteDelimited(w io.Writer, m proto.Message) (n int, err error) {

FILE: vendor/github.com/opentracing/opentracing-go/ext.go
  type TracerContextWithSpanExtension (line 14) | type TracerContextWithSpanExtension interface

FILE: vendor/github.com/opentracing/opentracing-go/ext/field.go
  function LogError (line 9) | func LogError(span opentracing.Span, err error, fields ...log.Field) {

FILE: vendor/github.com/opentracing/opentracing-go/ext/tags.go
  type SpanKindEnum (line 136) | type SpanKindEnum
  type spanKindTagName (line 138) | type spanKindTagName
    method Set (line 141) | func (tag spanKindTagName) Set(span opentracing.Span, value SpanKindEn...
  type rpcServerOption (line 145) | type rpcServerOption struct
    method Apply (line 149) | func (r rpcServerOption) Apply(o *opentracing.StartSpanOptions) {
  function RPCServerOption (line 160) | func RPCServerOption(client opentracing.SpanContext) opentracing.StartSp...
  type StringTagName (line 167) | type StringTagName
    method Set (line 170) | func (tag StringTagName) Set(span opentracing.Span, value string) {
  type Uint32TagName (line 177) | type Uint32TagName
    method Set (line 180) | func (tag Uint32TagName) Set(span opentracing.Span, value uint32) {
  type Uint16TagName (line 187) | type Uint16TagName
    method Set (line 190) | func (tag Uint16TagName) Set(span opentracing.Span, value uint16) {
  type BoolTagName (line 197) | type BoolTagName
    method Set (line 200) | func (tag BoolTagName) Set(span opentracing.Span, value bool) {
  type IPv4TagName (line 205) | type IPv4TagName
    method Set (line 208) | func (tag IPv4TagName) Set(span opentracing.Span, value uint32) {
    method SetString (line 213) | func (tag IPv4TagName) SetString(span opentracing.Span, value string) {

FILE: vendor/github.com/opentracing/opentracing-go/globaltracer.go
  type registeredTracer (line 3) | type registeredTracer struct
  function SetGlobalTracer (line 18) | func SetGlobalTracer(tracer Tracer) {
  function GlobalTracer (line 25) | func GlobalTracer() Tracer {
  function StartSpan (line 30) | func StartSpan(operationName string, opts ...StartSpanOption) Span {
  function InitGlobalTracer (line 35) | func InitGlobalTracer(tracer Tracer) {
  function IsGlobalTracerRegistered (line 40) | func IsGlobalTracerRegistered() bool {

FILE: vendor/github.com/opentracing/opentracing-go/gocontext.go
  type contextKey (line 5) | type contextKey struct
  function ContextWithSpan (line 11) | func ContextWithSpan(ctx context.Context, span Span) context.Context {
  function SpanFromContext (line 26) | func SpanFromContext(ctx context.Context) Span {
  function StartSpanFromContext (line 48) | func StartSpanFromContext(ctx context.Context, operationName string, opt...
  function StartSpanFromContextWithTracer (line 59) | func StartSpanFromContextWithTracer(ctx context.Context, tracer Tracer, ...

FILE: vendor/github.com/opentracing/opentracing-go/log/field.go
  type fieldType (line 8) | type fieldType
  constant stringType (line 11) | stringType fieldType = iota
  constant boolType (line 12) | boolType
  constant intType (line 13) | intType
  constant int32Type (line 14) | int32Type
  constant uint32Type (line 15) | uint32Type
  constant int64Type (line 16) | int64Type
  constant uint64Type (line 17) | uint64Type
  constant float32Type (line 18) | float32Type
  constant float64Type (line 19) | float64Type
  constant errorType (line 20) | errorType
  constant objectType (line 21) | objectType
  constant lazyLoggerType (line 22) | lazyLoggerType
  constant noopType (line 23) | noopType
  type Field (line 32) | type Field struct
    method Marshal (line 209) | func (lf Field) Marshal(visitor Encoder) {
    method Key (line 245) | func (lf Field) Key() string {
    method Value (line 250) | func (lf Field) Value() interface{} {
    method String (line 280) | func (lf Field) String() string {
  function String (line 41) | func String(key, val string) Field {
  function Bool (line 50) | func Bool(key string, val bool) Field {
  function Int (line 63) | func Int(key string, val int) Field {
  function Int32 (line 72) | func Int32(key string, val int32) Field {
  function Int64 (line 81) | func Int64(key string, val int64) Field {
  function Uint32 (line 90) | func Uint32(key string, val uint32) Field {
  function Uint64 (line 99) | func Uint64(key string, val uint64) Field {
  function Float32 (line 108) | func Float32(key string, val float32) Field {
  function Float64 (line 117) | func Float64(key string, val float64) Field {
  function Error (line 126) | func Error(err error) Field {
  function Object (line 138) | func Object(key string, obj interface{}) Field {
  function Event (line 147) | func Event(val string) Field {
  function Message (line 152) | func Message(val string) Field {
  type LazyLogger (line 157) | type LazyLogger
  function Lazy (line 162) | func Lazy(ll LazyLogger) Field {
  function Noop (line 182) | func Noop() Field {
  type Encoder (line 193) | type Encoder interface

FILE: vendor/github.com/opentracing/opentracing-go/log/util.go
  function InterleavedKVToFields (line 10) | func InterleavedKVToFields(keyValues ...interface{}) ([]Field, error) {

FILE: vendor/
Copy disabled (too large) Download .json
Condensed preview — 1224 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (22,421K chars).
[
  {
    "path": ".dockerignore",
    "chars": 19,
    "preview": "cmd/octorpki/cache\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "chars": 2433,
    "preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
  },
  {
    "path": ".github/workflows/go.yml",
    "chars": 992,
    "preview": "name: Go\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n    name: Build\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1718,
    "preview": "name: Release\n\non:\n  push:\n    tags:\n      - 'v*'\n\njobs:\n  build:\n    name: Build\n    runs-on: ubuntu-latest\n    steps:\n"
  },
  {
    "path": ".gitignore",
    "chars": 28,
    "preview": "cmd/**/cache/*\ncmd/**/*.pem\n"
  },
  {
    "path": "Dockerfile",
    "chars": 673,
    "preview": "ARG src_dir=\"/octorpki\"\n\nFROM golang:alpine as builder\nARG src_dir\nARG LDFLAGS=\"\"\n\nRUN apk --update --no-cache add git &"
  },
  {
    "path": "Dockerfile.prod",
    "chars": 559,
    "preview": "ARG src_uri=github.com/cloudflare/cfrpki/cmd/octorpki\n\nFROM golang:alpine as builder\nARG src_uri\n\nRUN apk --update --no-"
  },
  {
    "path": "LICENSE",
    "chars": 1481,
    "preview": "Copyright (c) 2019, Cloudflare. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without"
  },
  {
    "path": "Makefile",
    "chars": 2816,
    "preview": "EXTENSION ?= \nDIST_DIR ?= dist/\nGOOS ?= linux\nARCH ?= $(shell uname -m)\nBUILDINFOSDET ?= \n\nDOCKER_REPO   := cloudflare/\n"
  },
  {
    "path": "Monitoring.md",
    "chars": 7466,
    "preview": "# Monitoring\n\nThe most requested feature is visibility into the validation data.\nThis document covers basic monitoring a"
  },
  {
    "path": "README.md",
    "chars": 7668,
    "preview": "# Cloudflare RPKI Validator Tools and Libraries\n\n## DEPRECATION NOTICE\n**This software is no longer maintained. We advis"
  },
  {
    "path": "api/schemas/schemas.go",
    "chars": 1678,
    "preview": "package schemas\n\ntype OutputROA struct {\n\tPrefix    string `json:\"prefix\"`\n\tMaxLength int    `json:\"max-length\"`\n}\n\ntype"
  },
  {
    "path": "ca/xml.go",
    "chars": 3715,
    "preview": "package ca\n\nimport (\n\t\"bytes\"\n\t\"encoding/xml\"\n\t\"io\"\n)\n\nconst (\n\tXML_VERSION_RFC8181 = 4\n\tXML_VERSION_RFC8183 = 1\n)\n\ntype"
  },
  {
    "path": "cmd/ctrpki/ctrpki.go",
    "chars": 5310,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"encoding/hex\"\n\t\"flag\"\n\t\"net/http\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tsyncpki"
  },
  {
    "path": "cmd/localrpki/localrpki.go",
    "chars": 3321,
    "preview": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tsyncpki \"g"
  },
  {
    "path": "cmd/octorpki/ct.go",
    "chars": 2940,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/cloudflare/cfrpk"
  },
  {
    "path": "cmd/octorpki/filter.go",
    "chars": 864,
    "preview": "package main\n\nimport \"github.com/cloudflare/gortr/prefixfile\"\n\nfunc FilterInvalidPrefixLen(roalist []prefixfile.ROAJson)"
  },
  {
    "path": "cmd/octorpki/filter_test.go",
    "chars": 1203,
    "preview": "package main\n\nimport (\n\t\"testing\"\n\n\t\"github.com/cloudflare/gortr/prefixfile\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfu"
  },
  {
    "path": "cmd/octorpki/octorpki.go",
    "chars": 46670,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"crypto/ecdsa\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"encoding/asn1\"\n\t\"encoding/hex\"\n\t\"enc"
  },
  {
    "path": "cmd/octorpki/rrdp_fetcher.go",
    "chars": 896,
    "preview": "package main\n\nimport (\n\t\"sync\"\n\n\t\"github.com/opentracing/opentracing-go\"\n)\n\ntype rrdpFetchJob struct {\n\tpath  string\n\trs"
  },
  {
    "path": "cmd/octorpki/rsync_fetcher.go",
    "chars": 774,
    "preview": "package main\n\nimport (\n\t\"sync\"\n\n\t\"github.com/opentracing/opentracing-go\"\n)\n\ntype rsyncFetcher struct {\n\toctoRPKI *OctoRP"
  },
  {
    "path": "cmd/octorpki/tals/afrinic.tal",
    "chars": 495,
    "preview": "rsync://rpki.afrinic.net/repository/AfriNIC.cer\nhttps://rpki.afrinic.net/repository/AfriNIC.cer\n\nMIIBIjANBgkqhkiG9w0BAQE"
  },
  {
    "path": "cmd/octorpki/tals/apnic.tal",
    "chars": 531,
    "preview": "rsync://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer\nhttp://rpki.apnic.net/repository/apnic-rpki-root-iana-"
  },
  {
    "path": "cmd/octorpki/tals/arin.tal",
    "chars": 487,
    "preview": "rsync://rpki.arin.net/repository/arin-rpki-ta.cer\nhttps://rrdp.arin.net/arin-rpki-ta.cer\n\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ"
  },
  {
    "path": "cmd/octorpki/tals/lacnic.tal",
    "chars": 508,
    "preview": "https://rrdp.lacnic.net/ta/rta-lacnic-rpki.cer\nrsync://repository.lacnic.net/rpki/lacnic/rta-lacnic-rpki.cer\n\nMIIBIjANBg"
  },
  {
    "path": "cmd/octorpki/tals/ripe.tal",
    "chars": 482,
    "preview": "rsync://rpki.ripe.net/ta/ripe-ncc-ta.cer\nhttps://rpki.ripe.net/ta/ripe-ncc-ta.cer\n\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBC"
  },
  {
    "path": "compose/docker-compose.yml",
    "chars": 1434,
    "preview": "version: \"3\"\nservices:\n  prometheus:\n    image: prom/prometheus\n    volumes:\n      - ./prometheus.yml:/etc/prometheus/pr"
  },
  {
    "path": "compose/grafana-dashboard-provider.yml",
    "chars": 262,
    "preview": "apiVersion: 1\n\nproviders:\n  - name: 'Provider'\n    orgId: 1\n    folder: ''\n    folderUid: ''\n    type: file\n    disableD"
  },
  {
    "path": "compose/grafana-dashboard-rpki.json",
    "chars": 16922,
    "preview": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": \"-- Grafana --\",\n        \"enable\""
  },
  {
    "path": "compose/grafana-datasources.yml",
    "chars": 120,
    "preview": "apiVersion: 1\n\ndatasources:\n  - name: Prometheus\n    type: prometheus\n    url: http://prometheus:9090\n    access: proxy\n"
  },
  {
    "path": "compose/private.pem",
    "chars": 227,
    "preview": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIJ/JtiRkVppbKPH1LVm8dqc1DxgfBAqnkqwwUn2zit4eoAoGCCqGSM49\nAwEHoUQDQgAEn7QdFabWI12Y"
  },
  {
    "path": "compose/prometheus.yml",
    "chars": 400,
    "preview": "global:\n  scrape_interval:     15s\n  evaluation_interval: 15s\nalerting:\n  alertmanagers:\n  - static_configs:\n    - targe"
  },
  {
    "path": "compose/public.pem",
    "chars": 178,
    "preview": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEn7QdFabWI12YqsGadC+XLZq1Jlqe\nd33aaZuLX+3UV86opBux4QhUqz69"
  },
  {
    "path": "go.mod",
    "chars": 1688,
    "preview": "module github.com/cloudflare/cfrpki\n\ngo 1.19\n\nrequire (\n\tgithub.com/cloudflare/gortr v0.14.7\n\tgithub.com/getsentry/sentr"
  },
  {
    "path": "go.sum",
    "chars": 14305,
    "preview": "dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ng"
  },
  {
    "path": "ov/ov.go",
    "chars": 2126,
    "preview": "// Origin validator\n\npackage ov\n\nimport (\n\t\"errors\"\n\t\"net\"\n\n\t\"github.com/kentik/patricia\"\n\t\"github.com/kentik/patricia/i"
  },
  {
    "path": "ov/ov_test.go",
    "chars": 1697,
    "preview": "package ov\n\nimport (\n\t\"github.com/stretchr/testify/assert\"\n\t\"net\"\n\t\"testing\"\n)\n\ntype TestROA struct {\n\tASN       uint32\n"
  },
  {
    "path": "package/after-install-octorpki.sh",
    "chars": 242,
    "preview": "#!/bin/bash\n\nset -x\n\naddgroup --system octorpki\nadduser --system --home /var/lib/octorpki --shell /usr/sbin/nologin --di"
  },
  {
    "path": "package/before-remove-octorpki.sh",
    "chars": 116,
    "preview": "#!/bin/bash\n\nset -x\n\nsystemctl stop octorpki\nsystemctl disable octorpki\n\ndeluser octorpki\ndelgroup octorpki\n\nexit 0\n"
  },
  {
    "path": "package/octorpki.env",
    "chars": 32,
    "preview": "OCTORPKI_ARGS=-output.sign=false"
  },
  {
    "path": "package/octorpki.service",
    "chars": 256,
    "preview": "[Unit]\nDescription=OctoRPKI\nAfter=network.target\n\n[Service]\nType=simple\nEnvironmentFile=/etc/default/octorpki\nWorkingDir"
  },
  {
    "path": "sync/api/cfrpki.pb.go",
    "chars": 25269,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: cfrpki.proto\n\npackage cfrpki\n\nimport (\n\tcontext \"context\"\n\tf"
  },
  {
    "path": "sync/api/cfrpki.proto",
    "chars": 1064,
    "preview": "syntax = \"proto3\";\n\nservice RPKIAPI {\n    rpc GetResource (ResourceQuery) returns (ResourceData) {}\n    rpc GetRepositor"
  },
  {
    "path": "sync/api/fetch.go",
    "chars": 2015,
    "preview": "package cfrpki\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"strings\"\n\n\tlibrpki \"github.com/cloudflare/cfrpki/validator/lib"
  },
  {
    "path": "sync/lib/errors.go",
    "chars": 1863,
    "preview": "package syncpki\n\nimport (\n\t\"fmt\"\n\t\"github.com/getsentry/sentry-go\"\n\t\"net/http\"\n\t\"runtime\"\n)\n\nconst (\n\tERROR_RRDP_UNKNOWN"
  },
  {
    "path": "sync/lib/fetch.go",
    "chars": 3860,
    "preview": "package syncpki\n\nimport (\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\tlibrpki \"github.com/cloudflare"
  },
  {
    "path": "sync/lib/fetch_test.go",
    "chars": 928,
    "preview": "package syncpki\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestGetLocalPath(t *testing.T) {\n\tte"
  },
  {
    "path": "sync/lib/rrdp.go",
    "chars": 8730,
    "preview": "package syncpki\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"encoding/xml\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"string"
  },
  {
    "path": "sync/lib/rrdp_struct.go",
    "chars": 864,
    "preview": "package syncpki\n\nimport (\n\t\"encoding/xml\"\n)\n\ntype RootNode struct {\n\tXmlns     string `xml:\"xmlns,attr\"`\n\tVersion   stri"
  },
  {
    "path": "sync/lib/rsync.go",
    "chars": 2828,
    "preview": "package syncpki\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"strings\"\n\n\tlog \"github.com/s"
  },
  {
    "path": "sync/lib/rsync_test.go",
    "chars": 842,
    "preview": "package syncpki\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestExtractFoldersPathFromRsyncURL(t"
  },
  {
    "path": "sync/lib/utils.go",
    "chars": 2023,
    "preview": "package syncpki\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype Logger interface {\n\tInfof(string, ...interface{})\n\tInfo(.."
  },
  {
    "path": "validator/lib/ber.go",
    "chars": 5824,
    "preview": "package librpki\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n)\n\n/*\n  The BER to DER ASN.1 conversion has been implemented from:\n  https:"
  },
  {
    "path": "validator/lib/cert.go",
    "chars": 22060,
    "preview": "package librpki\n\nimport (\n\t\"bytes\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n"
  },
  {
    "path": "validator/lib/cert_test.go",
    "chars": 3411,
    "preview": "package librpki\n\nimport (\n\t\"net\"\n\t\"testing\"\n\n\t//\"encoding/asn1\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"crypto/x50"
  },
  {
    "path": "validator/lib/cms.go",
    "chars": 14289,
    "preview": "package librpki\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"encoding/asn1\"\n\t\"errors\"\n\t\""
  },
  {
    "path": "validator/lib/crl.go",
    "chars": 2322,
    "preview": "package librpki\n\nimport (\n\t\"crypto\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"errors\"\n\t\"io\"\n\t\"math/big\"\n\t\"ti"
  },
  {
    "path": "validator/lib/manifest.go",
    "chars": 2710,
    "preview": "package librpki\n\nimport (\n\t\"encoding/asn1\"\n\t\"errors\"\n\t\"math/big\"\n\t\"time\"\n)\n\nvar (\n\tSIAManifest = asn1.ObjectIdentifier{1"
  },
  {
    "path": "validator/lib/manifest_test.go",
    "chars": 1853,
    "preview": "package librpki\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/as"
  },
  {
    "path": "validator/lib/roa.go",
    "chars": 7394,
    "preview": "package librpki\n\nimport (\n\t\"encoding/asn1\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"sort\"\n\t\"time\"\n)\n\nvar (\n\tRoaOID = asn1.ObjectIdentif"
  },
  {
    "path": "validator/lib/roa_test.go",
    "chars": 3046,
    "preview": "package librpki\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"github.com/"
  },
  {
    "path": "validator/lib/tal.go",
    "chars": 5058,
    "preview": "package librpki\n\nimport (\n\t\"bytes\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"crypto/x509\"\n\t\"encoding/asn1\"\n\t\"encoding/base64\"\n\t\"err"
  },
  {
    "path": "validator/lib/tal_test.go",
    "chars": 2838,
    "preview": "package librpki\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/stretchr/test"
  },
  {
    "path": "validator/lib/xml.go",
    "chars": 1635,
    "preview": "package librpki\n\nimport (\n\t\"bytes\"\n\t\"encoding/asn1\"\n\t\"encoding/xml\"\n)\n\nvar (\n\tXMLOID = asn1.ObjectIdentifier{1, 2, 840, "
  },
  {
    "path": "validator/lib/xml_test.go",
    "chars": 2019,
    "preview": "package librpki\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"encoding/he"
  },
  {
    "path": "validator/pki/errors.go",
    "chars": 10723,
    "preview": "package pki\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"github.com/cloudflare/cfrpki/validator/lib\"\n\t\"github.com/getsentry/sentry"
  },
  {
    "path": "validator/pki/pki.go",
    "chars": 24239,
    "preview": "package pki\n\nimport (\n\t\"bytes\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n"
  },
  {
    "path": "validator/pki/pki_test.go",
    "chars": 20634,
    "preview": "package pki\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n"
  },
  {
    "path": "vendor/github.com/beorn7/perks/LICENSE",
    "chars": 1058,
    "preview": "Copyright (C) 2013 Blake Mizerany\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this "
  },
  {
    "path": "vendor/github.com/beorn7/perks/quantile/exampledata.txt",
    "chars": 5339,
    "preview": "8\n5\n26\n12\n5\n235\n13\n6\n28\n30\n3\n3\n3\n3\n5\n2\n33\n7\n2\n4\n7\n12\n14\n5\n8\n3\n10\n4\n5\n3\n6\n6\n209\n20\n3\n10\n14\n3\n4\n6\n8\n5\n11\n7\n3\n2\n3\n3\n212\n5\n2"
  },
  {
    "path": "vendor/github.com/beorn7/perks/quantile/stream.go",
    "chars": 7956,
    "preview": "// Package quantile computes approximate quantiles over an unbounded data\n// stream within low memory and CPU bounds.\n//"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/LICENSE.txt",
    "chars": 1068,
    "preview": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na cop"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/README.md",
    "chars": 2375,
    "preview": "# xxhash\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/ces"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/testall.sh",
    "chars": 282,
    "preview": "#!/bin/bash\nset -eu -o pipefail\n\n# Small convenience script for running the tests with various combinations of\n# arch/ta"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash.go",
    "chars": 5168,
    "preview": "// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described\n// at http://cyan4973.github.io/xxHash/.\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s",
    "chars": 3539,
    "preview": "//go:build !appengine && gc && !purego\n// +build !appengine\n// +build gc\n// +build !purego\n\n#include \"textflag.h\"\n\n// Re"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s",
    "chars": 3346,
    "preview": "//go:build !appengine && gc && !purego\n// +build !appengine\n// +build gc\n// +build !purego\n\n#include \"textflag.h\"\n\n// Re"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_asm.go",
    "chars": 301,
    "preview": "//go:build (amd64 || arm64) && !appengine && gc && !purego\n// +build amd64 arm64\n// +build !appengine\n// +build gc\n// +b"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_other.go",
    "chars": 1602,
    "preview": "//go:build (!amd64 && !arm64) || appengine || !gc || purego\n// +build !amd64,!arm64 appengine !gc purego\n\npackage xxhash"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_safe.go",
    "chars": 413,
    "preview": "//go:build appengine\n// +build appengine\n\n// This file contains the safe implementations of otherwise unsafe-using code."
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go",
    "chars": 2078,
    "preview": "//go:build !appengine\n// +build !appengine\n\n// This file encapsulates usage of unsafe.\n// xxhash_safe.go contains the sa"
  },
  {
    "path": "vendor/github.com/cloudflare/gortr/LICENSE.txt",
    "chars": 1482,
    "preview": "Copyright (c) 2018, Cloudflare. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without"
  },
  {
    "path": "vendor/github.com/cloudflare/gortr/prefixfile/prefixfile.go",
    "chars": 3859,
    "preview": "package prefixfile\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/asn1\"\n\t\"encoding/hex\"\n\t\"errors\"\n"
  },
  {
    "path": "vendor/github.com/cloudflare/gortr/prefixfile/slurm.go",
    "chars": 3483,
    "preview": "package prefixfile\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n)\n\ntype SlurmPrefixFilter struct {\n\tPrefix  string\n\tAS"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/LICENSE",
    "chars": 766,
    "preview": "ISC License\n\nCopyright (c) 2012-2016 Dave Collins <dave@davec.name>\n\nPermission to use, copy, modify, and/or distribute "
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/bypass.go",
    "chars": 4715,
    "preview": "// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>\n//\n// Permission to use, copy, modify, and distribute this sof"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/bypasssafe.go",
    "chars": 1741,
    "preview": "// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>\n//\n// Permission to use, copy, modify, and distribute this sof"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/common.go",
    "chars": 10364,
    "preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/config.go",
    "chars": 12842,
    "preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/doc.go",
    "chars": 8527,
    "preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/dump.go",
    "chars": 13794,
    "preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/format.go",
    "chars": 11314,
    "preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/spew.go",
    "chars": 5969,
    "preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.codecov.yml",
    "chars": 412,
    "preview": "codecov:\n  # across\n  notify:\n    # Do not notify until at least this number of reports have been uploaded\n    # from th"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.craft.yml",
    "chars": 237,
    "preview": "minVersion: 0.35.0\nchangelogPolicy: simple\nartifactProvider:\n  name: none\ntargets:\n  - name: github\n    tagPrefix: v\n  -"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.gitattributes",
    "chars": 248,
    "preview": "# Tell Git to use LF for line endings on all platforms.\n# Required to have correct test data on Windows.\n# https://githu"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.gitignore",
    "chars": 188,
    "preview": "# Code coverage artifacts\ncoverage.txt\ncoverage.out\ncoverage.html\n.coverage/\n\n# Just my personal way of tracking stuff —"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.golangci.yml",
    "chars": 811,
    "preview": "linters:\n  disable-all: true\n  enable:\n    - bodyclose\n    - deadcode\n    - depguard\n    - dogsled\n    - dupl\n    - errc"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/CHANGELOG.md",
    "chars": 23887,
    "preview": "# Changelog\n\n## 0.19.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.19.0.\n\n#"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md",
    "chars": 2877,
    "preview": "# Contributing to sentry-go\n\nHey, thank you if you're reading this, we welcome your contribution!\n\n## Sending a Pull Req"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/LICENSE",
    "chars": 1093,
    "preview": "MIT License\n\nCopyright (c) 2019 Functional Software, Inc. dba Sentry\n\nPermission is hereby granted, free of charge, to a"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/MIGRATION.md",
    "chars": 195,
    "preview": "# `raven-go` to `sentry-go` Migration Guide\n\nA [`raven-go` to `sentry-go` migration guide](https://docs.sentry.io/platfo"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/Makefile",
    "chars": 2653,
    "preview": ".DEFAULT_GOAL := help\n\nMKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))\nMKFILE_DIR := $(dir $(MKFILE_PATH))\nALL_GO"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/README.md",
    "chars": 5311,
    "preview": "<p align=\"center\">\n  <a href=\"https://sentry.io/?utm_source=github&utm_medium=logo\" target=\"_blank\">\n    <picture>\n     "
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/client.go",
    "chars": 22459,
    "preview": "package sentry\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"os\"\n\t\"reflect\"\n\t\"sort\""
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/doc.go",
    "chars": 1719,
    "preview": "/*\nPackage sentry is the official Sentry SDK for Go.\n\nUse it to report errors and track application performance through "
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/dsn.go",
    "chars": 5180,
    "preview": "package sentry\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype scheme string\n\nconst ("
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/dynamic_sampling_context.go",
    "chars": 2857,
    "preview": "package sentry\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/getsentry/sentry-go/internal/otel/baggage\"\n)\n\nconst (\n\tsent"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/hub.go",
    "chars": 11057,
    "preview": "package sentry\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype contextKey int\n\n// Keys used to store values in a Context. U"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/integrations.go",
    "chars": 7407,
    "preview": "package sentry\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// ========================="
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/interfaces.go",
    "chars": 13448,
    "preview": "package sentry\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Protocol Docs (k"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/debug/transport.go",
    "chars": 1742,
    "preview": "package debug\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\t\"net/http/httputil\"\n)\n\n// Transport imp"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/otel/baggage/README.md",
    "chars": 1100,
    "preview": "## Why do we have this \"otel/baggage\" folder?\n\nThe root sentry-go SDK (namely, the Dynamic Sampling functionality) needs"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/otel/baggage/baggage.go",
    "chars": 16718,
    "preview": "// # Copyright The OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you ma"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage/baggage.go",
    "chars": 1794,
    "preview": "// This file was vendored in unmodified from\n// https://github.com/open-telemetry/opentelemetry-go/blob/c21b6b6bb31a2f74"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/category.go",
    "chars": 1164,
    "preview": "package ratelimit\n\nimport (\n\t\"strings\"\n\n\t\"golang.org/x/text/cases\"\n\t\"golang.org/x/text/language\"\n)\n\n// Reference:\n// htt"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/deadline.go",
    "chars": 619,
    "preview": "package ratelimit\n\nimport \"time\"\n\n// A Deadline is a time instant when a rate limit expires.\ntype Deadline time.Time\n\n//"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/doc.go",
    "chars": 127,
    "preview": "// Package ratelimit provides tools to work with rate limits imposed by Sentry's\n// data ingestion pipeline.\npackage rat"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/map.go",
    "chars": 1699,
    "preview": "package ratelimit\n\nimport (\n\t\"net/http\"\n\t\"time\"\n)\n\n// Map maps categories to rate limit deadlines.\n//\n// A rate limit is"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/rate_limits.go",
    "chars": 2252,
    "preview": "package ratelimit\n\nimport (\n\t\"errors\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\nvar errInvalidXSRLRetryAfter = errors.New"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/retry_after.go",
    "chars": 1140,
    "preview": "package ratelimit\n\nimport (\n\t\"errors\"\n\t\"strconv\"\n\t\"time\"\n)\n\nconst defaultRetryAfter = 1 * time.Minute\n\nvar errInvalidRet"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/scope.go",
    "chars": 10816,
    "preview": "package sentry\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n)\n\n// Scope holds contextual data for the current sc"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/sentry.go",
    "chars": 3588,
    "preview": "package sentry\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\n// Deprecated: Use SDKVersion instead.\nconst Version = SDKVersion\n\n// Ver"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/sourcereader.go",
    "chars": 1250,
    "preview": "package sentry\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"sync\"\n)\n\ntype sourceReader struct {\n\tmu    sync.Mutex\n\tcache map[string][][]by"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/span_recorder.go",
    "chars": 1420,
    "preview": "package sentry\n\nimport (\n\t\"sync\"\n)\n\n// A spanRecorder stores a span tree that makes up a transaction. Safe for\n// concur"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/stacktrace.go",
    "chars": 9896,
    "preview": "package sentry\n\nimport (\n\t\"go/build\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strings\"\n)\n\nconst unknown string = \"unknow"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/traces_sampler.go",
    "chars": 562,
    "preview": "package sentry\n\n// A SamplingContext is passed to a TracesSampler to determine a sampling\n// decision.\n//\n// TODO(tracin"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/tracing.go",
    "chars": 27120,
    "preview": "package sentry\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strin"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/transport.go",
    "chars": 15522,
    "preview": "package sentry\n\nimport (\n\t\"bytes\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/util.go",
    "chars": 2798,
    "preview": "package sentry\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\texec \"golang."
  },
  {
    "path": "vendor/github.com/go-logr/logr/.golangci.yaml",
    "chars": 425,
    "preview": "run:\n  timeout: 1m\n  tests: true\n\nlinters:\n  disable-all: true\n  enable:\n    - asciicheck\n    - deadcode\n    - errcheck\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/CHANGELOG.md",
    "chars": 140,
    "preview": "# CHANGELOG\n\n## v1.0.0-rc1\n\nThis is the first logged release.  Major changes (including breaking changes)\nhave occurred "
  },
  {
    "path": "vendor/github.com/go-logr/logr/CONTRIBUTING.md",
    "chars": 579,
    "preview": "# Contributing\n\nLogr is open to pull-requests, provided they fit within the intended scope of\nthe project.  Specifically"
  },
  {
    "path": "vendor/github.com/go-logr/logr/LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "vendor/github.com/go-logr/logr/README.md",
    "chars": 12280,
    "preview": "# A minimal logging API for Go\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.d"
  },
  {
    "path": "vendor/github.com/go-logr/logr/discard.go",
    "chars": 1424,
    "preview": "/*\nCopyright 2020 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "vendor/github.com/go-logr/logr/logr.go",
    "chars": 20632,
    "preview": "/*\nCopyright 2019 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "vendor/github.com/golang/protobuf/AUTHORS",
    "chars": 173,
    "preview": "# This source code refers to The Go Authors for copyright purposes.\n# The master list of authors is in the main Go distr"
  },
  {
    "path": "vendor/github.com/golang/protobuf/CONTRIBUTORS",
    "chars": 170,
    "preview": "# This source code was written by the Go contributors.\n# The master list of contributors is in the main Go distribution,"
  },
  {
    "path": "vendor/github.com/golang/protobuf/LICENSE",
    "chars": 1480,
    "preview": "Copyright 2010 The Go Authors.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without"
  },
  {
    "path": "vendor/github.com/golang/protobuf/jsonpb/decode.go",
    "chars": 15804,
    "preview": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/jsonpb/encode.go",
    "chars": 14359,
    "preview": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/jsonpb/json.go",
    "chars": 2359,
    "preview": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/buffer.go",
    "chars": 9791,
    "preview": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/defaults.go",
    "chars": 1637,
    "preview": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/deprecated.go",
    "chars": 3188,
    "preview": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/discard.go",
    "chars": 1618,
    "preview": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/extensions.go",
    "chars": 10945,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/properties.go",
    "chars": 9108,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/proto.go",
    "chars": 6004,
    "preview": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/registry.go",
    "chars": 10502,
    "preview": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/text_decode.go",
    "chars": 20106,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/text_encode.go",
    "chars": 13043,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/wire.go",
    "chars": 1905,
    "preview": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/wrappers.go",
    "chars": 1238,
    "preview": "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/any/any.pb.go",
    "chars": 2762,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: github.com/golang/protobuf/ptypes/any/any.proto\n\npackage any"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/any.go",
    "chars": 5139,
    "preview": "// Copyright 2016 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/doc.go",
    "chars": 472,
    "preview": "// Copyright 2016 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go",
    "chars": 3098,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: github.com/golang/protobuf/ptypes/duration/duration.proto\n\np"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/duration.go",
    "chars": 2481,
    "preview": "// Copyright 2016 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go",
    "chars": 3166,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/timestamp.go",
    "chars": 3707,
    "preview": "// Copyright 2016 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/.gitignore",
    "chars": 297,
    "preview": "*.iml\n*.swo\n*.swp\n*.tfstate\n*.tfstate.backup\n*~\n/.idea\n/certcheck\n/chainfix\n/coverage.txt\n/createtree\n/crlcheck\n/ctclien"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/.golangci.yaml",
    "chars": 775,
    "preview": "run:\n  deadline: 90s\n  skip-dirs:\n    - (^|/)x509($|/)\n    - (^|/)x509util($|/)\n    - (^|/)asn1($|/)\n\nlinters-settings:\n"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/AUTHORS",
    "chars": 880,
    "preview": "# This is the official list of benchmark authors for copyright purposes.\n# This file is distinct from the CONTRIBUTORS f"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/CHANGELOG.md",
    "chars": 24930,
    "preview": "# CERTIFICATE-TRANSPARENCY-GO Changelog\n\n## HEAD\n\n### Integration\n\n * Breaking change to API for `integration.HammerCTLo"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/CODEOWNERS",
    "chars": 35,
    "preview": "*\t@google/certificate-transparency\n"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/CONTRIBUTING.md",
    "chars": 2485,
    "preview": "# How to contribute #\n\nWe'd love to accept your patches and contributions to this project.  There are\na just a few small"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/CONTRIBUTORS",
    "chars": 2499,
    "preview": "# People who have agreed to one of the CLAs and can contribute patches.\n# The AUTHORS file lists the copyright holders; "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/PULL_REQUEST_TEMPLATE.md",
    "chars": 635,
    "preview": "<!---\nDescribe your changes in detail here.\nIf this fixes an issue, please write \"Fixes #123\", substituting the issue nu"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/README.md",
    "chars": 5605,
    "preview": "# Certificate Transparency: Go Code\n\n[![Build Status](https://travis-ci.org/google/certificate-transparency-go.svg?branc"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/asn1/README.md",
    "chars": 250,
    "preview": "# Important Notice\n\nThis is a fork of the `encoding/asn1` Go package. The original source can be found on\n[GitHub](https"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/asn1/asn1.go",
    "chars": 35683,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/asn1/common.go",
    "chars": 5767,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/asn1/marshal.go",
    "chars": 16324,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.pb.go",
    "chars": 10677,
    "preview": "// Copyright 2017 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.proto",
    "chars": 1594,
    "preview": "// Copyright 2017 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/client/getentries.go",
    "chars": 2294,
    "preview": "// Copyright 2016 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/client/logclient.go",
    "chars": 8087,
    "preview": "// Copyright 2014 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/client/multilog.go",
    "chars": 7542,
    "preview": "// Copyright 2017 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/cloudbuild.yaml",
    "chars": 6890,
    "preview": "#############################################################################\n## The top section of this file is identic"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/cloudbuild_master.yaml",
    "chars": 7203,
    "preview": "#############################################################################\n## The top section of this file is identic"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/cloudbuild_tag.yaml",
    "chars": 5888,
    "preview": "#############################################################################\n## The top section of this file is identic"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/codecov.yml",
    "chars": 527,
    "preview": "# Customizations to codecov for c-t-go repo. This will be merged into\n# the team / default codecov yaml file.\n#\n# Valida"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/jsonclient/backoff.go",
    "chars": 1702,
    "preview": "// Copyright 2017 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/jsonclient/client.go",
    "chars": 10935,
    "preview": "// Copyright 2016 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/proto_gen.go",
    "chars": 1579,
    "preview": "// Copyright 2021 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/serialization.go",
    "chars": 10899,
    "preview": "// Copyright 2015 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/signatures.go",
    "chars": 3656,
    "preview": "// Copyright 2015 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/tls/signature.go",
    "chars": 4626,
    "preview": "// Copyright 2016 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/tls/tls.go",
    "chars": 22153,
    "preview": "// Copyright 2016 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/tls/types.go",
    "chars": 2966,
    "preview": "// Copyright 2016 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/types.go",
    "chars": 21180,
    "preview": "// Copyright 2015 Google LLC. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/x509/README.md",
    "chars": 248,
    "preview": "# Important Notice\n\nThis is a fork of the `crypto/x509` Go package. The original source can be found on\n[GitHub](https:/"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/x509/cert_pool.go",
    "chars": 3841,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/x509/curves.go",
    "chars": 1155,
    "preview": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/x509/error.go",
    "chars": 5772,
    "preview": "package x509\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Error implements the error interface and describes a "
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/x509/errors.go",
    "chars": 10094,
    "preview": "package x509\n\nimport \"fmt\"\n\n// To preserve error IDs, only append to this list, never insert.\nconst (\n\tErrInvalidID Erro"
  },
  {
    "path": "vendor/github.com/google/certificate-transparency-go/x509/names.go",
    "chars": 5377,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  }
]

// ... and 1024 more files (download for full content)

About this extraction

This page contains the full source code of the cloudflare/cfrpki GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1224 files (20.0 MB), approximately 5.3M tokens, and a symbol index with 106713 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!