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_channel_websock_handshake_io(QIOChannel *ioc, GIOCondition condition, gpointer user_data) { QIOTask *task = user_data; QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK( qio_task_get_source(task)); Error *err = NULL; int ret; ret = qio_channel_websock_handshake_read(wioc, &err); if (ret < 0) { trace_qio_channel_websock_handshake_fail(ioc); qio_task_abort(task, err); error_free(err); return FALSE; } if (ret == 0) { trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN); /* need more data still */ return TRUE; } object_ref(OBJECT(task)); trace_qio_channel_websock_handshake_reply(ioc); qio_channel_add_watch( wioc->master, G_IO_OUT, qio_channel_websock_handshake_send, task, (GDestroyNotify)object_unref); 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); }