# Using the measurex package to write network experiments This tutorial teaches you how to write OONI network experiments using the primitives in the `./internal/measurex` package. The name of this package means either "measure extensions" or "measure crossover". The measure extension interpretation of the name explains what this package does. It contains extensions to our basic networking code (`./internal/netxlite`) that allow us to perform OONI measurements. The measure crossover interpretation explains its history. Since OONI has been written in Go, we've mostly performed measurements using "tracing". That is, by registering hooks that run when specific operations happen (e.g., TCP connect or TLS handshake) and then making sense of the network trace. This is the approach with which most experiments are written as of 2021-09-24. But we have also seen that in several cases a step-by-step approach is preferrable. Under this approach, you perform individual operations and record their result right away. So, for example, you have a connection and a TLS config, you perform a TLS handshake, and immediately after you create and store somewhere a data structure containing the result. This package is at the crossover of these two approaches, because basically it contains enough primitives to support both. What we are going to do in this tutorial is the following: - we will start from very simple-step-by-step measurements such as TCP connect, DNS lookup, and TLS handshake; - we will see how `measurex` provides support for composing these primitives in larger steps, which will lead us to eventually perform all the measurements that matter for a given input URL (including discovering QUIC endpoints and following redirections); - finally, as an exercise, we will use the knowledge acquired in the rest of the tutorial to rewrite a subset of the Web Connectivity experiment (as of 2021-09-24 the flagship OONI experiment). This will be an opportunity to explore more low level aspects of `measurex`. As part of the process, we'll introduce you to the data format used by OONI and there will be proposed exercises where we simulate censorship conditions and we see how that impacts the generated measurements. Every chapter will show how to write a simple `main.go` program that explains how to use some primitives. The chapter text itself is autogenerated from comments inside the actual `main.go` the we describe in the chapter. For this reason, if you need to change a chapter, you need to change the corresponding `main.go` file and then follow the instructions at `./internal/tutorial/generate` to regenerate the markdown text of the chapter. More in detail, here's the index: - [chapter01](chapter01) explains how to use the "system" resolver - [chapter02](chapter02) deals with establishing TCP connections - [chapter03](chapter03) is about using custom DNS-over-UDP resolvers - [chapter04](chapter04) shows how to measure TLS handshakes - [chapter05](chapter05) is about the QUIC handshake - [chapter06](chapter06) shows how to get a webpage knowing its URL and the endpoint (i.e., IP address and TCP/UDP port) - [chapter07](chapter07) shows how to extend what we did in chapter06 to cover _all_ the IP addresses in the URL's domain - [chapter08](chapter08) is about HTTPSSvc DNS queries and how they can be used to discover and test QUIC endpoints, thus extending the work done in chapter07 - [chapter09](chapter09) improves upon chapter08 showing how to run endpoints measurements in parallel - [chapter10](chapter10) improves upon chapter09 by also running DNS queries in parallel - [chapter11](chapter11) tells you that all the code we have been writing so far, and specifically the code we have in chapter10, is actually the implementation of an API of `measurex` called `MeasureURL`, and then shows you how you can simplify the code in chapter10 by using this API. - [chapter12](chapter12) extends the work done in chapter11 by teaching you about a more high-level API that discovers and follows all redirections, calling `MeasureURL` for each redirection. - [chapter13](chapter13) contains the exercise regarding rewriting WebConnectivity using all the tools you have learned so far and pointing you at additional `measurex` API that could be useful to solve the problem. - [chapter14](chapter14) contains our solution to the exercise.