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