dialgoogle_test.go 5.35 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package net

import (
	"flag"
9
	"fmt"
10
	"io"
11
	"strings"
12 13 14 15
	"syscall"
	"testing"
)

16
// If an IPv6 tunnel is running, we can try dialing a real IPv6 address.
17
var testIPv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present")
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
func TestResolveGoogle(t *testing.T) {
	if testing.Short() || !*testExternal {
		t.Skip("skipping test to avoid external network")
	}

	for _, network := range []string{"tcp", "tcp4", "tcp6"} {
		addr, err := ResolveTCPAddr(network, "www.google.com:http")
		if err != nil {
			if (network == "tcp" || network == "tcp4") && !supportsIPv4 {
				t.Logf("ipv4 is not supported: %v", err)
			} else if network == "tcp6" && !supportsIPv6 {
				t.Logf("ipv6 is not supported: %v", err)
			} else {
				t.Errorf("ResolveTCPAddr failed: %v", err)
			}
			continue
		}
		if (network == "tcp" || network == "tcp4") && addr.IP.To4() == nil {
			t.Errorf("got %v; expected an IPv4 address on %v", addr, network)
		} else if network == "tcp6" && (addr.IP.To16() == nil || addr.IP.To4() != nil) {
			t.Errorf("got %v; expected an IPv6 address on %v", addr, network)
		}
	}
}

func TestDialGoogle(t *testing.T) {
	if testing.Short() || !*testExternal {
		t.Skip("skipping test to avoid external network")
	}

	d := &Dialer{DualStack: true}
	for _, network := range []string{"tcp", "tcp4", "tcp6"} {
		if network == "tcp" && !supportsIPv4 && !supportsIPv6 {
			t.Logf("skipping test; both ipv4 and ipv6 are not supported")
			continue
		} else if network == "tcp4" && !supportsIPv4 {
			t.Logf("skipping test; ipv4 is not supported")
			continue
		} else if network == "tcp6" && !supportsIPv6 {
			t.Logf("skipping test; ipv6 is not supported")
			continue
		} else if network == "tcp6" && !*testIPv6 {
			t.Logf("test disabled; use -ipv6 to enable")
			continue
		}
		if c, err := d.Dial(network, "www.google.com:http"); err != nil {
			t.Errorf("Dial failed: %v", err)
		} else {
			c.Close()
		}
	}
}

72 73 74
// fd is already connected to the destination, port 80.
// Run an HTTP request to fetch the appropriate page.
func fetchGoogle(t *testing.T, fd Conn, network, addr string) {
75
	req := []byte("GET /robots.txt HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
76 77 78 79 80 81 82 83 84 85 86 87
	n, err := fd.Write(req)

	buf := make([]byte, 1000)
	n, err = io.ReadFull(fd, buf)

	if n < 1000 {
		t.Errorf("fetchGoogle: short HTTP read from %s %s - %v", network, addr, err)
		return
	}
}

func doDial(t *testing.T, network, addr string) {
88
	fd, err := Dial(network, addr)
89 90 91 92 93 94 95 96
	if err != nil {
		t.Errorf("Dial(%q, %q, %q) = _, %v", network, "", addr, err)
		return
	}
	fetchGoogle(t, fd, network, addr)
	fd.Close()
}

97
var googleaddrsipv4 = []string{
98
	"%d.%d.%d.%d:80",
99
	"www.google.com:80",
100
	"%d.%d.%d.%d:http",
101
	"www.google.com:http",
102 103 104 105 106
	"%03d.%03d.%03d.%03d:0080",
	"[::ffff:%d.%d.%d.%d]:80",
	"[::ffff:%02x%02x:%02x%02x]:80",
	"[0:0:0:0:0000:ffff:%d.%d.%d.%d]:80",
	"[0:0:0:0:000000:ffff:%d.%d.%d.%d]:80",
107
	"[0:0:0:0::ffff:%d.%d.%d.%d]:80",
108 109
}

110
func TestDialGoogleIPv4(t *testing.T) {
111
	if testing.Short() || !*testExternal {
112
		t.Skip("skipping test to avoid external network")
113 114
	}

115
	// Insert an actual IPv4 address for google.com
116
	// into the table.
117
	addrs, err := LookupIP("www.google.com")
118 119 120
	if err != nil {
		t.Fatalf("lookup www.google.com: %v", err)
	}
121 122 123 124 125 126 127 128 129
	var ip IP
	for _, addr := range addrs {
		if x := addr.To4(); x != nil {
			ip = x
			break
		}
	}
	if ip == nil {
		t.Fatalf("no IPv4 addresses for www.google.com")
130 131
	}

132
	for i, s := range googleaddrsipv4 {
133
		if strings.Contains(s, "%") {
134
			googleaddrsipv4[i] = fmt.Sprintf(s, ip[0], ip[1], ip[2], ip[3])
135 136 137
		}
	}

138 139
	for i := 0; i < len(googleaddrsipv4); i++ {
		addr := googleaddrsipv4[i]
140 141 142 143 144 145 146
		if addr == "" {
			continue
		}
		t.Logf("-- %s --", addr)
		doDial(t, "tcp", addr)
		if addr[0] != '[' {
			doDial(t, "tcp4", addr)
147 148
			if supportsIPv6 {
				// make sure syscall.SocketDisableIPv6 flag works.
149
				syscall.SocketDisableIPv6 = true
150
				doDial(t, "tcp", addr)
151 152 153 154
				doDial(t, "tcp4", addr)
				syscall.SocketDisableIPv6 = false
			}
		}
155 156 157 158 159 160 161 162 163
	}
}

var googleaddrsipv6 = []string{
	"[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:80",
	"ipv6.google.com:80",
	"[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:http",
	"ipv6.google.com:http",
}
164

165
func TestDialGoogleIPv6(t *testing.T) {
166
	if testing.Short() || !*testExternal {
167
		t.Skip("skipping test to avoid external network")
168 169
	}
	// Only run tcp6 if the kernel will take it.
170
	if !supportsIPv6 {
171
		t.Skip("skipping test; ipv6 is not supported")
172 173
	}
	if !*testIPv6 {
174
		t.Skip("test disabled; use -ipv6 to enable")
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
	}

	// Insert an actual IPv6 address for ipv6.google.com
	// into the table.
	addrs, err := LookupIP("ipv6.google.com")
	if err != nil {
		t.Fatalf("lookup ipv6.google.com: %v", err)
	}
	var ip IP
	for _, addr := range addrs {
		if x := addr.To16(); x != nil {
			ip = x
			break
		}
	}
	if ip == nil {
		t.Fatalf("no IPv6 addresses for ipv6.google.com")
	}

	for i, s := range googleaddrsipv6 {
		if strings.Contains(s, "%") {
			googleaddrsipv6[i] = fmt.Sprintf(s, ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15])
		}
	}

	for i := 0; i < len(googleaddrsipv6); i++ {
		addr := googleaddrsipv6[i]
		if addr == "" {
			continue
204
		}
205 206 207
		t.Logf("-- %s --", addr)
		doDial(t, "tcp", addr)
		doDial(t, "tcp6", addr)
208 209
	}
}