wip: move from g_idle to non blocking io

This commit is contained in:
Gergely Polonkai 2019-01-10 15:03:17 +01:00
parent 51a7ea4d3e
commit 2819efdf80
3 changed files with 56 additions and 19 deletions

View File

@ -353,21 +353,15 @@ data_read(GObject *source, GAsyncResult *result, gpointer user_data)
}
g_debug("Read %ld bytes", bytes_read);
// Re-add the idle handler
g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
G_SOURCE_FUNC(check_incoming_data),
g_object_ref(singleton),
g_object_unref);
}
static gboolean
check_incoming_data(SsbScuttler *scuttler)
read_inbound(GSocket *socket, GIOCondition condition, SsbScuttler *scuttler)
{
DataReadType *data = g_slice_new(DataReadType);
GInputStream *stream = g_io_stream_get_input_stream(G_IO_STREAM(scuttler->connection));
g_debug("Checking for incoming data");
g_debug("Data is flowing in!");
data->scuttler = scuttler;
data->read_buffer = g_malloc(MAX_MESSAGE_SIZE);
@ -404,11 +398,6 @@ ssb_scuttler_ensure(const gchar *ssb_dir)
initialise(singleton, ssb_dir);
}
g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
G_SOURCE_FUNC(check_incoming_data),
g_object_ref(singleton),
g_object_unref);
return TRUE;
}
@ -475,13 +464,19 @@ ssb_scuttler_shs_connect(SsbScuttler *scuttler, GError **error)
GError *err = NULL;
if (crypto_box_keypair(kx_pk, kx_sk) < 0) {
g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYGEN, "Could not generate auth keypair");
g_set_error(error,
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYGEN,
"Could not generate auth keypair");
return FALSE;
}
g_debug("SHS auth keypair generated");
if (crypto_auth(local_app_mac, kx_pk, crypto_box_PUBLICKEYBYTES, scuttler->app_key) < 0) {
g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYAUTH, "Failed to generate app mac");
g_set_error(error,
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYAUTH,
"Failed to generate app mac");
return FALSE;
}
@ -496,6 +491,8 @@ ssb_scuttler_shs_connect(SsbScuttler *scuttler, GError **error)
return FALSE;
}
g_debug("Challenge sent");
// Receive challenge response
if (!ssb_scuttler_read(scuttler, buf, sizeof(buf), &err)) {
g_propagate_error(error, err);
@ -503,11 +500,15 @@ ssb_scuttler_shs_connect(SsbScuttler *scuttler, GError **error)
return FALSE;
}
g_debug("Challenge response read");
memcpy(remote_app_mac, buf, crypto_box_PUBLICKEYBYTES);
memcpy(remote_kx_pk, buf + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
if (crypto_auth_verify(buf, remote_kx_pk, crypto_box_PUBLICKEYBYTES, scuttler->app_key) < 0) {
g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYVERIFY, "Wrong protocol (version?)");
g_set_error(error,
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_KEYVERIFY,
"Wrong protocol (version?)");
return FALSE;
}
@ -676,8 +677,12 @@ connection_finished(GObject *source, GAsyncResult *result, gpointer user_data)
SsbScuttler *scuttler = g_task_get_task_data(task);
GError *err = NULL;
GSocketConnection *connection = g_socket_client_connect_finish(socket_client, result, &err);
GSocket *socket;
GSource *socket_source;
if (connection == NULL) {
g_warning("Unable to connect to SBOT/* ");
g_task_return_error(task, err);
g_object_unref(task);
@ -687,6 +692,8 @@ connection_finished(GObject *source, GAsyncResult *result, gpointer user_data)
g_clear_object(&(scuttler->connection));
scuttler->connection = connection;
g_debug("Connected to SBOT");
// TODO: This is only required if noauth is not set
if (!ssb_scuttler_shs_connect(scuttler, &err)) {
g_task_return_error(task, err);
@ -695,6 +702,14 @@ connection_finished(GObject *source, GAsyncResult *result, gpointer user_data)
return;
}
socket = g_socket_connection_get_socket(connection);
g_socket_set_blocking(socket, FALSE);
socket_source = g_socket_create_source(socket, G_IO_IN | G_IO_PRI, NULL);
g_source_set_callback(socket_source,
(GSourceFunc)read_inbound,
g_object_ref(scuttler), g_object_unref);
g_source_attach(socket_source, g_main_context_get_thread_default());
g_task_return_boolean(task, TRUE);
emit_connected(scuttler, TRUE);
g_object_unref(task);
@ -887,6 +902,8 @@ ssb_scuttler_muxrpc_call(SsbScuttler *scuttler,
JsonNode *req_node = json_node_new(JSON_NODE_OBJECT);
GError *err = NULL;
g_debug("Calling %s SBOT method", method);
json_object_set_string_member(req_object, "name", method);
json_object_set_string_member(req_object, "args", argument);
@ -899,19 +916,26 @@ ssb_scuttler_muxrpc_call(SsbScuttler *scuttler,
json_node_free(req_node);
if ((request_len = strlen(request)) > MAX_MESSAGE_SIZE) {
g_set_error(error, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_REQUEST_TOO_LARGE, "Request too large");
g_set_error(error, SSB_SCUTTLER_ERROR,
SSB_SCUTTLER_ERROR_REQUEST_TOO_LARGE,
"Request too large");
return;
}
req_id = g_atomic_int_add(&(scuttler->request_id), 1);
if (!ssb_scuttler_send_packet(scuttler, SSB_PACKET_TYPE_JSON, request, request_len, req_id, !is_request, FALSE, &err)) {
if (!ssb_scuttler_send_packet(scuttler,
SSB_PACKET_TYPE_JSON, request, request_len,
req_id, !is_request, FALSE,
&err)) {
g_propagate_error(error, err);
return;
}
g_debug("%s request sent", method);
g_free(request);
}
@ -1045,7 +1069,9 @@ ssb_scuttler_whoami_async(SsbScuttler *scuttler,
task = g_task_new(scuttler, cancellable, callback, user_data);
if (!scuttler->connection) {
g_task_return_new_error(task, SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_NOTCONNECTED, "Scuttler is not connected");
g_task_return_new_error(task,
SSB_SCUTTLER_ERROR, SSB_SCUTTLER_ERROR_NOTCONNECTED,
"Scuttler is not connected");
g_object_unref(task);
return;

View File

@ -33,6 +33,10 @@ void ssb_scuttler_connect_async(SsbScuttler *scuttler,
gboolean ssb_scuttler_connect_finish(SsbScuttler *scuttler,
GAsyncResult *result,
GError **error);
void ssb_scuttler_whoami_async(SsbScuttler *scuttler,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
G_END_DECLS

View File

@ -83,6 +83,11 @@ ssb_app_dispose(GObject *gobject)
G_OBJECT_CLASS(ssb_app_parent_class)->dispose(gobject);
}
static void
whoami_finished(GObject *source, GAsyncResult *res, gpointer user_data)
{
}
void
connect_finished(GObject *source, GAsyncResult *res, gpointer user_data)
{
@ -90,6 +95,8 @@ connect_finished(GObject *source, GAsyncResult *res, gpointer user_data)
SsbApp *app = user_data;
GError *err = NULL;
gboolean connect_successful = ssb_scuttler_connect_finish(scuttler, res, &err);
ssb_scuttler_whoami_async(scuttler, NULL, whoami_finished, app);
}
static void