1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
package main
import (
"context"
"errors"
"fmt"
"net"
"os"
"time"
"go.wit.com/lib/protobuf/argvpb"
"go.wit.com/log"
)
func ipv6fails() bool {
var s string
var err error
var addrs []net.IP
addrs, err = LookupIPv6("ipv6.google.com")
if err != nil {
log.Printf("%v\n", err)
log.Info(s)
WarningForIpv4()
s = "THIS FEATURE IS NOT SUPPORTED ON IPv4"
argvpb.BadExit(s, err)
}
if len(addrs) == 0 {
s = "THIS FEATURE IS NOT SUPPORTED ON IPv4."
argvpb.BadExit(s, errors.New("IPv6 DNS is not returning ip addresses"))
}
addrs, err = LookupIPv6("cgit.grid.wit.com")
if err != nil {
log.Printf("%v\n", err)
log.Info(s)
WarningForIpv4()
s = "Your OS is not correctly resolving IPv6 addresses."
argvpb.BadExit(s, err)
}
if len(addrs) == 0 {
s = "Your OS is not correctly resolving IPv6 addresses."
argvpb.BadExit(s, errors.New("IPv6 DNS is not returning ip addresses"))
}
/*
s, err = IPv6TestDNS()
if err != nil {
log.Printf("%v\n", err)
log.Info(s)
WarningForIpv4()
s = "THIS FEATURE IS NOT SUPPORTED ON IPv4"
argvpb.BadExit(s, nil)
}
*/
s, err = IPv6TestPing()
if err != nil {
log.Printf("%v\n", err)
log.Info(s)
WarningForIpv4()
s = "THIS FEATURE IS NOT SUPPORTED ON IPv4"
argvpb.BadExit(s, nil)
}
return true
}
func WarningForIpv4() {
log.Info("")
pfile, _ := resources.ReadFile("resources/IPv4")
log.Info("")
log.Info(string(pfile))
}
// The host we will try to connect to.
// ipv6.google.com is a good choice as it's highly available and resolves only to AAAA records (IPv6).
const ipv6TestHost = "ipv6.google.com"
const testPort = "443" // HTTPS port, almost always open.
func LookupIPv6(hostname string) ([]net.IP, error) {
dnsTimeout := 2 * time.Second
ctx, cancel := context.WithTimeout(context.Background(), dnsTimeout)
defer cancel()
addrs, err := net.DefaultResolver.LookupIP(ctx, "ip6", ipv6TestHost)
return addrs, err
}
// a better test that should fail right away
func IPv6TestDNS() (string, error) {
// --- Step 1: Fast DNS Lookup ---
// We'll use a separate, short timeout just for the DNS resolution.
// If DNS is broken, we'll know in a second or two.
dnsTimeout := 2 * time.Second
ctx, cancel := context.WithTimeout(context.Background(), dnsTimeout)
defer cancel()
// net.DefaultResolver.LookupIPAddr forces the resolver to look up the host.
// We specify "ip6" to ensure we only get AAAA records.
// addrs, err := net.DefaultResolver.LookupIPAddr(ctx, "ip6", ipv6TestHost)
addrs, err := net.DefaultResolver.LookupIP(ctx, "ip6", ipv6TestHost)
if err != nil {
fmt.Printf("IPv6 DNS resolution failed: %v\n", err)
fmt.Println("This likely means your network cannot resolve IPv6 addresses.")
return "IPv6 connectivity test failed", err
}
if len(addrs) == 0 {
fmt.Printf("No IPv6 addresses found for %s\n", ipv6TestHost)
return "this should happen", errors.New("good or bad")
}
testping(addrs)
return "IPv6 DNS lookup worked.", nil
}
func testping(addrs []net.IP) {
// If we get here, DNS is working. Let's use the first address we found.
targetIP := addrs[0].String()
fmt.Printf("Successfully resolved %s to IPv6 address: %s\n", ipv6TestHost, targetIP)
// --- Step 2: Connection Attempt ---
// Now we try to connect to the IP we found. This tests routing and firewalls.
connectionTimeout := 3 * time.Second
conn, err := net.DialTimeout("tcp6", net.JoinHostPort(targetIP, testPort), connectionTimeout)
if err != nil {
fmt.Printf("IPv6 connection to %s failed: %v\n", targetIP, err)
fmt.Println("This likely means your network has an IPv6 routing or firewall issue.")
os.Exit(1)
}
defer conn.Close()
fmt.Println("IPv6 ping test successful.")
}
func IPv6TestPing() (string, error) {
// We use net.DialTimeout to attempt a TCP connection.
// By specifying "tcp6" as the network, we force the dialer to use IPv6 only.
// If the system can't resolve the AAAA record or can't route to the IPv6 address,
// this will fail.
timeout := 2 * time.Second
conn, err := net.DialTimeout("tcp6", net.JoinHostPort(ipv6TestHost, testPort), timeout)
// Check the result.
if err != nil {
// The connection failed. This indicates that IPv6 is not working correctly.
return "IPv6 ping test failed", err
}
// If we get here, the connection was successful.
// It's good practice to close the connection we opened.
conn.Close()
return "IPv6 ping test successful.", nil
}
|