1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package net
6
7import (
8	"context"
9	"errors"
10	"fmt"
11	"internal/poll"
12	"io"
13	"io/fs"
14	"net/internal/socktest"
15	"os"
16	"runtime"
17	"strings"
18	"testing"
19	"time"
20)
21
22func (e *OpError) isValid() error {
23	if e.Op == "" {
24		return fmt.Errorf("OpError.Op is empty: %v", e)
25	}
26	if e.Net == "" {
27		return fmt.Errorf("OpError.Net is empty: %v", e)
28	}
29	for _, addr := range []Addr{e.Source, e.Addr} {
30		switch addr := addr.(type) {
31		case nil:
32		case *TCPAddr:
33			if addr == nil {
34				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
35			}
36		case *UDPAddr:
37			if addr == nil {
38				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
39			}
40		case *IPAddr:
41			if addr == nil {
42				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
43			}
44		case *IPNet:
45			if addr == nil {
46				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
47			}
48		case *UnixAddr:
49			if addr == nil {
50				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
51			}
52		case *pipeAddr:
53			if addr == nil {
54				return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
55			}
56		case fileAddr:
57			if addr == "" {
58				return fmt.Errorf("OpError.Source or Addr is empty: %#v, %v", addr, e)
59			}
60		default:
61			return fmt.Errorf("OpError.Source or Addr is unknown type: %T, %v", addr, e)
62		}
63	}
64	if e.Err == nil {
65		return fmt.Errorf("OpError.Err is empty: %v", e)
66	}
67	return nil
68}
69
70// parseDialError parses nestedErr and reports whether it is a valid
71// error value from Dial, Listen functions.
72// It returns nil when nestedErr is valid.
73func parseDialError(nestedErr error) error {
74	if nestedErr == nil {
75		return nil
76	}
77
78	switch err := nestedErr.(type) {
79	case *OpError:
80		if err := err.isValid(); err != nil {
81			return err
82		}
83		nestedErr = err.Err
84		goto second
85	}
86	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
87
88second:
89	if isPlatformError(nestedErr) {
90		return nil
91	}
92	switch err := nestedErr.(type) {
93	case *AddrError, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError:
94		return nil
95	case interface{ isAddrinfoErrno() }:
96		return nil
97	case *os.SyscallError:
98		nestedErr = err.Err
99		goto third
100	case *fs.PathError: // for Plan 9
101		nestedErr = err.Err
102		goto third
103	}
104	switch nestedErr {
105	case errCanceled, ErrClosed, errMissingAddress, errNoSuitableAddress,
106		context.DeadlineExceeded, context.Canceled:
107		return nil
108	}
109	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
110
111third:
112	if isPlatformError(nestedErr) {
113		return nil
114	}
115	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
116}
117
118var dialErrorTests = []struct {
119	network, address string
120}{
121	{"foo", ""},
122	{"bar", "baz"},
123	{"datakit", "mh/astro/r70"},
124	{"tcp", ""},
125	{"tcp", "127.0.0.1:☺"},
126	{"tcp", "no-such-name:80"},
127	{"tcp", "mh/astro/r70:http"},
128
129	{"tcp", JoinHostPort("127.0.0.1", "-1")},
130	{"tcp", JoinHostPort("127.0.0.1", "123456789")},
131	{"udp", JoinHostPort("127.0.0.1", "-1")},
132	{"udp", JoinHostPort("127.0.0.1", "123456789")},
133	{"ip:icmp", "127.0.0.1"},
134
135	{"unix", "/path/to/somewhere"},
136	{"unixgram", "/path/to/somewhere"},
137	{"unixpacket", "/path/to/somewhere"},
138}
139
140func TestDialError(t *testing.T) {
141	switch runtime.GOOS {
142	case "plan9":
143		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
144	}
145
146	origTestHookLookupIP := testHookLookupIP
147	defer func() { testHookLookupIP = origTestHookLookupIP }()
148	testHookLookupIP = func(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
149		return nil, &DNSError{Err: "dial error test", Name: "name", Server: "server", IsTimeout: true}
150	}
151	sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
152		return nil, errOpNotSupported
153	})
154	defer sw.Set(socktest.FilterConnect, nil)
155
156	d := Dialer{Timeout: someTimeout}
157	for i, tt := range dialErrorTests {
158		i, tt := i, tt
159		t.Run(fmt.Sprint(i), func(t *testing.T) {
160			c, err := d.Dial(tt.network, tt.address)
161			if err == nil {
162				t.Errorf("should fail; %s:%s->%s", c.LocalAddr().Network(), c.LocalAddr(), c.RemoteAddr())
163				c.Close()
164				return
165			}
166			if tt.network == "tcp" || tt.network == "udp" {
167				nerr := err
168				if op, ok := nerr.(*OpError); ok {
169					nerr = op.Err
170				}
171				if sys, ok := nerr.(*os.SyscallError); ok {
172					nerr = sys.Err
173				}
174				if nerr == errOpNotSupported {
175					t.Fatalf("should fail without %v; %s:%s->", nerr, tt.network, tt.address)
176				}
177			}
178			if c != nil {
179				t.Errorf("Dial returned non-nil interface %T(%v) with err != nil", c, c)
180			}
181			if err = parseDialError(err); err != nil {
182				t.Error(err)
183			}
184		})
185	}
186}
187
188func TestProtocolDialError(t *testing.T) {
189	switch runtime.GOOS {
190	case "solaris", "illumos":
191		t.Skipf("not supported on %s", runtime.GOOS)
192	}
193
194	for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} {
195		var err error
196		switch network {
197		case "tcp":
198			_, err = DialTCP(network, nil, &TCPAddr{Port: 1 << 16})
199		case "udp":
200			_, err = DialUDP(network, nil, &UDPAddr{Port: 1 << 16})
201		case "ip:4294967296":
202			_, err = DialIP(network, nil, nil)
203		case "unix", "unixpacket", "unixgram":
204			_, err = DialUnix(network, nil, &UnixAddr{Name: "//"})
205		}
206		if err == nil {
207			t.Errorf("%s: should fail", network)
208			continue
209		}
210		if err := parseDialError(err); err != nil {
211			t.Errorf("%s: %v", network, err)
212			continue
213		}
214		t.Logf("%s: error as expected: %v", network, err)
215	}
216}
217
218func TestDialAddrError(t *testing.T) {
219	switch runtime.GOOS {
220	case "plan9":
221		t.Skipf("not supported on %s", runtime.GOOS)
222	}
223
224	if !supportsIPv4() || !supportsIPv6() {
225		t.Skip("both IPv4 and IPv6 are required")
226	}
227
228	for _, tt := range []struct {
229		network string
230		lit     string
231		addr    *TCPAddr
232	}{
233		{"tcp4", "::1", nil},
234		{"tcp4", "", &TCPAddr{IP: IPv6loopback}},
235		// We don't test the {"tcp6", "byte sequence", nil}
236		// case for now because there is no easy way to
237		// control name resolution.
238		{"tcp6", "", &TCPAddr{IP: IP{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}}},
239	} {
240		desc := tt.lit
241		if desc == "" {
242			desc = tt.addr.String()
243		}
244		t.Run(fmt.Sprintf("%s/%s", tt.network, desc), func(t *testing.T) {
245			var err error
246			var c Conn
247			var op string
248			if tt.lit != "" {
249				c, err = Dial(tt.network, JoinHostPort(tt.lit, "0"))
250				op = fmt.Sprintf("Dial(%q, %q)", tt.network, JoinHostPort(tt.lit, "0"))
251			} else {
252				c, err = DialTCP(tt.network, nil, tt.addr)
253				op = fmt.Sprintf("DialTCP(%q, %q)", tt.network, tt.addr)
254			}
255			t.Logf("%s: %v", op, err)
256			if err == nil {
257				c.Close()
258				t.Fatalf("%s succeeded, want error", op)
259			}
260			if perr := parseDialError(err); perr != nil {
261				t.Fatal(perr)
262			}
263			operr := err.(*OpError).Err
264			aerr, ok := operr.(*AddrError)
265			if !ok {
266				t.Fatalf("OpError.Err is %T, want *AddrError", operr)
267			}
268			want := tt.lit
269			if tt.lit == "" {
270				want = tt.addr.IP.String()
271			}
272			if aerr.Addr != want {
273				t.Errorf("error Addr=%q, want %q", aerr.Addr, want)
274			}
275		})
276	}
277}
278
279var listenErrorTests = []struct {
280	network, address string
281}{
282	{"foo", ""},
283	{"bar", "baz"},
284	{"datakit", "mh/astro/r70"},
285	{"tcp", "127.0.0.1:☺"},
286	{"tcp", "no-such-name:80"},
287	{"tcp", "mh/astro/r70:http"},
288
289	{"tcp", JoinHostPort("127.0.0.1", "-1")},
290	{"tcp", JoinHostPort("127.0.0.1", "123456789")},
291
292	{"unix", "/path/to/somewhere"},
293	{"unixpacket", "/path/to/somewhere"},
294}
295
296func TestListenError(t *testing.T) {
297	switch runtime.GOOS {
298	case "plan9":
299		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
300	}
301
302	origTestHookLookupIP := testHookLookupIP
303	defer func() { testHookLookupIP = origTestHookLookupIP }()
304	testHookLookupIP = func(_ context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
305		return nil, &DNSError{Err: "listen error test", Name: "name", Server: "server", IsTimeout: true}
306	}
307	sw.Set(socktest.FilterListen, func(so *socktest.Status) (socktest.AfterFilter, error) {
308		return nil, errOpNotSupported
309	})
310	defer sw.Set(socktest.FilterListen, nil)
311
312	for i, tt := range listenErrorTests {
313		t.Run(fmt.Sprintf("%s_%s", tt.network, tt.address), func(t *testing.T) {
314			ln, err := Listen(tt.network, tt.address)
315			if err == nil {
316				t.Errorf("#%d: should fail; %s:%s->", i, ln.Addr().Network(), ln.Addr())
317				ln.Close()
318				return
319			}
320			if tt.network == "tcp" {
321				nerr := err
322				if op, ok := nerr.(*OpError); ok {
323					nerr = op.Err
324				}
325				if sys, ok := nerr.(*os.SyscallError); ok {
326					nerr = sys.Err
327				}
328				if nerr == errOpNotSupported {
329					t.Fatalf("#%d: should fail without %v; %s:%s->", i, nerr, tt.network, tt.address)
330				}
331			}
332			if ln != nil {
333				t.Errorf("Listen returned non-nil interface %T(%v) with err != nil", ln, ln)
334			}
335			if err = parseDialError(err); err != nil {
336				t.Errorf("#%d: %v", i, err)
337			}
338		})
339	}
340}
341
342var listenPacketErrorTests = []struct {
343	network, address string
344}{
345	{"foo", ""},
346	{"bar", "baz"},
347	{"datakit", "mh/astro/r70"},
348	{"udp", "127.0.0.1:☺"},
349	{"udp", "no-such-name:80"},
350	{"udp", "mh/astro/r70:http"},
351
352	{"udp", JoinHostPort("127.0.0.1", "-1")},
353	{"udp", JoinHostPort("127.0.0.1", "123456789")},
354}
355
356func TestListenPacketError(t *testing.T) {
357	switch runtime.GOOS {
358	case "plan9":
359		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
360	}
361
362	origTestHookLookupIP := testHookLookupIP
363	defer func() { testHookLookupIP = origTestHookLookupIP }()
364	testHookLookupIP = func(_ context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
365		return nil, &DNSError{Err: "listen error test", Name: "name", Server: "server", IsTimeout: true}
366	}
367
368	for i, tt := range listenPacketErrorTests {
369		t.Run(fmt.Sprintf("%s_%s", tt.network, tt.address), func(t *testing.T) {
370			c, err := ListenPacket(tt.network, tt.address)
371			if err == nil {
372				t.Errorf("#%d: should fail; %s:%s->", i, c.LocalAddr().Network(), c.LocalAddr())
373				c.Close()
374				return
375			}
376			if c != nil {
377				t.Errorf("ListenPacket returned non-nil interface %T(%v) with err != nil", c, c)
378			}
379			if err = parseDialError(err); err != nil {
380				t.Errorf("#%d: %v", i, err)
381			}
382		})
383	}
384}
385
386func TestProtocolListenError(t *testing.T) {
387	switch runtime.GOOS {
388	case "plan9":
389		t.Skipf("not supported on %s", runtime.GOOS)
390	}
391
392	for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} {
393		var err error
394		switch network {
395		case "tcp":
396			_, err = ListenTCP(network, &TCPAddr{Port: 1 << 16})
397		case "udp":
398			_, err = ListenUDP(network, &UDPAddr{Port: 1 << 16})
399		case "ip:4294967296":
400			_, err = ListenIP(network, nil)
401		case "unix", "unixpacket":
402			_, err = ListenUnix(network, &UnixAddr{Name: "//"})
403		case "unixgram":
404			_, err = ListenUnixgram(network, &UnixAddr{Name: "//"})
405		}
406		if err == nil {
407			t.Errorf("%s: should fail", network)
408			continue
409		}
410		if err = parseDialError(err); err != nil {
411			t.Errorf("%s: %v", network, err)
412			continue
413		}
414	}
415}
416
417// parseReadError parses nestedErr and reports whether it is a valid
418// error value from Read functions.
419// It returns nil when nestedErr is valid.
420func parseReadError(nestedErr error) error {
421	if nestedErr == nil {
422		return nil
423	}
424
425	switch err := nestedErr.(type) {
426	case *OpError:
427		if err := err.isValid(); err != nil {
428			return err
429		}
430		nestedErr = err.Err
431		goto second
432	}
433	if nestedErr == io.EOF {
434		return nil
435	}
436	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
437
438second:
439	if isPlatformError(nestedErr) {
440		return nil
441	}
442	switch err := nestedErr.(type) {
443	case *os.SyscallError:
444		nestedErr = err.Err
445		goto third
446	}
447	switch nestedErr {
448	case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
449		return nil
450	}
451	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
452
453third:
454	if isPlatformError(nestedErr) {
455		return nil
456	}
457	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
458}
459
460// parseWriteError parses nestedErr and reports whether it is a valid
461// error value from Write functions.
462// It returns nil when nestedErr is valid.
463func parseWriteError(nestedErr error) error {
464	if nestedErr == nil {
465		return nil
466	}
467
468	switch err := nestedErr.(type) {
469	case *OpError:
470		if err := err.isValid(); err != nil {
471			return err
472		}
473		nestedErr = err.Err
474		goto second
475	}
476	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
477
478second:
479	if isPlatformError(nestedErr) {
480		return nil
481	}
482	switch err := nestedErr.(type) {
483	case *AddrError, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError:
484		return nil
485	case interface{ isAddrinfoErrno() }:
486		return nil
487	case *os.SyscallError:
488		nestedErr = err.Err
489		goto third
490	}
491	switch nestedErr {
492	case errCanceled, ErrClosed, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF:
493		return nil
494	}
495	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
496
497third:
498	if isPlatformError(nestedErr) {
499		return nil
500	}
501	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
502}
503
504// parseCloseError parses nestedErr and reports whether it is a valid
505// error value from Close functions.
506// It returns nil when nestedErr is valid.
507func parseCloseError(nestedErr error, isShutdown bool) error {
508	if nestedErr == nil {
509		return nil
510	}
511
512	// Because historically we have not exported the error that we
513	// return for an operation on a closed network connection,
514	// there are programs that test for the exact error string.
515	// Verify that string here so that we don't break those
516	// programs unexpectedly. See issues #4373 and #19252.
517	want := "use of closed network connection"
518	if !isShutdown && !strings.Contains(nestedErr.Error(), want) {
519		return fmt.Errorf("error string %q does not contain expected string %q", nestedErr, want)
520	}
521
522	if !isShutdown && !errors.Is(nestedErr, ErrClosed) {
523		return fmt.Errorf("errors.Is(%v, errClosed) returns false, want true", nestedErr)
524	}
525
526	switch err := nestedErr.(type) {
527	case *OpError:
528		if err := err.isValid(); err != nil {
529			return err
530		}
531		nestedErr = err.Err
532		goto second
533	}
534	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
535
536second:
537	if isPlatformError(nestedErr) {
538		return nil
539	}
540	switch err := nestedErr.(type) {
541	case *os.SyscallError:
542		nestedErr = err.Err
543		goto third
544	case *fs.PathError: // for Plan 9
545		nestedErr = err.Err
546		goto third
547	}
548	switch nestedErr {
549	case ErrClosed:
550		return nil
551	}
552	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
553
554third:
555	if isPlatformError(nestedErr) {
556		return nil
557	}
558	switch nestedErr {
559	case fs.ErrClosed: // for Plan 9
560		return nil
561	}
562	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
563}
564
565func TestCloseError(t *testing.T) {
566	t.Run("tcp", func(t *testing.T) {
567		ln := newLocalListener(t, "tcp")
568		defer ln.Close()
569		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
570		if err != nil {
571			t.Fatal(err)
572		}
573		defer c.Close()
574
575		for i := 0; i < 3; i++ {
576			err = c.(*TCPConn).CloseRead()
577			if perr := parseCloseError(err, true); perr != nil {
578				t.Errorf("#%d: %v", i, perr)
579			}
580		}
581		for i := 0; i < 3; i++ {
582			err = c.(*TCPConn).CloseWrite()
583			if perr := parseCloseError(err, true); perr != nil {
584				t.Errorf("#%d: %v", i, perr)
585			}
586		}
587		for i := 0; i < 3; i++ {
588			err = c.Close()
589			if perr := parseCloseError(err, false); perr != nil {
590				t.Errorf("#%d: %v", i, perr)
591			}
592			err = ln.Close()
593			if perr := parseCloseError(err, false); perr != nil {
594				t.Errorf("#%d: %v", i, perr)
595			}
596		}
597	})
598
599	t.Run("udp", func(t *testing.T) {
600		if !testableNetwork("udp") {
601			t.Skipf("skipping: udp not available")
602		}
603
604		pc, err := ListenPacket("udp", "127.0.0.1:0")
605		if err != nil {
606			t.Fatal(err)
607		}
608		defer pc.Close()
609
610		for i := 0; i < 3; i++ {
611			err = pc.Close()
612			if perr := parseCloseError(err, false); perr != nil {
613				t.Errorf("#%d: %v", i, perr)
614			}
615		}
616	})
617}
618
619// parseAcceptError parses nestedErr and reports whether it is a valid
620// error value from Accept functions.
621// It returns nil when nestedErr is valid.
622func parseAcceptError(nestedErr error) error {
623	if nestedErr == nil {
624		return nil
625	}
626
627	switch err := nestedErr.(type) {
628	case *OpError:
629		if err := err.isValid(); err != nil {
630			return err
631		}
632		nestedErr = err.Err
633		goto second
634	}
635	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
636
637second:
638	if isPlatformError(nestedErr) {
639		return nil
640	}
641	switch err := nestedErr.(type) {
642	case *os.SyscallError:
643		nestedErr = err.Err
644		goto third
645	case *fs.PathError: // for Plan 9
646		nestedErr = err.Err
647		goto third
648	}
649	switch nestedErr {
650	case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
651		return nil
652	}
653	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
654
655third:
656	if isPlatformError(nestedErr) {
657		return nil
658	}
659	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
660}
661
662func TestAcceptError(t *testing.T) {
663	handler := func(ls *localServer, ln Listener) {
664		for {
665			ln.(*TCPListener).SetDeadline(time.Now().Add(5 * time.Millisecond))
666			c, err := ln.Accept()
667			if perr := parseAcceptError(err); perr != nil {
668				t.Error(perr)
669			}
670			if err != nil {
671				if c != nil {
672					t.Errorf("Accept returned non-nil interface %T(%v) with err != nil", c, c)
673				}
674				if nerr, ok := err.(Error); !ok || (!nerr.Timeout() && !nerr.Temporary()) {
675					return
676				}
677				continue
678			}
679			c.Close()
680		}
681	}
682	ls := newLocalServer(t, "tcp")
683	if err := ls.buildup(handler); err != nil {
684		ls.teardown()
685		t.Fatal(err)
686	}
687
688	time.Sleep(100 * time.Millisecond)
689	ls.teardown()
690}
691
692// parseCommonError parses nestedErr and reports whether it is a valid
693// error value from miscellaneous functions.
694// It returns nil when nestedErr is valid.
695func parseCommonError(nestedErr error) error {
696	if nestedErr == nil {
697		return nil
698	}
699
700	switch err := nestedErr.(type) {
701	case *OpError:
702		if err := err.isValid(); err != nil {
703			return err
704		}
705		nestedErr = err.Err
706		goto second
707	}
708	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
709
710second:
711	if isPlatformError(nestedErr) {
712		return nil
713	}
714	switch err := nestedErr.(type) {
715	case *os.SyscallError:
716		nestedErr = err.Err
717		goto third
718	case *os.LinkError:
719		nestedErr = err.Err
720		goto third
721	case *fs.PathError:
722		nestedErr = err.Err
723		goto third
724	}
725	switch nestedErr {
726	case ErrClosed:
727		return nil
728	}
729	return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
730
731third:
732	if isPlatformError(nestedErr) {
733		return nil
734	}
735	return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
736}
737
738func TestFileError(t *testing.T) {
739	switch runtime.GOOS {
740	case "windows":
741		t.Skipf("not supported on %s", runtime.GOOS)
742	}
743
744	f, err := os.CreateTemp("", "go-nettest")
745	if err != nil {
746		t.Fatal(err)
747	}
748	defer os.Remove(f.Name())
749	defer f.Close()
750
751	c, err := FileConn(f)
752	if err != nil {
753		if c != nil {
754			t.Errorf("FileConn returned non-nil interface %T(%v) with err != nil", c, c)
755		}
756		if perr := parseCommonError(err); perr != nil {
757			t.Error(perr)
758		}
759	} else {
760		c.Close()
761		t.Error("should fail")
762	}
763	ln, err := FileListener(f)
764	if err != nil {
765		if ln != nil {
766			t.Errorf("FileListener returned non-nil interface %T(%v) with err != nil", ln, ln)
767		}
768		if perr := parseCommonError(err); perr != nil {
769			t.Error(perr)
770		}
771	} else {
772		ln.Close()
773		t.Error("should fail")
774	}
775	pc, err := FilePacketConn(f)
776	if err != nil {
777		if pc != nil {
778			t.Errorf("FilePacketConn returned non-nil interface %T(%v) with err != nil", pc, pc)
779		}
780		if perr := parseCommonError(err); perr != nil {
781			t.Error(perr)
782		}
783	} else {
784		pc.Close()
785		t.Error("should fail")
786	}
787
788	ln = newLocalListener(t, "tcp")
789
790	for i := 0; i < 3; i++ {
791		f, err := ln.(*TCPListener).File()
792		if err != nil {
793			if perr := parseCommonError(err); perr != nil {
794				t.Error(perr)
795			}
796		} else {
797			f.Close()
798		}
799		ln.Close()
800	}
801}
802
803func parseLookupPortError(nestedErr error) error {
804	if nestedErr == nil {
805		return nil
806	}
807
808	switch nestedErr.(type) {
809	case *AddrError, *DNSError:
810		return nil
811	case *fs.PathError: // for Plan 9
812		return nil
813	}
814	return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
815}
816
817func TestContextError(t *testing.T) {
818	if !errors.Is(errCanceled, context.Canceled) {
819		t.Error("errCanceled is not context.Canceled")
820	}
821	if !errors.Is(errTimeout, context.DeadlineExceeded) {
822		t.Error("errTimeout is not context.DeadlineExceeded")
823	}
824}
825