Exemple #1
0
udp_connection_t *
udp_bind ( const char *subsystem, const char *name,
           const char *bindaddr, int port,
           const char *ifname, int rxsize )
{
  int fd, ifindex, reuse = 1;
  udp_connection_t *uc;
  char buf[256];
  socklen_t addrlen;

  uc = calloc(1, sizeof(udp_connection_t));
  uc->fd                   = -1;
  uc->host                 = bindaddr ? strdup(bindaddr) : NULL;
  uc->port                 = port;
  uc->ifname               = ifname ? strdup(ifname) : NULL;
  uc->subsystem            = subsystem ? strdup(subsystem) : NULL;
  uc->name                 = name ? strdup(name) : NULL;
  uc->rxtxsize             = rxsize;

  if (udp_resolve(uc, 1) < 0) {
    udp_close(uc);
    return UDP_FATAL_ERROR;
  }

  /* Open socket */
  if ((fd = tvh_socket(uc->ip.ss_family, SOCK_DGRAM, 0)) == -1) {
    tvherror(subsystem, "%s - failed to create socket [%s]",
             name, strerror(errno));
    udp_close(uc);
    return UDP_FATAL_ERROR;
  }

  /* Mark reuse address */
  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

  /* Bind to interface */
  ifindex = udp_ifindex_required(uc) ? udp_get_ifindex(ifname) : 0;
  if (ifindex < 0) {
    tvherror(subsystem, "%s - could not find interface %s",
             name, ifname);
    goto error;
  }

  /* IPv4 */
  if (uc->ip.ss_family == AF_INET) {
#if defined(PLATFORM_DARWIN)
    struct ip_mreq       m;
#else
    struct ip_mreqn      m;
#endif
    memset(&m,   0, sizeof(m));

    /* Bind */
    if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in)) == -1) {
      inet_ntop(AF_INET, &IP_AS_V4(uc->ip, addr), buf, sizeof(buf));
      tvherror(subsystem, "%s - cannot bind %s:%hu [e=%s]",
               name, buf, ntohs(IP_AS_V4(uc->ip, port)), strerror(errno));
      goto error;
    }

    if (uc->multicast) {
      /* Join group */
      m.imr_multiaddr      = IP_AS_V4(uc->ip, addr);
#if !defined(PLATFORM_DARWIN)
      m.imr_address.s_addr = 0;
      m.imr_ifindex        = ifindex;
#else
      if (udp_get_ifaddr(fd, ifname, &m.imr_interface) == -1) {
        tvherror(subsystem, "%s - cannot find ip address for interface %s [e=%s]",
                 name, ifname,  strerror(errno));
        goto error;
      }
#endif

      if (setsockopt(fd, udp_get_solip(), IP_ADD_MEMBERSHIP, &m, sizeof(m))) {
        inet_ntop(AF_INET, &m.imr_multiaddr, buf, sizeof(buf));
        tvhwarn(subsystem, "%s - cannot join %s [%s]",
                name, buf, strerror(errno));
      }
   }

  /* Bind to IPv6 group */
  } else {
    struct ipv6_mreq m;
    memset(&m,   0, sizeof(m));

    /* Bind */
    if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in6)) == -1) {
      inet_ntop(AF_INET6, &IP_AS_V6(uc->ip, addr), buf, sizeof(buf));
      tvherror(subsystem, "%s - cannot bind %s:%hu [e=%s]",
               name, buf, ntohs(IP_AS_V6(uc->ip, port)), strerror(errno));
      goto error;
    }

    if (uc->multicast) {
      /* Join group */
      m.ipv6mr_multiaddr = IP_AS_V6(uc->ip, addr);
      m.ipv6mr_interface = ifindex;
#ifdef SOL_IPV6
      if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &m, sizeof(m))) {
        inet_ntop(AF_INET, &m.ipv6mr_multiaddr, buf, sizeof(buf));
        tvhwarn(subsystem, "%s - cannot join %s [%s]",
                name, buf, strerror(errno));
      }
#else
      tvherror(subsystem, "IPv6 multicast not supported");
      goto error;
#endif
    }
  }

  addrlen = sizeof(uc->ip);
  getsockname(fd, (struct sockaddr *)&uc->ip, &addrlen);
    
  /* Increase RX buffer size */
  if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rxsize, sizeof(rxsize)) == -1)
    tvhwarn(subsystem, "%s - cannot increase UDP rx buffer size [%s]",
            name, strerror(errno));

  uc->fd = fd;
  return uc;

error:
  udp_close(uc);
  return NULL;
}
Exemple #2
0
udp_connection_t *
udp_sendinit ( const char *subsystem, const char *name,
               const char *ifname, int txsize )
{
  int fd, ifindex;
  udp_connection_t *uc;

  uc = calloc(1, sizeof(udp_connection_t));
  uc->fd                   = -1;
  uc->ifname               = ifname ? strdup(ifname) : NULL;
  uc->subsystem            = subsystem ? strdup(subsystem) : NULL;
  uc->name                 = name ? strdup(name) : NULL;
  uc->rxtxsize             = txsize;

  /* Open socket */
  if ((fd = tvh_socket(uc->ip.ss_family, SOCK_DGRAM, 0)) == -1) {
    tvherror(subsystem, "%s - failed to create socket [%s]",
             name, strerror(errno));
    udp_close(uc);
    return UDP_FATAL_ERROR;
  }

  uc->fd = fd;

  /* Bind to interface */
  ifindex = udp_ifindex_required(uc) ? udp_get_ifindex(ifname) : 0;
  if (ifindex < 0) {
    tvherror(subsystem, "%s - could not find interface %s",
             name, ifname);
    goto error;
  }

  if (uc->multicast) {
    if (uc->ip.ss_family == AF_INET) {
#if !defined(PLATFORM_DARWIN)
      struct ip_mreqn m;
      memset(&m, 0, sizeof(m));
      m.imr_ifindex = ifindex;
#else
      struct in_addr m;
      if (udp_get_ifaddr(fd, ifname, &m) == -1) {
        tvherror(subsystem, "%s - cannot find ip address for interface %s [e=%s]",
                 name, ifname,  strerror(errno));
        goto error;
      }
#endif
      if (setsockopt(fd, udp_get_solip(), IP_MULTICAST_IF, &m, sizeof(m)))
        tvhwarn(subsystem, "%s - cannot set source interface %s [%s]",
                name, ifname, strerror(errno));
    } else {
      struct ipv6_mreq m;
      memset(&m,   0, sizeof(m));
      m.ipv6mr_interface = ifindex;
#ifdef SOL_IPV6
      if (setsockopt(fd, SOL_IPV6, IPV6_MULTICAST_IF, &m, sizeof(m))) {
        tvhwarn(subsystem, "%s - cannot set source interface %s [%s]",
                name, ifname, strerror(errno));
      }
#else
      tvherror(subsystem, "IPv6 multicast not supported");
      goto error;
#endif
    }
  }

  /* Increase TX buffer size */
  if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &txsize, sizeof(txsize)) == -1)
    tvhwarn(subsystem, "%s - cannot increase UDP tx buffer size [%s]",
            name, strerror(errno));

  return uc;

error:
  udp_close(uc);
  return NULL;
}