Commit 67179ffd authored by Philip Withnall's avatar Philip Withnall

agent: Add missing stream-closed checks for pseudo-TCP

This got lost in rebasing the FIN–ACK work. component->tcp is now only
NULL before the pseudo-TCP stream is initially created — afterwards, it
is always non-NULL, but pseudo_tcp_stream_is_closed() returns TRUE if
the stream has closed (gracefully or on errors). This allows
differentiation between the states: TCP support was never initialised;
and TCP support was initialised but is now closed.
parent 7b6935c6
...@@ -1625,7 +1625,7 @@ pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data) ...@@ -1625,7 +1625,7 @@ pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data)
nice_debug ("Stream or Component disappeared during the callback"); nice_debug ("Stream or Component disappeared during the callback");
goto out; goto out;
} }
if (!component->tcp) { if (pseudo_tcp_socket_is_closed (component->tcp)) {
nice_debug ("PseudoTCP socket got destroyed in readable callback!"); nice_debug ("PseudoTCP socket got destroyed in readable callback!");
goto out; goto out;
} }
...@@ -1769,7 +1769,7 @@ notify_pseudo_tcp_socket_clock (gpointer user_data) ...@@ -1769,7 +1769,7 @@ notify_pseudo_tcp_socket_clock (gpointer user_data)
static void static void
adjust_tcp_clock (NiceAgent *agent, Stream *stream, Component *component) adjust_tcp_clock (NiceAgent *agent, Stream *stream, Component *component)
{ {
if (component->tcp) { if (!pseudo_tcp_socket_is_closed (component->tcp)) {
guint64 timeout = component->last_clock_timeout; guint64 timeout = component->last_clock_timeout;
if (pseudo_tcp_socket_get_next_clock (component->tcp, &timeout)) { if (pseudo_tcp_socket_get_next_clock (component->tcp, &timeout)) {
...@@ -1929,10 +1929,13 @@ process_queued_tcp_packets (NiceAgent *agent, Stream *stream, ...@@ -1929,10 +1929,13 @@ process_queued_tcp_packets (NiceAgent *agent, Stream *stream,
guint stream_id = stream->id; guint stream_id = stream->id;
guint component_id = component->id; guint component_id = component->id;
g_assert (agent->reliable);
if (component->selected_pair.local == NULL || if (component->selected_pair.local == NULL ||
component->tcp == NULL || pseudo_tcp_socket_is_closed (component->tcp) ||
nice_socket_is_reliable (component->selected_pair.local->sockptr)) nice_socket_is_reliable (component->selected_pair.local->sockptr))
return; return;
}
nice_debug ("%s: Sending outstanding packets for agent %p.", G_STRFUNC, nice_debug ("%s: Sending outstanding packets for agent %p.", G_STRFUNC,
agent); agent);
...@@ -1951,7 +1954,7 @@ process_queued_tcp_packets (NiceAgent *agent, Stream *stream, ...@@ -1951,7 +1954,7 @@ process_queued_tcp_packets (NiceAgent *agent, Stream *stream,
"pseudo_tcp_socket_notify_packet()"); "pseudo_tcp_socket_notify_packet()");
return; return;
} }
if (!component->tcp) { if (pseudo_tcp_socket_is_closed (component->tcp)) {
nice_debug ("PseudoTCP socket got destroyed in" nice_debug ("PseudoTCP socket got destroyed in"
" pseudo_tcp_socket_notify_packet()!"); " pseudo_tcp_socket_notify_packet()!");
return; return;
...@@ -2100,7 +2103,8 @@ void agent_signal_component_state_change (NiceAgent *agent, guint stream_id, gui ...@@ -2100,7 +2103,8 @@ void agent_signal_component_state_change (NiceAgent *agent, guint stream_id, gui
component->state = state; component->state = state;
process_queued_tcp_packets (agent, stream, component); if (agent->reliable)
process_queued_tcp_packets (agent, stream, component);
agent_queue_signal (agent, signals[SIGNAL_COMPONENT_STATE_CHANGED], agent_queue_signal (agent, signals[SIGNAL_COMPONENT_STATE_CHANGED],
stream_id, component_id, state); stream_id, component_id, state);
...@@ -3477,7 +3481,8 @@ agent_recv_message_unlocked ( ...@@ -3477,7 +3481,8 @@ agent_recv_message_unlocked (
/* Unhandled STUN; try handling TCP data, then pass to the client. */ /* Unhandled STUN; try handling TCP data, then pass to the client. */
if (message->length > 0 && agent->reliable) { if (message->length > 0 && agent->reliable) {
if (!nice_socket_is_reliable (nicesock) && component->tcp) { if (!nice_socket_is_reliable (nicesock) &&
!pseudo_tcp_socket_is_closed (component->tcp)) {
/* If we don’t yet have an underlying selected socket, queue up the /* If we don’t yet have an underlying selected socket, queue up the
* incoming data to handle later. This is because we can’t send ACKs (or, * incoming data to handle later. This is because we can’t send ACKs (or,
* more importantly for the first few packets, SYNACKs) without an * more importantly for the first few packets, SYNACKs) without an
...@@ -3508,7 +3513,7 @@ agent_recv_message_unlocked ( ...@@ -3508,7 +3513,7 @@ agent_recv_message_unlocked (
/* Success! Handled out-of-band. */ /* Success! Handled out-of-band. */
retval = RECV_OOB; retval = RECV_OOB;
goto done; goto done;
} else if (!nice_socket_is_reliable (nicesock)) { } else if (pseudo_tcp_socket_is_closed (component->tcp)) {
nice_debug ("Received data on a pseudo tcp FAILED component. Ignoring."); nice_debug ("Received data on a pseudo tcp FAILED component. Ignoring.");
retval = RECV_OOB; retval = RECV_OOB;
...@@ -3950,7 +3955,7 @@ nice_agent_recv_messages_blocking_or_nonblocking (NiceAgent *agent, ...@@ -3950,7 +3955,7 @@ nice_agent_recv_messages_blocking_or_nonblocking (NiceAgent *agent,
/* For a reliable stream, grab any data from the pseudo-TCP input buffer /* For a reliable stream, grab any data from the pseudo-TCP input buffer
* before trying the sockets. */ * before trying the sockets. */
if (agent->reliable && component->tcp != NULL && if (agent->reliable &&
pseudo_tcp_socket_get_available_bytes (component->tcp) > 0) { pseudo_tcp_socket_get_available_bytes (component->tcp) > 0) {
pseudo_tcp_socket_recv_messages (component->tcp, pseudo_tcp_socket_recv_messages (component->tcp,
component->recv_messages, component->n_recv_messages, component->recv_messages, component->n_recv_messages,
...@@ -4007,7 +4012,7 @@ nice_agent_recv_messages_blocking_or_nonblocking (NiceAgent *agent, ...@@ -4007,7 +4012,7 @@ nice_agent_recv_messages_blocking_or_nonblocking (NiceAgent *agent,
component->recv_messages, component->n_recv_messages); component->recv_messages, component->n_recv_messages);
error_reported = (child_error != NULL && error_reported = (child_error != NULL &&
!g_error_matches (child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); !g_error_matches (child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK));
reached_eos = (agent->reliable && component->tcp != NULL && reached_eos = (agent->reliable &&
pseudo_tcp_socket_is_closed_remotely (component->tcp) && pseudo_tcp_socket_is_closed_remotely (component->tcp) &&
nice_input_message_iter_compare (&prev_recv_messages_iter, nice_input_message_iter_compare (&prev_recv_messages_iter,
&component->recv_messages_iter)); &component->recv_messages_iter));
...@@ -4189,7 +4194,7 @@ nice_agent_send_messages_nonblocking_internal ( ...@@ -4189,7 +4194,7 @@ nice_agent_send_messages_nonblocking_internal (
if(agent->reliable && if(agent->reliable &&
!nice_socket_is_reliable (component->selected_pair.local->sockptr)) { !nice_socket_is_reliable (component->selected_pair.local->sockptr)) {
if (component->tcp != NULL) { if (!pseudo_tcp_socket_is_closed (component->tcp)) {
/* Send on the pseudo-TCP socket. */ /* Send on the pseudo-TCP socket. */
n_sent = pseudo_tcp_socket_send_messages (component->tcp, messages, n_sent = pseudo_tcp_socket_send_messages (component->tcp, messages,
n_messages, allow_partial, &child_error); n_messages, allow_partial, &child_error);
...@@ -4629,7 +4634,7 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) ...@@ -4629,7 +4634,7 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data)
}; };
RecvStatus retval = 0; RecvStatus retval = 0;
if (component->tcp == NULL) { if (pseudo_tcp_socket_is_closed (component->tcp)) {
nice_debug ("Agent %p: not handling incoming packet for s%d:%d " nice_debug ("Agent %p: not handling incoming packet for s%d:%d "
"because pseudo-TCP socket does not exist in reliable mode.", agent, "because pseudo-TCP socket does not exist in reliable mode.", agent,
stream->id, component->id); stream->id, component->id);
...@@ -4802,7 +4807,8 @@ nice_agent_attach_recv ( ...@@ -4802,7 +4807,8 @@ nice_agent_attach_recv (
* next incoming data. * next incoming data.
* but only do this if we know we're already readable, otherwise we might * but only do this if we know we're already readable, otherwise we might
* trigger an error in the initial, pre-connection attach. */ * trigger an error in the initial, pre-connection attach. */
if (component->tcp && component->tcp_readable) if (agent->reliable && !pseudo_tcp_socket_is_closed (component->tcp) &&
component->tcp_readable)
pseudo_tcp_socket_readable (component->tcp, component); pseudo_tcp_socket_readable (component->tcp, component);
} }
...@@ -4839,7 +4845,7 @@ nice_agent_set_selected_pair ( ...@@ -4839,7 +4845,7 @@ nice_agent_set_selected_pair (
conn_check_prune_stream (agent, stream); conn_check_prune_stream (agent, stream);
if (agent->reliable && !nice_socket_is_reliable (pair.local->sockptr) && if (agent->reliable && !nice_socket_is_reliable (pair.local->sockptr) &&
component->tcp == NULL) { pseudo_tcp_socket_is_closed (component->tcp)) {
nice_debug ("Agent %p: not setting selected pair for s%d:%d because " nice_debug ("Agent %p: not setting selected pair for s%d:%d because "
"pseudo tcp socket does not exist in reliable mode", agent, "pseudo tcp socket does not exist in reliable mode", agent,
stream->id, component->id); stream->id, component->id);
...@@ -4980,7 +4986,7 @@ nice_agent_set_selected_remote_candidate ( ...@@ -4980,7 +4986,7 @@ nice_agent_set_selected_remote_candidate (
goto done; goto done;
if (agent->reliable && !nice_socket_is_reliable (lcandidate->sockptr) && if (agent->reliable && !nice_socket_is_reliable (lcandidate->sockptr) &&
component->tcp == NULL) { pseudo_tcp_socket_is_closed (component->tcp)) {
nice_debug ("Agent %p: not setting selected remote candidate s%d:%d because" nice_debug ("Agent %p: not setting selected remote candidate s%d:%d because"
" pseudo tcp socket does not exist in reliable mode", agent, " pseudo tcp socket does not exist in reliable mode", agent,
stream->id, component->id); stream->id, component->id);
......
...@@ -345,8 +345,8 @@ nice_input_stream_close (GInputStream *stream, GCancellable *cancellable, ...@@ -345,8 +345,8 @@ nice_input_stream_close (GInputStream *stream, GCancellable *cancellable,
/* Shut down the read side of the pseudo-TCP stream, if it still exists. */ /* Shut down the read side of the pseudo-TCP stream, if it still exists. */
if (agent_find_component (agent, priv->stream_id, priv->component_id, if (agent_find_component (agent, priv->stream_id, priv->component_id,
&_stream, &component) && &_stream, &component) && agent->reliable &&
component->tcp != NULL) { !pseudo_tcp_socket_is_closed (component->tcp)) {
pseudo_tcp_socket_shutdown (component->tcp, PSEUDO_TCP_SHUTDOWN_RD); pseudo_tcp_socket_shutdown (component->tcp, PSEUDO_TCP_SHUTDOWN_RD);
} }
...@@ -387,7 +387,7 @@ nice_input_stream_is_readable (GPollableInputStream *stream) ...@@ -387,7 +387,7 @@ nice_input_stream_is_readable (GPollableInputStream *stream)
/* If it’s a reliable agent, see if there’s any pending data in the pseudo-TCP /* If it’s a reliable agent, see if there’s any pending data in the pseudo-TCP
* buffer. */ * buffer. */
if (component->tcp != NULL && if (agent->reliable &&
pseudo_tcp_socket_get_available_bytes (component->tcp) > 0) { pseudo_tcp_socket_get_available_bytes (component->tcp) > 0) {
retval = TRUE; retval = TRUE;
goto done; goto done;
......
...@@ -489,8 +489,8 @@ nice_output_stream_close (GOutputStream *stream, GCancellable *cancellable, ...@@ -489,8 +489,8 @@ nice_output_stream_close (GOutputStream *stream, GCancellable *cancellable,
/* Shut down the write side of the pseudo-TCP stream. */ /* Shut down the write side of the pseudo-TCP stream. */
if (agent_find_component (agent, priv->stream_id, priv->component_id, if (agent_find_component (agent, priv->stream_id, priv->component_id,
&_stream, &component) && &_stream, &component) && agent->reliable &&
component->tcp != NULL) { !pseudo_tcp_socket_is_closed (component->tcp)) {
pseudo_tcp_socket_shutdown (component->tcp, PSEUDO_TCP_SHUTDOWN_WR); pseudo_tcp_socket_shutdown (component->tcp, PSEUDO_TCP_SHUTDOWN_WR);
} }
...@@ -533,8 +533,7 @@ nice_output_stream_is_writable (GPollableOutputStream *stream) ...@@ -533,8 +533,7 @@ nice_output_stream_is_writable (GPollableOutputStream *stream)
/* If it’s a reliable agent, see if there’s any space in the pseudo-TCP /* If it’s a reliable agent, see if there’s any space in the pseudo-TCP
* output buffer. */ * output buffer. */
if (!nice_socket_is_reliable (sockptr)) { if (!nice_socket_is_reliable (sockptr)) {
if (component->tcp != NULL) retval = pseudo_tcp_socket_can_send (component->tcp);
retval = pseudo_tcp_socket_can_send (component->tcp);
} else { } else {
retval = (g_socket_condition_check (sockptr->fileno, G_IO_OUT) != 0); retval = (g_socket_condition_check (sockptr->fileno, G_IO_OUT) != 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment