diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index a6250c1f9e6..be16ae6ef21 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -1,36 +1,20 @@ /**************************************************************************** * include/nuttx/net/net.h * - * Copyright (C) 2007, 2009-2014, 2016-2019 Gregory Nutt. All rights - * reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ @@ -111,6 +95,7 @@ /* Definitions of 8-bit socket flags */ +#define _SF_INITD 0x01 /* Bit 0: Socket structure is initialized */ #define _SF_CLOEXEC 0x04 /* Bit 2: Close on execute */ #define _SF_NONBLOCK 0x08 /* Bit 3: Don't block if no data (TCP/READ only) */ #define _SF_LISTENING 0x10 /* Bit 4: SOCK_STREAM is listening */ @@ -122,12 +107,14 @@ /* Connection state encoding: * * _SF_CONNECTED==1 && _SF_CLOSED==0 - the socket is connected - * _SF_CONNECTED==0 && _SF_CLOSED==1 - the socket was gracefully disconnected + * _SF_CONNECTED==0 && _SF_CLOSED==1 - the socket was gracefully + * disconnected * _SF_CONNECTED==0 && _SF_CLOSED==0 - the socket was rudely disconnected */ /* Macro to manage the socket state and flags */ +#define _SS_INITD(s) (((s) & _SF_INITD) != 0) #define _SS_ISCLOEXEC(s) (((s) & _SF_CLOEXEC) != 0) #define _SS_ISNONBLOCK(s) (((s) & _SF_NONBLOCK) != 0) #define _SS_ISLISTENING(s) (((s) & _SF_LISTENING) != 0) @@ -135,6 +122,22 @@ #define _SS_ISCONNECTED(s) (((s) & _SF_CONNECTED) != 0) #define _SS_ISCLOSED(s) (((s) & _SF_CLOSED) != 0) +/* Determine if a socket is valid. Valid means both (1) allocated and (2) + * successfully initialized: + * + * Allocated: psock->s_crefs > 0 + * Initialized: _SF_INITD bit set in psock->s_flags + * + * This logic is used within the OS to pick the sockets to be cloned when a + * new task is created. A complexity in SMP mode is that a socket may be + * allocated, but not yet initialized when the socket is cloned by another + * pthread. + */ + +#define _PS_ALLOCD(psock) ((psock)->s_crefs > 0) +#define _PS_INITD(psock) (_SS_INITD((psock)->s_flags)) +#define _PS_VALID(psock) (_PS_ALLOCD(psock) && _PS_INITD(psock)) + /**************************************************************************** * Public Types ****************************************************************************/ @@ -496,9 +499,9 @@ FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid); * Description: * Check if the socket descriptor is valid for the provided TCB and if it * supports the requested access. This trivial operation is part of the - * fdopen() operation when the fdopen() is performed on a socket descriptor. - * It simply performs some sanity checking before permitting the socket - * descriptor to be wrapped as a C FILE stream. + * fdopen() operation when the fdopen() is performed on a socket + * descriptor. It simply performs some sanity checking before permitting + * the socket descriptor to be wrapped as a C FILE stream. * ****************************************************************************/ @@ -731,7 +734,8 @@ int psock_listen(FAR struct socket *psock, int backlog); * Input Parameters: * psock Reference to the listening socket structure * addr Receives the address of the connecting client - * addrlen Input: allocated size of 'addr', Return: returned size of 'addr' + * addrlen Input: allocated size of 'addr', Return: returned size of + * 'addr' * newsock Location to return the accepted socket information. * * Returned Value: @@ -1555,7 +1559,8 @@ int net_vfcntl(int sockfd, int cmd, va_list ap); * * Input Parameters: * dev - The device driver structure to be registered. - * lltype - Link level protocol used by the driver (Ethernet, SLIP, TUN, ... + * lltype - Link level protocol used by the driver (Ethernet, SLIP, TUN, + * ... * * Returned Value: * 0:Success; negated errno on failure diff --git a/net/socket/net_close.c b/net/socket/net_close.c index 2ac498e6747..8d00fceac0b 100644 --- a/net/socket/net_close.c +++ b/net/socket/net_close.c @@ -1,35 +1,20 @@ /**************************************************************************** * net/socket/net_close.c * - * Copyright (C) 2007-2017 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ @@ -80,7 +65,7 @@ int psock_close(FAR struct socket *psock) /* Verify that the sockfd corresponds to valid, allocated socket */ - if (!psock || psock->s_crefs <= 0) + if (psock == NULL || psock->s_crefs <= 0) { return -EBADF; } @@ -95,20 +80,38 @@ int psock_close(FAR struct socket *psock) if (psock->s_crefs <= 1 && psock->s_conn != NULL) { + /* Assume that the socket close operation will be successful. Save + * the current flags and mark the socket uninitialized. This avoids + * race conditions in the SMP case. We save the flags as a type + * unsigned int in case the size of s_flags changes in the future + * (currently uint8_t). + */ + + unsigned int saveflags = psock->s_flags; + + psock->s_flags &= ~_SF_INITD; + /* Let the address family's close() method handle the operation */ - DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_close != NULL); + DEBUGASSERT(psock->s_sockif != NULL && + psock->s_sockif->si_close != NULL); + ret = psock->s_sockif->si_close(psock); /* Was the close successful */ if (ret < 0) { + /* No.. restore the socket flags */ + + psock->s_flags = saveflags; return ret; } } - /* Then release our reference on the socket structure containing the connection */ + /* Then release our reference on the socket structure containing the + * connection. + */ psock_release(psock); return OK; diff --git a/net/socket/socket.c b/net/socket/socket.c index 86ec8da9298..ce15f19ff8b 100644 --- a/net/socket/socket.c +++ b/net/socket/socket.c @@ -1,35 +1,20 @@ /**************************************************************************** * net/socket/socket.c * - * Copyright (C) 2007-2009, 2012, 2014-2015 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ @@ -64,7 +49,8 @@ * domain (see sys/socket.h) * type (see sys/socket.h) * protocol (see sys/socket.h) - * psock A pointer to a user allocated socket structure to be initialized. + * psock A pointer to a user allocated socket structure to be + * initialized. * * Returned Value: * Returns zero (OK) on success. On failure, it returns a negated errno @@ -90,7 +76,8 @@ * ****************************************************************************/ -int psock_socket(int domain, int type, int protocol, FAR struct socket *psock) +int psock_socket(int domain, int type, int protocol, + FAR struct socket *psock) { FAR const struct sock_intf_s *sockif = NULL; int ret; @@ -217,6 +204,9 @@ int socket(int domain, int type, int protocol) goto errout_with_sockfd; } + /* The socket has been successfully initialized */ + + psock->s_flags |= _SF_INITD; return sockfd; errout_with_sockfd: diff --git a/sched/group/group_setuptaskfiles.c b/sched/group/group_setuptaskfiles.c index b481e467439..9cfe8e5c19b 100644 --- a/sched/group/group_setuptaskfiles.c +++ b/sched/group/group_setuptaskfiles.c @@ -1,35 +1,20 @@ /**************************************************************************** * sched/group/group_setuptaskfiles.c * - * Copyright (C) 2007-2008, 2010, 2012-2013 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ @@ -167,13 +152,15 @@ static inline void sched_dupsockets(FAR struct task_tcb_s *tcb) for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++) { - /* Check if this parent socket is allocated. We can tell if the - * socket is allocated because it will have a positive, non-zero - * reference count. + /* Check if this parent socket is valid. Valid means both (1) + * allocated and (2) successfully initialized. A complexity in SMP + * mode is that a socket my be allocated, but not yet initialized when + * the socket is cloned by another pthread. + * + * Sockets with the close-on-exec flag set should not be cloned either. */ - if (parent[i].s_crefs > 0 && - !_SS_ISCLOEXEC(parent[i].s_flags)) + if (_PS_VALID(&parent[i]) && !_SS_ISCLOEXEC(parent[i].s_flags)) { /* Yes... duplicate it for the child */ @@ -213,7 +200,8 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb) DEBUGASSERT(group); #ifndef CONFIG_DISABLE_PTHREAD - DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); + DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != + TCB_FLAG_TTYPE_PTHREAD); #endif /* Initialize file descriptors for the TCB */