Commit Graph

123 Commits

Author SHA1 Message Date
Simone Basso
1776ea1288
cleanup: remove websteps summer 2021 implementation (#722)
See https://github.com/ooni/probe/issues/2094
2022-05-13 15:06:03 +02:00
DecFox
5d2afaade4
cli: upgrade to lucas-clemente/quic-go@v0.27.0 (#715)
* quic-go upgrade: replaced Session/EarlySession with Connection/EarlyConnection

* quic-go upgrade: added context to RoundTripper.Dial

* quic-go upgrade: made corresponding changes to tutorial

* quic-go upgrade: changed sess variable instances to qconn

* quic-go upgrade: made corresponding changes to tutorial

* cleanup: remove unnecessary comments

Those comments made sense in terms of illustrating the changes
but they're going to be less useful once we merge.

* fix(go.mod): apparently we needed `go1.18.1 mod tidy`

VSCode just warned me about this. It seems fine to apply this
change as part of the pull request at hand.

* cleanup(netxlite): http3dialer can be removed

We used to use http3dialer to glue a QUIC dialer, which had a
context as its first argument, to the Dial function used by the
HTTP3 transport, which did not have a context as its first
argument.

Now that HTTP3 transport has a Dial function taking a context as
its first argument, we don't need http3dialer
anymore, since we can use the QUIC dialer directly.

Cc: @DecFox

* Revert "cleanup(netxlite): http3dialer can be removed"

This reverts commit c62244c620cee5fadcc2ca89d8228c8db0b96add
to investigate the build failure mentioned at
https://github.com/ooni/probe-cli/pull/715#issuecomment-1119450484

* chore(netx): show that test was already broken

We didn't see the breakage before because we were not using
the created transport, but the issue of using a nil dialer was
already present before, we just didn't see it.

Now we understand why removing the http3transport in
c62244c620cee5fadcc2ca89d8228c8db0b96add did cause the
breakage mentioned at
https://github.com/ooni/probe-cli/pull/715#issuecomment-1119450484

* fix(netx): convert broken integration test to working unit test

There's no point in using the network here. Add a fake dialer that
breaks and ensure we're getting the expected error.

We've now improved upon the original test because the original test was
not doing anything while now we're testing whether we get back a QUIC
dialer that _can be used_.

After this commit, I can then readd the cleanup commit
c62244c620cee5fadcc2ca89d8228c8db0b96add and it won't be
broken anymore (at least, this is what I expected to happen).

* Revert "Revert "cleanup(netxlite): http3dialer can be removed""

This reverts commit 0e254bfc6ba3bfd65365ce3d8de2c8ec51b925ff
because now we should have fixed the broken test.

Co-authored-by: decfox <decfox>
Co-authored-by: Simone Basso <bassosimone@gmail.com>
2022-05-06 12:24:03 +02:00
Simone Basso
d3c5196474
fix(ooniprobe): use ooniprobe-cli-unattended for unattended runs (#714)
This diff changes the software name used by unattended runs for which
we did not override the default software name (`ooniprobe-cli`).

It will become `ooniprobe-cli-unattended`. This software name is in line
with the one we use for Android, iOS, and desktop unattended runs.

While working in this diff, I introduced string constants for the run
types and a string constant for the default software name.

See https://github.com/ooni/probe/issues/2081.
2022-04-29 13:41:09 +02:00
kelmenhorst
0735e2018f
feat: add oonireport client (#682)
The oonireport client (re-)uploads a measurement report file. This can be helpful when the measurement was not uploaded at runtime.

Usage: `./oonireport upload <file>`, where `<file>` is a json(l) file containing one OONI measurement per line.

This pull request refers to https://github.com/ooni/probe/issues/2003 and https://github.com/ooni/probe/issues/950.

Co-authored-by: Simone Basso <bassosimone@gmail.com>
2022-02-14 15:24:36 +01:00
Ain Ghazal
00b5c73c3a
jafar(README.md): fix typo (#692)
Co-authored-by: Ain Ghazal <ainghazal@riseup.net>
2022-02-10 17:38:51 +01:00
Simone Basso
7bbd36a434
[forwardport] fix(jafar/iptables/test): force using pure Go resolver (#690)
This commit forward ports 8f2d7945f806579af4d0495f4b8f5a6a01eefb0c, whose
commit message is as follows:

- - -

The discrepancy I was seeing between my local tests and tests run
in the CI is that my systemd is configured to use DoT.

Hence, it was bypassing iptables rules because the query was sent
over an encrypted tunnel. Using a pure Go resolver fixes since
that always uses UDP, so the filter works.

Also, reason that we want as minimal as possible tests, so refactor
a test so that we use just a resolver rather than an HTTP client, and,
while there, also enforce this resolver to be a pure Go resolver.

Reference issue: https://github.com/ooni/probe/issues/2016

This diff WILL need to be forward ported to master.
2022-02-09 15:32:45 +01:00
Simone Basso
85664f1e31
feat(torsf): collect tor logs, select rendezvous method, count bytes (#683)
This diff contains significant improvements over the previous
implementation of the torsf experiment.

We add support for configuring different rendezvous methods after
the convo at https://github.com/ooni/probe/issues/2004. In doing
that, I've tried to use a terminology that is consistent with the
names being actually used by tor developers.

In terms of what to do next, this diff basically instruments
torsf to always rendezvous using domain fronting. Yet, it's also
possible to change the rendezvous method from the command line,
when using miniooni, which allows to experiment a bit more. In the
same vein, by default we use a persistent tor datadir, but it's
also possible to use a temporary datadir using the cmdline.

Here's how a generic invocation of `torsf` looks like:

```bash
./miniooni -O DisablePersistentDatadir=true \
           -O RendezvousMethod=amp \
           -O DisableProgress=true \
           torsf
```

(The default is `DisablePersistentDatadir=false` and
`RendezvousMethod=domain_fronting`.)

With this implementation, we can start measuring whether snowflake
and tor together can boostrap, which seems the most important thing
to focus on at the beginning. Understanding why the bootstrap most
often does not converge with a temporary datadir on Android devices
remains instead an open problem for now. (I'll also update the
relevant issues or create new issues after commit this.)

We also address some methodology improvements that were proposed
in https://github.com/ooni/probe/issues/1686. Namely:

1. we record the tor version;

2. we include the bootstrap percentage by reading the logs;

3. we set the anomaly key correctly;

4. we measure the bytes send and received (by `tor` not by `snowflake`, since
doing it for snowflake seems more complex at this stage).

What remains to be done is the possibility of including Snowflake
events into the measurement, which is not possible until the new
improvements at common/event in snowflake.git are included into a
tagged version of snowflake itself. (I'll make sure to mention
this aspect to @cohosh in https://github.com/ooni/probe/issues/2004.)
2022-02-07 17:05:36 +01:00
Simone Basso
d2fb7f8e6c
fix(jafar): re-enable previously broken integration test (#681)
I have tested this integration test locally and it's now WAI.

It may be that it will fail again when run on GitHub Actions, which will
indicate we cannot fully trust Actions for running _some_ tests.

Closes https://github.com/ooni/probe/issues/1913.
2022-02-01 14:47:22 +01:00
Simone Basso
e904b90006
feature: merge measurex and netx archival layer (1/N) (#663)
This diff introduces a new package called `./internal/archival`. This package collects data from `./internal/model` network interfaces (e.g., `Dialer`, `QUICDialer`, `HTTPTransport`), saves such data into an internal tabular data format suitable for on-line processing and analysis, and allows exporting data into the OONI data format.

The code for collecting and the internal tabular data formats are adapted from `measurex`. The code for formatting and exporting OONI data-format-compliant structures is adapted from `netx/archival`.

My original objective was to _also_ (1) fully replace `netx/archival` with this package and (2) adapt `measurex` to use this package rather than its own code. Both operations seem easily feasible because: (a) this code is `measurex` code without extensions that are `measurex` related, which will need to be added back as part of the process; (b) the API provided by this code allows for trivially converting from using `netx/archival` to using this code.

Yet, both changes should not be taken lightly. After implementing them, there's need to spend some time doing QA and ensuring all nettests work as intended. However, I am planning a release in the next two weeks, and this QA task is likely going to defer the release. For this reason, I have chosen to commit the work done so far into the tree and defer the second part of this refactoring for a later moment in time. (This explains why the title mentions "1/N").

On a more high-level perspective, it would also be beneficial, I guess, to explain _why_ I am doing these changes. There are two intertwined reasons. The first reason is that `netx/archival` has shortcomings deriving from its original https://github.com/ooni/netx legacy. The most relevant shortcoming is that it saves all kind of data into the same tabular structure named `Event`. This design choice is unfortunate because it does not allow one to apply data-type specific logic when processing the results. In turn, this choice results in complex processing code. Therefore, I believe that replacing the code with event-specific data structures is clearly an improvement in terms of code maintainability and would quite likely lead us to more confidently change and evolve the codebase.

The second reason why I would like to move forward these changes is to unify the codepaths used for measuring. At this point in time, we basically have two codepaths: `./internal/engine/netx` and `./internal/measurex`. They both have pros and cons and I don't think we want to rewrite whole experiments using `netx`. Rather, what we probably want is to gradually merge these two codepaths such that `netx` is a set of abstractions on top of `measurex` (which is more low-level and has a more-easily-testable design). Because saving events and generating an archival data format out of them consists of at least 50% of the complexity of both `netx` and `measurex`, it seems reasonable to unify this archival-related part of the two codebases as the first step.

At the highest level of abstraction, these changes are part of the train of changes which will eventually lead us to bless `websteps` as a first class citizen in OONI land. Because `websteps` requires different underlying primitives, I chose to develop these primitives from scratch rather than wrestling with `netx`, which used another model. The model used by `websteps` is that we perform each operation in isolation and immediately we save the results, while `netx` creates whole data structures and collects all the events happening via tracing. We believe the model used by `websteps` to be better because it does not require your code to figure out everything that happened after the measurement, which is a source of subtle bugs in the current implementation. So, when I started implementing websteps I extracted the bits of `netx` that could also be beneficial to `websteps` into a separate library, thus `netxlite` was born.

The reference issue describing merging the archival of `netx` and `measurex` is https://github.com/ooni/probe/issues/1957. As of this writing the issue still references the original plan, which I could not complete by the end of this Sprint, so I am going to adapt the text of the issue to only refer to what was done in here next. Of course, I also need follow-up issues.
2022-01-14 12:13:10 +01:00
Simone Basso
d3c6c11e48
cleanup(netx): remove the DNSClient type (#660)
The DNSClient type existed because the Resolver type did not
include CloseIdleConnections in its signature.

Now that Resolver includes CloseIdleConnections, the DNSClient
type has become unnecessary and can be safely removed.

See https://github.com/ooni/probe/issues/1956.
2022-01-10 11:53:06 +01:00
Simone Basso
423a3feacc
cleanup(netx): remove unused ChainResolver (#657)
This is another cleanup point mentioned by https://github.com/ooni/probe/issues/1956.

While there, fix a bunch of comments in jafar that were incorrectly
referring to the netx package name.
2022-01-07 19:18:33 +01:00
Simone Basso
566c6b246a
cleanup: remove unnecessary legacy interfaces (#656)
This diff addresses another point of https://github.com/ooni/probe/issues/1956:

> - [ ] observe that we're still using a bunch of private interfaces for common interfaces such as the `Dialer`, so we can get rid of these private interfaces and always use the ones in `model`, which allows us to remove a bunch of legacy wrappers

Additional cleanups may still be possible. The more I cleanup, the more I see
there's extra legacy code we can dispose of (which seems good?).
2022-01-07 18:33:37 +01:00
Simone Basso
f0181c432f
refactor: move httpx into the internal package (#646)
This concludes the TODO list at https://github.com/ooni/probe/issues/1951
2022-01-05 17:17:20 +01:00
Simone Basso
eed51978ca
refactor(httpx): hide the real APIClient (#648)
As mentioned in https://github.com/ooni/probe/issues/1951, one of
the main issues I did see with httpx.APIClient is that in some cases
it's used in a very fragile way by probeservices.Client.

This happens in psiphon.go and tor.go, where we create a copy of
the APIClient and then modify it's Authorization field.

If we ever refactor probeservices.Client to take a pointer to
httpx.Client, we are now mutating the httpx.Client.

Of course, we don't want that to happen.

This diff attempts to address such a problem as follows:

1. we create a new APIClientTemplate type that holds the same
fields of an APIClient and allows to build an APIClient

2. we modify every user of APIClient to use APIClientTemplate

3. when we need an APIClient, we build it from the corresponding
template and, when we need to use a specific Authorization, we
use a build factory that sets APIClient.Authorization

4. we hide APIClient by renaming it apiClient and by defining
an interface called APIClient that allows to use it

So, now the codebase always uses the opaque APIClient interface to
issue API calls and always uses the APIClientTemplate to build an
opaque APIClient.

Boom! We have separated construction from usage and we are not
mutating in weird ways the APIClient anymore.
2022-01-05 14:15:42 +01:00
Simone Basso
7b7df2c6af
refactor(httpx): improve and modernize (1/n) (#647)
This PR starts to implement the refactoring described at https://github.com/ooni/probe/issues/1951. I originally wrote more patches than the ones in this PR, but overall they were not readable. Since I want to squash and merge, here's a reasonable subset of the original patches that will still be readable and understandable in the future.
2022-01-05 12:48:32 +01:00
Simone Basso
273b70bacc
refactor: interfaces and data types into the model package (#642)
## Checklist

- [x] I have read the [contribution guidelines](https://github.com/ooni/probe-cli/blob/master/CONTRIBUTING.md)
- [x] reference issue for this pull request: https://github.com/ooni/probe/issues/1885
- [x] related ooni/spec pull request: N/A

Location of the issue tracker: https://github.com/ooni/probe

## Description

This PR contains a set of changes to move important interfaces and data types into the `./internal/model` package.

The criteria for including an interface or data type in here is roughly that the type should be important and used by several packages. We are especially interested to move more interfaces here to increase modularity.

An additional side effect is that, by reading this package, one should be able to understand more quickly how different parts of the codebase interact with each other.

This is what I want to move in `internal/model`:

- [x] most important interfaces from `internal/netxlite`
- [x] everything that was previously part of `internal/engine/model`
- [x] mocks from `internal/netxlite/mocks` should also be moved in here as a subpackage
2022-01-03 13:53:23 +01:00
Simone Basso
611fed05f4
[forwardport] release 3.11: update all the dependencies (#636) (#637)
* [forwardport] release 3.11: update all the dependencies (#636)

This diff forward ports e291e436b3c332300f5567796f9c48bb9bc1e652.

* chore: use go1.17.4 everywhere

Part of https://github.com/ooni/probe/issues/1843

* chore: update to the latest ooni/oohttp

Part of https://github.com/ooni/probe/issues/1843

* chore: update the dependencies

Note: I did an update and not an upgrade (i.e., I didn't check
whether we have next-major-versions of dependencies).

Part of https://github.com/ooni/probe/issues/1843

* chore: update the user-agent we use

Part of https://github.com/ooni/probe/issues/1843

* chore: update ooni/oohttp and ooni/probe-assets

Part of https://github.com/ooni/probe/issues/1843

* chore: run go generate again

Part of https://github.com/ooni/probe/issues/1843

* fix(jafar): skip currently broken test

Created issue for it here: https://github.com/ooni/probe/issues/1913
2021-12-06 17:46:13 +01:00
Simone Basso
2044b78a5a
refactor: introduce and use InputOrStaticDefault (#632)
This commit introduces a new `InputLoader` policy by which, if no
input is provided, we use a static default input list.

We also modify the code to use this policy for dnscheck and
stunreachability, with proper input.

We also modify `miniooni` to pass the new `ExperimentName` field to
the `InputLoader` to indicate which default input list to use.

This diff is part of a set of diffs aiming at fixing
https://github.com/ooni/probe/issues/1814 and has been
extracted from https://github.com/ooni/probe-cli/pull/539.

What remains to be done, after this diff has landed is to ensure
things also work for ooniprobe and oonimkall.
2021-12-03 15:30:56 +01:00
Simone Basso
fdbf871103
[forwardport] ci/cd: publish binaries onto a release when we create a tag (#609) (#611)
This diff forwardports 856e436e20d511a4f0d618546da7921fa9f8c5f6 to the master branch

Original commit message:

- - -

This pull request changes `mk` and github workflows to build and publish binaries on tag. We also update the documentation to explain this new branching model. Basically, we have release branches where we produce binary packages and we add extra code, on tag, to publish such packages inside a release.

We discussed removing most secrets from builds in this repository and having a different tool/repository that takes in input also secrets for doing follow-up actions after publishing. As a consequence, this pull request also removes all pieces of code that require secrets. The next step is to reinstate this code in this new repository/tool.

The existing code in `mk` also implemented caching. This feature was useful when doing local builds because it reduced the time required to obtain binary releases. With builds running as part of GitHub actions, we don't need caching because we spawn parallel machines to build binaries. Therefore, let us also remove caching, which makes the code simpler. (Caching in itself is hard and in https://github.com/ooni/probe/issues/1875 I noted that, for example, caching of the `ooni/go` repository was leading to some unwanted behaviour when changing the branch. Without caching, this behaviour is gone and we always generally use fresh information to produce builds.) Of course, this means that local builds are now slower, but I do not think this is a problem _because_ we want to use GitHub actions for building in the common case.

Reference issues: https://github.com/ooni/probe/issues/1879 and https://github.com/ooni/probe/issues/1875.

The final aspect to mention to conclude this description is an implementation one:

```
          gh release create -p $tag --target $GITHUB_SHA || true
```

The code above uses `|| true` because there could already be a release. So, basically, it means that, if a release does not already exist, then we're going to create one. Otherwise, it does not matter because there's already a release.
2021-11-23 15:56:25 +01:00
Simone Basso
264e30f016
[forwardport] fix(mk): do nothing if we already have psiphon config (#605) (#606)
This diff forward ports ea44e99451f345474738b9010ff791759a1f1367.

Original commit message:

- - -

This change allows for producing cloud builds using the psiphon
config files. We will add those files as build secrets. Only people
in the organization and collaborators with at least "write"
access could trigger builds containing such secrets.

Before this change, `./mk` unconditionally attempted to clone
github.com/ooni/probe-private. Now, it only checks whether
we need to clone _if_ files are not already there.

This allows us to use GitHub actions and secrets to copy the
files in there _without_ needing to clone a private repo.

Cloning a private repo would require us to include as repository
secret an access token with full `repo` scope, which is a very
broad scope. Instead, by using secrets to include psiphon config,
we are narrowing down the secrets required to make a release build.

See https://github.com/ooni/probe/issues/1878

This diff WILL require forward porting to the master branch.
2021-11-19 12:40:10 +01:00
Simone Basso
0a322ebab0
[forwardport] fix: avoid http3 for dns.google and www.google.com (#593) (#594)
This commit forward ports dedd84fa7ecb09f718f6b1a9c83999cb37b34dfa.

Original commit message:

- - -

This diff changes code the release/3.11 branch to ensure we're not using dns.google and www.google.com over HTTP3. As documented in https://github.com/ooni/probe/issues/1873, since this morning (approx) these services do not support HTTP3 anymore. (I didn't bother with checking whether this issue affects _other_ Google services; I just limited my analysis to the services that we were using as part of testing.)

This patch WILL require forward porting to the master branch.
2021-11-12 14:43:28 +01:00
Simone Basso
6f90d29bfa
feat(miniooni): add the --censor flag (#571)
This flag is similar to the previous --self-censor-spec and tells
miniooni what censorship to implement for itself.

This concludes the design at https://github.com/ooni/probe/issues/1803#issuecomment-957323297
2021-11-03 14:23:47 +01:00
Simone Basso
1f0fcafb8a
fix: ensure we bind oohelperd with the repo's version number (#558)
Work related to https://github.com/ooni/probe/issues/1506#issuecomment-949715707.

This diff cherry-picks from the release/3.11 branch.
2021-10-22 17:21:38 +02:00
Simone Basso
2fa87f0e00
fix(wcth): match legacy TH w/ empty DNS reply (#546)
See https://github.com/ooni/probe/issues/1707#issuecomment-944322725
2021-10-15 16:20:07 +02:00
Simone Basso
2d1666b88b
fix(wcth): emit empty Addrs when input URL contains addr (#545)
Matches the behavior that the legacy TH implements in this
situation and reduces slightly the differences.

See https://github.com/ooni/probe/issues/1707#issuecomment-944143329
2021-10-15 12:00:20 +02:00
Simone Basso
4b8cae692b
fix(oohelperd): reduce errors to what the old TH would emit (#543)
Reducing the errors is not done in a perfect way.

We have documented the most striking differences inside
https://github.com/ooni/probe/issues/1707#issuecomment-942283746 and
some attempts to improve the situation further inside
https://github.com/ooni/probe/issues/1707#issuecomment-942341255.

A better strategy for the future would be to introduce more
specific timeout errors, such as dns_timeout_error, etc.

More testing may be needed to further validate and compare the
old and the new TH, but this requires Jafar improvements to
more precisely simulate more complex censorship.
2021-10-13 16:37:02 +02:00
Simone Basso
9e365661f0
fix(oohelperd): return HTTP headers as empty map on error (#541)
Part of https://github.com/ooni/probe/issues/1707
2021-10-13 13:27:09 +02:00
Simone Basso
ba9151d4fa
feat(webstepsx): websteps using measurex (#530)
This diff adds the prototype websteps implementation that used
to live at https://github.com/ooni/probe-cli/pull/506.

The code is reasonably good already and it's pointing to a roaming
test helper that I've properly configured.

You can run websteps with:

```
./miniooni -n websteps
```

This will go over the test list for your country.

At this stage the mechanics of the experiment is set, but we
still need to have a conversation on the following topics:

1. whether we're okay with reusing the data format used by other
OONI experiments, or we would like to use a more compact data
format (which may either be a more compact JSON or we can choose
to always submit compressed measurements for websteps);

2. the extent to which we would like to keep the measurement as
a collection of "the experiment saw this" and "the test helper
saw that" and let the pipeline choose an overall score: this is
clearly an option, but there is also the opposite option to
build a summary of the measurement on the probe.

Compared to the previous prototype of websteps, the main
architectural change we have here is that we are following
the point of view of the probe and the test helper is
much more dumb. Basically, the probe will choose which
redirection to follow and ask the test helper every time
it discovers a new URL to measure it w/o redirections.

Reference issue: https://github.com/ooni/probe/issues/1733
2021-09-30 02:06:27 +02:00
Simone Basso
ff1c170562
feat(engine): allow runner to return many measurements (#527)
This is required to implement websteps, which is currently tracked
by https://github.com/ooni/probe/issues/1733.

We introduce the concept of async runner. An async runner will
post measurements on a channel until it is done. When it is done,
it will close the channel to notify the reader about that.

This change causes sync experiments now to strictly return either
a non-nil measurement or a non-nil error.

While this is a pretty much obvious situation in golang, we had
some parts of the codebase that were not robust to this assumption
and attempted to submit a measurement after the measure call
returned an error.

Luckily, we had enough tests to catch this change in our assumption
and this is why there are extra docs and tests changes.
2021-09-30 00:54:52 +02:00
Simone Basso
6d3a4f1db8
refactor: merge dnsx and errorsx into netxlite (#517)
When preparing a tutorial for netxlite, I figured it is easier
to tell people "hey, this is the package you should use for all
low-level networking stuff" rather than introducing people to
a set of packages working together where some piece of functionality
is here and some other piece is there.

Part of https://github.com/ooni/probe/issues/1591
2021-09-28 12:42:01 +02:00
Simone Basso
985c1ba761
fix(oohelperd): reduce differences with legacy helper (#504)
Part of https://github.com/ooni/probe/issues/1707
2021-09-27 08:13:30 +02:00
Simone Basso
254a5511e9
doc(oohelper): tweak documentation (#499)
Part of https://github.com/ooni/probe/issues/1733
2021-09-09 19:55:23 +02:00
Simone Basso
c54cc73afa
refactor(oohelper): remove unnecessary dep from netx (#498)
There are a bunch of packages where we don't really need to depend
on netx but we can use local definitions that describe what we are
expecting from data structures we receive in input. This diff
addresses one of such cases.

Part of https://github.com/ooni/probe/issues/1591
2021-09-09 19:40:03 +02:00
Simone Basso
b5826a0c44
refactor(jafar): remove unnecessary dep on netx (#497) 2021-09-09 18:01:20 +02:00
Simone Basso
1d79d70b43
refactor: migrate apitool from netx to netxlite (#496)
I discovered which transport were used by apitool and made sure he gets the same transports now. While there, I discovered an issue with ooni/oohttp that has been fixed with cba9b1ce5e.

Part of https://github.com/ooni/probe/issues/1591
2021-09-09 01:19:17 +02:00
Simone Basso
e68adec9a5
fix(netxlite): http3 transport needs logging by default (#492)
Adapt other places where it was not using a logger to either choose
a reasonable logger or disable logging for backwards compat.

See https://github.com/ooni/probe/issues/1591
2021-09-08 20:49:01 +02:00
Simone Basso
83440cf110
refactor: split errorsx in good and legacy (#477)
The legacy part for now is internal/errorsx. It will stay there until
I figure out whether it also needs some extra bug fixing.

The good part is now in internal/netxlite/errorsx and contains all the
logic for mapping errors. We need to further improve upon this logic
by writing more thorough integration tests for QUIC.

We also need to copy the various dialer, conn, etc adapters that set
errors. We will put them inside netxlite and we will generate errors in
a way that is less crazy with respect to the major operation. (The
idea is to always wrap, given that now we measure in an incremental way
and we don't measure every operation together.)

Part of https://github.com/ooni/probe/issues/1591
2021-09-07 17:09:30 +02:00
Simone Basso
b9c4ad0b2b
fix(netxlite): http3 propagates CloseIdleConnections to its dialer (#471)
With this change, we are now able to change more dependent code to simplify
the way in which we create and manage resolvers.

See https://github.com/ooni/probe/issues/1591
2021-09-06 21:52:00 +02:00
Simone Basso
7a9499fee3
refactor(dialer): it should close idle connections (#457)
Like we did before for the resolver, a dialer should propagate the
request to close idle connections to underlying types.

See https://github.com/ooni/probe/issues/1591
2021-09-05 19:55:28 +02:00
Simone Basso
a3654f60b7
refactor(netxlite): add more functions to resolver (#455)
We would like to refactor the code so that a DoH resolver owns the
connections of its underlying HTTP client.

To do that, we need first to incorporate CloseIdleConnections
into the Resolver model. Then, we need to add the same function
to all netxlite types that wrap a Resolver type.

At the same time, we want the rest of the code for now to continue
with the simpler definition of a Resolver, now called ResolverLegacy.

We will eventually propagate this change to the rest of the tree
and simplify the way in which we manage Resolvers.

To make this possible, we introduce a new factory function that
adapts a ResolverLegacy to become a Resolver.

See https://github.com/ooni/probe/issues/1591.
2021-09-05 18:03:50 +02:00
Simone Basso
2e0118d1a6
refactor(netxlite): hide details without breaking the rest of the tree (#454)
## Description

This PR continues the refactoring of `netx` under the following principles:

1. do not break the rest of the tree and do not engage in extensive tree-wide refactoring yet
2. move under `netxlite` clearly related subpackages (e.g., `iox`, `netxmocks`)
3. move into `internal/netxlite/internal` stuff that is clearly private of `netxlite`
4. hide implementation details in `netxlite` pending new factories
5. refactor `tls` code in `netxlite` to clearly separate `crypto/tls` code from `utls` code

After each commit, I run `go test -short -race ./...` locally. Each individual commit explains what it does. I will squash, but this operation will preserve the original commit titles, so this will give further insight on each step.

## Commits

* refactor: rename netxmocks -> netxlite/mocks

Part of https://github.com/ooni/probe/issues/1591

* refactor: rename quicx -> netxlite/quicx

See https://github.com/ooni/probe/issues/1591

* refactor: rename iox -> netxlite/iox

Regenerate sources and make sure the tests pass.

See https://github.com/ooni/probe/issues/1591.

* refactor(iox): move MockableReader to netxlite/mocks

See https://github.com/ooni/probe/issues/1591

* refactor(netxlite): generator is an implementation detail

See https://github.com/ooni/probe/issues/1591

* refactor(netxlite): separate tls and utls code

See https://github.com/ooni/probe/issues/1591

* refactor(netxlite): hide most types but keep old names as legacy

With this change we avoid breaking the rest of the tree, but we start
hiding some implementation details a bit. Factories will follow.

See https://github.com/ooni/probe/issues/1591
2021-09-05 14:49:38 +02:00
Simone Basso
ae799c4942
fix: completely remove support for h3-29 (#453)
The quic-go library does not support it anymore. So, let us be consistent
and remove any reference to h3-29 from our codebase.

Closes https://github.com/ooni/probe/issues/1740.
2021-09-05 12:57:48 +02:00
Simone Basso
276beb8719
fix(oohelper): do not stop if DNS fails locally (#450)
When a probe gets a local DNS failure, it will continue and nonetheless
query the test helper without any IP address, just an empty list.

This diff fixes the behavior of cmd/oohelper to do the same.

Work part of https://github.com/ooni/probe/issues/1707.
2021-09-05 12:06:02 +02:00
kelmenhorst
1874f7a7c2
enable utls for websteps (#442)
This diff enables `websteps` to use uTLS for TLS parroting. It integrates the `oohttp.StdlibTransport` wrapper which uses the `ooni/oohttp` fork. `oohttp` supports TLS-like connections like `utls.Conn`.
As a prototype, the testhelper and `websteps` code now uses the `utls.HelloChrome_Auto` fingerprint, i.e. the simulated TLS fingerprint of the Google Chrome browser.

It is a further contribution for my GSoC project.

Reference issue: https://github.com/ooni/probe/issues/1733
2021-08-18 16:10:27 +02:00
Simone Basso
f18a9852db
doc: mention the test helper spec we're using (#436)
See https://github.com/ooni/probe/issues/1729
2021-08-17 12:52:51 +02:00
Simone Basso
f2b6a5972f
refactor: sync messages with spec draft (#435)
Work part of: https://github.com/ooni/probe/issues/1733

Spec draft: https://github.com/ooni/spec/pull/219
2021-08-17 11:56:36 +02:00
Simone Basso
ce854e8ae1
refactor(oohelperd): better distinguish different helpers (#434)
Part of https://github.com/ooni/probe/issues/1733
2021-08-17 11:23:53 +02:00
Simone Basso
bef5b87a8a
refactor: fully move IDNAResolver to netxlite (#433)
We started doing this in https://github.com/ooni/probe-cli/pull/432.

This work is part of https://github.com/ooni/probe/issues/1733.
2021-08-17 11:02:12 +02:00
kelmenhorst
c31591f298
cli: new testhelper and the websteps experiment prototype (#432)
This is the extension of https://github.com/ooni/probe-cli/pull/431, and my final deliverable for GSoC 2021.

The diff introduces:

1) The new `testhelper` which supports testing multiple IP endpoints per domain and introduces HTTP/3 control measurements. The specification of the `testhelper` can be found at https://github.com/ooni/spec/pull/219. The `testhelper` algorithm consists of three main steps:

   * `InitialChecks` verifies that the input URL can be parsed, has an expected scheme, and contains a valid domain name.

   * `Explore` enumerates all the URLs that it discovers by redirection from the original URL, or by detecting h3 support at the target host.

   * `Generate` performs a step-by-step measurement of each discovered URL.

2) A prototype of the corresponding new experiment `websteps` which uses the control measurement of the `testhelper` to know which URLs to measure, and what to expect. The prototype does not yet have:

   * unit and integration tests,

   * an analysis tool to compare the control and the probe measurement.

This PR is my final deliverable as it is the outcome of the trials, considerations and efforts of my GSoC weeks at OONI. 
It fully integrates HTTP/3 (QUIC) support which has been only used in the `urlgetter` experiment until now.

Related issues: https://github.com/ooni/probe/issues/1729 and https://github.com/ooni/probe/issues/1733.
2021-08-17 10:29:06 +02:00
Simone Basso
6b7d270bda
refactor: move tls handshaker to netxlite (#400)
Part of https://github.com/ooni/probe/issues/1505
2021-06-25 11:07:26 +02:00
Simone Basso
8a0beee808
refactor: start pivoting netx (#396)
What do I mean by pivoting? Netx is currently organized by row:

```
               | dialer | quicdialer | resolver | ...
 saving        |        |            |          | ...
 errorwrapping |        |            |          | ...
 logging       |        |            |          | ...
 mocking/sys   |        |            |          | ...
```

Every row needs to implement saving, errorwrapping, logging, mocking (or
adapting to the system or to some underlying library).

This causes cross package dependencies and, in turn, complexity. For
example, we need the `trace` package for supporting saving.

And `dialer`, `quickdialer`, et al. need to depend on such a package.

The same goes for errorwrapping.

This arrangement further complicates testing. For example, I am
currently working on https://github.com/ooni/probe/issues/1505 and
I realize it need to repeat integration tests in multiple places.

Let's say instead we pivot the above matrix as follows:

```
             | saving | errorwrapping | logging | ...
 dialer      |        |               |         | ...
 quicdialer  |        |               |         | ...
 logging     |        |               |         | ...
 mocking/sys |        |               |         | ...
 ...
```

In this way, now every row contains everything related to a specific
action to perform. We can now share code without relying on extra
support packages. What's more, we can write tests and, judding from
the way in which things are made, it seems we only need integration
testing in `errorwrapping` because it's where data quality matters
whereas, in all other cases, unit testing is fine.

I am going, therefore, to proceed with these changes and "pivot"
`netx`. Hopefully, it won't be too painful.
2021-06-23 15:53:12 +02:00
Federico Ceratto
8e26dbae8e
oohelperd packaging and CI (#374)
Closes https://github.com/ooni/backend/issues/499

Co-authored-by: Simone Basso <bassosimone@gmail.com>
2021-06-15 15:53:22 +02:00
Simone Basso
fd5405ade1
cleanup(all): stop using deprecated ioutil functions (#381)
Spotted while working on https://github.com/ooni/probe/issues/1417

See https://golang.org/pkg/io/ioutil/
2021-06-15 14:01:45 +02:00
Simone Basso
0fdc9cafb5
fix(all): introduce and use iox.ReadAllContext (#379)
* fix(all): introduce and use iox.ReadAllContext

This improvement over the ioutil.ReadAll utility returns early
if the context expires. This enables us to unblock stuck code in
case there's censorship confounding the TCP stack.

See https://github.com/ooni/probe/issues/1417.

Compared to the functionality postulated in the above mentioned
issue, I choose to be more generic and separate limiting the
maximum body size (not implemented here) from using the context
to return early when reading a body (or any other reader).

After implementing iox.ReadAllContext, I made sure we always
use it everywhere in the tree instead of ioutil.ReadAll.

This includes many parts of the codebase where in theory we don't
need iox.ReadAllContext. Though, changing all the places makes
checking whether we're not using ioutil.ReadAll where we should
not be using it easy: `git grep` should return no lines.

* Update internal/iox/iox_test.go

* fix(ndt7): treat context errors as non-errors

The rationale is explained by the comment documenting reduceErr.

* Update internal/engine/experiment/ndt7/download.go
2021-06-15 11:57:40 +02:00
Simone Basso
85c71c09dc
feat: introduce ptx package for pluggable transports dialers (#373)
* feat: introduce ptx package for pluggable transports dialers

Version 2 of the pluggable transports specification defines a function
that's like `Dial() (net.Conn, error`).

Because we use contexts as much as possible in `probe-cli`, we are
wrapping such an interface into a `DialContext` func.

The code for obfs4 is adapted from https://github.com/ooni/probe-cli/pull/341.

The code for snowflake is significantly easier than it is in
https://github.com/ooni/probe-cli/pull/341, because now Snowflake
supports the PTv2 spec (thanks @cohosh!).

The code for setting up a pluggable transport listener has also
been adapted from https://github.com/ooni/probe-cli/pull/341.

We cannot merge this code yet, because we need unit testing, yet the
newly added code already seems suitable for these use cases:

1. testing by dialing and seeing whether we can dial (which is not
very useful but still better than not doing it);

2. spawning tor+pluggable transports for circumvention (we need a
little more hammering like we did in https://github.com/ooni/probe-cli/pull/341,
which is basically https://github.com/ooni/probe/issues/1565, and then
we will be able to do that, as demonstrated by the new, simple client which
already allows us to use pluggable transports with tor);

3. testing by launching tor (when available) with a set of
pluggable transports (which depends on https://github.com/ooni/probe-engine/issues/897
and has not been assigned an issue yet).

* fix: tweaks after self code-review

* feat: write quick tests for ptx/obfs4

(They run in 0.4s, so I think it's fine for them to always run.)

* feat(ptx/snowflake): write unit and integration tests

* feat: create a fake PTDialer

The idea is that we'll use this simpler PTDialer for testing.

* feat: finish writing tests for new package

* Apply suggestions from code review

* Update internal/ptx/dependencies_test.go

Co-authored-by: Arturo Filastò <arturo@openobservatory.org>

* Update internal/ptx/dependencies_test.go

Co-authored-by: Arturo Filastò <arturo@openobservatory.org>

* chore: use as testing bridge one that's used by tor browser

The previous testing bridge used to be used by tor browser but
it was subsequently removed here:

e26e91bef8

See https://github.com/ooni/probe-cli/pull/373#discussion_r649820724

Co-authored-by: Arturo Filastò <arturo@openobservatory.org>
2021-06-14 10:20:54 +02:00
Simone Basso
adbde7246b
refactor(netx): remove the self censorship mechanism (#364)
We're currently use jafar for QA and jafar is a better mechanism,
even though it is not portable outside of Linux.

This self censorship mechanism was less cool and added a bunch
of (also cognitive) complexity to netx.

If we ever want to go down a self censorship like road, we probably
want to do as little work as possible in the problem and as much
work as possible inside a helper like jafar.

Part of https://github.com/ooni/probe/issues/1591.
2021-06-08 19:40:17 +02:00
Simone Basso
39aec6677d
cleanup(shellx): do not directly depend on apex/log (#357) 2021-06-04 14:02:18 +02:00
Simone Basso
33de701263
refactor: flatten and separate (#353)
* refactor(atomicx): move outside the engine package

After merging probe-engine into probe-cli, my impression is that we have
too much unnecessary nesting of packages in this repository.

The idea of this commit and of a bunch of following commits will instead
be to reduce the nesting and simplify the structure.

While there, improve the documentation.

* fix: always use the atomicx package

For consistency, never use sync/atomic and always use ./internal/atomicx
so we can just grep and make sure we're not risking to crash if we make
a subtle mistake on a 32 bit platform.

While there, mention in the contributing guidelines that we want to
always prefer the ./internal/atomicx package over sync/atomic.

* fix(atomicx): remove unnecessary constructor

We don't need a constructor here. The default constructed `&Int64{}`
instance is already usable and the constructor does not add anything to
what we are doing, rather it just creates extra confusion.

* cleanup(atomicx): we are not using Float64

Because atomicx.Float64 is unused, we can safely zap it.

* cleanup(atomicx): simplify impl and improve tests

We can simplify the implementation by using defer and by letting
the Load() method call Add(0).

We can improve tests by making many goroutines updated the
atomic int64 value concurrently.

* refactor(fsx): can live in the ./internal pkg

Let us reduce the amount of nesting. While there, ensure that the
package only exports the bare minimum, and improve the documentation
of the tests, to ease reading the code.

* refactor: move runtimex to ./internal

* refactor: move shellx into the ./internal package

While there, remove unnecessary dependency between packages.

While there, specify in the contributing guidelines that
one should use x/sys/execabs instead of os/exec.

* refactor: move ooapi into the ./internal pkg

* refactor(humanize): move to ./internal and better docs

* refactor: move platform to ./internal

* refactor(randx): move to ./internal

* refactor(multierror): move into the ./internal pkg

* refactor(kvstore): all kvstores in ./internal

Rather than having part of the kvstore inside ./internal/engine/kvstore
and part in ./internal/engine/kvstore.go, let us put every piece of code
that is kvstore related into the ./internal/kvstore package.

* fix(kvstore): always return ErrNoSuchKey on Get() error

It should help to use the kvstore everywhere removing all the
copies that are lingering around the tree.

* sessionresolver: make KVStore mandatory

Simplifies implementation. While there, use the ./internal/kvstore
package rather than having our private implementation.

* fix(ooapi): use the ./internal/kvstore package

* fix(platform): better documentation
2021-06-04 10:34:18 +02:00
Simone Basso
c5ad5eedeb
feat: create tunnel inside NewSession (#286)
* feat: create tunnel inside NewSession

We want to create the tunnel when we create the session. This change
allows us to nicely ignore the problem of creating a tunnel when we
already have a proxy, as well as the problem of locking. Everything is
happening, in fact, inside of the NewSession factory.

Modify miniooni such that --tunnel is just syntactic sugar for
--proxy, at least for now. We want, in the future, to teach the
tunnel to possibly use a socks5 proxy.

Because starting a tunnel is a slow operation, we need a context in
NewSession. This causes a bunch of places to change. Not really a big
deal except we need to propagate the changes.

Make sure that the mobile code can create a new session using a
proxy for all the APIs we support.

Make sure all tests are still green and we don't loose coverage of
the various ways in which this code could be used.

This change is part of https://github.com/ooni/probe/issues/985.

* changes after merge

* fix: only keep tests that can hopefully work

While there, identify other places where we should add more
tests or fix integration tests.

Part of https://github.com/ooni/probe/issues/985
2021-04-05 15:28:13 +02:00
Simone Basso
a849213b59
fix(engine): break circular dep betwen session and tunnel (#295)
This diff breaks the circular dependency between session and
tunnel, by introducing the concept of early session.

An early session is a session that is able to fetch the psiphon
configuration file _only_ if it's embedded in the binary.

This breaks `miniooni --tunnel=psiphon` for users who have
access to the OONI backend. They are not the users we are
writing this feature for, though, so I think this is reasonable.

At the same time, this opens up the possibility of creating
a psiphon tunnel when constructing a session, which is the
approach I was following in https://github.com/ooni/probe-cli/pull/286.

This work is part of https://github.com/ooni/probe/issues/985.

Once this diff is in, I can land https://github.com/ooni/probe-cli/pull/286.
2021-04-05 12:02:35 +02:00
Simone Basso
8fe4e5410d
feat(tunnel): introduce persistent tunnel state dir (#294)
* feat(tunnel): introduce persistent tunnel state dir

This diff introduces a persistent state directory for tunnels, so that
we can bootstrap them more quickly after the first time.

Part of https://github.com/ooni/probe/issues/985

* fix: make tunnel dir optional

We have many tests where it does not make sense to explicitly
provide a tunnel dir because we're not using tunnels.

This should simplify setting up a session.

* fix(tunnel): repair tests

* final changes

* more cleanups
2021-04-05 11:27:41 +02:00
Simone Basso
51459e23b2
fix(oohelper): make sure the CI is green (#282)
* chore(oohelper): increase tests verbosity

Hopefully this helps with https://github.com/ooni/probe/issues/1409.

* fix(oohelper): use a nonstandard resolver

* fix previous

* make the diff pleasant/committable/correct
2021-04-01 20:11:13 +02:00
Simone Basso
31e478b04e
refactor: redesign how we import assets (#260)
* fix(pkg.go.dev): import a subpackage containing the assets

We're trying to fix this issue that pkg.go.dev does not build.

Thanks to @hellais for this very neat idea! Let's keep our
fingers crossed and see whether it fixes!

* feat: use embedded geoip databases

Closes https://github.com/ooni/probe/issues/1372.

Work done as part of https://github.com/ooni/probe/issues/1369.

* fix(assetsx): add tests

* feat: simplify and just vendor uncompressed DBs

* remove tests that seems not necessary anymore

* fix: run go mod tidy

* Address https://github.com/ooni/probe-cli/pull/260/files#r605181364

* rewrite a test in a better way

* fix: gently cleanup the legacy assetsdir

Do not remove the whole directory with brute force. Just zap the
files whose name we know. Then attempt to delete the legacy directory
as well. If not empty, just fail. This is fine because it means the
user has stored other files inside the directory.

* fix: create .miniooni if missing
2021-04-01 16:57:31 +02:00
Simone Basso
a0763756b2
fix(miniooni): replace --limit with --max-runtime (#272)
Part of https://github.com/ooni/probe/issues/1299
2021-03-29 20:38:23 +02:00
Simone Basso
b718335ee3
refactor(inputloader): remove unnecessary javisms (#271)
Part of https://github.com/ooni/probe/issues/1299.
2021-03-29 20:00:50 +02:00
Simone Basso
f5b5ac47b0
refactor: merge libminiooni into cmd/miniooni (#268)
We used to have an external package called libminiooni so that
third parties could use it. We wrote this such that we could
support github.com/bassosimone/aladdin.

That was actually a not-so-good idea because it added to the APIs
we needed to maintain.

Since the merge of engine into cli, such an API is not public
anymore and aladdin has been deprecated and archived.

Therefore, we can now cleanup the situation and merge libminiooni
into miniooni again, thus making the codebase more local.

This cleanup has been identified while working on
https://github.com/ooni/probe/issues/1299.
2021-03-29 19:03:53 +02:00
Simone Basso
322394fe63
feat: use go1.16 and resources embedding (#235)
* feat: use go1.16 embedding for resources

We want to embed everything that can be easily embedded. We should, at a
minimum, replace the downloading of resources and bindata.

Ref: https://github.com/ooni/probe/issues/1367.

* fix: get rid of bindata and use go embed instead

* fix: start unbreaking some automatic tests

* fix: fetch resources as part of the mobile build

* fix: convert more stuff to go1.16

I still expect many breakages, but we'll fix them.

* fix: make the windows CI green

* fix: get resources before running QA

* fix: go1.16 uses modules by default

* hopefully fix all other outstanding issues

* fix(QA/telegram.py): add another DC IP address

* Apply suggestions from code review
2021-03-02 12:08:24 +01:00
Simone Basso
18ca6d5f35
fix: use golang.org/x/sys/execabs (#224)
Closes https://github.com/ooni/probe-engine/issues/1195
2021-02-10 07:40:48 +01:00
Simone Basso
f53b3be66e
feat: add end-to-end testing to this repository (#220)
* feat: add end-to-end testing to this repository

Part of https://github.com/ooni/probe-engine/issues/1181

Motivation: we want to run this check from the repository where
we work the most, such that it's unlikely it pauses due to inactivity,
as it may happen for less frequently touched upon repositories.

Code adapted from https://github.com/ooni/e2etesting/

* fix: correct name for main branch
2021-02-04 14:25:03 +01:00
Simone Basso
26d807c50f
fix: always use probe-cli version (and make it alpha) (#219)
See https://github.com/ooni/probe-engine/issues/1181

While there, run `go fmt ./...`
2021-02-04 11:00:27 +01:00
Simone Basso
31cf7d2fdf
doc: ensure all top dirs have an explanatory README (#214)
* doc: ensure all top dirs have an explanatory README

This makes the repository a lil bit nicer to newcomers.

Part of https://github.com/ooni/probe/issues/1335

* fix: re-run bindata to embed the README

The readme is small, so we can pay the price of adding it.

On a related note, I am very pleased the Go team implemented the
`//go:embed` feature, so we can get rid of this bindata thing.
2021-02-03 16:54:00 +01:00
Simone Basso
4eeadd06a5
refactor: move more commands to internal/cmd (#207)
* refactor: move more commands to internal/cmd

Part of https://github.com/ooni/probe/issues/1335.

We would like all commands to be at the same level of engine
rather than inside engine (now that we can do it).

* fix: update .gitignore

* refactor: also move jafar outside engine

* We should be good now?
2021-02-03 12:23:15 +01:00
Simone Basso
6351d898d6
refactor: miniooni should be outside of the engine (#206)
* refactor: miniooni should be outside of the engine

This is part of https://github.com/ooni/probe/issues/1335. We also need
to think whether we wanna keep libminiooni and miniooni separated.

The previous use case for having a top-level libminiooni was that of
enabling others to integrate miniooni into other binaries.

This was usegul when studying internet censorship in Spain in May 2020.

I am wondering whether we should be keeping this complexity. I am not
sure about this and probably we should be killing it.

(In any case, reducing complexity is not the objective of this diff,
since I would like instead to move things around with minimal changes
and make sure we have a ~good repository organization here.)

* fix: import in libminiooni
2021-02-03 11:21:10 +01:00