diff --git a/src/network.c b/src/network.c
index 546f5e2d142ad46d03548a5410d5c139ba361018..ddc36e772176aa57715471ff652ebb7c5229d82a 100644 (file)
--- a/src/network.c
+++ b/src/network.c
#include "common.h"
#include "utils_debug.h"
-/*
- * From RFC2365:
- *
- * The IPv4 Organization Local Scope -- 239.192.0.0/14
- *
- * 239.192.0.0/14 is defined to be the IPv4 Organization Local Scope, and is
- * the space from which an organization should allocate sub-ranges when
- * defining scopes for private use.
- *
- * Port 25826 is not assigned as of 2005-09-12
- */
-
-#define IPV4_MCAST_GROUP "239.192.74.66"
-#define UDP_PORT 25826
-
/* 1500 - 40 - 8 = Ethernet packet - IPv6 header - UDP header */
/* #define BUFF_SIZE 1452 */
typedef struct sockent
{
int fd;
+ int mode;
struct sockaddr_storage *addr;
socklen_t addrlen;
struct sockent *next;
{
int loop = 1;
+ DBG ("fd = %i; calling `bind'", se->fd);
+
if (bind (se->fd, ai->ai_addr, ai->ai_addrlen) == -1)
{
syslog (LOG_ERR, "bind: %s", strerror (errno));
{
struct ip_mreq mreq;
+ DBG ("fd = %i; IPv4 multicast address found", se->fd);
+
mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
mreq.imr_interface.s_addr = htonl (INADDR_ANY);
{
struct ipv6_mreq mreq;
+ DBG ("fd = %i; IPv6 multicast address found", se->fd);
+
memcpy (&mreq.ipv6mr_multiaddr,
&addr->sin6_addr,
sizeof (addr->sin6_addr));
memcpy (se->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
se->addrlen = ai_ptr->ai_addrlen;
+ se->mode = operating_mode;
se->fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
se->next = NULL;
if (socklist_tail == NULL)
{
- socklist_head = socklist_tail = se;
+ socklist_head = se;
+ socklist_tail = se;
}
else
{
return (num_added);
}
+static int network_connect_default (void)
+{
+ int ret;
+
+ if (socklist_head != NULL)
+ return (0);
+
+ DBG ("socklist_head is NULL");
+
+ ret = 0;
+
+ if (network_create_socket (NET_DEFAULT_V6_ADDR, NET_DEFAULT_PORT) > 0)
+ ret++;
+
+ /* Don't use IPv4 and IPv6 in parallel by default.. */
+ if ((operating_mode == MODE_CLIENT) && (ret != 0))
+ return (ret);
+
+ if (network_create_socket (NET_DEFAULT_V4_ADDR, NET_DEFAULT_PORT) > 0)
+ ret++;
+
+ if (ret == 0)
+ ret = -1;
+
+ return (ret);
+}
+
static int network_get_listen_socket (void)
{
int fd;
fd_set readfds;
sockent_t *se;
- while (1)
+ if (socklist_head == NULL)
+ network_connect_default ();
+
+ FD_ZERO (&readfds);
+ max_fd = -1;
+ for (se = socklist_head; se != NULL; se = se->next)
{
- FD_ZERO (&readfds);
- max_fd = -1;
- for (se = socklist_head; se != NULL; se = se->next)
- {
- FD_SET (se->fd, &readfds);
- if (se->fd >= max_fd)
- max_fd = se->fd + 1;
- }
+ if (se->mode != operating_mode)
+ continue;
- if (max_fd == -1)
- {
- syslog (LOG_WARNING, "No listen sockets found!");
- return (-1);
- }
+ FD_SET (se->fd, &readfds);
+ if (se->fd >= max_fd)
+ max_fd = se->fd + 1;
+ }
- status = select (max_fd, &readfds, NULL, NULL, NULL);
+ if (max_fd == -1)
+ {
+ syslog (LOG_WARNING, "No listen sockets found!");
+ return (-1);
+ }
- if ((status == -1) && (errno == EINTR))
- continue;
- else if (status == -1)
- {
+ status = select (max_fd, &readfds, NULL, NULL, NULL);
+
+ if (status == -1)
+ {
+ if (errno != EINTR)
syslog (LOG_ERR, "select: %s", strerror (errno));
- return (-1);
- }
- else
- break;
- } /* while (true) */
+ return (-1);
+ }
fd = -1;
for (se = socklist_head; se != NULL; se = se->next)
+ {
+ if (se->mode != operating_mode)
+ continue;
+
if (FD_ISSET (se->fd, &readfds))
{
fd = se->fd;
break;
}
+ }
if (fd == -1)
syslog (LOG_WARNING, "No socket ready..?");
buf[buflen] = '\0';
buflen++;
+ if (socklist_head == NULL)
+ network_connect_default ();
+
ret = 0;
for (se = socklist_head; se != NULL; se = se->next)
{
+ if (se->mode != operating_mode)
+ continue;
+
DBG ("fd = %i", se->fd);
while (1)
else
{
syslog (LOG_ERR, "sendto: %s", strerror (errno));
+ ret = -1;
break;
}
}