Stay organized with collections
Save and categorize content based on your preferences.
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:
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.googleaddress: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.googleaddress: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.
Reach out to the Psiphon team to obtain a config that gives you access to
their network. This may require a contract.
Add the received Psiphon config to the fallback section of your Smart
Dialer config. Since JSON is compatible with YAML, you can copy and paste
your Psiphon config directly into the fallback section, like this:
To use the Smart Dialer, create a StrategyFinder object and call the
NewDialer method, passing in the list of test domains and the YAML config.
The NewDialer method will return a transport.StreamDialer that can be used
to create connections using the found strategy. For example:
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-06-17 UTC."],[],[],null,["# Smart Dialer Config\n\nThe **Smart Dialer** searches for a strategy that unblocks DNS and TLS for a\ngiven list of test domains. It takes a config describing multiple strategies to\npick from.\n\nYAML config for the Smart Dialer\n--------------------------------\n\nThe config that the Smart Dialer takes is in a YAML format. Here is an example: \n\n dns:\n - system: {}\n - https:\n name: 8.8.8.8\n - https:\n name: 9.9.9.9\n tls:\n - \"\"\n - split:2\n - tlsfrag:1\n\n fallback:\n - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1\n\n### DNS Configuration\n\n- The `dns` field specifies a list of DNS resolvers to test.\n- Each DNS resolver can be one of the following types:\n - `system`: Use the system resolver. Specify with an empty object.\n - `https`: Use an encrypted DNS over HTTPS (DoH) resolver.\n - `tls`: Use an encrypted DNS over TLS (DoT) resolver.\n - `udp`: Use a UDP resolver.\n - `tcp`: Use a TCP resolver.\n\n#### DNS-over-HTTPS Resolver (DoH)\n\n https:\n name: dns.google\n address: 8.8.8.8\n\n- `name`: The domain name of the DoH server.\n- `address`: The host:port of the DoH server. Defaults to `name`:443.\n\n#### DNS-over-TLS Resolver (DoT)\n\n tls:\n name: dns.google\n address: 8.8.8.8\n\n- `name`: The domain name of the DoT server.\n- `address`: The host:port of the DoT server. Defaults to `name`:853.\n\n#### UDP Resolver\n\n udp:\n address: 8.8.8.8\n\n- `address`: The host:port of the UDP resolver.\n\n#### TCP Resolver\n\n tcp:\n address: 8.8.8.8\n\n- `address`: The host:port of the TCP resolver.\n\n### TLS Configuration\n\n- The `tls` field specifies a list of TLS transports to test.\n- Each TLS transport is a string that specifies the transport to use.\n- For example, `override:host=cloudflare.net|tlsfrag:1` specifies a transport that uses domain fronting with Cloudflare and TLS fragmentation. See the [config documentation](https://pkg.go.dev/github.com/Jigsaw-Code/outline-sdk/x/configurl#hdr-Config_Format) for details.\n\n### Fallback Configuration\n\nA fallback configuration is used if none of the proxyless strategies are able to\nconnect. For example it can specify a backup proxy server to attempt the user's\nconnection. Using a fallback will be slower to start, since first the other\nDNS/TLS strategies must fail/timeout.\n\nThe fallback strings should be:\n\n- A valid `StreamDialer` config string as defined in [`configurl`](https://pkg.go.dev/github.com/Jigsaw-Code/outline-sdk/x/configurl#hdr-Proxy_Protocols).\n- A valid Psiphon configuration object as a child of a `psiphon` field.\n\n#### Shadowsocks server example\n\n fallback:\n - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1\n\n#### SOCKS5 server example\n\n fallback:\n - socks5://[USERINFO]@[HOST]:[PORT]\n\n#### Psiphon config example\n\nTo use the [Psiphon](https://psiphon.ca/) network, you will need to:\n\n1. Reach out to the Psiphon team to obtain a config that gives you access to their network. This may require a contract.\n2. Add the received Psiphon config to the `fallback` section of your Smart Dialer config. Since JSON is compatible with YAML, you can copy and paste your Psiphon config directly into the `fallback` section, like this:\n\n fallback:\n - psiphon: {\n \"PropagationChannelId\": \"FFFFFFFFFFFFFFFF\",\n \"SponsorId\": \"FFFFFFFFFFFFFFFF\",\n \"DisableLocalSocksProxy\" : true,\n \"DisableLocalHTTPProxy\" : true,\n ...\n }\n\n| **Note:** The Psiphon codebase is licensed under the GPL, which can impose license restrictions on your own code. You may want to consider obtaining a special license from them.\n\n### How to Use the Smart Dialer\n\nTo use the Smart Dialer, create a `StrategyFinder` object and call the\n`NewDialer` method, passing in the list of test domains and the YAML config.\nThe `NewDialer` method will return a `transport.StreamDialer` that can be used\nto create connections using the found strategy. For example: \n\n finder := &smart.StrategyFinder{\n TestTimeout: 5 * time.Second,\n LogWriter: os.Stdout,\n StreamDialer: &transport.TCPDialer{},\n PacketDialer: &transport.UDPDialer{},\n }\n\n configBytes := []byte(`\n dns:\n - system: {}\n - https:\n name: 8.8.8.8\n - https:\n name: 9.9.9.9\n tls:\n - \"\"\n - split:2\n - tlsfrag:1\n fallback:\n - ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTprSzdEdHQ0MkJLOE9hRjBKYjdpWGFK@1.2.3.4:9999/?outline=1\n `)\n\n dialer, err := finder.NewDialer(\n context.Background(),\n []string{\"www.google.com\"},\n configBytes\n )\n if err != nil {\n // Handle error.\n }\n\n // Use dialer to create connections.\n\nThis is a basic example and may need to be adapted for your specific use case."]]