inet_recvfrom.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591
  1. /****************************************************************************
  2. * net/inet/inet_recvfrom.c
  3. *
  4. * Copyright (C) 2007-2009, 2011-2018 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/types.h>
  41. #include <sys/socket.h>
  42. #include <stdint.h>
  43. #include <string.h>
  44. #include <errno.h>
  45. #include <debug.h>
  46. #include <assert.h>
  47. #include <arch/irq.h>
  48. #include <nuttx/clock.h>
  49. #include <nuttx/semaphore.h>
  50. #include <nuttx/cancelpt.h>
  51. #include <nuttx/net/net.h>
  52. #include <nuttx/mm/iob.h>
  53. #include <nuttx/net/netdev.h>
  54. #include <nuttx/net/ip.h>
  55. #include <nuttx/net/tcp.h>
  56. #include <nuttx/net/udp.h>
  57. #include "netdev/netdev.h"
  58. #include "devif/devif.h"
  59. #include "tcp/tcp.h"
  60. #include "udp/udp.h"
  61. #include "pkt/pkt.h"
  62. #include "local/local.h"
  63. #include "socket/socket.h"
  64. #include "usrsock/usrsock.h"
  65. #include "inet/inet.h"
  66. /****************************************************************************
  67. * Pre-processor Definitions
  68. ****************************************************************************/
  69. #define IPv4BUF ((struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
  70. #define IPv6BUF ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
  71. #define UDPIPv4BUF ((struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv4_HDRLEN])
  72. #define UDPIPv6BUF ((struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
  73. #define TCPIPv4BUF ((struct tcp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv4_HDRLEN])
  74. #define TCPIPv6BUF ((struct tcp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
  75. /****************************************************************************
  76. * Private Types
  77. ****************************************************************************/
  78. #if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
  79. struct inet_recvfrom_s
  80. {
  81. FAR struct socket *ir_sock; /* The parent socket structure */
  82. #ifdef CONFIG_NET_SOCKOPTS
  83. clock_t ir_starttime; /* rcv start time for determining timeout */
  84. #endif
  85. FAR struct devif_callback_s *ir_cb; /* Reference to callback instance */
  86. sem_t ir_sem; /* Semaphore signals recv completion */
  87. size_t ir_buflen; /* Length of receive buffer */
  88. uint8_t *ir_buffer; /* Pointer to receive buffer */
  89. FAR struct sockaddr *ir_from; /* Address of sender */
  90. FAR socklen_t *ir_fromlen; /* Number of bytes allocated for address of sender */
  91. ssize_t ir_recvlen; /* The received length */
  92. int ir_result; /* Success:OK, failure:negated errno */
  93. };
  94. #endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
  95. /****************************************************************************
  96. * Private Functions
  97. ****************************************************************************/
  98. /****************************************************************************
  99. * Name: inet_update_recvlen
  100. *
  101. * Description:
  102. * Update information about space available for new data and update size
  103. * of data in buffer, This logic accounts for the case where
  104. * inet_udp_readahead() sets state.ir_recvlen == -1 .
  105. *
  106. * Input Parameters:
  107. * pstate recvfrom state structure
  108. * recvlen size of new data appended to buffer
  109. *
  110. * Returned Value:
  111. * None
  112. *
  113. ****************************************************************************/
  114. #if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
  115. static inline void inet_update_recvlen(FAR struct inet_recvfrom_s *pstate,
  116. size_t recvlen)
  117. {
  118. if (pstate->ir_recvlen < 0)
  119. {
  120. pstate->ir_recvlen = 0;
  121. }
  122. pstate->ir_recvlen += recvlen;
  123. pstate->ir_buffer += recvlen;
  124. pstate->ir_buflen -= recvlen;
  125. }
  126. #endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
  127. /****************************************************************************
  128. * Name: inet_recvfrom_newdata
  129. *
  130. * Description:
  131. * Copy the read data from the packet
  132. *
  133. * Input Parameters:
  134. * dev The structure of the network driver that generated the event.
  135. * pstate recvfrom state structure
  136. *
  137. * Returned Value:
  138. * The number of bytes taken from the packet.
  139. *
  140. * Assumptions:
  141. * The network is locked.
  142. *
  143. ****************************************************************************/
  144. #if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
  145. static size_t inet_recvfrom_newdata(FAR struct net_driver_s *dev,
  146. FAR struct inet_recvfrom_s *pstate)
  147. {
  148. size_t recvlen;
  149. /* Get the length of the data to return */
  150. if (dev->d_len > pstate->ir_buflen)
  151. {
  152. recvlen = pstate->ir_buflen;
  153. }
  154. else
  155. {
  156. recvlen = dev->d_len;
  157. }
  158. /* Copy the new appdata into the user buffer */
  159. memcpy(pstate->ir_buffer, dev->d_appdata, recvlen);
  160. ninfo("Received %d bytes (of %d)\n", (int)recvlen, (int)dev->d_len);
  161. /* Update the accumulated size of the data read */
  162. inet_update_recvlen(pstate, recvlen);
  163. return recvlen;
  164. }
  165. #endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
  166. /****************************************************************************
  167. * Name: inet_tcp_newdata
  168. *
  169. * Description:
  170. * Copy the read data from the packet
  171. *
  172. * Input Parameters:
  173. * dev The structure of the network driver that generated the event
  174. * pstate recvfrom state structure
  175. *
  176. * Returned Value:
  177. * None.
  178. *
  179. * Assumptions:
  180. * The network is locked.
  181. *
  182. ****************************************************************************/
  183. #ifdef NET_TCP_HAVE_STACK
  184. static inline void inet_tcp_newdata(FAR struct net_driver_s *dev,
  185. FAR struct inet_recvfrom_s *pstate)
  186. {
  187. /* Take as much data from the packet as we can */
  188. size_t recvlen = inet_recvfrom_newdata(dev, pstate);
  189. /* If there is more data left in the packet that we could not buffer, then
  190. * add it to the read-ahead buffers.
  191. */
  192. if (recvlen < dev->d_len)
  193. {
  194. #ifdef CONFIG_NET_TCP_READAHEAD
  195. FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pstate->ir_sock->s_conn;
  196. FAR uint8_t *buffer = (FAR uint8_t *)dev->d_appdata + recvlen;
  197. uint16_t buflen = dev->d_len - recvlen;
  198. #ifdef CONFIG_DEBUG_NET
  199. uint16_t nsaved;
  200. nsaved = tcp_datahandler(conn, buffer, buflen);
  201. #else
  202. (void)tcp_datahandler(conn, buffer, buflen);
  203. #endif
  204. /* There are complicated buffering issues that are not addressed fully
  205. * here. For example, what if up_datahandler() cannot buffer the
  206. * remainder of the packet? In that case, the data will be dropped but
  207. * still ACKed. Therefore it would not be resent.
  208. *
  209. * This is probably not an issue here because we only get here if the
  210. * read-ahead buffers are empty and there would have to be something
  211. * serioulsy wrong with the configuration not to be able to buffer a
  212. * partial packet in this context.
  213. */
  214. #ifdef CONFIG_DEBUG_NET
  215. if (nsaved < buflen)
  216. {
  217. nerr("ERROR: packet data not saved (%d bytes)\n", buflen - nsaved);
  218. }
  219. #endif
  220. #else
  221. nerr("ERROR: packet data lost (%d bytes)\n", dev->d_len - recvlen);
  222. #endif
  223. }
  224. /* Indicate no data in the buffer */
  225. dev->d_len = 0;
  226. }
  227. #endif /* NET_TCP_HAVE_STACK */
  228. /****************************************************************************
  229. * Name: inet_udp_newdata
  230. *
  231. * Description:
  232. * Copy the read data from the packet
  233. *
  234. * Input Parameters:
  235. * dev The sructure of the network driver that generated the event
  236. * pstate recvfrom state structure
  237. *
  238. * Returned Value:
  239. * None.
  240. *
  241. * Assumptions:
  242. * The network is locked.
  243. *
  244. ****************************************************************************/
  245. #ifdef NET_UDP_HAVE_STACK
  246. static inline void inet_udp_newdata(FAR struct net_driver_s *dev,
  247. FAR struct inet_recvfrom_s *pstate)
  248. {
  249. /* Take as much data from the packet as we can */
  250. (void)inet_recvfrom_newdata(dev, pstate);
  251. /* Indicate no data in the buffer */
  252. dev->d_len = 0;
  253. }
  254. #endif /* NET_UDP_HAVE_STACK */
  255. /****************************************************************************
  256. * Name: inet_tcp_readahead and inet_udp_readahead
  257. *
  258. * Description:
  259. * Copy the read-ahead data from the packet
  260. *
  261. * Input Parameters:
  262. * pstate recvfrom state structure
  263. *
  264. * Returned Value:
  265. * None
  266. *
  267. * Assumptions:
  268. * The network is locked.
  269. *
  270. ****************************************************************************/
  271. #if defined(NET_TCP_HAVE_STACK) && defined(CONFIG_NET_TCP_READAHEAD)
  272. static inline void inet_tcp_readahead(struct inet_recvfrom_s *pstate)
  273. {
  274. FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pstate->ir_sock->s_conn;
  275. FAR struct iob_s *iob;
  276. int recvlen;
  277. /* Check there is any TCP data already buffered in a read-ahead
  278. * buffer.
  279. */
  280. while ((iob = iob_peek_queue(&conn->readahead)) != NULL &&
  281. pstate->ir_buflen > 0)
  282. {
  283. DEBUGASSERT(iob->io_pktlen > 0);
  284. /* Transfer that buffered data from the I/O buffer chain into
  285. * the user buffer.
  286. */
  287. recvlen = iob_copyout(pstate->ir_buffer, iob, pstate->ir_buflen, 0);
  288. ninfo("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen);
  289. /* Update the accumulated size of the data read */
  290. inet_update_recvlen(pstate, recvlen);
  291. /* If we took all of the ata from the I/O buffer chain is empty, then
  292. * release it. If there is still data available in the I/O buffer
  293. * chain, then just trim the data that we have taken from the
  294. * beginning of the I/O buffer chain.
  295. */
  296. if (recvlen >= iob->io_pktlen)
  297. {
  298. FAR struct iob_s *tmp;
  299. /* Remove the I/O buffer chain from the head of the read-ahead
  300. * buffer queue.
  301. */
  302. tmp = iob_remove_queue(&conn->readahead);
  303. DEBUGASSERT(tmp == iob);
  304. UNUSED(tmp);
  305. /* And free the I/O buffer chain */
  306. (void)iob_free_chain(iob);
  307. }
  308. else
  309. {
  310. /* The bytes that we have received from the head of the I/O
  311. * buffer chain (probably changing the head of the I/O
  312. * buffer queue).
  313. */
  314. (void)iob_trimhead_queue(&conn->readahead, recvlen);
  315. }
  316. }
  317. }
  318. #endif /* NET_TCP_HAVE_STACK && CONFIG_NET_TCP_READAHEAD */
  319. #if defined(NET_UDP_HAVE_STACK) && defined(CONFIG_NET_UDP_READAHEAD)
  320. static inline void inet_udp_readahead(struct inet_recvfrom_s *pstate)
  321. {
  322. FAR struct udp_conn_s *conn = (FAR struct udp_conn_s *)pstate->ir_sock->s_conn;
  323. FAR struct iob_s *iob;
  324. int recvlen;
  325. /* Check there is any UDP datagram already buffered in a read-ahead
  326. * buffer.
  327. */
  328. pstate->ir_recvlen = -1;
  329. if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
  330. {
  331. FAR struct iob_s *tmp;
  332. uint8_t src_addr_size;
  333. DEBUGASSERT(iob->io_pktlen > 0);
  334. /* Transfer that buffered data from the I/O buffer chain into
  335. * the user buffer.
  336. */
  337. recvlen = iob_copyout(&src_addr_size, iob, sizeof(uint8_t), 0);
  338. if (recvlen != sizeof(uint8_t))
  339. {
  340. goto out;
  341. }
  342. if (0
  343. #ifdef CONFIG_NET_IPv6
  344. || src_addr_size == sizeof(struct sockaddr_in6)
  345. #endif
  346. #ifdef CONFIG_NET_IPv4
  347. || src_addr_size == sizeof(struct sockaddr_in)
  348. #endif
  349. )
  350. {
  351. if (pstate->ir_from)
  352. {
  353. socklen_t len = *pstate->ir_fromlen;
  354. len = (socklen_t)src_addr_size > len ? len : (socklen_t)src_addr_size;
  355. recvlen = iob_copyout((FAR uint8_t *)pstate->ir_from, iob,
  356. len, sizeof(uint8_t));
  357. if (recvlen != len)
  358. {
  359. goto out;
  360. }
  361. }
  362. }
  363. if (pstate->ir_buflen > 0)
  364. {
  365. recvlen = iob_copyout(pstate->ir_buffer, iob, pstate->ir_buflen,
  366. src_addr_size + sizeof(uint8_t));
  367. ninfo("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen);
  368. /* Update the accumulated size of the data read */
  369. pstate->ir_recvlen = recvlen;
  370. pstate->ir_buffer += recvlen;
  371. pstate->ir_buflen -= recvlen;
  372. }
  373. else
  374. {
  375. pstate->ir_recvlen = 0;
  376. }
  377. out:
  378. /* Remove the I/O buffer chain from the head of the read-ahead
  379. * buffer queue.
  380. */
  381. tmp = iob_remove_queue(&conn->readahead);
  382. DEBUGASSERT(tmp == iob);
  383. UNUSED(tmp);
  384. /* And free the I/O buffer chain */
  385. (void)iob_free_chain(iob);
  386. }
  387. }
  388. #endif
  389. /****************************************************************************
  390. * Name: inet_recvfrom_timeout
  391. *
  392. * Description:
  393. * Check for recvfrom timeout.
  394. *
  395. * Input Parameters:
  396. * pstate recvfrom state structure
  397. *
  398. * Returned Value:
  399. * TRUE:timeout FALSE:no timeout
  400. *
  401. * Assumptions:
  402. * The network is locked.
  403. *
  404. ****************************************************************************/
  405. #if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
  406. #ifdef CONFIG_NET_SOCKOPTS
  407. static int inet_recvfrom_timeout(struct inet_recvfrom_s *pstate)
  408. {
  409. FAR struct socket *psock = 0;
  410. socktimeo_t timeo = 0;
  411. /* Check for a timeout configured via setsockopts(SO_RCVTIMEO). If none...
  412. * we well let the read hang forever (except for the special case below).
  413. */
  414. /* Get the socket reference from the private data */
  415. psock = pstate->ir_sock;
  416. if (psock)
  417. {
  418. /* Recover the timeout value (zero if no timeout) */
  419. timeo = psock->s_rcvtimeo;
  420. }
  421. /* Use a fixed, configurable delay under the following circumstances:
  422. *
  423. * 1) This delay function has been enabled with CONFIG_NET_TCP_RECVDELAY > 0
  424. * 2) Some data has already been received from the socket. Since this can
  425. * only be true for a TCP/IP socket, this logic applies only to TCP/IP
  426. * sockets. And either
  427. * 3) There is no configured receive timeout, or
  428. * 4) The configured receive timeout is greater than than the delay
  429. */
  430. #if CONFIG_NET_TCP_RECVDELAY > 0
  431. if ((timeo == 0 || timeo > CONFIG_NET_TCP_RECVDELAY) &&
  432. pstate->ir_recvlen > 0)
  433. {
  434. /* Use the configured timeout */
  435. timeo = CONFIG_NET_TCP_RECVDELAY;
  436. }
  437. #endif
  438. /* Is there an effective timeout? */
  439. if (timeo)
  440. {
  441. /* Yes.. Check if the timeout has elapsed */
  442. return net_timeo(pstate->ir_starttime, timeo);
  443. }
  444. /* No timeout -- hang forever waiting for data. */
  445. return FALSE;
  446. }
  447. #endif /* CONFIG_NET_SOCKOPTS */
  448. #endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
  449. /****************************************************************************
  450. * Name: inet_tcp_sender
  451. *
  452. * Description:
  453. * Getting the sender's address from the UDP packet
  454. *
  455. * Input Parameters:
  456. * dev - The device driver data structure
  457. * pstate - the recvfrom state structure
  458. *
  459. * Returned Value:
  460. * None
  461. *
  462. * Assumptions:
  463. * The network is locked
  464. *
  465. ****************************************************************************/
  466. #ifdef NET_TCP_HAVE_STACK
  467. static inline void inet_tcp_sender(FAR struct net_driver_s *dev,
  468. FAR struct inet_recvfrom_s *pstate)
  469. {
  470. /* Get the family from the packet type, IP address from the IP header, and
  471. * the port number from the TCP header.
  472. */
  473. #ifdef CONFIG_NET_IPv6
  474. #ifdef CONFIG_NET_IPv4
  475. if (IFF_IS_IPv6(dev->d_flags))
  476. #endif
  477. {
  478. FAR struct sockaddr_in6 *infrom =
  479. (FAR struct sockaddr_in6 *)pstate->ir_from;
  480. if (infrom)
  481. {
  482. FAR struct tcp_hdr_s *tcp = TCPIPv6BUF;
  483. FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
  484. infrom->sin6_family = AF_INET6;
  485. infrom->sin6_port = tcp->srcport;
  486. net_ipv6addr_copy(infrom->sin6_addr.s6_addr, ipv6->srcipaddr);
  487. }
  488. }
  489. #endif /* CONFIG_NET_IPv6 */
  490. #ifdef CONFIG_NET_IPv4
  491. #ifdef CONFIG_NET_IPv6
  492. else
  493. #endif
  494. {
  495. FAR struct sockaddr_in *infrom =
  496. (FAR struct sockaddr_in *)pstate->ir_from;
  497. if (infrom)
  498. {
  499. FAR struct tcp_hdr_s *tcp = TCPIPv4BUF;
  500. FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
  501. infrom->sin_family = AF_INET;
  502. infrom->sin_port = tcp->srcport;
  503. net_ipv4addr_copy(infrom->sin_addr.s_addr,
  504. net_ip4addr_conv32(ipv4->srcipaddr));
  505. }
  506. }
  507. #endif /* CONFIG_NET_IPv4 */
  508. }
  509. #endif /* NET_TCP_HAVE_STACK */
  510. /****************************************************************************
  511. * Name: inet_tcp_eventhandler
  512. *
  513. * Description:
  514. * This function is called with the network locked to perform the actual
  515. * TCP receive operation via by the lower, device interfacing layer.
  516. *
  517. * Input Parameters:
  518. * dev The structure of the network driver that generated the event.
  519. * pvconn The connection structure associated with the socket
  520. * flags Set of events describing why the callback was invoked
  521. *
  522. * Returned Value:
  523. * None
  524. *
  525. * Assumptions:
  526. * The network is locked.
  527. *
  528. ****************************************************************************/
  529. #ifdef NET_TCP_HAVE_STACK
  530. static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev,
  531. FAR void *pvconn, FAR void *pvpriv,
  532. uint16_t flags)
  533. {
  534. FAR struct inet_recvfrom_s *pstate = (struct inet_recvfrom_s *)pvpriv;
  535. #if 0 /* REVISIT: The assertion fires. Why? */
  536. FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
  537. /* The TCP socket is connected and, hence, should be bound to a device.
  538. * Make sure that the polling device is the own that we are bound to.
  539. */
  540. DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
  541. if (conn->dev != NULL && conn->dev != dev)
  542. {
  543. return flags;
  544. }
  545. #endif
  546. ninfo("flags: %04x\n", flags);
  547. /* 'priv' might be null in some race conditions (?) */
  548. if (pstate)
  549. {
  550. /* If new data is available, then complete the read action. */
  551. if ((flags & TCP_NEWDATA) != 0)
  552. {
  553. /* Copy the data from the packet (saving any unused bytes from the
  554. * packet in the read-ahead buffer).
  555. */
  556. inet_tcp_newdata(dev, pstate);
  557. /* Save the sender's address in the caller's 'from' location */
  558. inet_tcp_sender(dev, pstate);
  559. /* Indicate that the data has been consumed and that an ACK
  560. * should be sent.
  561. */
  562. flags = (flags & ~TCP_NEWDATA) | TCP_SNDACK;
  563. /* Check for transfer complete. We will consider the transfer
  564. * complete in own of two different ways, depending on the setting
  565. * of CONFIG_NET_TCP_RECVDELAY.
  566. *
  567. * 1) If CONFIG_NET_TCP_RECVDELAY == 0 then we will consider the
  568. * TCP/IP transfer complete as soon as any data has been received.
  569. * This is safe because if any additional data is received, it
  570. * will be retained in the TCP/IP read-ahead buffer until the
  571. * next receive is performed.
  572. * 2) CONFIG_NET_TCP_RECVDELAY > 0 may be set to wait a little
  573. * bit to determine if more data will be received. You might
  574. * do this if read-ahead buffering is disabled and we want to
  575. * minimize the loss of back-to-back packets. In this case,
  576. * the transfer is complete when either a) the entire user buffer
  577. * is full or 2) when the receive timeout occurs (below).
  578. */
  579. #if CONFIG_NET_TCP_RECVDELAY > 0
  580. if (pstate->ir_buflen == 0)
  581. #else
  582. if (pstate->ir_recvlen > 0)
  583. #endif
  584. {
  585. ninfo("TCP resume\n");
  586. /* The TCP receive buffer is non-empty. Return now and don't
  587. * allow any further TCP call backs.
  588. */
  589. pstate->ir_cb->flags = 0;
  590. pstate->ir_cb->priv = NULL;
  591. pstate->ir_cb->event = NULL;
  592. /* Wake up the waiting thread, returning the number of bytes
  593. * actually read.
  594. */
  595. nxsem_post(&pstate->ir_sem);
  596. }
  597. #ifdef CONFIG_NET_SOCKOPTS
  598. /* Reset the timeout. We will want a short timeout to terminate
  599. * the TCP receive.
  600. */
  601. pstate->ir_starttime = clock_systimer();
  602. #endif
  603. }
  604. /* Check for a loss of connection.
  605. *
  606. * TCP_DISCONN_EVENTS:
  607. * TCP_CLOSE: The remote host has closed the connection
  608. * TCP_ABORT: The remote host has aborted the connection
  609. * TCP_TIMEDOUT: Connection aborted due to too many retransmissions.
  610. * NETDEV_DOWN: The network device went down
  611. */
  612. else if ((flags & TCP_DISCONN_EVENTS) != 0)
  613. {
  614. FAR struct socket *psock = pstate->ir_sock;
  615. nwarn("WARNING: Lost connection\n");
  616. /* We could get here recursively through the callback actions of
  617. * tcp_lost_connection(). So don't repeat that action if we have
  618. * already been disconnected.
  619. */
  620. DEBUGASSERT(psock != NULL);
  621. if (_SS_ISCONNECTED(psock->s_flags))
  622. {
  623. /* Handle loss-of-connection event */
  624. tcp_lost_connection(psock, pstate->ir_cb, flags);
  625. }
  626. /* Check if the peer gracefully closed the connection. */
  627. if ((flags & TCP_CLOSE) != 0)
  628. {
  629. /* This case should always return success (zero)! The value of
  630. * ir_recvlen, if zero, will indicate that the connection was
  631. * gracefully closed.
  632. */
  633. pstate->ir_result = 0;
  634. }
  635. else
  636. {
  637. /* If no data has been received, then return ENOTCONN.
  638. * Otherwise, let this return success. The failure will
  639. * be reported the next time that recv[from]() is called.
  640. */
  641. #if CONFIG_NET_TCP_RECVDELAY > 0
  642. if (pstate->ir_recvlen > 0)
  643. {
  644. pstate->ir_result = 0;
  645. }
  646. else
  647. {
  648. pstate->ir_result = -ENOTCONN;
  649. }
  650. #else
  651. pstate->ir_result = -ENOTCONN;
  652. #endif
  653. }
  654. /* Wake up the waiting thread */
  655. nxsem_post(&pstate->ir_sem);
  656. }
  657. #ifdef CONFIG_NET_SOCKOPTS
  658. /* No data has been received -- this is some other event... probably a
  659. * poll -- check for a timeout.
  660. */
  661. else if (inet_recvfrom_timeout(pstate))
  662. {
  663. /* Yes.. the timeout has elapsed... do not allow any further
  664. * callbacks
  665. */
  666. ninfo("TCP timeout\n");
  667. pstate->ir_cb->flags = 0;
  668. pstate->ir_cb->priv = NULL;
  669. pstate->ir_cb->event = NULL;
  670. /* Report an error only if no data has been received. (If
  671. * CONFIG_NET_TCP_RECVDELAY then ir_recvlen should always be
  672. * less than or equal to zero).
  673. */
  674. #if CONFIG_NET_TCP_RECVDELAY > 0
  675. if (pstate->ir_recvlen <= 0)
  676. #endif
  677. {
  678. /* Report the timeout error */
  679. pstate->ir_result = -EAGAIN;
  680. }
  681. /* Wake up the waiting thread, returning either the error -EAGAIN
  682. * that signals the timeout event or the data received up to
  683. * the point that the timeout occurred (no error).
  684. */
  685. nxsem_post(&pstate->ir_sem);
  686. }
  687. #endif /* CONFIG_NET_SOCKOPTS */
  688. }
  689. return flags;
  690. }
  691. #endif /* NET_TCP_HAVE_STACK */
  692. /****************************************************************************
  693. * Name: inet_udp_sender
  694. *
  695. * Description:
  696. * Getting the sender's address from the UDP packet
  697. *
  698. * Input Parameters:
  699. * dev - The device driver data structure
  700. * pstate - the recvfrom state structure
  701. *
  702. * Returned Value:
  703. * None
  704. *
  705. * Assumptions:
  706. * The network is locked.
  707. *
  708. ****************************************************************************/
  709. #ifdef NET_UDP_HAVE_STACK
  710. static inline void inet_udp_sender(struct net_driver_s *dev, struct inet_recvfrom_s *pstate)
  711. {
  712. /* Get the family from the packet type, IP address from the IP header, and
  713. * the port number from the UDP header.
  714. */
  715. #ifdef CONFIG_NET_IPv6
  716. #ifdef CONFIG_NET_IPv4
  717. if (IFF_IS_IPv6(dev->d_flags))
  718. #endif
  719. {
  720. FAR struct sockaddr_in6 *infrom =
  721. (FAR struct sockaddr_in6 *)pstate->ir_from;
  722. FAR socklen_t *fromlen = pstate->ir_fromlen;
  723. if (infrom)
  724. {
  725. FAR struct udp_hdr_s *udp = UDPIPv6BUF;
  726. FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
  727. infrom->sin6_family = AF_INET6;
  728. infrom->sin6_port = udp->srcport;
  729. *fromlen = sizeof(struct sockaddr_in6);
  730. net_ipv6addr_copy(infrom->sin6_addr.s6_addr, ipv6->srcipaddr);
  731. }
  732. }
  733. #endif /* CONFIG_NET_IPv6 */
  734. #ifdef CONFIG_NET_IPv4
  735. #ifdef CONFIG_NET_IPv6
  736. else
  737. #endif
  738. {
  739. FAR struct sockaddr_in *infrom =
  740. (FAR struct sockaddr_in *)pstate->ir_from;
  741. if (infrom)
  742. {
  743. #ifdef CONFIG_NET_IPv6
  744. FAR struct udp_conn_s *conn =
  745. (FAR struct udp_conn_s *)pstate->ir_sock->s_conn;
  746. /* Hybrid dual-stack IPv6/IPv4 implementations recognize a special
  747. * class of addresses, the IPv4-mapped IPv6 addresses.
  748. */
  749. if (conn->domain == PF_INET6)
  750. {
  751. FAR struct sockaddr_in6 *infrom6 = (FAR struct sockaddr_in6 *)infrom;
  752. FAR socklen_t *fromlen = pstate->ir_fromlen;
  753. FAR struct udp_hdr_s *udp = UDPIPv6BUF;
  754. FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
  755. in_addr_t ipv4addr;
  756. /* Encode the IPv4 address as an IPv4-mapped IPv6 address */
  757. infrom6->sin6_family = AF_INET6;
  758. infrom6->sin6_port = udp->srcport;
  759. *fromlen = sizeof(struct sockaddr_in6);
  760. ipv4addr = net_ip4addr_conv32(ipv6->srcipaddr);
  761. ip6_map_ipv4addr(ipv4addr, infrom6->sin6_addr.s6_addr16);
  762. }
  763. else
  764. #endif
  765. {
  766. FAR struct udp_hdr_s *udp = UDPIPv4BUF;
  767. FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
  768. infrom->sin_family = AF_INET;
  769. infrom->sin_port = udp->srcport;
  770. net_ipv4addr_copy(infrom->sin_addr.s_addr,
  771. net_ip4addr_conv32(ipv4->srcipaddr));
  772. }
  773. }
  774. }
  775. #endif /* CONFIG_NET_IPv4 */
  776. }
  777. #endif /* NET_UDP_HAVE_STACK */
  778. /****************************************************************************
  779. * Name: inet_udp_terminate
  780. *
  781. * Description:
  782. * Terminate the UDP transfer.
  783. *
  784. * Input Parameters:
  785. * pstate - The recvfrom state structure
  786. * result - The result of the operation
  787. *
  788. * Returned Value:
  789. * None
  790. *
  791. ****************************************************************************/
  792. #ifdef NET_UDP_HAVE_STACK
  793. static void inet_udp_terminate(FAR struct inet_recvfrom_s *pstate, int result)
  794. {
  795. /* Don't allow any further UDP call backs. */
  796. pstate->ir_cb->flags = 0;
  797. pstate->ir_cb->priv = NULL;
  798. pstate->ir_cb->event = NULL;
  799. /* Save the result of the transfer */
  800. pstate->ir_result = result;
  801. /* Wake up the waiting thread, returning the number of bytes
  802. * actually read.
  803. */
  804. nxsem_post(&pstate->ir_sem);
  805. }
  806. #endif /* NET_UDP_HAVE_STACK */
  807. /****************************************************************************
  808. * Name: inet_udp_eventhandler
  809. *
  810. * Description:
  811. * This function is called with the network locked to perform the actual
  812. * UDP receive operation via by the lower, device interfacing layer.
  813. *
  814. * Input Parameters:
  815. * dev The structure of the network driver that generated the event.
  816. * pvconn The connection structure associated with the socket
  817. * flags Set of events describing why the callback was invoked
  818. *
  819. * Returned Value:
  820. * None
  821. *
  822. * Assumptions:
  823. * The network is locked.
  824. *
  825. ****************************************************************************/
  826. #ifdef NET_UDP_HAVE_STACK
  827. static uint16_t inet_udp_eventhandler(FAR struct net_driver_s *dev,
  828. FAR void *pvconn, FAR void *pvpriv,
  829. uint16_t flags)
  830. {
  831. FAR struct inet_recvfrom_s *pstate = (FAR struct inet_recvfrom_s *)pvpriv;
  832. ninfo("flags: %04x\n", flags);
  833. /* 'priv' might be null in some race conditions (?) */
  834. if (pstate)
  835. {
  836. /* If the network device has gone down, then we will have terminate
  837. * the wait now with an error.
  838. */
  839. if ((flags & NETDEV_DOWN) != 0)
  840. {
  841. /* Terminate the transfer with an error. */
  842. nerr("ERROR: Network is down\n");
  843. inet_udp_terminate(pstate, -ENETUNREACH);
  844. }
  845. /* If new data is available, then complete the read action. */
  846. else if ((flags & UDP_NEWDATA) != 0)
  847. {
  848. /* Copy the data from the packet */
  849. inet_udp_newdata(dev, pstate);
  850. /* We are finished. */
  851. ninfo("UDP done\n");
  852. /* Save the sender's address in the caller's 'from' location */
  853. inet_udp_sender(dev, pstate);
  854. /* Don't allow any further UDP call backs. */
  855. inet_udp_terminate(pstate, OK);
  856. /* Indicate that the data has been consumed */
  857. flags &= ~UDP_NEWDATA;
  858. }
  859. #ifdef CONFIG_NET_SOCKOPTS
  860. /* No data has been received -- this is some other event... probably a
  861. * poll -- check for a timeout.
  862. */
  863. else if (inet_recvfrom_timeout(pstate))
  864. {
  865. /* Yes.. the timeout has elapsed... do not allow any further
  866. * callbacks
  867. */
  868. nerr("ERROR: UDP timeout\n");
  869. /* Terminate the transfer with an -EAGAIN error */
  870. inet_udp_terminate(pstate, -EAGAIN);
  871. }
  872. #endif /* CONFIG_NET_SOCKOPTS */
  873. }
  874. return flags;
  875. }
  876. #endif /* NET_UDP_HAVE_STACK */
  877. /****************************************************************************
  878. * Name: inet_recvfrom_initialize
  879. *
  880. * Description:
  881. * Initialize the state structure
  882. *
  883. * Input Parameters:
  884. * psock Pointer to the socket structure for the socket
  885. * buf Buffer to receive data
  886. * len Length of buffer
  887. * pstate A pointer to the state structure to be initialized
  888. *
  889. * Returned Value:
  890. * None
  891. *
  892. * Assumptions:
  893. *
  894. ****************************************************************************/
  895. #if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
  896. static void inet_recvfrom_initialize(FAR struct socket *psock, FAR void *buf,
  897. size_t len, FAR struct sockaddr *infrom,
  898. FAR socklen_t *fromlen,
  899. FAR struct inet_recvfrom_s *pstate)
  900. {
  901. /* Initialize the state structure. */
  902. memset(pstate, 0, sizeof(struct inet_recvfrom_s));
  903. /* This semaphore is used for signaling and, hence, should not have
  904. * priority inheritance enabled.
  905. */
  906. (void)nxsem_init(&pstate->ir_sem, 0, 0); /* Doesn't really fail */
  907. (void)nxsem_setprotocol(&pstate->ir_sem, SEM_PRIO_NONE);
  908. pstate->ir_buflen = len;
  909. pstate->ir_buffer = buf;
  910. pstate->ir_from = infrom;
  911. pstate->ir_fromlen = fromlen;
  912. /* Set up the start time for the timeout */
  913. pstate->ir_sock = psock;
  914. #ifdef CONFIG_NET_SOCKOPTS
  915. pstate->ir_starttime = clock_systimer();
  916. #endif
  917. }
  918. /* The only un-initialization that has to be performed is destroying the
  919. * semaphore.
  920. */
  921. #define inet_recvfrom_uninitialize(s) nxsem_destroy(&(s)->ir_sem)
  922. #endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
  923. /****************************************************************************
  924. * Name: inet_recvfrom_result
  925. *
  926. * Description:
  927. * Evaluate the result of the recv operations
  928. *
  929. * Input Parameters:
  930. * result The result of the net_lockedwait operation (may indicate EINTR)
  931. * pstate A pointer to the state structure to be initialized
  932. *
  933. * Returned Value:
  934. * The result of the recv operation with errno set appropriately
  935. *
  936. * Assumptions:
  937. *
  938. ****************************************************************************/
  939. #if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK)
  940. static ssize_t inet_recvfrom_result(int result, struct inet_recvfrom_s *pstate)
  941. {
  942. /* Check for a error/timeout detected by the event handler. Errors are
  943. * signaled by negative errno values for the rcv length
  944. */
  945. if (pstate->ir_result < 0)
  946. {
  947. /* This might return EAGAIN on a timeout or ENOTCONN on loss of
  948. * connection (TCP only)
  949. */
  950. return pstate->ir_result;
  951. }
  952. /* If net_lockedwait failed, then we were probably reawakened by a signal. In
  953. * this case, net_lockedwait will have returned negated errno appropriately.
  954. */
  955. if (result < 0)
  956. {
  957. return result;
  958. }
  959. return pstate->ir_recvlen;
  960. }
  961. #endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */
  962. /****************************************************************************
  963. * Name: inet_udp_recvfrom
  964. *
  965. * Description:
  966. * Perform the recvfrom operation for a UDP SOCK_DGRAM
  967. *
  968. * Input Parameters:
  969. * psock Pointer to the socket structure for the SOCK_DRAM socket
  970. * buf Buffer to receive data
  971. * len Length of buffer
  972. * from INET address of source (may be NULL)
  973. *
  974. * Returned Value:
  975. * On success, returns the number of characters received. On error,
  976. * -errno is returned (see recvfrom for list of errnos).
  977. *
  978. * Assumptions:
  979. *
  980. ****************************************************************************/
  981. #ifdef NET_UDP_HAVE_STACK
  982. static ssize_t inet_udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
  983. FAR struct sockaddr *from, FAR socklen_t *fromlen)
  984. {
  985. FAR struct udp_conn_s *conn = (FAR struct udp_conn_s *)psock->s_conn;
  986. FAR struct net_driver_s *dev;
  987. struct inet_recvfrom_s state;
  988. int ret;
  989. /* Perform the UDP recvfrom() operation */
  990. /* Initialize the state structure. This is done with the network locked
  991. * because we don't want anything to happen until we are ready.
  992. */
  993. net_lock();
  994. inet_recvfrom_initialize(psock, buf, len, from, fromlen, &state);
  995. #ifdef CONFIG_NET_UDP_READAHEAD
  996. /* Copy the read-ahead data from the packet */
  997. inet_udp_readahead(&state);
  998. /* The default return value is the number of bytes that we just copied
  999. * into the user buffer. We will return this if the socket has become
  1000. * disconnected or if the user request was completely satisfied with
  1001. * data from the readahead buffers.
  1002. */
  1003. ret = state.ir_recvlen;
  1004. #else
  1005. /* Otherwise, the default return value of zero is used (only for the case
  1006. * where len == state.ir_buflen is zero).
  1007. */
  1008. ret = 0;
  1009. #endif
  1010. #ifdef CONFIG_NET_UDP_READAHEAD
  1011. /* Handle non-blocking UDP sockets */
  1012. if (_SS_ISNONBLOCK(psock->s_flags))
  1013. {
  1014. /* Return the number of bytes read from the read-ahead buffer if
  1015. * something was received (already in 'ret'); EAGAIN if not.
  1016. */
  1017. if (ret < 0)
  1018. {
  1019. /* Nothing was received */
  1020. ret = -EAGAIN;
  1021. }
  1022. }
  1023. /* It is okay to block if we need to. If there is space to receive anything
  1024. * more, then we will wait to receive the data. Otherwise return the number
  1025. * of bytes read from the read-ahead buffer (already in 'ret').
  1026. *
  1027. * NOTE: that inet_udp_readahead() may set state.ir_recvlen == -1.
  1028. */
  1029. else if (state.ir_recvlen <= 0)
  1030. #endif
  1031. {
  1032. /* Get the device that will handle the packet transfers. This may be
  1033. * NULL if the UDP socket is bound to INADDR_ANY. In that case, no
  1034. * NETDEV_DOWN notifications will be received.
  1035. */
  1036. dev = udp_find_laddr_device(conn);
  1037. /* Set up the callback in the connection */
  1038. state.ir_cb = udp_callback_alloc(dev, conn);
  1039. if (state.ir_cb)
  1040. {
  1041. /* Set up the callback in the connection */
  1042. state.ir_cb->flags = (UDP_NEWDATA | UDP_POLL | NETDEV_DOWN);
  1043. state.ir_cb->priv = (FAR void *)&state;
  1044. state.ir_cb->event = inet_udp_eventhandler;
  1045. /* Wait for either the receive to complete or for an error/timeout
  1046. * to occur. net_lockedwait will also terminate if a signal is
  1047. * received.
  1048. */
  1049. ret = net_lockedwait(&state. ir_sem);
  1050. /* Make sure that no further events are processed */
  1051. udp_callback_free(dev, conn, state.ir_cb);
  1052. ret = inet_recvfrom_result(ret, &state);
  1053. }
  1054. else
  1055. {
  1056. ret = -EBUSY;
  1057. }
  1058. }
  1059. net_unlock();
  1060. inet_recvfrom_uninitialize(&state);
  1061. return ret;
  1062. }
  1063. #endif /* NET_UDP_HAVE_STACK */
  1064. /****************************************************************************
  1065. * Name: inet_tcp_recvfrom
  1066. *
  1067. * Description:
  1068. * Perform the recvfrom operation for a TCP/IP SOCK_STREAM
  1069. *
  1070. * Input Parameters:
  1071. * psock Pointer to the socket structure for the SOCK_DRAM socket
  1072. * buf Buffer to receive data
  1073. * len Length of buffer
  1074. * from INET address of source (may be NULL)
  1075. *
  1076. * Returned Value:
  1077. * On success, returns the number of characters received. On error,
  1078. * -errno is returned (see recvfrom for list of errnos).
  1079. *
  1080. * Assumptions:
  1081. *
  1082. ****************************************************************************/
  1083. #ifdef NET_TCP_HAVE_STACK
  1084. static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
  1085. FAR struct sockaddr *from, FAR socklen_t *fromlen)
  1086. {
  1087. struct inet_recvfrom_s state;
  1088. int ret;
  1089. /* Initialize the state structure. This is done with the network locked
  1090. * because we don't want anything to happen until we are ready.
  1091. */
  1092. net_lock();
  1093. inet_recvfrom_initialize(psock, buf, len, from, fromlen, &state);
  1094. /* Handle any any TCP data already buffered in a read-ahead buffer. NOTE
  1095. * that there may be read-ahead data to be retrieved even after the
  1096. * socket has been disconnected.
  1097. */
  1098. #ifdef CONFIG_NET_TCP_READAHEAD
  1099. inet_tcp_readahead(&state);
  1100. /* The default return value is the number of bytes that we just copied
  1101. * into the user buffer. We will return this if the socket has become
  1102. * disconnected or if the user request was completely satisfied with
  1103. * data from the readahead buffers.
  1104. */
  1105. ret = state.ir_recvlen;
  1106. #else
  1107. /* Otherwise, the default return value of zero is used (only for the case
  1108. * where len == state.ir_buflen is zero).
  1109. */
  1110. ret = 0;
  1111. #endif
  1112. /* Verify that the SOCK_STREAM has been and still is connected */
  1113. if (!_SS_ISCONNECTED(psock->s_flags))
  1114. {
  1115. /* Was any data transferred from the readahead buffer after we were
  1116. * disconnected? If so, then return the number of bytes received. We
  1117. * will wait to return end disconnection indications the next time that
  1118. * recvfrom() is called.
  1119. *
  1120. * If no data was received (i.e., ret == 0 -- it will not be negative)
  1121. * and the connection was gracefully closed by the remote peer, then return
  1122. * success. If ir_recvlen is zero, the caller of recvfrom() will get an
  1123. * end-of-file indication.
  1124. */
  1125. #ifdef CONFIG_NET_TCP_READAHEAD
  1126. if (ret <= 0 && !_SS_ISCLOSED(psock->s_flags))
  1127. #else
  1128. if (!_SS_ISCLOSED(psock->s_flags))
  1129. #endif
  1130. {
  1131. /* Nothing was previously received from the readahead buffers.
  1132. * The SOCK_STREAM must be (re-)connected in order to receive any
  1133. * additional data.
  1134. */
  1135. ret = -ENOTCONN;
  1136. }
  1137. }
  1138. /* In general, this implementation will not support non-blocking socket
  1139. * operations... except in a few cases: Here for TCP receive with read-ahead
  1140. * enabled. If this socket is configured as non-blocking then return EAGAIN
  1141. * if no data was obtained from the read-ahead buffers.
  1142. */
  1143. else
  1144. #ifdef CONFIG_NET_TCP_READAHEAD
  1145. if (_SS_ISNONBLOCK(psock->s_flags))
  1146. {
  1147. /* Return the number of bytes read from the read-ahead buffer if
  1148. * something was received (already in 'ret'); EAGAIN if not.
  1149. */
  1150. if (ret <= 0)
  1151. {
  1152. /* Nothing was received */
  1153. ret = -EAGAIN;
  1154. }
  1155. }
  1156. /* It is okay to block if we need to. If there is space to receive anything
  1157. * more, then we will wait to receive the data. Otherwise return the number
  1158. * of bytes read from the read-ahead buffer (already in 'ret').
  1159. */
  1160. else
  1161. #endif
  1162. /* We get here when we we decide that we need to setup the wait for incoming
  1163. * TCP/IP data. Just a few more conditions to check:
  1164. *
  1165. * 1) Make sure thet there is buffer space to receive additional data
  1166. * (state.ir_buflen > 0). This could be zero, for example, if read-ahead
  1167. * buffering was enabled and we filled the user buffer with data from
  1168. * the read-ahead buffers. And
  1169. * 2) if read-ahead buffering is enabled (CONFIG_NET_TCP_READAHEAD)
  1170. * and delay logic is disabled (CONFIG_NET_TCP_RECVDELAY == 0), then we
  1171. * not want to wait if we already obtained some data from the read-ahead
  1172. * buffer. In that case, return now with what we have (don't want for more
  1173. * because there may be no timeout).
  1174. */
  1175. #if CONFIG_NET_TCP_RECVDELAY == 0 && defined(CONFIG_NET_TCP_READAHEAD)
  1176. if (state.ir_recvlen == 0 && state.ir_buflen > 0)
  1177. #else
  1178. if (state.ir_buflen > 0)
  1179. #endif
  1180. {
  1181. FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn;
  1182. /* Set up the callback in the connection */
  1183. state.ir_cb = tcp_callback_alloc(conn);
  1184. if (state.ir_cb)
  1185. {
  1186. state.ir_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_DISCONN_EVENTS);
  1187. state.ir_cb->priv = (FAR void *)&state;
  1188. state.ir_cb->event = inet_tcp_eventhandler;
  1189. /* Wait for either the receive to complete or for an error/timeout
  1190. * to occur. net_lockedwait will also terminate if a signal isi
  1191. * received.
  1192. */
  1193. ret = net_lockedwait(&state.ir_sem);
  1194. /* Make sure that no further events are processed */
  1195. tcp_callback_free(conn, state.ir_cb);
  1196. ret = inet_recvfrom_result(ret, &state);
  1197. }
  1198. else
  1199. {
  1200. ret = -EBUSY;
  1201. }
  1202. }
  1203. net_unlock();
  1204. inet_recvfrom_uninitialize(&state);
  1205. return (ssize_t)ret;
  1206. }
  1207. #endif /* NET_TCP_HAVE_STACK */
  1208. /****************************************************************************
  1209. * Public Functions
  1210. ****************************************************************************/
  1211. /****************************************************************************
  1212. * Name: inet_recvfrom
  1213. *
  1214. * Description:
  1215. * Implements the socket recvfrom interface for the case of the AF_INET
  1216. * and AF_INET6 address families. inet_recvfrom() receives messages from
  1217. * a socket, and may be used to receive data on a socket whether or not it
  1218. * is connection-oriented.
  1219. *
  1220. * If 'from' is not NULL, and the underlying protocol provides the source
  1221. * address, this source address is filled in. The argument 'fromlen' is
  1222. * initialized to the size of the buffer associated with from, and
  1223. * modified on return to indicate the actual size of the address stored
  1224. * there.
  1225. *
  1226. * Input Parameters:
  1227. * psock A pointer to a NuttX-specific, internal socket structure
  1228. * buf Buffer to receive data
  1229. * len Length of buffer
  1230. * flags Receive flags
  1231. * from Address of source (may be NULL)
  1232. * fromlen The length of the address structure
  1233. *
  1234. * Returned Value:
  1235. * On success, returns the number of characters received. If no data is
  1236. * available to be received and the peer has performed an orderly shutdown,
  1237. * recv() will return 0. Otherwise, on errors, a negated errno value is
  1238. * returned (see recvfrom() for the list of appropriate error values).
  1239. *
  1240. ****************************************************************************/
  1241. ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
  1242. int flags, FAR struct sockaddr *from,
  1243. FAR socklen_t *fromlen)
  1244. {
  1245. ssize_t ret;
  1246. /* If a 'from' address has been provided, verify that it is large
  1247. * enough to hold this address family.
  1248. */
  1249. if (from)
  1250. {
  1251. socklen_t minlen;
  1252. /* Get the minimum socket length */
  1253. switch (psock->s_domain)
  1254. {
  1255. #ifdef CONFIG_NET_IPv4
  1256. case PF_INET:
  1257. {
  1258. minlen = sizeof(struct sockaddr_in);
  1259. }
  1260. break;
  1261. #endif
  1262. #ifdef CONFIG_NET_IPv6
  1263. case PF_INET6:
  1264. {
  1265. minlen = sizeof(struct sockaddr_in6);
  1266. }
  1267. break;
  1268. #endif
  1269. default:
  1270. DEBUGPANIC();
  1271. return -EINVAL;
  1272. }
  1273. if (*fromlen < minlen)
  1274. {
  1275. return -EINVAL;
  1276. }
  1277. }
  1278. /* Read from the network interface driver buffer */
  1279. /* Or perform the TCP/IP or UDP recv() operation */
  1280. switch (psock->s_type)
  1281. {
  1282. #ifdef CONFIG_NET_TCP
  1283. case SOCK_STREAM:
  1284. {
  1285. #ifdef NET_TCP_HAVE_STACK
  1286. ret = inet_tcp_recvfrom(psock, buf, len, from, fromlen);
  1287. #else
  1288. ret = -ENOSYS;
  1289. #endif
  1290. }
  1291. break;
  1292. #endif /* CONFIG_NET_TCP */
  1293. #ifdef CONFIG_NET_UDP
  1294. case SOCK_DGRAM:
  1295. {
  1296. #ifdef NET_UDP_HAVE_STACK
  1297. ret = inet_udp_recvfrom(psock, buf, len, from, fromlen);
  1298. #else
  1299. ret = -ENOSYS;
  1300. #endif
  1301. }
  1302. break;
  1303. #endif /* CONFIG_NET_UDP */
  1304. default:
  1305. {
  1306. nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
  1307. ret = -ENOSYS;
  1308. }
  1309. break;
  1310. }
  1311. return ret;
  1312. }
  1313. #endif /* CONFIG_NET */