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); } }
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); } } }
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); }
/* 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); } }