forked from ooni/probe-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(enginenetx): make static/loadable policy easier to use (ooni…
…#1297) This diff makes the policy previously known as loadable and now know as the static policy easier to use, by having a constructor that reads from a key-value store and by passing it a fallback policy to use. With this design, it should be possible to have code that uses the static policy if applied, falling back to whatever policy we are otherwise constructing into the NewNetwork constructor. In a subsequent commit, I will hook this code into NewNetwork, so that we can override the policy by changing the filesystem. While there, notice several failures in the test suite and apply workarounds (see ooni/probe#2539, ooni/probe#2540, ooni/probe#2541). Part of ooni/probe#2531.
- Loading branch information
1 parent
2492145
commit d9f1366
Showing
10 changed files
with
342 additions
and
150 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package enginenetx | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/ooni/probe-cli/v3/internal/hujsonx" | ||
"github.com/ooni/probe-cli/v3/internal/model" | ||
) | ||
|
||
// HTTPSDialerStaticPolicy is an [HTTPSDialerPolicy] incorporating verbatim | ||
// a static policy loaded from the engine's key-value store. | ||
// | ||
// This policy is very useful for exploration and experimentation. | ||
type HTTPSDialerStaticPolicy struct { | ||
// Fallback is the fallback policy in case the static one does not | ||
// contain a rule for a specific domain. | ||
Fallback HTTPSDialerPolicy | ||
|
||
// Root is the root of the statically loaded policy. | ||
Root *HTTPSDialerStaticPolicyRoot | ||
} | ||
|
||
// httpsDialerStaticPolicyKey is the kvstore key used to retrieve the static policy. | ||
const httpsDialerStaticPolicyKey = "httpsdialer.conf" | ||
|
||
// errDialerStaticPolicyWrongVersion means that the static policy document has the wrong version number. | ||
var errDialerStaticPolicyWrongVersion = errors.New("wrong static policy version") | ||
|
||
// NewHTTPSDialerStaticPolicy attempts to constructs a static policy using a given fallback | ||
// policy and either returns a good policy or an error. The typical error case is the one | ||
// in which there's no httpsDialerStaticPolicyKey in the key-value store. | ||
func NewHTTPSDialerStaticPolicy( | ||
kvStore model.KeyValueStore, fallback HTTPSDialerPolicy) (*HTTPSDialerStaticPolicy, error) { | ||
// attempt to read the static policy bytes from the kvstore | ||
data, err := kvStore.Get(httpsDialerStaticPolicyKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// attempt to parse the static policy using human-readable JSON | ||
var root HTTPSDialerStaticPolicyRoot | ||
if err := hujsonx.Unmarshal(data, &root); err != nil { | ||
return nil, err | ||
} | ||
|
||
// make sure the version is OK | ||
if root.Version != httpsDialerStaticPolicyVersion { | ||
err := fmt.Errorf( | ||
"%s: %w: expected=%d got=%d", | ||
httpsDialerStaticPolicyKey, | ||
errDialerStaticPolicyWrongVersion, | ||
httpsDialerStaticPolicyVersion, | ||
root.Version, | ||
) | ||
return nil, err | ||
} | ||
|
||
out := &HTTPSDialerStaticPolicy{ | ||
Fallback: fallback, | ||
Root: &root, | ||
} | ||
return out, nil | ||
} | ||
|
||
// httpsDialerStaticPolicyVersion is the current version of the static policy file. | ||
const httpsDialerStaticPolicyVersion = 1 | ||
|
||
// HTTPSDialerStaticPolicyRoot is the root of a statically loaded policy. | ||
type HTTPSDialerStaticPolicyRoot struct { | ||
// Domains maps each domain to its policy. | ||
Domains map[string][]*HTTPSDialerTactic | ||
|
||
// Version is the data structure version. | ||
Version int | ||
} | ||
|
||
var _ HTTPSDialerPolicy = &HTTPSDialerStaticPolicy{} | ||
|
||
// LookupTactics implements HTTPSDialerPolicy. | ||
func (ldp *HTTPSDialerStaticPolicy) LookupTactics( | ||
ctx context.Context, domain string, port string, reso model.Resolver) ([]*HTTPSDialerTactic, error) { | ||
tactics, found := ldp.Root.Domains[domain] | ||
if !found { | ||
return ldp.Fallback.LookupTactics(ctx, domain, port, reso) | ||
} | ||
return tactics, nil | ||
} | ||
|
||
// Parallelism implements HTTPSDialerPolicy. | ||
func (ldp *HTTPSDialerStaticPolicy) Parallelism() int { | ||
return 16 | ||
} |
Oops, something went wrong.