fd_windows.go 17 KB

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