Ejemplo n.º 1
0
static void
test_ipv6 (void)
{
  NiceAddress addr, other, v4addr;
  gchar str[NICE_ADDRESS_STRING_LEN];
  struct sockaddr_in6 sin, sin2;

  g_assert (nice_address_set_from_string (&v4addr, "172.1.0.1") == TRUE);

  memset (&sin, 0, sizeof (sin));
  memset (&sin2, 0, sizeof (sin2));

  memset (&addr, 0, sizeof (NiceAddress));
  memset (&other, 0, sizeof (NiceAddress));
  nice_address_init (&addr);
  nice_address_init (&other);
  nice_address_set_ipv6 (&addr, (guchar *)
      "\x00\x11\x22\x33"
      "\x44\x55\x66\x77"
      "\x88\x99\xaa\xbb"
      "\xcc\xdd\xee\xff");
  g_assert (addr.s.ip6.sin6_family == AF_INET6);

  nice_address_to_string (&addr, str);
  g_assert (0 == strcmp (str, "11:2233:4455:6677:8899:aabb:ccdd:eeff"));

  nice_address_set_port (&addr, 9876); /* in native byte order */
  nice_address_set_from_string (&other, "11:2233:4455:6677:8899:aabb:ccdd:eeff");
  nice_address_set_port (&other, 9876); /* in native byte order */

  nice_address_copy_to_sockaddr (&other, (struct sockaddr*)&sin2);
  nice_address_copy_to_sockaddr (&addr, (struct sockaddr*)&sin);
  g_assert (nice_address_equal (&addr, &other) == TRUE);
  nice_address_to_string (&addr, str);
  nice_address_to_string (&other, str);

  g_assert (memcmp (&sin, &sin2, sizeof(sin)) == 0);

  /* private IPv6 address */
  nice_address_set_ipv6 (&addr, (guchar *)
      "\xfc\x00\x00\x00"
      "\x00\x00\x00\x00"
      "\x00\x00\x00\x00"
      "\x00\x00\x00\x01");
  g_assert (nice_address_is_private (&addr) == TRUE);
  nice_address_set_ipv6 (&addr, (guchar *)
      "\x00\x00\x00\x00"
      "\x00\x00\x00\x00"
      "\x00\x00\x00\x00"
      "\x00\x00\x00\x01");
  g_assert (nice_address_is_private (&addr) == TRUE);

  /* mismatching address families */
  g_assert (nice_address_equal (&addr, &v4addr) != TRUE);

  /* mismatched type */
  addr.s.addr.sa_family = AF_UNSPEC;
  /*g_assert (nice_address_equal (&addr, &v4addr) != TRUE);*/
}
Ejemplo n.º 2
0
static gboolean
socket_send (NiceSocket *sock, const NiceAddress *to,
    guint len, const gchar *buf)
{
  struct sockaddr_storage sa;
  ssize_t sent;

  nice_address_copy_to_sockaddr (to, (struct sockaddr *)&sa);

  sent = sendto (sock->fileno, buf, len, 0, (struct sockaddr *) &sa,
      sa.ss_family == AF_INET? sizeof (struct sockaddr_in) :
      sizeof(struct sockaddr_in6));

  return sent == (ssize_t)len;
}
Ejemplo n.º 3
0
NiceSocket *
nice_tcp_bsd_socket_new (GMainContext *ctx, NiceAddress *addr)
{
  union {
    struct sockaddr_storage storage;
    struct sockaddr addr;
  } name;
  NiceSocket *sock;
  TcpPriv *priv;
  GSocket *gsock = NULL;
  GError *gerr = NULL;
  gboolean gret = FALSE;
  GSocketAddress *gaddr;

  if (addr == NULL) {
    /* We can't connect a tcp socket with no destination address */
    return NULL;
  }

  sock = g_slice_new0 (NiceSocket);

  nice_address_copy_to_sockaddr (addr, &name.addr);

  if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) {
    gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM,
        G_SOCKET_PROTOCOL_TCP, NULL);

    name.storage.ss_family = AF_INET;
#ifdef HAVE_SA_LEN
    name.storage.ss_len = sizeof (struct sockaddr_in);
#endif
  } else if (name.storage.ss_family == AF_INET6) {
    gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM,
        G_SOCKET_PROTOCOL_TCP, NULL);
    name.storage.ss_family = AF_INET6;
#ifdef HAVE_SA_LEN
    name.storage.ss_len = sizeof (struct sockaddr_in6);
#endif
  }

  if (gsock == NULL) {
    g_slice_free (NiceSocket, sock);
    return NULL;
  }

  gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name));
  if (gaddr == NULL) {
    g_object_unref (gsock);
    g_slice_free (NiceSocket, sock);
    return NULL;
  }

  /* GSocket: All socket file descriptors are set to be close-on-exec. */
  g_socket_set_blocking (gsock, false);

  gret = g_socket_connect (gsock, gaddr, NULL, &gerr);
  g_object_unref (gaddr);

  if (gret == FALSE) {
    if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_PENDING) == FALSE) {
      g_error_free (gerr);
      g_socket_close (gsock, NULL);
      g_object_unref (gsock);
      g_slice_free (NiceSocket, sock);
      return NULL;
    }
    g_error_free (gerr);
  }

  gaddr = g_socket_get_local_address (gsock, NULL);
  if (gaddr == NULL ||
      !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) {
    g_slice_free (NiceSocket, sock);
    g_socket_close (gsock, NULL);
    g_object_unref (gsock);
    return NULL;
  }
  g_object_unref (gaddr);

  nice_address_set_from_sockaddr (&sock->addr, &name.addr);

  sock->priv = priv = g_slice_new0 (TcpPriv);

  if (ctx == NULL)
    ctx = g_main_context_default ();
  priv->context = g_main_context_ref (ctx);
  priv->server_addr = *addr;
  priv->error = FALSE;

  sock->fileno = gsock;
  sock->send_messages = socket_send_messages;
  sock->recv_messages = socket_recv_messages;
  sock->is_reliable = socket_is_reliable;
  sock->close = socket_close;

  return sock;
}
Ejemplo n.º 4
0
NiceSocket *
nice_tcp_bsd_socket_new (GMainContext *ctx, NiceAddress *local_addr,
    NiceAddress *remote_addr, gboolean reliable)
{
  union {
    struct sockaddr_storage storage;
    struct sockaddr addr;
  } name;
  NiceSocket *sock;
  GSocket *gsock = NULL;
  GError *gerr = NULL;
  gboolean gret = FALSE;
  GSocketAddress *gaddr;

  if (remote_addr == NULL) {
    /* We can't connect a tcp socket with no destination address */
    return NULL;
  }

  nice_address_copy_to_sockaddr (remote_addr, &name.addr);

  if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) {
    gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM,
        G_SOCKET_PROTOCOL_TCP, NULL);

    name.storage.ss_family = AF_INET;
#ifdef HAVE_SA_LEN
    name.storage.ss_len = sizeof (struct sockaddr_in);
#endif
  } else if (name.storage.ss_family == AF_INET6) {
    gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM,
        G_SOCKET_PROTOCOL_TCP, NULL);
    name.storage.ss_family = AF_INET6;
#ifdef HAVE_SA_LEN
    name.storage.ss_len = sizeof (struct sockaddr_in6);
#endif
  }

  if (gsock == NULL) {
    return NULL;
  }

  gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name));
  if (gaddr == NULL) {
    g_object_unref (gsock);
    return NULL;
  }

  /* GSocket: All socket file descriptors are set to be close-on-exec. */
  g_socket_set_blocking (gsock, false);

  gret = g_socket_connect (gsock, gaddr, NULL, &gerr);
  g_object_unref (gaddr);

  if (gret == FALSE) {
    if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_PENDING) == FALSE) {
      g_error_free (gerr);
      g_socket_close (gsock, NULL);
      g_object_unref (gsock);
      return NULL;
    }
    g_error_free (gerr);
  }

  nice_address_copy_to_sockaddr (local_addr, &name.addr);
  gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name));
  if (gaddr == NULL) {
    g_socket_close (gsock, NULL);
    g_object_unref (gsock);
    return NULL;
  }
  g_socket_bind (gsock, gaddr, FALSE, NULL);
  g_object_unref (gaddr);

  sock = nice_tcp_bsd_socket_new_from_gsock (ctx, gsock, local_addr, remote_addr,
      reliable);
  g_object_unref (gsock);

  return sock;
}
Ejemplo n.º 5
0
NiceSocket *
nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr)
{
  union {
    struct sockaddr_storage storage;
    struct sockaddr addr;
  } name;
  NiceSocket *sock;
  TcpPassivePriv *priv;
  GSocket *gsock = NULL;
  gboolean gret = FALSE;
  GSocketAddress *gaddr;

  if (addr != NULL) {
    nice_address_copy_to_sockaddr(addr, &name.addr);
  } else {
    memset (&name, 0, sizeof (name));
    name.storage.ss_family = AF_UNSPEC;
  }

  if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) {
    gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM,
        G_SOCKET_PROTOCOL_TCP, NULL);

    name.storage.ss_family = AF_INET;
#ifdef HAVE_SA_LEN
    name.storage.ss_len = sizeof (struct sockaddr_in);
#endif
  } else if (name.storage.ss_family == AF_INET6) {
    gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM,
        G_SOCKET_PROTOCOL_TCP, NULL);
    name.storage.ss_family = AF_INET6;
#ifdef HAVE_SA_LEN
    name.storage.ss_len = sizeof (struct sockaddr_in6);
#endif
  }

  if (gsock == NULL) {
    return NULL;
  }

  gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name));

  if (gaddr == NULL) {
    g_object_unref (gsock);
    return NULL;
  }

  /* GSocket: All socket file descriptors are set to be close-on-exec. */
  g_socket_set_blocking (gsock, false);

  gret = g_socket_bind (gsock, gaddr, FALSE, NULL) &&
      g_socket_listen (gsock, NULL);
  g_object_unref (gaddr);

  if (gret == FALSE) {
    g_socket_close (gsock, NULL);
    g_object_unref (gsock);
    return NULL;
  }

  gaddr = g_socket_get_local_address (gsock, NULL);
  if (gaddr == NULL ||
      !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) {
    g_socket_close (gsock, NULL);
    g_object_unref (gsock);
    return NULL;
  }
  g_object_unref (gaddr);

  if (ctx == NULL) {
    ctx = g_main_context_default ();
  }

  sock = g_slice_new0 (NiceSocket);

  nice_address_set_from_sockaddr (&sock->addr, &name.addr);

  sock->priv = priv = g_slice_new0 (TcpPassivePriv);
  priv->context = g_main_context_ref (ctx);
  priv->connections = g_hash_table_new_full ((GHashFunc) nice_address_hash,
      (GEqualFunc) nice_address_equal, (
          GDestroyNotify) nice_address_free, NULL);
  priv->writable_cb = NULL;
  priv->writable_data = NULL;

  sock->type = NICE_SOCKET_TYPE_TCP_PASSIVE;
  sock->fileno = gsock;
  sock->send_messages = socket_send_messages;
  sock->send_messages_reliable = socket_send_messages_reliable;
  sock->recv_messages = socket_recv_messages;
  sock->is_reliable = socket_is_reliable;
  sock->can_send = socket_can_send;
  sock->set_writable_callback = socket_set_writable_callback;
  sock->close = socket_close;

  return sock;
}
Ejemplo n.º 6
0
NiceSocket *
nice_udp_bsd_socket_new (NiceAddress *addr)
{
  int sockfd = -1;
  struct sockaddr_storage name;
  socklen_t name_len = sizeof (name);
  NiceSocket *sock = g_slice_new0 (NiceSocket);

  if (addr != NULL) {
    nice_address_copy_to_sockaddr(addr, (struct sockaddr *)&name);
  } else {
    memset (&name, 0, sizeof (name));
    name.ss_family = AF_UNSPEC;
  }

  if (name.ss_family == AF_UNSPEC || name.ss_family == AF_INET) {
    sockfd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    name.ss_family = AF_INET;
#ifdef HAVE_SA_LEN
    name.ss_len = sizeof (struct sockaddr_in);
#endif
  } else if (name.ss_family == AF_INET6) {
    sockfd = socket (PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    name.ss_family = AF_INET6;
#ifdef HAVE_SA_LEN
    name.ss_len = sizeof (struct sockaddr_in6);
#endif
  }

  if (sockfd == -1) {
    g_slice_free (NiceSocket, sock);
    return NULL;
  }

#ifdef FD_CLOEXEC
  fcntl (sockfd, F_SETFD, fcntl (sockfd, F_GETFD) | FD_CLOEXEC);
#endif
#ifdef O_NONBLOCK
  fcntl (sockfd, F_SETFL, fcntl (sockfd, F_GETFL) | O_NONBLOCK);
#endif

  if(bind (sockfd, (struct sockaddr *) &name,
          name.ss_family == AF_INET? sizeof (struct sockaddr_in) :
          sizeof(struct sockaddr_in6)) < 0) {
    g_slice_free (NiceSocket, sock);
#ifdef G_OS_WIN32
    closesocket(sockfd);
#else
    close (sockfd);
#endif
    return NULL;
  }

  name_len = name.ss_family == AF_INET? sizeof (struct sockaddr_in) :
      sizeof(struct sockaddr_in6);
  if (getsockname (sockfd, (struct sockaddr *) &name, &name_len) < 0) {
    g_slice_free (NiceSocket, sock);
#ifdef G_OS_WIN32
    closesocket(sockfd);
#else
    close (sockfd);
#endif
    return NULL;
  }

  nice_address_set_from_sockaddr (&sock->addr, (struct sockaddr *)&name);
  sock->fileno = sockfd;

  sock->send = socket_send;
  sock->recv = socket_recv;
  sock->is_reliable = socket_is_reliable;
  sock->close = socket_close;

  return sock;
}