Esempio n. 1
0
static gint socket_send_messages_reliable (NiceSocket *sock,
    const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages)
{
  TcpPassivePriv *priv = sock->priv;

  if (to) {
    NiceSocket *peer_socket = g_hash_table_lookup (priv->connections, to);
    if (peer_socket)
      return nice_socket_send_messages_reliable (peer_socket, to, messages,
          n_messages);
  }
  return -1;
}
static gint
socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to,
    const NiceOutputMessage *messages, guint n_messages)
{
  PseudoSSLPriv *priv = sock->priv;

  if (priv->handshaken) {
    /* Fast path: pass directly through to the base socket once the handshake is
     * complete. */
    if (priv->base_socket == NULL)
      return -1;

    return nice_socket_send_messages_reliable (priv->base_socket, to, messages,
        n_messages);
  } else {
    nice_socket_queue_send (&priv->send_queue, to, messages, n_messages);
  }
  return n_messages;
}
Esempio n. 3
0
static gint
socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to,
    const NiceOutputMessage *messages, guint n_messages)
{
  HttpPriv *priv = sock->priv;

  if (priv->state == HTTP_STATE_CONNECTED) {
    /* Fast path. */
    if (!priv->base_socket)
      return -1;

    return nice_socket_send_messages_reliable (priv->base_socket, to, messages,
        n_messages);
  } else if (priv->state == HTTP_STATE_ERROR) {
    return -1;
  } else {
    nice_socket_queue_send (&priv->send_queue, to, messages, n_messages);
  }

  return n_messages;
}
Esempio n. 4
0
NiceSocket *
nice_http_socket_new (NiceSocket *base_socket,
    NiceAddress *addr, gchar *username, gchar *password)
{
  HttpPriv *priv;
  NiceSocket *sock = NULL;

  if (addr) {
    sock = g_slice_new0 (NiceSocket);
    sock->priv = priv = g_slice_new0 (HttpPriv);

    priv->base_socket = base_socket;
    priv->addr = *addr;
    priv->username = g_strdup (username);
    priv->password = g_strdup (password);
    priv->recv_buf = NULL;
    priv->recv_buf_length = 0;
    priv->recv_buf_pos = 0;
    priv->recv_buf_fill = 0;
    priv->content_length = 0;

    sock->type = NICE_SOCKET_TYPE_HTTP;
    sock->fileno = priv->base_socket->fileno;
    sock->addr = priv->base_socket->addr;
    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;

    /* Send HTTP CONNECT */
    {
      gchar *msg = NULL;
      gchar *credential = NULL;
      gchar host[INET6_ADDRSTRLEN];
      gint port = nice_address_get_port (&priv->addr);
      GOutputVector local_bufs;
      NiceOutputMessage local_messages;

      nice_address_to_string (&priv->addr, host);

      if (username) {
        gchar * userpass = g_strdup_printf ("%s:%s", username,
            password ? password : "");
        gchar * auth = g_base64_encode ((guchar *)userpass, strlen (userpass));
        credential = g_strdup_printf ("Proxy-Authorization: Basic %s\r\n", auth);
        g_free (auth);
        g_free (userpass);
      }
      msg = g_strdup_printf ("CONNECT %s:%d HTTP/1.0\r\n"
          "Host: %s\r\n"
          "User-Agent: %s\r\n"
          "Content-Length: 0\r\n"
          "Proxy-Connection: Keep-Alive\r\n"
          "Connection: Keep-Alive\r\n"
          "Cache-Control: no-cache\r\n"
          "Pragma: no-cache\r\n"
          "%s\r\n", host, port, host, HTTP_USER_AGENT,
          credential? credential : "" );
      g_free (credential);

      local_bufs.buffer = msg;
      local_bufs.size = strlen (msg);
      local_messages.buffers = &local_bufs;
      local_messages.n_buffers = 1;

      nice_socket_send_messages_reliable (priv->base_socket, NULL,
          &local_messages, 1);
      priv->state = HTTP_STATE_INIT;
      g_free (msg);
    }
  }

  return sock;
}
Esempio n. 5
0
static gssize
socket_send_message (NiceSocket *sock, const NiceAddress *to,
    const NiceOutputMessage *message, gboolean reliable)
{
  TurnTcpPriv *priv = sock->priv;
  guint8 padbuf[3] = {0, 0, 0};
  GOutputVector *local_bufs;
  NiceOutputMessage local_message;
  guint j;
  gint ret;
  guint n_bufs;
  union {
    guint16 google_len;
    struct {
      guint8 pt;
      guint8 zero;
    } msoc;
  } header_buf;
  guint offset = 0;

  /* Socket has been closed: */
  if (sock->priv == NULL)
    return -1;

  /* Count the number of buffers. */
  if (message->n_buffers == -1) {
    n_bufs = 0;

    for (j = 0; message->buffers[j].buffer != NULL; j++)
      n_bufs++;
  } else {
    n_bufs = message->n_buffers;
  }

  /* Allocate a new array of buffers, covering all the buffers in the input
   * @message, but with an additional one for a header and one for a footer. */
  local_bufs = g_malloc_n (n_bufs + 1, sizeof (GOutputVector));
  local_message.buffers = local_bufs;
  local_message.n_buffers = n_bufs + 1;

  if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
    header_buf.google_len = htons (output_message_get_size (message));
    local_bufs[0].buffer = &header_buf;
    local_bufs[0].size = sizeof (guint16);
    offset = 1;
  } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
      priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
    gsize message_len = output_message_get_size (message);
    gsize padlen = (message_len % 4) ? 4 - (message_len % 4) : 0;

    local_bufs[n_bufs].buffer = &padbuf;
    local_bufs[n_bufs].size = padlen;
  } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) {
    union {
      guint32 u32;
      guint8 u8[4];
    } cookie;
    guint16 len = output_message_get_size (message);

    /* Copy the cookie from possibly split messages */
    cookie.u32 = 0;
    if (len > sizeof (TURN_MAGIC_COOKIE) + MAGIC_COOKIE_OFFSET) {
      guint16 buf_offset = 0;
      guint i;

      for (i = 0; i < n_bufs; i++) {
        if (message->buffers[i].size >
            (gsize) (MAGIC_COOKIE_OFFSET - buf_offset)) {
          /* If the cookie is split, we assume it's data */
          if (message->buffers[i].size > sizeof (TURN_MAGIC_COOKIE) +
              MAGIC_COOKIE_OFFSET - buf_offset) {
            const guint8 *buf = message->buffers[i].buffer;
            memcpy (&cookie.u8, buf + MAGIC_COOKIE_OFFSET - buf_offset,
                sizeof (TURN_MAGIC_COOKIE));
          }
          break;
        } else {
          buf_offset += message->buffers[i].size;
        }
      }
    }

    cookie.u32 = ntohl(cookie.u32);
    header_buf.msoc.zero = 0;
    if (cookie.u32 == TURN_MAGIC_COOKIE)
      header_buf.msoc.pt = MS_TURN_CONTROL_MESSAGE;
    else
      header_buf.msoc.pt = MS_TURN_END_TO_END_DATA;

    local_bufs[0].buffer = &header_buf;
    local_bufs[0].size = sizeof(header_buf.msoc);
    offset = 1;
  } else {
    local_message.n_buffers = n_bufs;
  }

  /* Copy the existing buffers across. */
  for (j = 0; j < n_bufs; j++) {
    local_bufs[j + offset].buffer = message->buffers[j].buffer;
    local_bufs[j + offset].size = message->buffers[j].size;
  }


  if (reliable)
    ret = nice_socket_send_messages_reliable (priv->base_socket, to,
        &local_message, 1);
  else
    ret = nice_socket_send_messages (priv->base_socket, to, &local_message, 1);

  if (ret == 1)
    ret = output_message_get_size (&local_message);

  g_free (local_bufs);

  return ret;
}