// ConenctEx wraps syscall.ConnectEx. func (sw *Switch) ConnectEx(s syscall.Handle, sa syscall.Sockaddr, b *byte, n uint32, nwr *uint32, o *syscall.Overlapped) (err error) { so := sw.sockso(s) if so == nil { return syscall.ConnectEx(s, sa, b, n, nwr, o) } sw.fmu.RLock() f, _ := sw.fltab[FilterConnect] sw.fmu.RUnlock() af, err := f.apply(so) if err != nil { return err } so.Err = syscall.ConnectEx(s, sa, b, n, nwr, o) if err = af.apply(so); err != nil { return err } sw.smu.Lock() defer sw.smu.Unlock() if so.Err != nil { sw.stats.getLocked(so.Cookie).ConnectFailed++ return so.Err } sw.stats.getLocked(so.Cookie).Connected++ return nil }
func (fd *netFD) connect(la, ra syscall.Sockaddr) error { // Do not need to call fd.writeLock here, // because fd is not yet accessible to user, // so no concurrent operations are possible. if !canUseConnectEx(fd.net) { return syscall.Connect(fd.sysfd, ra) } // ConnectEx windows API requires an unconnected, previously bound socket. if la == nil { switch ra.(type) { case *syscall.SockaddrInet4: la = &syscall.SockaddrInet4{} case *syscall.SockaddrInet6: la = &syscall.SockaddrInet6{} default: panic("unexpected type in connect") } if err := syscall.Bind(fd.sysfd, la); err != nil { return err } } // Call ConnectEx API. o := &fd.wop o.sa = ra _, err := wsrv.ExecIO(o, "ConnectEx", func(o *operation) error { return syscall.ConnectEx(o.fd.sysfd, o.sa, nil, 0, nil, &o.o) }) if err != nil { return err } // Refresh socket properties. return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))) }
func (o *connectOp) Submit() error { return syscall.ConnectEx(o.fd.sysfd, o.ra, nil, 0, nil, &o.o) }