Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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);
}