#ifdef IPV6_V6ONLY
/*
- * Accepts only IPv6 connections on IPv6 sockets
- * (and open an IPv4 socket later as well if needed).
- * Only Linux and FreeBSD can map IPv4 connections on IPv6 sockets,
- * so this allows for more uniform handling across platforms. Besides,
- * it makes sure that IPv4 addresses will be printed as w.x.y.z rather
- * than ::ffff:w.x.y.z
+ * Accepts only IPv6 connections on IPv6 sockets.
+ * If possible, we should open two sockets, but it is not always possible.
*/
if (family == AF_INET6)
setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){ 1 }, sizeof (int));
case SOCK_STREAM:
case SOCK_RDM:
case SOCK_SEQPACKET:
+#ifdef SOCK_DCCP
+ case SOCK_DCCP:
+#endif
if (listen (fd, INT_MAX))
{
msg_Err (p_this, "socket listen error (%s)",
}
-int net_ListenSingle (vlc_object_t *obj, const char *host, int port,
- int family, int socktype, int protocol)
-{
- int *fdv = net_Listen (obj, host, port, family, socktype, protocol);
- if (fdv == NULL)
- return -1;
-
- for (unsigned i = 1; fdv[i] != -1; i++)
- {
- msg_Warn (obj, "Multiple sockets opened. Dropping extra ones!");
- net_Close (fdv[i]);
- }
-
- int fd = fdv[0];
- assert (fd != -1);
-
- free (fdv);
- return fd;
-}
-
-
-
-/*****************************************************************************
- * __net_Close:
- *****************************************************************************
- * Close a network handle
- *****************************************************************************/
-void net_Close (int fd)
-{
-#ifdef UNDER_CE
- CloseHandle ((HANDLE)fd);
-#elif defined (WIN32)
- closesocket (fd);
-#else
- (void)close (fd);
-#endif
-}
-
-
static ssize_t
net_ReadInner (vlc_object_t *restrict p_this, unsigned fdc, const int *fdv,
const v_socket_t *const *restrict vsv,
- uint8_t *restrict p_buf, size_t i_buflen,
- vlc_bool_t dontwait, vlc_bool_t waitall)
+ uint8_t *restrict p_buf, size_t i_buflen, vlc_bool_t waitall)
{
size_t i_total = 0;
while (i_buflen > 0)
{
- if (p_this->b_die)
+ if( ( p_this->b_die ) || ( p_this->p_libvlc->b_die ) )
{
#if defined(WIN32) || defined(UNDER_CE)
- WSASetLastError(WSAEINTR);
+ WSASetLastError (WSAEINTR);
#else
errno = EINTR;
#endif
ufd[i].revents = 0;
}
- switch (poll (ufd, fdc, dontwait ? 0 : 500))
+ switch (poll (ufd, fdc, 500))
{
case -1:
goto error;
if (ufd[i].revents == 0)
continue;
+#ifndef POLLRDHUP /* This is nice but non-portable */
+# define POLLRDHUP 0
+#endif
if (i_total > 0)
{
// Errors (-1) and EOF (0) will be returned on next run
- if (ufd[i].revents & (POLLERR|POLLNVAL|POLLHUP))
+ if (ufd[i].revents & (POLLERR|POLLNVAL|POLLRDHUP))
return i_total;
}
else
{
- if (ufd[i].revents & POLLHUP)
+ if (ufd[i].revents & POLLRDHUP)
return 0; // EOF, read() would yield 0
}
fdc = 1;
fdv += i;
vsv += i;
+
break;
}
}
else
{
-#if defined(WIN32) || defined(UNDER_CE)
+#ifdef WIN32
n = recv (*fdv, p_buf, i_buflen, 0);
#else
n = read (*fdv, p_buf, i_buflen);
if (n == -1)
{
#if defined(WIN32) || defined(UNDER_CE)
- switch (WSAGetLastError())
+ switch (WSAGetLastError ())
{
case WSAEWOULDBLOCK:
/* only happens with vs != NULL (SSL) - not really an error */
goto error;
}
#else
- if (errno == EAGAIN) /* spurious wake-up (sucks if fdc > 1) */
+ /* spurious wake-up or TLS did not yield any actual data */
+ if (errno == EAGAIN)
continue;
goto error;
#endif
p_buf += n;
i_buflen -= n;
- if ((n == 0) || dontwait || !waitall)
+ if ((n == 0) || !waitall)
break;
}
return i_total;
{
return net_ReadInner( p_this, 1, &(int){ fd },
&(const v_socket_t *){ p_vs },
- buf, len, VLC_FALSE, b_retry );
-}
-
-
-/*****************************************************************************
- * __net_ReadNonBlock:
- *****************************************************************************
- * Read from a network socket, non blocking mode.
- * This function should only be used after a poll() (or select(), but you
- * should use poll instead of select()) invocation to avoid busy loops.
- *****************************************************************************/
-ssize_t __net_ReadNonBlock( vlc_object_t *restrict p_this, int fd,
- const v_socket_t *restrict p_vs,
- uint8_t *restrict buf, size_t len )
-{
- return net_ReadInner (p_this, 1, &(int){ fd },
- &(const v_socket_t *){ p_vs },
- buf, len, VLC_TRUE, VLC_FALSE);
+ buf, len, b_retry );
}
memset( vsv, 0, sizeof (vsv) );
return net_ReadInner( p_this, nfd, fds, vsv,
- buf, len, VLC_FALSE, VLC_FALSE );
+ buf, len, VLC_FALSE );
}
continue;
}
- if ((ufd[0].revents & POLLERR) && (i_total > 0))
+ if ((ufd[0].revents & (POLLERR|POLLNVAL|POLLHUP)) && (i_total > 0))
return i_total; // error will be dequeued separately on next call
if (p_vs != NULL)
val = p_vs->pf_send (p_vs->p_sys, p_data, i_data);
else
-#if defined(WIN32) || defined(UNDER_CE)
+#ifdef WIN32
val = send (fd, p_data, i_data, 0);
#else
val = write (fd, p_data, i_data);
msg_Err (p_this, "Write error: %s", net_strerror (net_errno));
break;
}
- if (val == 0)
- return i_total;
p_data += val;
i_data -= val;
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_addr = *((struct in6_addr*)src);
- if( 0 == WSAAddressToStringA((LPSOCKADDR)&addr,
- sizeof(struct sockaddr_in6),
+ if( 0 == WSAAddressToStringA((LPSOCKADDR)&addr,
+ sizeof(struct sockaddr_in6),
NULL, dst, &cnt) )
{
dst[cnt] = '\0';