github.com/metacubex/tfo-go@v0.0.0-20240228025757-be1269474a66/netpoll_windows.go (about)

     1  package tfo
     2  
     3  import (
     4  	"net"
     5  	"sync"
     6  	"syscall"
     7  	"time"
     8  	_ "unsafe"
     9  )
    10  
    11  //go:linkname sockaddrToTCP net.sockaddrToTCP
    12  func sockaddrToTCP(sa syscall.Sockaddr) net.Addr
    13  
    14  //go:linkname execIO internal/poll.execIO
    15  func execIO(o *operation, submit func(o *operation) error) (int, error)
    16  
    17  // pFD is a file descriptor. The net and os packages embed this type in
    18  // a larger type representing a network connection or OS file.
    19  //
    20  // Stay in sync with FD in src/internal/poll/fd_windows.go
    21  type pFD struct {
    22  	fdmuS uint64
    23  	fdmuR uint32
    24  	fdmuW uint32
    25  
    26  	// System file descriptor. Immutable until Close.
    27  	Sysfd syscall.Handle
    28  
    29  	// Read operation.
    30  	rop operation
    31  	// Write operation.
    32  	wop operation
    33  
    34  	// I/O poller.
    35  	pd uintptr
    36  
    37  	// Used to implement pread/pwrite.
    38  	l sync.Mutex
    39  
    40  	// For console I/O.
    41  	lastbits       []byte   // first few bytes of the last incomplete rune in last write
    42  	readuint16     []uint16 // buffer to hold uint16s obtained with ReadConsole
    43  	readbyte       []byte   // buffer to hold decoding of readuint16 from utf16 to utf8
    44  	readbyteOffset int      // readbyte[readOffset:] is yet to be consumed with file.Read
    45  
    46  	// Semaphore signaled when file is closed.
    47  	csema uint32
    48  
    49  	skipSyncNotif bool
    50  
    51  	// Whether this is a streaming descriptor, as opposed to a
    52  	// packet-based descriptor like a UDP socket.
    53  	IsStream bool
    54  
    55  	// Whether a zero byte read indicates EOF. This is false for a
    56  	// message based socket connection.
    57  	ZeroReadIsEOF bool
    58  
    59  	// Whether this is a file rather than a network socket.
    60  	isFile bool
    61  
    62  	// The kind of this file.
    63  	kind byte
    64  }
    65  
    66  func (fd *pFD) ConnectEx(ra syscall.Sockaddr, b []byte) (n int, err error) {
    67  	fd.wop.sa = ra
    68  	n, err = execIO(&fd.wop, func(o *operation) error {
    69  		return syscall.ConnectEx(o.fd.Sysfd, o.sa, &b[0], uint32(len(b)), &o.qty, &o.o)
    70  	})
    71  	return
    72  }
    73  
    74  // Network file descriptor.
    75  //
    76  // Copied from src/net/fd_posix.go
    77  type netFD struct {
    78  	pfd pFD
    79  
    80  	// immutable until Close
    81  	family      int
    82  	sotype      int
    83  	isConnected bool // handshake completed or use of association with peer
    84  	net         string
    85  	laddr       net.Addr
    86  	raddr       net.Addr
    87  }
    88  
    89  //go:linkname newFD net.newFD
    90  func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error)
    91  
    92  //go:linkname netFDInit net.(*netFD).init
    93  func netFDInit(fd *netFD) error
    94  
    95  //go:linkname netFDClose net.(*netFD).Close
    96  func netFDClose(fd *netFD) error
    97  
    98  //go:linkname netFDCtrlNetwork net.(*netFD).ctrlNetwork
    99  func netFDCtrlNetwork(fd *netFD) string
   100  
   101  //go:linkname netFDWrite net.(*netFD).Write
   102  func netFDWrite(fd *netFD, p []byte) (int, error)
   103  
   104  //go:linkname netFDSetWriteDeadline net.(*netFD).SetWriteDeadline
   105  func netFDSetWriteDeadline(fd *netFD, t time.Time) error
   106  
   107  func (fd *netFD) init() error {
   108  	return netFDInit(fd)
   109  }
   110  
   111  func (fd *netFD) Close() error {
   112  	return netFDClose(fd)
   113  }
   114  
   115  func (fd *netFD) ctrlNetwork() string {
   116  	return netFDCtrlNetwork(fd)
   117  }
   118  
   119  func (fd *netFD) Write(p []byte) (int, error) {
   120  	return netFDWrite(fd, p)
   121  }
   122  
   123  func (fd *netFD) SetWriteDeadline(t time.Time) error {
   124  	return netFDSetWriteDeadline(fd, t)
   125  }
   126  
   127  // Copied from src/net/rawconn.go
   128  type rawConn struct {
   129  	fd *netFD
   130  }
   131  
   132  func newRawConn(fd *netFD) *rawConn {
   133  	return &rawConn{fd: fd}
   134  }
   135  
   136  //go:linkname rawConnControl net.(*rawConn).Control
   137  func rawConnControl(c *rawConn, f func(uintptr)) error
   138  
   139  //go:linkname rawConnRead net.(*rawConn).Read
   140  func rawConnRead(c *rawConn, f func(uintptr) bool) error
   141  
   142  //go:linkname rawConnWrite net.(*rawConn).Write
   143  func rawConnWrite(c *rawConn, f func(uintptr) bool) error
   144  
   145  func (c *rawConn) Control(f func(uintptr)) error {
   146  	return rawConnControl(c, f)
   147  }
   148  
   149  func (c *rawConn) Read(f func(uintptr) bool) error {
   150  	return rawConnRead(c, f)
   151  }
   152  
   153  func (c *rawConn) Write(f func(uintptr) bool) error {
   154  	return rawConnWrite(c, f)
   155  }