static void flush_queue (CockpitPortal *self) { CockpitPortalMessage *message; GQueue *queue; queue = self->queue; self->queue = NULL; if (queue) { g_debug ("flushing portal queue"); for (;;) { message = g_queue_pop_head (queue); if (!message) break; g_assert (self->state != PORTAL_OPENING); if (self->transport) cockpit_transport_emit_recv (self->transport, message->channel, message->payload); cockpit_portal_message_free (message); } g_queue_free (queue); } }
static void emit_string (TestCase *tc, const gchar *channel, const gchar *string) { GBytes *bytes = g_bytes_new (string, strlen (string)); cockpit_transport_emit_recv (COCKPIT_TRANSPORT (tc->transport), channel, bytes); g_bytes_unref (bytes); }
static void on_pipe_read (CockpitPipe *pipe, GByteArray *input, gboolean end_of_data, gpointer user_data) { CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data); GBytes *message; GBytes *payload; gchar *channel; guint32 size; for (;;) { if (input->len < sizeof (size)) { if (!end_of_data) g_debug ("%s: want more data", self->name); break; } memcpy (&size, input->data, sizeof (size)); size = GUINT32_FROM_BE (size); if (input->len < size + sizeof (size)) { g_debug ("%s: want more data", self->name); break; } message = cockpit_pipe_consume (input, sizeof (size), size); payload = cockpit_transport_parse_frame (message, &channel); if (payload) { g_debug ("%s: received a %d byte payload", self->name, (int)size); cockpit_transport_emit_recv ((CockpitTransport *)self, channel, payload); g_bytes_unref (payload); g_free (channel); } g_bytes_unref (message); } if (end_of_data) { /* Received a partial message */ if (input->len > 0) { g_warning ("%s: received truncated %d byte frame", self->name, input->len); cockpit_pipe_close (pipe, "internal-error"); } } }
static void drain_buffer (CockpitSshTransport *self) { GBytes *message; GBytes *payload; gchar *channel; guint32 size; for (;;) { if (self->buffer->len < sizeof (size)) { if (!self->received_eof) g_debug ("%s: want len have %d", self->logname, (int)self->buffer->len); break; } memcpy (&size, self->buffer->data, sizeof (size)); size = GUINT32_FROM_BE (size); if (self->buffer->len < size + sizeof (size)) { g_debug ("%s: want %d have %d", self->logname, (int)(size + sizeof (size)), (int)self->buffer->len); break; } message = cockpit_pipe_consume (self->buffer, sizeof (size), size, 0); payload = cockpit_transport_parse_frame (message, &channel); if (payload) { g_debug ("%s: received a %d byte payload", self->logname, (int)g_bytes_get_size (payload)); cockpit_transport_emit_recv ((CockpitTransport *)self, channel, payload); g_bytes_unref (payload); g_free (channel); } g_bytes_unref (message); } if (self->received_eof) { /* Received a partial message */ if (self->buffer->len > 0) { g_warning ("%s: received truncated %d byte frame", self->logname, (int)self->buffer->len); close_immediately (self, "internal-error"); } } }
static void on_pipe_read (CockpitPipe *pipe, GByteArray *input, gboolean end_of_data, gpointer user_data) { CockpitInteractTransport *self = COCKPIT_INTERACT_TRANSPORT (user_data); GBytes *message; GBytes *payload; gchar *channel; guint8 *pos; guint32 size; for (;;) { pos = NULL; if (input->len > 0) pos = (guint8 *)g_strstr_len ((gchar *)input->data, input->len, self->delimiter); if (!pos) { if (!end_of_data) g_debug ("%s: want more data", self->name); break; } size = pos - input->data; message = cockpit_pipe_consume (input, 0, size, self->delimiter_len); payload = cockpit_transport_parse_frame (message, &channel); if (payload) { g_debug ("%s: received a %d byte payload", self->name, (int)size); cockpit_transport_emit_recv ((CockpitTransport *)self, channel, payload); g_bytes_unref (payload); g_free (channel); } g_bytes_unref (message); } }
static void send_init_command (CockpitTransport *transport, gboolean interactive) { const gchar *checksum; JsonObject *object; GBytes *bytes; object = json_object_new (); json_object_set_string_member (object, "command", "init"); json_object_set_int_member (object, "version", 1); /* * When in interactive mode pretend we received an init * message, and don't print one out. */ if (interactive) { json_object_set_string_member (object, "host", "localhost"); } else { checksum = cockpit_packages_get_checksum (packages); if (checksum) json_object_set_string_member (object, "checksum", checksum); } bytes = cockpit_json_write_bytes (object); json_object_unref (object); if (interactive) cockpit_transport_emit_recv (transport, NULL, bytes); else cockpit_transport_send (transport, NULL, bytes); g_bytes_unref (bytes); }
/** * cockpit_transport_read_from_pipe: * * Meant to be used in a "read" handler for a #CockpitPipe * Closed is pointer to a boolean value that may be updated * during the read and parse loop. */ void cockpit_transport_read_from_pipe (CockpitTransport *self, const gchar *logname, CockpitPipe *pipe, gboolean *closed, GByteArray *input, gboolean end_of_data) { GBytes *message; GBytes *payload; gchar *channel; guint32 i, size; gchar *data; /* This may be updated during the loop. */ g_assert (closed != NULL); g_object_ref (self); while (!*closed) { size = 0; data = (gchar *)input->data; for (i = 0; i < input->len; i++) { /* Check invalid characters, prevent integer overflow, limit max length */ if (i > 7 || data[i] < '0' || data[i] > '9') break; size *= 10; size += data[i] - '0'; } if (i == input->len) { if (!end_of_data) g_debug ("%s: want more data", logname); break; } if (data[i] != '\n') { g_warning ("%s: incorrect protocol: received invalid length prefix", logname); cockpit_pipe_close (pipe, "protocol-error"); break; } if (input->len < i + 1 + size) { g_debug ("%s: want more data 2", logname); break; } message = cockpit_pipe_consume (input, i + 1, size, 0); payload = cockpit_transport_parse_frame (message, &channel); if (payload) { g_debug ("%s: received a %d byte payload", logname, (int)size); cockpit_transport_emit_recv (self, channel, payload); g_bytes_unref (payload); g_free (channel); } g_bytes_unref (message); } if (end_of_data) { /* Received a partial message */ if (input->len > 0) { g_debug ("%s: received truncated %d byte frame", logname, input->len); cockpit_pipe_close (pipe, "disconnected"); } } g_object_unref (self); }
static void on_pipe_read (CockpitPipe *pipe, GByteArray *input, gboolean end_of_data, gpointer user_data) { CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data); GBytes *message; GBytes *payload; gchar *channel; guint32 i, size; gchar *data; g_object_ref (self); for (;;) { size = 0; data = (gchar *)input->data; for (i = 0; i < input->len; i++) { /* Check invalid characters, prevent integer overflow, limit max length */ if (i > 7 || data[i] < '0' || data[i] > '9') break; size *= 10; size += data[i] - '0'; } if (i == input->len) { if (!end_of_data) g_debug ("%s: want more data", self->name); break; } if (data[i] != '\n') { g_warning ("%s: incorrect protocol: received invalid length prefix", self->name); cockpit_pipe_close (pipe, "protocol-error"); break; } if (input->len < i + 1 + size) { g_debug ("%s: want more data 2", self->name); break; } message = cockpit_pipe_consume (input, i + 1, size, 0); payload = cockpit_transport_parse_frame (message, &channel); if (payload) { g_debug ("%s: received a %d byte payload", self->name, (int)size); cockpit_transport_emit_recv ((CockpitTransport *)self, channel, payload); g_bytes_unref (payload); g_free (channel); } g_bytes_unref (message); } if (end_of_data) { /* Received a partial message */ if (input->len > 0) { g_debug ("%s: received truncated %d byte frame", self->name, input->len); cockpit_pipe_close (pipe, "disconnected"); } } g_object_unref (self); }