smart

package
v0.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2025 License: Apache-2.0 Imports: 25 Imported by: 3

README

Smart Dialer

The Smart Dialer searches for a strategy that unblocks DNS and TLS for a given list of test domains. It takes a config describing multiple strategies to pick from.

YAML config for the Smart Dialer

The config that the Smart Dialer takes is in a YAML format. Here is an example:

dns:
  - system: {}
  - https:
      name: 8.8.8.8
  - https:
      name: 9.9.9.9
tls:
  - ""
  - split:2
  - tlsfrag:1

fallback:
  - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1
DNS Configuration
  • The dns field specifies a list of DNS resolvers to test.
  • Each DNS resolver can be one of the following types:
    • system: Use the system resolver. Specify with an empty object.
    • https: Use an encrypted DNS over HTTPS (DoH) resolver.
    • tls: Use an encrypted DNS over TLS (DoT) resolver.
    • udp: Use a UDP resolver.
    • tcp: Use a TCP resolver.
DNS-over-HTTPS Resolver (DoH)
https:
  name: dns.google
  address: 8.8.8.8
  • name: The domain name of the DoH server.
  • address: The host:port of the DoH server. Defaults to name:443.
DNS-over-TLS Resolver (DoT)
tls:
  name: dns.google
  address: 8.8.8.8
  • name: The domain name of the DoT server.
  • address: The host:port of the DoT server. Defaults to name:853.
UDP Resolver
udp:
  address: 8.8.8.8
  • address: The host:port of the UDP resolver.
TCP Resolver
tcp:
  address: 8.8.8.8
  • address: The host:port of the TCP resolver.
TLS Configuration
  • The tls field specifies a list of TLS transports to test.
  • Each TLS transport is a string that specifies the transport to use.
  • For example, override:host=cloudflare.net|tlsfrag:1 specifies a transport that uses domain fronting with Cloudflare and TLS fragmentation. See the config documentation for details.
Fallback Configuration

A fallback configuration is used if none of the proxyless strategies are able to connect. For example it can specify a backup proxy server to attempt the user's connection. Using a fallback will be slower to start, since first the other DNS/TLS strategies must fail/timeout.

The fallback strings should be:

  • A valid StreamDialer config string as defined in configurl
  • A valid Psiphon configuration object as a child of a psiphon field.
Shadowsocks server example
fallback:
  - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1
SOCKS5 server example
fallback:
  - socks5://[USERINFO]@[HOST]:[PORT]
Psiphon config example

[!WARNING] The Psiphon library is not included in the build by default because the Psiphon codebase uses GPL. To support Psiphon configuration please build using the psiphon build tag. When integrating Psiphon into your application please work with the Psiphon team at sponsor@psiphon.ca

JSON is a subset of YAML. If you have an existing psiphon JSON configuration file you can simply copy-and-paste it into your smart-proxy config.yaml file like so:

fallback:
  - psiphon: <YOUR_PSIPHON_CONFIG_HERE>
fallback:
  - psiphon: {
      "PropagationChannelId": "FFFFFFFFFFFFFFFF",
      "SponsorId": "FFFFFFFFFFFFFFFF",
      "DisableLocalSocksProxy" : true,
      "DisableLocalHTTPProxy" : true,
      ...
    }
Using the Smart Dialer

To use the Smart Dialer, create a StrategyFinder object and call the NewDialer method, passing in the list of test domains and the JSON config. The NewDialer method will return a transport.StreamDialer that can be used to create connections using the found strategy. For example:

finder := &smart.StrategyFinder{
    TestTimeout:  5 * time.Second,
    LogWriter:   os.Stdout,
    StreamDialer: &transport.TCPDialer{},
    PacketDialer: &transport.UDPDialer{},
}

configBytes := []byte(`
dns:
  - system: {}
  - https:
      name: 8.8.8.8
  - https:
      name: 9.9.9.9
tls:
  - ""
  - split:2
  - tlsfrag:1
fallback:
  - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1
`)

dialer, err := finder.NewDialer(context.Background(), []string{"www.google.com"}, configBytes)
if err != nil {
    // Handle error.
}

// Use dialer to create connections.

Please note that this is a basic example and may need to be adapted for your specific use case.

Documentation

Overview

Package smart provides utilities to dynamically find serverless strategies for circumvention.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type SearchResult added in v0.0.3

type SearchResult struct {
	Dialer          transport.StreamDialer
	Config          fallbackEntryConfig
	ConfigSignature string
}

type StrategyFinder

type StrategyFinder struct {
	TestTimeout  time.Duration
	LogWriter    io.Writer
	StreamDialer transport.StreamDialer
	PacketDialer transport.PacketDialer
	Cache        StrategyResultCache
	// contains filtered or unexported fields
}

func (*StrategyFinder) NewDialer

func (f *StrategyFinder) NewDialer(ctx context.Context, testDomains []string, configBytes []byte) (transport.StreamDialer, error)

NewDialer uses the config in configBytes to search for a strategy that unblocks DNS and TLS for all of the testDomains, returning a dialer with the found strategy. It returns an error if no strategy was found that unblocks the testDomains. The testDomains must be domains with a TLS service running on port 443.

type StrategyResultCache added in v0.0.4

type StrategyResultCache interface {
	// Get retrieves a strategy result value associated with the given key.
	// It returns the value text encoded in UTF-8 and true if found.
	Get(key string) (value []byte, ok bool)

	// Put adds the strategy result value encoded in UTF-8 to the cache with the given key.
	// If called with nil value, it should remove the cache entry.
	Put(key string, value []byte)
}

StrategyResultCache is a cache of strategy results that can be used by StrategyFinder to resume a strategy efficiently. Implementations are expected to be called concurrently from different goroutines.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL