diff options
Diffstat (limited to 'nuttx/net/socket/socket.c')
-rw-r--r-- | nuttx/net/socket/socket.c | 265 |
1 files changed, 174 insertions, 91 deletions
diff --git a/nuttx/net/socket/socket.c b/nuttx/net/socket/socket.c index 8e00143ca..427dd7016 100644 --- a/nuttx/net/socket/socket.c +++ b/nuttx/net/socket/socket.c @@ -54,6 +54,152 @@ #include "local/local.h" /**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: psock_tcp_alloc + * + * Description: + * Allocate and attach a TCP connection structure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int psock_tcp_alloc(FAR struct socket *psock) +{ + /* Allocate the TCP connection structure */ + + FAR struct tcp_conn_s *conn = tcp_alloc(psock->s_domain); + if (!conn) + { + /* Failed to reserve a connection structure */ + + return -ENOMEM; + } + + /* Set the reference count on the connection structure. This reference + * count will be incremented only if the socket is dup'ed + */ + + DEBUGASSERT(conn->crefs == 0); + conn->crefs = 1; + + /* Save the pre-allocated connection in the socket structure */ + + psock->s_conn = conn; + return OK; +} +#endif /* CONFIG_NET_TCP */ + +/**************************************************************************** + * Name: psock_udp_alloc + * + * Description: + * Allocate and attach a UDP connection structure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_UDP +static int psock_udp_alloc(FAR struct socket *psock) +{ + /* Allocate the UDP connection structure */ + + FAR struct udp_conn_s *conn = udp_alloc(psock->s_domain); + if (!conn) + { + /* Failed to reserve a connection structure */ + + return -ENOMEM; + } + + /* Set the reference count on the connection structure. This reference + * count will be incremented only if the socket is dup'ed + */ + + DEBUGASSERT(conn->crefs == 0); + conn->crefs = 1; + + /* Save the pre-allocated connection in the socket structure */ + + psock->s_conn = conn; + return OK; +} +#endif /* CONFIG_NET_UDP */ + +/**************************************************************************** + * Name: psock_pkt_alloc + * + * Description: + * Allocate and attach a raw packet connection structure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_PKT +static int psock_pkt_alloc(FAR struct socket *psock) +{ + /* Allocate the packet socket connection structure and save in the new + * socket instance. + */ + + FAR struct pkt_conn_s *conn = pkt_alloc(); + if (!conn) + { + /* Failed to reserve a connection structure */ + + return -ENOMEM; + } + + /* Set the reference count on the connection structure. This reference + * count will be incremented only if the socket is dup'ed + */ + + DEBUGASSERT(conn->crefs == 0); + conn->crefs = 1; + + /* Save the pre-allocated connection in the socket structure */ + + psock->s_conn = conn; + return OK; +} +#endif /* CONFIG_NET_PKT */ + +/**************************************************************************** + * Name: psock_local_alloc + * + * Description: + * Allocate and attach a local, Unix domain connection structure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_LOCAL +static int psock_local_alloc(FAR struct socket *psock) +{ + /* Allocate the local connection structure */ + + FAR struct local_conn_s *conn = local_alloc(); + if (!conn) + { + /* Failed to reserve a connection structure */ + + return -ENOMEM; + } + + /* Set the reference count on the connection structure. This reference + * count will be incremented only if the socket is dup'ed + */ + + DEBUGASSERT(conn->lc_crefs == 0); + conn->lc_crefs = 1; + + /* Save the pre-allocated connection in the socket structure */ + + psock->s_conn = conn; + return OK; +} +#endif /* CONFIG_NET_LOCAL */ + +/**************************************************************************** * Public Functions ****************************************************************************/ @@ -101,6 +247,7 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock) bool ipdomain = false; #endif bool dgramok = false; + int ret; int err; /* Only PF_INET, PF_INET6 or PF_PACKET domains supported */ @@ -209,27 +356,9 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock) if (ipdomain) #endif { - /* Allocate the TCP connection structure */ + /* Allocate and attach the TCP connection structure */ - FAR struct tcp_conn_s *conn = tcp_alloc(domain); - if (!conn) - { - /* Failed to reserve a connection structure */ - - goto errout; /* With err == ENFILE or ENOMEM */ - } - - /* Set the reference count on the connection structure. This - * reference count will be increment only if the socket is - * dup'ed - */ - - DEBUGASSERT(conn->crefs == 0); - conn->crefs = 1; - - /* Save the pre-allocated connection in the socket structure */ - - psock->s_conn = conn; + ret = psock_tcp_alloc(psock); } #endif /* CONFIG_NET_TCP */ @@ -238,29 +367,21 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock) else #endif { - /* Allocate the local connection structure */ - - FAR struct local_conn_s *conn = local_alloc(); - if (!conn) - { - /* Failed to reserve a connection structure */ + /* Allocate and attach the local connection structure */ - goto errout; /* With err == ENFILE or ENOMEM */ - } - - /* Set the reference count on the connection structure. This - * reference count will be increment only if the socket is - * dup'ed - */ + ret = psock_local_alloc(psock); + } +#endif /* CONFIG_NET_LOCAL */ - DEBUGASSERT(conn->crefs == 0); - conn->crefs = 1; + /* Check for failures to allocate the connection structure. */ - /* Save the pre-allocated connection in the socket structure */ + if (ret < 0) + { + /* Failed to reserve a connection structure */ - psock->s_conn = conn; + err = -ret; + goto errout; } -#endif /* CONFIG_NET_LOCAL */ } break; #endif @@ -273,27 +394,9 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock) if (ipdomain) #endif { - /* Allocate the UDP connection structure */ - - FAR struct udp_conn_s *conn = udp_alloc(domain); - if (!conn) - { - /* Failed to reserve a connection structure */ - - goto errout; /* With err == ENFILE or ENOMEM */ - } + /* Allocate and attach the UDP connection structure */ - /* Set the reference count on the connection structure. This - * reference count will be increment only if the socket is - * dup'ed - */ - - DEBUGASSERT(conn->crefs == 0); - conn->crefs = 1; - - /* Save the pre-allocated connection in the socket structure */ - - psock->s_conn = conn; + ret = psock_udp_alloc(psock); } #endif /* CONFIG_NET_UDP */ @@ -302,29 +405,21 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock) else #endif { - /* Allocate the local connection structure */ - - FAR struct local_conn_s *conn = local_alloc(); - if (!conn) - { - /* Failed to reserve a connection structure */ + /* Allocate and attach the local connection structure */ - goto errout; /* With err == ENFILE or ENOMEM */ - } - - /* Set the reference count on the connection structure. This - * reference count will be increment only if the socket is - * dup'ed - */ + ret = psock_local_alloc(psock); + } +#endif /* CONFIG_NET_LOCAL */ - DEBUGASSERT(conn->crefs == 0); - conn->crefs = 1; + /* Check for failures to allocate the connection structure. */ - /* Save the pre-allocated connection in the socket structure */ + if (ret < 0) + { + /* Failed to reserve a connection structure */ - psock->s_conn = conn; + err = -ret; + goto errout; } -#endif /* CONFIG_NET_LOCAL */ } break; #endif @@ -332,26 +427,14 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock) #ifdef CONFIG_NET_PKT case SOCK_RAW: { - /* Allocate the packet socket connection structure and save - * in the new socket instance. - */ - - FAR struct pkt_conn_s *conn = pkt_alloc(); - if (!conn) + ret = psock_pkt_alloc(FAR struct socket *psock) + if (ret < 0) { /* Failed to reserve a connection structure */ + err = -ret; goto errout; } - - /* Set the reference count on the connection structure. This - * reference count will be increment only if the socket is - * dup'ed - */ - - DEBUGASSERT(conn->crefs == 0); - psock->s_conn = conn; - conn->crefs = 1; } break; #endif |