1// Copyright 2009 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 "io" 10 "os" 11) 12 13func (c *TCPConn) readFrom(r io.Reader) (int64, error) { 14 return genericReadFrom(c, r) 15} 16 17func (c *TCPConn) writeTo(w io.Writer) (int64, error) { 18 return genericWriteTo(c, w) 19} 20 21func (sd *sysDialer) dialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) { 22 if h := sd.testHookDialTCP; h != nil { 23 return h(ctx, sd.network, laddr, raddr) 24 } 25 if h := testHookDialTCP; h != nil { 26 return h(ctx, sd.network, laddr, raddr) 27 } 28 return sd.doDialTCP(ctx, laddr, raddr) 29} 30 31func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) { 32 switch sd.network { 33 case "tcp4": 34 // Plan 9 doesn't complain about [::]:0->127.0.0.1, so it's up to us. 35 if laddr != nil && len(laddr.IP) != 0 && laddr.IP.To4() == nil { 36 return nil, &AddrError{Err: "non-IPv4 local address", Addr: laddr.String()} 37 } 38 case "tcp", "tcp6": 39 default: 40 return nil, UnknownNetworkError(sd.network) 41 } 42 if raddr == nil { 43 return nil, errMissingAddress 44 } 45 fd, err := dialPlan9(ctx, sd.network, laddr, raddr) 46 if err != nil { 47 return nil, err 48 } 49 return newTCPConn(fd, sd.Dialer.KeepAlive, sd.Dialer.KeepAliveConfig, testPreHookSetKeepAlive, testHookSetKeepAlive), nil 50} 51 52func (ln *TCPListener) ok() bool { return ln != nil && ln.fd != nil && ln.fd.ctl != nil } 53 54func (ln *TCPListener) accept() (*TCPConn, error) { 55 fd, err := ln.fd.acceptPlan9() 56 if err != nil { 57 return nil, err 58 } 59 return newTCPConn(fd, ln.lc.KeepAlive, ln.lc.KeepAliveConfig, testPreHookSetKeepAlive, testHookSetKeepAlive), nil 60} 61 62func (ln *TCPListener) close() error { 63 if err := ln.fd.pfd.Close(); err != nil { 64 return err 65 } 66 if _, err := ln.fd.ctl.WriteString("hangup"); err != nil { 67 ln.fd.ctl.Close() 68 return err 69 } 70 if err := ln.fd.ctl.Close(); err != nil { 71 return err 72 } 73 return nil 74} 75 76func (ln *TCPListener) file() (*os.File, error) { 77 f, err := ln.dup() 78 if err != nil { 79 return nil, err 80 } 81 return f, nil 82} 83 84func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) { 85 fd, err := listenPlan9(ctx, sl.network, laddr) 86 if err != nil { 87 return nil, err 88 } 89 return &TCPListener{fd: fd, lc: sl.ListenConfig}, nil 90} 91