Socket implements socket.Provider.Socket.
(t *kernel.Task, stypeflags linux.SockType, protocol int)
| 238 | |
| 239 | // Socket implements socket.Provider.Socket. |
| 240 | func (p *socketProvider) Socket(t *kernel.Task, stypeflags linux.SockType, protocol int) (*vfs.FileDescription, *syserr.Error) { |
| 241 | // Check that we are using the host network stack. |
| 242 | netCtx := t.NetworkContext() |
| 243 | if netCtx == nil { |
| 244 | return nil, nil |
| 245 | } |
| 246 | stack, ok := netCtx.(*Stack) |
| 247 | if !ok { |
| 248 | return nil, nil |
| 249 | } |
| 250 | |
| 251 | stype := stypeflags & linux.SOCK_TYPE_MASK |
| 252 | |
| 253 | // Raw and packet sockets require CAP_NET_RAW. |
| 254 | if stype == linux.SOCK_RAW || p.family == linux.AF_PACKET { |
| 255 | if !t.HasCapabilityIn(linux.CAP_NET_RAW, t.NetworkNamespace().UserNamespace()) { |
| 256 | return nil, syserr.ErrNotPermitted |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | // Convert generic IPPROTO_IP protocol to the actual protocol depending |
| 261 | // on family and type. |
| 262 | if protocol == linux.IPPROTO_IP && (p.family == linux.AF_INET || p.family == linux.AF_INET6) { |
| 263 | switch stype { |
| 264 | case linux.SOCK_STREAM: |
| 265 | protocol = linux.IPPROTO_TCP |
| 266 | case linux.SOCK_DGRAM: |
| 267 | protocol = linux.IPPROTO_UDP |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | // Validate the socket based on family, type, and protocol. |
| 272 | var supported bool |
| 273 | for _, allowed := range stack.allowedSocketTypes { |
| 274 | isAllowedFamily := p.family == allowed.Family |
| 275 | isAllowedType := int(stype) == allowed.Type |
| 276 | isAllowedProtocol := protocol == allowed.Protocol || allowed.Protocol == AllowAllProtocols |
| 277 | if isAllowedFamily && isAllowedType && isAllowedProtocol { |
| 278 | supported = true |
| 279 | break |
| 280 | } |
| 281 | } |
| 282 | if !supported { |
| 283 | // Return nil error here to give other socket providers a |
| 284 | // chance to create this socket. |
| 285 | return nil, nil |
| 286 | } |
| 287 | |
| 288 | // Conservatively ignore all flags specified by the application and add |
| 289 | // SOCK_NONBLOCK since socketOperations requires it. |
| 290 | st := int(stype) | unix.SOCK_NONBLOCK | unix.SOCK_CLOEXEC |
| 291 | fd, err := unix.Socket(p.family, st, protocol) |
| 292 | if err != nil { |
| 293 | return nil, syserr.FromError(err) |
| 294 | } |
| 295 | return newSocket(t, p.family, stype, protocol, fd, uint32(stypeflags&unix.SOCK_NONBLOCK)) |
| 296 | } |
| 297 |
nothing calls this directly
no test coverage detected