Skip to content

Commit

Permalink
fix: rename beacons to bridges (#1349)
Browse files Browse the repository at this point in the history
They're quack like bridges, OONI bridges. Also, name the config file
from the PoV of the user.

Part of ooni/probe#2531.
  • Loading branch information
bassosimone authored Oct 6, 2023
1 parent f29dbba commit cf67bdb
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package enginenetx

//
// beacons policy - a policy where we treat some IP addresses as special for
// bridges policy - a policy where we treat some IP addresses as special for
// some domains, bypassing DNS lookups and using custom SNIs
//

Expand All @@ -11,31 +11,31 @@ import (
"time"
)

// beaconsPolicy is a policy where we use beacons for communicating
// bridgesPolicy is a policy where we use bridges for communicating
// with the OONI backend, i.e., api.ooni.io.
//
// A beacon is an IP address that can route traffic from and to
// A bridge is an IP address that can route traffic from and to
// the OONI backend and accepts any SNI.
//
// The zero value is invalid; please, init MANDATORY fields.
type beaconsPolicy struct {
type bridgesPolicy struct {
// Fallback is the MANDATORY fallback policy.
Fallback httpsDialerPolicy
}

var _ httpsDialerPolicy = &beaconsPolicy{}
var _ httpsDialerPolicy = &bridgesPolicy{}

// LookupTactics implements httpsDialerPolicy.
func (p *beaconsPolicy) LookupTactics(ctx context.Context, domain, port string) <-chan *httpsDialerTactic {
func (p *bridgesPolicy) LookupTactics(ctx context.Context, domain, port string) <-chan *httpsDialerTactic {
out := make(chan *httpsDialerTactic)

go func() {
defer close(out) // tell the parent when we're done
index := 0

// emit beacons related tactics first which are empty if there are
// no beacons for the givend domain and port
for tx := range p.beaconsTacticsForDomain(domain, port) {
// emit bridges related tactics first which are empty if there are
// no bridges for the givend domain and port
for tx := range p.bridgesTacticsForDomain(domain, port) {
tx.InitialDelay = happyEyeballsDelay(index)
index += 1
out <- tx
Expand All @@ -56,7 +56,7 @@ func (p *beaconsPolicy) LookupTactics(ctx context.Context, domain, port string)
return out
}

var beaconsPolicyTestHelpersDomains = []string{
var bridgesPolicyTestHelpersDomains = []string{
"0.th.ooni.org",
"1.th.ooni.org",
"2.th.ooni.org",
Expand All @@ -65,7 +65,7 @@ var beaconsPolicyTestHelpersDomains = []string{
}

// TODO(bassosimone): this would be slices.Contains when we'll use go1.21
func beaconsPolicySlicesContains(slice []string, value string) bool {
func bridgesPolicySlicesContains(slice []string, value string) bool {
for _, entry := range slice {
if value == entry {
return true
Expand All @@ -74,22 +74,22 @@ func beaconsPolicySlicesContains(slice []string, value string) bool {
return false
}

func (p *beaconsPolicy) maybeRewriteTestHelpersTactics(input <-chan *httpsDialerTactic) <-chan *httpsDialerTactic {
func (p *bridgesPolicy) maybeRewriteTestHelpersTactics(input <-chan *httpsDialerTactic) <-chan *httpsDialerTactic {
out := make(chan *httpsDialerTactic)

go func() {
defer close(out) // tell the parent when we're done

for tactic := range input {
// When we're not connecting to a TH, pass the policy down the chain unmodified
if !beaconsPolicySlicesContains(beaconsPolicyTestHelpersDomains, tactic.VerifyHostname) {
if !bridgesPolicySlicesContains(bridgesPolicyTestHelpersDomains, tactic.VerifyHostname) {
out <- tactic
continue
}

// This is the case where we're connecting to a test helper. Let's try
// to produce policies hiding the SNI to censoring middleboxes.
for _, sni := range p.beaconsDomainsInRandomOrder() {
for _, sni := range p.bridgesDomainsInRandomOrder() {
out <- &httpsDialerTactic{
Address: tactic.Address,
InitialDelay: 0,
Expand All @@ -104,19 +104,19 @@ func (p *beaconsPolicy) maybeRewriteTestHelpersTactics(input <-chan *httpsDialer
return out
}

func (p *beaconsPolicy) beaconsTacticsForDomain(domain, port string) <-chan *httpsDialerTactic {
func (p *bridgesPolicy) bridgesTacticsForDomain(domain, port string) <-chan *httpsDialerTactic {
out := make(chan *httpsDialerTactic)

go func() {
defer close(out) // tell the parent when we're done

// we currently only have beacons for api.ooni.io
// we currently only have bridges for api.ooni.io
if domain != "api.ooni.io" {
return
}

for _, ipAddr := range p.beaconsAddrs() {
for _, sni := range p.beaconsDomainsInRandomOrder() {
for _, ipAddr := range p.bridgesAddrs() {
for _, sni := range p.bridgesDomainsInRandomOrder() {
out <- &httpsDialerTactic{
Address: ipAddr,
InitialDelay: 0,
Expand All @@ -131,23 +131,23 @@ func (p *beaconsPolicy) beaconsTacticsForDomain(domain, port string) <-chan *htt
return out
}

func (p *beaconsPolicy) beaconsDomainsInRandomOrder() (out []string) {
out = p.beaconsDomains()
func (p *bridgesPolicy) bridgesDomainsInRandomOrder() (out []string) {
out = p.bridgesDomains()
r := rand.New(rand.NewSource(time.Now().UnixNano()))
r.Shuffle(len(out), func(i, j int) {
out[i], out[j] = out[j], out[i]
})
return
}

func (p *beaconsPolicy) beaconsAddrs() (out []string) {
func (p *bridgesPolicy) bridgesAddrs() (out []string) {
return append(
out,
"162.55.247.208",
)
}

func (p *beaconsPolicy) beaconsDomains() (out []string) {
func (p *bridgesPolicy) bridgesDomains() (out []string) {
// See https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40273
return append(
out,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (
)

func TestBeaconsPolicy(t *testing.T) {
t.Run("for domains for which we don't have beacons and DNS failure", func(t *testing.T) {
t.Run("for domains for which we don't have bridges and DNS failure", func(t *testing.T) {
expected := errors.New("mocked error")
p := &beaconsPolicy{
p := &bridgesPolicy{
Fallback: &dnsPolicy{
Logger: model.DiscardLogger,
Resolver: &mocks.Resolver{
Expand All @@ -36,8 +36,8 @@ func TestBeaconsPolicy(t *testing.T) {
}
})

t.Run("for domains for which we don't have beacons and DNS success", func(t *testing.T) {
p := &beaconsPolicy{
t.Run("for domains for which we don't have bridges and DNS success", func(t *testing.T) {
p := &bridgesPolicy{
Fallback: &dnsPolicy{
Logger: model.DiscardLogger,
Resolver: &mocks.Resolver{
Expand Down Expand Up @@ -78,7 +78,7 @@ func TestBeaconsPolicy(t *testing.T) {

t.Run("for the api.ooni.io domain", func(t *testing.T) {
expected := errors.New("mocked error")
p := &beaconsPolicy{
p := &bridgesPolicy{
Fallback: &dnsPolicy{
Logger: model.DiscardLogger,
Resolver: &mocks.Resolver{
Expand Down Expand Up @@ -118,11 +118,11 @@ func TestBeaconsPolicy(t *testing.T) {
})

t.Run("for test helper domains", func(t *testing.T) {
for _, domain := range beaconsPolicyTestHelpersDomains {
for _, domain := range bridgesPolicyTestHelpersDomains {
t.Run(domain, func(t *testing.T) {
expectedAddrs := []string{"164.92.180.7"}

p := &beaconsPolicy{
p := &bridgesPolicy{
Fallback: &dnsPolicy{
Logger: model.DiscardLogger,
Resolver: &mocks.Resolver{
Expand Down
2 changes: 1 addition & 1 deletion internal/enginenetx/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func newHTTPSDialerPolicy(

// create a composed fallback TLS dialer policy
fallback := &statsPolicy{
Fallback: &beaconsPolicy{Fallback: &dnsPolicy{logger, resolver}},
Fallback: &bridgesPolicy{Fallback: &dnsPolicy{logger, resolver}},
Stats: stats,
}

Expand Down
18 changes: 9 additions & 9 deletions internal/enginenetx/statspolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {
// prepare the content of the stats
twentyMinutesAgo := time.Now().Add(-20 * time.Minute)

const beaconAddress = netemx.AddressApiOONIIo
const bridgeAddress = netemx.AddressApiOONIIo

expectTacticsStats := []*statsTactic{{
CountStarted: 5,
Expand All @@ -34,7 +34,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {
HistoTLSVerificationError: map[string]int64{},
LastUpdated: twentyMinutesAgo,
Tactic: &httpsDialerTactic{
Address: beaconAddress,
Address: bridgeAddress,
InitialDelay: 0,
Port: "443",
SNI: "www.repubblica.it",
Expand All @@ -53,7 +53,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {
HistoTLSVerificationError: map[string]int64{},
LastUpdated: twentyMinutesAgo,
Tactic: &httpsDialerTactic{
Address: beaconAddress,
Address: bridgeAddress,
InitialDelay: 0,
Port: "443",
SNI: "www.kernel.org",
Expand All @@ -72,7 +72,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {
HistoTLSVerificationError: map[string]int64{},
LastUpdated: twentyMinutesAgo,
Tactic: &httpsDialerTactic{
Address: beaconAddress,
Address: bridgeAddress,
InitialDelay: 0,
Port: "443",
SNI: "theconversation.com",
Expand Down Expand Up @@ -104,7 +104,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {
HistoTLSVerificationError: map[string]int64{},
LastUpdated: time.Time{}, // the zero time should exclude this one
Tactic: &httpsDialerTactic{
Address: beaconAddress,
Address: bridgeAddress,
InitialDelay: 0,
Port: "443",
SNI: "ilpost.it",
Expand Down Expand Up @@ -151,7 +151,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
switch domain {
case "api.ooni.io":
return []string{beaconAddress}, nil
return []string{bridgeAddress}, nil
default:
return nil, netxlite.ErrOODNSNoSuchHost
}
Expand Down Expand Up @@ -182,7 +182,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {

// extend the expected list to include DNS results
expect = append(expect, &httpsDialerTactic{
Address: beaconAddress,
Address: bridgeAddress,
InitialDelay: 2 * time.Second,
Port: "443",
SNI: "api.ooni.io",
Expand Down Expand Up @@ -216,7 +216,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {
switch domain {
case "api.ooni.io":
// Twice so we try to cause duplicate entries also with the DNS policy
return []string{beaconAddress, beaconAddress}, nil
return []string{bridgeAddress, bridgeAddress}, nil
default:
return nil, netxlite.ErrOODNSNoSuchHost
}
Expand Down Expand Up @@ -247,7 +247,7 @@ func TestStatsPolicyWorkingAsIntended(t *testing.T) {

// extend the expected list to include DNS results
expect = append(expect, &httpsDialerTactic{
Address: beaconAddress,
Address: bridgeAddress,
InitialDelay: 2 * time.Second,
Port: "443",
SNI: "api.ooni.io",
Expand Down
4 changes: 2 additions & 2 deletions internal/enginenetx/userpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package enginenetx

//
// user policy - the possibility of loading a user policy from a JSON
// document named `httpsdialer.conf` in $OONI_HOME/engine that contains
// document named `bridges.conf` in $OONI_HOME/engine that contains
// a specific policy for TLS dialing for specific endpoints.
//
// This policy helps a lot with exploration and experimentation.
Expand Down Expand Up @@ -32,7 +32,7 @@ type userPolicy struct {
}

// userPolicyKey is the kvstore key used to retrieve the user policy.
const userPolicyKey = "httpsdialer.conf"
const userPolicyKey = "bridges.conf"

// errUserPolicyWrongVersion means that the user policy document has the wrong version number.
var errUserPolicyWrongVersion = errors.New("wrong user policy version")
Expand Down
2 changes: 1 addition & 1 deletion internal/enginenetx/userpolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestUserPolicy(t *testing.T) {
name: "with empty JSON",
key: userPolicyKey,
input: []byte(`{}`),
expectErr: "httpsdialer.conf: wrong user policy version: expected=3 got=0",
expectErr: "bridges.conf: wrong user policy version: expected=3 got=0",
expectedPolicy: nil,
}, {
name: "with real serialized policy",
Expand Down

0 comments on commit cf67bdb

Please sign in to comment.