2010-11-04 08:30:39 -06:00
// 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 (
2015-08-18 20:19:58 -06:00
"bytes"
2016-04-14 18:47:25 -06:00
"context"
2014-12-30 23:45:46 -07:00
"fmt"
2016-01-13 05:04:10 -07:00
"internal/testenv"
2015-10-31 23:29:45 -06:00
"runtime"
2012-09-09 08:53:48 -06:00
"strings"
2010-11-04 08:30:39 -06:00
"testing"
2014-12-30 23:45:46 -07:00
"time"
2010-11-04 08:30:39 -06:00
)
2016-04-14 18:47:25 -06:00
func lookupLocalhost ( ctx context . Context , fn func ( context . Context , string ) ( [ ] IPAddr , error ) , host string ) ( [ ] IPAddr , error ) {
2015-04-05 02:00:14 -06:00
switch host {
case "localhost" :
return [ ] IPAddr {
{ IP : IPv4 ( 127 , 0 , 0 , 1 ) } ,
{ IP : IPv6loopback } ,
} , nil
default :
2016-04-14 18:47:25 -06:00
return fn ( ctx , host )
2015-04-05 02:00:14 -06:00
}
}
2015-05-12 21:44:45 -06:00
// The Lookup APIs use various sources such as local database, DNS or
// mDNS, and may use platform-dependent DNS stub resolver if possible.
// The APIs accept any of forms for a query; host name in various
// encodings, UTF-8 encoded net name, domain name, FQDN or absolute
// FQDN, but the result would be one of the forms and it depends on
// the circumstances.
2014-08-28 21:28:31 -06:00
var lookupGoogleSRVTests = [ ] struct {
service , proto , name string
cname , target string
} {
{
"xmpp-server" , "tcp" , "google.com" ,
2015-12-04 01:54:21 -07:00
"google.com." , "google.com." ,
2015-05-12 21:44:45 -06:00
} ,
{
"xmpp-server" , "tcp" , "google.com." ,
2015-12-04 01:54:21 -07:00
"google.com." , "google.com." ,
2015-05-12 21:44:45 -06:00
} ,
// non-standard back door
{
"" , "" , "_xmpp-server._tcp.google.com" ,
2015-12-04 01:54:21 -07:00
"google.com." , "google.com." ,
2014-08-28 21:28:31 -06:00
} ,
{
2015-05-12 21:44:45 -06:00
"" , "" , "_xmpp-server._tcp.google.com." ,
2015-12-04 01:54:21 -07:00
"google.com." , "google.com." ,
2014-08-28 21:28:31 -06:00
} ,
}
func TestLookupGoogleSRV ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2011-04-15 09:21:29 -06:00
}
2016-04-13 21:17:44 -06:00
2015-05-12 21:44:45 -06:00
if ! supportsIPv4 || ! * testIPv4 {
t . Skip ( "IPv4 is required" )
}
2014-08-28 21:28:31 -06:00
for _ , tt := range lookupGoogleSRVTests {
cname , srvs , err := LookupSRV ( tt . service , tt . proto , tt . name )
if err != nil {
2016-05-06 12:46:35 -06:00
testenv . SkipFlakyNet ( t )
2014-08-28 21:28:31 -06:00
t . Fatal ( err )
}
if len ( srvs ) == 0 {
t . Error ( "got no record" )
}
2015-12-04 01:54:21 -07:00
if ! strings . HasSuffix ( cname , tt . cname ) {
2015-05-12 21:44:45 -06:00
t . Errorf ( "got %s; want %s" , cname , tt . cname )
2014-08-28 21:28:31 -06:00
}
for _ , srv := range srvs {
2015-12-04 01:54:21 -07:00
if ! strings . HasSuffix ( srv . Target , tt . target ) {
2015-05-12 21:44:45 -06:00
t . Errorf ( "got %v; want a record containing %s" , srv , tt . target )
2014-08-28 21:28:31 -06:00
}
}
2010-11-04 08:30:39 -06:00
}
2014-08-28 21:28:31 -06:00
}
2015-05-12 21:44:45 -06:00
var lookupGmailMXTests = [ ] struct {
name , host string
} {
2015-12-04 01:54:21 -07:00
{ "gmail.com" , "google.com." } ,
{ "gmail.com." , "google.com." } ,
2015-05-12 21:44:45 -06:00
}
2014-08-28 21:28:31 -06:00
func TestLookupGmailMX ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2010-11-04 08:30:39 -06:00
}
2016-04-13 21:17:44 -06:00
2015-05-12 21:44:45 -06:00
if ! supportsIPv4 || ! * testIPv4 {
t . Skip ( "IPv4 is required" )
2014-08-28 21:28:31 -06:00
}
2015-05-12 21:44:45 -06:00
for _ , tt := range lookupGmailMXTests {
mxs , err := LookupMX ( tt . name )
if err != nil {
t . Fatal ( err )
}
if len ( mxs ) == 0 {
t . Error ( "got no record" )
}
for _ , mx := range mxs {
2015-12-04 01:54:21 -07:00
if ! strings . HasSuffix ( mx . Host , tt . host ) {
2015-05-12 21:44:45 -06:00
t . Errorf ( "got %v; want a record containing %s" , mx , tt . host )
}
2014-08-28 21:28:31 -06:00
}
2011-10-18 11:57:04 -06:00
}
2010-11-04 08:30:39 -06:00
}
2011-08-04 18:27:51 -06:00
2015-05-12 21:44:45 -06:00
var lookupGmailNSTests = [ ] struct {
name , host string
} {
2015-12-04 01:54:21 -07:00
{ "gmail.com" , "google.com." } ,
{ "gmail.com." , "google.com." } ,
2015-05-12 21:44:45 -06:00
}
2014-08-28 21:28:31 -06:00
func TestLookupGmailNS ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2011-08-04 18:27:51 -06:00
}
2016-04-13 21:17:44 -06:00
2015-05-12 21:44:45 -06:00
if ! supportsIPv4 || ! * testIPv4 {
t . Skip ( "IPv4 is required" )
2011-08-04 18:27:51 -06:00
}
2015-05-12 21:44:45 -06:00
for _ , tt := range lookupGmailNSTests {
nss , err := LookupNS ( tt . name )
if err != nil {
2016-05-06 12:46:35 -06:00
testenv . SkipFlakyNet ( t )
2015-05-12 21:44:45 -06:00
t . Fatal ( err )
}
if len ( nss ) == 0 {
t . Error ( "got no record" )
}
for _ , ns := range nss {
2015-12-04 01:54:21 -07:00
if ! strings . HasSuffix ( ns . Host , tt . host ) {
2015-05-12 21:44:45 -06:00
t . Errorf ( "got %v; want a record containing %s" , ns , tt . host )
}
2014-08-28 21:28:31 -06:00
}
2011-08-04 18:27:51 -06:00
}
}
2015-05-12 21:44:45 -06:00
var lookupGmailTXTTests = [ ] struct {
name , txt , host string
} {
{ "gmail.com" , "spf" , "google.com" } ,
{ "gmail.com." , "spf" , "google.com" } ,
}
2014-08-28 21:28:31 -06:00
func TestLookupGmailTXT ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2012-10-18 00:39:04 -06:00
}
2016-04-13 21:17:44 -06:00
2015-05-12 21:44:45 -06:00
if ! supportsIPv4 || ! * testIPv4 {
t . Skip ( "IPv4 is required" )
2014-08-28 21:28:31 -06:00
}
2015-05-12 21:44:45 -06:00
for _ , tt := range lookupGmailTXTTests {
txts , err := LookupTXT ( tt . name )
if err != nil {
t . Fatal ( err )
}
if len ( txts ) == 0 {
t . Error ( "got no record" )
}
for _ , txt := range txts {
if ! strings . Contains ( txt , tt . txt ) || ( ! strings . HasSuffix ( txt , tt . host ) && ! strings . HasSuffix ( txt , tt . host + "." ) ) {
t . Errorf ( "got %s; want a record containing %s, %s" , txt , tt . txt , tt . host )
}
2014-08-28 21:28:31 -06:00
}
}
}
2015-01-28 04:08:41 -07:00
var lookupGooglePublicDNSAddrTests = [ ] struct {
2015-05-12 21:44:45 -06:00
addr , name string
2014-08-28 21:28:31 -06:00
} {
2015-12-04 01:54:21 -07:00
{ "8.8.8.8" , ".google.com." } ,
{ "8.8.4.4" , ".google.com." } ,
{ "2001:4860:4860::8888" , ".google.com." } ,
{ "2001:4860:4860::8844" , ".google.com." } ,
2014-08-28 21:28:31 -06:00
}
func TestLookupGooglePublicDNSAddr ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2012-10-18 00:39:04 -06:00
}
2016-04-13 21:17:44 -06:00
2015-05-12 21:44:45 -06:00
if ! supportsIPv4 || ! supportsIPv6 || ! * testIPv4 || ! * testIPv6 {
t . Skip ( "both IPv4 and IPv6 are required" )
}
2014-08-28 21:28:31 -06:00
2015-01-28 04:08:41 -07:00
for _ , tt := range lookupGooglePublicDNSAddrTests {
2014-08-28 21:28:31 -06:00
names , err := LookupAddr ( tt . addr )
if err != nil {
t . Fatal ( err )
}
if len ( names ) == 0 {
t . Error ( "got no record" )
}
for _ , name := range names {
2015-12-04 01:54:21 -07:00
if ! strings . HasSuffix ( name , tt . name ) {
2015-05-12 21:44:45 -06:00
t . Errorf ( "got %s; want a record containing %s" , name , tt . name )
2014-08-28 21:28:31 -06:00
}
}
2012-10-18 00:39:04 -06:00
}
}
2015-11-26 20:06:11 -07:00
func TestLookupIPv6LinkLocalAddr ( t * testing . T ) {
2016-01-13 05:04:10 -07:00
if ! supportsIPv6 || ! * testIPv6 {
2015-11-26 20:06:11 -07:00
t . Skip ( "IPv6 is required" )
}
addrs , err := LookupHost ( "localhost" )
if err != nil {
t . Fatal ( err )
}
found := false
for _ , addr := range addrs {
if addr == "fe80::1%lo0" {
found = true
break
}
}
if ! found {
t . Skipf ( "not supported on %s" , runtime . GOOS )
}
if _ , err := LookupAddr ( "fe80::1%lo0" ) ; err != nil {
t . Error ( err )
}
}
2015-05-12 21:44:45 -06:00
var lookupIANACNAMETests = [ ] struct {
name , cname string
} {
2015-12-04 01:54:21 -07:00
{ "www.iana.org" , "icann.org." } ,
{ "www.iana.org." , "icann.org." } ,
2015-05-12 21:44:45 -06:00
}
2014-08-28 21:28:31 -06:00
func TestLookupIANACNAME ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2011-09-12 21:05:33 -06:00
}
2016-04-13 21:17:44 -06:00
2015-05-12 21:44:45 -06:00
if ! supportsIPv4 || ! * testIPv4 {
t . Skip ( "IPv4 is required" )
2011-09-12 21:05:33 -06:00
}
2015-05-12 21:44:45 -06:00
for _ , tt := range lookupIANACNAMETests {
cname , err := LookupCNAME ( tt . name )
if err != nil {
t . Fatal ( err )
}
2015-12-04 01:54:21 -07:00
if ! strings . HasSuffix ( cname , tt . cname ) {
2015-05-12 21:44:45 -06:00
t . Errorf ( "got %s; want a record containing %s" , cname , tt . cname )
}
2011-09-12 21:05:33 -06:00
}
}
2015-05-12 21:44:45 -06:00
var lookupGoogleHostTests = [ ] struct {
name string
} {
{ "google.com" } ,
{ "google.com." } ,
}
2014-08-28 21:28:31 -06:00
func TestLookupGoogleHost ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2011-08-04 18:27:51 -06:00
}
2016-04-13 21:17:44 -06:00
2015-05-12 21:44:45 -06:00
if ! supportsIPv4 || ! * testIPv4 {
t . Skip ( "IPv4 is required" )
2011-08-04 18:27:51 -06:00
}
2015-05-12 21:44:45 -06:00
for _ , tt := range lookupGoogleHostTests {
addrs , err := LookupHost ( tt . name )
if err != nil {
t . Fatal ( err )
}
if len ( addrs ) == 0 {
t . Error ( "got no record" )
}
for _ , addr := range addrs {
if ParseIP ( addr ) == nil {
t . Errorf ( "got %q; want a literal IP address" , addr )
}
2014-08-28 21:28:31 -06:00
}
2011-08-04 18:27:51 -06:00
}
}
2012-02-23 19:58:30 -07:00
2015-05-12 21:44:45 -06:00
var lookupGoogleIPTests = [ ] struct {
name string
} {
{ "google.com" } ,
{ "google.com." } ,
}
2014-08-28 21:28:31 -06:00
func TestLookupGoogleIP ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2012-09-09 08:53:48 -06:00
}
2016-04-13 21:17:44 -06:00
2015-05-12 21:44:45 -06:00
if ! supportsIPv4 || ! * testIPv4 {
t . Skip ( "IPv4 is required" )
2014-08-28 21:28:31 -06:00
}
2015-05-12 21:44:45 -06:00
for _ , tt := range lookupGoogleIPTests {
ips , err := LookupIP ( tt . name )
if err != nil {
t . Fatal ( err )
}
if len ( ips ) == 0 {
t . Error ( "got no record" )
}
for _ , ip := range ips {
if ip . To4 ( ) == nil && ip . To16 ( ) == nil {
t . Errorf ( "got %v; want an IP address" , ip )
}
2014-08-28 21:28:31 -06:00
}
2012-09-09 08:53:48 -06:00
}
}
2012-02-23 19:58:30 -07:00
var revAddrTests = [ ] struct {
Addr string
Reverse string
ErrPrefix string
} {
{ "1.2.3.4" , "4.3.2.1.in-addr.arpa." , "" } ,
{ "245.110.36.114" , "114.36.110.245.in-addr.arpa." , "" } ,
{ "::ffff:12.34.56.78" , "78.56.34.12.in-addr.arpa." , "" } ,
{ "::1" , "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." , "" } ,
{ "1::" , "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa." , "" } ,
{ "1234:567::89a:bcde" , "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa." , "" } ,
{ "1234:567:fefe:bcbc:adad:9e4a:89a:bcde" , "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa." , "" } ,
{ "1.2.3" , "" , "unrecognized address" } ,
{ "1.2.3.4.5" , "" , "unrecognized address" } ,
{ "1234:567:bcbca::89a:bcde" , "" , "unrecognized address" } ,
{ "1234:567::bcbc:adad::89a:bcde" , "" , "unrecognized address" } ,
}
func TestReverseAddress ( t * testing . T ) {
for i , tt := range revAddrTests {
a , err := reverseaddr ( tt . Addr )
if len ( tt . ErrPrefix ) > 0 && err == nil {
t . Errorf ( "#%d: expected %q, got <nil> (error)" , i , tt . ErrPrefix )
continue
}
if len ( tt . ErrPrefix ) == 0 && err != nil {
t . Errorf ( "#%d: expected <nil>, got %q (error)" , i , err )
}
if err != nil && err . ( * DNSError ) . Err != tt . ErrPrefix {
t . Errorf ( "#%d: expected %q, got %q (mismatched error)" , i , tt . ErrPrefix , err . ( * DNSError ) . Err )
}
if a != tt . Reverse {
t . Errorf ( "#%d: expected %q, got %q (reverse address)" , i , tt . Reverse , a )
}
}
}
2014-12-30 23:45:46 -07:00
func TestLookupIPDeadline ( t * testing . T ) {
if ! * testDNSFlood {
t . Skip ( "test disabled; use -dnsflood to enable" )
}
const N = 5000
const timeout = 3 * time . Second
2016-04-14 18:47:25 -06:00
ctxHalfTimeout , cancel := context . WithTimeout ( context . Background ( ) , timeout / 2 )
defer cancel ( )
ctxTimeout , cancel := context . WithTimeout ( context . Background ( ) , timeout )
defer cancel ( )
2014-12-30 23:45:46 -07:00
c := make ( chan error , 2 * N )
for i := 0 ; i < N ; i ++ {
name := fmt . Sprintf ( "%d.net-test.golang.org" , i )
go func ( ) {
2016-04-14 18:47:25 -06:00
_ , err := lookupIPContext ( ctxHalfTimeout , name )
2014-12-30 23:45:46 -07:00
c <- err
} ( )
go func ( ) {
2016-04-14 18:47:25 -06:00
_ , err := lookupIPContext ( ctxTimeout , name )
2014-12-30 23:45:46 -07:00
c <- err
} ( )
}
qstats := struct {
succeeded , failed int
timeout , temporary , other int
unknown int
} { }
deadline := time . After ( timeout + time . Second )
for i := 0 ; i < 2 * N ; i ++ {
select {
case <- deadline :
t . Fatal ( "deadline exceeded" )
case err := <- c :
switch err := err . ( type ) {
case nil :
qstats . succeeded ++
case Error :
qstats . failed ++
if err . Timeout ( ) {
qstats . timeout ++
}
if err . Temporary ( ) {
qstats . temporary ++
}
if ! err . Timeout ( ) && ! err . Temporary ( ) {
qstats . other ++
}
default :
qstats . failed ++
qstats . unknown ++
}
}
}
// A high volume of DNS queries for sub-domain of golang.org
// would be coordinated by authoritative or recursive server,
// or stub resolver which implements query-response rate
// limitation, so we can expect some query successes and more
// failures including timeout, temporary and other here.
// As a rule, unknown must not be shown but it might possibly
// happen due to issue 4856 for now.
t . Logf ( "%v succeeded, %v failed (%v timeout, %v temporary, %v other, %v unknown)" , qstats . succeeded , qstats . failed , qstats . timeout , qstats . temporary , qstats . other , qstats . unknown )
}
2015-08-18 20:19:58 -06:00
2015-11-29 02:06:23 -07:00
func TestLookupDotsWithLocalSource ( t * testing . T ) {
2016-01-13 05:04:10 -07:00
if ! supportsIPv4 || ! * testIPv4 {
2015-11-26 20:09:14 -07:00
t . Skip ( "IPv4 is required" )
}
for i , fn := range [ ] func ( ) func ( ) { forceGoDNS , forceCgoDNS } {
fixup := fn ( )
if fixup == nil {
continue
}
names , err := LookupAddr ( "127.0.0.1" )
fixup ( )
if err != nil {
2016-01-13 05:04:10 -07:00
t . Logf ( "#%d: %v" , i , err )
2015-11-26 20:09:14 -07:00
continue
}
2016-01-06 18:37:05 -07:00
mode := "netgo"
if i == 1 {
mode = "netcgo"
}
2016-01-21 01:22:30 -07:00
loop :
for i , name := range names {
2016-01-06 18:37:05 -07:00
if strings . Index ( name , "." ) == len ( name ) - 1 { // "localhost" not "localhost."
2016-01-21 01:22:30 -07:00
for j := range names {
if j == i {
continue
}
if names [ j ] == name [ : len ( name ) - 1 ] {
// It's OK if we find the name without the dot,
// as some systems say 127.0.0.1 localhost localhost.
continue loop
}
}
2016-01-06 18:37:05 -07:00
t . Errorf ( "%s: got %s; want %s" , mode , name , name [ : len ( name ) - 1 ] )
} else if strings . Contains ( name , "." ) && ! strings . HasSuffix ( name , "." ) { // "localhost.localdomain." not "localhost.localdomain"
t . Errorf ( "%s: got %s; want name ending with trailing dot" , mode , name )
2015-11-26 20:09:14 -07:00
}
}
}
}
func TestLookupDotsWithRemoteSource ( t * testing . T ) {
2016-04-13 21:17:44 -06:00
if testenv . Builder ( ) == "" {
testenv . MustHaveExternalNetwork ( t )
2016-01-13 05:04:10 -07:00
}
2016-04-13 21:17:44 -06:00
2016-01-22 21:28:14 -07:00
if ! supportsIPv4 || ! * testIPv4 {
2016-01-13 05:04:10 -07:00
t . Skip ( "IPv4 is required" )
2015-08-18 20:19:58 -06:00
}
2015-11-26 20:09:14 -07:00
if fixup := forceGoDNS ( ) ; fixup != nil {
testDots ( t , "go" )
fixup ( )
}
if fixup := forceCgoDNS ( ) ; fixup != nil {
2015-08-18 20:19:58 -06:00
testDots ( t , "cgo" )
2015-11-26 20:09:14 -07:00
fixup ( )
2015-08-18 20:19:58 -06:00
}
}
func testDots ( t * testing . T , mode string ) {
names , err := LookupAddr ( "8.8.8.8" ) // Google dns server
if err != nil {
2016-05-06 10:24:57 -06:00
testenv . SkipFlakyNet ( t )
2015-08-18 20:19:58 -06:00
t . Errorf ( "LookupAddr(8.8.8.8): %v (mode=%v)" , err , mode )
} else {
for _ , name := range names {
if ! strings . HasSuffix ( name , ".google.com." ) {
t . Errorf ( "LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)" , names , mode )
break
}
}
}
cname , err := LookupCNAME ( "www.mit.edu" )
2016-05-06 10:24:57 -06:00
if err != nil {
testenv . SkipFlakyNet ( t )
t . Errorf ( "LookupCNAME(www.mit.edu, mode=%v): %v" , mode , err )
} else if ! strings . HasSuffix ( cname , "." ) {
t . Errorf ( "LookupCNAME(www.mit.edu) = %v, want cname ending in . with trailing dot (mode=%v)" , cname , mode )
2015-08-18 20:19:58 -06:00
}
mxs , err := LookupMX ( "google.com" )
if err != nil {
2016-05-06 10:24:57 -06:00
testenv . SkipFlakyNet ( t )
2015-08-18 20:19:58 -06:00
t . Errorf ( "LookupMX(google.com): %v (mode=%v)" , err , mode )
} else {
for _ , mx := range mxs {
if ! strings . HasSuffix ( mx . Host , ".google.com." ) {
t . Errorf ( "LookupMX(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)" , mxString ( mxs ) , mode )
break
}
}
}
nss , err := LookupNS ( "google.com" )
if err != nil {
2016-05-06 10:24:57 -06:00
testenv . SkipFlakyNet ( t )
2015-08-18 20:19:58 -06:00
t . Errorf ( "LookupNS(google.com): %v (mode=%v)" , err , mode )
} else {
for _ , ns := range nss {
if ! strings . HasSuffix ( ns . Host , ".google.com." ) {
t . Errorf ( "LookupNS(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)" , nsString ( nss ) , mode )
break
}
}
}
cname , srvs , err := LookupSRV ( "xmpp-server" , "tcp" , "google.com" )
if err != nil {
2016-05-06 10:24:57 -06:00
testenv . SkipFlakyNet ( t )
2015-08-18 20:19:58 -06:00
t . Errorf ( "LookupSRV(xmpp-server, tcp, google.com): %v (mode=%v)" , err , mode )
} else {
if ! strings . HasSuffix ( cname , ".google.com." ) {
t . Errorf ( "LookupSRV(xmpp-server, tcp, google.com) returned cname=%v, want name ending in .google.com. with trailing dot (mode=%v)" , cname , mode )
}
for _ , srv := range srvs {
if ! strings . HasSuffix ( srv . Target , ".google.com." ) {
t . Errorf ( "LookupSRV(xmpp-server, tcp, google.com) returned addrs=%v, want names ending in .google.com. with trailing dot (mode=%v)" , srvString ( srvs ) , mode )
break
}
}
}
}
func mxString ( mxs [ ] * MX ) string {
var buf bytes . Buffer
sep := ""
fmt . Fprintf ( & buf , "[" )
for _ , mx := range mxs {
fmt . Fprintf ( & buf , "%s%s:%d" , sep , mx . Host , mx . Pref )
sep = " "
}
fmt . Fprintf ( & buf , "]" )
return buf . String ( )
}
func nsString ( nss [ ] * NS ) string {
var buf bytes . Buffer
sep := ""
fmt . Fprintf ( & buf , "[" )
for _ , ns := range nss {
fmt . Fprintf ( & buf , "%s%s" , sep , ns . Host )
sep = " "
}
fmt . Fprintf ( & buf , "]" )
return buf . String ( )
}
func srvString ( srvs [ ] * SRV ) string {
var buf bytes . Buffer
sep := ""
fmt . Fprintf ( & buf , "[" )
for _ , srv := range srvs {
fmt . Fprintf ( & buf , "%s%s:%d:%d:%d" , sep , srv . Target , srv . Port , srv . Priority , srv . Weight )
sep = " "
}
fmt . Fprintf ( & buf , "]" )
return buf . String ( )
}
2015-10-31 23:29:45 -06:00
var lookupPortTests = [ ] struct {
network string
name string
port int
ok bool
} {
2016-05-12 14:02:00 -06:00
// See http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
//
// Please be careful about adding new mappings for testings.
// There are platforms having incomplete mappings for
// restricted resource access and security reasons.
2015-10-31 23:29:45 -06:00
2016-05-12 14:02:00 -06:00
{ "tcp" , "0" , 0 , true } ,
{ "tcp" , "http" , 80 , true } ,
2015-10-31 23:29:45 -06:00
{ "udp" , "0" , 0 , true } ,
{ "udp" , "domain" , 53 , true } ,
{ "--badnet--" , "zzz" , 0 , false } ,
{ "tcp" , "--badport--" , 0 , false } ,
{ "tcp" , "-1" , 0 , false } ,
{ "tcp" , "65536" , 0 , false } ,
{ "udp" , "-1" , 0 , false } ,
{ "udp" , "65536" , 0 , false } ,
2016-02-19 13:53:17 -07:00
{ "tcp" , "123456789" , 0 , false } ,
2015-12-14 11:22:23 -07:00
// Issue 13610: LookupPort("tcp", "")
{ "tcp" , "" , 0 , true } ,
{ "tcp4" , "" , 0 , true } ,
2016-05-12 14:02:00 -06:00
{ "tcp6" , "" , 0 , true } ,
2015-12-14 11:22:23 -07:00
{ "udp" , "" , 0 , true } ,
2016-05-12 14:02:00 -06:00
{ "udp4" , "" , 0 , true } ,
{ "udp6" , "" , 0 , true } ,
2015-10-31 23:29:45 -06:00
}
func TestLookupPort ( t * testing . T ) {
switch runtime . GOOS {
case "nacl" :
t . Skipf ( "not supported on %s" , runtime . GOOS )
2016-03-02 19:12:30 -07:00
case "android" :
if netGo {
t . Skipf ( "not supported on %s without cgo; see golang.org/issues/14576" , runtime . GOOS )
}
2015-10-31 23:29:45 -06:00
}
for _ , tt := range lookupPortTests {
2016-05-12 14:02:00 -06:00
port , err := LookupPort ( tt . network , tt . name )
if port != tt . port || ( err == nil ) != tt . ok {
2016-02-19 13:53:17 -07:00
t . Errorf ( "LookupPort(%q, %q) = %d, %v; want %d, error=%t" , tt . network , tt . name , port , err , tt . port , ! tt . ok )
2015-10-31 23:29:45 -06:00
}
2016-05-12 14:02:00 -06:00
if err != nil {
if perr := parseLookupPortError ( err ) ; perr != nil {
t . Error ( perr )
}
}
2015-10-31 23:29:45 -06:00
}
}