func (c *Conn) Close() error {
	c.ep.Close()
	return nil
}
Close implements net.Conn.Close.
package gonet
import (
	"context"
	"errors"
	"io"
	"net"
	"sync"
	"time"
	"github.com/google/netstack/tcpip"
	"github.com/google/netstack/tcpip/buffer"
	"github.com/google/netstack/tcpip/stack"
	"github.com/google/netstack/tcpip/transport/tcp"
	"github.com/google/netstack/tcpip/transport/udp"
	"github.com/google/netstack/waiter"
)
var (
	errCanceled   = errors.New("operation canceled")
	errWouldBlock = errors.New("operation would block")
)
type timeoutError struct{}
func (e *timeoutError) Error() string   { return "i/o timeout" }
func (e *timeoutError) Timeout() bool   { return true }
func (e *timeoutError) Temporary() bool { return true }
type Listener struct {
	stack  *stack.Stack
	ep     tcpip.Endpoint
	wq     *waiter.Queue
	cancel chan struct{}
}
func NewListener(s *stack.Stack, addr tcpip.FullAddress, network tcpip.NetworkProtocolNumber) (*Listener, error) {
	var wq waiter.Queue
	ep, err := s.NewEndpoint(tcp.ProtocolNumber, network, &wq)
	if err != nil {
		return nil, errors.New(err.String())
	}
	if err := ep.Bind(addr); err != nil {
		ep.Close()
		return nil, &net.OpError{
			Op:   "bind",
			Net:  "tcp",
			Addr: fullToTCPAddr(addr),
			Err:  errors.New(err.String()),
		}
	}
	if err := ep.Listen(10); err != nil {
		ep.Close()
		return nil, &net.OpError{
			Op:   "listen",
			Net:  "tcp",
			Addr: fullToTCPAddr(addr),
			Err:  errors.New(err.String()),
		}
	}
	return &Listener{
		stack:  s,
		ep:     ep,
		wq:     &wq,
		cancel: make(chan struct{}),
	}, nil
}
func (l *Listener) Close() error {
	l.ep.Close()
	return nil
}
func (l *Listener) Shutdown() {
	l.ep.Shutdown(tcpip.ShutdownWrite | tcpip.ShutdownRead)
	close(l.cancel)  
}
func (l *Listener) Addr() net.Addr {
	a, err := l.ep.GetLocalAddress()
	if err != nil {
		return nil
	}
	return fullToTCPAddr(a)
}
type deadlineTimer struct {
	mu sync.Mutex
	readTimer     *time.Timer
	readCancelCh  chan struct{}
	writeTimer    *time.Timer
	writeCancelCh chan struct{}
}
func (d *deadlineTimer) init() {
	d.readCancelCh = make(chan struct{})
	d.writeCancelCh = make(chan struct{})
}
func (d *deadlineTimer) readCancel() <-chan struct{} {
	d.mu.Lock()
	c := d.readCancelCh
	d.mu.Unlock()
	return c
}
func (d *deadlineTimer) writeCancel() <-chan struct{} {
	d.mu.Lock()
	c := d.writeCancelCh
	d.mu.Unlock()
	return c
}
func (d *deadlineTimer) setDeadline(cancelCh *chan struct{}, timer **time.Timer, t time.Time) {
	if *timer != nil && !(*timer).Stop() {
		*cancelCh = make(chan struct{})
	}
	select {
	case <-*cancelCh:
		*cancelCh = make(chan struct{})
	default:
	}
	if t.IsZero() {
		return
	}
	timeout := t.Sub(time.Now())
	if timeout <= 0 {
		close(*cancelCh)
		return
	}
	ch := *cancelCh
	*timer = time.AfterFunc(timeout, func() {
		close(ch)
	})
}
func (d *deadlineTimer) SetReadDeadline(t time.Time) error {
	d.mu.Lock()
	d.setDeadline(&d.readCancelCh, &d.readTimer, t)
	d.mu.Unlock()
	return nil
}
func (d *deadlineTimer) SetWriteDeadline(t time.Time) error {
	d.mu.Lock()
	d.setDeadline(&d.writeCancelCh, &d.writeTimer, t)
	d.mu.Unlock()
	return nil
}
func (d *deadlineTimer) SetDeadline(t time.Time) error {
	d.mu.Lock()
	d.setDeadline(&d.readCancelCh, &d.readTimer, t)
	d.setDeadline(&d.writeCancelCh, &d.writeTimer, t)
	d.mu.Unlock()
	return nil
}
type Conn struct {
	deadlineTimer
	wq *waiter.Queue
	ep tcpip.Endpoint
	readMu sync.Mutex
	read buffer.View
}
func NewConn(wq *waiter.Queue, ep tcpip.Endpoint) *Conn {
	c := &Conn{
		wq: wq,
		ep: ep,
	}
	c.deadlineTimer.init()
	return c
}
func (l *Listener) Accept() (net.Conn, error) {
	n, wq, err := l.ep.Accept()
	if err == tcpip.ErrWouldBlock {
		waitEntry, notifyCh := waiter.NewChannelEntry(nil)
		l.wq.EventRegister(&waitEntry, waiter.EventIn)
		defer l.wq.EventUnregister(&waitEntry)
		for {
			n, wq, err = l.ep.Accept()
			if err != tcpip.ErrWouldBlock {
				break
			}
			select {
			case <-l.cancel:
				return nil, errCanceled
			case <-notifyCh:
			}
		}
	}
	if err != nil {
		return nil, &net.OpError{
			Op:   "accept",
			Net:  "tcp",
			Addr: l.Addr(),
			Err:  errors.New(err.String()),
		}
	}
	return NewConn(wq, n), nil
}
type opErrorer interface {
	newOpError(op string, err error) *net.OpError
}
func commonRead(ep tcpip.Endpoint, wq *waiter.Queue, deadline <-chan struct{}, addr *tcpip.FullAddress, errorer opErrorer, dontWait bool) ([]byte, error) {
	select {
	case <-deadline:
		return nil, errorer.newOpError("read", &timeoutError{})
	default:
	}
	read, _, err := ep.Read(addr)
	if err == tcpip.ErrWouldBlock {
		if dontWait {
			return nil, errWouldBlock
		}
		waitEntry, notifyCh := waiter.NewChannelEntry(nil)
		wq.EventRegister(&waitEntry, waiter.EventIn)
		defer wq.EventUnregister(&waitEntry)
		for {
			read, _, err = ep.Read(addr)
			if err != tcpip.ErrWouldBlock {
				break
			}
			select {
			case <-deadline:
				return nil, errorer.newOpError("read", &timeoutError{})
			case <-notifyCh:
			}
		}
	}
	if err == tcpip.ErrClosedForReceive {
		return nil, io.EOF
	}
	if err != nil {
		return nil, errorer.newOpError("read", errors.New(err.String()))
	}
	return read, nil
}
func (c *Conn) Read(b []byte) (int, error) {
	c.readMu.Lock()
	defer c.readMu.Unlock()
	deadline := c.readCancel()
	numRead := 0
	for numRead != len(b) {
		if len(c.read) == 0 {
			var err error
			c.read, err = commonRead(c.ep, c.wq, deadline, nil, c, numRead != 0)
			if err != nil {
				if numRead != 0 {
					return numRead, nil
				}
				return numRead, err
			}
		}
		n := copy(b[numRead:], c.read)
		c.read.TrimFront(n)
		numRead += n
		if len(c.read) == 0 {
			c.read = nil
		}
	}
	return numRead, nil
}
func (c *Conn) Write(b []byte) (int, error) {
	deadline := c.writeCancel()
	select {
	case <-deadline:
		return 0, c.newOpError("write", &timeoutError{})
	default:
	}
	v := buffer.NewViewFromBytes(b)
	var (
		err      *tcpip.Error
		nbytes   int
		reg      bool
		notifyCh chan struct{}
	)
	for nbytes < len(b) && (err == tcpip.ErrWouldBlock || err == nil) {
		if err == tcpip.ErrWouldBlock {
			if !reg {
				reg = true
				var waitEntry waiter.Entry
				waitEntry, notifyCh = waiter.NewChannelEntry(nil)
				c.wq.EventRegister(&waitEntry, waiter.EventOut)
				defer c.wq.EventUnregister(&waitEntry)
			} else {
				select {
				case <-deadline:
					return nbytes, c.newOpError("write", &timeoutError{})
				case <-notifyCh:
				}
			}
		}
		var n int64
		var resCh <-chan struct{}
		n, resCh, err = c.ep.Write(tcpip.SlicePayload(v), tcpip.WriteOptions{})
		nbytes += int(n)
		v.TrimFront(int(n))
		if resCh != nil {
			select {
			case <-deadline:
				return nbytes, c.newOpError("write", &timeoutError{})
			case <-resCh:
			}
			n, _, err = c.ep.Write(tcpip.SlicePayload(v), tcpip.WriteOptions{})
			nbytes += int(n)
			v.TrimFront(int(n))
		}
	}
	if err == nil {
		return nbytes, nil
	}
	return nbytes, c.newOpError("write", errors.New(err.String()))
}