Skip to content
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2b1461f
changed checkIPv6Connectivity to use goroutines and started adding tests
BPplays Sep 16, 2025
68cb76d
made checkIPv6Connectivity more generic and changed name to checkConn…
BPplays Sep 16, 2025
a899c79
better discription of checkConnectivity
BPplays Sep 16, 2025
24ec3bc
check if both ipv6 and ipv4 are available and fallback to both if doe…
BPplays Sep 17, 2025
d01fbad
added discription of IPv4Resolvers
BPplays Sep 17, 2025
2a1c9ee
cleaned up comment that made no sense
BPplays Sep 17, 2025
8026ce2
changed discription of init()
BPplays Sep 17, 2025
ecc0155
fix missing wg.Done()
BPplays Sep 17, 2025
b522f26
better var name
BPplays Sep 19, 2025
fd0b3fc
defer con close right after dial
BPplays Sep 19, 2025
f6627ac
simplified comparison
BPplays Sep 19, 2025
2d5aa55
just realised probably don't need multiple host checks for udp, prob …
BPplays Sep 20, 2025
d2b0d06
give func better name
BPplays Nov 20, 2025
134f05d
give func better doc
BPplays Nov 20, 2025
a28f4a1
fix test not added; new tests; change port to show it's not doing a d…
BPplays Nov 20, 2025
b3e6ac3
made func for test panic if err, and changed name
BPplays Nov 20, 2025
557f338
test code formatting
BPplays Nov 20, 2025
1748d28
changed checkIPv6Connectivity to use goroutines and started adding tests
BPplays Sep 16, 2025
b3ce9d1
made checkIPv6Connectivity more generic and changed name to checkConn…
BPplays Sep 16, 2025
b5e6687
better discription of checkConnectivity
BPplays Sep 16, 2025
e8ed7f8
check if both ipv6 and ipv4 are available and fallback to both if doe…
BPplays Sep 17, 2025
d594df6
added discription of IPv4Resolvers
BPplays Sep 17, 2025
d3eaf13
cleaned up comment that made no sense
BPplays Sep 17, 2025
804212d
changed discription of init()
BPplays Sep 17, 2025
753626c
fix missing wg.Done()
BPplays Sep 17, 2025
7fb4098
better var name
BPplays Sep 19, 2025
948e917
defer con close right after dial
BPplays Sep 19, 2025
d31a8a4
simplified comparison
BPplays Sep 19, 2025
a6da2b9
just realised probably don't need multiple host checks for udp, prob …
BPplays Sep 20, 2025
a772556
give func better name
BPplays Nov 20, 2025
50f9c27
give func better doc
BPplays Nov 20, 2025
a1187a5
fix test not added; new tests; change port to show it's not doing a d…
BPplays Nov 20, 2025
e5e7d90
made func for test panic if err, and changed name
BPplays Nov 20, 2025
a96c0a1
test code formatting
BPplays Nov 20, 2025
3225867
Merge branch 'better_conn_check' of github.com:BPplays/cdncheck into …
BPplays Nov 25, 2025
0479207
added new test and better goroutine
BPplays Dec 19, 2025
48a1123
revert diff port test, may be more valuble to make sure can bind to u…
BPplays Dec 19, 2025
01eeef7
fix not saved for last commit
BPplays Dec 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 75 additions & 18 deletions cdncheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,7 @@ var (
DefaultCloudProviders string
)

// DefaultResolvers trusted (taken from fastdialer) - IPv4 only
var DefaultResolvers = []string{
"1.1.1.1:53",
"1.0.0.1:53",
"8.8.8.8:53",
"8.8.4.4:53",
}
var DefaultResolvers []string

// IPv6Resolvers trusted IPv6 resolvers
var IPv6Resolvers = []string{
Expand All @@ -31,22 +25,85 @@ var IPv6Resolvers = []string{
"[2001:4860:4860::8844]:53",
}

// checkIPv6Connectivity tests if IPv6 connectivity is available
func checkIPv6Connectivity() bool {
// Test with a well-known IPv6 DNS server
testAddr := "[2001:4860:4860::8888]:53"
conn, err := net.DialTimeout("udp", testAddr, 3*time.Second)
if err != nil {
return false
// IPv4Resolvers trusted IPv4 resolvers
var IPv4Resolvers = []string{
"1.1.1.1:53",
"1.0.0.1:53",
"8.8.8.8:53",
"8.8.4.4:53",
}

// checkDialConnectivity tests if you can net.Dial to any of the IPs you input
//
// - IPs: IPs and ports (e.g. "[2001:db8::1]:53")
//
// - proto: protocol to use (e.g. "udp", "tcp", etc)
func checkDialConnectivity(IPs []string, proto string) bool {
var wg sync.WaitGroup
results := make(chan bool, len(IPs))

for _, IP := range IPs {
wg.Add(1)
go func(){
defer wg.Done()

conn, err := net.DialTimeout(proto, IP, 3*time.Second)
if conn != nil {
defer conn.Close()
}

results <- err == nil
}()
}
conn.Close()
return true
wg.Wait()
close(results)

for result := range results {
if result { return true }
}
return false
}

func availableIpVersions() (hasV6 bool, hasV4 bool) {
var wg sync.WaitGroup

wg.Add(1)
go func(){
defer wg.Done()
if checkDialConnectivity([]string{"[2001:4860:4860::8888]:10000"}, "udp") {
hasV6 = true
}
}()

wg.Add(1)
go func(){
defer wg.Done()
if checkDialConnectivity([]string{"8.8.8.8:10000"}, "udp") {
hasV4 = true
}
}()

wg.Wait()

return hasV6, hasV4
}

// init checks for IPv6 connectivity and adds IPv6 resolvers if available

// init checks for IPv6 and IPv4 connectivity and adds either group of resolvers if available, falls back to both if it can't detect any
func init() {
if checkIPv6Connectivity() {
hasV6, hasV4 := availableIpVersions()

if hasV6 {
DefaultResolvers = append(DefaultResolvers, IPv6Resolvers...)
}

if hasV4 {
DefaultResolvers = append(DefaultResolvers, IPv4Resolvers...)
}

if len(DefaultResolvers) <= 0 {
DefaultResolvers = append(DefaultResolvers, IPv6Resolvers...)
DefaultResolvers = append(DefaultResolvers, IPv4Resolvers...)
}
}

Expand Down
36 changes: 36 additions & 0 deletions cdncheck_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ import (
"github.com/stretchr/testify/require"
)

func allHostportsWithPortForTest(hostports []string, port string) (newIps []string) {
for _, hostport := range hostports {
host, _, err := net.SplitHostPort(hostport)
if err != nil { panic(err) }
newIps = append(newIps, net.JoinHostPort(host, port))
}

return newIps
}

func TestCDNCheckValid(t *testing.T) {
client := New()

Expand All @@ -30,3 +40,29 @@ func TestCDNCheckValid(t *testing.T) {
require.Nil(t, err, "Could not check ip in ranger")
require.False(t, found, "Localhost IP found in blacklist")
}


func TestConnCheckValid(t *testing.T) {
require.True(
t,
checkDialConnectivity(DefaultResolvers, "udp"),
"DefaultResolvers is showing no connectivity",
)

require.True(
t,
checkDialConnectivity(allHostportsWithPortForTest(DefaultResolvers, "10000"), "udp"),
"DefaultResolvers using port 10000 is showing no net.Dial connectivity",
)

require.False(
t,
checkDialConnectivity([]string{
"[::]:0",
"[::]:53",
"[::]:5",
"[::]:10",
}, "tcp"),
"invalid IPs showing as having connectivity",
)
}
Loading