github.com/fjballest/golang@v0.0.0-20151209143359-e4c5fe594ca8/src/net/fd_windows.go (about)

     1  // Copyright 2010 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  
     5  package net
     6  
     7  import (
     8  	"internal/race"
     9  	"os"
    10  	"runtime"
    11  	"sync"
    12  	"syscall"
    13  	"time"
    14  	"unsafe"
    15  )
    16  
    17  var (
    18  	initErr error
    19  	ioSync  uint64
    20  )
    21  
    22  // CancelIo Windows API cancels all outstanding IO for a particular
    23  // socket on current thread. To overcome that limitation, we run
    24  // special goroutine, locked to OS single thread, that both starts
    25  // and cancels IO. It means, there are 2 unavoidable thread switches
    26  // for every IO.
    27  // Some newer versions of Windows has new CancelIoEx API, that does
    28  // not have that limitation and can be used from any thread. This
    29  // package uses CancelIoEx API, if present, otherwise it fallback
    30  // to CancelIo.
    31  
    32  var (
    33  	canCancelIO                               bool // determines if CancelIoEx API is present
    34  	skipSyncNotif                             bool
    35  	hasLoadSetFileCompletionNotificationModes bool
    36  )
    37  
    38  func sysInit() {
    39  	var d syscall.WSAData
    40  	e := syscall.WSAStartup(uint32(0x202), &d)
    41  	if e != nil {
    42  		initErr = os.NewSyscallError("wsastartup", e)
    43  	}
    44  	canCancelIO = syscall.LoadCancelIoEx() == nil
    45  	if syscall.LoadGetAddrInfo() == nil {
    46  		lookupPort = newLookupPort
    47  		lookupIP = newLookupIP
    48  	}
    49  
    50  	hasLoadSetFileCompletionNotificationModes = syscall.LoadSetFileCompletionNotificationModes() == nil
    51  	if hasLoadSetFileCompletionNotificationModes {
    52  		// It's not safe to use FILE_SKIP_COMPLETION_PORT_ON_SUCCESS if non IFS providers are installed:
    53  		// http://support.microsoft.com/kb/2568167
    54  		skipSyncNotif = true
    55  		protos := [2]int32{syscall.IPPROTO_TCP, 0}
    56  		var buf [32]syscall.WSAProtocolInfo
    57  		len := uint32(unsafe.Sizeof(buf))
    58  		n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len)
    59  		if err != nil {
    60  			skipSyncNotif = false
    61  		} else {
    62  			for i := int32(0); i < n; i++ {
    63  				if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
    64  					skipSyncNotif = false
    65  					break
    66  				}
    67  			}
    68  		}
    69  	}
    70  }
    71  
    72  func canUseConnectEx(net string) bool {
    73  	switch net {
    74  	case "udp", "udp4", "udp6", "ip", "ip4", "ip6":
    75  		// ConnectEx windows API does not support connectionless sockets.
    76  		return false
    77  	}
    78  	return syscall.LoadConnectEx() == nil
    79  }
    80  
    81  func dial(net string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
    82  	if !canUseConnectEx(net) {
    83  		// Use the relatively inefficient goroutine-racing
    84  		// implementation of DialTimeout.
    85  		return dialChannel(net, ra, dialer, deadline)
    86  	}
    87  	return dialer(deadline)
    88  }
    89  
    90  // operation contains superset of data necessary to perform all async IO.
    91  type operation struct {
    92  	// Used by IOCP interface, it must be first field
    93  	// of the struct, as our code rely on it.
    94  	o syscall.Overlapped
    95  
    96  	// fields used by runtime.netpoll
    97  	runtimeCtx uintptr
    98  	mode       int32
    99  	errno      int32
   100  	qty        uint32
   101  
   102  	// fields used only by net package
   103  	fd     *netFD
   104  	errc   chan error
   105  	buf    syscall.WSABuf
   106  	sa     syscall.Sockaddr
   107  	rsa    *syscall.RawSockaddrAny
   108  	rsan   int32
   109  	handle syscall.Handle
   110  	flags  uint32
   111  }
   112  
   113  func (o *operation) InitBuf(buf []byte) {
   114  	o.buf.Len = uint32(len(buf))
   115  	o.buf.Buf = nil
   116  	if len(buf) != 0 {
   117  		o.buf.Buf = &buf[0]
   118  	}
   119  }
   120  
   121  // ioSrv executes net IO requests.
   122  type ioSrv struct {
   123  	req chan ioSrvReq
   124  }
   125  
   126  type ioSrvReq struct {
   127  	o      *operation
   128  	submit func(o *operation) error // if nil, cancel the operation
   129  }
   130  
   131  // ProcessRemoteIO will execute submit IO requests on behalf
   132  // of other goroutines, all on a single os thread, so it can
   133  // cancel them later. Results of all operations will be sent
   134  // back to their requesters via channel supplied in request.
   135  // It is used only when the CancelIoEx API is unavailable.
   136  func (s *ioSrv) ProcessRemoteIO() {
   137  	runtime.LockOSThread()
   138  	defer runtime.UnlockOSThread()
   139  	for r := range s.req {
   140  		if r.submit != nil {
   141  			r.o.errc <- r.submit(r.o)
   142  		} else {
   143  			r.o.errc <- syscall.CancelIo(r.o.fd.sysfd)
   144  		}
   145  	}
   146  }
   147  
   148  // ExecIO executes a single IO operation o. It submits and cancels
   149  // IO in the current thread for systems where Windows CancelIoEx API
   150  // is available. Alternatively, it passes the request onto
   151  // runtime netpoll and waits for completion or cancels request.
   152  func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) error) (int, error) {
   153  	fd := o.fd
   154  	// Notify runtime netpoll about starting IO.
   155  	err := fd.pd.Prepare(int(o.mode))
   156  	if err != nil {
   157  		return 0, err
   158  	}
   159  	// Start IO.
   160  	if canCancelIO {
   161  		err = submit(o)
   162  	} else {
   163  		// Send request to a special dedicated thread,
   164  		// so it can stop the IO with CancelIO later.
   165  		s.req <- ioSrvReq{o, submit}
   166  		err = <-o.errc
   167  	}
   168  	switch err {
   169  	case nil:
   170  		// IO completed immediately
   171  		if o.fd.skipSyncNotif {
   172  			// No completion message will follow, so return immediately.
   173  			return int(o.qty), nil
   174  		}
   175  		// Need to get our completion message anyway.
   176  	case syscall.ERROR_IO_PENDING:
   177  		// IO started, and we have to wait for its completion.
   178  		err = nil
   179  	default:
   180  		return 0, err
   181  	}
   182  	// Wait for our request to complete.
   183  	err = fd.pd.Wait(int(o.mode))
   184  	if err == nil {
   185  		// All is good. Extract our IO results and return.
   186  		if o.errno != 0 {
   187  			err = syscall.Errno(o.errno)
   188  			return 0, err
   189  		}
   190  		return int(o.qty), nil
   191  	}
   192  	// IO is interrupted by "close" or "timeout"
   193  	netpollErr := err
   194  	switch netpollErr {
   195  	case errClosing, errTimeout:
   196  		// will deal with those.
   197  	default:
   198  		panic("net: unexpected runtime.netpoll error: " + netpollErr.Error())
   199  	}
   200  	// Cancel our request.
   201  	if canCancelIO {
   202  		err := syscall.CancelIoEx(fd.sysfd, &o.o)
   203  		// Assuming ERROR_NOT_FOUND is returned, if IO is completed.
   204  		if err != nil && err != syscall.ERROR_NOT_FOUND {
   205  			// TODO(brainman): maybe do something else, but panic.
   206  			panic(err)
   207  		}
   208  	} else {
   209  		s.req <- ioSrvReq{o, nil}
   210  		<-o.errc
   211  	}
   212  	// Wait for cancelation to complete.
   213  	fd.pd.WaitCanceled(int(o.mode))
   214  	if o.errno != 0 {
   215  		err = syscall.Errno(o.errno)
   216  		if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
   217  			err = netpollErr
   218  		}
   219  		return 0, err
   220  	}
   221  	// We issued a cancelation request. But, it seems, IO operation succeeded
   222  	// before the cancelation request run. We need to treat the IO operation as
   223  	// succeeded (the bytes are actually sent/recv from network).
   224  	return int(o.qty), nil
   225  }
   226  
   227  // Start helper goroutines.
   228  var rsrv, wsrv *ioSrv
   229  var onceStartServer sync.Once
   230  
   231  func startServer() {
   232  	rsrv = new(ioSrv)
   233  	wsrv = new(ioSrv)
   234  	if !canCancelIO {
   235  		// Only CancelIo API is available. Lets start two special goroutines
   236  		// locked to an OS thread, that both starts and cancels IO. One will
   237  		// process read requests, while other will do writes.
   238  		rsrv.req = make(chan ioSrvReq)
   239  		go rsrv.ProcessRemoteIO()
   240  		wsrv.req = make(chan ioSrvReq)
   241  		go wsrv.ProcessRemoteIO()
   242  	}
   243  }
   244  
   245  // Network file descriptor.
   246  type netFD struct {
   247  	// locking/lifetime of sysfd + serialize access to Read and Write methods
   248  	fdmu fdMutex
   249  
   250  	// immutable until Close
   251  	sysfd         syscall.Handle
   252  	family        int
   253  	sotype        int
   254  	isConnected   bool
   255  	skipSyncNotif bool
   256  	net           string
   257  	laddr         Addr
   258  	raddr         Addr
   259  
   260  	rop operation // read operation
   261  	wop operation // write operation
   262  
   263  	// wait server
   264  	pd pollDesc
   265  }
   266  
   267  func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) {
   268  	if initErr != nil {
   269  		return nil, initErr
   270  	}
   271  	onceStartServer.Do(startServer)
   272  	return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
   273  }
   274  
   275  func (fd *netFD) init() error {
   276  	if err := fd.pd.Init(fd); err != nil {
   277  		return err
   278  	}
   279  	if hasLoadSetFileCompletionNotificationModes {
   280  		// We do not use events, so we can skip them always.
   281  		flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE)
   282  		// It's not safe to skip completion notifications for UDP:
   283  		// http://blogs.technet.com/b/winserverperformance/archive/2008/06/26/designing-applications-for-high-performance-part-iii.aspx
   284  		if skipSyncNotif && fd.net == "tcp" {
   285  			flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
   286  		}
   287  		err := syscall.SetFileCompletionNotificationModes(fd.sysfd, flags)
   288  		if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 {
   289  			fd.skipSyncNotif = true
   290  		}
   291  	}
   292  	// Disable SIO_UDP_CONNRESET behavior.
   293  	// http://support.microsoft.com/kb/263823
   294  	switch fd.net {
   295  	case "udp", "udp4", "udp6":
   296  		ret := uint32(0)
   297  		flag := uint32(0)
   298  		size := uint32(unsafe.Sizeof(flag))
   299  		err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0)
   300  		if err != nil {
   301  			return os.NewSyscallError("wsaioctl", err)
   302  		}
   303  	}
   304  	fd.rop.mode = 'r'
   305  	fd.wop.mode = 'w'
   306  	fd.rop.fd = fd
   307  	fd.wop.fd = fd
   308  	fd.rop.runtimeCtx = fd.pd.runtimeCtx
   309  	fd.wop.runtimeCtx = fd.pd.runtimeCtx
   310  	if !canCancelIO {
   311  		fd.rop.errc = make(chan error)
   312  		fd.wop.errc = make(chan error)
   313  	}
   314  	return nil
   315  }
   316  
   317  func (fd *netFD) setAddr(laddr, raddr Addr) {
   318  	fd.laddr = laddr
   319  	fd.raddr = raddr
   320  	runtime.SetFinalizer(fd, (*netFD).Close)
   321  }
   322  
   323  func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
   324  	// Do not need to call fd.writeLock here,
   325  	// because fd is not yet accessible to user,
   326  	// so no concurrent operations are possible.
   327  	if err := fd.init(); err != nil {
   328  		return err
   329  	}
   330  	if !deadline.IsZero() {
   331  		fd.setWriteDeadline(deadline)
   332  		defer fd.setWriteDeadline(noDeadline)
   333  	}
   334  	if !canUseConnectEx(fd.net) {
   335  		return os.NewSyscallError("connect", connectFunc(fd.sysfd, ra))
   336  	}
   337  	// ConnectEx windows API requires an unconnected, previously bound socket.
   338  	if la == nil {
   339  		switch ra.(type) {
   340  		case *syscall.SockaddrInet4:
   341  			la = &syscall.SockaddrInet4{}
   342  		case *syscall.SockaddrInet6:
   343  			la = &syscall.SockaddrInet6{}
   344  		default:
   345  			panic("unexpected type in connect")
   346  		}
   347  		if err := syscall.Bind(fd.sysfd, la); err != nil {
   348  			return os.NewSyscallError("bind", err)
   349  		}
   350  	}
   351  	// Call ConnectEx API.
   352  	o := &fd.wop
   353  	o.sa = ra
   354  	_, err := wsrv.ExecIO(o, "ConnectEx", func(o *operation) error {
   355  		return connectExFunc(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
   356  	})
   357  	if err != nil {
   358  		if _, ok := err.(syscall.Errno); ok {
   359  			err = os.NewSyscallError("connectex", err)
   360  		}
   361  		return err
   362  	}
   363  	// Refresh socket properties.
   364  	return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))))
   365  }
   366  
   367  func (fd *netFD) destroy() {
   368  	if fd.sysfd == syscall.InvalidHandle {
   369  		return
   370  	}
   371  	// Poller may want to unregister fd in readiness notification mechanism,
   372  	// so this must be executed before closeFunc.
   373  	fd.pd.Close()
   374  	closeFunc(fd.sysfd)
   375  	fd.sysfd = syscall.InvalidHandle
   376  	// no need for a finalizer anymore
   377  	runtime.SetFinalizer(fd, nil)
   378  }
   379  
   380  // Add a reference to this fd.
   381  // Returns an error if the fd cannot be used.
   382  func (fd *netFD) incref() error {
   383  	if !fd.fdmu.Incref() {
   384  		return errClosing
   385  	}
   386  	return nil
   387  }
   388  
   389  // Remove a reference to this FD and close if we've been asked to do so
   390  // (and there are no references left).
   391  func (fd *netFD) decref() {
   392  	if fd.fdmu.Decref() {
   393  		fd.destroy()
   394  	}
   395  }
   396  
   397  // Add a reference to this fd and lock for reading.
   398  // Returns an error if the fd cannot be used.
   399  func (fd *netFD) readLock() error {
   400  	if !fd.fdmu.RWLock(true) {
   401  		return errClosing
   402  	}
   403  	return nil
   404  }
   405  
   406  // Unlock for reading and remove a reference to this FD.
   407  func (fd *netFD) readUnlock() {
   408  	if fd.fdmu.RWUnlock(true) {
   409  		fd.destroy()
   410  	}
   411  }
   412  
   413  // Add a reference to this fd and lock for writing.
   414  // Returns an error if the fd cannot be used.
   415  func (fd *netFD) writeLock() error {
   416  	if !fd.fdmu.RWLock(false) {
   417  		return errClosing
   418  	}
   419  	return nil
   420  }
   421  
   422  // Unlock for writing and remove a reference to this FD.
   423  func (fd *netFD) writeUnlock() {
   424  	if fd.fdmu.RWUnlock(false) {
   425  		fd.destroy()
   426  	}
   427  }
   428  
   429  func (fd *netFD) Close() error {
   430  	if !fd.fdmu.IncrefAndClose() {
   431  		return errClosing
   432  	}
   433  	// unblock pending reader and writer
   434  	fd.pd.Evict()
   435  	fd.decref()
   436  	return nil
   437  }
   438  
   439  func (fd *netFD) shutdown(how int) error {
   440  	if err := fd.incref(); err != nil {
   441  		return err
   442  	}
   443  	defer fd.decref()
   444  	return syscall.Shutdown(fd.sysfd, how)
   445  }
   446  
   447  func (fd *netFD) closeRead() error {
   448  	return fd.shutdown(syscall.SHUT_RD)
   449  }
   450  
   451  func (fd *netFD) closeWrite() error {
   452  	return fd.shutdown(syscall.SHUT_WR)
   453  }
   454  
   455  func (fd *netFD) Read(buf []byte) (int, error) {
   456  	if err := fd.readLock(); err != nil {
   457  		return 0, err
   458  	}
   459  	defer fd.readUnlock()
   460  	o := &fd.rop
   461  	o.InitBuf(buf)
   462  	n, err := rsrv.ExecIO(o, "WSARecv", func(o *operation) error {
   463  		return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
   464  	})
   465  	if race.Enabled {
   466  		race.Acquire(unsafe.Pointer(&ioSync))
   467  	}
   468  	err = fd.eofError(n, err)
   469  	if _, ok := err.(syscall.Errno); ok {
   470  		err = os.NewSyscallError("wsarecv", err)
   471  	}
   472  	return n, err
   473  }
   474  
   475  func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) {
   476  	if len(buf) == 0 {
   477  		return 0, nil, nil
   478  	}
   479  	if err := fd.readLock(); err != nil {
   480  		return 0, nil, err
   481  	}
   482  	defer fd.readUnlock()
   483  	o := &fd.rop
   484  	o.InitBuf(buf)
   485  	n, err := rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error {
   486  		if o.rsa == nil {
   487  			o.rsa = new(syscall.RawSockaddrAny)
   488  		}
   489  		o.rsan = int32(unsafe.Sizeof(*o.rsa))
   490  		return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
   491  	})
   492  	err = fd.eofError(n, err)
   493  	if _, ok := err.(syscall.Errno); ok {
   494  		err = os.NewSyscallError("wsarecvfrom", err)
   495  	}
   496  	if err != nil {
   497  		return n, nil, err
   498  	}
   499  	sa, _ := o.rsa.Sockaddr()
   500  	return n, sa, nil
   501  }
   502  
   503  func (fd *netFD) Write(buf []byte) (int, error) {
   504  	if err := fd.writeLock(); err != nil {
   505  		return 0, err
   506  	}
   507  	defer fd.writeUnlock()
   508  	if race.Enabled {
   509  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
   510  	}
   511  	o := &fd.wop
   512  	o.InitBuf(buf)
   513  	n, err := wsrv.ExecIO(o, "WSASend", func(o *operation) error {
   514  		return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
   515  	})
   516  	if _, ok := err.(syscall.Errno); ok {
   517  		err = os.NewSyscallError("wsasend", err)
   518  	}
   519  	return n, err
   520  }
   521  
   522  func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) {
   523  	if len(buf) == 0 {
   524  		return 0, nil
   525  	}
   526  	if err := fd.writeLock(); err != nil {
   527  		return 0, err
   528  	}
   529  	defer fd.writeUnlock()
   530  	o := &fd.wop
   531  	o.InitBuf(buf)
   532  	o.sa = sa
   533  	n, err := wsrv.ExecIO(o, "WSASendto", func(o *operation) error {
   534  		return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
   535  	})
   536  	if _, ok := err.(syscall.Errno); ok {
   537  		err = os.NewSyscallError("wsasendto", err)
   538  	}
   539  	return n, err
   540  }
   541  
   542  func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) {
   543  	// Get new socket.
   544  	s, err := sysSocket(fd.family, fd.sotype, 0)
   545  	if err != nil {
   546  		return nil, err
   547  	}
   548  
   549  	// Associate our new socket with IOCP.
   550  	netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
   551  	if err != nil {
   552  		closeFunc(s)
   553  		return nil, err
   554  	}
   555  	if err := netfd.init(); err != nil {
   556  		fd.Close()
   557  		return nil, err
   558  	}
   559  
   560  	// Submit accept request.
   561  	o.handle = s
   562  	o.rsan = int32(unsafe.Sizeof(rawsa[0]))
   563  	_, err = rsrv.ExecIO(o, "AcceptEx", func(o *operation) error {
   564  		return syscall.AcceptEx(o.fd.sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
   565  	})
   566  	if err != nil {
   567  		netfd.Close()
   568  		if _, ok := err.(syscall.Errno); ok {
   569  			err = os.NewSyscallError("acceptex", err)
   570  		}
   571  		return nil, err
   572  	}
   573  
   574  	// Inherit properties of the listening socket.
   575  	err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
   576  	if err != nil {
   577  		netfd.Close()
   578  		return nil, os.NewSyscallError("setsockopt", err)
   579  	}
   580  
   581  	return netfd, nil
   582  }
   583  
   584  func (fd *netFD) accept() (*netFD, error) {
   585  	if err := fd.readLock(); err != nil {
   586  		return nil, err
   587  	}
   588  	defer fd.readUnlock()
   589  
   590  	o := &fd.rop
   591  	var netfd *netFD
   592  	var err error
   593  	var rawsa [2]syscall.RawSockaddrAny
   594  	for {
   595  		netfd, err = fd.acceptOne(rawsa[:], o)
   596  		if err == nil {
   597  			break
   598  		}
   599  		// Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
   600  		// returned here. These happen if connection reset is received
   601  		// before AcceptEx could complete. These errors relate to new
   602  		// connection, not to AcceptEx, so ignore broken connection and
   603  		// try AcceptEx again for more connections.
   604  		nerr, ok := err.(*os.SyscallError)
   605  		if !ok {
   606  			return nil, err
   607  		}
   608  		errno, ok := nerr.Err.(syscall.Errno)
   609  		if !ok {
   610  			return nil, err
   611  		}
   612  		switch errno {
   613  		case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
   614  			// ignore these and try again
   615  		default:
   616  			return nil, err
   617  		}
   618  	}
   619  
   620  	// Get local and peer addr out of AcceptEx buffer.
   621  	var lrsa, rrsa *syscall.RawSockaddrAny
   622  	var llen, rlen int32
   623  	syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&rawsa[0])),
   624  		0, uint32(o.rsan), uint32(o.rsan), &lrsa, &llen, &rrsa, &rlen)
   625  	lsa, _ := lrsa.Sockaddr()
   626  	rsa, _ := rrsa.Sockaddr()
   627  
   628  	netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
   629  	return netfd, nil
   630  }
   631  
   632  // Unimplemented functions.
   633  
   634  func (fd *netFD) dup() (*os.File, error) {
   635  	// TODO: Implement this
   636  	return nil, syscall.EWINDOWS
   637  }
   638  
   639  func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
   640  	return 0, 0, 0, nil, syscall.EWINDOWS
   641  }
   642  
   643  func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
   644  	return 0, 0, syscall.EWINDOWS
   645  }