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