PageRenderTime 40ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/nuttx/net/socket.c

https://github.com/luozhongchao/Firmware
C | 286 lines | 105 code | 40 blank | 141 comment | 42 complexity | ee1984d5ea9cf63e3787aee20b8ae4cc MD5 | raw file
Possible License(s): 0BSD
  1. /****************************************************************************
  2. * net/socket.c
  3. *
  4. * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #ifdef CONFIG_NET
  40. #include <sys/socket.h>
  41. #include <errno.h>
  42. #include <assert.h>
  43. #include <debug.h>
  44. #include "net_internal.h"
  45. /****************************************************************************
  46. * Global Functions
  47. ****************************************************************************/
  48. /****************************************************************************
  49. * Function: psock_socket
  50. *
  51. * Description:
  52. * socket() creates an endpoint for communication and returns a socket
  53. * structure.
  54. *
  55. * Parameters:
  56. * domain (see sys/socket.h)
  57. * type (see sys/socket.h)
  58. * protocol (see sys/socket.h)
  59. * psock A pointer to a user allocated socket structure to be initialized.
  60. *
  61. * Returned Value:
  62. * 0 on success; -1 on error with errno set appropriately
  63. *
  64. * EACCES
  65. * Permission to create a socket of the specified type and/or protocol
  66. * is denied.
  67. * EAFNOSUPPORT
  68. * The implementation does not support the specified address family.
  69. * EINVAL
  70. * Unknown protocol, or protocol family not available.
  71. * EMFILE
  72. * Process file table overflow.
  73. * ENFILE
  74. * The system limit on the total number of open files has been reached.
  75. * ENOBUFS or ENOMEM
  76. * Insufficient memory is available. The socket cannot be created until
  77. * sufficient resources are freed.
  78. * EPROTONOSUPPORT
  79. * The protocol type or the specified protocol is not supported within
  80. * this domain.
  81. *
  82. * Assumptions:
  83. *
  84. ****************************************************************************/
  85. int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
  86. {
  87. int err = ENFILE;
  88. /* Only PF_INET or PF_INET6 domains supported */
  89. #ifdef CONFIG_NET_IPv6
  90. if ( domain != PF_INET6)
  91. #else
  92. if ( domain != PF_INET)
  93. #endif
  94. {
  95. err = EAFNOSUPPORT;
  96. goto errout;
  97. }
  98. /* Only SOCK_STREAM and possible SOCK_DRAM are supported */
  99. #if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_UDP)
  100. if ((type == SOCK_STREAM && protocol != 0 && protocol != IPPROTO_TCP) ||
  101. (type == SOCK_DGRAM && protocol != 0 && protocol != IPPROTO_UDP) ||
  102. (type != SOCK_STREAM && type != SOCK_DGRAM))
  103. #elif defined(CONFIG_NET_TCP)
  104. if ((type == SOCK_STREAM && protocol != 0 && protocol != IPPROTO_TCP) ||
  105. (type != SOCK_STREAM))
  106. #elif defined(CONFIG_NET_UDP)
  107. if ((type == SOCK_DGRAM && protocol != 0 && protocol != IPPROTO_UDP) ||
  108. (type != SOCK_DGRAM))
  109. #endif
  110. {
  111. err = EPROTONOSUPPORT;
  112. goto errout;
  113. }
  114. /* Everything looks good. Initialize the socket structure */
  115. /* Save the protocol type */
  116. psock->s_type = type;
  117. psock->s_conn = NULL;
  118. /* Allocate the appropriate connection structure. This reserves the
  119. * the connection structure is is unallocated at this point. It will
  120. * not actually be initialized until the socket is connected.
  121. */
  122. err = ENOMEM; /* Assume failure to allocate connection instance */
  123. switch (type)
  124. {
  125. #ifdef CONFIG_NET_TCP
  126. case SOCK_STREAM:
  127. {
  128. /* Allocate the TCP connection structure and save in the new
  129. * socket instance.
  130. */
  131. struct uip_conn *conn = uip_tcpalloc();
  132. if (conn)
  133. {
  134. /* Set the reference count on the connection structure. This
  135. * reference count will be increment only if the socket is
  136. * dup'ed
  137. */
  138. DEBUGASSERT(conn->crefs == 0);
  139. psock->s_conn = conn;
  140. conn->crefs = 1;
  141. }
  142. }
  143. break;
  144. #endif
  145. #ifdef CONFIG_NET_UDP
  146. case SOCK_DGRAM:
  147. {
  148. /* Allocate the UDP connection structure and save in the new
  149. * socket instance.
  150. */
  151. struct uip_udp_conn *conn = uip_udpalloc();
  152. if (conn)
  153. {
  154. /* Set the reference count on the connection structure. This
  155. * reference count will be increment only if the socket is
  156. * dup'ed
  157. */
  158. DEBUGASSERT(conn->crefs == 0);
  159. psock->s_conn = conn;
  160. conn->crefs = 1;
  161. }
  162. }
  163. break;
  164. #endif
  165. default:
  166. break;
  167. }
  168. /* Did we succesfully allocate some kind of connection structure? */
  169. if (!psock->s_conn)
  170. {
  171. /* Failed to reserve a connection structure */
  172. goto errout; /* With err == ENFILE or ENOMEM */
  173. }
  174. return OK;
  175. errout:
  176. errno = err;
  177. return ERROR;
  178. }
  179. /****************************************************************************
  180. * Function: socket
  181. *
  182. * Description:
  183. * socket() creates an endpoint for communication and returns a descriptor.
  184. *
  185. * Parameters:
  186. * domain (see sys/socket.h)
  187. * type (see sys/socket.h)
  188. * protocol (see sys/socket.h)
  189. *
  190. * Returned Value:
  191. * A non-negative socket descriptor on success; -1 on error with errno set
  192. * appropriately.
  193. *
  194. * EACCES
  195. * Permission to create a socket of the specified type and/or protocol
  196. * is denied.
  197. * EAFNOSUPPORT
  198. * The implementation does not support the specified address family.
  199. * EINVAL
  200. * Unknown protocol, or protocol family not available.
  201. * EMFILE
  202. * Process file table overflow.
  203. * ENFILE
  204. * The system limit on the total number of open files has been reached.
  205. * ENOBUFS or ENOMEM
  206. * Insufficient memory is available. The socket cannot be created until
  207. * sufficient resources are freed.
  208. * EPROTONOSUPPORT
  209. * The protocol type or the specified protocol is not supported within
  210. * this domain.
  211. *
  212. * Assumptions:
  213. *
  214. ****************************************************************************/
  215. int socket(int domain, int type, int protocol)
  216. {
  217. FAR struct socket *psock;
  218. int sockfd;
  219. int ret;
  220. /* Allocate a socket descriptor */
  221. sockfd = sockfd_allocate(0);
  222. if (sockfd < 0)
  223. {
  224. set_errno(ENFILE);
  225. return ERROR;
  226. }
  227. /* Get the underlying socket structure */
  228. psock = sockfd_socket(sockfd);
  229. if (!psock)
  230. {
  231. set_errno(ENOSYS); /* should not happen */
  232. goto errout;
  233. }
  234. /* Initialize the socket structure */
  235. ret = psock_socket(domain, type, protocol, psock);
  236. if (ret < 0)
  237. {
  238. /* Error already set by psock_socket() */
  239. goto errout;
  240. }
  241. return sockfd;
  242. errout:
  243. sockfd_release(sockfd);
  244. return ERROR;
  245. }
  246. #endif /* CONFIG_NET */