static void write_to_sock (PseudoTcpSocket *sock)
{
  gchar buf[1024];
  gsize len;
  gint wlen;
  guint total = 0;

  while (TRUE) {
    len = fread (buf, 1, sizeof(buf), in);
    if (len == 0) {
      g_debug ("Done reading data from file");
      g_assert (feof (in));
      reading_done = TRUE;
      pseudo_tcp_socket_close (sock, FALSE);
      break;
    } else {
      wlen = pseudo_tcp_socket_send (sock, buf, len);
      g_debug ("Sending %" G_GSIZE_FORMAT " bytes : %d", len, wlen);
      total += wlen;
      total_read += wlen;
      if (wlen < (gint) len) {
        g_debug ("seeking  %ld from %lu", wlen - len, ftell (in));
        fseek (in, wlen - len, SEEK_CUR);
        g_assert (!feof (in));
        g_debug ("Socket queue full after %d bytes written", total);
        break;
      }
    }
  }
  adjust_clock (sock);
}
static void readable (PseudoTcpSocket *sock, gpointer data)
{
  gchar buf[1024];
  gint len;
  g_debug ("Socket %p Readable", sock);

  do {
    len = pseudo_tcp_socket_recv (sock, buf, sizeof(buf));

    if (len > 0) {
      g_debug ("Read %d bytes", len);
      if (out) {
        if (fwrite (buf, len, 1, out) == 0)
          g_debug ("Error writing to output file");
        else {
          total_wrote += len;

          g_assert (total_wrote <= total_read);
          g_debug ("Written %d bytes, need %d bytes", total_wrote, total_read);
          if (total_wrote == total_read && feof (in)) {
            g_assert (reading_done);
            pseudo_tcp_socket_close (sock, FALSE);
          }
        }
      } else {
        if (len == 26 && strncmp (buf, "abcdefghijklmnopqrstuvwxyz", len) == 0) {
          pseudo_tcp_socket_close (sock, FALSE);
        } else {
          g_debug ("Error reading data.. read %d bytes : %s", len, buf);
          exit (-1);
        }
      }
    } else if (len == 0) {
      pseudo_tcp_socket_close (sock, FALSE);
    }
  } while (len > 0);

  if (len == -1 &&
      pseudo_tcp_socket_get_error (sock) != EWOULDBLOCK) {
    g_debug ("Error reading from socket %p: %s", sock,
        g_strerror (pseudo_tcp_socket_get_error (sock)));
    exit (-1);
  }
}
Пример #3
0
static void
readable (PseudoTcpSocket *sock, gpointer data)
{
  gchar buf[1024];
  gint len;
  g_debug ("Socket %p Readable", sock);

  do {
    len = pseudo_tcp_socket_recv (sock, buf, sizeof(buf));

    if (len > 0) {
      g_debug ("Read %d bytes", len);
      if (out) {
        if (fwrite (buf, len, 1, out) == 0)
          g_debug ("Error writing to output file");
        else {
          total_wrote += len;

          g_assert (total_wrote <= total_read);
          g_debug ("Written %d bytes, need %d bytes", total_wrote, total_read);
          if (total_wrote == total_read && feof (in)) {
            g_assert (reading_done);
            pseudo_tcp_socket_close (sock, FALSE);
          }
        }
      } else {
        pseudo_tcp_socket_close (sock, FALSE);
      }
    } else if (len == 0) {
      pseudo_tcp_socket_close (sock, FALSE);
    }
  } while (len > 0);

  if (len == -1 &&
      pseudo_tcp_socket_get_error (sock) != EWOULDBLOCK) {
    g_printerr ("Error reading from socket %p: %s.\n",
        sock, g_strerror (pseudo_tcp_socket_get_error (sock)));

    retval = -1;
    g_main_loop_quit (main_loop);
    return;
  }
}
static void opened (PseudoTcpSocket *sock, gpointer data)
{
  g_debug ("Socket %p Opened", sock);
  if (sock == left) {
    if (in)
      write_to_sock (sock);
    else {
      pseudo_tcp_socket_send (sock, "abcdefghijklmnopqrstuvwxyz", 26);
      reading_done = TRUE;
      pseudo_tcp_socket_close (sock, FALSE);
    }
  }
}
Пример #5
0
void
component_free (Component *cmp)
{
  GSList *i;
  GList *item;

  for (i = cmp->local_candidates; i; i = i->next) {
    NiceCandidate *candidate = i->data;
    nice_candidate_free (candidate);
  }

  for (i = cmp->remote_candidates; i; i = i->next) {
    NiceCandidate *candidate = i->data;
    nice_candidate_free (candidate);
  }

  if (cmp->restart_candidate)
    nice_candidate_free (cmp->restart_candidate),
      cmp->restart_candidate = NULL;

  for (i = cmp->sockets; i; i = i->next) {
    NiceSocket *udpsocket = i->data;
    nice_socket_free (udpsocket);
  }

  for (i = cmp->gsources; i; i = i->next) {
    GSource *source = i->data;
    g_source_destroy (source);
    g_source_unref (source);
  }
 
  for (i = cmp->incoming_checks; i; i = i->next) {
    IncomingCheck *icheck = i->data;
    g_free (icheck->username);
    g_slice_free (IncomingCheck, icheck);
  }

  g_slist_free (cmp->local_candidates);
  g_slist_free (cmp->remote_candidates);
  g_slist_free (cmp->sockets);
  g_slist_free (cmp->gsources);
  g_slist_free (cmp->incoming_checks);

  for (item = cmp->turn_servers; item; item = g_list_next (item)) {
    TurnServer *turn = item->data;
    g_free (turn->username);
    g_free (turn->password);
    g_slice_free (TurnServer, turn);
  }
  g_list_free (cmp->turn_servers);

  if (cmp->selected_pair.keepalive.tick_source != NULL) {
    g_source_destroy (cmp->selected_pair.keepalive.tick_source);
    g_source_unref (cmp->selected_pair.keepalive.tick_source);
    cmp->selected_pair.keepalive.tick_source = NULL;
  }

  if (cmp->tcp_clock) {
    g_source_destroy (cmp->tcp_clock);
    g_source_unref (cmp->tcp_clock);
    cmp->tcp_clock = NULL;
  }
  if (cmp->tcp) {
    pseudo_tcp_socket_close (cmp->tcp, TRUE);
    g_object_unref (cmp->tcp);
    cmp->tcp = NULL;
  }
  if (cmp->tcp_data != NULL) {
    g_slice_free (TcpUserData, cmp->tcp_data);
    cmp->tcp_data = NULL;
  }

  g_slice_free (Component, cmp);
}
Пример #6
0
/* Must be called with the agent lock held as it touches internal Component
 * state. */
void
nice_component_close (NiceComponent *cmp)
{
  IOCallbackData *data;
  GOutputVector *vec;

  /* Start closing the pseudo-TCP socket first. FIXME: There is a very big and
   * reliably triggerable race here. pseudo_tcp_socket_close() does not block
   * on the socket closing — it only sends the first packet of the FIN
   * handshake. nice_component_close() will immediately afterwards close the
   * underlying component sockets, aborting the handshake.
   *
   * On the principle that starting the FIN handshake is better than not
   * starting it, even if it’s later truncated, call pseudo_tcp_socket_close().
   * A long-term fix is needed in the form of making nice_component_close() (and
   * all its callers) async, so we can properly block on closure. */
  if (cmp->tcp) {
    pseudo_tcp_socket_close (cmp->tcp, TRUE);
  }

  if (cmp->restart_candidate)
    nice_candidate_free (cmp->restart_candidate),
      cmp->restart_candidate = NULL;

  if (cmp->turn_candidate)
    nice_candidate_free (cmp->turn_candidate),
        cmp->turn_candidate = NULL;

  while (cmp->local_candidates) {
    agent_remove_local_candidate (cmp->agent, cmp->local_candidates->data);
    nice_candidate_free (cmp->local_candidates->data);
    cmp->local_candidates = g_slist_delete_link (cmp->local_candidates,
        cmp->local_candidates);
  }

  g_slist_free_full (cmp->remote_candidates,
      (GDestroyNotify) nice_candidate_free);
  cmp->remote_candidates = NULL;
  nice_component_free_socket_sources (cmp);
  g_slist_free_full (cmp->incoming_checks,
      (GDestroyNotify) incoming_check_free);
  cmp->incoming_checks = NULL;

  nice_component_clean_turn_servers (cmp);

  if (cmp->tcp_clock) {
    g_source_destroy (cmp->tcp_clock);
    g_source_unref (cmp->tcp_clock);
    cmp->tcp_clock = NULL;
  }
  if (cmp->tcp_writable_cancellable) {
    g_cancellable_cancel (cmp->tcp_writable_cancellable);
    g_clear_object (&cmp->tcp_writable_cancellable);
  }

  while ((data = g_queue_pop_head (&cmp->pending_io_messages)) != NULL)
    io_callback_data_free (data);

  nice_component_deschedule_io_callback (cmp);

  g_cancellable_cancel (cmp->stop_cancellable);

  while ((vec = g_queue_pop_head (&cmp->queued_tcp_packets)) != NULL) {
    g_free ((gpointer) vec->buffer);
    g_slice_free (GOutputVector, vec);
  }
}