github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/net/internal/socktest/sys_unix.go (about) 1 // Copyright 2015 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 //go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris 6 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris 7 8 package socktest 9 10 import "syscall" 11 12 // Socket wraps syscall.Socket. 13 func (sw *Switch) Socket(family, sotype, proto int) (s int, err error) { 14 sw.once.Do(sw.init) 15 16 so := &Status{Cookie: cookie(family, sotype, proto)} 17 sw.fmu.RLock() 18 f := sw.fltab[FilterSocket] 19 sw.fmu.RUnlock() 20 21 af, err := f.apply(so) 22 if err != nil { 23 return -1, err 24 } 25 s, so.Err = syscall.Socket(family, sotype, proto) 26 if err = af.apply(so); err != nil { 27 if so.Err == nil { 28 syscall.Close(s) 29 } 30 return -1, err 31 } 32 33 sw.smu.Lock() 34 defer sw.smu.Unlock() 35 if so.Err != nil { 36 sw.stats.getLocked(so.Cookie).OpenFailed++ 37 return -1, so.Err 38 } 39 nso := sw.addLocked(s, family, sotype, proto) 40 sw.stats.getLocked(nso.Cookie).Opened++ 41 return s, nil 42 } 43 44 // Close wraps syscall.Close. 45 func (sw *Switch) Close(s int) (err error) { 46 so := sw.sockso(s) 47 if so == nil { 48 return syscall.Close(s) 49 } 50 sw.fmu.RLock() 51 f := sw.fltab[FilterClose] 52 sw.fmu.RUnlock() 53 54 af, err := f.apply(so) 55 if err != nil { 56 return err 57 } 58 so.Err = syscall.Close(s) 59 if err = af.apply(so); err != nil { 60 return err 61 } 62 63 sw.smu.Lock() 64 defer sw.smu.Unlock() 65 if so.Err != nil { 66 sw.stats.getLocked(so.Cookie).CloseFailed++ 67 return so.Err 68 } 69 delete(sw.sotab, s) 70 sw.stats.getLocked(so.Cookie).Closed++ 71 return nil 72 } 73 74 // Connect wraps syscall.Connect. 75 func (sw *Switch) Connect(s int, sa syscall.Sockaddr) (err error) { 76 so := sw.sockso(s) 77 if so == nil { 78 return syscall.Connect(s, sa) 79 } 80 sw.fmu.RLock() 81 f := sw.fltab[FilterConnect] 82 sw.fmu.RUnlock() 83 84 af, err := f.apply(so) 85 if err != nil { 86 return err 87 } 88 so.Err = syscall.Connect(s, sa) 89 if err = af.apply(so); err != nil { 90 return err 91 } 92 93 sw.smu.Lock() 94 defer sw.smu.Unlock() 95 if so.Err != nil { 96 sw.stats.getLocked(so.Cookie).ConnectFailed++ 97 return so.Err 98 } 99 sw.stats.getLocked(so.Cookie).Connected++ 100 return nil 101 } 102 103 // Listen wraps syscall.Listen. 104 func (sw *Switch) Listen(s, backlog int) (err error) { 105 so := sw.sockso(s) 106 if so == nil { 107 return syscall.Listen(s, backlog) 108 } 109 sw.fmu.RLock() 110 f := sw.fltab[FilterListen] 111 sw.fmu.RUnlock() 112 113 af, err := f.apply(so) 114 if err != nil { 115 return err 116 } 117 so.Err = syscall.Listen(s, backlog) 118 if err = af.apply(so); err != nil { 119 return err 120 } 121 122 sw.smu.Lock() 123 defer sw.smu.Unlock() 124 if so.Err != nil { 125 sw.stats.getLocked(so.Cookie).ListenFailed++ 126 return so.Err 127 } 128 sw.stats.getLocked(so.Cookie).Listened++ 129 return nil 130 } 131 132 // Accept wraps syscall.Accept. 133 func (sw *Switch) Accept(s int) (ns int, sa syscall.Sockaddr, err error) { 134 so := sw.sockso(s) 135 if so == nil { 136 return syscall.Accept(s) 137 } 138 sw.fmu.RLock() 139 f := sw.fltab[FilterAccept] 140 sw.fmu.RUnlock() 141 142 af, err := f.apply(so) 143 if err != nil { 144 return -1, nil, err 145 } 146 ns, sa, so.Err = syscall.Accept(s) 147 if err = af.apply(so); err != nil { 148 if so.Err == nil { 149 syscall.Close(ns) 150 } 151 return -1, nil, err 152 } 153 154 sw.smu.Lock() 155 defer sw.smu.Unlock() 156 if so.Err != nil { 157 sw.stats.getLocked(so.Cookie).AcceptFailed++ 158 return -1, nil, so.Err 159 } 160 nso := sw.addLocked(ns, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol()) 161 sw.stats.getLocked(nso.Cookie).Accepted++ 162 return ns, sa, nil 163 } 164 165 // GetsockoptInt wraps syscall.GetsockoptInt. 166 func (sw *Switch) GetsockoptInt(s, level, opt int) (soerr int, err error) { 167 so := sw.sockso(s) 168 if so == nil { 169 return syscall.GetsockoptInt(s, level, opt) 170 } 171 sw.fmu.RLock() 172 f := sw.fltab[FilterGetsockoptInt] 173 sw.fmu.RUnlock() 174 175 af, err := f.apply(so) 176 if err != nil { 177 return -1, err 178 } 179 soerr, so.Err = syscall.GetsockoptInt(s, level, opt) 180 so.SocketErr = syscall.Errno(soerr) 181 if err = af.apply(so); err != nil { 182 return -1, err 183 } 184 185 if so.Err != nil { 186 return -1, so.Err 187 } 188 if opt == syscall.SO_ERROR && (so.SocketErr == syscall.Errno(0) || so.SocketErr == syscall.EISCONN) { 189 sw.smu.Lock() 190 sw.stats.getLocked(so.Cookie).Connected++ 191 sw.smu.Unlock() 192 } 193 return soerr, nil 194 }