static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc, GIOCondition condition, gpointer user_data) { QIOTask *task = user_data; QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK( qio_task_get_source(task)); Error *err = NULL; ssize_t ret; ret = qio_channel_write(wioc->master, (char *)wioc->encoutput.buffer, wioc->encoutput.offset, &err); if (ret < 0) { trace_qio_channel_websock_handshake_fail(ioc); qio_task_abort(task, err); error_free(err); return FALSE; } buffer_advance(&wioc->encoutput, ret); if (wioc->encoutput.offset == 0) { trace_qio_channel_websock_handshake_complete(ioc); qio_task_complete(task); return FALSE; } trace_qio_channel_websock_handshake_pending(ioc, G_IO_OUT); return TRUE; }
static gboolean qio_task_thread_result(gpointer opaque) { struct QIOTaskThreadData *data = opaque; trace_qio_task_thread_result(data->task); qio_task_complete(data->task); if (data->destroy) { data->destroy(data->opaque); } if (data->context) { g_main_context_unref(data->context); } g_free(data); return FALSE; }
static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc, QIOTask *task) { Error *err = NULL; QCryptoTLSSessionHandshakeStatus status; if (qcrypto_tls_session_handshake(ioc->session, &err) < 0) { trace_qio_channel_tls_handshake_fail(ioc); qio_task_abort(task, err); goto cleanup; } status = qcrypto_tls_session_get_handshake_status(ioc->session); if (status == QCRYPTO_TLS_HANDSHAKE_COMPLETE) { trace_qio_channel_tls_handshake_complete(ioc); if (qcrypto_tls_session_check_credentials(ioc->session, &err) < 0) { trace_qio_channel_tls_credentials_deny(ioc); qio_task_abort(task, err); goto cleanup; } trace_qio_channel_tls_credentials_allow(ioc); qio_task_complete(task); } else { GIOCondition condition; if (status == QCRYPTO_TLS_HANDSHAKE_SENDING) { condition = G_IO_OUT; } else { condition = G_IO_IN; } trace_qio_channel_tls_handshake_pending(ioc, status); qio_channel_add_watch(ioc->master, condition, qio_channel_tls_handshake_io, task, NULL); } cleanup: error_free(err); }