connect.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /****************************************************************************
  2. * net/socket/connect.c
  3. *
  4. * Copyright (C) 2007-2012, 2015-2017 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. #include <sys/types.h>
  40. #include <sys/socket.h>
  41. #include <stdint.h>
  42. #include <errno.h>
  43. #include <assert.h>
  44. #include <debug.h>
  45. #include <nuttx/cancelpt.h>
  46. #include <nuttx/net/net.h>
  47. #include "socket/socket.h"
  48. #ifdef CONFIG_NET
  49. /****************************************************************************
  50. * Public Functions
  51. ****************************************************************************/
  52. /****************************************************************************
  53. * Name: psock_connect
  54. *
  55. * Description:
  56. * connect() connects the socket referred to by the structure 'psock'
  57. * to the address specified by 'addr'. The addrlen argument specifies
  58. * the size of 'addr'. The format of the address in 'addr' is
  59. * determined by the address space of the socket 'psock'.
  60. *
  61. * If the socket 'psock' is of type SOCK_DGRAM then 'addr' is the address
  62. * to which datagrams are sent by default, and the only address from which
  63. * datagrams are received. If the socket is of type SOCK_STREAM or
  64. * SOCK_SEQPACKET, this call attempts to make a connection to the socket
  65. * that is bound to the address specified by 'addr'.
  66. *
  67. * Generally, connection-based protocol sockets may successfully connect()
  68. * only once; connectionless protocol sockets may use connect() multiple
  69. * times to change their association. Connectionless sockets may dissolve
  70. * the association by connecting to an address with the sa_family member of
  71. * sockaddr set to AF_UNSPEC.
  72. *
  73. * Input Parameters:
  74. * psock Pointer to a socket structure initialized by psock_socket()
  75. * addr Server address (form depends on type of socket)
  76. * addrlen Length of actual 'addr'
  77. *
  78. * Returned Value:
  79. * Returns zero (OK) on success. On failure, it returns a negated errno
  80. * value to indicate the nature of the error.
  81. *
  82. * EACCES, EPERM
  83. * The user tried to connect to a broadcast address without having the
  84. * socket broadcast flag enabled or the connection request failed
  85. * because of a local firewall rule.
  86. * EADDRINUSE
  87. * Local address is already in use.
  88. * EAFNOSUPPORT
  89. * The passed address didn't have the correct address family in its
  90. * sa_family field.
  91. * EAGAIN
  92. * No more free local ports or insufficient entries in the routing
  93. * cache.
  94. * EALREADY
  95. * The socket is non-blocking and a previous connection attempt has
  96. * not yet been completed.
  97. * EBADF
  98. * The file descriptor is not a valid index in the descriptor table.
  99. * ECONNREFUSED
  100. * No one listening on the remote address.
  101. * EFAULT
  102. * The socket structure address is outside the user's address space.
  103. * EINPROGRESS
  104. * The socket is non-blocking and the connection cannot be completed
  105. * immediately.
  106. * EINTR
  107. * The system call was interrupted by a signal that was caught.
  108. * EISCONN
  109. * The socket is already connected.
  110. * ENETUNREACH
  111. * Network is unreachable.
  112. * ENOTSOCK
  113. * The file descriptor is not associated with a socket.
  114. * ETIMEDOUT
  115. * Timeout while attempting connection. The server may be too busy
  116. * to accept new connections.
  117. *
  118. * Assumptions:
  119. *
  120. ****************************************************************************/
  121. int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr,
  122. socklen_t addrlen)
  123. {
  124. int ret;
  125. /* Verify that the psock corresponds to valid, allocated socket */
  126. if (psock == NULL || psock->s_crefs <= 0)
  127. {
  128. return -EBADF;
  129. }
  130. /* Make sure that an address was provided */
  131. if (addr == NULL)
  132. {
  133. return -EFAULT;
  134. }
  135. /* Let the address family's connect() method handle the operation */
  136. DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_connect != NULL);
  137. ret = psock->s_sockif->si_connect(psock, addr, addrlen);
  138. if (ret < 0)
  139. {
  140. return ret;
  141. }
  142. return OK;
  143. }
  144. /****************************************************************************
  145. * Name: connect
  146. *
  147. * Description:
  148. * connect() connects the socket referred to by the file descriptor 'sockfd'
  149. * to the address specified by 'addr'. The addrlen argument specifies
  150. * the size of 'addr'. The format of the address in 'addr' is
  151. * determined by the address space of the socket 'sockfd'.
  152. *
  153. * If the socket 'sockfd' is of type SOCK_DGRAM then 'addr' is the address
  154. * to which datagrams are sent by default, and the only address from which
  155. * datagrams are received. If the socket is of type SOCK_STREAM or
  156. * SOCK_SEQPACKET, this call attempts to make a connection to the socket
  157. * that is bound to the address specified by 'addr'.
  158. *
  159. * Generally, connection-based protocol sockets may successfully connect()
  160. * only once; connectionless protocol sockets may use connect() multiple
  161. * times to change their association. Connectionless sockets may dissolve
  162. * the association by connecting to an address with the sa_family member of
  163. * sockaddr set to AF_UNSPEC.
  164. *
  165. * Input Parameters:
  166. * sockfd Socket descriptor returned by socket()
  167. * addr Server address (form depends on type of socket)
  168. * addrlen Length of actual 'addr'
  169. *
  170. * Returned Value:
  171. * 0 on success; -1 on error with errno set appropriately
  172. *
  173. * EACCES, EPERM
  174. * The user tried to connect to a broadcast address without having the
  175. * socket broadcast flag enabled or the connection request failed
  176. * because of a local firewall rule.
  177. * EADDRINUSE
  178. * Local address is already in use.
  179. * EAFNOSUPPORT
  180. * The passed address didn't have the correct address family in its
  181. * sa_family field.
  182. * EAGAIN
  183. * No more free local ports or insufficient entries in the routing
  184. * cache.
  185. * EALREADY
  186. * The socket is non-blocking and a previous connection attempt has
  187. * not yet been completed.
  188. * EBADF
  189. * The file descriptor is not a valid index in the descriptor table.
  190. * ECONNREFUSED
  191. * No one listening on the remote address.
  192. * EFAULT
  193. * The socket structure address is outside the user's address space.
  194. * EINPROGRESS
  195. * The socket is non-blocking and the connection cannot be completed
  196. * immediately.
  197. * EINTR
  198. * The system call was interrupted by a signal that was caught.
  199. * EISCONN
  200. * The socket is already connected.
  201. * ENETUNREACH
  202. * Network is unreachable.
  203. * ENOTSOCK
  204. * The file descriptor is not associated with a socket.
  205. * ETIMEDOUT
  206. * Timeout while attempting connection. The server may be too busy
  207. * to accept new connections.
  208. *
  209. * Assumptions:
  210. *
  211. ****************************************************************************/
  212. int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen)
  213. {
  214. FAR struct socket *psock;
  215. int ret;
  216. /* accept() is a cancellation point */
  217. (void)enter_cancellation_point();
  218. /* Get the underlying socket structure */
  219. psock = sockfd_socket(sockfd);
  220. /* Then let psock_connect() do all of the work */
  221. ret = psock_connect(psock, addr, addrlen);
  222. if (ret < 0)
  223. {
  224. set_errno(-ret);
  225. ret = ERROR;
  226. }
  227. leave_cancellation_point();
  228. return ret;
  229. }
  230. #endif /* CONFIG_NET */