Watt-32 tcp/ip  2.2 dev-rel.10
receive.c
Go to the documentation of this file.
1 
5 /* BSD sockets functionality for Watt-32 TCP/IP
6  *
7  * Copyright (c) 1997-2002 Gisle Vanem <gvanem@yahoo.no>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  * must display the following acknowledgement:
19  * This product includes software developed by Gisle Vanem
20  * Bergen, Norway.
21  *
22  * THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
26  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Version
34  *
35  * 0.5 : Dec 18, 1997 : G. Vanem - created
36  * 0.6 : Aug 08, 2002 : G. Vanem - added AF_INET6 support
37  */
38 
39 
40 #include "socket.h"
41 
42 #if defined(USE_BSD_API)
43 
44 static int tcp_receive (Socket *sock, void *buf, int len, int flags,
45  struct sockaddr *from, size_t *fromlen);
46 
47 static int udp_receive (Socket *sock, void *buf, int len, int flags,
48  struct sockaddr *from, size_t *fromlen);
49 
50 static int raw_receive (Socket *sock, void *buf, unsigned len, int flags,
51  struct sockaddr *from, size_t *fromlen);
52 
53 /*
54  * receive() flags:
55  * MSG_PEEK
56  * MSG_WAITALL
57  * MSG_OOB (not yet supported)
58  * MSG_DONTROUTE (not yet supported)
59  * MSG_EOR (not yet supported)
60  * MSG_TRUNC (not yet supported)
61  * MSG_CTRUNC (not yet supported)
62  *
63  * Only one flags bit is handled at a time.
64  */
65 
66 static int receive (const char *func, int s, void *buf, int len, int flags,
67  struct sockaddr *from, size_t *fromlen)
68 {
70  int ret = 0;
71 
72  if (func)
73  SOCK_DEBUGF (("\n%s:%d", func, s));
74 
75  if (!socket)
76  {
77  if (_sock_dos_fd(s))
78  {
79  SOCK_DEBUGF ((", ENOTSOCK"));
80  SOCK_ERRNO (ENOTSOCK);
81  return (-1);
82  }
83  SOCK_DEBUGF ((", EBADF"));
84  SOCK_ERRNO (EBADF);
85  return (-1);
86  }
87 
88  VERIFY_RW (buf, len);
89 
90  if (from && fromlen)
91  {
92  size_t sa_len = (socket->so_family == AF_INET6) ?
93  sizeof(struct sockaddr_in6) :
94  (socket->so_family == AF_PACKET) ?
95  sizeof(struct sockaddr_ll) :
96  sizeof(struct sockaddr_in);
97 
98  if (*fromlen < sa_len)
99  {
100  SOCK_DEBUGF ((", EADDRNOTAVAIL (fromlen = %d, sa_len = %d)",
101  (int)*fromlen, (int)sa_len));
102  SOCK_ERRNO (EADDRNOTAVAIL);
103  return (-1);
104  }
105  VERIFY_RW (from, sa_len);
106  }
107 
108  if (socket->so_state & SS_CONN_REFUSED)
109  {
110  if (socket->so_error == ECONNRESET) /* from BSO_RST_CALLBACK */
111  {
112  SOCK_DEBUGF ((", ECONNRESET"));
113  SOCK_ERRNO (ECONNRESET);
114  }
115  else
116  {
117  SOCK_DEBUGF ((", ECONNREFUSED (1)"));
118  SOCK_ERRNO (ECONNREFUSED);
119  }
120  return (-1);
121  }
122 
123  if (socket->so_state & SS_CANTRCVMORE)
124  {
125  SOCK_DEBUGF ((", EPIPE (can't recv more)"));
126  SOCK_ERRNO (EPIPE); /* !! was ENOTCONN */
127  return (-1);
128  }
129 
130  if ((flags & MSG_PEEK) && (flags & MSG_WAITALL))
131  {
132  SOCK_DEBUGF ((", invalid PEEK+WAITALL flags"));
133  SOCK_ERRNO (EINVAL);
134  return (-1);
135  }
136 
137  /* If application installs the same signal handlers we do, we must
138  * exit cracefully from below loops.
139  */
140  if (_sock_sig_setup() < 0)
141  {
142  SOCK_DEBUGF ((", EINTR"));
143  SOCK_ERRNO (EINTR);
144  return (-1);
145  }
146 
147  switch (socket->so_type)
148  {
149  case SOCK_STREAM:
150  ret = tcp_receive (socket, buf, len, flags, from, fromlen);
151  SOCK_DEBUGF ((", len=%d", ret));
152  break;
153 
154  case SOCK_DGRAM:
155  ret = udp_receive (socket, buf, len, flags, from, fromlen);
156  SOCK_DEBUGF ((", len=%d", ret));
157  break;
158 
159  case SOCK_RAW:
160  ret = raw_receive (socket, buf, len, flags, from, fromlen);
161  SOCK_DEBUGF ((", len=%d", ret));
162  break;
163 
164  case SOCK_PACKET:
165  /* give raw packets a chance to be polled first. */
166  tcp_tick (NULL);
167  ret = sock_packet_receive (socket, buf, len, from, fromlen);
168  SOCK_DEBUGF ((", len=%d", ret));
169  break;
170 
171  default:
172  SOCK_DEBUGF ((", EPROTONOSUPPORT"));
173  SOCK_ERRNO (EPROTONOSUPPORT);
174  ret = -1;
175  break;
176  }
177  _sock_sig_restore();
178  return (ret);
179 }
180 
181 /*
182  * recvfrom(): receive from socket 's'. Address (src-ip/port) is put
183  * in 'from' (if non-NULL)
184  */
185 int W32_CALL recvfrom (int s, void *buf, int len, int flags,
186  struct sockaddr *from, int *fromlen)
187 {
188  return receive ("recvfrom", s, buf, len, flags, from, (size_t*)fromlen);
189 }
190 
191 /*
192  * recv(): receive data from socket 's'. Flags may be
193  * MSG_PEEK, MSG_OOB or MSG_WAITALL
194  * Normally used on SOCK_STREAM sockets.
195  */
196 int W32_CALL recv (int s, void *buf, int len, int flags)
197 {
198  return receive ("recv", s, buf, len, flags, NULL, NULL);
199 }
200 
201 /*
202  * read_s(): As above but no flags.
203  */
204 int W32_CALL read_s (int s, char *buf, int len)
205 {
206  return receive ("read_s", s, buf, len, 0, NULL, NULL);
207 }
208 
209 /*
210  * recvmsg(): read into a 'msg->msg_iov' vector.
211  * Loop for each element in the vector. If 'msg->msg_name'
212  * is non-NULL, fill in from-addr.
213  */
214 int W32_CALL recvmsg (int s, struct msghdr *msg, int flags)
215 {
216  struct iovec *iov;
217  int count = msg->msg_iovlen;
218  int i, bytes, len;
219 
220  SOCK_DEBUGF (("\nrecvmsg:%d, iovecs=%d", s, count));
221 
222  iov = msg->msg_iov;
223  if (!iov)
224  {
225  SOCK_DEBUGF ((", EFAULT"));
226  SOCK_ERRNO (EFAULT);
227  return (-1);
228  }
229 
230  for (i = bytes = 0; i < count; i++)
231  {
232 #if (DOSX)
233  if (!valid_addr(iov[i].iov_base, iov[i].iov_len))
234  {
235  SOCK_DEBUGF ((", EFAULT (iovec[%d] = %p/%d)",
236  (int)i, iov[i].iov_base, iov[i].iov_len));
237  SOCK_ERRNO (EFAULT);
238  return (-1);
239  }
240 #endif
241 
242  len = receive (NULL, s, iov[i].iov_base, iov[i].iov_len,
243  flags, (struct sockaddr*)msg->msg_name,
244  (size_t*)&msg->msg_namelen);
245  if (len < 0)
246  {
247  bytes = -1;
248  break;
249  }
250  bytes += len;
251  if (len != iov[i].iov_len) /* nothing more to read */
252  break;
253  }
254  SOCK_DEBUGF ((", total %d", bytes));
255  return (bytes);
256 }
257 
258 /*
259  * readv_s(): Complementary of writev_s().
260  */
261 int W32_CALL readv_s (int s, const struct iovec *vector, size_t count)
262 {
263  int i, len, bytes = 0;
264 
265  SOCK_DEBUGF (("\nreadv_s:%d, iovecs=%lu", s, (DWORD)count));
266 
267  for (i = 0; i < (int)count; i++)
268  {
269 #if (DOSX)
270  if (!valid_addr(vector[i].iov_base, vector[i].iov_len))
271  {
272  SOCK_DEBUGF ((", EFAULT (iovec[%d] = %p/%d)",
273  (int)i, vector[i].iov_base, vector[i].iov_len));
274  SOCK_ERRNO (EFAULT);
275  return (-1);
276  }
277 #endif
278 
279  len = receive (NULL, s, vector[i].iov_base, vector[i].iov_len,
280  0, NULL, NULL);
281  if (len < 0)
282  {
283  bytes = -1;
284  break;
285  }
286  bytes += len;
287  if (len != vector[i].iov_len) /* nothing more to read */
288  break;
289  }
290  SOCK_DEBUGF ((", total %d", bytes));
291  return (bytes);
292 }
293 
294 /*
295  * Fill in packet's address in 'from' and length in 'fromlen'.
296  * Only used for UDP & Raw-IP. TCP have peer info in 'socket->remote_addr'.
297  */
298 static void udp_raw_fill_from_ip4 (struct sockaddr *from, size_t *fromlen,
299  const struct in_addr *peer, WORD port)
300 {
301  struct sockaddr_in *sa = (struct sockaddr_in*) from;
302 
303  if (sa && fromlen && *fromlen >= sizeof(*sa))
304  {
305  memset (sa, 0, sizeof(*sa));
306  sa->sin_addr = *peer;
307  sa->sin_family = AF_INET;
308  sa->sin_port = port;
309  }
310  if (fromlen)
311  *fromlen = sizeof (*sa);
312 }
313 
314 #if defined(USE_IPV6)
315 static void udp_raw_fill_from_ip6 (struct sockaddr *from, size_t *fromlen,
316  const void *peer, WORD port)
317 {
318  struct sockaddr_in6 *sa = (struct sockaddr_in6*) from;
319 
320  if (sa && fromlen)
321  {
322  memset (sa, 0, sizeof(*sa));
323  memcpy (&sa->sin6_addr, peer, sizeof(sa->sin6_addr));
324  sa->sin6_family = AF_INET6;
325  sa->sin6_port = port;
326  }
327  if (fromlen)
328  *fromlen = sizeof (*sa);
329 }
330 #endif
331 
332 /*
333  * TCP receiver
334  */
335 static int tcp_receive (Socket *socket, void *buf, int len, int flags,
336  struct sockaddr *from, size_t *fromlen)
337 {
338  int ret = 0;
339  BOOL got_fin = FALSE; /* got FIN from peer */
340  DWORD timer = 0UL;
341  sock_type *sk = (sock_type*) socket->tcp_sock;
342 
343  if (!from && !socket->local_addr)
344  {
345  SOCK_DEBUGF ((", no local_addr"));
346  SOCK_ERRNO (ENOTCONN);
347  return (-1);
348  }
349 
350  if (flags & MSG_OOB)
351  {
352  SOCK_DEBUGF ((", no OOB-data"));
353  SOCK_ERRNO (EWOULDBLOCK);
354  return (-1);
355  }
356 
357  if (socket->timeout && sock_inactive)
358  timer = set_timeout (1000 * socket->timeout);
359 
360  while (1)
361  {
362  BOOL ok = (tcp_tick(sk) != 0);
363 
364  tcp_Retransmitter (TRUE);
365 
366  if (socket->so_state & SS_ISDISCONNECTING)
367  {
368  got_fin = TRUE; /* might not have got a FIN, but need to read */
369  goto read_it;
370  }
371 
373 #if 0
374  if ((socket-so_options & SO_OOBINLINE) && urgent_data(sk))
375  {
376  ret = urgent_data_read (sk, (BYTE*)buf, len);
377  break;
378  }
379 #endif
380 
381  /* Don't do this for a listening socket
382  */
383  if (!(socket->so_options & SO_ACCEPTCONN))
384  {
385  if ((sk->tcp.locflags & LF_GOT_FIN) && /* got FIN, no unACK data */
386  sk->tcp.rx_datalen == 0)
387  {
388  socket->so_state |= SS_ISDISCONNECTING; /* We may receive more */
389  socket->so_state &= ~SS_ISCONNECTED; /* no longer ESTAB state */
390  got_fin = TRUE;
391  SOCK_DEBUGF ((", got FIN"));
392  goto read_it;
393  }
394 
395  if (!ok)
396  {
397  socket->so_state |= (SS_CANTRCVMORE | SS_ISDISCONNECTING);
398  socket->so_state &= ~SS_ISCONNECTED;
399  SOCK_DEBUGF ((", EPIPE"));
400  SOCK_ERRNO (EPIPE); /* !! was ENOTCONN */
401  return (-1);
402  }
403  }
404 
405  if (sock_rbused(sk) > socket->recv_lowat)
406  {
407 read_it:
408  if (flags & MSG_PEEK)
409  ret = sock_preread (sk, (BYTE*)buf, len);
410  else if (flags & MSG_WAITALL)
411  ret = sock_read (sk, (BYTE*)buf, len);
412  else ret = sock_fastread (sk, (BYTE*)buf, len);
413  break;
414  }
415 
416  if (socket->so_state & SS_CONN_REFUSED)
417  {
418  SOCK_DEBUGF ((", ECONNREFUSED (2)"));
419  SOCK_ERRNO (ECONNREFUSED);
420  return (-1);
421  }
422 
423  if (socket->so_state & SS_NBIO)
424  {
425  SOCK_DEBUGF ((", EWOULDBLOCK"));
426  SOCK_ERRNO (EWOULDBLOCK);
427  return (-1);
428  }
429 
430  if (chk_timeout(timer))
431  {
432  SOCK_DEBUGF ((", ETIMEDOUT"));
433  SOCK_ERRNO (ETIMEDOUT);
434  return (-1);
435  }
436 
437  if (_sock_sig_pending())
438  {
439  SOCK_DEBUGF ((", EINTR"));
440  SOCK_ERRNO (EINTR);
441  return (-1);
442  }
443 
444  if (sk->tcp.usr_yield)
445  (*sk->tcp.usr_yield)();
446  else WATT_YIELD();
447  }
448 
449  if (ret > 0)
450  {
451  int sa_len = (socket->so_family == AF_INET6) ?
452  sizeof(struct sockaddr_in6) :
453  sizeof(struct sockaddr_in);
454  if (from)
455  memcpy (from, socket->remote_addr, sa_len);
456  if (fromlen)
457  *fromlen = sa_len;
458  socket->keepalive = 0UL; /* reset keep-alive timer */
459  }
460  else if (ret < 0)
461  {
462  if (got_fin) /* A FIN and -1 from sock_xread() maps to 0 */
463  ret = 0;
464  else /* else some buffer/socket error */
465  {
466  SOCK_DEBUGF ((", EIO"));
467  SOCK_ERRNO (EIO);
468  }
469  }
470  return (ret);
471 }
472 
473 
474 /*
475  * UDP receiver
476  */
477 static int udp_receive (Socket *socket, void *buf, int len, int flags,
478  struct sockaddr *from, size_t *fromlen)
479 {
480  int ret = 0;
481  DWORD timer = 0UL;
482 
483  if (socket->timeout)
484  timer = set_timeout (1000 * socket->timeout);
485 
487 #if 0
488  /* If bind() not called, allow data from anybody on any port !!
489  */
490  if (from && !socket->local_addr)
491  {
492  struct sockaddr_in addr = { AF_INET, 0, { INADDR_ANY }};
493 
494  socket->so_state |= SS_PRIV;
495 
496  if (_UDP_listen (socket, addr.sin_addr, addr.sin_port) < 0)
497  return (-1);
498  }
499 #endif
500 
501  while (1)
502  {
503  sock_type *sk = (sock_type*) socket->udp_sock;
504  BOOL ok = (tcp_tick(sk) != 0);
505 
506  WATT_YIELD();
507 
508  if (socket->so_error == ECONNREFUSED ||
509  (sk->udp.locflags & LF_GOT_ICMP))
510  {
511  socket->so_state |= (SS_CANTRCVMORE | SS_CANTSENDMORE);
512  SOCK_DEBUGF ((", ECONNREFUSED"));
513  SOCK_ERRNO (ECONNREFUSED);
514  return (-1);
515  }
516 
517  if (!ok)
518  {
519  socket->so_state |= (SS_CANTRCVMORE | SS_CANTSENDMORE);
520  SOCK_DEBUGF ((", EPIPE"));
521  SOCK_ERRNO (EPIPE); /* !! was ENOTCONN */
522  return (-1);
523  }
524 
525  tcp_Retransmitter (TRUE);
526 
527  /* If this socket is for broadcast (or is unbound), check the
528  * queue setup by sock_recv_init() (in _UDP_listen).
529  * Note: it is possible to receive 0-byte probe packets.
530  */
531  if (socket->so_family == AF_INET && (socket->so_state & SS_PRIV))
532  {
533  struct in_addr peer = { 0 };
534  sock_type *udp = (sock_type*)socket->udp_sock;
535  WORD port;
536 
537  SOCK_ERRNO (0);
538  ret = sock_recv_from (udp, &peer.s_addr, &port, buf, len,
539  (flags & MSG_PEEK) ? 1 : 0);
540 
541  if (ret && _w32_errno != EBADF && peer.s_addr)
542  {
543  udp_raw_fill_from_ip4 (from, fromlen, &peer, port);
544  SOCK_DEBUGF ((", 1: remote: %s (%d)", inet_ntoa(peer), ntohs(port)));
545 
546  if (ret < 0) /* 0-byte probe */
547  return (0);
548  return (ret);
549  }
550  }
551 
552 #if defined(USE_IPV6)
553  else if (socket->so_family == AF_INET6 && (socket->so_state & SS_PRIV))
554  {
555  struct in6_addr peer;
556  sock_type *udp = (sock_type*) socket->udp_sock;
557  WORD port;
558 
559  SOCK_ERRNO (0);
560  memcpy (&peer, &in6addr_any, sizeof(peer));
561  ret = sock_recv_from (udp, (DWORD*)&peer, &port, buf, len,
562  (flags & MSG_PEEK) ? 1 : 0);
563 
564  if (ret && _w32_errno != EBADF && !IN6_IS_ADDR_UNSPECIFIED(&peer))
565  {
566  udp_raw_fill_from_ip6 (from, fromlen, &peer, port);
567  SOCK_DEBUGF ((", 1: remote: %s (%d)", _inet6_ntoa(&peer), ntohs(port)));
568 
569  if (ret < 0) /* 0-byte probe */
570  return (0);
571  return (ret);
572  }
573  }
574 #endif
575 
576  else if (sock_rbused(sk) > socket->recv_lowat)
577  {
578  if (flags & MSG_PEEK)
579  ret = sock_preread (sk, (BYTE*)buf, len);
580  else if (flags & MSG_WAITALL)
581  ret = sock_read (sk, (BYTE*)buf, len);
582  else ret = sock_fastread (sk, (BYTE*)buf, len);
583  break;
584  }
585 
586  if (socket->so_state & SS_CONN_REFUSED)
587  {
588  SOCK_DEBUGF ((", ECONNREFUSED (2)"));
589  SOCK_ERRNO (ECONNREFUSED);
590  return (-1);
591  }
592 
593  if (socket->so_state & SS_NBIO)
594  {
595  SOCK_DEBUGF ((", EWOULDBLOCK"));
596  SOCK_ERRNO (EWOULDBLOCK);
597  return (-1);
598  }
599 
600  if (chk_timeout(timer))
601  {
602  SOCK_DEBUGF ((", ETIMEDOUT"));
603  SOCK_ERRNO (ETIMEDOUT);
604  return (-1);
605  }
606 
607  if (_sock_sig_pending())
608  {
609  SOCK_DEBUGF ((", EINTR"));
610  SOCK_ERRNO (EINTR);
611  return (-1);
612  }
613  }
614 
615  if (ret > 0)
616  {
617 #if defined(USE_IPV6)
618  if (socket->so_family == AF_INET6)
619  {
620  WORD port = htons (socket->udp_sock->hisport);
621  const void *peer = &socket->udp_sock->his6addr[0];
622 
623  udp_raw_fill_from_ip6 (from, fromlen, peer, port);
624 
625  if (socket->remote_addr)
626  {
627  struct sockaddr_in6 *ra = (struct sockaddr_in6*)socket->remote_addr;
628 
629  ra->sin6_family = AF_INET6;
630  ra->sin6_port = port;
631  memcpy (&ra->sin6_addr, peer, sizeof(ra->sin6_addr));
632  }
633  SOCK_DEBUGF ((", 2: remote: %s (%d)", _inet6_ntoa(peer), ntohs(port)));
634  }
635  else
636 #endif
637  {
638  struct in_addr peer;
639  _udp_Socket *udp = socket->udp_sock;
640  WORD port;
641 
642  port = htons (udp->hisport);
643  peer.s_addr = htonl (udp->hisaddr);
644 
645  udp_raw_fill_from_ip4 (from, fromlen, &peer, port);
646 
647  if (socket->remote_addr)
648  {
649  socket->remote_addr->sin_family = AF_INET;
650  socket->remote_addr->sin_addr = peer;
651  socket->remote_addr->sin_port = port;
652  }
653  SOCK_DEBUGF ((", 2: remote: %s (%d)", inet_ntoa(peer), ntohs(port)));
654  }
655  }
656  return (ret);
657 }
658 
659 
660 /*
661  * Raw-IP receiver. Doesn't handle IP-options yet.
662  */
663 static int raw_receive (Socket *socket, void *buf, unsigned len, int flags,
664  struct sockaddr *from, size_t *fromlen)
665 {
666  _raw_Socket *raw = NULL;
667  DWORD timer, loop;
668 
669 #if defined(USE_IPV6)
670  _raw6_Socket *raw6 = NULL;
671 
672  if (socket->so_family == AF_INET6)
673  {
674  if (len < sizeof(raw6->ip6))
675  {
676  SOCK_DEBUGF (("EINVAL"));
677  SOCK_ERRNO (EINVAL);
678  return (-1);
679  }
680  }
681  else
682 #endif
683  if (len < sizeof(raw->ip))
684  {
685  SOCK_DEBUGF (("EINVAL"));
686  SOCK_ERRNO (EINVAL);
687  return (-1);
688  }
689 
690  if (socket->timeout)
691  timer = set_timeout (1000 * socket->timeout);
692  else timer = 0;
693  loop = 1;
694 
695  while (1)
696  {
697  unsigned ip_len, hdr_len;
698 
699  /* give sock_rbused() and memcpy() below a chance to run
700  * before sock_raw_recv() (via tcp_tick) drops a packet
701  */
702  if (loop++ > 1)
703  {
704  tcp_tick (NULL);
705  tcp_Retransmitter (TRUE);
706  }
707 
708 #if defined(USE_IPV6)
709  if (socket->so_family == AF_INET6)
710  {
711  raw6 = (_raw6_Socket*) find_oldest_raw6 (socket->raw6_sock);
712  ip_len = raw6 ? intel16 (raw6->ip6.len) : 0;
713  hdr_len = sizeof(in6_Header);
714  }
715  else
716 #endif
717  {
718  raw = (_raw_Socket*) find_oldest_raw (socket->raw_sock);
719  ip_len = raw ? intel16 (raw->ip.length) : 0; /* includes header length */
720  hdr_len = sizeof(in_Header);
721  }
722 
723 #if defined(USE_IPV6)
724  if (socket->so_family == AF_INET6)
725  {
726  if (ip_len >= hdr_len + socket->recv_lowat)
727  {
728  struct in6_Header *ip6 = (struct in6_Header*) buf;
729 
730  /* SOCK_RAW shall always return IP-header and data in 'buf'
731  */
732  memcpy (ip6, &raw6->ip6, hdr_len);
733  len = min (ip_len - hdr_len, len);
734  if (len > 0)
735  memcpy (++ip6, &raw6->rx_data[0], len);
736 
737  raw6->used = FALSE;
738 
739  udp_raw_fill_from_ip6 (from, fromlen, &raw6->ip6.source[0], 0);
740  SOCK_DEBUGF ((", remote: %s", _inet6_ntoa(&raw6->ip6.source[0])));
741  return (len + hdr_len);
742  }
743  }
744  else
745 #endif
746  if (ip_len >= hdr_len + socket->recv_lowat)
747  {
748  struct in_addr peer;
749  struct in_Header *ip = (struct in_Header*) buf;
750 
751  /* SOCK_RAW shall always return IP-header and data in 'buf'
752  */
753  memcpy (ip, &raw->ip, min(hdr_len,len)); /* first, copy the IP-header */
754  len = min (ip_len - hdr_len, len);
755  if (len > 0)
756  memcpy (++ip, &raw->rx_data[0], len); /* copy the rest. max 666000 bytes */
757 
758  peer.s_addr = raw->ip.source;
759  raw->used = FALSE;
760 
761  udp_raw_fill_from_ip4 (from, fromlen, &peer, 0);
762  SOCK_DEBUGF ((", remote: %s", inet_ntoa(peer)));
763  return (len + hdr_len);
764  }
765 
766  if (socket->so_state & SS_NBIO)
767  {
768  SOCK_DEBUGF ((", EWOULDBLOCK"));
769  SOCK_ERRNO (EWOULDBLOCK);
770  break;
771  }
772 
773  if (chk_timeout(timer))
774  {
775  SOCK_DEBUGF ((", ETIMEDOUT"));
776  SOCK_ERRNO (ETIMEDOUT);
777  break;
778  }
779 
780  if (_sock_sig_pending())
781  {
782  SOCK_DEBUGF ((", EINTR"));
783  SOCK_ERRNO (EINTR);
784  break;
785  }
786 
787  WATT_YIELD();
788  }
789 
790  ARGSUSED (flags);
791  return (-1);
792 }
793 #endif /* USE_BSD_API */
int W32_CALL sock_read(sock_type *s, BYTE *buf, size_t maxlen)
Read a socket with maximum 'maxlen' bytes.
Definition: pctcp.c:2875
static int tcp_receive(Socket *sock, void *buf, int len, int flags, struct sockaddr *from, size_t *fromlen)
Definition: receive.c:335
Definition: socket.h:137
Definition: socket.h:242
BOOL used
used flag; packet not read yet
Definition: wattcp.h:696
Definition: if.h:84
DWORD W32_CALL set_timeout(DWORD msec)
Return time for when given timeout (msec) expires.
Definition: timer.c:503
Socket * _socklist_find(int s)
Returns a pointer to the Socket structure associated with socket 's'.
Definition: socket.c:1534
BOOL _sock_dos_fd(int s)
_sock_dos_fd - Return TRUE if `s' is a valid DOS/Win32 handle.
Definition: socket.c:222
Definition: in.h:153
Definition: ip.h:67
int W32_CALL sock_fastread(sock_type *s, BYTE *buf, int len)
Read a socket with maximum 'len' bytes.
Definition: pctcp.c:2931
Definition: in.h:146
BYTE rx_data[MAX_FRAG_SIZE]
room for 1 jumbo IP packet
Definition: wattcp.h:699
Definition: wtypes.h:179
void tcp_Retransmitter(BOOL force)
Called periodically to perform retransmissions.
Definition: pctcp.c:1209
static int udp_receive(Socket *sock, void *buf, int len, int flags, struct sockaddr *from, size_t *fromlen)
Definition: receive.c:477
unsigned sock_packet_receive(Socket *sock, void *buf, unsigned len, struct sockaddr *from, size_t *fromlen)
Called from receive.c for AF_PACKET sockets.
Definition: socket.c:601
const char * _inet6_ntoa(const void *ip)
Convert an IPv6-address 'ip' into a string.
Definition: netaddr.c:401
WORD W32_CALL tcp_tick(sock_type *s)
Must be called periodically by user application (or BSD socket API).
Definition: pctcp.c:1389
ip6_address his6addr
peer's ip-6 address
Definition: wattcp.h:602
BOOL W32_CALL chk_timeout(DWORD value)
Check if milli-sec value has expired:
Definition: timer.c:547