[libvirt] [PATCH 11/15] Convert libvirtd over to the new RPC handling APIs

Daniel P. Berrange berrange at redhat.com
Thu Dec 16 11:45:31 UTC 2010


This guts the libvirtd daemon, removing all its networking and
RPC handling code. Instead it calls out to the new virServerPtr
APIs for all its RPC & networking work

As a fallout all libvirtd daemon error reporting now takes place
via the normal internal error reporting APIs. There is no need
to call separate error reporting APIs in RPC code, nor should
code use VIR_WARN/VIR_ERROR for reporting fatal problems anymore.

NB, this mail has been edit to remove all the auto-generated
code changes, to try & reduce the size somewhat. So none of
the remote_dispatch* or qemu_dispatch* files remain.

* daemon/qemu_dispatch_*.h, daemon/remote_dispatch_*.h: Remove
  old generated dispatcher code
* daemon/qemu_dispatch.h, daemon/remote_dispatch.h: New dispatch
  code
* daemon/dispatch.c, daemon/dispatch.h: Remove obsoleted code
* daemon/remote.c, daemon/remote.h: Rewrite for new dispatch
  APIs
* daemon/libvirtd.c, daemon/libvirtd.h: Remove all networking
  code
* daemon/stream.c, daemon/stream.h: Update for new APIs
* daemon/Makefile.am: Link to libvirt-net-rpc-server.la
---
 daemon/Makefile.am                  |   59 +-
 daemon/dispatch.c                   |  707 -----
 daemon/dispatch.h                   |   70 -
 daemon/libvirtd.c                   | 2993 +++++----------------
 daemon/libvirtd.h                   |  246 +--
 daemon/qemu_dispatch.h              |   58 +
 daemon/qemu_dispatch_args.h         |    5 -
 daemon/qemu_dispatch_prototypes.h   |   12 -
 daemon/qemu_dispatch_ret.h          |    5 -
 daemon/qemu_dispatch_table.h        |   14 -
 daemon/remote.c                     | 3802 +++++++++++----------------
 daemon/remote.h                     |   64 +-
 daemon/remote_dispatch.h            | 5073 +++++++++++++++++++++++++++++++++++
 daemon/remote_dispatch_args.h       |  173 --
 daemon/remote_dispatch_prototypes.h | 1564 -----------
 daemon/remote_dispatch_ret.h        |  140 -
 daemon/remote_dispatch_table.h      | 1019 -------
 daemon/remote_generate_stubs.pl     |  195 --
 daemon/stream.c                     |  479 ++--
 daemon/stream.h                     |   28 +-
 po/POTFILES.in                      |    1 -
 21 files changed, 7567 insertions(+), 9140 deletions(-)
 delete mode 100644 daemon/dispatch.c
 delete mode 100644 daemon/dispatch.h
 create mode 100644 daemon/qemu_dispatch.h
 delete mode 100644 daemon/qemu_dispatch_args.h
 delete mode 100644 daemon/qemu_dispatch_prototypes.h
 delete mode 100644 daemon/qemu_dispatch_ret.h
 delete mode 100644 daemon/qemu_dispatch_table.h
 create mode 100644 daemon/remote_dispatch.h
 delete mode 100644 daemon/remote_dispatch_args.h
 delete mode 100644 daemon/remote_dispatch_prototypes.h
 delete mode 100644 daemon/remote_dispatch_ret.h
 delete mode 100644 daemon/remote_dispatch_table.h
 delete mode 100755 daemon/remote_generate_stubs.pl

diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 72778e5..5acb3f8 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -3,19 +3,11 @@
 CLEANFILES =
 
 DAEMON_SOURCES =					\
-		event.c event.h				\
 		libvirtd.c libvirtd.h			\
-		remote.c remote.h			\
-		dispatch.c dispatch.h			\
 		stream.c stream.h			\
-		remote_dispatch_prototypes.h		\
-		remote_dispatch_table.h			\
-		remote_dispatch_args.h			\
-		remote_dispatch_ret.h			\
-		qemu_dispatch_prototypes.h		\
-		qemu_dispatch_table.h			\
-		qemu_dispatch_args.h			\
-		qemu_dispatch_ret.h			\
+		remote.c remote.h			\
+		remote_dispatch.h			\
+		qemu_dispatch.h				\
 		../src/remote/remote_protocol.c		\
 		../src/remote/qemu_protocol.c
 
@@ -24,7 +16,6 @@ AVAHI_SOURCES =						\
 
 DISTCLEANFILES =
 EXTRA_DIST =						\
-	remote_generate_stubs.pl			\
 	libvirtd.conf					\
 	libvirtd.init.in				\
 	libvirtd.policy-0				\
@@ -82,6 +73,7 @@ libvirtd_CFLAGS = \
 	-I$(top_srcdir)/src \
 	-I$(top_srcdir)/src/util \
 	-I$(top_srcdir)/src/conf \
+	-I$(top_srcdir)/src/rpc \
 	-I$(top_srcdir)/src/remote \
 	$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
 	$(POLKIT_CFLAGS) \
@@ -100,7 +92,10 @@ libvirtd_LDADD =					\
 	$(SASL_LIBS)					\
 	$(POLKIT_LIBS)
 
-libvirtd_LDADD += ../src/libvirt-qemu.la
+libvirtd_LDADD += \
+	../src/libvirt-net-rpc-server.la \
+	../src/libvirt-net-rpc.la \
+	../src/libvirt-qemu.la
 
 if ! WITH_DRIVER_MODULES
 if WITH_QEMU
@@ -206,43 +201,17 @@ endif
 
 
 remote.c: \
-	remote_dispatch_prototypes.h \
-	remote_dispatch_table.h \
-	qemu_dispatch_prototypes.h \
-	qemu_dispatch_table.h
-
-remote.h: \
-	remote_dispatch_args.h \
-	remote_dispatch_ret.h \
-	qemu_dispatch_args.h \
-	qemu_dispatch_ret.h
+	remote_dispatch.h \
+	qemu_dispatch.h
 
 REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
 QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
 
-remote_dispatch_prototypes.h: $(srcdir)/remote_generate_stubs.pl $(REMOTE_PROTOCOL)
-	$(AM_V_GEN)perl -w $(srcdir)/remote_generate_stubs.pl -c -p remote $(REMOTE_PROTOCOL) > $@
-
-remote_dispatch_table.h: $(srcdir)/remote_generate_stubs.pl $(REMOTE_PROTOCOL)
-	$(AM_V_GEN)perl -w $(srcdir)/remote_generate_stubs.pl -c -t remote $(REMOTE_PROTOCOL) > $@
-
-remote_dispatch_args.h: $(srcdir)/remote_generate_stubs.pl $(REMOTE_PROTOCOL)
-	$(AM_V_GEN)perl -w $(srcdir)/remote_generate_stubs.pl -c -a remote $(REMOTE_PROTOCOL) > $@
-
-remote_dispatch_ret.h: $(srcdir)/remote_generate_stubs.pl $(REMOTE_PROTOCOL)
-	$(AM_V_GEN)perl -w $(srcdir)/remote_generate_stubs.pl -c -r remote $(REMOTE_PROTOCOL) > $@
-
-qemu_dispatch_prototypes.h: $(srcdir)/remote_generate_stubs.pl $(QEMU_PROTOCOL)
-	$(AM_V_GEN)perl -w $(srcdir)/remote_generate_stubs.pl -p qemu $(QEMU_PROTOCOL) > $@
-
-qemu_dispatch_table.h: $(srcdir)/remote_generate_stubs.pl $(QEMU_PROTOCOL)
-	$(AM_V_GEN)perl -w $(srcdir)/remote_generate_stubs.pl -t qemu $(QEMU_PROTOCOL) > $@
-
-qemu_dispatch_args.h: $(srcdir)/remote_generate_stubs.pl $(QEMU_PROTOCOL)
-	$(AM_V_GEN)perl -w $(srcdir)/remote_generate_stubs.pl -a qemu $(QEMU_PROTOCOL) > $@
+remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl $(REMOTE_PROTOCOL)
+	$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -c remote $(REMOTE_PROTOCOL) > $@
 
-qemu_dispatch_ret.h: $(srcdir)/remote_generate_stubs.pl $(QEMU_PROTOCOL)
-	$(AM_V_GEN)perl -w $(srcdir)/remote_generate_stubs.pl -r qemu $(QEMU_PROTOCOL) > $@
+qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl $(QEMU_PROTOCOL)
+	$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl qemu $(QEMU_PROTOCOL) > $@
 
 LOGROTATE_CONFS = libvirtd.qemu.logrotate libvirtd.lxc.logrotate \
                   libvirtd.uml.logrotate
diff --git a/daemon/dispatch.c b/daemon/dispatch.c
deleted file mode 100644
index bf2ac73..0000000
--- a/daemon/dispatch.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * dispatch.h: RPC message dispatching infrastructure
- *
- * Copyright (C) 2007, 2008, 2009 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
- *
- * Author: Richard W.M. Jones <rjones at redhat.com>
- * Author: Daniel P. Berrange <berrange at redhat.com>
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdbool.h>
-
-#include "dispatch.h"
-#include "remote.h"
-
-#include "memory.h"
-
-/* Convert a libvirt  virError object into wire format */
-static void
-remoteDispatchCopyError (remote_error *rerr,
-                         virErrorPtr verr)
-{
-    rerr->code = verr->code;
-    rerr->domain = verr->domain;
-    rerr->message = verr->message ? malloc(sizeof(char*)) : NULL;
-    if (rerr->message) *rerr->message = strdup(verr->message);
-    rerr->level = verr->level;
-    rerr->str1 = verr->str1 ? malloc(sizeof(char*)) : NULL;
-    if (rerr->str1) *rerr->str1 = strdup(verr->str1);
-    rerr->str2 = verr->str2 ? malloc(sizeof(char*)) : NULL;
-    if (rerr->str2) *rerr->str2 = strdup(verr->str2);
-    rerr->str3 = verr->str3 ? malloc(sizeof(char*)) : NULL;
-    if (rerr->str3) *rerr->str3 = strdup(verr->str3);
-    rerr->int1 = verr->int1;
-    rerr->int2 = verr->int2;
-}
-
-
-/* A set of helpers for sending back errors to client
-   in various ways .... */
-
-static void
-remoteDispatchStringError (remote_error *rerr,
-                           int code, const char *msg)
-{
-    virError verr;
-
-    memset(&verr, 0, sizeof verr);
-
-    /* Construct the dummy libvirt virError. */
-    verr.code = code;
-    verr.domain = VIR_FROM_REMOTE;
-    verr.message = (char *)msg;
-    verr.level = VIR_ERR_ERROR;
-    verr.str1 = (char *)msg;
-
-    remoteDispatchCopyError(rerr, &verr);
-}
-
-
-void remoteDispatchAuthError (remote_error *rerr)
-{
-    remoteDispatchStringError (rerr, VIR_ERR_AUTH_FAILED, "authentication failed");
-}
-
-
-void remoteDispatchFormatError (remote_error *rerr,
-                                const char *fmt, ...)
-{
-    va_list args;
-    char msgbuf[1024];
-    char *msg = msgbuf;
-
-    va_start (args, fmt);
-    vsnprintf (msgbuf, sizeof msgbuf, fmt, args);
-    va_end (args);
-
-    remoteDispatchStringError (rerr, VIR_ERR_RPC, msg);
-}
-
-
-void remoteDispatchGenericError (remote_error *rerr)
-{
-    remoteDispatchStringError(rerr,
-                              VIR_ERR_INTERNAL_ERROR,
-                              "library function returned error but did not set virterror");
-}
-
-
-void remoteDispatchOOMError (remote_error *rerr)
-{
-    remoteDispatchStringError(rerr,
-                              VIR_ERR_NO_MEMORY,
-                              "out of memory");
-}
-
-
-void remoteDispatchConnError (remote_error *rerr,
-                              virConnectPtr conn)
-{
-    virErrorPtr verr;
-
-    if (conn)
-        verr = virConnGetLastError(conn);
-    else
-        verr = virGetLastError();
-    if (verr)
-        remoteDispatchCopyError(rerr, verr);
-    else
-        remoteDispatchGenericError(rerr);
-}
-
-static int
-remoteSerializeError(struct qemud_client *client,
-                     remote_error *rerr,
-                     int program,
-                     int version,
-                     int procedure,
-                     int type,
-                     int serial)
-{
-    XDR xdr;
-    unsigned int len;
-    struct qemud_client_message *msg = NULL;
-
-    DEBUG("prog=%d ver=%d proc=%d type=%d serial=%d, msg=%s",
-          program, version, procedure, type, serial,
-          rerr->message ? *rerr->message : "(none)");
-
-    if (VIR_ALLOC(msg) < 0)
-        goto fatal_error;
-
-    /* Return header. */
-    msg->hdr.prog = program;
-    msg->hdr.vers = version;
-    msg->hdr.proc = procedure;
-    msg->hdr.type = type;
-    msg->hdr.serial = serial;
-    msg->hdr.status = REMOTE_ERROR;
-
-    msg->bufferLength = sizeof(msg->buffer);
-
-    /* Serialise the return header. */
-    xdrmem_create (&xdr,
-                   msg->buffer,
-                   msg->bufferLength,
-                   XDR_ENCODE);
-
-    len = 0; /* We'll come back and write this later. */
-    if (!xdr_u_int (&xdr, &len))
-        goto xdr_error;
-
-    if (!xdr_remote_message_header (&xdr, &msg->hdr))
-        goto xdr_error;
-
-    /* Error was not set, so synthesize a generic error message. */
-    if (rerr->code == 0)
-        remoteDispatchGenericError(rerr);
-
-    if (!xdr_remote_error (&xdr, rerr))
-        goto xdr_error;
-
-    /* Write the length word. */
-    len = xdr_getpos (&xdr);
-    if (xdr_setpos (&xdr, 0) == 0)
-        goto xdr_error;
-
-    if (!xdr_u_int (&xdr, &len))
-        goto xdr_error;
-
-    xdr_destroy (&xdr);
-
-    msg->bufferLength = len;
-    msg->bufferOffset = 0;
-
-    /* Put reply on end of tx queue to send out  */
-    qemudClientMessageQueuePush(&client->tx, msg);
-    qemudUpdateClientEvent(client);
-    xdr_free((xdrproc_t)xdr_remote_error,  (char *)rerr);
-
-    return 0;
-
-xdr_error:
-    VIR_WARN("Failed to serialize remote error '%s' as XDR",
-             rerr->message ? *rerr->message : "<unknown>");
-    xdr_destroy(&xdr);
-    VIR_FREE(msg);
-fatal_error:
-    xdr_free((xdrproc_t)xdr_remote_error,  (char *)rerr);
-    return -1;
-}
-
-
-/*
- * @client: the client to send the error to
- * @rerr: the error object to send
- * @req: the message this error is in reply to
- *
- * Send an error message to the client
- *
- * Returns 0 if the error was sent, -1 upon fatal error
- */
-int
-remoteSerializeReplyError(struct qemud_client *client,
-                          remote_error *rerr,
-                          remote_message_header *req) {
-    /*
-     * For data streams, errors are sent back as data streams
-     * For method calls, errors are sent back as method replies
-     */
-    return remoteSerializeError(client,
-                                rerr,
-                                req->prog,
-                                req->vers,
-                                req->proc,
-                                req->type == REMOTE_STREAM ? REMOTE_STREAM : REMOTE_REPLY,
-                                req->serial);
-}
-
-int
-remoteSerializeStreamError(struct qemud_client *client,
-                           remote_error *rerr,
-                           int proc,
-                           int serial)
-{
-    return remoteSerializeError(client,
-                                rerr,
-                                REMOTE_PROGRAM,
-                                REMOTE_PROTOCOL_VERSION,
-                                proc,
-                                REMOTE_STREAM,
-                                serial);
-}
-
-/*
- * @msg: the complete incoming message, whose header to decode
- *
- * Decodes the header part of the client message, but does not
- * validate the decoded fields in the header. It expects
- * bufferLength to refer to length of the data packet. Upon
- * return bufferOffset will refer to the amount of the packet
- * consumed by decoding of the header.
- *
- * returns 0 if successfully decoded, -1 upon fatal error
- */
-int
-remoteDecodeClientMessageHeader (struct qemud_client_message *msg)
-{
-    XDR xdr;
-    int ret = -1;
-
-    msg->bufferOffset = REMOTE_MESSAGE_HEADER_XDR_LEN;
-
-    /* Parse the header. */
-    xdrmem_create (&xdr,
-                   msg->buffer + msg->bufferOffset,
-                   msg->bufferLength - msg->bufferOffset,
-                   XDR_DECODE);
-
-    if (!xdr_remote_message_header (&xdr, &msg->hdr))
-        goto cleanup;
-
-    msg->bufferOffset += xdr_getpos(&xdr);
-
-    ret = 0;
-
-cleanup:
-    xdr_destroy(&xdr);
-    return ret;
-}
-
-
-/*
- * @msg: the outgoing message, whose header to encode
- *
- * Encodes the header part of the client message, setting the
- * message offset ready to encode the payload. Leaves space
- * for the length field later. Upon return bufferLength will
- * refer to the total available space for message, while
- * bufferOffset will refer to current space used by header
- *
- * returns 0 if successfully encoded, -1 upon fatal error
- */
-int
-remoteEncodeClientMessageHeader (struct qemud_client_message *msg)
-{
-    XDR xdr;
-    int ret = -1;
-    unsigned int len = 0;
-
-    msg->bufferLength = sizeof(msg->buffer);
-    msg->bufferOffset = 0;
-
-    /* Format the header. */
-    xdrmem_create (&xdr,
-                   msg->buffer,
-                   msg->bufferLength,
-                   XDR_ENCODE);
-
-    /* The real value is filled in shortly */
-    if (!xdr_u_int (&xdr, &len)) {
-        goto cleanup;
-    }
-
-    if (!xdr_remote_message_header (&xdr, &msg->hdr))
-        goto cleanup;
-
-    len = xdr_getpos(&xdr);
-    xdr_setpos(&xdr, 0);
-
-    /* Fill in current length - may be re-written later
-     * if a payload is added
-     */
-    if (!xdr_u_int (&xdr, &len)) {
-        goto cleanup;
-    }
-
-    msg->bufferOffset += len;
-
-    ret = 0;
-
-cleanup:
-    xdr_destroy(&xdr);
-    return ret;
-}
-
-
-static int
-remoteDispatchClientCall (struct qemud_server *server,
-                          struct qemud_client *client,
-                          struct qemud_client_message *msg,
-                          bool qemu_protocol);
-
-
-/*
- * @server: the unlocked server object
- * @client: the locked client object
- * @msg: the complete incoming message packet, with header already decoded
- *
- * This function gets called from qemud when it pulls a incoming
- * remote protocol message off the dispatch queue for processing.
- *
- * The @msg parameter must have had its header decoded already by
- * calling remoteDecodeClientMessageHeader
- *
- * Returns 0 if the message was dispatched, -1 upon fatal error
- */
-int
-remoteDispatchClientRequest(struct qemud_server *server,
-                            struct qemud_client *client,
-                            struct qemud_client_message *msg)
-{
-    int ret;
-    remote_error rerr;
-    bool qemu_call;
-
-    DEBUG("prog=%d ver=%d type=%d status=%d serial=%d proc=%d",
-          msg->hdr.prog, msg->hdr.vers, msg->hdr.type,
-          msg->hdr.status, msg->hdr.serial, msg->hdr.proc);
-
-    memset(&rerr, 0, sizeof rerr);
-
-    /* Check version, etc. */
-    if (msg->hdr.prog == REMOTE_PROGRAM)
-        qemu_call = false;
-    else if (msg->hdr.prog == QEMU_PROGRAM)
-        qemu_call = true;
-    else {
-        remoteDispatchFormatError (&rerr,
-                                   _("program mismatch (actual %x, expected %x or %x)"),
-                                   msg->hdr.prog, REMOTE_PROGRAM, QEMU_PROGRAM);
-        goto error;
-    }
-
-    if (!qemu_call && msg->hdr.vers != REMOTE_PROTOCOL_VERSION) {
-        remoteDispatchFormatError (&rerr,
-                                   _("version mismatch (actual %x, expected %x)"),
-                                   msg->hdr.vers, REMOTE_PROTOCOL_VERSION);
-        goto error;
-    }
-    else if (qemu_call && msg->hdr.vers != QEMU_PROTOCOL_VERSION) {
-        remoteDispatchFormatError (&rerr,
-                                   _("version mismatch (actual %x, expected %x)"),
-                                   msg->hdr.vers, QEMU_PROTOCOL_VERSION);
-        goto error;
-    }
-
-    switch (msg->hdr.type) {
-    case REMOTE_CALL:
-        return remoteDispatchClientCall(server, client, msg, qemu_call);
-
-    case REMOTE_STREAM:
-        /* Since stream data is non-acked, async, we may continue to received
-         * stream packets after we closed down a stream. Just drop & ignore
-         * these.
-         */
-        VIR_INFO("Ignoring unexpected stream data serial=%d proc=%d status=%d",
-                 msg->hdr.serial, msg->hdr.proc, msg->hdr.status);
-        qemudClientMessageRelease(client, msg);
-        break;
-
-    default:
-        remoteDispatchFormatError (&rerr, _("type (%d) != REMOTE_CALL"),
-                                   (int) msg->hdr.type);
-        goto error;
-    }
-
-    return 0;
-
-error:
-    ret = remoteSerializeReplyError(client, &rerr, &msg->hdr);
-
-    if (ret >= 0)
-        VIR_FREE(msg);
-
-    return ret;
-}
-
-
-/*
- * @server: the unlocked server object
- * @client: the locked client object
- * @msg: the complete incoming method call, with header already decoded
- *
- * This method is used to dispatch an message representing an
- * incoming method call from a client. It decodes the payload
- * to obtain method call arguments, invokves the method and
- * then sends a reply packet with the return values
- *
- * Returns 0 if the reply was sent, or -1 upon fatal error
- */
-static int
-remoteDispatchClientCall (struct qemud_server *server,
-                          struct qemud_client *client,
-                          struct qemud_client_message *msg,
-                          bool qemu_protocol)
-{
-    XDR xdr;
-    remote_error rerr;
-    dispatch_args args;
-    dispatch_ret ret;
-    const dispatch_data *data = NULL;
-    int rv = -1;
-    unsigned int len;
-    virConnectPtr conn = NULL;
-
-    memset(&args, 0, sizeof args);
-    memset(&ret, 0, sizeof ret);
-    memset(&rerr, 0, sizeof rerr);
-
-    if (msg->hdr.status != REMOTE_OK) {
-        remoteDispatchFormatError (&rerr, _("status (%d) != REMOTE_OK"),
-                                   (int) msg->hdr.status);
-        goto rpc_error;
-    }
-
-    /* If client is marked as needing auth, don't allow any RPC ops,
-     * except for authentication ones
-     */
-    if (client->auth) {
-        if (msg->hdr.proc != REMOTE_PROC_AUTH_LIST &&
-            msg->hdr.proc != REMOTE_PROC_AUTH_SASL_INIT &&
-            msg->hdr.proc != REMOTE_PROC_AUTH_SASL_START &&
-            msg->hdr.proc != REMOTE_PROC_AUTH_SASL_STEP &&
-            msg->hdr.proc != REMOTE_PROC_AUTH_POLKIT
-            ) {
-            /* Explicitly *NOT* calling  remoteDispatchAuthError() because
-               we want back-compatability with libvirt clients which don't
-               support the VIR_ERR_AUTH_FAILED error code */
-            remoteDispatchFormatError (&rerr, "%s", _("authentication required"));
-            goto rpc_error;
-        }
-    }
-
-    if (qemu_protocol)
-        data = qemuGetDispatchData(msg->hdr.proc);
-    else
-        data = remoteGetDispatchData(msg->hdr.proc);
-
-    if (!data) {
-        remoteDispatchFormatError (&rerr, _("unknown procedure: %d"),
-                                   msg->hdr.proc);
-        goto rpc_error;
-    }
-
-    /* De-serialize payload with args from the wire message */
-    xdrmem_create (&xdr,
-                   msg->buffer + msg->bufferOffset,
-                   msg->bufferLength - msg->bufferOffset,
-                   XDR_DECODE);
-    if (!((data->args_filter)(&xdr, &args))) {
-        xdr_destroy (&xdr);
-        remoteDispatchFormatError (&rerr, "%s", _("parse args failed"));
-        goto rpc_error;
-    }
-    xdr_destroy (&xdr);
-
-    /* Call function. */
-    conn = client->conn;
-    virMutexUnlock(&client->lock);
-
-    /*
-     * When the RPC handler is called:
-     *
-     *  - Server object is unlocked
-     *  - Client object is unlocked
-     *
-     * Without locking, it is safe to use:
-     *
-     *   'conn', 'rerr', 'args and 'ret'
-     */
-    rv = (data->fn)(server, client, conn, &msg->hdr, &rerr, &args, &ret);
-
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
-
-    xdr_free (data->args_filter, (char*)&args);
-
-    if (rv < 0)
-        goto rpc_error;
-
-    /* Return header. We're re-using same message object, so
-     * only need to tweak type/status fields */
-    /*msg->hdr.prog = msg->hdr.prog;*/
-    /*msg->hdr.vers = msg->hdr.vers;*/
-    /*msg->hdr.proc = msg->hdr.proc;*/
-    msg->hdr.type = REMOTE_REPLY;
-    /*msg->hdr.serial = msg->hdr.serial;*/
-    msg->hdr.status = REMOTE_OK;
-
-    if (remoteEncodeClientMessageHeader(msg) < 0) {
-        xdr_free (data->ret_filter, (char*)&ret);
-        remoteDispatchFormatError(&rerr, "%s", _("failed to serialize reply header"));
-        goto xdr_hdr_error;
-    }
-
-
-    /* Now for the payload */
-    xdrmem_create (&xdr,
-                   msg->buffer,
-                   msg->bufferLength,
-                   XDR_ENCODE);
-
-    if (xdr_setpos(&xdr, msg->bufferOffset) == 0) {
-        remoteDispatchFormatError(&rerr, "%s", _("failed to change XDR reply offset"));
-        goto xdr_error;
-    }
-
-    /* If OK, serialise return structure, if error serialise error. */
-    /* Serialise reply data */
-    if (!((data->ret_filter) (&xdr, &ret))) {
-        remoteDispatchFormatError(&rerr, "%s", _("failed to serialize reply payload (probable message size limit)"));
-        goto xdr_error;
-    }
-
-    /* Update the length word. */
-    msg->bufferOffset += xdr_getpos (&xdr);
-    len = msg->bufferOffset;
-    if (xdr_setpos (&xdr, 0) == 0) {
-        remoteDispatchFormatError(&rerr, "%s", _("failed to change XDR reply offset"));
-        goto xdr_error;
-    }
-
-    if (!xdr_u_int (&xdr, &len)) {
-        remoteDispatchFormatError(&rerr, "%s", _("failed to update reply length header"));
-        goto xdr_error;
-    }
-
-    xdr_destroy (&xdr);
-    xdr_free (data->ret_filter, (char*)&ret);
-
-    /* Reset ready for I/O */
-    msg->bufferLength = len;
-    msg->bufferOffset = 0;
-
-    /* Put reply on end of tx queue to send out  */
-    qemudClientMessageQueuePush(&client->tx, msg);
-    qemudUpdateClientEvent(client);
-
-    return 0;
-
-xdr_error:
-    /* Bad stuff serializing reply. Try to send a little info
-     * back to client to assist in bug reporting/diagnosis */
-    xdr_free (data->ret_filter, (char*)&ret);
-    xdr_destroy (&xdr);
-    /* fallthrough */
-
-xdr_hdr_error:
-    VIR_WARN("Failed to serialize reply for program '%d' proc '%d' as XDR",
-             msg->hdr.prog, msg->hdr.proc);
-    /* fallthrough */
-
-rpc_error:
-    /* Bad stuff (de-)serializing message, but we have an
-     * RPC error message we can send back to the client */
-    rv = remoteSerializeReplyError(client, &rerr, &msg->hdr);
-
-    if (rv >= 0)
-        VIR_FREE(msg);
-
-    return rv;
-}
-
-
-int
-remoteSendStreamData(struct qemud_client *client,
-                     struct qemud_client_stream *stream,
-                     const char *data,
-                     unsigned int len)
-{
-    struct qemud_client_message *msg;
-    XDR xdr;
-
-    DEBUG("client=%p stream=%p data=%p len=%d", client, stream, data, len);
-
-    if (VIR_ALLOC(msg) < 0) {
-        return -1;
-    }
-
-    /* Return header. We're re-using same message object, so
-     * only need to tweak type/status fields */
-    msg->hdr.prog = REMOTE_PROGRAM;
-    msg->hdr.vers = REMOTE_PROTOCOL_VERSION;
-    msg->hdr.proc = stream->procedure;
-    msg->hdr.type = REMOTE_STREAM;
-    msg->hdr.serial = stream->serial;
-    /*
-     * NB
-     *   data != NULL + len > 0    => REMOTE_CONTINUE   (Sending back data)
-     *   data != NULL + len == 0   => REMOTE_CONTINUE   (Sending read EOF)
-     *   data == NULL              => REMOTE_OK         (Sending finish handshake confirmation)
-     */
-    msg->hdr.status = data ? REMOTE_CONTINUE : REMOTE_OK;
-
-    if (remoteEncodeClientMessageHeader(msg) < 0)
-        goto fatal_error;
-
-    if (data && len) {
-        if ((msg->bufferLength - msg->bufferOffset) < len)
-            goto fatal_error;
-
-        /* Now for the payload */
-        xdrmem_create (&xdr,
-                       msg->buffer,
-                       msg->bufferLength,
-                       XDR_ENCODE);
-
-        /* Skip over existing header already written */
-        if (xdr_setpos(&xdr, msg->bufferOffset) == 0)
-            goto xdr_error;
-
-        memcpy(msg->buffer + msg->bufferOffset, data, len);
-        msg->bufferOffset += len;
-
-        /* Update the length word. */
-        len = msg->bufferOffset;
-        if (xdr_setpos (&xdr, 0) == 0)
-            goto xdr_error;
-
-        if (!xdr_u_int (&xdr, &len))
-            goto xdr_error;
-
-        xdr_destroy (&xdr);
-
-        DEBUG("Total %d", msg->bufferOffset);
-    }
-    if (data)
-        msg->streamTX = 1;
-
-    /* Reset ready for I/O */
-    msg->bufferLength = msg->bufferOffset;
-    msg->bufferOffset = 0;
-
-    /* Put reply on end of tx queue to send out  */
-    qemudClientMessageQueuePush(&client->tx, msg);
-    qemudUpdateClientEvent(client);
-
-    return 0;
-
-xdr_error:
-    xdr_destroy (&xdr);
-fatal_error:
-    VIR_FREE(msg);
-    VIR_WARN("Failed to serialize stream data for proc %d as XDR",
-             stream->procedure);
-    return -1;
-}
diff --git a/daemon/dispatch.h b/daemon/dispatch.h
deleted file mode 100644
index 85f8fc3..0000000
--- a/daemon/dispatch.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * dispatch.h: RPC message dispatching infrastructure
- *
- * Copyright (C) 2007, 2008, 2009 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
- *
- * Author: Richard W.M. Jones <rjones at redhat.com>
- * Author: Daniel P. Berrange <berrange at redhat.com>
- */
-
-#ifndef __LIBVIRTD_DISPATCH_H__
-# define __LIBVIRTD_DISPATCH_H__
-
-
-# include "libvirtd.h"
-
-
-int
-remoteDecodeClientMessageHeader (struct qemud_client_message *req);
-int
-remoteEncodeClientMessageHeader (struct qemud_client_message *req);
-
-int
-remoteDispatchClientRequest (struct qemud_server *server,
-                             struct qemud_client *client,
-                             struct qemud_client_message *req);
-
-
-void remoteDispatchFormatError (remote_error *rerr,
-                                const char *fmt, ...)
-    ATTRIBUTE_FMT_PRINTF(2, 3);
-
-void remoteDispatchAuthError (remote_error *rerr);
-void remoteDispatchGenericError (remote_error *rerr);
-void remoteDispatchOOMError (remote_error *rerr);
-void remoteDispatchConnError (remote_error *rerr,
-                              virConnectPtr conn);
-
-
-int
-remoteSerializeReplyError(struct qemud_client *client,
-                          remote_error *rerr,
-                          remote_message_header *req);
-int
-remoteSerializeStreamError(struct qemud_client *client,
-                           remote_error *rerr,
-                           int proc,
-                           int serial);
-
-
-int
-remoteSendStreamData(struct qemud_client *client,
-                     struct qemud_client_stream *stream,
-                     const char *data,
-                     unsigned int len);
-
-#endif /* __LIBVIRTD_DISPATCH_H__ */
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 2df9337..0203588 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -23,31 +23,13 @@
 
 #include <config.h>
 
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <limits.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <string.h>
-#include <errno.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
 #include <getopt.h>
-#include <fnmatch.h>
+#include <stdlib.h>
 #include <grp.h>
-#include <signal.h>
-#include <netdb.h>
-#include <locale.h>
 
 #include "libvirt_internal.h"
 #include "virterror_internal.h"
@@ -56,16 +38,20 @@
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
 #include "libvirtd.h"
-#include "dispatch.h"
 
 #include "util.h"
-#include "uuid.h"
-#include "remote_driver.h"
-#include "conf.h"
-#include "event.h"
+#include "files.h"
+#include "virterror_internal.h"
+#include "logging.h"
 #include "memory.h"
-#include "stream.h"
+#include "conf.h"
+#include "virnetserver.h"
+#include "threads.h"
+#include "remote.h"
+#include "remote_driver.h"
+//#include "stream.h"
 #include "hooks.h"
+#include "uuid.h"
 #include "virtaudit.h"
 #ifdef HAVE_AVAHI
 # include "mdns.h"
@@ -106,100 +92,57 @@
 # endif
 #endif
 
-
-#ifdef __sun
-# include <ucred.h>
-# include <priv.h>
-
-# ifndef PRIV_VIRT_MANAGE
-#  define PRIV_VIRT_MANAGE ((const char *)"virt_manage")
-# endif
-
-# ifndef PRIV_XVM_CONTROL
-#  define PRIV_XVM_CONTROL ((const char *)"xvm_control")
-# endif
-
-# define PU_RESETGROUPS          0x0001  /* Remove supplemental groups */
-# define PU_CLEARLIMITSET        0x0008  /* L=0 */
-
-extern int __init_daemon_priv(int, uid_t, gid_t, ...);
-
-# define SYSTEM_UID 60
-
-static gid_t unix_sock_gid = 60; /* Not used */
-static int unix_sock_rw_mask = 0666;
-static int unix_sock_ro_mask = 0666;
-
-#else
-
-static gid_t unix_sock_gid = 0; /* Only root by default */
-static int unix_sock_rw_mask = 0700; /* Allow user only */
-static int unix_sock_ro_mask = 0777; /* Allow world */
-
-#endif /* __sun */
-
 #include "configmake.h"
 
-static int godaemon = 0;        /* -d: Be a daemon */
-static int verbose = 0;         /* -v: Verbose mode */
-static int timeout = -1;        /* -t: Shutdown timeout */
-static int sigwrite = -1;       /* Signal handler pipe */
-static int ipsock = 0;          /* -l  Listen for TCP/IP */
-
-/* Defaults for configuration file elements */
-static int listen_tls = 1;
-static int listen_tcp = 0;
-static char *listen_addr  = (char *) LIBVIRTD_LISTEN_ADDR;
-static char *tls_port = (char *) LIBVIRTD_TLS_PORT;
-static char *tcp_port = (char *) LIBVIRTD_TCP_PORT;
+virNetSASLContextPtr saslCtxt = NULL;
+virNetServerProgramPtr remoteProgram = NULL;
+virNetServerProgramPtr qemuProgram = NULL;
 
-static char *unix_sock_dir = NULL;
+struct daemonConfig {
+    char *host_uuid;
 
-#if HAVE_POLKIT
-static int auth_unix_rw = REMOTE_AUTH_POLKIT;
-static int auth_unix_ro = REMOTE_AUTH_POLKIT;
-#else
-static int auth_unix_rw = REMOTE_AUTH_NONE;
-static int auth_unix_ro = REMOTE_AUTH_NONE;
-#endif /* HAVE_POLKIT */
-#if HAVE_SASL
-static int auth_tcp = REMOTE_AUTH_SASL;
-#else
-static int auth_tcp = REMOTE_AUTH_NONE;
-#endif
-static int auth_tls = REMOTE_AUTH_NONE;
+    int listen_tls;
+    int listen_tcp;
+    char *listen_addr;
+    char *tls_port;
+    char *tcp_port;
 
-static int mdns_adv = 1;
-static char *mdns_name = NULL;
+    char *unix_sock_ro_perms;
+    char *unix_sock_rw_perms;
+    char *unix_sock_group;
+    char *unix_sock_dir;
 
-static int tls_no_verify_certificate = 0;
-static char **tls_allowed_dn_list = NULL;
+    int auth_unix_rw;
+    int auth_unix_ro;
+    int auth_tcp;
+    int auth_tls;
 
-static char *key_file = (char *) LIBVIRT_SERVERKEY;
-static char *cert_file = (char *) LIBVIRT_SERVERCERT;
-static char *ca_file = (char *) LIBVIRT_CACERT;
-static char *crl_file = (char *) "";
+    int mdns_adv;
+    char *mdns_name;
 
-static gnutls_certificate_credentials_t x509_cred;
-static gnutls_dh_params_t dh_params;
+    int tls_no_verify_certificate;
+    char **tls_allowed_dn_list;
+    char **sasl_allowed_username_list;
 
-static int min_workers = 5;
-static int max_workers = 20;
-static int max_clients = 20;
+    char *key_file;
+    char *cert_file;
+    char *ca_file;
+    char *crl_file;
 
-/* Total number of 'in-process' RPC calls allowed across all clients */
-static int max_requests = 20;
-/* Total number of 'in-process' RPC calls allowed by a single client*/
-static int max_client_requests = 5;
+    int min_workers;
+    int max_workers;
+    int max_clients;
 
-static int audit_level = 1;
-static int audit_logging = 0;
+    int max_requests;
+    int max_client_requests;
 
-#define DH_BITS 1024
+    int log_level;
+    char *log_filters;
+    char *log_outputs;
 
-static sig_atomic_t sig_errors = 0;
-static int sig_lasterrno = 0;
-static const char *argv0;
+    int audit_level;
+    int audit_logging;
+};
 
 enum {
     VIR_DAEMON_ERR_NONE = 0,
@@ -229,194 +172,9 @@ VIR_ENUM_IMPL(virDaemonErr, VIR_DAEMON_ERR_LAST,
               "Unable to look for hook scripts",
               "Unable to initialize audit system")
 
-static void sig_handler(int sig, siginfo_t * siginfo,
-                        void* context ATTRIBUTE_UNUSED) {
-    int origerrno;
-    int r;
-
-    /* set the sig num in the struct */
-    siginfo->si_signo = sig;
-
-    origerrno = errno;
-    r = safewrite(sigwrite, siginfo, sizeof(*siginfo));
-    if (r == -1) {
-        sig_errors++;
-        sig_lasterrno = errno;
-    }
-    errno = origerrno;
-}
-
-static void qemudDispatchClientEvent(int watch, int fd, int events, void *opaque);
-static void qemudDispatchServerEvent(int watch, int fd, int events, void *opaque);
-static int qemudStartWorker(struct qemud_server *server, struct qemud_worker *worker);
-
-void
-qemudClientMessageQueuePush(struct qemud_client_message **queue,
-                            struct qemud_client_message *msg)
-{
-    struct qemud_client_message *tmp = *queue;
-
-    if (tmp) {
-        while (tmp->next)
-            tmp = tmp->next;
-        tmp->next = msg;
-    } else {
-        *queue = msg;
-    }
-}
-
-struct qemud_client_message *
-qemudClientMessageQueueServe(struct qemud_client_message **queue)
-{
-    struct qemud_client_message *tmp = *queue;
-
-    if (tmp) {
-        *queue = tmp->next;
-        tmp->next = NULL;
-    }
-
-    return tmp;
-}
-
-static int
-remoteCheckCertFile(const char *type, const char *file)
-{
-    struct stat sb;
-    if (stat(file, &sb) < 0) {
-        char ebuf[1024];
-        VIR_ERROR(_("Cannot access %s '%s': %s"),
-                  type, file, virStrerror(errno, ebuf, sizeof ebuf));
-        return -1;
-    }
-    return 0;
-}
 
-static int
-remoteInitializeGnuTLS (void)
+static int daemonForkIntoBackground(const char *argv0)
 {
-    int err;
-
-    /* Initialise GnuTLS. */
-    gnutls_global_init ();
-
-    err = gnutls_certificate_allocate_credentials (&x509_cred);
-    if (err) {
-        VIR_ERROR(_("gnutls_certificate_allocate_credentials: %s"),
-                  gnutls_strerror (err));
-        return -1;
-    }
-
-    if (ca_file && ca_file[0] != '\0') {
-        if (remoteCheckCertFile("CA certificate", ca_file) < 0)
-            return -1;
-
-        qemudDebug ("loading CA cert from %s", ca_file);
-        err = gnutls_certificate_set_x509_trust_file (x509_cred, ca_file,
-                                                      GNUTLS_X509_FMT_PEM);
-        if (err < 0) {
-            VIR_ERROR(_("gnutls_certificate_set_x509_trust_file: %s"),
-                      gnutls_strerror (err));
-            return -1;
-        }
-    }
-
-    if (crl_file && crl_file[0] != '\0') {
-        if (remoteCheckCertFile("CA revocation list", crl_file) < 0)
-            return -1;
-
-        DEBUG("loading CRL from %s", crl_file);
-        err = gnutls_certificate_set_x509_crl_file (x509_cred, crl_file,
-                                                    GNUTLS_X509_FMT_PEM);
-        if (err < 0) {
-            VIR_ERROR(_("gnutls_certificate_set_x509_crl_file: %s"),
-                      gnutls_strerror (err));
-            return -1;
-        }
-    }
-
-    if (cert_file && cert_file[0] != '\0' && key_file && key_file[0] != '\0') {
-        if (remoteCheckCertFile("server certificate", cert_file) < 0)
-            return -1;
-        if (remoteCheckCertFile("server key", key_file) < 0)
-            return -1;
-        DEBUG("loading cert and key from %s and %s", cert_file, key_file);
-        err =
-            gnutls_certificate_set_x509_key_file (x509_cred,
-                                                  cert_file, key_file,
-                                                  GNUTLS_X509_FMT_PEM);
-        if (err < 0) {
-            VIR_ERROR(_("gnutls_certificate_set_x509_key_file: %s"),
-                      gnutls_strerror (err));
-            return -1;
-        }
-    }
-
-    /* Generate Diffie Hellman parameters - for use with DHE
-     * kx algorithms. These should be discarded and regenerated
-     * once a day, once a week or once a month. Depending on the
-     * security requirements.
-     */
-    err = gnutls_dh_params_init (&dh_params);
-    if (err < 0) {
-        VIR_ERROR(_("gnutls_dh_params_init: %s"), gnutls_strerror (err));
-        return -1;
-    }
-    err = gnutls_dh_params_generate2 (dh_params, DH_BITS);
-    if (err < 0) {
-        VIR_ERROR(_("gnutls_dh_params_generate2: %s"), gnutls_strerror (err));
-        return -1;
-    }
-
-    gnutls_certificate_set_dh_params (x509_cred, dh_params);
-
-    return 0;
-}
-
-static void
-qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
-                         int fd ATTRIBUTE_UNUSED,
-                         int events ATTRIBUTE_UNUSED,
-                         void *opaque) {
-    struct qemud_server *server = (struct qemud_server *)opaque;
-    siginfo_t siginfo;
-
-    virMutexLock(&server->lock);
-
-    if (saferead(server->sigread, &siginfo, sizeof(siginfo)) != sizeof(siginfo)) {
-        char ebuf[1024];
-        VIR_ERROR(_("Failed to read from signal pipe: %s"),
-                  virStrerror(errno, ebuf, sizeof ebuf));
-        virMutexUnlock(&server->lock);
-        return;
-    }
-
-    switch (siginfo.si_signo) {
-    case SIGHUP:
-        VIR_INFO0(_("Reloading configuration on SIGHUP"));
-        virHookCall(VIR_HOOK_DRIVER_DAEMON, "-",
-                    VIR_HOOK_DAEMON_OP_RELOAD, SIGHUP, "SIGHUP", NULL);
-        if (virStateReload() < 0)
-            VIR_WARN0("Error while reloading drivers");
-
-        break;
-
-    case SIGINT:
-    case SIGQUIT:
-    case SIGTERM:
-        VIR_WARN("Shutting down on signal %d", siginfo.si_signo);
-        server->quitEventThread = 1;
-        break;
-
-    default:
-        VIR_INFO(_("Received unexpected signal %d"), siginfo.si_signo);
-        break;
-    }
-
-    virMutexUnlock(&server->lock);
-}
-
-
-static int daemonForkIntoBackground(void) {
     int statuspipe[2];
     if (pipe(statuspipe) < 0)
         return -1;
@@ -501,7 +259,8 @@ static int daemonForkIntoBackground(void) {
     }
 }
 
-static int qemudWritePidFile(const char *pidFile) {
+static int daemonWritePidFile(const char *pidFile, const char *argv0)
+{
     int fd;
     FILE *fh;
     char ebuf[1024];
@@ -538,325 +297,84 @@ static int qemudWritePidFile(const char *pidFile) {
     return 0;
 }
 
-static int qemudListenUnix(struct qemud_server *server,
-                           char *path, int readonly, int auth) {
-    struct qemud_socket *sock;
-    mode_t oldmask;
-    gid_t oldgrp;
-    char ebuf[1024];
-
-    if (VIR_ALLOC(sock) < 0) {
-        VIR_ERROR0(_("Failed to allocate memory for struct qemud_socket"));
-        return -1;
-    }
-
-    sock->readonly = readonly;
-    sock->type = QEMUD_SOCK_TYPE_UNIX;
-    sock->auth = auth;
-    sock->path = path;
-    sock->addr.len = sizeof(sock->addr.data.un);
-    if (!(sock->addrstr = strdup(path))) {
-        VIR_ERROR(_("Failed to copy socket address: %s"),
-                  virStrerror(errno, ebuf, sizeof ebuf));
-        goto cleanup;
-    }
-
-    if ((sock->fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
-        VIR_ERROR(_("Failed to create socket: %s"),
-                  virStrerror(errno, ebuf, sizeof ebuf));
-        goto cleanup;
-    }
-
-    if (virSetCloseExec(sock->fd) < 0 ||
-        virSetNonBlock(sock->fd) < 0)
-        goto cleanup;
-
-    sock->addr.data.un.sun_family = AF_UNIX;
-    if (virStrcpyStatic(sock->addr.data.un.sun_path, path) == NULL) {
-        VIR_ERROR(_("Path %s too long for unix socket"), path);
-        goto cleanup;
-    }
-    if (sock->addr.data.un.sun_path[0] == '@')
-        sock->addr.data.un.sun_path[0] = '\0';
-
-    oldgrp = getgid();
-    oldmask = umask(readonly ? ~unix_sock_ro_mask : ~unix_sock_rw_mask);
-    if (server->privileged && setgid(unix_sock_gid)) {
-        VIR_ERROR(_("Failed to set group ID to %d"), unix_sock_gid);
-        goto cleanup;
-    }
-
-    if (bind(sock->fd, &sock->addr.data.sa, sock->addr.len) < 0) {
-        VIR_ERROR(_("Failed to bind socket to '%s': %s"),
-                  path, virStrerror(errno, ebuf, sizeof ebuf));
-        goto cleanup;
-    }
-    umask(oldmask);
-    if (server->privileged && setgid(oldgrp)) {
-        VIR_ERROR(_("Failed to restore group ID to %d"), oldgrp);
-        goto cleanup;
-    }
-
-    if (listen(sock->fd, 30) < 0) {
-        VIR_ERROR(_("Failed to listen for connections on '%s': %s"),
-                  path, virStrerror(errno, ebuf, sizeof ebuf));
-        goto cleanup;
-    }
-
-    sock->next = server->sockets;
-    server->sockets = sock;
-    server->nsockets++;
-
-    return 0;
-
- cleanup:
-    VIR_FORCE_CLOSE(sock->fd);
-    VIR_FREE(sock);
-    return -1;
-}
-
-// See: http://people.redhat.com/drepper/userapi-ipv6.html
-static int
-remoteMakeSockets (int *fds, int max_fds, int *nfds_r, const char *node, const char *service)
-{
-    struct addrinfo *ai;
-    struct addrinfo hints;
-    memset (&hints, 0, sizeof hints);
-    hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
-    hints.ai_socktype = SOCK_STREAM;
-
-    int e = getaddrinfo (node, service, &hints, &ai);
-    if (e != 0) {
-        VIR_ERROR(_("getaddrinfo: %s"), gai_strerror (e));
-        return -1;
-    }
-
-    struct addrinfo *runp = ai;
-    while (runp && *nfds_r < max_fds) {
-        char ebuf[1024];
-        fds[*nfds_r] = socket (runp->ai_family, runp->ai_socktype,
-                               runp->ai_protocol);
-        if (fds[*nfds_r] == -1) {
-            VIR_ERROR(_("socket: %s"), virStrerror (errno, ebuf, sizeof ebuf));
-            return -1;
-        }
-
-        int opt = 1;
-        setsockopt (fds[*nfds_r], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt);
-
-#ifdef IPV6_V6ONLY
-        if (runp->ai_family == PF_INET6) {
-            int on = 1;
-            /*
-             * Normally on Linux an INET6 socket will bind to the INET4
-             * address too. If getaddrinfo returns results with INET4
-             * first though, this will result in INET6 binding failing.
-             * We can trivially cope with multiple server sockets, so
-             * we force it to only listen on IPv6
-             */
-            setsockopt(fds[*nfds_r], IPPROTO_IPV6,IPV6_V6ONLY,
-                       (void*)&on, sizeof on);
-        }
-#endif
-
-        if (bind (fds[*nfds_r], runp->ai_addr, runp->ai_addrlen) == -1) {
-            if (errno != EADDRINUSE) {
-                VIR_ERROR(_("bind: %s"), virStrerror (errno, ebuf, sizeof ebuf));
-                return -1;
-            }
-            VIR_FORCE_CLOSE(fds[*nfds_r]);
-        } else {
-            ++*nfds_r;
-        }
-        runp = runp->ai_next;
-    }
 
-    freeaddrinfo (ai);
-    return 0;
-}
-
-/* Listen on the named/numbered TCP port.  On a machine with IPv4 and
- * IPv6 interfaces this may generate several sockets.
- */
 static int
-remoteListenTCP (struct qemud_server *server,
-                 const char *addr,
-                 const char *port,
-                 int type,
-                 int auth)
+daemonPidFilePath(bool privileged,
+                  char **pidfile)
 {
-    int fds[2];
-    int nfds = 0;
-    int i;
-    struct qemud_socket *sock;
-
-    if (remoteMakeSockets (fds, 2, &nfds, addr, port) == -1)
-        return -1;
-
-    for (i = 0; i < nfds; ++i) {
-        char ebuf[1024];
-
-        if (VIR_ALLOC(sock) < 0) {
-            VIR_ERROR(_("remoteListenTCP: calloc: %s"),
-                      virStrerror (errno, ebuf, sizeof ebuf));
-            goto cleanup;
-        }
-
-        sock->addr.len = sizeof(sock->addr.data.stor);
-        sock->readonly = 0;
-        sock->next = server->sockets;
-        server->sockets = sock;
-        server->nsockets++;
-
-        sock->fd = fds[i];
-        sock->type = type;
-        sock->auth = auth;
-
-        if (getsockname(sock->fd, &sock->addr.data.sa, &sock->addr.len) < 0)
-            goto cleanup;
+    if (privileged) {
+        if (!(*pidfile = strdup(LOCALSTATEDIR "/run/libvirtd.pid")))
+            goto no_memory;
+    } else {
+        char *userdir = NULL;
 
-        if (!(sock->addrstr = virSocketFormatAddrFull(&sock->addr, true, ";")))
-            goto cleanup;
+        if (!(userdir = virGetUserDirectory(geteuid())))
+            goto error;
 
-        if (virSetCloseExec(sock->fd) < 0 ||
-            virSetNonBlock(sock->fd) < 0)
-            goto cleanup;
+        if (virAsprintf(pidfile, "%s/.libvirt/libvirtd.pid", userdir) < 0)
+            goto no_memory;
 
-        if (listen (sock->fd, 30) < 0) {
-            VIR_ERROR(_("remoteListenTCP: listen: %s"),
-                      virStrerror (errno, ebuf, sizeof ebuf));
-            goto cleanup;
-        }
+        VIR_FREE(userdir);
     }
 
     return 0;
 
-cleanup:
-    for (i = 0; i < nfds; ++i)
-        VIR_FORCE_CLOSE(fds[i]);
+no_memory:
+    virReportOOMError();
+error:
     return -1;
 }
 
-static int qemudInitPaths(struct qemud_server *server,
-                          char **sockname,
-                          char **roSockname)
+static int
+daemonUnixSocketPaths(struct daemonConfig *config,
+                      bool privileged,
+                      char **sockfile,
+                      char **rosockfile)
 {
-    char *base_dir_prefix = NULL;
-    char *sock_dir_prefix = NULL;
-    int ret = -1;
-
-    /* The base_dir_prefix is the base under which all libvirtd
-     * files live */
-    if (server->privileged) {
-        if (!(base_dir_prefix = strdup (LOCALSTATEDIR)))
+    if (config->unix_sock_dir) {
+        if (virAsprintf(sockfile, "%s/libvirt-sock", config->unix_sock_dir) < 0)
             goto no_memory;
-    } else {
-        uid_t uid = geteuid();
-        if (!(base_dir_prefix = virGetUserDirectory(uid)))
-            goto cleanup;
-    }
-
-    /* The unix_sock_dir is the location under which all
-     * unix domain sockets live */
-    if (unix_sock_dir) {
-        if (!(sock_dir_prefix = strdup(unix_sock_dir)))
+        if (privileged &&
+            virAsprintf(rosockfile, "%s/libvirt-sock-ro", config->unix_sock_dir) < 0)
             goto no_memory;
-
-        /* Change the group ownership of /var/run/libvirt to unix_sock_gid */
-        if (server->privileged) {
-            if (chown(unix_sock_dir, -1, unix_sock_gid) < 0)
-                VIR_ERROR(_("Failed to change group ownership of %s"),
-                          unix_sock_dir);
-        }
     } else {
-        if (server->privileged) {
-            if (virAsprintf(&sock_dir_prefix, "%s/run/libvirt",
-                            base_dir_prefix) < 0)
+        if (privileged) {
+            if (!(*sockfile = strdup(LOCALSTATEDIR "/run/libvirt/libvirt-sock")))
                 goto no_memory;
-        } else {
-            if (virAsprintf(&sock_dir_prefix, "%s/.libvirt",
-                            base_dir_prefix) < 0)
+            if (!(*rosockfile = strdup(LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro")))
                 goto no_memory;
-        }
-    }
+        } else {
+            char *userdir = NULL;
 
-    if (server->privileged) {
-        if (virAsprintf(sockname, "%s/libvirt-sock",
-                        sock_dir_prefix) < 0)
-            goto no_memory;
-        if (virAsprintf(roSockname, "%s/libvirt-sock-ro",
-                        sock_dir_prefix) < 0)
-            goto no_memory;
-        unlink(*sockname);
-        unlink(*roSockname);
-    } else {
-        if (virAsprintf(sockname, "@%s/libvirt-sock",
-                        sock_dir_prefix) < 0)
-            goto no_memory;
-        /* There is no RO socket in unprivileged mode,
-         * since the user always has full RW access
-         * to their private instance */
-    }
+            if (!(userdir = virGetUserDirectory(geteuid())))
+                goto error;
 
-    if (server->privileged) {
-        if (virAsprintf(&server->logDir, "%s/log/libvirt",
-                        base_dir_prefix) < 0)
-            goto no_memory;
-    } else {
-        if (virAsprintf(&server->logDir, "%s/.libvirt/log",
-                        base_dir_prefix) < 0)
-            goto no_memory;
-    }
+            if (virAsprintf(sockfile, "@%s/.libvirt/libvirt-sock", userdir) < 0) {
+                VIR_FREE(userdir);
+                goto no_memory;
+            }
 
-    ret = 0;
+            VIR_FREE(userdir);
+        }
+    }
+    return 0;
 
 no_memory:
-    if (ret != 0)
-        virReportOOMError();
-
- cleanup:
-    VIR_FREE(base_dir_prefix);
-    VIR_FREE(sock_dir_prefix);
-    return ret;
+    virReportOOMError();
+error:
+    return -1;
 }
 
-static void virshErrorHandler(void *opaque ATTRIBUTE_UNUSED, virErrorPtr err ATTRIBUTE_UNUSED)
+
+static void daemonErrorHandler(void *opaque ATTRIBUTE_UNUSED,
+                               virErrorPtr err ATTRIBUTE_UNUSED)
 {
     /* Don't do anything, since logging infrastructure already
      * took care of reporting the error */
 }
 
-static struct qemud_server *qemudInitialize(void) {
-    struct qemud_server *server;
-
-    if (VIR_ALLOC(server) < 0) {
-        VIR_ERROR0(_("Failed to allocate struct qemud_server"));
-        return NULL;
-    }
-
-    server->privileged = geteuid() == 0 ? 1 : 0;
-    server->sigread = server->sigwrite = -1;
-
-    if (virMutexInit(&server->lock) < 0) {
-        VIR_ERROR0(_("cannot initialize mutex"));
-        VIR_FREE(server);
-        return NULL;
-    }
-    if (virCondInit(&server->job) < 0) {
-        VIR_ERROR0(_("cannot initialize condition variable"));
-        virMutexDestroy(&server->lock);
-        VIR_FREE(server);
-        return NULL;
-    }
-
-    if (virEventInit() < 0) {
-        VIR_ERROR0(_("Failed to initialize event system"));
-        virMutexDestroy(&server->lock);
-        if (virCondDestroy(&server->job) < 0)
-        {}
-        VIR_FREE(server);
-        return NULL;
-    }
+static void daemonInitialize(void)
+{
 
     /*
      * Note that the order is important: the first ones have a higher
@@ -912,83 +430,104 @@ static struct qemud_server *qemudInitialize(void) {
     oneRegister();
 # endif
 #endif
-
-    virEventRegisterImpl(virEventAddHandleImpl,
-                         virEventUpdateHandleImpl,
-                         virEventRemoveHandleImpl,
-                         virEventAddTimeoutImpl,
-                         virEventUpdateTimeoutImpl,
-                         virEventRemoveTimeoutImpl);
-
-    return server;
 }
 
-static int qemudNetworkInit(struct qemud_server *server) {
-    char *sockname = NULL;
-    char *roSockname = NULL;
-#if HAVE_SASL
-    int err;
-#endif /* HAVE_SASL */
+static int daemonSetupNetworking(virNetServerPtr srv,
+                                 struct daemonConfig *config,
+                                 const char *sock_path,
+                                 const char *sock_path_ro,
+                                 bool ipsock)
+{
+    virNetServerServicePtr svc = NULL;
+    virNetServerServicePtr svcRO = NULL;
+    virNetServerServicePtr svcTCP = NULL;
+    virNetServerServicePtr svcTLS = NULL;
+    gid_t unix_sock_gid = 0;
+    int unix_sock_ro_mask = 0;
+    int unix_sock_rw_mask = 0;
+
+    if (config->unix_sock_group) {
+        if (!virNetServerIsPrivileged(srv)) {
+            VIR_WARN0("Cannot set group when not running as root");
+            return -1;
+        }
+        if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0)
+            return -1;
+    }
 
-    if (qemudInitPaths(server, &sockname, &roSockname) < 0)
-        goto cleanup;
+    if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) {
+        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms);
+        goto error;
+    }
 
-    if (qemudListenUnix(server, sockname, 0, auth_unix_rw) < 0)
-        goto cleanup;
-    sockname = NULL;
+    if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
+        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms);
+        goto error;
+    }
 
-    if (roSockname != NULL && qemudListenUnix(server, roSockname, 1, auth_unix_ro) < 0)
-        goto cleanup;
-    roSockname = NULL;
+    if (!(svc = virNetServerServiceNewUNIX(sock_path,
+                                           unix_sock_rw_mask,
+                                           unix_sock_gid,
+                                           config->auth_unix_rw,
+                                           false,
+                                           NULL)))
+        goto error;
+    if (sock_path_ro &&
+        !(svcRO = virNetServerServiceNewUNIX(sock_path_ro,
+                                             unix_sock_ro_mask,
+                                             unix_sock_gid,
+                                             config->auth_unix_ro,
+                                             true,
+                                             NULL)))
+        goto error;
 
-#if HAVE_SASL
-    if (auth_unix_rw == REMOTE_AUTH_SASL ||
-        auth_unix_ro == REMOTE_AUTH_SASL ||
-        auth_tcp == REMOTE_AUTH_SASL ||
-        auth_tls == REMOTE_AUTH_SASL) {
-        if ((err = sasl_server_init(NULL, "libvirt")) != SASL_OK) {
-            VIR_ERROR(_("Failed to initialize SASL authentication %s"),
-                      sasl_errstring(err, NULL, NULL));
-            goto cleanup;
-        }
-    }
-#endif
+    if (virNetServerAddService(srv, svc) < 0)
+        goto error;
+    if (svcRO &&
+        virNetServerAddService(srv, svcRO) < 0)
+        goto error;
 
-#if HAVE_POLKIT0
-    if (auth_unix_rw == REMOTE_AUTH_POLKIT ||
-        auth_unix_ro == REMOTE_AUTH_POLKIT) {
-        DBusError derr;
+    if (ipsock) {
+        if (config->listen_tcp &&
+            !(svcTCP = virNetServerServiceNewTCP(config->listen_addr,
+                                                 config->tcp_port,
+                                                 config->auth_tcp,
+                                                 false,
+                                                 NULL)))
+            goto error;
 
-        dbus_connection_set_change_sigpipe(FALSE);
-        dbus_threads_init_default();
+        if (virNetServerAddService(srv, svcTCP) < 0)
+            goto error;
 
-        dbus_error_init(&derr);
-        server->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr);
-        if (!(server->sysbus)) {
-            VIR_ERROR(_("Failed to connect to system bus for PolicyKit auth: %s"),
-                      derr.message);
-            dbus_error_free(&derr);
-            goto cleanup;
-        }
-        dbus_connection_set_exit_on_disconnect(server->sysbus, FALSE);
-    }
-#endif
+        if (config->listen_tls) {
+            virNetTLSContextPtr ctxt = NULL;
 
-    if (ipsock) {
-        if (listen_tcp && remoteListenTCP (server, listen_addr, tcp_port, QEMUD_SOCK_TYPE_TCP, auth_tcp) < 0)
-            goto cleanup;
+            if (!(ctxt = virNetTLSContextNewServer(config->ca_file,
+                                                   config->crl_file,
+                                                   config->cert_file,
+                                                   config->key_file,
+                                                   (const char *const*)config->tls_allowed_dn_list,
+                                                   config->tls_no_verify_certificate ? false : true)))
+                goto error;
 
-        if (listen_tls) {
-            if (remoteInitializeGnuTLS () < 0)
-                goto cleanup;
+            if (!(svcTLS =
+                  virNetServerServiceNewTCP(config->listen_addr,
+                                            config->tls_port,
+                                            config->auth_tls,
+                                            false,
+                                            ctxt))) {
+                virNetTLSContextFree(ctxt);
+                goto error;
+            }
+            if (virNetServerAddService(srv, svcTLS) < 0)
+                goto error;
 
-            if (remoteListenTCP (server, listen_addr, tls_port, QEMUD_SOCK_TYPE_TLS, auth_tls) < 0)
-                goto cleanup;
+            virNetTLSContextFree(ctxt);
         }
     }
 
-#ifdef HAVE_AVAHI
-    if (server->privileged && mdns_adv) {
+#ifdef HAVE_AVAHIXXXXXXXXXXXXX
+    if (virNetServerIsPrivileged(srv) && mdns_adv) {
         struct libvirtd_mdns_group *group;
         struct qemud_socket *sock;
         int port = 0;
@@ -1016,7 +555,7 @@ static int qemudNetworkInit(struct qemud_server *server) {
             VIR_FREE(localhost);
             if (ret < 0) {
                 virReportOOMError();
-                goto cleanup;
+                goto error;
             }
             group = libvirtd_mdns_add_group(server->mdns, groupname);
             VIR_FREE(groupname);
@@ -1048,235 +587,47 @@ static int qemudNetworkInit(struct qemud_server *server) {
     }
 #endif
 
-    return 0;
-
- cleanup:
-    VIR_FREE(sockname);
-    VIR_FREE(roSockname);
-    return -1;
-}
-
-static int qemudNetworkEnable(struct qemud_server *server) {
-    struct qemud_socket *sock;
-
-    sock = server->sockets;
-    while (sock) {
-        if ((sock->watch = virEventAddHandleImpl(sock->fd,
-                                                 VIR_EVENT_HANDLE_READABLE |
-                                                 VIR_EVENT_HANDLE_ERROR |
-                                                 VIR_EVENT_HANDLE_HANGUP,
-                                                 qemudDispatchServerEvent,
-                                                 server, NULL)) < 0) {
-            VIR_ERROR0(_("Failed to add server event callback"));
-            return -1;
-        }
-
-        sock = sock->next;
-    }
-    return 0;
-}
-
-
-static gnutls_session_t
-remoteInitializeTLSSession (void)
-{
-    gnutls_session_t session;
-    int err;
-
-    err = gnutls_init (&session, GNUTLS_SERVER);
-    if (err != 0) goto failed;
-
-    /* avoid calling all the priority functions, since the defaults
-     * are adequate.
-     */
-    err = gnutls_set_default_priority (session);
-    if (err != 0) goto failed;
-
-    err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred);
-    if (err != 0) goto failed;
-
-    /* request client certificate if any.
-     */
-    gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST);
-
-    gnutls_dh_set_prime_bits (session, DH_BITS);
-
-    return session;
-
-failed:
-    VIR_ERROR(_("remoteInitializeTLSSession: %s"),
-              gnutls_strerror (err));
-    return NULL;
-}
-
-/* Check DN is on tls_allowed_dn_list. */
-static int
-remoteCheckDN (const char *dname)
-{
-    char **wildcards;
-
-    /* If the list is not set, allow any DN. */
-    wildcards = tls_allowed_dn_list;
-    if (!wildcards)
-        return 1;
-
-    while (*wildcards) {
-        if (fnmatch (*wildcards, dname, 0) == 0)
-            return 1;
-        wildcards++;
-    }
-
-    /* Print the client's DN. */
-    DEBUG(_("remoteCheckDN: failed: client DN is %s"), dname);
-
-    return 0; // Not found.
-}
-
-static int
-remoteCheckCertificate(struct qemud_client *client)
-{
-    int ret;
-    unsigned int status;
-    const gnutls_datum_t *certs;
-    unsigned int nCerts, i;
-    time_t now;
-    char name[256];
-    size_t namesize = sizeof name;
-
-    memset(name, 0, namesize);
-
-    if ((ret = gnutls_certificate_verify_peers2 (client->tlssession, &status)) < 0){
-        VIR_ERROR(_("Failed to verify certificate peers: %s"),
-                  gnutls_strerror (ret));
-        goto authdeny;
-    }
-
-    if (status != 0) {
-        if (status & GNUTLS_CERT_INVALID)
-            VIR_ERROR0(_("The client certificate is not trusted."));
-
-        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-            VIR_ERROR0(_("The client certificate has unknown issuer."));
-
-        if (status & GNUTLS_CERT_REVOKED)
-            VIR_ERROR0(_("The client certificate has been revoked."));
-
-#ifndef GNUTLS_1_0_COMPAT
-        if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
-            VIR_ERROR0(_("The client certificate uses an insecure algorithm."));
-#endif
-
-        goto authdeny;
-    }
-
-    if (gnutls_certificate_type_get(client->tlssession) != GNUTLS_CRT_X509) {
-        VIR_ERROR0(_("Only x509 certificates are supported"));
-        goto authdeny;
-    }
 
-    if (!(certs = gnutls_certificate_get_peers(client->tlssession, &nCerts))) {
-        VIR_ERROR0(_("The certificate has no peers"));
-        goto authdeny;
+    if (config->auth_unix_rw == REMOTE_AUTH_SASL ||
+        config->auth_unix_ro == REMOTE_AUTH_SASL ||
+        config->auth_tcp == REMOTE_AUTH_SASL ||
+        config->auth_tls == REMOTE_AUTH_SASL) {
+        saslCtxt = virNetSASLContextNewServer(
+            (const char *const*)config->sasl_allowed_username_list);
+        if (!saslCtxt)
+            goto error;
     }
 
-    now = time (NULL);
-
-    for (i = 0; i < nCerts; i++) {
-        gnutls_x509_crt_t cert;
-
-        if (gnutls_x509_crt_init (&cert) < 0) {
-            VIR_ERROR0(_("Unable to initialize certificate"));
-            goto authfail;
-        }
-
-        if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
-            VIR_ERROR0(_("Unable to load certificate"));
-            gnutls_x509_crt_deinit (cert);
-            goto authfail;
-        }
-
-        if (i == 0) {
-            ret = gnutls_x509_crt_get_dn (cert, name, &namesize);
-            if (ret != 0) {
-                VIR_ERROR(_("Failed to get certificate distinguished name: %s"),
-                          gnutls_strerror(ret));
-                gnutls_x509_crt_deinit (cert);
-                goto authfail;
-            }
-
-            if (!remoteCheckDN (name)) {
-                /* This is the most common error: make it informative. */
-                VIR_ERROR0(_("Client's Distinguished Name is not on the list "
-                             "of allowed clients (tls_allowed_dn_list).  Use "
-                             "'certtool -i --infile clientcert.pem' to view the"
-                             "Distinguished Name field in the client certificate,"
-                             "or run this daemon with --verbose option."));
-                gnutls_x509_crt_deinit (cert);
-                goto authdeny;
-            }
-        }
+#if HAVE_POLKIT0
+    if (auth_unix_rw == REMOTE_AUTH_POLKIT ||
+        auth_unix_ro == REMOTE_AUTH_POLKIT) {
+        DBusError derr;
 
-        if (gnutls_x509_crt_get_expiration_time (cert) < now) {
-            VIR_ERROR0(_("The client certificate has expired"));
-            gnutls_x509_crt_deinit (cert);
-            goto authdeny;
-        }
+        dbus_connection_set_change_sigpipe(FALSE);
+        dbus_threads_init_default();
 
-        if (gnutls_x509_crt_get_activation_time (cert) > now) {
-            VIR_ERROR0(_("The client certificate is not yet active"));
-            gnutls_x509_crt_deinit (cert);
-            goto authdeny;
+        dbus_error_init(&derr);
+        server->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr);
+        if (!(server->sysbus)) {
+            VIR_ERROR(_("Failed to connect to system bus for PolicyKit auth: %s"),
+                      derr.message);
+            dbus_error_free(&derr);
+            goto error;
         }
+        dbus_connection_set_exit_on_disconnect(server->sysbus, FALSE);
     }
+#endif
 
-    PROBE(CLIENT_TLS_ALLOW, "fd=%d, name=%s", client->fd, (char *)name);
     return 0;
 
-authdeny:
-    PROBE(CLIENT_TLS_DENY, "fd=%d, name=%s", client->fd, (char *)name);
-    return -1;
-
-authfail:
-    PROBE(CLIENT_TLS_FAIL, "fd=%d", client->fd);
+error:
+    virNetServerServiceFree(svcTLS);
+    virNetServerServiceFree(svcTCP);
+    virNetServerServiceFree(svc);
+    virNetServerServiceFree(svcRO);
     return -1;
 }
 
-/* Check the client's access. */
-static int
-remoteCheckAccess (struct qemud_client *client)
-{
-    struct qemud_client_message *confirm;
-
-    /* Verify client certificate. */
-    if (remoteCheckCertificate (client) == -1) {
-        VIR_ERROR0(_("remoteCheckCertificate: "
-                     "failed to verify client's certificate"));
-        if (!tls_no_verify_certificate) return -1;
-        else VIR_INFO0(_("remoteCheckCertificate: tls_no_verify_certificate "
-                          "is set so the bad certificate is ignored"));
-    }
-
-    if (client->tx) {
-        VIR_INFO("%s",
-                 _("client had unexpected data pending tx after access check"));
-        return -1;
-    }
-
-    if (VIR_ALLOC(confirm) < 0)
-        return -1;
-
-    /* Checks have succeeded.  Write a '\1' byte back to the client to
-     * indicate this (otherwise the socket is abruptly closed).
-     * (NB. The '\1' byte is sent in an encrypted record).
-     */
-    confirm->async = 1;
-    confirm->bufferLength = 1;
-    confirm->bufferOffset = 0;
-    confirm->buffer[0] = '\1';
-
-    client->tx = confirm;
-    return 0;
-}
 
 #if HAVE_POLKIT
 int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid) {
@@ -1295,1211 +646,52 @@ int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid) {
     *uid = cr.uid;
 # else
     /* XXX Many more OS support UNIX socket credentials we could port to. See dbus ....*/
-#  error "UNIX socket credentials not supported/implemented on this platform yet..."
-# endif
-    return 0;
-}
-#endif
-
-
-static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket *sock) {
-    int fd;
-    virSocketAddr addr;
-    char *addrstr = NULL;
-    struct qemud_client *client = NULL;
-    int no_slow_start = 1;
-    int i;
-
-    addr.len = sizeof(addr.data.stor);
-    if ((fd = accept(sock->fd, &addr.data.sa, &addr.len)) < 0) {
-        char ebuf[1024];
-        if (errno == EAGAIN)
-            return 0;
-        VIR_ERROR(_("Failed to accept connection: %s"),
-                  virStrerror(errno, ebuf, sizeof ebuf));
-        return -1;
-    }
-    if (!(addrstr = virSocketFormatAddrFull(&addr, true, ";"))) {
-        VIR_ERROR0(_("Failed to format addresss: out of memory"));
-        goto error;
-    }
-
-    PROBE(CLIENT_CONNECT, "fd=%d, readonly=%d localAddr=%s remoteAddr=%s",
-          fd, sock->readonly, sock->addrstr, addrstr);
-
-    if (server->nclients >= max_clients) {
-        VIR_ERROR(_("Too many active clients (%d), dropping connection from %s"),
-                  max_clients, addrstr);
-        goto error;
-    }
-
-    if (VIR_RESIZE_N(server->clients, server->nclients_max,
-                     server->nclients, 1) < 0) {
-        VIR_ERROR0(_("Out of memory allocating clients"));
-        goto error;
-    }
-
-#ifdef __sun
-    {
-        ucred_t *ucred = NULL;
-        const priv_set_t *privs;
-
-        if (getpeerucred (fd, &ucred) == -1 ||
-            (privs = ucred_getprivset (ucred, PRIV_EFFECTIVE)) == NULL) {
-            if (ucred != NULL)
-                ucred_free (ucred);
-            goto error;
-        }
-
-        if (!priv_ismember (privs, PRIV_VIRT_MANAGE)) {
-            ucred_free (ucred);
-            goto error;
-        }
-
-        ucred_free (ucred);
-    }
-#endif /* __sun */
-
-    /* Disable Nagle.  Unix sockets will ignore this. */
-    setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_slow_start,
-                sizeof no_slow_start);
-
-    if (virSetCloseExec(fd) < 0 ||
-        virSetNonBlock(fd) < 0) {
-        goto error;
-    }
-
-    if (VIR_ALLOC(client) < 0)
-        goto error;
-    if (virMutexInit(&client->lock) < 0) {
-        VIR_ERROR0(_("cannot initialize mutex"));
-        goto error;
-    }
-
-    client->magic = QEMUD_CLIENT_MAGIC;
-    client->fd = fd;
-    client->readonly = sock->readonly;
-    client->type = sock->type;
-    client->auth = sock->auth;
-    client->addr = addr;
-    client->addrstr = addrstr;
-    addrstr = NULL;
-
-    for (i = 0 ; i < VIR_DOMAIN_EVENT_ID_LAST ; i++) {
-        client->domainEventCallbackID[i] = -1;
-    }
-
-    /* Prepare one for packet receive */
-    if (VIR_ALLOC(client->rx) < 0)
-        goto error;
-    client->rx->bufferLength = REMOTE_MESSAGE_HEADER_XDR_LEN;
-
-
-#if HAVE_POLKIT
-    /* Only do policy checks for non-root - allow root user
-       through with no checks, as a fail-safe - root can easily
-       change policykit policy anyway, so its pointless trying
-       to restrict root */
-    if (client->auth == REMOTE_AUTH_POLKIT) {
-        uid_t uid;
-        pid_t pid;
-
-        if (qemudGetSocketIdentity(client->fd, &uid, &pid) < 0)
-            goto error;
-
-        /* Client is running as root, so disable auth */
-        if (uid == 0) {
-            VIR_INFO(_("Turn off polkit auth for privileged client pid %d from %s"),
-                     pid, client->addrstr);
-            client->auth = REMOTE_AUTH_NONE;
-        }
-    }
-#endif
-
-    if (client->type != QEMUD_SOCK_TYPE_TLS) {
-        /* Plain socket, so prepare to read first message */
-        if (qemudRegisterClientEvent (server, client) < 0)
-            goto error;
-    } else {
-        int ret;
-
-        client->tlssession = remoteInitializeTLSSession ();
-        if (client->tlssession == NULL)
-            goto error;
-
-        gnutls_transport_set_ptr (client->tlssession,
-                                  (gnutls_transport_ptr_t) (long) fd);
-
-        /* Begin the TLS handshake. */
-        ret = gnutls_handshake (client->tlssession);
-        if (ret == 0) {
-            client->handshake = 0;
-
-            /* Unlikely, but ...  Next step is to check the certificate. */
-            if (remoteCheckAccess (client) == -1)
-                goto error;
-
-            /* Handshake & cert check OK,  so prepare to read first message */
-            if (qemudRegisterClientEvent(server, client) < 0)
-                goto error;
-        } else if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
-            /* Most likely, need to do more handshake data */
-            client->handshake = 1;
-
-            if (qemudRegisterClientEvent (server, client) < 0)
-                goto error;
-        } else {
-            PROBE(CLIENT_TLS_FAIL, "fd=%d", client->fd);
-            VIR_ERROR(_("TLS handshake failed for client %s: %s"),
-                      client->addrstr, gnutls_strerror (ret));
-            goto error;
-        }
-    }
-
-    server->clients[server->nclients++] = client;
-
-    if (server->nclients > server->nactiveworkers &&
-        server->nactiveworkers < server->nworkers) {
-        for (i = 0 ; i < server->nworkers ; i++) {
-            if (!server->workers[i].hasThread) {
-                if (qemudStartWorker(server, &server->workers[i]) < 0)
-                    return -1;
-                server->nactiveworkers++;
-                break;
-            }
-        }
-    }
-
-
-    return 0;
-
-error:
-    if (client) {
-        if (client->tlssession) gnutls_deinit (client->tlssession);
-        if (client) {
-            VIR_FREE(client->addrstr);
-            VIR_FREE(client->rx);
-        }
-        VIR_FREE(client);
-    }
-    VIR_FREE(addrstr);
-    VIR_FORCE_CLOSE(fd);
-    PROBE(CLIENT_DISCONNECT, "fd=%d", fd);
-    return -1;
-}
-
-
-/*
- * You must hold lock for at least the client
- * We don't free stuff here, merely disconnect the client's
- * network socket & resources.
- * We keep the libvirt connection open until any async
- * jobs have finished, then clean it up elsehwere
- */
-void qemudDispatchClientFailure(struct qemud_client *client) {
-    if (client->watch != -1) {
-        virEventRemoveHandleImpl(client->watch);
-        client->watch = -1;
-    }
-
-    /* Deregister event delivery callback */
-    if (client->conn) {
-        int i;
-
-        for (i = 0 ; i < VIR_DOMAIN_EVENT_ID_LAST ; i++) {
-            if (client->domainEventCallbackID[i] != -1) {
-                DEBUG("Deregistering to relay remote events %d", i);
-                virConnectDomainEventDeregisterAny(client->conn,
-                                                   client->domainEventCallbackID[i]);
-            }
-            client->domainEventCallbackID[i] = -1;
-        }
-    }
-
-#if HAVE_SASL
-    if (client->saslconn) {
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
-    }
-    VIR_FREE(client->saslUsername);
-#endif
-    if (client->tlssession) {
-        gnutls_deinit (client->tlssession);
-        client->tlssession = NULL;
-    }
-    if (client->fd != -1) {
-        PROBE(CLIENT_DISCONNECT, "fd=%d", client->fd);
-        VIR_FORCE_CLOSE(client->fd);
-    }
-    VIR_FREE(client->addrstr);
-}
-
-
-/* Caller must hold server lock */
-static struct qemud_client *qemudPendingJob(struct qemud_server *server)
-{
-    int i;
-    for (i = 0 ; i < server->nclients ; i++) {
-        virMutexLock(&server->clients[i]->lock);
-        if (server->clients[i]->dx) {
-            /* Delibrately don't unlock client - caller wants the lock */
-            return server->clients[i];
-        }
-        virMutexUnlock(&server->clients[i]->lock);
-    }
-    return NULL;
-}
-
-static void *qemudWorker(void *data)
-{
-    struct qemud_worker *worker = data;
-    struct qemud_server *server = worker->server;
-
-    while (1) {
-        struct qemud_client *client = NULL;
-        struct qemud_client_message *msg;
-
-        virMutexLock(&server->lock);
-        while ((client = qemudPendingJob(server)) == NULL) {
-            if (worker->quitRequest ||
-                virCondWait(&server->job, &server->lock) < 0) {
-                virMutexUnlock(&server->lock);
-                return NULL;
-            }
-        }
-        if (worker->quitRequest) {
-            virMutexUnlock(&client->lock);
-            virMutexUnlock(&server->lock);
-            return NULL;
-        }
-        worker->processingCall = 1;
-        virMutexUnlock(&server->lock);
-
-        /* We own a locked client now... */
-        client->refs++;
-
-        /* Remove our message from dispatch queue while we use it */
-        msg = qemudClientMessageQueueServe(&client->dx);
-
-        /* This function drops the lock during dispatch,
-         * and re-acquires it before returning */
-        if (remoteDispatchClientRequest (server, client, msg) < 0) {
-            VIR_FREE(msg);
-            qemudDispatchClientFailure(client);
-            client->refs--;
-            virMutexUnlock(&client->lock);
-            continue;
-        }
-
-        client->refs--;
-        virMutexUnlock(&client->lock);
-
-        virMutexLock(&server->lock);
-        worker->processingCall = 0;
-        virMutexUnlock(&server->lock);
-    }
-}
-
-static int
-qemudStartWorker(struct qemud_server *server,
-                 struct qemud_worker *worker)
-{
-    pthread_attr_t attr;
-    int ret = -1;
-
-    if (pthread_attr_init(&attr) != 0)
-        return -1;
-    /* We want to join workers, so don't detach them */
-    /*pthread_attr_setdetachstate(&attr, 1);*/
-
-    if (worker->hasThread)
-        goto cleanup;
-
-    worker->server = server;
-    worker->hasThread = 1;
-    worker->quitRequest = 0;
-    worker->processingCall = 0;
-
-    if (pthread_create(&worker->thread,
-                       &attr,
-                       qemudWorker,
-                       worker) != 0) {
-        worker->hasThread = 0;
-        worker->server = NULL;
-        goto cleanup;
-    }
-
-    ret = 0;
-cleanup:
-    pthread_attr_destroy(&attr);
-    return ret;
-}
-
-
-/*
- * Read data into buffer using wire decoding (plain or TLS)
- *
- * Returns:
- *   -1 on error or EOF
- *    0 on EAGAIN
- *    n number of bytes
- */
-static ssize_t qemudClientReadBuf(struct qemud_client *client,
-                                  char *data, ssize_t len) {
-    ssize_t ret;
-
-    if (len < 0) {
-        VIR_ERROR(_("unexpected negative length request %lld"),
-                  (long long int) len);
-        qemudDispatchClientFailure(client);
-        return -1;
-    }
-
-    /*qemudDebug ("qemudClientRead: len = %d", len);*/
-
-    if (!client->tlssession) {
-        char ebuf[1024];
-        ret = read (client->fd, data, len);
-        if (ret == -1 && (errno == EAGAIN ||
-                          errno == EINTR))
-            return 0;
-        if (ret <= 0) {
-            if (ret != 0)
-                VIR_ERROR(_("read: %s"),
-                          virStrerror (errno, ebuf, sizeof ebuf));
-            qemudDispatchClientFailure(client);
-            return -1;
-        }
-    } else {
-        ret = gnutls_record_recv (client->tlssession, data, len);
-
-        if (ret < 0 && (ret == GNUTLS_E_AGAIN ||
-                        ret == GNUTLS_E_INTERRUPTED))
-            return 0;
-        if (ret <= 0) {
-            if (ret != 0)
-                VIR_ERROR(_("gnutls_record_recv: %s"),
-                          gnutls_strerror (ret));
-            qemudDispatchClientFailure(client);
-            return -1;
-        }
-    }
-
-    return ret;
-}
-
-/*
- * Read data into buffer without decoding
- *
- * Returns:
- *   -1 on error or EOF
- *    0 on EAGAIN
- *    n number of bytes
- */
-static ssize_t qemudClientReadPlain(struct qemud_client *client) {
-    ssize_t ret;
-    ret = qemudClientReadBuf(client,
-                             client->rx->buffer + client->rx->bufferOffset,
-                             client->rx->bufferLength - client->rx->bufferOffset);
-    if (ret <= 0)
-        return ret; /* -1 error, 0 eagain */
-
-    client->rx->bufferOffset += ret;
-    return ret;
-}
-
-#if HAVE_SASL
-/*
- * Read data into buffer decoding with SASL
- *
- * Returns:
- *   -1 on error or EOF
- *    0 on EAGAIN
- *    n number of bytes
- */
-static ssize_t qemudClientReadSASL(struct qemud_client *client) {
-    ssize_t got, want;
-
-    /* We're doing a SSF data read, so now its times to ensure
-     * future writes are under SSF too.
-     *
-     * cf remoteSASLCheckSSF in remote.c
-     */
-    client->saslSSF |= QEMUD_SASL_SSF_WRITE;
-
-    /* Need to read some more data off the wire */
-    if (client->saslDecoded == NULL) {
-        int ret;
-        char encoded[8192];
-        ssize_t encodedLen = sizeof(encoded);
-        encodedLen = qemudClientReadBuf(client, encoded, encodedLen);
-
-        if (encodedLen <= 0)
-            return encodedLen;
-
-        ret = sasl_decode(client->saslconn, encoded, encodedLen,
-                          &client->saslDecoded, &client->saslDecodedLength);
-        if (ret != SASL_OK) {
-            VIR_ERROR(_("failed to decode SASL data %s"),
-                      sasl_errstring(ret, NULL, NULL));
-            qemudDispatchClientFailure(client);
-            return -1;
-        }
-
-        client->saslDecodedOffset = 0;
-    }
-
-    /* Some buffered decoded data to return now */
-    got = client->saslDecodedLength - client->saslDecodedOffset;
-    want = client->rx->bufferLength - client->rx->bufferOffset;
-
-    if (want > got)
-        want = got;
-
-    memcpy(client->rx->buffer + client->rx->bufferOffset,
-           client->saslDecoded + client->saslDecodedOffset, want);
-    client->saslDecodedOffset += want;
-    client->rx->bufferOffset += want;
-
-    if (client->saslDecodedOffset == client->saslDecodedLength) {
-        client->saslDecoded = NULL;
-        client->saslDecodedOffset = client->saslDecodedLength = 0;
-    }
-
-    return want;
-}
-#endif
-
-/*
- * Read as much data off wire as possible till we fill our
- * buffer, or would block on I/O
- */
-static ssize_t qemudClientRead(struct qemud_client *client) {
-#if HAVE_SASL
-    if (client->saslSSF & QEMUD_SASL_SSF_READ)
-        return qemudClientReadSASL(client);
-    else
-#endif
-        return qemudClientReadPlain(client);
-}
-
-
-/*
- * Read data until we get a complete message to process
- */
-static void qemudDispatchClientRead(struct qemud_server *server,
-                                    struct qemud_client *client) {
-    /*qemudDebug ("qemudDispatchClientRead: mode = %d", client->mode);*/
-
-readmore:
-    if (qemudClientRead(client) < 0)
-        return; /* Error */
-
-    if (client->rx->bufferOffset < client->rx->bufferLength)
-        return; /* Still not read enough */
-
-    /* Either done with length word header */
-    if (client->rx->bufferLength == REMOTE_MESSAGE_HEADER_XDR_LEN) {
-        unsigned int len;
-        XDR x;
-
-        xdrmem_create(&x, client->rx->buffer, client->rx->bufferLength, XDR_DECODE);
-
-        if (!xdr_u_int(&x, &len)) {
-            xdr_destroy (&x);
-            DEBUG0("Failed to decode packet length");
-            qemudDispatchClientFailure(client);
-            return;
-        }
-        xdr_destroy (&x);
-
-        if (len < REMOTE_MESSAGE_HEADER_XDR_LEN) {
-            DEBUG("Packet length %u too small", len);
-            qemudDispatchClientFailure(client);
-            return;
-        }
-
-        /* Length includes the size of the length word itself */
-        len -= REMOTE_MESSAGE_HEADER_XDR_LEN;
-
-        if (len > REMOTE_MESSAGE_MAX) {
-            DEBUG("Packet length %u too large", len);
-            qemudDispatchClientFailure(client);
-            return;
-        }
-
-        /* Prepare to read rest of message */
-        client->rx->bufferLength += len;
-
-        qemudUpdateClientEvent(client);
-
-        /* Try and read payload immediately instead of going back
-           into poll() because chances are the data is already
-           waiting for us */
-        goto readmore;
-    } else {
-        /* Grab the completed message */
-        struct qemud_client_message *msg = qemudClientMessageQueueServe(&client->rx);
-        struct qemud_client_filter *filter;
-
-        /* Decode the header so we can use it for routing decisions */
-        if (remoteDecodeClientMessageHeader(msg) < 0) {
-            VIR_FREE(msg);
-            qemudDispatchClientFailure(client);
-        }
-
-        /* Check if any filters match this message */
-        filter = client->filters;
-        while (filter) {
-            int ret;
-            ret = (filter->query)(client, msg, filter->opaque);
-            if (ret == 1) {
-                msg = NULL;
-                break;
-            } else if (ret == -1) {
-                VIR_FREE(msg);
-                qemudDispatchClientFailure(client);
-                return;
-            }
-            filter = filter->next;
-        }
-
-        /* Move completed message to the end of the dispatch queue */
-        if (msg)
-            qemudClientMessageQueuePush(&client->dx, msg);
-        client->nrequests++;
-
-        /* Possibly need to create another receive buffer */
-        if ((client->nrequests < max_client_requests &&
-             VIR_ALLOC(client->rx) < 0)) {
-            qemudDispatchClientFailure(client);
-        } else {
-            if (client->rx)
-                client->rx->bufferLength = REMOTE_MESSAGE_HEADER_XDR_LEN;
-
-            qemudUpdateClientEvent(client);
-
-            /* Tell one of the workers to get on with it... */
-            virCondSignal(&server->job);
-        }
-    }
-}
-
-
-/*
- * Send a chunk of data using wire encoding (plain or TLS)
- *
- * Returns:
- *   -1 on error
- *    0 on EAGAIN
- *    n number of bytes
- */
-static ssize_t qemudClientWriteBuf(struct qemud_client *client,
-                                   const char *data, ssize_t len) {
-    ssize_t ret;
-
-    if (len < 0) {
-        VIR_ERROR(_("unexpected negative length request %lld"),
-                  (long long int) len);
-        qemudDispatchClientFailure(client);
-        return -1;
-    }
-
-    if (!client->tlssession) {
-        char ebuf[1024];
-        if ((ret = write(client->fd, data, len)) == -1) {
-            if (errno == EAGAIN || errno == EINTR)
-                return 0;
-            VIR_ERROR(_("write: %s"), virStrerror (errno, ebuf, sizeof ebuf));
-            qemudDispatchClientFailure(client);
-            return -1;
-        }
-    } else {
-        ret = gnutls_record_send (client->tlssession, data, len);
-        if (ret < 0) {
-            if (ret == GNUTLS_E_INTERRUPTED ||
-                ret == GNUTLS_E_AGAIN)
-                return 0;
-
-            VIR_ERROR(_("gnutls_record_send: %s"), gnutls_strerror (ret));
-            qemudDispatchClientFailure(client);
-            return -1;
-        }
-    }
-    return ret;
-}
-
-
-/*
- * Send client->tx using no encoding
- *
- * Returns:
- *   -1 on error or EOF
- *    0 on EAGAIN
- *    n number of bytes
- */
-static int qemudClientWritePlain(struct qemud_client *client) {
-    int ret = qemudClientWriteBuf(client,
-                                  client->tx->buffer + client->tx->bufferOffset,
-                                  client->tx->bufferLength - client->tx->bufferOffset);
-    if (ret <= 0)
-        return ret; /* -1 error, 0 = egain */
-    client->tx->bufferOffset += ret;
-    return ret;
-}
-
-
-#if HAVE_SASL
-/*
- * Send client->tx using SASL encoding
- *
- * Returns:
- *   -1 on error
- *    0 on EAGAIN
- *    n number of bytes
- */
-static int qemudClientWriteSASL(struct qemud_client *client) {
-    int ret;
-
-    /* Not got any pending encoded data, so we need to encode raw stuff */
-    if (client->saslEncoded == NULL) {
-        ret = sasl_encode(client->saslconn,
-                          client->tx->buffer + client->tx->bufferOffset,
-                          client->tx->bufferLength - client->tx->bufferOffset,
-                          &client->saslEncoded,
-                          &client->saslEncodedLength);
-
-        if (ret != SASL_OK) {
-            VIR_ERROR(_("failed to encode SASL data %s"),
-                      sasl_errstring(ret, NULL, NULL));
-            qemudDispatchClientFailure(client);
-            return -1;
-        }
-
-        client->saslEncodedOffset = 0;
-    }
-
-    /* Send some of the encoded stuff out on the wire */
-    ret = qemudClientWriteBuf(client,
-                              client->saslEncoded + client->saslEncodedOffset,
-                              client->saslEncodedLength - client->saslEncodedOffset);
-
-    if (ret <= 0)
-        return ret; /* -1 error, 0 == egain */
-
-    /* Note how much we sent */
-    client->saslEncodedOffset += ret;
-
-    /* Sent all encoded, so update raw buffer to indicate completion */
-    if (client->saslEncodedOffset == client->saslEncodedLength) {
-        client->saslEncoded = NULL;
-        client->saslEncodedOffset = client->saslEncodedLength = 0;
-
-        /* Mark as complete, so caller detects completion */
-        client->tx->bufferOffset = client->tx->bufferLength;
-    }
-
-    return ret;
-}
-#endif
-
-/*
- * Send as much data in the client->tx as possible
- *
- * Returns:
- *   -1 on error or EOF
- *    0 on EAGAIN
- *    n number of bytes
- */
-static ssize_t qemudClientWrite(struct qemud_client *client) {
-#if HAVE_SASL
-    if (client->saslSSF & QEMUD_SASL_SSF_WRITE)
-        return qemudClientWriteSASL(client);
-    else
-#endif
-        return qemudClientWritePlain(client);
-}
-
-
-void
-qemudClientMessageRelease(struct qemud_client *client,
-                          struct qemud_client_message *msg)
-{
-    if (msg->streamTX) {
-        remoteStreamMessageFinished(client, msg);
-    } else if (!msg->async)
-        client->nrequests--;
-
-    /* See if the recv queue is currently throttled */
-    if (!client->rx &&
-        client->nrequests < max_client_requests) {
-        /* Reset message record for next RX attempt */
-        memset(msg, 0, sizeof(*msg));
-        client->rx = msg;
-        /* Get ready to receive next message */
-        client->rx->bufferLength = REMOTE_MESSAGE_HEADER_XDR_LEN;
-    } else {
-        VIR_FREE(msg);
-    }
-
-    qemudUpdateClientEvent(client);
-}
-
-
-/*
- * Process all queued client->tx messages until
- * we would block on I/O
- */
-static void
-qemudDispatchClientWrite(struct qemud_client *client) {
-    while (client->tx) {
-        ssize_t ret;
-
-        ret = qemudClientWrite(client);
-        if (ret < 0) {
-            qemudDispatchClientFailure(client);
-            return;
-        }
-        if (ret == 0)
-            return; /* Would block on write EAGAIN */
-
-        if (client->tx->bufferOffset == client->tx->bufferLength) {
-            struct qemud_client_message *reply;
-
-            /* Get finished reply from head of tx queue */
-            reply = qemudClientMessageQueueServe(&client->tx);
-
-            qemudClientMessageRelease(client, reply);
-
-            if (client->closing)
-                qemudDispatchClientFailure(client);
-         }
-    }
-}
-
-static void
-qemudDispatchClientHandshake(struct qemud_client *client) {
-    int ret;
-    /* Continue the handshake. */
-    ret = gnutls_handshake (client->tlssession);
-    if (ret == 0) {
-        client->handshake = 0;
-
-        /* Finished.  Next step is to check the certificate. */
-        if (remoteCheckAccess (client) == -1)
-            qemudDispatchClientFailure(client);
-        else
-            qemudUpdateClientEvent(client);
-    } else if (ret == GNUTLS_E_AGAIN ||
-               ret == GNUTLS_E_INTERRUPTED) {
-        /* Carry on waiting for more handshake. Update
-           the events just in case handshake data flow
-           direction has changed */
-        qemudUpdateClientEvent (client);
-    } else {
-        PROBE(CLIENT_TLS_FAIL, "fd=%d", client->fd);
-        /* Fatal error in handshake */
-        VIR_ERROR(_("TLS handshake failed: %s"),
-                  gnutls_strerror (ret));
-        qemudDispatchClientFailure(client);
-    }
-}
-
-static void
-qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) {
-    struct qemud_server *server = (struct qemud_server *)opaque;
-    struct qemud_client *client = NULL;
-    int i;
-
-    virMutexLock(&server->lock);
-
-    for (i = 0 ; i < server->nclients ; i++) {
-        virMutexLock(&server->clients[i]->lock);
-        if (server->clients[i]->watch == watch) {
-            client = server->clients[i];
-            break;
-        }
-        virMutexUnlock(&server->clients[i]->lock);
-    }
-
-    virMutexUnlock(&server->lock);
-
-    if (!client) {
-        return;
-    }
-
-    if (client->fd != fd) {
-        virMutexUnlock(&client->lock);
-        return;
-    }
-
-    if (events & (VIR_EVENT_HANDLE_WRITABLE |
-                  VIR_EVENT_HANDLE_READABLE)) {
-        if (client->handshake) {
-            qemudDispatchClientHandshake(client);
-        } else {
-            if (events & VIR_EVENT_HANDLE_WRITABLE)
-                qemudDispatchClientWrite(client);
-            if (events & VIR_EVENT_HANDLE_READABLE)
-                qemudDispatchClientRead(server, client);
-        }
-    }
-
-    /* NB, will get HANGUP + READABLE at same time upon
-     * disconnect */
-    if (events & (VIR_EVENT_HANDLE_ERROR |
-                  VIR_EVENT_HANDLE_HANGUP))
-        qemudDispatchClientFailure(client);
-
-    virMutexUnlock(&client->lock);
-}
-
-
-/*
- * @client: a locked client object
- */
-static int
-qemudCalculateHandleMode(struct qemud_client *client) {
-    int mode = 0;
-
-    if (client->handshake) {
-        if (gnutls_record_get_direction (client->tlssession) == 0)
-            mode |= VIR_EVENT_HANDLE_READABLE;
-        else
-            mode |= VIR_EVENT_HANDLE_WRITABLE;
-    } else {
-        /* If there is a message on the rx queue then
-         * we're wanting more input */
-        if (client->rx)
-            mode |= VIR_EVENT_HANDLE_READABLE;
-
-        /* If there are one or more messages to send back to client,
-           then monitor for writability on socket */
-        if (client->tx)
-            mode |= VIR_EVENT_HANDLE_WRITABLE;
-    }
-
-    return mode;
-}
-
-/*
- * @server: a locked or unlocked server object
- * @client: a locked client object
- */
-int qemudRegisterClientEvent(struct qemud_server *server,
-                             struct qemud_client *client) {
-    int mode;
-
-    mode = qemudCalculateHandleMode(client);
-
-    if ((client->watch = virEventAddHandleImpl(client->fd,
-                                               mode,
-                                               qemudDispatchClientEvent,
-                                               server, NULL)) < 0)
-        return -1;
-
-    return 0;
-}
-
-/*
- * @client: a locked client object
- */
-void qemudUpdateClientEvent(struct qemud_client *client) {
-    int mode;
-
-    mode = qemudCalculateHandleMode(client);
-
-    virEventUpdateHandleImpl(client->watch, mode);
-}
-
-
-static void
-qemudDispatchServerEvent(int watch, int fd, int events, void *opaque) {
-    struct qemud_server *server = (struct qemud_server *)opaque;
-    struct qemud_socket *sock;
-
-    virMutexLock(&server->lock);
-
-    sock = server->sockets;
-
-    while (sock) {
-        if (sock->watch == watch)
-            break;
-
-        sock = sock->next;
-    }
-
-    if (sock && sock->fd == fd && events)
-        qemudDispatchServer(server, sock);
-
-    virMutexUnlock(&server->lock);
-}
-
-
-static int qemudOneLoop(void) {
-    sig_atomic_t errors;
-
-    if (virEventRunOnce() < 0)
-        return -1;
-
-    /* Check for any signal handling errors and log them. */
-    errors = sig_errors;
-    if (errors) {
-        char ebuf[1024];
-        sig_errors -= errors;
-        VIR_ERROR(_("Signal handler reported %d errors: last error: %s"),
-                  errors, virStrerror (sig_lasterrno, ebuf, sizeof ebuf));
-        return -1;
-    }
-
-    return 0;
-}
-
-static void qemudInactiveTimer(int timerid, void *data) {
-    struct qemud_server *server = (struct qemud_server *)data;
-
-    if (virStateActive() ||
-        server->clients) {
-        DEBUG0("Timer expired but still active, not shutting down");
-        virEventUpdateTimeoutImpl(timerid, -1);
-    } else {
-        DEBUG0("Timer expired and inactive, shutting down");
-        server->quitEventThread = 1;
-    }
-}
-
-static void qemudFreeClient(struct qemud_client *client) {
-    while (client->rx) {
-        struct qemud_client_message *msg
-            = qemudClientMessageQueueServe(&client->rx);
-        VIR_FREE(msg);
-    }
-    while (client->dx) {
-        struct qemud_client_message *msg
-            = qemudClientMessageQueueServe(&client->dx);
-        VIR_FREE(msg);
-    }
-    while (client->tx) {
-        struct qemud_client_message *msg
-            = qemudClientMessageQueueServe(&client->tx);
-        VIR_FREE(msg);
-    }
-
-    while (client->streams)
-        remoteRemoveClientStream(client, client->streams);
-
-    if (client->conn)
-        virConnectClose(client->conn);
-    virMutexDestroy(&client->lock);
-    VIR_FREE(client->addrstr);
-    VIR_FREE(client);
-}
-
-static void *qemudRunLoop(void *opaque) {
-    struct qemud_server *server = opaque;
-    int timerid = -1;
-    int i;
-    int timerActive = 0;
-
-    virMutexLock(&server->lock);
-
-    if (timeout > 0 &&
-        (timerid = virEventAddTimeoutImpl(-1,
-                                          qemudInactiveTimer,
-                                          server, NULL)) < 0) {
-        VIR_ERROR0(_("Failed to register shutdown timeout"));
-        return NULL;
-    }
-
-    if (min_workers > max_workers)
-        max_workers = min_workers;
-
-    server->nworkers = max_workers;
-    if (VIR_ALLOC_N(server->workers, server->nworkers) < 0) {
-        VIR_ERROR0(_("Failed to allocate workers"));
-        return NULL;
-    }
-
-    for (i = 0 ; i < min_workers ; i++) {
-        if (qemudStartWorker(server, &server->workers[i]) < 0)
-            goto cleanup;
-        server->nactiveworkers++;
-    }
-
-    for (;!server->quitEventThread;) {
-        /* A shutdown timeout is specified, so check
-         * if any drivers have active state, if not
-         * shutdown after timeout seconds
-         */
-        if (timeout > 0) {
-            if (timerActive) {
-                if (server->clients) {
-                    DEBUG("Deactivating shutdown timer %d", timerid);
-                    virEventUpdateTimeoutImpl(timerid, -1);
-                    timerActive = 0;
-                }
-            } else {
-                if (!virStateActive() &&
-                    !server->clients) {
-                    DEBUG("Activating shutdown timer %d", timerid);
-                    virEventUpdateTimeoutImpl(timerid, timeout * 1000);
-                    timerActive = 1;
-                }
-            }
-        }
-
-        virMutexUnlock(&server->lock);
-        if (qemudOneLoop() < 0) {
-            virMutexLock(&server->lock);
-            DEBUG0("Loop iteration error, exiting");
-            break;
-        }
-        virMutexLock(&server->lock);
-
-    reprocess:
-        for (i = 0 ; i < server->nclients ; i++) {
-            int inactive;
-            virMutexLock(&server->clients[i]->lock);
-            inactive = server->clients[i]->fd == -1
-                && server->clients[i]->refs == 0;
-            virMutexUnlock(&server->clients[i]->lock);
-            if (inactive) {
-                qemudFreeClient(server->clients[i]);
-                server->nclients--;
-                if (i < server->nclients)
-                    memmove(server->clients + i,
-                            server->clients + i + 1,
-                            sizeof (*server->clients) * (server->nclients - i));
-
-                VIR_SHRINK_N(server->clients, server->nclients_max,
-                             server->nclients_max - server->nclients);
-                goto reprocess;
-            }
-        }
-
-        /* If number of active workers exceeds both the min_workers
-         * threshold and the number of clients, then kill some
-         * off */
-        for (i = 0 ; (i < server->nworkers &&
-                      server->nactiveworkers > server->nclients &&
-                      server->nactiveworkers > min_workers) ; i++) {
-
-            if (server->workers[i].hasThread &&
-                !server->workers[i].processingCall) {
-                server->workers[i].quitRequest = 1;
-
-                virCondBroadcast(&server->job);
-                virMutexUnlock(&server->lock);
-                pthread_join(server->workers[i].thread, NULL);
-                virMutexLock(&server->lock);
-                server->workers[i].hasThread = 0;
-                server->nactiveworkers--;
-            }
-        }
-    }
-
-cleanup:
-    for (i = 0 ; i < server->nworkers ; i++) {
-        if (!server->workers[i].hasThread)
-            continue;
-
-        server->workers[i].quitRequest = 1;
-        virCondBroadcast(&server->job);
-
-        virMutexUnlock(&server->lock);
-        pthread_join(server->workers[i].thread, NULL);
-        virMutexLock(&server->lock);
-        server->workers[i].hasThread = 0;
-    }
-    VIR_FREE(server->workers);
-    for (i = 0; i < server->nclients; i++)
-        qemudFreeClient(server->clients[i]);
-    server->nclients = 0;
-    VIR_SHRINK_N(server->clients, server->nclients_max, server->nclients_max);
-
-    virMutexUnlock(&server->lock);
-    return NULL;
-}
-
-
-static int
-qemudStartEventLoop(struct qemud_server *server)
-{
-    pthread_attr_t attr;
-    int ret = -1;
-
-    if (pthread_attr_init(&attr) != 0)
-        return -1;
-    /* We want to join the eventloop, so don't detach it */
-    /*pthread_attr_setdetachstate(&attr, 1);*/
-
-    if (pthread_create(&server->eventThread,
-                       &attr,
-                       qemudRunLoop,
-                       server) != 0)
-        goto cleanup;
-
-    server->hasEventThread = 1;
-
-    ret = 0;
-cleanup:
-    pthread_attr_destroy(&attr);
-    return ret;
+#  error "UNIX socket credentials not supported/implemented on this platform yet..."
+# endif
+    return 0;
 }
+#endif
 
 
-static void qemudCleanup(struct qemud_server *server) {
-    struct qemud_socket *sock;
 
-    VIR_FORCE_CLOSE(server->sigread);
-    VIR_FORCE_CLOSE(server->sigwrite);
+#if 0
+XXX connection check
 
-    sock = server->sockets;
-    while (sock) {
-        struct qemud_socket *next = sock->next;
-        if (sock->watch)
-            virEventRemoveHandleImpl(sock->watch);
-        VIR_FORCE_CLOSE(sock->fd);
+#if HAVE_POLKIT
+    /* Only do policy checks for non-root - allow root user
+       through with no checks, as a fail-safe - root can easily
+       change policykit policy anyway, so its pointless trying
+       to restrict root */
+    if (client->auth == REMOTE_AUTH_POLKIT) {
+        uid_t uid;
+        pid_t pid;
 
-        /* Unlink unix domain sockets which are not in
-         * the abstract namespace */
-        if (sock->path &&
-            sock->path[0] != '@')
-            unlink(sock->path);
-        VIR_FREE(sock->path);
-        VIR_FREE(sock->addrstr);
+        if (qemudGetSocketIdentity(client->fd, &uid, &pid) < 0)
+            goto error;
 
-        VIR_FREE(sock);
-        sock = next;
-    }
-    VIR_FREE(server->logDir);
-
-#ifdef HAVE_SASL
-    if (server->saslUsernameWhitelist) {
-        char **list = server->saslUsernameWhitelist;
-        while (*list) {
-            VIR_FREE(*list);
-            list++;
+        /* Client is running as root, so disable auth */
+        if (uid == 0) {
+            VIR_INFO(_("Turn off polkit auth for privileged client pid %d from %s"),
+                     pid, addrstr);
+            client->auth = REMOTE_AUTH_NONE;
         }
-        VIR_FREE(server->saslUsernameWhitelist);
     }
 #endif
 
-#if HAVE_POLKIT0
-        if (server->sysbus)
-            dbus_connection_unref(server->sysbus);
 #endif
 
-    virStateCleanup();
 
-    if (virCondDestroy(&server->job) < 0) {
-        ;
-    }
-    virMutexDestroy(&server->lock);
+static int daemonShutdownCheck(virNetServerPtr srv ATTRIBUTE_UNUSED,
+                               void *opaque ATTRIBUTE_UNUSED)
+{
+    if (virStateActive())
+        return 0;
 
-    VIR_FREE(server);
+    return 1;
 }
 
+
+
 /* Allocate an array of malloc'd strings from the config file, filename
  * (used only in diagnostics), using handle "conf".  Upon error, return -1
  * and free any allocated memory.  Otherwise, save the array in *list_arg
@@ -2598,13 +790,11 @@ checkType (virConfValuePtr p, const char *filename,
         virConfValuePtr p = virConfGetValue (conf, #var_name);          \
         if (p) {                                                        \
             if (checkType (p, filename, #var_name, VIR_CONF_STRING) < 0) \
-                goto free_and_fail;                                     \
-            (var_name) = strdup (p->str);                               \
-            if ((var_name) == NULL) {                                   \
-                char ebuf[1024];                                        \
-                VIR_ERROR(_("remoteReadConfigFile: %s"),		\
-                          virStrerror(errno, ebuf, sizeof ebuf));       \
-                goto free_and_fail;                                     \
+                goto error;                                             \
+            VIR_FREE(data->var_name);                                   \
+            if (!(data->var_name = strdup (p->str))) {                  \
+                virReportOOMError();                                    \
+                goto error;                                             \
             }                                                           \
         }                                                               \
     } while (0)
@@ -2615,8 +805,8 @@ checkType (virConfValuePtr p, const char *filename,
         virConfValuePtr p = virConfGetValue (conf, #var_name);          \
         if (p) {                                                        \
             if (checkType (p, filename, #var_name, VIR_CONF_LONG) < 0)  \
-                goto free_and_fail;                                     \
-            (var_name) = p->l;                                          \
+                goto error;                                             \
+            data->var_name = p->l;                                      \
         }                                                               \
     } while (0)
 
@@ -2635,15 +825,11 @@ static int remoteConfigGetAuth(virConfPtr conf, const char *key, int *auth, cons
         return 0;
 
     if (STREQ(p->str, "none")) {
-        *auth = REMOTE_AUTH_NONE;
-#if HAVE_SASL
+        *auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
     } else if (STREQ(p->str, "sasl")) {
-        *auth = REMOTE_AUTH_SASL;
-#endif
-#if HAVE_POLKIT
+        *auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
     } else if (STREQ(p->str, "polkit")) {
-        *auth = REMOTE_AUTH_POLKIT;
-#endif
+        *auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
     } else {
         VIR_ERROR(_("remoteReadConfigFile: %s: %s: unsupported auth %s"),
                   filename, key, p->str);
@@ -2653,26 +839,6 @@ static int remoteConfigGetAuth(virConfPtr conf, const char *key, int *auth, cons
     return 0;
 }
 
-#ifdef HAVE_SASL
-static inline int
-remoteReadSaslAllowedUsernameList (virConfPtr conf,
-                                   struct qemud_server *server,
-                                   const char *filename)
-{
-    return
-        remoteConfigGetStringList (conf, "sasl_allowed_username_list",
-                                   &server->saslUsernameWhitelist, filename);
-}
-#else
-static inline int
-remoteReadSaslAllowedUsernameList (virConfPtr conf ATTRIBUTE_UNUSED,
-                                   struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   const char *filename ATTRIBUTE_UNUSED)
-{
-    return 0;
-}
-#endif
-
 /*
  * Set up the logging environment
  * By default if daemonized all errors go to syslog and the logging
@@ -2680,13 +846,10 @@ remoteReadSaslAllowedUsernameList (virConfPtr conf ATTRIBUTE_UNUSED,
  * debugging is asked for then output informations or debug.
  */
 static int
-qemudSetLogging(virConfPtr conf, const char *filename)
+daemonSetupLogging(struct daemonConfig *config,
+                   bool verbose,
+                   bool godaemon)
 {
-    int log_level = 0;
-    char *log_filters = NULL;
-    char *log_outputs = NULL;
-    int ret = -1;
-
     virLogReset();
 
     /*
@@ -2703,21 +866,16 @@ qemudSetLogging(virConfPtr conf, const char *filename)
      * level has been set, we must process variables in the opposite
      * order, each one overriding the previous.
      */
-    GET_CONF_INT (conf, filename, log_level);
-    if (log_level != 0)
-        virLogSetDefaultPriority(log_level);
+    if (config->log_level != 0)
+        virLogSetDefaultPriority(config->log_level);
 
     virLogSetFromEnv();
 
-    if (virLogGetNbFilters() == 0) {
-        GET_CONF_STR (conf, filename, log_filters);
-        virLogParseFilters(log_filters);
-    }
+    if (virLogGetNbFilters() == 0)
+        virLogParseFilters(config->log_filters);
 
-    if (virLogGetNbOutputs() == 0) {
-        GET_CONF_STR (conf, filename, log_outputs);
-        virLogParseOutputs(log_outputs);
-    }
+    if (virLogGetNbOutputs() == 0)
+        virLogParseOutputs(config->log_outputs);
 
     /*
      * If no defined outputs, then direct to syslog when running
@@ -2726,13 +884,13 @@ qemudSetLogging(virConfPtr conf, const char *filename)
     if (virLogGetNbOutputs() == 0) {
         char *tmp = NULL;
         if (godaemon) {
-            if (virAsprintf (&tmp, "%d:syslog:libvirtd",
-                             virLogGetDefaultPriority()) < 0)
-                goto free_and_fail;
+            if (virAsprintf(&tmp, "%d:syslog:libvirtd",
+                            virLogGetDefaultPriority()) < 0)
+                goto no_memory;
         } else {
-            if (virAsprintf (&tmp, "%d:stderr",
-                             virLogGetDefaultPriority()) < 0)
-                goto free_and_fail;
+            if (virAsprintf(&tmp, "%d:stderr",
+                            virLogGetDefaultPriority()) < 0)
+                goto no_memory;
         }
         virLogParseOutputs(tmp);
         VIR_FREE(tmp);
@@ -2744,46 +902,175 @@ qemudSetLogging(virConfPtr conf, const char *filename)
     if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO))
         virLogSetDefaultPriority(VIR_LOG_INFO);
 
-    ret = 0;
+    return 0;
 
-free_and_fail:
-    VIR_FREE(log_filters);
-    VIR_FREE(log_outputs);
-    return(ret);
+no_memory:
+    virReportOOMError();
+    return -1;
 }
 
-/* Read the config file if it exists.
- * Only used in the remote case, hence the name.
- */
 static int
-remoteReadConfigFile (struct qemud_server *server, const char *filename)
+daemonConfigFilePath(bool privileged, char **configfile)
 {
-    virConfPtr conf;
+    if (privileged) {
+        if (!(*configfile = strdup(SYSCONFDIR "/libvirt/libvirtd.conf")))
+            goto no_memory;
+    } else {
+        char *userdir = NULL;
+
+        if (!(userdir = virGetUserDirectory(geteuid())))
+            goto error;
+
+        if (virAsprintf(configfile, "%s/.libvirt/libvirtd.conf", userdir) < 0) {
+            VIR_FREE(userdir);
+            goto no_memory;
+        }
+        VIR_FREE(userdir);
+    }
+
+    return 0;
+
+no_memory:
+    virReportOOMError();
+error:
+    return -1;
+}
+
+static void
+daemonConfigFree(struct daemonConfig *data);
+
+static struct daemonConfig*
+daemonConfigNew(bool privileged)
+{
+    struct daemonConfig *data;
+
+    if (VIR_ALLOC(data) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    data->listen_tls = 1;
+    data->listen_tcp = 0;
 
-    /* The following variable names must match the corresponding
-       configuration strings.  */
-    char *unix_sock_ro_perms = NULL;
-    char *unix_sock_rw_perms = NULL;
-    char *unix_sock_group = NULL;
-    char *buf = NULL;
-    char *host_uuid = NULL;
+    if (!(data->tls_port = strdup(LIBVIRTD_TLS_PORT)))
+        goto no_memory;
+    if (!(data->tcp_port = strdup(LIBVIRTD_TCP_PORT)))
+        goto no_memory;
 
+    /* Only default to PolicyKit if running as root */
 #if HAVE_POLKIT
-    /* Change the default back to no auth for non-root */
-    if (!server->privileged && auth_unix_rw == REMOTE_AUTH_POLKIT)
-        auth_unix_rw = REMOTE_AUTH_NONE;
-    if (!server->privileged && auth_unix_ro == REMOTE_AUTH_POLKIT)
-        auth_unix_ro = REMOTE_AUTH_NONE;
+    if (privileged) {
+        data->auth_unix_rw = REMOTE_AUTH_POLKIT;
+        data->auth_unix_ro = REMOTE_AUTH_POLKIT;
+    } else {
+#endif
+        data->auth_unix_rw = REMOTE_AUTH_NONE;
+        data->auth_unix_ro = REMOTE_AUTH_NONE;
+#if HAVE_POLKIT
+    }
 #endif
 
+    if (data->auth_unix_rw == REMOTE_AUTH_POLKIT)
+        data->unix_sock_rw_perms = strdup("0777"); /* Allow world */
+    else
+        data->unix_sock_rw_perms = strdup("0700"); /* Allow user only */
+    data->unix_sock_ro_perms = strdup("0777"); /* Always allow world */
+    if (!data->unix_sock_ro_perms ||
+        !data->unix_sock_rw_perms)
+        goto no_memory;
+
+#if HAVE_SASL
+    data->auth_tcp = REMOTE_AUTH_SASL;
+#else
+    data->auth_tcp = REMOTE_AUTH_NONE;
+#endif
+    data->auth_tls = REMOTE_AUTH_NONE;
+
+    data->mdns_adv = 1;
+
+    if (!(data->key_file = strdup(LIBVIRT_SERVERKEY)))
+        goto no_memory;
+    if (!(data->cert_file = strdup(LIBVIRT_SERVERCERT)))
+        goto no_memory;
+    if (!(data->ca_file = strdup(LIBVIRT_CACERT)))
+        goto no_memory;
+
+    data->min_workers = 5;
+    data->max_workers = 20;
+    data->max_clients = 20;
+
+    data->max_requests = 20;
+    data->max_client_requests = 5;
+
+    data->audit_level = 1;
+    data->audit_logging = 0;
+
+
+    return data;
+
+no_memory:
+    virReportOOMError();
+    daemonConfigFree(data);
+    return NULL;
+}
+
+static void
+daemonConfigFree(struct daemonConfig *data)
+{
+    char **tmp;
+
+    if (!data)
+        return;
+
+    VIR_FREE(data->listen_addr);
+    VIR_FREE(data->tls_port);
+    VIR_FREE(data->tcp_port);
+
+    VIR_FREE(data->unix_sock_ro_perms);
+    VIR_FREE(data->unix_sock_rw_perms);
+    VIR_FREE(data->unix_sock_group);
+    VIR_FREE(data->unix_sock_dir);
+    VIR_FREE(data->mdns_name);
+
+    tmp = data->tls_allowed_dn_list;
+    while (tmp && *tmp) {
+        VIR_FREE(*tmp);
+        tmp++;
+    }
+    VIR_FREE(data->tls_allowed_dn_list);
+
+    tmp = data->sasl_allowed_username_list;
+    while (tmp && *tmp) {
+        VIR_FREE(*tmp);
+        tmp++;
+    }
+    VIR_FREE(data->sasl_allowed_username_list);
+
+    VIR_FREE(data->key_file);
+    VIR_FREE(data->ca_file);
+    VIR_FREE(data->cert_file);
+    VIR_FREE(data->crl_file);
+
+    VIR_FREE(data->log_filters);
+    VIR_FREE(data->log_outputs);
+
+    VIR_FREE(data);
+}
+
+
+/* Read the config file if it exists.
+ * Only used in the remote case, hence the name.
+ */
+static int
+daemonConfigLoad(struct daemonConfig *data,
+                 const char *filename)
+{
+    virConfPtr conf;
+
     conf = virConfReadFile (filename, 0);
-    if (!conf) return -1;
+    if (!conf)
+        return -1;
 
-    /*
-     * First get all the logging settings and activate them
-     */
-    if (qemudSetLogging(conf, filename) < 0)
-        goto free_and_fail;
 
     GET_CONF_INT (conf, filename, listen_tcp);
     GET_CONF_INT (conf, filename, listen_tls);
@@ -2791,76 +1078,28 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
     GET_CONF_STR (conf, filename, tcp_port);
     GET_CONF_STR (conf, filename, listen_addr);
 
-    if (remoteConfigGetAuth(conf, "auth_unix_rw", &auth_unix_rw, filename) < 0)
-        goto free_and_fail;
+    if (remoteConfigGetAuth(conf, "auth_unix_rw", &data->auth_unix_rw, filename) < 0)
+        goto error;
 #if HAVE_POLKIT
     /* Change default perms to be wide-open if PolicyKit is enabled.
      * Admin can always override in config file
      */
-    if (auth_unix_rw == REMOTE_AUTH_POLKIT)
-        unix_sock_rw_mask = 0777;
+    if (data->auth_unix_rw == REMOTE_AUTH_POLKIT) {
+        VIR_FREE(data->unix_sock_rw_perms);
+        if (!(data->unix_sock_rw_perms = strdup("0777")))
+            goto no_memory;
+    }
 #endif
-    if (remoteConfigGetAuth(conf, "auth_unix_ro", &auth_unix_ro, filename) < 0)
-        goto free_and_fail;
-    if (remoteConfigGetAuth(conf, "auth_tcp", &auth_tcp, filename) < 0)
-        goto free_and_fail;
-    if (remoteConfigGetAuth(conf, "auth_tls", &auth_tls, filename) < 0)
-        goto free_and_fail;
+    if (remoteConfigGetAuth(conf, "auth_unix_ro", &data->auth_unix_ro, filename) < 0)
+        goto error;
+    if (remoteConfigGetAuth(conf, "auth_tcp", &data->auth_tcp, filename) < 0)
+        goto error;
+    if (remoteConfigGetAuth(conf, "auth_tls", &data->auth_tls, filename) < 0)
+        goto error;
 
     GET_CONF_STR (conf, filename, unix_sock_group);
-    if (unix_sock_group) {
-        if (!server->privileged) {
-            VIR_WARN0("Cannot set group when not running as root");
-        } else {
-            int ret;
-            struct group grpdata, *grp;
-            size_t maxbuf = sysconf(_SC_GETGR_R_SIZE_MAX);
-
-            if (maxbuf == -1)
-                maxbuf = 1024;
-
-            if (VIR_ALLOC_N(buf, maxbuf) < 0) {
-                VIR_ERROR0(_("Failed to allocate memory for buffer"));
-                goto free_and_fail;
-            }
-
-            while ((ret = getgrnam_r(unix_sock_group, &grpdata,
-                                     buf, maxbuf,
-                                     &grp)) == ERANGE) {
-                    maxbuf *= 2;
-                    if (maxbuf > 65536 || VIR_REALLOC_N(buf, maxbuf) < 0) {
-                        VIR_ERROR0(_("Failed to reallocate enough memory for buffer"));
-                        goto free_and_fail;
-                    }
-            }
-
-            if (ret != 0 || !grp) {
-                VIR_ERROR(_("Failed to lookup group '%s'"), unix_sock_group);
-                goto free_and_fail;
-            }
-            unix_sock_gid = grp->gr_gid;
-            VIR_FREE(buf);
-        }
-        VIR_FREE(unix_sock_group);
-    }
-
     GET_CONF_STR (conf, filename, unix_sock_ro_perms);
-    if (unix_sock_ro_perms) {
-        if (virStrToLong_i (unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) {
-            VIR_ERROR(_("Failed to parse mode '%s'"), unix_sock_ro_perms);
-            goto free_and_fail;
-        }
-        VIR_FREE(unix_sock_ro_perms);
-    }
-
     GET_CONF_STR (conf, filename, unix_sock_rw_perms);
-    if (unix_sock_rw_perms) {
-        if (virStrToLong_i (unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
-            VIR_ERROR(_("Failed to parse mode '%s'"), unix_sock_rw_perms);
-            goto free_and_fail;
-        }
-        VIR_FREE(unix_sock_rw_perms);
-    }
 
     GET_CONF_STR (conf, filename, unix_sock_dir);
 
@@ -2874,12 +1113,14 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
     GET_CONF_STR (conf, filename, ca_file);
     GET_CONF_STR (conf, filename, crl_file);
 
-    if (remoteConfigGetStringList (conf, "tls_allowed_dn_list",
-                                   &tls_allowed_dn_list, filename) < 0)
-        goto free_and_fail;
+    if (remoteConfigGetStringList(conf, "tls_allowed_dn_list",
+                                  &data->tls_allowed_dn_list, filename) < 0)
+        goto error;
+
 
-    if (remoteReadSaslAllowedUsernameList (conf, server, filename) < 0)
-        goto free_and_fail;
+    if (remoteConfigGetStringList(conf, "sasl_allowed_username_list",
+                                  &data->sasl_allowed_username_list, filename) < 0)
+        goto error;
 
 
     GET_CONF_INT (conf, filename, min_workers);
@@ -2893,51 +1134,31 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
     GET_CONF_INT (conf, filename, audit_logging);
 
     GET_CONF_STR (conf, filename, host_uuid);
-    if (virSetHostUUIDStr(host_uuid)) {
-        VIR_ERROR(_("invalid host UUID: %s"), host_uuid);
-        goto free_and_fail;
-    }
 
-    VIR_FREE(host_uuid);
+    GET_CONF_INT (conf, filename, log_level);
+    GET_CONF_STR (conf, filename, log_filters);
+    GET_CONF_STR (conf, filename, log_outputs);
 
     virConfFree (conf);
     return 0;
 
- free_and_fail:
+no_memory:
+    virReportOOMError();
+error:
     virConfFree (conf);
-    VIR_FREE(host_uuid);
-    VIR_FREE(mdns_name);
-    VIR_FREE(unix_sock_ro_perms);
-    VIR_FREE(unix_sock_rw_perms);
-    VIR_FREE(unix_sock_group);
-    VIR_FREE(buf);
-
-    /* Don't bother trying to free listen_addr, tcp_port, tls_port, key_file,
-       cert_file, ca_file, or crl_file, since they are initialized to
-       non-malloc'd strings.  Besides, these are static variables, and callers
-       are unlikely to call this function more than once, so there wouldn't
-       even be a real leak.  */
-
-    if (tls_allowed_dn_list) {
-        int i;
-        for (i = 0; tls_allowed_dn_list[i]; i++)
-            VIR_FREE(tls_allowed_dn_list[i]);
-        VIR_FREE(tls_allowed_dn_list);
-    }
-
     return -1;
 }
 
 /* Display version information. */
 static void
-version (void)
+daemonVersion(const char *argv0)
 {
     printf ("%s (%s) %s\n", argv0, PACKAGE_NAME, PACKAGE_VERSION);
 }
 
 #ifdef __sun
 static int
-qemudSetupPrivs (void)
+daemonSetupPrivs(void)
 {
     chown ("/var/run/libvirt", SYSTEM_UID, SYSTEM_UID);
 
@@ -2956,72 +1177,61 @@ qemudSetupPrivs (void)
     return 0;
 }
 #else
-# define qemudSetupPrivs() 0
+# define daemonSetupPrivs() 0
 #endif
 
 
-/*
- * Doing anything non-trivial in signal handlers is pretty dangerous,
- * since there are very few async-signal safe POSIX funtions. To
- * deal with this we setup a very simple signal handler. It simply
- * writes the signal number to a pipe. The main event loop then sees
- * the signal on the pipe and can safely do the processing from
- * event loop context
- */
-static int
-daemonSetupSignals(struct qemud_server *server)
+static void daemonShutdownHandler(virNetServerPtr srv,
+                                  siginfo_t *sig ATTRIBUTE_UNUSED,
+                                  void *opaque ATTRIBUTE_UNUSED)
 {
-    struct sigaction sig_action;
-    int sigpipe[2];
+    virNetServerQuit(srv);
+}
 
-    if (pipe(sigpipe) < 0)
+static int daemonSetupSignals(virNetServerPtr srv)
+{
+    if (virNetServerAddSignalHandler(srv, SIGINT, daemonShutdownHandler, NULL) < 0)
         return -1;
+    if (virNetServerAddSignalHandler(srv, SIGQUIT, daemonShutdownHandler, NULL) < 0)
+        return -1;
+    if (virNetServerAddSignalHandler(srv, SIGTERM, daemonShutdownHandler, NULL) < 0)
+        return -1;
+    return 0;
+}
 
-    if (virSetNonBlock(sigpipe[0]) < 0 ||
-        virSetNonBlock(sigpipe[1]) < 0 ||
-        virSetCloseExec(sigpipe[0]) < 0 ||
-        virSetCloseExec(sigpipe[1]) < 0) {
-        char ebuf[1024];
-        VIR_ERROR(_("Failed to create pipe: %s"),
-                  virStrerror(errno, ebuf, sizeof ebuf));
-        goto error;
-    }
-
-    sig_action.sa_sigaction = sig_handler;
-    sig_action.sa_flags = SA_SIGINFO;
-    sigemptyset(&sig_action.sa_mask);
-
-    sigaction(SIGHUP, &sig_action, NULL);
-    sigaction(SIGINT, &sig_action, NULL);
-    sigaction(SIGQUIT, &sig_action, NULL);
-    sigaction(SIGTERM, &sig_action, NULL);
-
-    sig_action.sa_handler = SIG_IGN;
-    sigaction(SIGPIPE, &sig_action, NULL);
+static void daemonRunStateInit(void *opaque)
+{
+    virNetServerPtr srv = opaque;
 
-    if (virEventAddHandleImpl(sigpipe[0],
-                              VIR_EVENT_HANDLE_READABLE,
-                              qemudDispatchSignalEvent,
-                              server, NULL) < 0) {
-        VIR_ERROR0(_("Failed to register callback for signal pipe"));
-        goto error;
+    /* Start the stateful HV drivers
+     * This is delibrately done after telling the parent process
+     * we're ready, since it can take a long time and this will
+     * seriously delay OS bootup process */
+    if (virStateInitialize(virNetServerIsPrivileged(srv)) < 0) {
+        VIR_ERROR0(_("Driver state initialization failed"));
+        virNetServerFree(srv);
+        return;
     }
 
-    server->sigread = sigpipe[0];
-    server->sigwrite = sigpipe[1];
-    sigwrite = sigpipe[1];
+    /* Only now accept clients from network */
+    virNetServerUpdateServices(srv, true);
+    virNetServerFree(srv);
+}
 
+static int daemonStateInit(virNetServerPtr srv)
+{
+    virThread thr;
+    virNetServerRef(srv);
+    if (virThreadCreate(&thr, false, daemonRunStateInit, srv) < 0) {
+        virNetServerFree(srv);
+        return -1;
+    }
     return 0;
-
-error:
-    VIR_FORCE_CLOSE(sigpipe[0]);
-    VIR_FORCE_CLOSE(sigpipe[1]);
-    return -1;
 }
 
 /* Print command-line usage. */
 static void
-usage (void)
+daemonUsage(const char *argv0)
 {
     fprintf (stderr,
              _("\n\
@@ -3077,12 +1287,18 @@ enum {
 
 #define MAX_LISTEN 5
 int main(int argc, char **argv) {
-    struct qemud_server *server = NULL;
-    const char *pid_file = NULL;
-    const char *remote_config_file = NULL;
+    virNetServerPtr srv = NULL;
+    char *remote_config_file = NULL;
     int statuswrite = -1;
     int ret = 1;
-    argv0 = argv[0];
+    char *pid_file = NULL;
+    char *sock_file = NULL;
+    char *sock_file_ro = NULL;
+    int timeout = -1;        /* -t: Shutdown timeout */
+    int verbose = 0;
+    int godaemon = 0;
+    int ipsock = 0;
+    struct daemonConfig *config;
 
     struct option opts[] = {
         { "verbose", no_argument, &verbose, 1},
@@ -3100,7 +1316,7 @@ int main(int argc, char **argv) {
         bindtextdomain (PACKAGE, LOCALEDIR) == NULL ||
         textdomain(PACKAGE) == NULL ||
         virInitialize() < 0) {
-        fprintf(stderr, _("%s: initialization failed\n"), argv0);
+        fprintf(stderr, _("%s: initialization failed\n"), argv[0]);
         exit(EXIT_FAILURE);
     }
 
@@ -3142,65 +1358,96 @@ int main(int argc, char **argv) {
             break;
 
         case 'p':
-            pid_file = optarg;
+            VIR_FREE(pid_file);
+            if (!(pid_file = strdup(optarg)))
+                exit(EXIT_FAILURE);
             break;
 
         case 'f':
-            remote_config_file = optarg;
+            if (!(remote_config_file = strdup(optarg)))
+                exit(EXIT_FAILURE);
             break;
 
         case OPT_VERSION:
-            version ();
+            daemonVersion(argv[0]);
             return 0;
 
         case '?':
-            usage ();
+            daemonUsage(argv[0]);
             return 2;
 
         default:
             fprintf (stderr, _("%s: internal error: unknown flag: %c\n"),
-                     argv0, c);
+                     argv[0], c);
             exit (EXIT_FAILURE);
         }
     }
 
-    if (remote_config_file == NULL) {
-        static const char *default_config_file
-            = SYSCONFDIR "/libvirt/libvirtd.conf";
-        remote_config_file =
-            (access(default_config_file, R_OK) == 0
-             ? default_config_file
-             : "/dev/null");
+    if (!(config = daemonConfigNew(geteuid() == 0 ? true : false)))
+        exit(EXIT_FAILURE);
+
+    /* No explicit config, so try and find a default one */
+    if (remote_config_file == NULL &&
+        daemonConfigFilePath(geteuid() == 0 ? true : false,
+                             &remote_config_file) < 0)
+        exit(EXIT_FAILURE);
+
+    /* Read the config file if it exists*/
+    if (remote_config_file &&
+        daemonConfigLoad(config, remote_config_file) < 0)
+        exit(EXIT_FAILURE);
+
+    if (config->host_uuid &&
+        virSetHostUUIDStr(config->host_uuid) < 0) {
+        VIR_ERROR(_("invalid host UUID: %s"), config->host_uuid);
+        exit(EXIT_FAILURE);
     }
 
+    if (daemonSetupLogging(config, verbose, godaemon) < 0)
+        exit(EXIT_FAILURE);
+
+    if (daemonPidFilePath(geteuid() == 0 ? true : false,
+                          &pid_file) < 0)
+        exit(EXIT_FAILURE);
+
+    if (daemonUnixSocketPaths(config,
+                              geteuid() == 0 ? true : false,
+                              &sock_file,
+                              &sock_file_ro) < 0)
+        exit(EXIT_FAILURE);
+
     if (godaemon) {
         char ebuf[1024];
 
         if (chdir("/") < 0) {
             VIR_ERROR(_("cannot change to root directory: %s"),
                       virStrerror(errno, ebuf, sizeof(ebuf)));
-            goto error;
+            goto cleanup;
         }
 
-        if ((statuswrite = daemonForkIntoBackground()) < 0) {
+        if ((statuswrite = daemonForkIntoBackground(argv[0])) < 0) {
             VIR_ERROR(_("Failed to fork as daemon: %s"),
                       virStrerror(errno, ebuf, sizeof ebuf));
-            goto error;
+            goto cleanup;
         }
     }
 
     /* If running as root and no PID file is set, use the default */
     if (pid_file == NULL &&
         geteuid() == 0 &&
-        REMOTE_PID_FILE[0] != '\0')
-        pid_file = REMOTE_PID_FILE;
+        REMOTE_PID_FILE[0] != '\0') {
+        if (!(pid_file = strdup(REMOTE_PID_FILE))) {
+            ret = VIR_DAEMON_ERR_PIDFILE;
+            goto cleanup;
+        }
+    }
 
     /* If we have a pidfile set, claim it now, exiting if already taken */
     if (pid_file != NULL &&
-        qemudWritePidFile (pid_file) < 0) {
-        pid_file = NULL; /* Prevent unlinking of someone else's pid ! */
+        daemonWritePidFile(pid_file, argv[0]) < 0) {
+        VIR_FREE(pid_file); /* Prevent unlinking of someone else's pid ! */
         ret = VIR_DAEMON_ERR_PIDFILE;
-        goto error;
+        goto cleanup;
     }
 
     /* Ensure the rundir exists (on tmpfs on some systems) */
@@ -3213,56 +1460,87 @@ int main(int argc, char **argv) {
                 VIR_ERROR(_("unable to create rundir %s: %s"), rundir,
                           virStrerror(errno, ebuf, sizeof(ebuf)));
                 ret = VIR_DAEMON_ERR_RUNDIR;
-                goto error;
+                goto cleanup;
             }
         }
     }
 
+    if (!(srv = virNetServerNew(config->min_workers,
+                                config->max_workers,
+                                config->max_clients,
+                                remoteClientInitHook))) {
+        ret = VIR_DAEMON_ERR_INIT;
+        goto cleanup;
+    }
+
     /* Beyond this point, nothing should rely on using
      * getuid/geteuid() == 0, for privilege level checks.
-     * It must all use the flag 'server->privileged'
-     * which is also passed into all libvirt stateful
-     * drivers
      */
-    if (qemudSetupPrivs() < 0) {
+    if (daemonSetupPrivs() < 0) {
         ret = VIR_DAEMON_ERR_PRIVS;
-        goto error;
+        goto cleanup;
     }
 
-    if (!(server = qemudInitialize())) {
+    daemonInitialize();
+
+    remoteProcs[REMOTE_PROC_AUTH_LIST].needAuth = false;
+    remoteProcs[REMOTE_PROC_AUTH_SASL_INIT].needAuth = false;
+    remoteProcs[REMOTE_PROC_AUTH_SASL_STEP].needAuth = false;
+    remoteProcs[REMOTE_PROC_AUTH_SASL_START].needAuth = false;
+    remoteProcs[REMOTE_PROC_AUTH_POLKIT].needAuth = false;
+    if (!(remoteProgram = virNetServerProgramNew(REMOTE_PROGRAM,
+                                                 REMOTE_PROTOCOL_VERSION,
+                                                 remoteProcs,
+                                                 remoteNProcs))) {
         ret = VIR_DAEMON_ERR_INIT;
-        goto error;
+        goto cleanup;
+    }
+    if (virNetServerAddProgram(srv, remoteProgram) < 0) {
+        ret = VIR_DAEMON_ERR_INIT;
+        goto cleanup;
     }
 
-    if ((daemonSetupSignals(server)) < 0) {
-        ret = VIR_DAEMON_ERR_SIGNAL;
-        goto error;
+    if (!(qemuProgram = virNetServerProgramNew(QEMU_PROGRAM,
+                                               QEMU_PROTOCOL_VERSION,
+                                               qemuProcs,
+                                               qemuNProcs))) {
+        ret = VIR_DAEMON_ERR_INIT;
+        goto cleanup;
+    }
+    if (virNetServerAddProgram(srv, qemuProgram) < 0) {
+        ret = VIR_DAEMON_ERR_INIT;
+        goto cleanup;
     }
 
-    /* Read the config file (if it exists). */
-    if (remoteReadConfigFile (server, remote_config_file) < 0) {
-        ret = VIR_DAEMON_ERR_CONFIG;
-        goto error;
+    if (timeout != -1)
+        virNetServerAutoShutdown(srv,
+                                 timeout,
+                                 daemonShutdownCheck,
+                                 NULL);
+
+    if ((daemonSetupSignals(srv)) < 0) {
+        ret = VIR_DAEMON_ERR_SIGNAL;
+        goto cleanup;
     }
 
-    if (audit_level) {
+    if (config->audit_level) {
         if (virAuditOpen() < 0) {
-            if (audit_level > 1) {
+            if (config->audit_level > 1) {
                 ret = VIR_DAEMON_ERR_AUDIT;
-                goto error;
+                goto cleanup;
             }
         }
     }
-    virAuditLog(audit_logging);
+    virAuditLog(config->audit_logging);
 
     /* setup the hooks if any */
     if (virHookInitialize() < 0) {
         ret = VIR_DAEMON_ERR_HOOKS;
-        goto error;
+        goto cleanup;
     }
 
     /* Disable error func, now logging is setup */
-    virSetErrorFunc(NULL, virshErrorHandler);
+    virSetErrorFunc(NULL, daemonErrorHandler);
 
     /*
      * Call the daemon startup hook
@@ -3272,9 +1550,11 @@ int main(int argc, char **argv) {
     virHookCall(VIR_HOOK_DRIVER_DAEMON, "-", VIR_HOOK_DAEMON_OP_START,
                 0, "start", NULL);
 
-    if (qemudNetworkInit(server) < 0) {
+    if (daemonSetupNetworking(srv, config,
+                              sock_file, sock_file_ro,
+                              ipsock) < 0) {
         ret = VIR_DAEMON_ERR_NETWORK;
-        goto error;
+        goto cleanup;
     }
 
     /* Tell parent of daemon that basic initialization is complete
@@ -3289,52 +1569,24 @@ int main(int argc, char **argv) {
         VIR_FORCE_CLOSE(statuswrite);
     }
 
-    /* Start the event loop in a background thread, since
-     * state initialization needs events to be being processed */
-    if (qemudStartEventLoop(server) < 0) {
-        VIR_ERROR0(_("Event thread startup failed"));
-        goto error;
-    }
-
-    /* Start the stateful HV drivers
-     * This is delibrately done after telling the parent process
-     * we're ready, since it can take a long time and this will
-     * seriously delay OS bootup process */
-    if (virStateInitialize(server->privileged) < 0) {
-        VIR_ERROR0(_("Driver state initialization failed"));
-        goto shutdown;
+    /* Initialize drivers & then start accepting new clients from network */
+    if (daemonStateInit(srv) < 0) {
+        ret = VIR_DAEMON_ERR_INIT;
+        goto cleanup;
     }
 
-    /* Start accepting new clients from network */
-    virMutexLock(&server->lock);
-    if (qemudNetworkEnable(server) < 0) {
-        VIR_ERROR0(_("Network event loop enablement failed"));
-        goto shutdown;
-    }
-    virMutexUnlock(&server->lock);
+    /* Run event loop. */
+    virNetServerRun(srv);
 
     ret = 0;
 
-shutdown:
-    /* In a non-0 shutdown scenario we need to tell event loop
-     * to quit immediately. Otherwise in normal case we just
-     * sit in the thread join forever. Sure this means the
-     * main thread doesn't do anything useful ever, but that's
-     * not too much of drain on resources
-     */
-    if (ret != 0) {
-        virMutexLock(&server->lock);
-        if (server->hasEventThread)
-            /* This SIGQUIT triggers the shutdown process */
-            kill(getpid(), SIGQUIT);
-        virMutexUnlock(&server->lock);
-    }
-    pthread_join(server->eventThread, NULL);
-
     virHookCall(VIR_HOOK_DRIVER_DAEMON, "-", VIR_HOOK_DAEMON_OP_SHUTDOWN,
                 0, "shutdown", NULL);
 
-error:
+cleanup:
+    virNetServerProgramFree(remoteProgram);
+    virNetServerProgramFree(qemuProgram);
+    virNetServerFree(srv);
     if (statuswrite != -1) {
         if (ret != 0) {
             /* Tell parent of daemon what failed */
@@ -3345,10 +1597,13 @@ error:
         }
         VIR_FORCE_CLOSE(statuswrite);
     }
-    if (server)
-        qemudCleanup(server);
     if (pid_file)
         unlink (pid_file);
+    VIR_FREE(sock_file);
+    VIR_FREE(sock_file_ro);
+    VIR_FREE(pid_file);
+    VIR_FREE(remote_config_file);
+    daemonConfigFree(config);
     virLogShutdown();
     return ret;
 }
diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index af20e56..aa6560f 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -27,13 +27,6 @@
 
 # include <config.h>
 
-# include <gnutls/gnutls.h>
-# include <gnutls/x509.h>
-# include "gnutls_1_0_compat.h"
-# if HAVE_SASL
-#  include <sasl/sasl.h>
-# endif
-
 # if HAVE_POLKIT0
 #  include <dbus/dbus.h>
 # endif
@@ -49,6 +42,8 @@
 # include "logging.h"
 # include "threads.h"
 # include "network.h"
+# include "virnetsaslcontext.h"
+# include "virnetserverprogram.h"
 
 # if WITH_DTRACE
 #  ifndef LIBVIRTD_PROBES_H
@@ -67,231 +62,37 @@
                   #NAME ": " FMT, __VA_ARGS__);
 # endif
 
-# ifdef __GNUC__
-#  ifdef HAVE_ANSIDECL_H
-#   include <ansidecl.h>
-#  endif
-
-#  ifndef __GNUC_PREREQ
-#   if defined __GNUC__ && defined __GNUC_MINOR__
-#    define __GNUC_PREREQ(maj, min)                                        \
-    ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
-#   else
-#    define __GNUC_PREREQ(maj,min) 0
-#   endif
-#  endif
-
-/**
- * ATTRIBUTE_UNUSED:
- *
- * Macro to flag conciously unused parameters to functions
- */
-#  ifndef ATTRIBUTE_UNUSED
-#   define ATTRIBUTE_UNUSED __attribute__((__unused__))
-#  endif
-
-/**
- * ATTRIBUTE_FMT_PRINTF
- *
- * Macro used to check printf like functions, if compiling
- * with gcc.
- *
- * We use gnulib which guarentees we always have GNU style
- * printf format specifiers even on broken Win32 platforms
- * hence we have to force 'gnu_printf' for new GCC
- */
-#  ifndef ATTRIBUTE_FMT_PRINTF
-#   if __GNUC_PREREQ (4, 4)
-#    define ATTRIBUTE_FMT_PRINTF(fmtpos,argpos) __attribute__((__format__ (gnu_printf, fmtpos,argpos)))
-#   else
-#    define ATTRIBUTE_FMT_PRINTF(fmtpos,argpos) __attribute__((__format__ (printf, fmtpos,argpos)))
-#   endif
-#  endif
-
-#  ifndef ATTRIBUTE_RETURN_CHECK
-#   if __GNUC_PREREQ (3, 4)
-#    define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__))
-#   else
-#    define ATTRIBUTE_RETURN_CHECK
-#   endif
-#  endif
-
-# else
-#  ifndef ATTRIBUTE_UNUSED
-#   define ATTRIBUTE_UNUSED
-#  endif
-#  ifndef ATTRIBUTE_FMT_PRINTF
-#   define ATTRIBUTE_FMT_PRINTF(...)
-#  endif
-#  ifndef ATTRIBUTE_RETURN_CHECK
-#   define ATTRIBUTE_RETURN_CHECK
-#  endif
-# endif
-
-# define qemudDebug DEBUG
-
-/* Whether we're passing reads & writes through a sasl SSF */
-enum qemud_sasl_ssf {
-    QEMUD_SASL_SSF_NONE = 0,
-    QEMUD_SASL_SSF_READ = 1,
-    QEMUD_SASL_SSF_WRITE = 2,
-};
-
-enum qemud_sock_type {
-    QEMUD_SOCK_TYPE_UNIX = 0,
-    QEMUD_SOCK_TYPE_TCP = 1,
-    QEMUD_SOCK_TYPE_TLS = 2,
-};
-
-struct qemud_client_message {
-    char buffer [REMOTE_MESSAGE_MAX + REMOTE_MESSAGE_HEADER_XDR_LEN];
-    unsigned int bufferLength;
-    unsigned int bufferOffset;
-
-    unsigned int async : 1;
-    unsigned int streamTX : 1;
-
-    remote_message_header hdr;
-
-    struct qemud_client_message *next;
-};
-
-struct qemud_client;
-
-/* Allow for filtering of incoming messages to a custom
- * dispatch processing queue, instead of client->dx.
- */
-typedef int (*qemud_client_filter_func)(struct qemud_client *client,
-                                        struct qemud_client_message *msg, void *opaque);
-struct qemud_client_filter {
-    qemud_client_filter_func query;
-    void *opaque;
-
-    struct qemud_client_filter *next;
-};
-
-struct qemud_client_stream {
-    virStreamPtr st;
-    int procedure;
-    int serial;
-
-    unsigned int recvEOF : 1;
-    unsigned int closed : 1;
-
-    struct qemud_client_filter filter;
-
-    struct qemud_client_message *rx;
-    int tx;
-
-    struct qemud_client_stream *next;
-};
+typedef struct daemonClientStream daemonClientStream;
+typedef daemonClientStream *daemonClientStreamPtr;
+typedef struct daemonClientPrivate daemonClientPrivate;
+typedef daemonClientPrivate *daemonClientPrivatePtr;
 
 /* Stores the per-client connection state */
-struct qemud_client {
+struct daemonClientPrivate {
+    /* Hold while accessing any data except conn */
     virMutex lock;
 
-    int magic;
-
-    int fd;
-    int watch;
-    unsigned int readonly :1;
-    unsigned int closing :1;
     int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST];
 
-    virSocketAddr addr;
-    const char *addrstr;
-
-    int type; /* qemud_sock_type */
-    gnutls_session_t tlssession;
-    int auth;
-    unsigned int handshake :1; /* If we're in progress for TLS handshake */
-# if HAVE_SASL
-    sasl_conn_t *saslconn;
-    int saslSSF;
-    const char *saslDecoded;
-    unsigned int saslDecodedLength;
-    unsigned int saslDecodedOffset;
-    const char *saslEncoded;
-    unsigned int saslEncodedLength;
-    unsigned int saslEncodedOffset;
-    char *saslUsername;
-# endif
-
-    /* Count of meages in 'dx' or 'tx' queue
-     * ie RPC calls in progress. Does not count
-     * async events which are not used for
-     * throttling calculations */
-    int nrequests;
-    /* Zero or one messages being received. Zero if
-     * nrequests >= max_clients and throttling */
-    struct qemud_client_message *rx;
-    /* Zero or many messages waiting for a worker
-     * to process them */
-    struct qemud_client_message *dx;
-    /* Zero or many messages waiting for transmit
-     * back to client, including async events */
-    struct qemud_client_message *tx;
-    /* Filters to capture messages that would otherwise
-     * end up on the 'dx' queue */
-    struct qemud_client_filter *filters;
-
-    /* Data streams */
-    struct qemud_client_stream *streams;
-
+    virNetSASLSessionPtr sasl;
 
     /* This is only valid if a remote open call has been made on this
      * connection, otherwise it will be NULL.  Also if remote close is
      * called, it will be set back to NULL if that succeeds.
      */
     virConnectPtr conn;
-    int refs;
 
+    daemonClientStreamPtr streams;
 };
 
-# define QEMUD_CLIENT_MAGIC 0x7788aaee
-
-
-struct qemud_socket {
-    char *path;
-
-    virSocketAddr addr;
-    const char *addrstr;
-
-    int fd;
-    int watch;
-    int readonly;
-    int type; /* qemud_sock_type */
-    int auth;
-
-    struct qemud_socket *next;
-};
-
-struct qemud_worker {
-    pthread_t thread;
-    unsigned int hasThread :1;
-    unsigned int processingCall :1;
-    unsigned int quitRequest :1;
-
-    /* back-pointer to our server */
-    struct qemud_server *server;
-};
+extern virNetSASLContextPtr saslCtxt;
+extern virNetServerProgramPtr remoteProgram;
+extern virNetServerProgramPtr qemuProgram;
 
 /* Main server state */
 struct qemud_server {
-    virMutex lock;
-    virCond job;
-
     int privileged;
 
-    size_t nworkers;
-    size_t nactiveworkers;
-    struct qemud_worker *workers;
-    size_t nsockets;
-    struct qemud_socket *sockets;
-    size_t nclients;
-    size_t nclients_max;
-    struct qemud_client **clients;
-
     int sigread;
     int sigwrite;
     char *logDir;
@@ -309,27 +110,6 @@ struct qemud_server {
 # endif
 };
 
-void qemudLog(int priority, const char *fmt, ...)
-    ATTRIBUTE_FMT_PRINTF(2,3);
-
-
-
-int qemudRegisterClientEvent(struct qemud_server *server,
-                             struct qemud_client *client);
-void qemudUpdateClientEvent(struct qemud_client *client);
-
-void qemudDispatchClientFailure(struct qemud_client *client);
-
-void
-qemudClientMessageQueuePush(struct qemud_client_message **queue,
-                            struct qemud_client_message *msg);
-struct qemud_client_message *
-qemudClientMessageQueueServe(struct qemud_client_message **queue);
-
-void
-qemudClientMessageRelease(struct qemud_client *client,
-                          struct qemud_client_message *msg);
-
 
 # if HAVE_POLKIT
 int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
diff --git a/daemon/remote.c b/daemon/remote.c
index 9dba325..de3fa7b 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -22,26 +22,6 @@
 
 #include <config.h>
 
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <string.h>
-#include <errno.h>
-#include <fnmatch.h>
-#include <arpa/inet.h>
 #include "virterror_internal.h"
 
 #if HAVE_POLKIT0
@@ -50,19 +30,32 @@
 #endif
 
 #include "remote.h"
-#include "dispatch.h"
-
+#include "libvirtd.h"
 #include "libvirt_internal.h"
 #include "datatypes.h"
 #include "memory.h"
+#include "logging.h"
 #include "util.h"
 #include "stream.h"
 #include "uuid.h"
 #include "network.h"
 #include "libvirt/libvirt-qemu.h"
+#include "virnetserverservice.h"
+
+#include "remote_protocol.h"
+#include "qemu_protocol.h"
+
+
+#include "remote_dispatch.h"
+#include "qemu_dispatch.h"
 
-#define VIR_FROM_THIS VIR_FROM_REMOTE
-#define REMOTE_DEBUG(fmt, ...) DEBUG(fmt, __VA_ARGS__)
+
+#define VIR_FROM_THIS VIR_FROM_RPC
+
+#define virNetError(code, ...)                                    \
+    virReportErrorHelper(NULL, VIR_FROM_RPC, code, __FILE__,      \
+                         __FUNCTION__, __LINE__, __VA_ARGS__)
+#define REMOTE_DEBUG(fmt, ...) VIR_DEBUG(fmt, __VA_ARGS__)
 
 static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain);
 static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network network);
@@ -83,43 +76,13 @@ static void make_nonnull_nwfilter (remote_nonnull_nwfilter *net_dst, virNWFilter
 static void make_nonnull_domain_snapshot (remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
 
 
-#include "remote_dispatch_prototypes.h"
-#include "qemu_dispatch_prototypes.h"
-
-static const dispatch_data const dispatch_table[] = {
-#include "remote_dispatch_table.h"
-};
-
-static const dispatch_data const qemu_dispatch_table[] = {
-#include "qemu_dispatch_table.h"
-};
-
-const dispatch_data const *remoteGetDispatchData(int proc)
-{
-    if (proc >= ARRAY_CARDINALITY(dispatch_table) ||
-        dispatch_table[proc].fn == NULL) {
-        return NULL;
-    }
-
-    return &(dispatch_table[proc]);
-}
-
-const dispatch_data const *qemuGetDispatchData(int proc)
-{
-    if (proc >= ARRAY_CARDINALITY(qemu_dispatch_table) ||
-        qemu_dispatch_table[proc].fn == NULL) {
-        return NULL;
-    }
-
-    return &(qemu_dispatch_table[proc]);
-}
-
 /* Prototypes */
 static void
-remoteDispatchDomainEventSend (struct qemud_client *client,
-                               int procnr,
-                               xdrproc_t proc,
-                               void *data);
+remoteDispatchDomainEventSend(virNetServerClientPtr client,
+                              virNetServerProgramPtr program,
+                              int procnr,
+                              xdrproc_t proc,
+                              void *data);
 
 static int remoteRelayDomainEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
                                            virDomainPtr dom,
@@ -127,7 +90,7 @@ static int remoteRelayDomainEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
                                            int detail,
                                            void *opaque)
 {
-    struct qemud_client *client = opaque;
+    virNetServerClientPtr client = opaque;
     remote_domain_event_lifecycle_msg data;
 
     if (!client)
@@ -135,20 +98,16 @@ static int remoteRelayDomainEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     REMOTE_DEBUG("Relaying domain lifecycle event %d %d", event, detail);
 
-    virMutexLock(&client->lock);
-
     /* build return data */
     memset(&data, 0, sizeof data);
     make_nonnull_domain (&data.dom, dom);
     data.event = event;
     data.detail = detail;
 
-    remoteDispatchDomainEventSend (client,
+    remoteDispatchDomainEventSend (client, remoteProgram,
                                    REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE,
                                    (xdrproc_t)xdr_remote_domain_event_lifecycle_msg, &data);
 
-    virMutexUnlock(&client->lock);
-
     return 0;
 }
 
@@ -156,7 +115,7 @@ static int remoteRelayDomainEventReboot(virConnectPtr conn ATTRIBUTE_UNUSED,
                                         virDomainPtr dom,
                                         void *opaque)
 {
-    struct qemud_client *client = opaque;
+    virNetServerClientPtr client = opaque;
     remote_domain_event_reboot_msg data;
 
     if (!client)
@@ -164,18 +123,14 @@ static int remoteRelayDomainEventReboot(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     REMOTE_DEBUG("Relaying domain reboot event %s %d", dom->name, dom->id);
 
-    virMutexLock(&client->lock);
-
     /* build return data */
     memset(&data, 0, sizeof data);
     make_nonnull_domain (&data.dom, dom);
 
-    remoteDispatchDomainEventSend (client,
+    remoteDispatchDomainEventSend (client, remoteProgram,
                                    REMOTE_PROC_DOMAIN_EVENT_REBOOT,
                                    (xdrproc_t)xdr_remote_domain_event_reboot_msg, &data);
 
-    virMutexUnlock(&client->lock);
-
     return 0;
 }
 
@@ -185,7 +140,7 @@ static int remoteRelayDomainEventRTCChange(virConnectPtr conn ATTRIBUTE_UNUSED,
                                            long long offset,
                                            void *opaque)
 {
-    struct qemud_client *client = opaque;
+    virNetServerClientPtr client = opaque;
     remote_domain_event_rtc_change_msg data;
 
     if (!client)
@@ -193,19 +148,15 @@ static int remoteRelayDomainEventRTCChange(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     REMOTE_DEBUG("Relaying domain rtc change event %s %d %lld", dom->name, dom->id, offset);
 
-    virMutexLock(&client->lock);
-
     /* build return data */
     memset(&data, 0, sizeof data);
     make_nonnull_domain (&data.dom, dom);
     data.offset = offset;
 
-    remoteDispatchDomainEventSend (client,
+    remoteDispatchDomainEventSend (client, remoteProgram,
                                    REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
                                    (xdrproc_t)xdr_remote_domain_event_rtc_change_msg, &data);
 
-    virMutexUnlock(&client->lock);
-
     return 0;
 }
 
@@ -215,7 +166,7 @@ static int remoteRelayDomainEventWatchdog(virConnectPtr conn ATTRIBUTE_UNUSED,
                                           int action,
                                           void *opaque)
 {
-    struct qemud_client *client = opaque;
+    virNetServerClientPtr client = opaque;
     remote_domain_event_watchdog_msg data;
 
     if (!client)
@@ -223,19 +174,15 @@ static int remoteRelayDomainEventWatchdog(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     REMOTE_DEBUG("Relaying domain watchdog event %s %d %d", dom->name, dom->id, action);
 
-    virMutexLock(&client->lock);
-
     /* build return data */
     memset(&data, 0, sizeof data);
     make_nonnull_domain (&data.dom, dom);
     data.action = action;
 
-    remoteDispatchDomainEventSend (client,
+    remoteDispatchDomainEventSend (client, remoteProgram,
                                    REMOTE_PROC_DOMAIN_EVENT_WATCHDOG,
                                    (xdrproc_t)xdr_remote_domain_event_watchdog_msg, &data);
 
-    virMutexUnlock(&client->lock);
-
     return 0;
 }
 
@@ -247,7 +194,7 @@ static int remoteRelayDomainEventIOError(virConnectPtr conn ATTRIBUTE_UNUSED,
                                          int action,
                                          void *opaque)
 {
-    struct qemud_client *client = opaque;
+    virNetServerClientPtr client = opaque;
     remote_domain_event_io_error_msg data;
 
     if (!client)
@@ -255,8 +202,6 @@ static int remoteRelayDomainEventIOError(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     REMOTE_DEBUG("Relaying domain io error %s %d %s %s %d", dom->name, dom->id, srcPath, devAlias, action);
 
-    virMutexLock(&client->lock);
-
     /* build return data */
     memset(&data, 0, sizeof data);
     make_nonnull_domain (&data.dom, dom);
@@ -264,12 +209,10 @@ static int remoteRelayDomainEventIOError(virConnectPtr conn ATTRIBUTE_UNUSED,
     data.devAlias = (char*)devAlias;
     data.action = action;
 
-    remoteDispatchDomainEventSend (client,
+    remoteDispatchDomainEventSend (client, remoteProgram,
                                    REMOTE_PROC_DOMAIN_EVENT_IO_ERROR,
                                    (xdrproc_t)xdr_remote_domain_event_io_error_msg, &data);
 
-    virMutexUnlock(&client->lock);
-
     return 0;
 }
 
@@ -282,7 +225,7 @@ static int remoteRelayDomainEventIOErrorReason(virConnectPtr conn ATTRIBUTE_UNUS
                                                const char *reason,
                                                void *opaque)
 {
-    struct qemud_client *client = opaque;
+    virNetServerClientPtr client = opaque;
     remote_domain_event_io_error_reason_msg data;
 
     if (!client)
@@ -291,8 +234,6 @@ static int remoteRelayDomainEventIOErrorReason(virConnectPtr conn ATTRIBUTE_UNUS
     REMOTE_DEBUG("Relaying domain io error %s %d %s %s %d %s",
                  dom->name, dom->id, srcPath, devAlias, action, reason);
 
-    virMutexLock(&client->lock);
-
     /* build return data */
     memset(&data, 0, sizeof data);
     make_nonnull_domain (&data.dom, dom);
@@ -301,12 +242,10 @@ static int remoteRelayDomainEventIOErrorReason(virConnectPtr conn ATTRIBUTE_UNUS
     data.action = action;
     data.reason = (char*)reason;
 
-    remoteDispatchDomainEventSend (client,
+    remoteDispatchDomainEventSend (client, remoteProgram,
                                    REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON,
                                    (xdrproc_t)xdr_remote_domain_event_io_error_reason_msg, &data);
 
-    virMutexUnlock(&client->lock);
-
     return 0;
 }
 
@@ -320,7 +259,7 @@ static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
                                           virDomainEventGraphicsSubjectPtr subject,
                                           void *opaque)
 {
-    struct qemud_client *client = opaque;
+    virNetServerClientPtr client = opaque;
     remote_domain_event_graphics_msg data;
     int i;
 
@@ -337,8 +276,6 @@ static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
         REMOTE_DEBUG("  %s=%s", subject->identities[i].type, subject->identities[i].name);
     }
 
-    virMutexLock(&client->lock);
-
     /* build return data */
     memset(&data, 0, sizeof data);
     make_nonnull_domain (&data.dom, dom);
@@ -355,7 +292,7 @@ static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     data.subject.subject_len = subject->nidentity;
     if (VIR_ALLOC_N(data.subject.subject_val, data.subject.subject_len) < 0) {
-        VIR_WARN0("cannot allocate memory for graphics event subject");
+        virReportOOMError();
         return -1;
     }
     for (i = 0 ; i < data.subject.subject_len ; i++) {
@@ -363,14 +300,12 @@ static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
         data.subject.subject_val[i].name = (char*)subject->identities[i].name;
     }
 
-    remoteDispatchDomainEventSend (client,
+    remoteDispatchDomainEventSend (client, remoteProgram,
                                    REMOTE_PROC_DOMAIN_EVENT_GRAPHICS,
                                    (xdrproc_t)xdr_remote_domain_event_graphics_msg, &data);
 
     VIR_FREE(data.subject.subject_val);
 
-    virMutexUnlock(&client->lock);
-
     return 0;
 }
 
@@ -387,86 +322,134 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
 
 verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
 
+/*
+ * You must hold lock for at least the client
+ * We don't free stuff here, merely disconnect the client's
+ * network socket & resources.
+ * We keep the libvirt connection open until any async
+ * jobs have finished, then clean it up elsehwere
+ */
+static void remoteClientFreeFunc(void *data)
+{
+    struct daemonClientPrivate *priv = data;
+
+    /* Deregister event delivery callback */
+    if (priv->conn) {
+        int i;
+
+        for (i = 0 ; i < VIR_DOMAIN_EVENT_ID_LAST ; i++) {
+            if (priv->domainEventCallbackID[i] != -1) {
+                DEBUG("Deregistering to relay remote events %d", i);
+                virConnectDomainEventDeregisterAny(priv->conn,
+                                                   priv->domainEventCallbackID[i]);
+            }
+            priv->domainEventCallbackID[i] = -1;
+        }
+
+        virConnectClose(priv->conn);
+    }
+
+    VIR_FREE(priv);
+}
+
+
+
+int remoteClientInitHook(virNetServerPtr srv ATTRIBUTE_UNUSED,
+                         virNetServerClientPtr client)
+{
+    struct daemonClientPrivate *priv;
+    int i;
+
+    if (VIR_ALLOC(priv) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    if (virMutexInit(&priv->lock) < 0) {
+        VIR_FREE(priv);
+        virReportOOMError();
+        return -1;
+    }
+
+    for (i = 0 ; i < VIR_DOMAIN_EVENT_ID_LAST ; i++)
+        priv->domainEventCallbackID[i] = -1;
+
+    virNetServerClientSetPrivateData(client, priv, remoteClientFreeFunc);
+    return 0;
+}
+
 /*----- Functions. -----*/
 
 static int
-remoteDispatchOpen (struct qemud_server *server,
-                    struct qemud_client *client,
-                    virConnectPtr conn,
-                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                    remote_error *rerr,
-                    struct remote_open_args *args, void *ret ATTRIBUTE_UNUSED)
+remoteDispatchOpen (virNetServerPtr server ATTRIBUTE_UNUSED,
+                    virNetServerClientPtr client,
+                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                    struct remote_open_args *args)
 {
     const char *name;
     int flags, rc;
-
+    struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
+    DEBUG("priv=%p conn=%p", priv, priv->conn);
+    virMutexLock(&priv->lock);
     /* Already opened? */
-    if (conn) {
-        remoteDispatchFormatError (rerr, "%s", _("connection already open"));
+    if (priv->conn) {
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("connection already open"));
         return -1;
     }
 
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
-
     name = args->name ? *args->name : NULL;
 
     /* If this connection arrived on a readonly socket, force
      * the connection to be readonly.
      */
     flags = args->flags;
-    if (client->readonly) flags |= VIR_CONNECT_RO;
+    if (virNetServerClientGetReadonly(client))
+        flags |= VIR_CONNECT_RO;
 
-    client->conn =
+    priv->conn =
         flags & VIR_CONNECT_RO
         ? virConnectOpenReadOnly (name)
         : virConnectOpen (name);
 
-    if (client->conn == NULL)
-        remoteDispatchConnError(rerr, NULL);
+    if (priv->conn) {
+        rc = 0;
+    } else {
+        rc = -1;
+    }
 
-    rc = client->conn ? 0 : -1;
-    virMutexUnlock(&client->lock);
+    virMutexUnlock(&priv->lock);
     return rc;
 }
 
 #define CHECK_CONN(client)                                              \
-    if (!client->conn) {                                                \
-        remoteDispatchFormatError (rerr, "%s", _("connection not open")); \
+    struct daemonClientPrivate *priv =                                  \
+        virNetServerClientGetPrivateData(client);                       \
+    if (!priv->conn) {                                                  \
+        virNetError(VIR_ERR_RPC, "%s", _("connection not open"));       \
         return -1;                                                      \
     }
 
 static int
-remoteDispatchClose (struct qemud_server *server ATTRIBUTE_UNUSED,
-                     struct qemud_client *client ATTRIBUTE_UNUSED,
-                     virConnectPtr conn ATTRIBUTE_UNUSED,
-                     remote_message_header *hdr ATTRIBUTE_UNUSED,
-                     remote_error *rerr ATTRIBUTE_UNUSED,
-                     void *args ATTRIBUTE_UNUSED, void *ret ATTRIBUTE_UNUSED)
+remoteDispatchClose (virNetServerPtr server ATTRIBUTE_UNUSED,
+                     virNetServerClientPtr client,
+                     virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED)
 {
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
-
-    client->closing = 1;
-
-    virMutexUnlock(&client->lock);
+    virNetServerClientClose(client);
     return 0;
 }
 
 static int
-remoteDispatchSupportsFeature (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
+remoteDispatchSupportsFeature (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_supports_feature_args *args, remote_supports_feature_ret *ret)
 {
-    ret->supported = virDrvSupportsFeature (conn, args->feature);
+    CHECK_CONN(client);
+
+    ret->supported = virDrvSupportsFeature (priv->conn, args->feature);
 
     if (ret->supported == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -474,18 +457,16 @@ remoteDispatchSupportsFeature (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchGetType (struct qemud_server *server ATTRIBUTE_UNUSED,
-                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                       virConnectPtr conn,
-                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                       remote_error *rerr,
-                       void *args ATTRIBUTE_UNUSED, remote_get_type_ret *ret)
+remoteDispatchGetType (virNetServerPtr server ATTRIBUTE_UNUSED,
+                       virNetServerClientPtr client,
+                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                       remote_get_type_ret *ret)
 {
     const char *type;
+    CHECK_CONN(client);
 
-    type = virConnectGetType (conn);
+    type = virConnectGetType (priv->conn);
     if (type == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -494,7 +475,7 @@ remoteDispatchGetType (struct qemud_server *server ATTRIBUTE_UNUSED,
      */
     ret->type = strdup (type);
     if (!ret->type) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
@@ -502,18 +483,15 @@ remoteDispatchGetType (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchGetVersion (struct qemud_server *server ATTRIBUTE_UNUSED,
-                          struct qemud_client *client ATTRIBUTE_UNUSED,
-                          virConnectPtr conn,
-                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                          remote_error *rerr,
-                          void *args ATTRIBUTE_UNUSED,
+remoteDispatchGetVersion (virNetServerPtr server ATTRIBUTE_UNUSED,
+                          virNetServerClientPtr client,
+                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                           remote_get_version_ret *ret)
 {
     unsigned long hvVer;
+    CHECK_CONN(client);
 
-    if (virConnectGetVersion (conn, &hvVer) == -1) {
-        remoteDispatchConnError(rerr, conn);
+    if (virConnectGetVersion (priv->conn, &hvVer) == -1) {
         return -1;
     }
 
@@ -522,18 +500,15 @@ remoteDispatchGetVersion (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchGetLibVersion (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             void *args ATTRIBUTE_UNUSED,
+remoteDispatchGetLibVersion (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                              remote_get_lib_version_ret *ret)
 {
     unsigned long libVer;
+    CHECK_CONN(client);
 
-    if (virConnectGetLibVersion (conn, &libVer) == -1) {
-        remoteDispatchConnError(rerr, conn);
+    if (virConnectGetLibVersion (priv->conn, &libVer) == -1) {
         return -1;
     }
 
@@ -542,19 +517,16 @@ remoteDispatchGetLibVersion (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchGetHostname (struct qemud_server *server ATTRIBUTE_UNUSED,
-                           struct qemud_client *client ATTRIBUTE_UNUSED,
-                           virConnectPtr conn,
-                           remote_message_header *hdr ATTRIBUTE_UNUSED,
-                           remote_error *rerr,
-                           void *args ATTRIBUTE_UNUSED,
+remoteDispatchGetHostname (virNetServerPtr server ATTRIBUTE_UNUSED,
+                           virNetServerClientPtr client,
+                           virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                            remote_get_hostname_ret *ret)
 {
     char *hostname;
+    CHECK_CONN(client);
 
-    hostname = virConnectGetHostname (conn);
+    hostname = virConnectGetHostname (priv->conn);
     if (hostname == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -563,20 +535,16 @@ remoteDispatchGetHostname (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchGetUri (struct qemud_server *server ATTRIBUTE_UNUSED,
-                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                      virConnectPtr conn,
-                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                      remote_error *rerr,
-                      void *args ATTRIBUTE_UNUSED,
+remoteDispatchGetUri (virNetServerPtr server ATTRIBUTE_UNUSED,
+                      virNetServerClientPtr client,
+                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                       remote_get_uri_ret *ret)
 {
     char *uri;
     CHECK_CONN(client);
 
-    uri = virConnectGetURI (conn);
+    uri = virConnectGetURI (priv->conn);
     if (uri == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -585,20 +553,18 @@ remoteDispatchGetUri (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchGetMaxVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
-                           struct qemud_client *client ATTRIBUTE_UNUSED,
-                           virConnectPtr conn,
-                           remote_message_header *hdr ATTRIBUTE_UNUSED,
-                           remote_error *rerr,
+remoteDispatchGetMaxVcpus (virNetServerPtr server ATTRIBUTE_UNUSED,
+                           virNetServerClientPtr client,
+                           virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                            remote_get_max_vcpus_args *args,
                            remote_get_max_vcpus_ret *ret)
 {
     char *type;
+    CHECK_CONN(client);
 
     type = args->type ? *args->type : NULL;
-    ret->max_vcpus = virConnectGetMaxVcpus (conn, type);
+    ret->max_vcpus = virConnectGetMaxVcpus (priv->conn, type);
     if (ret->max_vcpus == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -606,18 +572,15 @@ remoteDispatchGetMaxVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNodeGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
-                           struct qemud_client *client ATTRIBUTE_UNUSED,
-                           virConnectPtr conn,
-                           remote_message_header *hdr ATTRIBUTE_UNUSED,
-                           remote_error *rerr,
-                           void *args ATTRIBUTE_UNUSED,
+remoteDispatchNodeGetInfo (virNetServerPtr server ATTRIBUTE_UNUSED,
+                           virNetServerClientPtr client,
+                           virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                            remote_node_get_info_ret *ret)
 {
     virNodeInfo info;
+    CHECK_CONN(client);
 
-    if (virNodeGetInfo (conn, &info) == -1) {
-        remoteDispatchConnError(rerr, conn);
+    if (virNodeGetInfo (priv->conn, &info) == -1) {
         return -1;
     }
 
@@ -634,19 +597,16 @@ remoteDispatchNodeGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchGetCapabilities (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
-                               void *args ATTRIBUTE_UNUSED,
+remoteDispatchGetCapabilities (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_get_capabilities_ret *ret)
 {
     char *caps;
+    CHECK_CONN(client);
 
-    caps = virConnectGetCapabilities (conn);
+    caps = virConnectGetCapabilities (priv->conn);
     if (caps == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -655,35 +615,33 @@ remoteDispatchGetCapabilities (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNodeGetCellsFreeMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
+remoteDispatchNodeGetCellsFreeMemory (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_node_get_cells_free_memory_args *args,
                                       remote_node_get_cells_free_memory_ret *ret)
 {
     int err;
+    CHECK_CONN(client);
 
     if (args->maxCells > REMOTE_NODE_MAX_CELLS) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxCells > REMOTE_NODE_MAX_CELLS"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxCells > REMOTE_NODE_MAX_CELLS"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->freeMems.freeMems_val, args->maxCells) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
-    err = virNodeGetCellsFreeMemory(conn,
+    err = virNodeGetCellsFreeMemory(priv->conn,
                                     (unsigned long long *)ret->freeMems.freeMems_val,
                                     args->startCell,
                                     args->maxCells);
     if (err <= 0) {
         VIR_FREE(ret->freeMems.freeMems_val);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     ret->freeMems.freeMems_len = err;
@@ -693,19 +651,16 @@ remoteDispatchNodeGetCellsFreeMemory (struct qemud_server *server ATTRIBUTE_UNUS
 
 
 static int
-remoteDispatchNodeGetFreeMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
-                                 void *args ATTRIBUTE_UNUSED,
+remoteDispatchNodeGetFreeMemory (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_node_get_free_memory_ret *ret)
 {
     unsigned long long freeMem;
+    CHECK_CONN(client);
 
-    freeMem = virNodeGetFreeMemory(conn);
+    freeMem = virNodeGetFreeMemory(priv->conn);
     if (freeMem == 0) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     ret->freeMem = freeMem;
@@ -714,28 +669,25 @@ remoteDispatchNodeGetFreeMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchDomainGetSchedulerType (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
+remoteDispatchDomainGetSchedulerType (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_domain_get_scheduler_type_args *args,
                                       remote_domain_get_scheduler_type_ret *ret)
 {
     virDomainPtr dom;
     char *type;
     int nparams;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     type = virDomainGetSchedulerType (dom, &nparams);
     if (type == NULL) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -746,33 +698,32 @@ remoteDispatchDomainGetSchedulerType (struct qemud_server *server ATTRIBUTE_UNUS
 }
 
 static int
-remoteDispatchDomainGetSchedulerParameters (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                                            virConnectPtr conn,
-                                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                            remote_error *rerr,
+remoteDispatchDomainGetSchedulerParameters (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                            virNetServerClientPtr client,
+                                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                             remote_domain_get_scheduler_parameters_args *args,
                                             remote_domain_get_scheduler_parameters_ret *ret)
 {
     virDomainPtr dom;
     virSchedParameterPtr params;
     int i, r, nparams;
+    CHECK_CONN(client);
 
     nparams = args->nparams;
 
     if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
-        remoteDispatchFormatError (rerr, "%s", _("nparams too large"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("nparams too large"));
         return -1;
     }
     if (VIR_ALLOC_N(params, nparams) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
         VIR_FREE(params);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -780,7 +731,6 @@ remoteDispatchDomainGetSchedulerParameters (struct qemud_server *server ATTRIBUT
     if (r == -1) {
         virDomainFree(dom);
         VIR_FREE(params);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -810,7 +760,8 @@ remoteDispatchDomainGetSchedulerParameters (struct qemud_server *server ATTRIBUT
         case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
             ret->params.params_val[i].value.remote_sched_param_value_u.b = params[i].value.b; break;
         default:
-            remoteDispatchFormatError (rerr, "%s", _("unknown type"));
+            virNetError(VIR_ERR_RPC,
+                        "%s", _("unknown type"));
             goto cleanup;
         }
     }
@@ -820,7 +771,7 @@ remoteDispatchDomainGetSchedulerParameters (struct qemud_server *server ATTRIBUT
     return 0;
 
 oom:
-    remoteDispatchOOMError(rerr);
+    virReportOOMError();
 cleanup:
     virDomainFree(dom);
     for (i = 0 ; i < nparams ; i++)
@@ -830,34 +781,34 @@ cleanup:
 }
 
 static int
-remoteDispatchDomainSetSchedulerParameters (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                                            virConnectPtr conn,
-                                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                            remote_error *rerr,
-                                            remote_domain_set_scheduler_parameters_args *args,
-                                            void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSetSchedulerParameters (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                            virNetServerClientPtr client,
+                                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                            remote_domain_set_scheduler_parameters_args *args)
 {
     virDomainPtr dom;
     int i, r, nparams;
     virSchedParameterPtr params;
+    CHECK_CONN(client);
 
     nparams = args->params.params_len;
 
     if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
-        remoteDispatchFormatError (rerr, "%s", _("nparams too large"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("nparams too large"));
         return -1;
     }
     if (VIR_ALLOC_N(params, nparams) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     /* Deserialise parameters. */
     for (i = 0; i < nparams; ++i) {
         if (virStrcpyStatic(params[i].field, args->params.params_val[i].field) == NULL) {
-            remoteDispatchFormatError(rerr, _("Field %s too big for destination"),
-                                      args->params.params_val[i].field);
+            virNetError(VIR_ERR_RPC,
+                        _("Field %s too big for destination"),
+                        args->params.params_val[i].field);
             return -1;
         }
         params[i].type = args->params.params_val[i].value.type;
@@ -877,10 +828,9 @@ remoteDispatchDomainSetSchedulerParameters (struct qemud_server *server ATTRIBUT
         }
     }
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
         VIR_FREE(params);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -888,7 +838,6 @@ remoteDispatchDomainSetSchedulerParameters (struct qemud_server *server ATTRIBUT
     virDomainFree(dom);
     VIR_FREE(params);
     if (r == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -896,28 +845,25 @@ remoteDispatchDomainSetSchedulerParameters (struct qemud_server *server ATTRIBUT
 }
 
 static int
-remoteDispatchDomainBlockStats (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
+remoteDispatchDomainBlockStats (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_domain_block_stats_args *args,
                                 remote_domain_block_stats_ret *ret)
 {
     virDomainPtr dom;
     char *path;
     struct _virDomainBlockStats stats;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     path = args->path;
 
     if (virDomainBlockStats (dom, path, &stats, sizeof stats) == -1) {
         virDomainFree (dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree (dom);
@@ -932,28 +878,25 @@ remoteDispatchDomainBlockStats (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainInterfaceStats (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchDomainInterfaceStats (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_domain_interface_stats_args *args,
                                     remote_domain_interface_stats_ret *ret)
 {
     virDomainPtr dom;
     char *path;
     struct _virDomainInterfaceStats stats;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     path = args->path;
 
     if (virDomainInterfaceStats (dom, path, &stats, sizeof stats) == -1) {
         virDomainFree (dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree (dom);
@@ -971,34 +914,32 @@ remoteDispatchDomainInterfaceStats (struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchDomainMemoryStats (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchDomainMemoryStats (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_domain_memory_stats_args *args,
                                  remote_domain_memory_stats_ret *ret)
 {
     virDomainPtr dom;
     struct _virDomainMemoryStat *stats;
     unsigned int nr_stats, i;
+    CHECK_CONN(client);
 
     if (args->maxStats > REMOTE_DOMAIN_MEMORY_STATS_MAX) {
-        remoteDispatchFormatError (rerr, "%s",
-                               _("maxStats > REMOTE_DOMAIN_MEMORY_STATS_MAX"));
+        virNetError(VIR_ERR_RPC, "%s",
+                    _("maxStats > REMOTE_DOMAIN_MEMORY_STATS_MAX"));
         return -1;
     }
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     /* Allocate stats array for making dispatch call */
     if (VIR_ALLOC_N(stats, args->maxStats) < 0) {
+        virReportOOMError();
         virDomainFree (dom);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
@@ -1006,14 +947,13 @@ remoteDispatchDomainMemoryStats (struct qemud_server *server ATTRIBUTE_UNUSED,
     virDomainFree (dom);
     if (nr_stats == -1) {
         VIR_FREE(stats);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     /* Allocate return buffer */
     if (VIR_ALLOC_N(ret->stats.stats_val, args->maxStats) < 0) {
+        virReportOOMError();
         VIR_FREE(stats);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
@@ -1028,11 +968,9 @@ remoteDispatchDomainMemoryStats (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainBlockPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
+remoteDispatchDomainBlockPeek (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_domain_block_peek_args *args,
                                remote_domain_block_peek_ret *ret)
 {
@@ -1041,10 +979,10 @@ remoteDispatchDomainBlockPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
     unsigned long long offset;
     size_t size;
     unsigned int flags;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     path = args->path;
@@ -1054,15 +992,15 @@ remoteDispatchDomainBlockPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
 
     if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) {
         virDomainFree (dom);
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("size > maximum buffer size"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("size > maximum buffer size"));
         return -1;
     }
 
     ret->buffer.buffer_len = size;
     if (VIR_ALLOC_N (ret->buffer.buffer_val, size) < 0) {
+        virReportOOMError();
         virDomainFree (dom);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
@@ -1070,7 +1008,6 @@ remoteDispatchDomainBlockPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
                             ret->buffer.buffer_val, flags) == -1) {
         /* free (ret->buffer.buffer_val); - caller frees */
         virDomainFree (dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree (dom);
@@ -1079,11 +1016,9 @@ remoteDispatchDomainBlockPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainMemoryPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
+remoteDispatchDomainMemoryPeek (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_domain_memory_peek_args *args,
                                 remote_domain_memory_peek_ret *ret)
 {
@@ -1091,10 +1026,10 @@ remoteDispatchDomainMemoryPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
     unsigned long long offset;
     size_t size;
     unsigned int flags;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     offset = args->offset;
@@ -1103,15 +1038,15 @@ remoteDispatchDomainMemoryPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
 
     if (size > REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX) {
         virDomainFree (dom);
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("size > maximum buffer size"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("size > maximum buffer size"));
         return -1;
     }
 
     ret->buffer.buffer_len = size;
     if (VIR_ALLOC_N (ret->buffer.buffer_val, size) < 0) {
+        virReportOOMError();
         virDomainFree (dom);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
@@ -1119,7 +1054,6 @@ remoteDispatchDomainMemoryPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
                              ret->buffer.buffer_val, flags) == -1) {
         /* free (ret->buffer.buffer_val); - caller frees */
         virDomainFree (dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree (dom);
@@ -1128,25 +1062,21 @@ remoteDispatchDomainMemoryPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainAttachDevice (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
-                                  remote_domain_attach_device_args *args,
-                                  void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainAttachDevice (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                  remote_domain_attach_device_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainAttachDevice (dom, args->xml) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1154,25 +1084,21 @@ remoteDispatchDomainAttachDevice (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainAttachDeviceFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
-                                       remote_domain_attach_device_flags_args *args,
-                                       void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainAttachDeviceFlags (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                       remote_domain_attach_device_flags_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainAttachDeviceFlags (dom, args->xml, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1180,25 +1106,21 @@ remoteDispatchDomainAttachDeviceFlags (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchDomainUpdateDeviceFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
-                                       remote_domain_update_device_flags_args *args,
-                                       void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainUpdateDeviceFlags (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                       remote_domain_update_device_flags_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainUpdateDeviceFlags (dom, args->xml, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1206,25 +1128,21 @@ remoteDispatchDomainUpdateDeviceFlags (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchDomainCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
-                            remote_domain_create_args *args,
-                            void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainCreate (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                            remote_domain_create_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainCreate (dom) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1232,25 +1150,22 @@ remoteDispatchDomainCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainCreateWithFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                     struct qemud_client *client ATTRIBUTE_UNUSED,
-                                     virConnectPtr conn,
-                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                     remote_error *rerr,
+remoteDispatchDomainCreateWithFlags (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                      remote_domain_create_with_flags_args *args,
                                      remote_domain_create_with_flags_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainCreateWithFlags (dom, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1260,19 +1175,17 @@ remoteDispatchDomainCreateWithFlags (struct qemud_server *server ATTRIBUTE_UNUSE
 }
 
 static int
-remoteDispatchDomainCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
+remoteDispatchDomainCreateXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_domain_create_xml_args *args,
                                remote_domain_create_xml_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = virDomainCreateXML (conn, args->xml_desc, args->flags);
+    dom = virDomainCreateXML (priv->conn, args->xml_desc, args->flags);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1283,19 +1196,17 @@ remoteDispatchDomainCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
+remoteDispatchDomainDefineXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_domain_define_xml_args *args,
                                remote_domain_define_xml_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = virDomainDefineXML (conn, args->xml);
+    dom = virDomainDefineXML (priv->conn, args->xml);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1306,25 +1217,21 @@ remoteDispatchDomainDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             remote_domain_destroy_args *args,
-                             void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainDestroy (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                             remote_domain_destroy_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainDestroy (dom) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1332,25 +1239,21 @@ remoteDispatchDomainDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainDetachDevice (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
-                                  remote_domain_detach_device_args *args,
-                                  void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainDetachDevice (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                  remote_domain_detach_device_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainDetachDevice (dom, args->xml) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1359,25 +1262,21 @@ remoteDispatchDomainDetachDevice (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainDetachDeviceFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
-                                       remote_domain_detach_device_flags_args *args,
-                                       void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainDetachDeviceFlags (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                       remote_domain_detach_device_flags_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainDetachDeviceFlags (dom, args->xml, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1386,19 +1285,17 @@ remoteDispatchDomainDetachDeviceFlags (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchDomainDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
+remoteDispatchDomainDumpXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                              remote_domain_dump_xml_args *args,
                              remote_domain_dump_xml_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1406,7 +1303,6 @@ remoteDispatchDomainDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
     ret->xml = virDomainGetXMLDesc (dom, args->flags);
     if (!ret->xml) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1414,42 +1310,40 @@ remoteDispatchDomainDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainXmlFromNative (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchDomainXmlFromNative (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_domain_xml_from_native_args *args,
                                    remote_domain_xml_from_native_ret *ret)
 {
+    CHECK_CONN(client);
+
     /* remoteDispatchClientRequest will free this. */
-    ret->domainXml = virConnectDomainXMLFromNative (conn,
+    ret->domainXml = virConnectDomainXMLFromNative (priv->conn,
                                                     args->nativeFormat,
                                                     args->nativeConfig,
                                                     args->flags);
     if (!ret->domainXml) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     return 0;
 }
 
 static int
-remoteDispatchDomainXmlToNative (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchDomainXmlToNative (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_domain_xml_to_native_args *args,
                                  remote_domain_xml_to_native_ret *ret)
 {
+    CHECK_CONN(client);
+
     /* remoteDispatchClientRequest will free this. */
-    ret->nativeConfig = virConnectDomainXMLToNative (conn,
+    ret->nativeConfig = virConnectDomainXMLToNative (priv->conn,
                                                      args->nativeFormat,
                                                      args->domainXml,
                                                      args->flags);
     if (!ret->nativeConfig) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     return 0;
@@ -1457,25 +1351,22 @@ remoteDispatchDomainXmlToNative (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchDomainGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchDomainGetAutostart (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_domain_get_autostart_args *args,
                                   remote_domain_get_autostart_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainGetAutostart (dom, &ret->autostart) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1483,26 +1374,23 @@ remoteDispatchDomainGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
+remoteDispatchDomainGetInfo (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                              remote_domain_get_info_args *args,
                              remote_domain_get_info_ret *ret)
 {
     virDomainPtr dom;
     virDomainInfo info;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainGetInfo (dom, &info) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1518,26 +1406,23 @@ remoteDispatchDomainGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainGetMaxMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchDomainGetMaxMemory (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_domain_get_max_memory_args *args,
                                   remote_domain_get_max_memory_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     ret->memory = virDomainGetMaxMemory (dom);
     if (ret->memory == 0) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1545,26 +1430,23 @@ remoteDispatchDomainGetMaxMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainGetMaxVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchDomainGetMaxVcpus (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_domain_get_max_vcpus_args *args,
                                  remote_domain_get_max_vcpus_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     ret->num = virDomainGetMaxVcpus (dom);
     if (ret->num == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1572,34 +1454,31 @@ remoteDispatchDomainGetMaxVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainGetSecurityLabel(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                     struct qemud_client *client ATTRIBUTE_UNUSED,
-                                     virConnectPtr conn,
-                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                     remote_error *rerr,
+remoteDispatchDomainGetSecurityLabel(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                      remote_domain_get_security_label_args *args,
                                      remote_domain_get_security_label_ret *ret)
 {
     virDomainPtr dom;
     virSecurityLabel seclabel;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain(conn, args->dom);
+    dom = get_nonnull_domain(priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     memset(&seclabel, 0, sizeof seclabel);
     if (virDomainGetSecurityLabel(dom, &seclabel) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     ret->label.label_len = strlen(seclabel.label) + 1;
     if (VIR_ALLOC_N(ret->label.label_val, ret->label.label_len) < 0) {
+        virReportOOMError();
         virDomainFree(dom);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
     strcpy(ret->label.label_val, seclabel.label);
@@ -1610,32 +1489,29 @@ remoteDispatchDomainGetSecurityLabel(struct qemud_server *server ATTRIBUTE_UNUSE
 }
 
 static int
-remoteDispatchNodeGetSecurityModel(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
-                                   void *args ATTRIBUTE_UNUSED,
+remoteDispatchNodeGetSecurityModel(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_node_get_security_model_ret *ret)
 {
     virSecurityModel secmodel;
+    CHECK_CONN(client);
 
     memset(&secmodel, 0, sizeof secmodel);
-    if (virNodeGetSecurityModel(conn, &secmodel) == -1) {
-        remoteDispatchConnError(rerr, conn);
+    if (virNodeGetSecurityModel(priv->conn, &secmodel) == -1) {
         return -1;
     }
 
     ret->model.model_len = strlen(secmodel.model) + 1;
     if (VIR_ALLOC_N(ret->model.model_val, ret->model.model_len) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
     strcpy(ret->model.model_val, secmodel.model);
 
     ret->doi.doi_len = strlen(secmodel.doi) + 1;
     if (VIR_ALLOC_N(ret->doi.doi_val, ret->doi.doi_len) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
     strcpy(ret->doi.doi_val, secmodel.doi);
@@ -1644,19 +1520,17 @@ remoteDispatchNodeGetSecurityModel(struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainGetOsType (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
+remoteDispatchDomainGetOsType (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_domain_get_os_type_args *args,
                                remote_domain_get_os_type_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1664,7 +1538,6 @@ remoteDispatchDomainGetOsType (struct qemud_server *server ATTRIBUTE_UNUSED,
     ret->type = virDomainGetOSType (dom);
     if (ret->type == NULL) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1672,11 +1545,9 @@ remoteDispatchDomainGetOsType (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainGetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
+remoteDispatchDomainGetVcpus (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                               remote_domain_get_vcpus_args *args,
                               remote_domain_get_vcpus_ret *ret)
 {
@@ -1684,22 +1555,24 @@ remoteDispatchDomainGetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
     virVcpuInfoPtr info = NULL;
     unsigned char *cpumaps = NULL;
     int info_len, i;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (args->maxinfo > REMOTE_VCPUINFO_MAX) {
         virDomainFree(dom);
-        remoteDispatchFormatError (rerr, "%s", _("maxinfo > REMOTE_VCPUINFO_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxinfo > REMOTE_VCPUINFO_MAX"));
         return -1;
     }
 
     if (args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) {
         virDomainFree(dom);
-        remoteDispatchFormatError (rerr, "%s", _("maxinfo * maplen > REMOTE_CPUMAPS_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxinfo * maplen > REMOTE_CPUMAPS_MAX"));
         return -1;
     }
 
@@ -1717,7 +1590,6 @@ remoteDispatchDomainGetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
         VIR_FREE(info);
         VIR_FREE(cpumaps);
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1748,31 +1620,28 @@ oom:
     VIR_FREE(info);
     VIR_FREE(cpumaps);
     virDomainFree(dom);
-    remoteDispatchOOMError(rerr);
+    virReportOOMError();
     return -1;
 }
 
 static int
-remoteDispatchDomainGetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchDomainGetVcpusFlags (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_domain_get_vcpus_flags_args *args,
                                    remote_domain_get_vcpus_flags_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     ret->num = virDomainGetVcpusFlags (dom, args->flags);
     if (ret->num == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -1780,11 +1649,9 @@ remoteDispatchDomainGetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainMigratePrepare (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchDomainMigratePrepare (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_domain_migrate_prepare_args *args,
                                     remote_domain_migrate_prepare_ret *ret)
 {
@@ -1794,22 +1661,22 @@ remoteDispatchDomainMigratePrepare (struct qemud_server *server ATTRIBUTE_UNUSED
     char *uri_in;
     char **uri_out;
     char *dname;
+    CHECK_CONN(client);
 
     uri_in = args->uri_in == NULL ? NULL : *args->uri_in;
     dname = args->dname == NULL ? NULL : *args->dname;
 
     /* Wacky world of XDR ... */
     if (VIR_ALLOC(uri_out) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
-    r = virDomainMigratePrepare (conn, &cookie, &cookielen,
+    r = virDomainMigratePrepare (priv->conn, &cookie, &cookielen,
                                  uri_in, uri_out,
                                  args->flags, dname, args->resource);
     if (r == -1) {
         VIR_FREE(uri_out);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1829,21 +1696,18 @@ remoteDispatchDomainMigratePrepare (struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchDomainMigratePerform (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
-                                    remote_domain_migrate_perform_args *args,
-                                    void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainMigratePerform (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                    remote_domain_migrate_perform_args *args)
 {
     int r;
     virDomainPtr dom;
     char *dname;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1856,7 +1720,6 @@ remoteDispatchDomainMigratePerform (struct qemud_server *server ATTRIBUTE_UNUSED
                                  args->flags, dname, args->resource);
     virDomainFree (dom);
     if (r == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1864,24 +1727,21 @@ remoteDispatchDomainMigratePerform (struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchDomainMigrateFinish (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchDomainMigrateFinish (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_domain_migrate_finish_args *args,
                                    remote_domain_migrate_finish_ret *ret)
 {
     virDomainPtr ddom;
     CHECK_CONN (client);
 
-    ddom = virDomainMigrateFinish (conn, args->dname,
+    ddom = virDomainMigrateFinish (priv->conn, args->dname,
                                    args->cookie.cookie_val,
                                    args->cookie.cookie_len,
                                    args->uri,
                                    args->flags);
     if (ddom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1891,11 +1751,9 @@ remoteDispatchDomainMigrateFinish (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainMigratePrepare2 (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                     struct qemud_client *client ATTRIBUTE_UNUSED,
-                                     virConnectPtr conn,
-                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                     remote_error *rerr,
+remoteDispatchDomainMigratePrepare2 (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                      remote_domain_migrate_prepare2_args *args,
                                      remote_domain_migrate_prepare2_ret *ret)
 {
@@ -1912,16 +1770,15 @@ remoteDispatchDomainMigratePrepare2 (struct qemud_server *server ATTRIBUTE_UNUSE
 
     /* Wacky world of XDR ... */
     if (VIR_ALLOC(uri_out) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
-    r = virDomainMigratePrepare2 (conn, &cookie, &cookielen,
+    r = virDomainMigratePrepare2 (priv->conn, &cookie, &cookielen,
                                   uri_in, uri_out,
                                   args->flags, dname, args->resource,
                                   args->dom_xml);
     if (r == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1936,25 +1793,22 @@ remoteDispatchDomainMigratePrepare2 (struct qemud_server *server ATTRIBUTE_UNUSE
 }
 
 static int
-remoteDispatchDomainMigrateFinish2 (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchDomainMigrateFinish2 (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_domain_migrate_finish2_args *args,
                                     remote_domain_migrate_finish2_ret *ret)
 {
     virDomainPtr ddom;
     CHECK_CONN (client);
 
-    ddom = virDomainMigrateFinish2 (conn, args->dname,
+    ddom = virDomainMigrateFinish2 (priv->conn, args->dname,
                                     args->cookie.cookie_val,
                                     args->cookie.cookie_len,
                                     args->uri,
                                     args->flags,
                                     args->retcode);
     if (ddom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1964,75 +1818,75 @@ remoteDispatchDomainMigrateFinish2 (struct qemud_server *server ATTRIBUTE_UNUSED
     return 0;
 }
 
+
 static int
-remoteDispatchDomainMigratePrepareTunnel(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                         struct qemud_client *client,
-                                         virConnectPtr conn,
-                                         remote_message_header *hdr,
-                                         remote_error *rerr,
-                                         remote_domain_migrate_prepare_tunnel_args *args,
-                                         void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainMigratePrepareTunnel(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                         virNetServerClientPtr client,
+                                         virNetMessageHeaderPtr hdr,
+                                         remote_domain_migrate_prepare_tunnel_args *args)
 {
     int r;
     char *dname;
-    struct qemud_client_stream *stream;
+    daemonClientStreamPtr stream;
     CHECK_CONN (client);
+    virStreamPtr st;
 
     dname = args->dname == NULL ? NULL : *args->dname;
 
-    stream = remoteCreateClientStream(conn, hdr);
+    st = virStreamNew(priv->conn, VIR_STREAM_NONBLOCK);
+    if (!st) {
+        return -1;
+    }
+
+    stream = daemonCreateClientStream(client, st, remoteProgram, hdr);
     if (!stream) {
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
-    r = virDomainMigratePrepareTunnel(conn, stream->st,
+    r = virDomainMigratePrepareTunnel(priv->conn, st,
                                       args->flags, dname, args->resource,
                                       args->dom_xml);
     if (r == -1) {
-        remoteFreeClientStream(client, stream);
-        remoteDispatchConnError(rerr, conn);
+        daemonFreeClientStream(client, stream);
         return -1;
     }
 
-    if (remoteAddClientStream(client, stream, 0) < 0) {
-        remoteDispatchConnError(rerr, conn);
-        virStreamAbort(stream->st);
-        remoteFreeClientStream(client, stream);
+    if (daemonAddClientStream(client, stream, 0) < 0) {
+        virStreamAbort(st);
+        daemonFreeClientStream(client, stream);
         return -1;
     }
 
     return 0;
 }
 
+
 static int
-remoteDispatchListDefinedDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchListDefinedDomains (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_list_defined_domains_args *args,
                                   remote_list_defined_domains_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_DOMAIN_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxnames > REMOTE_DOMAIN_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_DOMAIN_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virConnectListDefinedDomains (conn,
+        virConnectListDefinedDomains (priv->conn,
                                       ret->names.names_val, args->maxnames);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_val);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2040,19 +1894,17 @@ remoteDispatchListDefinedDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainLookupById (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
+remoteDispatchDomainLookupById (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_domain_lookup_by_id_args *args,
                                 remote_domain_lookup_by_id_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = virDomainLookupByID (conn, args->id);
+    dom = virDomainLookupByID (priv->conn, args->id);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2062,19 +1914,17 @@ remoteDispatchDomainLookupById (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchDomainLookupByName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_domain_lookup_by_name_args *args,
                                   remote_domain_lookup_by_name_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = virDomainLookupByName (conn, args->name);
+    dom = virDomainLookupByName (priv->conn, args->name);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2084,19 +1934,17 @@ remoteDispatchDomainLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchDomainLookupByUuid (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_domain_lookup_by_uuid_args *args,
                                   remote_domain_lookup_by_uuid_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = virDomainLookupByUUID (conn, (unsigned char *) args->uuid);
+    dom = virDomainLookupByUUID (priv->conn, (unsigned char *) args->uuid);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2106,18 +1954,15 @@ remoteDispatchDomainLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNumOfDefinedDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
-                                   void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfDefinedDomains (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_num_of_defined_domains_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfDefinedDomains (conn);
+    ret->num = virConnectNumOfDefinedDomains (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2125,26 +1970,24 @@ remoteDispatchNumOfDefinedDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainPinVcpu (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             remote_domain_pin_vcpu_args *args,
-                             void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainPinVcpu (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                             remote_domain_pin_vcpu_args *args)
 {
     virDomainPtr dom;
     int rv;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (args->cpumap.cpumap_len > REMOTE_CPUMAP_MAX) {
         virDomainFree(dom);
-        remoteDispatchFormatError (rerr, "%s", _("cpumap_len > REMOTE_CPUMAP_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("cpumap_len > REMOTE_CPUMAP_MAX"));
         return -1;
     }
 
@@ -2153,7 +1996,6 @@ remoteDispatchDomainPinVcpu (struct qemud_server *server ATTRIBUTE_UNUSED,
                            args->cpumap.cpumap_len);
     if (rv == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2161,25 +2003,21 @@ remoteDispatchDomainPinVcpu (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainReboot (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
-                            remote_domain_reboot_args *args,
-                            void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainReboot (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                            remote_domain_reboot_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainReboot (dom, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2187,17 +2025,14 @@ remoteDispatchDomainReboot (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainRestore (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             remote_domain_restore_args *args,
-                             void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainRestore (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                             remote_domain_restore_args *args)
 {
+    CHECK_CONN(client);
 
-    if (virDomainRestore (conn, args->from) == -1) {
-        remoteDispatchConnError(rerr, conn);
+    if (virDomainRestore (priv->conn, args->from) == -1) {
         return -1;
     }
 
@@ -2205,25 +2040,21 @@ remoteDispatchDomainRestore (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainResume (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
-                            remote_domain_resume_args *args,
-                            void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainResume (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                            remote_domain_resume_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainResume (dom) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2231,25 +2062,21 @@ remoteDispatchDomainResume (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainSave (struct qemud_server *server ATTRIBUTE_UNUSED,
-                          struct qemud_client *client ATTRIBUTE_UNUSED,
-                          virConnectPtr conn,
-                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                          remote_error *rerr,
-                          remote_domain_save_args *args,
-                          void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSave (virNetServerPtr server ATTRIBUTE_UNUSED,
+                          virNetServerClientPtr client,
+                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                          remote_domain_save_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainSave (dom, args->to) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2257,25 +2084,21 @@ remoteDispatchDomainSave (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainCoreDump (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
-                              remote_domain_core_dump_args *args,
-                              void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainCoreDump (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              remote_domain_core_dump_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainCoreDump (dom, args->to, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2283,25 +2106,21 @@ remoteDispatchDomainCoreDump (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
-                                  remote_domain_set_autostart_args *args,
-                                  void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSetAutostart (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                  remote_domain_set_autostart_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainSetAutostart (dom, args->autostart) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2309,25 +2128,21 @@ remoteDispatchDomainSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainSetMaxMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
-                                  remote_domain_set_max_memory_args *args,
-                                  void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSetMaxMemory (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                  remote_domain_set_max_memory_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainSetMaxMemory (dom, args->memory) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2335,25 +2150,21 @@ remoteDispatchDomainSetMaxMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainSetMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
-                               remote_domain_set_memory_args *args,
-                               void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSetMemory (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                               remote_domain_set_memory_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainSetMemory (dom, args->memory) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2361,31 +2172,27 @@ remoteDispatchDomainSetMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainSetMemoryParameters(struct qemud_server *server
-                                        ATTRIBUTE_UNUSED,
-                                        struct qemud_client *client
-                                        ATTRIBUTE_UNUSED,
-                                        virConnectPtr conn,
-                                        remote_message_header *
-                                        hdr ATTRIBUTE_UNUSED,
-                                        remote_error * rerr,
-                                        remote_domain_set_memory_parameters_args
-                                        * args, void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSetMemoryParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                        virNetServerClientPtr client,
+                                        virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                        remote_domain_set_memory_parameters_args *args)
 {
     virDomainPtr dom;
     int i, r, nparams;
     virMemoryParameterPtr params;
     unsigned int flags;
+    CHECK_CONN(client);
 
     nparams = args->params.params_len;
     flags = args->flags;
 
     if (nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) {
-        remoteDispatchFormatError(rerr, "%s", _("nparams too large"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("nparams too large"));
         return -1;
     }
     if (VIR_ALLOC_N(params, nparams) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
@@ -2393,10 +2200,9 @@ remoteDispatchDomainSetMemoryParameters(struct qemud_server *server
     for (i = 0; i < nparams; ++i) {
         if (virStrcpyStatic
             (params[i].field, args->params.params_val[i].field) == NULL) {
-            remoteDispatchFormatError(rerr,
-                                      _
-                                      ("Field %s too big for destination"),
-                                      args->params.params_val[i].field);
+            virNetError(VIR_ERR_RPC,
+                        _("Field %s too big for destination"),
+                        args->params.params_val[i].field);
             return -1;
         }
         params[i].type = args->params.params_val[i].value.type;
@@ -2434,10 +2240,9 @@ remoteDispatchDomainSetMemoryParameters(struct qemud_server *server
         }
     }
 
-    dom = get_nonnull_domain(conn, args->dom);
+    dom = get_nonnull_domain(priv->conn, args->dom);
     if (dom == NULL) {
         VIR_FREE(params);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2445,7 +2250,6 @@ remoteDispatchDomainSetMemoryParameters(struct qemud_server *server
     virDomainFree(dom);
     VIR_FREE(params);
     if (r == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2453,40 +2257,34 @@ remoteDispatchDomainSetMemoryParameters(struct qemud_server *server
 }
 
 static int
-remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
-                                        ATTRIBUTE_UNUSED,
-                                        struct qemud_client *client
-                                        ATTRIBUTE_UNUSED,
-                                        virConnectPtr conn,
-                                        remote_message_header *
-                                        hdr ATTRIBUTE_UNUSED,
-                                        remote_error * rerr,
-                                        remote_domain_get_memory_parameters_args
-                                        * args,
-                                        remote_domain_get_memory_parameters_ret
-                                        * ret)
+remoteDispatchDomainGetMemoryParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                        virNetServerClientPtr client,
+                                        virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                        remote_domain_get_memory_parameters_args *args,
+                                        remote_domain_get_memory_parameters_ret *ret)
 {
     virDomainPtr dom;
     virMemoryParameterPtr params;
     int i, r, nparams;
     unsigned int flags;
+    CHECK_CONN(client);
 
     nparams = args->nparams;
     flags = args->flags;
 
     if (nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) {
-        remoteDispatchFormatError(rerr, "%s", _("nparams too large"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("nparams too large"));
         return -1;
     }
     if (VIR_ALLOC_N(params, nparams) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
-    dom = get_nonnull_domain(conn, args->dom);
+    dom = get_nonnull_domain(priv->conn, args->dom);
     if (dom == NULL) {
         VIR_FREE(params);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2494,7 +2292,6 @@ remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
     if (r == -1) {
         virDomainFree(dom);
         VIR_FREE(params);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     /* In this case, we need to send back the number of parameters
@@ -2549,7 +2346,7 @@ remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
                     params[i].value.b;
                 break;
             default:
-                remoteDispatchFormatError(rerr, "%s", _("unknown type"));
+                virNetError(VIR_ERR_RPC, "%s", _("unknown type"));
                 goto cleanup;
         }
     }
@@ -2561,7 +2358,7 @@ remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
     return 0;
 
   oom:
-    remoteDispatchOOMError(rerr);
+    virReportOOMError();
   cleanup:
     virDomainFree(dom);
     for (i = 0; i < nparams; i++)
@@ -2571,25 +2368,21 @@ remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
 }
 
 static int
-remoteDispatchDomainSetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
-                              remote_domain_set_vcpus_args *args,
-                              void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSetVcpus (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              remote_domain_set_vcpus_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainSetVcpus (dom, args->nvcpus) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2597,25 +2390,21 @@ remoteDispatchDomainSetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainSetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
-                                   remote_domain_set_vcpus_flags_args *args,
-                                   void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSetVcpusFlags (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                   remote_domain_set_vcpus_flags_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainSetVcpusFlags (dom, args->nvcpus, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2623,25 +2412,21 @@ remoteDispatchDomainSetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainShutdown (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
-                              remote_domain_shutdown_args *args,
-                              void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainShutdown (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              remote_domain_shutdown_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainShutdown (dom) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2649,25 +2434,21 @@ remoteDispatchDomainShutdown (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainSuspend (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             remote_domain_suspend_args *args,
-                             void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSuspend (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                             remote_domain_suspend_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainSuspend (dom) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2675,25 +2456,21 @@ remoteDispatchDomainSuspend (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
-                              remote_domain_undefine_args *args,
-                              void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainUndefine (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              remote_domain_undefine_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainUndefine (dom) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2701,33 +2478,31 @@ remoteDispatchDomainUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchListDefinedNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchListDefinedNetworks (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_list_defined_networks_args *args,
                                    remote_list_defined_networks_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virConnectListDefinedNetworks (conn,
+        virConnectListDefinedNetworks (priv->conn,
                                        ret->names.names_val, args->maxnames);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_val);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2735,32 +2510,30 @@ remoteDispatchListDefinedNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchListDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
-                           struct qemud_client *client ATTRIBUTE_UNUSED,
-                           virConnectPtr conn,
-                           remote_message_header *hdr ATTRIBUTE_UNUSED,
-                           remote_error *rerr,
+remoteDispatchListDomains (virNetServerPtr server ATTRIBUTE_UNUSED,
+                           virNetServerClientPtr client,
+                           virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                            remote_list_domains_args *args,
                            remote_list_domains_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxids > REMOTE_DOMAIN_ID_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxids > REMOTE_DOMAIN_ID_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxids > REMOTE_DOMAIN_ID_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->ids.ids_val, args->maxids) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
-    ret->ids.ids_len = virConnectListDomains (conn,
+    ret->ids.ids_len = virConnectListDomains (priv->conn,
                                               ret->ids.ids_val, args->maxids);
     if (ret->ids.ids_len == -1) {
         VIR_FREE(ret->ids.ids_val);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2768,25 +2541,21 @@ remoteDispatchListDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainManagedSave (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
-                                 remote_domain_managed_save_args *args,
-                                 void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainManagedSave (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                 remote_domain_managed_save_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainManagedSave (dom, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2794,26 +2563,23 @@ remoteDispatchDomainManagedSave (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainHasManagedSaveImage (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                         struct qemud_client *client ATTRIBUTE_UNUSED,
-                                         virConnectPtr conn,
-                                         remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                         remote_error *rerr,
+remoteDispatchDomainHasManagedSaveImage (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                         virNetServerClientPtr client,
+                                         virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                          remote_domain_has_managed_save_image_args *args,
                                          remote_domain_has_managed_save_image_ret *ret)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     ret->ret = virDomainHasManagedSaveImage (dom, args->flags);
     if (ret->ret == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2821,25 +2587,21 @@ remoteDispatchDomainHasManagedSaveImage (struct qemud_server *server ATTRIBUTE_U
 }
 
 static int
-remoteDispatchDomainManagedSaveRemove (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
-                                       remote_domain_managed_save_remove_args *args,
-                                       void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainManagedSaveRemove (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                       remote_domain_managed_save_remove_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainManagedSaveRemove (dom, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virDomainFree(dom);
@@ -2847,33 +2609,31 @@ remoteDispatchDomainManagedSaveRemove (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchListNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
+remoteDispatchListNetworks (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                             remote_list_networks_args *args,
                             remote_list_networks_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virConnectListNetworks (conn,
+        virConnectListNetworks (priv->conn,
                                 ret->names.names_val, args->maxnames);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_len);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2881,25 +2641,21 @@ remoteDispatchListNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             remote_network_create_args *args,
-                             void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNetworkCreate (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                             remote_network_create_args *args)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = get_nonnull_network (conn, args->net);
+    net = get_nonnull_network (priv->conn, args->net);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNetworkCreate (net) == -1) {
         virNetworkFree(net);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNetworkFree(net);
@@ -2907,19 +2663,17 @@ remoteDispatchNetworkCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
+remoteDispatchNetworkCreateXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_network_create_xml_args *args,
                                 remote_network_create_xml_ret *ret)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = virNetworkCreateXML (conn, args->xml);
+    net = virNetworkCreateXML (priv->conn, args->xml);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2929,19 +2683,17 @@ remoteDispatchNetworkCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
+remoteDispatchNetworkDefineXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_network_define_xml_args *args,
                                 remote_network_define_xml_ret *ret)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = virNetworkDefineXML (conn, args->xml);
+    net = virNetworkDefineXML (priv->conn, args->xml);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2951,25 +2703,21 @@ remoteDispatchNetworkDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
-                              remote_network_destroy_args *args,
-                              void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNetworkDestroy (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              remote_network_destroy_args *args)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = get_nonnull_network (conn, args->net);
+    net = get_nonnull_network (priv->conn, args->net);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNetworkDestroy (net) == -1) {
         virNetworkFree(net);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNetworkFree(net);
@@ -2977,19 +2725,17 @@ remoteDispatchNetworkDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
+remoteDispatchNetworkDumpXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                               remote_network_dump_xml_args *args,
                               remote_network_dump_xml_ret *ret)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = get_nonnull_network (conn, args->net);
+    net = get_nonnull_network (priv->conn, args->net);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -2997,7 +2743,6 @@ remoteDispatchNetworkDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
     ret->xml = virNetworkGetXMLDesc (net, args->flags);
     if (!ret->xml) {
         virNetworkFree(net);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNetworkFree(net);
@@ -3005,25 +2750,22 @@ remoteDispatchNetworkDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchNetworkGetAutostart (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_network_get_autostart_args *args,
                                    remote_network_get_autostart_ret *ret)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = get_nonnull_network (conn, args->net);
+    net = get_nonnull_network (priv->conn, args->net);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNetworkGetAutostart (net, &ret->autostart) == -1) {
         virNetworkFree(net);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNetworkFree(net);
@@ -3031,19 +2773,17 @@ remoteDispatchNetworkGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkGetBridgeName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchNetworkGetBridgeName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_network_get_bridge_name_args *args,
                                     remote_network_get_bridge_name_ret *ret)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = get_nonnull_network (conn, args->net);
+    net = get_nonnull_network (priv->conn, args->net);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3051,7 +2791,6 @@ remoteDispatchNetworkGetBridgeName (struct qemud_server *server ATTRIBUTE_UNUSED
     ret->name = virNetworkGetBridgeName (net);
     if (!ret->name) {
         virNetworkFree(net);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNetworkFree(net);
@@ -3059,19 +2798,17 @@ remoteDispatchNetworkGetBridgeName (struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchNetworkLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchNetworkLookupByName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_network_lookup_by_name_args *args,
                                    remote_network_lookup_by_name_ret *ret)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = virNetworkLookupByName (conn, args->name);
+    net = virNetworkLookupByName (priv->conn, args->name);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3081,19 +2818,17 @@ remoteDispatchNetworkLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchNetworkLookupByUuid (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_network_lookup_by_uuid_args *args,
                                    remote_network_lookup_by_uuid_ret *ret)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = virNetworkLookupByUUID (conn, (unsigned char *) args->uuid);
+    net = virNetworkLookupByUUID (priv->conn, (unsigned char *) args->uuid);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3103,25 +2838,21 @@ remoteDispatchNetworkLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
-                                   remote_network_set_autostart_args *args,
-                                   void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNetworkSetAutostart (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                   remote_network_set_autostart_args *args)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = get_nonnull_network (conn, args->net);
+    net = get_nonnull_network (priv->conn, args->net);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNetworkSetAutostart (net, args->autostart) == -1) {
         virNetworkFree(net);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNetworkFree(net);
@@ -3129,25 +2860,21 @@ remoteDispatchNetworkSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNetworkUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
-                               remote_network_undefine_args *args,
-                               void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNetworkUndefine (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                               remote_network_undefine_args *args)
 {
     virNetworkPtr net;
+    CHECK_CONN(client);
 
-    net = get_nonnull_network (conn, args->net);
+    net = get_nonnull_network (priv->conn, args->net);
     if (net == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNetworkUndefine (net) == -1) {
         virNetworkFree(net);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNetworkFree(net);
@@ -3155,18 +2882,15 @@ remoteDispatchNetworkUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNumOfDefinedNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
-                                    void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfDefinedNetworks (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_num_of_defined_networks_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfDefinedNetworks (conn);
+    ret->num = virConnectNumOfDefinedNetworks (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3174,18 +2898,15 @@ remoteDispatchNumOfDefinedNetworks (struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchNumOfDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
-                            void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfDomains (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                             remote_num_of_domains_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfDomains (conn);
+    ret->num = virConnectNumOfDomains (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3193,18 +2914,15 @@ remoteDispatchNumOfDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNumOfNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfNetworks (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                              remote_num_of_networks_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfNetworks (conn);
+    ret->num = virConnectNumOfNetworks (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3214,18 +2932,15 @@ remoteDispatchNumOfNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 /*-------------------------------------------------------------*/
 static int
-remoteDispatchNumOfInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
-                               void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfInterfaces (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_num_of_interfaces_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfInterfaces (conn);
+    ret->num = virConnectNumOfInterfaces (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3233,33 +2948,31 @@ remoteDispatchNumOfInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchListInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
+remoteDispatchListInterfaces (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                               remote_list_interfaces_args *args,
                               remote_list_interfaces_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_INTERFACE_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxnames > REMOTE_INTERFACE_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_INTERFACE_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virConnectListInterfaces (conn,
+        virConnectListInterfaces (priv->conn,
                                   ret->names.names_val, args->maxnames);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_len);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3267,18 +2980,15 @@ remoteDispatchListInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNumOfDefinedInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
-                                      void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfDefinedInterfaces (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_num_of_defined_interfaces_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfDefinedInterfaces (conn);
+    ret->num = virConnectNumOfDefinedInterfaces (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3286,33 +2996,31 @@ remoteDispatchNumOfDefinedInterfaces (struct qemud_server *server ATTRIBUTE_UNUS
 }
 
 static int
-remoteDispatchListDefinedInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                     struct qemud_client *client ATTRIBUTE_UNUSED,
-                                     virConnectPtr conn,
-                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                     remote_error *rerr,
+remoteDispatchListDefinedInterfaces (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                      remote_list_defined_interfaces_args *args,
                                      remote_list_defined_interfaces_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxnames > REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virConnectListDefinedInterfaces (conn,
+        virConnectListDefinedInterfaces (priv->conn,
                                          ret->names.names_val, args->maxnames);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_len);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3320,19 +3028,17 @@ remoteDispatchListDefinedInterfaces (struct qemud_server *server ATTRIBUTE_UNUSE
 }
 
 static int
-remoteDispatchInterfaceLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                     struct qemud_client *client ATTRIBUTE_UNUSED,
-                                     virConnectPtr conn,
-                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                     remote_error *rerr,
+remoteDispatchInterfaceLookupByName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                      remote_interface_lookup_by_name_args *args,
                                      remote_interface_lookup_by_name_ret *ret)
 {
     virInterfacePtr iface;
+    CHECK_CONN(client);
 
-    iface = virInterfaceLookupByName (conn, args->name);
+    iface = virInterfaceLookupByName (priv->conn, args->name);
     if (iface == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3342,19 +3048,17 @@ remoteDispatchInterfaceLookupByName (struct qemud_server *server ATTRIBUTE_UNUSE
 }
 
 static int
-remoteDispatchInterfaceLookupByMacString (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                          struct qemud_client *client ATTRIBUTE_UNUSED,
-                                          virConnectPtr conn,
-                                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                          remote_error *rerr,
+remoteDispatchInterfaceLookupByMacString (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                          virNetServerClientPtr client,
+                                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                           remote_interface_lookup_by_mac_string_args *args,
                                           remote_interface_lookup_by_mac_string_ret *ret)
 {
     virInterfacePtr iface;
+    CHECK_CONN(client);
 
-    iface = virInterfaceLookupByMACString (conn, args->mac);
+    iface = virInterfaceLookupByMACString (priv->conn, args->mac);
     if (iface == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3364,19 +3068,17 @@ remoteDispatchInterfaceLookupByMacString (struct qemud_server *server ATTRIBUTE_
 }
 
 static int
-remoteDispatchInterfaceGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchInterfaceGetXmlDesc (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_interface_get_xml_desc_args *args,
                                    remote_interface_get_xml_desc_ret *ret)
 {
     virInterfacePtr iface;
+    CHECK_CONN(client);
 
-    iface = get_nonnull_interface (conn, args->iface);
+    iface = get_nonnull_interface (priv->conn, args->iface);
     if (iface == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3384,7 +3086,6 @@ remoteDispatchInterfaceGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
     ret->xml = virInterfaceGetXMLDesc (iface, args->flags);
     if (!ret->xml) {
         virInterfaceFree(iface);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virInterfaceFree(iface);
@@ -3392,19 +3093,17 @@ remoteDispatchInterfaceGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchInterfaceDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchInterfaceDefineXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_interface_define_xml_args *args,
                                   remote_interface_define_xml_ret *ret)
 {
     virInterfacePtr iface;
+    CHECK_CONN(client);
 
-    iface = virInterfaceDefineXML (conn, args->xml, args->flags);
+    iface = virInterfaceDefineXML (priv->conn, args->xml, args->flags);
     if (iface == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -3414,25 +3113,21 @@ remoteDispatchInterfaceDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchInterfaceUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
-                                 remote_interface_undefine_args *args,
-                                 void *ret ATTRIBUTE_UNUSED)
+remoteDispatchInterfaceUndefine (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                 remote_interface_undefine_args *args)
 {
     virInterfacePtr iface;
+    CHECK_CONN(client);
 
-    iface = get_nonnull_interface (conn, args->iface);
+    iface = get_nonnull_interface (priv->conn, args->iface);
     if (iface == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virInterfaceUndefine (iface) == -1) {
         virInterfaceFree(iface);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virInterfaceFree(iface);
@@ -3440,25 +3135,21 @@ remoteDispatchInterfaceUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchInterfaceCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
-                               remote_interface_create_args *args,
-                               void *ret ATTRIBUTE_UNUSED)
+remoteDispatchInterfaceCreate (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                               remote_interface_create_args *args)
 {
     virInterfacePtr iface;
+    CHECK_CONN(client);
 
-    iface = get_nonnull_interface (conn, args->iface);
+    iface = get_nonnull_interface (priv->conn, args->iface);
     if (iface == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virInterfaceCreate (iface, args->flags) == -1) {
         virInterfaceFree(iface);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virInterfaceFree(iface);
@@ -3466,25 +3157,21 @@ remoteDispatchInterfaceCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchInterfaceDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
-                                remote_interface_destroy_args *args,
-                                void *ret ATTRIBUTE_UNUSED)
+remoteDispatchInterfaceDestroy (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                remote_interface_destroy_args *args)
 {
     virInterfacePtr iface;
+    CHECK_CONN(client);
 
-    iface = get_nonnull_interface (conn, args->iface);
+    iface = get_nonnull_interface (priv->conn, args->iface);
     if (iface == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virInterfaceDestroy (iface, args->flags) == -1) {
         virInterfaceFree(iface);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virInterfaceFree(iface);
@@ -3494,30 +3181,37 @@ remoteDispatchInterfaceDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
 /*-------------------------------------------------------------*/
 
 static int
-remoteDispatchAuthList (struct qemud_server *server,
-                        struct qemud_client *client,
-                        virConnectPtr conn ATTRIBUTE_UNUSED,
-                        remote_message_header *hdr ATTRIBUTE_UNUSED,
-                        remote_error *rerr,
-                        void *args ATTRIBUTE_UNUSED,
+remoteDispatchAuthList (virNetServerPtr server ATTRIBUTE_UNUSED,
+                        virNetServerClientPtr client,
+                        virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                         remote_auth_list_ret *ret)
 {
+    int auth = virNetServerClientGetAuth(client);
+
     ret->types.types_len = 1;
     if (VIR_ALLOC_N(ret->types.types_val, ret->types.types_len) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
-    ret->types.types_val[0] = client->auth;
-    virMutexUnlock(&client->lock);
+
+    switch (auth) {
+    case VIR_NET_SERVER_SERVICE_AUTH_NONE:
+        ret->types.types_val[0] = REMOTE_AUTH_NONE;
+        break;
+    case VIR_NET_SERVER_SERVICE_AUTH_POLKIT:
+        ret->types.types_val[0] = REMOTE_AUTH_POLKIT;
+        break;
+    case VIR_NET_SERVER_SERVICE_AUTH_SASL:
+        ret->types.types_val[0] = REMOTE_AUTH_SASL;
+        break;
+    default:
+        ret->types.types_val[0] = REMOTE_AUTH_NONE;
+    }
 
     return 0;
 }
 
 
-#if HAVE_SASL
 /*
  * Initializes the SASL session in prepare for authentication
  * and gives the client a list of allowed mechanisms to choose
@@ -3525,324 +3219,166 @@ remoteDispatchAuthList (struct qemud_server *server,
  * XXX callbacks for stuff like password verification ?
  */
 static int
-remoteDispatchAuthSaslInit (struct qemud_server *server,
-                            struct qemud_client *client,
-                            virConnectPtr conn,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
-                            void *args ATTRIBUTE_UNUSED,
+remoteDispatchAuthSaslInit (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                             remote_auth_sasl_init_ret *ret)
 {
-    const char *mechlist = NULL;
-    sasl_security_properties_t secprops;
-    int err;
-    virSocketAddr sa;
-    char *localAddr, *remoteAddr;
+    virNetSASLSessionPtr sasl = NULL;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
 
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
+    virMutexLock(&priv->lock);
 
-    REMOTE_DEBUG("Initialize SASL auth %d", client->fd);
-    if (client->auth != REMOTE_AUTH_SASL ||
-        client->saslconn != NULL) {
+    REMOTE_DEBUG("Initialize SASL auth %d", virNetServerClientGetFD(client));
+    if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_SASL ||
+        priv->sasl != NULL) {
         VIR_ERROR0(_("client tried invalid SASL init request"));
         goto authfail;
     }
 
-    /* Get local address in form  IPADDR:PORT */
-    sa.len = sizeof(sa.data.stor);
-    if (getsockname(client->fd, &sa.data.sa, &sa.len) < 0) {
-        char ebuf[1024];
-        remoteDispatchFormatError(rerr,
-                                  _("failed to get sock address: %s"),
-                                  virStrerror(errno, ebuf, sizeof ebuf));
-        goto error;
-    }
-    if ((localAddr = virSocketFormatAddrFull(&sa, true, ";")) == NULL) {
-        remoteDispatchConnError(rerr, conn);
-        goto error;
-    }
-
-    /* Get remote address in form  IPADDR:PORT */
-    sa.len = sizeof(sa.data.stor);
-    if (getpeername(client->fd, &sa.data.sa, &sa.len) < 0) {
-        char ebuf[1024];
-        remoteDispatchFormatError(rerr, _("failed to get peer address: %s"),
-                                  virStrerror(errno, ebuf, sizeof ebuf));
-        VIR_FREE(localAddr);
-        goto error;
-    }
-    if ((remoteAddr = virSocketFormatAddrFull(&sa, true, ";")) == NULL) {
-        VIR_FREE(localAddr);
-        remoteDispatchConnError(rerr, conn);
-        goto error;
-    }
-
-    err = sasl_server_new("libvirt",
-                          NULL, /* FQDN - just delegates to gethostname */
-                          NULL, /* User realm */
-                          localAddr,
-                          remoteAddr,
-                          NULL, /* XXX Callbacks */
-                          SASL_SUCCESS_DATA,
-                          &client->saslconn);
-    VIR_FREE(localAddr);
-    VIR_FREE(remoteAddr);
-    if (err != SASL_OK) {
-        VIR_ERROR(_("sasl context setup failed %d (%s)"),
-                  err, sasl_errstring(err, NULL, NULL));
-        client->saslconn = NULL;
+    sasl = virNetSASLSessionNewServer(saslCtxt,
+                                      "libvirt",
+                                      virNetServerClientLocalAddrString(client),
+                                      virNetServerClientRemoteAddrString(client));
+    if (!sasl)
         goto authfail;
-    }
 
     /* Inform SASL that we've got an external SSF layer from TLS */
-    if (client->type == QEMUD_SOCK_TYPE_TLS) {
-        gnutls_cipher_algorithm_t cipher;
-        sasl_ssf_t ssf;
-
-        cipher = gnutls_cipher_get(client->tlssession);
-        if (!(ssf = (sasl_ssf_t)gnutls_cipher_get_key_size(cipher))) {
-            VIR_ERROR0(_("cannot get TLS cipher size"));
-            sasl_dispose(&client->saslconn);
-            client->saslconn = NULL;
+    if (virNetServerClientHasTLSSession(client)) {
+        int ssf;
+
+        if ((ssf = virNetServerClientGetTLSKeySize(client)) < 0)
             goto authfail;
-        }
-        ssf *= 8; /* tls key size is bytes, sasl wants bits */
-
-        err = sasl_setprop(client->saslconn, SASL_SSF_EXTERNAL, &ssf);
-        if (err != SASL_OK) {
-            VIR_ERROR(_("cannot set SASL external SSF %d (%s)"),
-                      err, sasl_errstring(err, NULL, NULL));
-            sasl_dispose(&client->saslconn);
-            client->saslconn = NULL;
+
+        ssf *= 8; /* key size is bytes, sasl wants bits */
+
+        DEBUG("Setting external SSF %d", ssf);
+        if (virNetSASLSessionExtKeySize(sasl, ssf) < 0)
             goto authfail;
-        }
     }
 
-    memset (&secprops, 0, sizeof secprops);
-    if (client->type == QEMUD_SOCK_TYPE_TLS ||
-        client->type == QEMUD_SOCK_TYPE_UNIX) {
+    if (virNetServerClientIsSecure(client))
         /* If we've got TLS or UNIX domain sock, we don't care about SSF */
-        secprops.min_ssf = 0;
-        secprops.max_ssf = 0;
-        secprops.maxbufsize = 8192;
-        secprops.security_flags = 0;
-    } else {
+        virNetSASLSessionSecProps(sasl, 0, 0, true);
+    else
         /* Plain TCP, better get an SSF layer */
-        secprops.min_ssf = 56; /* Good enough to require kerberos */
-        secprops.max_ssf = 100000; /* Arbitrary big number */
-        secprops.maxbufsize = 8192;
-        /* Forbid any anonymous or trivially crackable auth */
-        secprops.security_flags =
-            SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT;
-    }
-
-    err = sasl_setprop(client->saslconn, SASL_SEC_PROPS, &secprops);
-    if (err != SASL_OK) {
-        VIR_ERROR(_("cannot set SASL security props %d (%s)"),
-                  err, sasl_errstring(err, NULL, NULL));
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
-        goto authfail;
-    }
+        virNetSASLSessionSecProps(sasl,
+                                  56,  /* Good enough to require kerberos */
+                                  100000,  /* Arbitrary big number */
+                                  false); /* No anonymous */
 
-    err = sasl_listmech(client->saslconn,
-                        NULL, /* Don't need to set user */
-                        "", /* Prefix */
-                        ",", /* Separator */
-                        "", /* Suffix */
-                        &mechlist,
-                        NULL,
-                        NULL);
-    if (err != SASL_OK) {
-        VIR_ERROR(_("cannot list SASL mechanisms %d (%s)"),
-                  err, sasl_errdetail(client->saslconn));
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
+    if (!(ret->mechlist = virNetSASLSessionListMechanisms(sasl)))
         goto authfail;
-    }
-    REMOTE_DEBUG("Available mechanisms for client: '%s'", mechlist);
-    ret->mechlist = strdup(mechlist);
-    if (!ret->mechlist) {
-        VIR_ERROR0(_("cannot allocate mechlist"));
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
-        goto authfail;
-    }
+    REMOTE_DEBUG("Available mechanisms for client: '%s'", ret->mechlist);
 
-    virMutexUnlock(&client->lock);
+    priv->sasl = sasl;
+    virMutexUnlock(&priv->lock);
     return 0;
 
 authfail:
-    remoteDispatchAuthError(rerr);
-error:
-    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
-    virMutexUnlock(&client->lock);
+    virResetLastError();
+    virNetError(VIR_ERR_AUTH_FAILED, "%s",
+                _("authentication failed"));
+    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
+          virNetServerClientGetFD(client), REMOTE_AUTH_SASL);
+    virNetSASLSessionFree(sasl);
+    virMutexUnlock(&priv->lock);
     return -1;
 }
 
-
-/* We asked for an SSF layer, so sanity check that we actually
- * got what we asked for
+/*
  * Returns 0 if ok, -1 on error, -2 if rejected
  */
 static int
-remoteSASLCheckSSF (struct qemud_client *client,
-                    remote_error *rerr) {
-    const void *val;
-    int err, ssf;
-
-    if (client->type == QEMUD_SOCK_TYPE_TLS ||
-        client->type == QEMUD_SOCK_TYPE_UNIX)
-        return 0; /* TLS or UNIX domain sockets trivially OK */
-
-    err = sasl_getprop(client->saslconn, SASL_SSF, &val);
-    if (err != SASL_OK) {
-        VIR_ERROR(_("cannot query SASL ssf on connection %d (%s)"),
-                  err, sasl_errstring(err, NULL, NULL));
-        remoteDispatchAuthError(rerr);
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
-        return -1;
-    }
-    ssf = *(const int *)val;
-    REMOTE_DEBUG("negotiated an SSF of %d", ssf);
-    if (ssf < 56) { /* 56 is good for Kerberos */
-        VIR_ERROR(_("negotiated SSF %d was not strong enough"), ssf);
-        remoteDispatchAuthError(rerr);
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
-        return -2;
-    }
+remoteSASLFinish(virNetServerClientPtr client)
+{
+    const char *identity;
+    struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
+    int ssf;
 
-    /* Only setup for read initially, because we're about to send an RPC
-     * reply which must be in plain text. When the next incoming RPC
-     * arrives, we'll switch on writes too
-     *
-     * cf qemudClientReadSASL  in qemud.c
-     */
-    client->saslSSF = QEMUD_SASL_SSF_READ;
+    /* TLS or UNIX domain sockets trivially OK */
+    if (!virNetServerClientIsSecure(client)) {
+        if ((ssf = virNetSASLSessionGetKeySize(priv->sasl)) < 0)
+            return -1;
 
-    /* We have a SSF !*/
-    return 0;
-}
+        REMOTE_DEBUG("negotiated an SSF of %d", ssf);
+        if (ssf < 56) { /* 56 is good for Kerberos */
+            VIR_ERROR(_("negotiated SSF %d was not strong enough"), ssf);
+            return -2;
+        }
+    }
 
-/*
- * Returns 0 if ok, -1 on error, -2 if rejected
- */
-static int
-remoteSASLCheckAccess (struct qemud_server *server,
-                       struct qemud_client *client,
-                       remote_error *rerr) {
-    const void *val;
-    int err;
-    char **wildcards;
+    if (!(identity = virNetSASLSessionGetIdentity(priv->sasl)))
+        return -2;
 
-    err = sasl_getprop(client->saslconn, SASL_USERNAME, &val);
-    if (err != SASL_OK) {
-        VIR_ERROR(_("cannot query SASL username on connection %d (%s)"),
-                  err, sasl_errstring(err, NULL, NULL));
-        remoteDispatchAuthError(rerr);
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
-        return -1;
-    }
-    if (val == NULL) {
-        VIR_ERROR0(_("no client username was found"));
-        remoteDispatchAuthError(rerr);
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
-        return -1;
-    }
-    REMOTE_DEBUG("SASL client username %s", (const char *)val);
+    if (!virNetSASLContextCheckIdentity(saslCtxt, identity))
+        return -2;
 
-    client->saslUsername = strdup((const char*)val);
-    if (client->saslUsername == NULL) {
-        VIR_ERROR0(_("out of memory copying username"));
-        remoteDispatchAuthError(rerr);
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
+    if (virNetServerClientSetIdentity(client, identity) < 0)
         return -1;
-    }
 
-    /* If the list is not set, allow any DN. */
-    wildcards = server->saslUsernameWhitelist;
-    if (!wildcards)
-        return 0; /* No ACL, allow all */
 
-    while (*wildcards) {
-        if (fnmatch (*wildcards, client->saslUsername, 0) == 0)
-            return 0; /* Allowed */
-        wildcards++;
-    }
+    virNetServerClientSetSASLSession(client, priv->sasl);
 
-    /* Denied */
-    VIR_ERROR(_("SASL client %s not allowed in whitelist"), client->saslUsername);
-    remoteDispatchAuthError(rerr);
-    sasl_dispose(&client->saslconn);
-    client->saslconn = NULL;
-    return -2;
-}
+    REMOTE_DEBUG("Authentication successful %d", virNetServerClientGetFD(client));
+    PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
+          virNetServerClientGetFD(client), REMOTE_AUTH_SASL,
+          virNetSASLSessionGetIdentity(priv->sasl));
 
+    virNetSASLSessionFree(priv->sasl);
+    priv->sasl = NULL;
+
+    return 0;
+}
 
 /*
  * This starts the SASL authentication negotiation.
  */
 static int
-remoteDispatchAuthSaslStart (struct qemud_server *server,
-                             struct qemud_client *client,
-                             virConnectPtr conn ATTRIBUTE_UNUSED,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
+remoteDispatchAuthSaslStart (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                              remote_auth_sasl_start_args *args,
                              remote_auth_sasl_start_ret *ret)
 {
     const char *serverout;
-    unsigned int serveroutlen;
+    size_t serveroutlen;
     int err;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
 
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
+    virMutexLock(&priv->lock);
 
-    REMOTE_DEBUG("Start SASL auth %d", client->fd);
-    if (client->auth != REMOTE_AUTH_SASL ||
-        client->saslconn == NULL) {
+    REMOTE_DEBUG("Start SASL auth %d", virNetServerClientGetFD(client));
+    if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_SASL ||
+        priv->sasl == NULL) {
         VIR_ERROR0(_("client tried invalid SASL start request"));
         goto authfail;
     }
 
     REMOTE_DEBUG("Using SASL mechanism %s. Data %d bytes, nil: %d",
                  args->mech, args->data.data_len, args->nil);
-    err = sasl_server_start(client->saslconn,
-                            args->mech,
-                            /* NB, distinction of NULL vs "" is *critical* in SASL */
-                            args->nil ? NULL : args->data.data_val,
-                            args->data.data_len,
-                            &serverout,
-                            &serveroutlen);
-    if (err != SASL_OK &&
-        err != SASL_CONTINUE) {
-        VIR_ERROR(_("sasl start failed %d (%s)"),
-                  err, sasl_errdetail(client->saslconn));
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
+    err = virNetSASLSessionServerStart(priv->sasl,
+                                       args->mech,
+                                       /* NB, distinction of NULL vs "" is *critical* in SASL */
+                                       args->nil ? NULL : args->data.data_val,
+                                       args->data.data_len,
+                                       &serverout,
+                                       &serveroutlen);
+    if (err != VIR_NET_SASL_COMPLETE &&
+        err != VIR_NET_SASL_CONTINUE)
         goto authfail;
-    }
+
     if (serveroutlen > REMOTE_AUTH_SASL_DATA_MAX) {
-        VIR_ERROR(_("sasl start reply data too long %d"), serveroutlen);
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
+        VIR_ERROR(_("sasl start reply data too long %d"), (int)serveroutlen);
         goto authfail;
     }
 
     /* NB, distinction of NULL vs "" is *critical* in SASL */
     if (serverout) {
-        if (VIR_ALLOC_N(ret->data.data_val, serveroutlen) < 0) {
-            remoteDispatchOOMError(rerr);
-            goto error;
-        }
+        if (VIR_ALLOC_N(ret->data.data_val, serveroutlen) < 0)
+            goto authfail;
         memcpy(ret->data.data_val, serverout, serveroutlen);
     } else {
         ret->data.data_val = NULL;
@@ -3851,99 +3387,90 @@ remoteDispatchAuthSaslStart (struct qemud_server *server,
     ret->data.data_len = serveroutlen;
 
     REMOTE_DEBUG("SASL return data %d bytes, nil; %d", ret->data.data_len, ret->nil);
-    if (err == SASL_CONTINUE) {
+    if (err == VIR_NET_SASL_CONTINUE) {
         ret->complete = 0;
     } else {
         /* Check username whitelist ACL */
-        if ((err = remoteSASLCheckAccess(server, client, rerr)) < 0 ||
-            (err = remoteSASLCheckSSF(client, rerr)) < 0) {
+        if ((err = remoteSASLFinish(client)) < 0) {
             if (err == -2)
                 goto authdeny;
             else
                 goto authfail;
         }
 
-        REMOTE_DEBUG("Authentication successful %d", client->fd);
-        PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
-              client->fd, REMOTE_AUTH_SASL, client->saslUsername);
         ret->complete = 1;
-        client->auth = REMOTE_AUTH_NONE;
     }
 
-    virMutexUnlock(&client->lock);
+    virMutexUnlock(&priv->lock);
     return 0;
 
 authfail:
-    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
-    remoteDispatchAuthError(rerr);
+    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
+          virNetServerClientGetFD(client), REMOTE_AUTH_SASL);
     goto error;
 
 authdeny:
     PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
-          client->fd, REMOTE_AUTH_SASL, client->saslUsername);
+          virNetServerClientGetFD(client), REMOTE_AUTH_SASL,
+          virNetSASLSessionGetIdentity(priv->sasl));
     goto error;
 
 error:
-    virMutexUnlock(&client->lock);
+    virNetSASLSessionFree(priv->sasl);
+    priv->sasl = NULL;
+    virResetLastError();
+    virNetError(VIR_ERR_AUTH_FAILED, "%s",
+                _("authentication failed"));
+    virMutexUnlock(&priv->lock);
     return -1;
 }
 
 
 static int
-remoteDispatchAuthSaslStep (struct qemud_server *server,
-                            struct qemud_client *client,
-                            virConnectPtr conn ATTRIBUTE_UNUSED,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
+remoteDispatchAuthSaslStep (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                             remote_auth_sasl_step_args *args,
                             remote_auth_sasl_step_ret *ret)
 {
     const char *serverout;
-    unsigned int serveroutlen;
+    size_t serveroutlen;
     int err;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
 
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
 
-    REMOTE_DEBUG("Step SASL auth %d", client->fd);
-    if (client->auth != REMOTE_AUTH_SASL ||
-        client->saslconn == NULL) {
+    virMutexLock(&priv->lock);
+
+    REMOTE_DEBUG("Step SASL auth %d", virNetServerClientGetFD(client));
+    if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_SASL ||
+        priv->sasl == NULL) {
         VIR_ERROR0(_("client tried invalid SASL start request"));
         goto authfail;
     }
 
-    REMOTE_DEBUG("Using SASL Data %d bytes, nil: %d",
+    REMOTE_DEBUG("Step using SASL Data %d bytes, nil: %d",
                  args->data.data_len, args->nil);
-    err = sasl_server_step(client->saslconn,
-                           /* NB, distinction of NULL vs "" is *critical* in SASL */
-                           args->nil ? NULL : args->data.data_val,
-                           args->data.data_len,
-                           &serverout,
-                           &serveroutlen);
-    if (err != SASL_OK &&
-        err != SASL_CONTINUE) {
-        VIR_ERROR(_("sasl step failed %d (%s)"),
-                  err, sasl_errdetail(client->saslconn));
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
+    err = virNetSASLSessionServerStep(priv->sasl,
+                                      /* NB, distinction of NULL vs "" is *critical* in SASL */
+                                      args->nil ? NULL : args->data.data_val,
+                                      args->data.data_len,
+                                      &serverout,
+                                      &serveroutlen);
+    if (err != VIR_NET_SASL_COMPLETE &&
+        err != VIR_NET_SASL_CONTINUE)
         goto authfail;
-    }
 
     if (serveroutlen > REMOTE_AUTH_SASL_DATA_MAX) {
         VIR_ERROR(_("sasl step reply data too long %d"),
-                  serveroutlen);
-        sasl_dispose(&client->saslconn);
-        client->saslconn = NULL;
+                  (int)serveroutlen);
         goto authfail;
     }
 
     /* NB, distinction of NULL vs "" is *critical* in SASL */
     if (serverout) {
-        if (VIR_ALLOC_N(ret->data.data_val, serveroutlen) < 0) {
-            remoteDispatchOOMError(rerr);
-            goto error;
-        }
+        if (VIR_ALLOC_N(ret->data.data_val, serveroutlen) < 0)
+            goto authfail;
         memcpy(ret->data.data_val, serverout, serveroutlen);
     } else {
         ret->data.data_val = NULL;
@@ -3952,100 +3479,51 @@ remoteDispatchAuthSaslStep (struct qemud_server *server,
     ret->data.data_len = serveroutlen;
 
     REMOTE_DEBUG("SASL return data %d bytes, nil; %d", ret->data.data_len, ret->nil);
-    if (err == SASL_CONTINUE) {
+    if (err == VIR_NET_SASL_CONTINUE) {
         ret->complete = 0;
     } else {
         /* Check username whitelist ACL */
-        if ((err = remoteSASLCheckAccess(server, client, rerr)) < 0 ||
-            (err = remoteSASLCheckSSF(client, rerr)) < 0) {
+        if ((err = remoteSASLFinish(client)) < 0) {
             if (err == -2)
                 goto authdeny;
             else
                 goto authfail;
         }
 
-        REMOTE_DEBUG("Authentication successful %d", client->fd);
-        PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
-              client->fd, REMOTE_AUTH_SASL, client->saslUsername);
         ret->complete = 1;
-        client->auth = REMOTE_AUTH_NONE;
     }
 
-    virMutexUnlock(&client->lock);
+    virMutexUnlock(&priv->lock);
     return 0;
 
 authfail:
-    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
-    remoteDispatchAuthError(rerr);
+    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
+          virNetServerClientGetFD(client), REMOTE_AUTH_SASL);
     goto error;
 
 authdeny:
     PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
-          client->fd, REMOTE_AUTH_SASL, client->saslUsername);
+          virNetServerClientGetFD(client), REMOTE_AUTH_SASL,
+          virNetSASLSessionGetIdentity(priv->sasl));
     goto error;
 
 error:
-    virMutexUnlock(&client->lock);
+    virNetSASLSessionFree(priv->sasl);
+    priv->sasl = NULL;
+    virResetLastError();
+    virNetError(VIR_ERR_AUTH_FAILED, "%s",
+                _("authentication failed"));
+    virMutexUnlock(&priv->lock);
     return -1;
 }
 
 
-#else /* HAVE_SASL */
-static int
-remoteDispatchAuthSaslInit (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn ATTRIBUTE_UNUSED,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
-                            void *args ATTRIBUTE_UNUSED,
-                            remote_auth_sasl_init_ret *ret ATTRIBUTE_UNUSED)
-{
-    VIR_ERROR0(_("client tried unsupported SASL init request"));
-    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
-    remoteDispatchAuthError(rerr);
-    return -1;
-}
-
-static int
-remoteDispatchAuthSaslStart (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn ATTRIBUTE_UNUSED,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             remote_auth_sasl_start_args *args ATTRIBUTE_UNUSED,
-                             remote_auth_sasl_start_ret *ret ATTRIBUTE_UNUSED)
-{
-    VIR_ERROR0(_("client tried unsupported SASL start request"));
-    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
-    remoteDispatchAuthError(rerr);
-    return -1;
-}
-
-static int
-remoteDispatchAuthSaslStep (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn ATTRIBUTE_UNUSED,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
-                            remote_auth_sasl_step_args *args ATTRIBUTE_UNUSED,
-                            remote_auth_sasl_step_ret *ret ATTRIBUTE_UNUSED)
-{
-    VIR_ERROR0(_("client tried unsupported SASL step request"));
-    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
-    remoteDispatchAuthError(rerr);
-    return -1;
-}
-#endif /* HAVE_SASL */
-
 
 #if HAVE_POLKIT1
 static int
-remoteDispatchAuthPolkit (struct qemud_server *server,
-                          struct qemud_client *client,
-                          virConnectPtr conn ATTRIBUTE_UNUSED,
-                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                          remote_error *rerr,
-                          void *args ATTRIBUTE_UNUSED,
+remoteDispatchAuthPolkit (virNetServerPtr server ATTRIBUTE_UNUSED,
+                          virNetServerClientPtr client,
+                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                           remote_auth_polkit_ret *ret)
 {
     pid_t callerPid = -1;
@@ -4055,14 +3533,14 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
     char pidbuf[50];
     char ident[100];
     int rv;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
 
-    memset(ident, 0, sizeof ident);
 
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
+    memset(ident, 0, sizeof ident);
 
-    action = client->readonly ?
+    virMutexLock(&priv->lock);
+    action = virNetServerClientGetReadonly(client) ?
         "org.libvirt.unix.monitor" :
         "org.libvirt.unix.manage";
 
@@ -4074,13 +3552,13 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
       NULL
     };
 
-    REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
-    if (client->auth != REMOTE_AUTH_POLKIT) {
+    REMOTE_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
+    if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) {
         VIR_ERROR0(_("client tried invalid PolicyKit init request"));
         goto authfail;
     }
 
-    if (qemudGetSocketIdentity(client->fd, &callerUid, &callerPid) < 0) {
+    if (qemudGetSocketIdentity(virNetServerClientGetFD(client), &callerUid, &callerPid) < 0) {
         VIR_ERROR0(_("cannot get peer socket identity"));
         goto authfail;
     }
@@ -4109,37 +3587,38 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
         goto authdeny;
     }
     PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
-          client->fd, REMOTE_AUTH_POLKIT, (char *)ident);
+          virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT, ident);
     VIR_INFO(_("Policy allowed action %s from pid %d, uid %d"),
              action, callerPid, callerUid);
     ret->complete = 1;
-    client->auth = REMOTE_AUTH_NONE;
 
-    virMutexUnlock(&client->lock);
+    virNetServerClientSetIdentity(client, ident);
+    virMutexUnlock(&priv->lock);
+
     return 0;
 
 authfail:
-    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_POLKIT);
+    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
+          virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT);
     goto error;
 
 authdeny:
     PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
-          client->fd, REMOTE_AUTH_POLKIT, (char *)ident);
+          virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT, (char *)ident);
     goto error;
 
 error:
-    remoteDispatchAuthError(rerr);
-    virMutexUnlock(&client->lock);
+    virResetLastError();
+    virNetError(VIR_ERR_AUTH_FAILED, "%s",
+                _("authentication failed"));
+    virMutexUnlock(&priv->lock);
     return -1;
 }
 #elif HAVE_POLKIT0
 static int
-remoteDispatchAuthPolkit (struct qemud_server *server,
-                          struct qemud_client *client,
-                          virConnectPtr conn ATTRIBUTE_UNUSED,
-                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                          remote_error *rerr,
-                          void *args ATTRIBUTE_UNUSED,
+remoteDispatchAuthPolkit (virNetServerPtr server ATTRIBUTE_UNUSED,
+                          virNetServerClientPtr client,
+                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                           remote_auth_polkit_ret *ret)
 {
     pid_t callerPid;
@@ -4153,6 +3632,9 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
     const char *action;
     char ident[100];
     int rv;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
+
 
     memset(ident, 0, sizeof ident);
 
@@ -4164,13 +3646,13 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
         "org.libvirt.unix.monitor" :
         "org.libvirt.unix.manage";
 
-    REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
+    REMOTE_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
     if (client->auth != REMOTE_AUTH_POLKIT) {
         VIR_ERROR0(_("client tried invalid PolicyKit init request"));
         goto authfail;
     }
 
-    if (qemudGetSocketIdentity(client->fd, &callerUid, &callerPid) < 0) {
+    if (qemudGetSocketIdentity(virNetServerClientGetFD(client), &callerUid, &callerPid) < 0) {
         VIR_ERROR0(_("cannot get peer socket identity"));
         goto authfail;
     }
@@ -4240,7 +3722,7 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
         goto authdeny;
     }
     PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
-          client->fd, REMOTE_AUTH_POLKIT, ident);
+          virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT, ident);
     VIR_INFO(_("Policy allowed action %s from pid %d, uid %d, result %s"),
              action, callerPid, callerUid,
              polkit_result_to_string_representation(pkresult));
@@ -4251,16 +3733,19 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
     return 0;
 
 authfail:
-    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_POLKIT);
+    PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
+          virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT);
     goto error;
 
 authdeny:
     PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
-          client->fd, REMOTE_AUTH_POLKIT, ident);
+          virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT, ident);
     goto error;
 
 error:
-    remoteDispatchAuthError(rerr);
+    virResetLastError();
+    virNetError(VIR_ERR_AUTH_FAILED, "%s",
+                _("authentication failed"));
     virMutexUnlock(&client->lock);
     return -1;
 }
@@ -4268,12 +3753,9 @@ error:
 #else /* !HAVE_POLKIT0 & !HAVE_POLKIT1*/
 
 static int
-remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
-                          struct qemud_client *client ATTRIBUTE_UNUSED,
-                          virConnectPtr conn ATTRIBUTE_UNUSED,
-                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                          remote_error *rerr,
-                          void *args ATTRIBUTE_UNUSED,
+remoteDispatchAuthPolkit (virNetServerPtr server ATTRIBUTE_UNUSED,
+                          virNetServerClientPtr client,
+                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                           remote_auth_polkit_ret *ret ATTRIBUTE_UNUSED)
 {
     VIR_ERROR0(_("client tried unsupported PolicyKit init request"));
@@ -4289,33 +3771,31 @@ remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchListDefinedStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchListDefinedStoragePools (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_list_defined_storage_pools_args *args,
                                        remote_list_defined_storage_pools_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr, "%s",
-                            _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC, "%s",
+                    _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virConnectListDefinedStoragePools (conn,
+        virConnectListDefinedStoragePools (priv->conn,
                                            ret->names.names_val, args->maxnames);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_val);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4323,33 +3803,31 @@ remoteDispatchListDefinedStoragePools (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchListStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
+remoteDispatchListStoragePools (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_list_storage_pools_args *args,
                                 remote_list_storage_pools_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC, "%s",
+                    _("maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virConnectListStoragePools (conn,
-                                ret->names.names_val, args->maxnames);
+        virConnectListStoragePools (priv->conn,
+                                    ret->names.names_val, args->maxnames);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_val);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4357,21 +3835,20 @@ remoteDispatchListStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchFindStoragePoolSources (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
+remoteDispatchFindStoragePoolSources (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_find_storage_pool_sources_args *args,
                                       remote_find_storage_pool_sources_ret *ret)
 {
+    CHECK_CONN(client);
+
     ret->xml =
-        virConnectFindStoragePoolSources (conn,
+        virConnectFindStoragePoolSources (priv->conn,
                                           args->type,
                                           args->srcSpec ? *args->srcSpec : NULL,
                                           args->flags);
     if (ret->xml == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4380,25 +3857,21 @@ remoteDispatchFindStoragePoolSources (struct qemud_server *server ATTRIBUTE_UNUS
 
 
 static int
-remoteDispatchStoragePoolCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
-                                 remote_storage_pool_create_args *args,
-                                 void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStoragePoolCreate (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                 remote_storage_pool_create_args *args)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolCreate (pool, args->flags) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4406,19 +3879,17 @@ remoteDispatchStoragePoolCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStoragePoolCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchStoragePoolCreateXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_storage_pool_create_xml_args *args,
                                     remote_storage_pool_create_xml_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = virStoragePoolCreateXML (conn, args->xml, args->flags);
+    pool = virStoragePoolCreateXML (priv->conn, args->xml, args->flags);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4428,19 +3899,17 @@ remoteDispatchStoragePoolCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchStoragePoolDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchStoragePoolDefineXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_storage_pool_define_xml_args *args,
                                     remote_storage_pool_define_xml_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = virStoragePoolDefineXML (conn, args->xml, args->flags);
+    pool = virStoragePoolDefineXML (priv->conn, args->xml, args->flags);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4450,25 +3919,21 @@ remoteDispatchStoragePoolDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchStoragePoolBuild (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
-                                remote_storage_pool_build_args *args,
-                                void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStoragePoolBuild (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                remote_storage_pool_build_args *args)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolBuild (pool, args->flags) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4477,25 +3942,21 @@ remoteDispatchStoragePoolBuild (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchStoragePoolDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
-                                  remote_storage_pool_destroy_args *args,
-                                  void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStoragePoolDestroy (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                  remote_storage_pool_destroy_args *args)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolDestroy (pool) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4503,25 +3964,21 @@ remoteDispatchStoragePoolDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStoragePoolDelete (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
-                                 remote_storage_pool_delete_args *args,
-                                 void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStoragePoolDelete (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                 remote_storage_pool_delete_args *args)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolDelete (pool, args->flags) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4529,25 +3986,21 @@ remoteDispatchStoragePoolDelete (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStoragePoolRefresh (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
-                                  remote_storage_pool_refresh_args *args,
-                                  void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStoragePoolRefresh (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                  remote_storage_pool_refresh_args *args)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolRefresh (pool, args->flags) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4555,26 +4008,23 @@ remoteDispatchStoragePoolRefresh (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStoragePoolGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchStoragePoolGetInfo (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_storage_pool_get_info_args *args,
                                   remote_storage_pool_get_info_ret *ret)
 {
     virStoragePoolPtr pool;
     virStoragePoolInfo info;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolGetInfo (pool, &info) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4589,19 +4039,17 @@ remoteDispatchStoragePoolGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStoragePoolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchStoragePoolDumpXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_storage_pool_dump_xml_args *args,
                                   remote_storage_pool_dump_xml_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4609,7 +4057,6 @@ remoteDispatchStoragePoolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
     ret->xml = virStoragePoolGetXMLDesc (pool, args->flags);
     if (!ret->xml) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4617,25 +4064,22 @@ remoteDispatchStoragePoolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStoragePoolGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchStoragePoolGetAutostart (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_storage_pool_get_autostart_args *args,
                                        remote_storage_pool_get_autostart_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolGetAutostart (pool, &ret->autostart) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4644,19 +4088,17 @@ remoteDispatchStoragePoolGetAutostart (struct qemud_server *server ATTRIBUTE_UNU
 
 
 static int
-remoteDispatchStoragePoolLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchStoragePoolLookupByName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_storage_pool_lookup_by_name_args *args,
                                        remote_storage_pool_lookup_by_name_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = virStoragePoolLookupByName (conn, args->name);
+    pool = virStoragePoolLookupByName (priv->conn, args->name);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4666,19 +4108,17 @@ remoteDispatchStoragePoolLookupByName (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchStoragePoolLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchStoragePoolLookupByUuid (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_storage_pool_lookup_by_uuid_args *args,
                                        remote_storage_pool_lookup_by_uuid_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = virStoragePoolLookupByUUID (conn, (unsigned char *) args->uuid);
+    pool = virStoragePoolLookupByUUID (priv->conn, (unsigned char *) args->uuid);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4688,27 +4128,24 @@ remoteDispatchStoragePoolLookupByUuid (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchStoragePoolLookupByVolume (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                         struct qemud_client *client ATTRIBUTE_UNUSED,
-                                         virConnectPtr conn,
-                                         remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                         remote_error *rerr,
+remoteDispatchStoragePoolLookupByVolume (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                         virNetServerClientPtr client,
+                                         virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                          remote_storage_pool_lookup_by_volume_args *args,
                                          remote_storage_pool_lookup_by_volume_ret *ret)
 {
     virStoragePoolPtr pool;
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    vol = get_nonnull_storage_vol (conn, args->vol);
+    vol = get_nonnull_storage_vol (priv->conn, args->vol);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     pool = virStoragePoolLookupByVolume (vol);
     virStorageVolFree(vol);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4718,25 +4155,21 @@ remoteDispatchStoragePoolLookupByVolume (struct qemud_server *server ATTRIBUTE_U
 }
 
 static int
-remoteDispatchStoragePoolSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
-                                       remote_storage_pool_set_autostart_args *args,
-                                       void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStoragePoolSetAutostart (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                       remote_storage_pool_set_autostart_args *args)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolSetAutostart (pool, args->autostart) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4744,25 +4177,21 @@ remoteDispatchStoragePoolSetAutostart (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchStoragePoolUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
-                                   remote_storage_pool_undefine_args *args,
-                                   void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStoragePoolUndefine (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                   remote_storage_pool_undefine_args *args)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStoragePoolUndefine (pool) == -1) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4770,18 +4199,15 @@ remoteDispatchStoragePoolUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNumOfStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
-                                 void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfStoragePools (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_num_of_storage_pools_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfStoragePools (conn);
+    ret->num = virConnectNumOfStoragePools (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4789,18 +4215,15 @@ remoteDispatchNumOfStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchNumOfDefinedStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                        struct qemud_client *client ATTRIBUTE_UNUSED,
-                                        virConnectPtr conn,
-                                        remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                        remote_error *rerr,
-                                        void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfDefinedStoragePools (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                        virNetServerClientPtr client,
+                                        virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                         remote_num_of_defined_storage_pools_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfDefinedStoragePools (conn);
+    ret->num = virConnectNumOfDefinedStoragePools (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4808,32 +4231,30 @@ remoteDispatchNumOfDefinedStoragePools (struct qemud_server *server ATTRIBUTE_UN
 }
 
 static int
-remoteDispatchStoragePoolListVolumes (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
+remoteDispatchStoragePoolListVolumes (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_storage_pool_list_volumes_args *args,
                                       remote_storage_pool_list_volumes_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX"));
         return -1;
     }
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
+        virReportOOMError();
         virStoragePoolFree(pool);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
@@ -4843,7 +4264,6 @@ remoteDispatchStoragePoolListVolumes (struct qemud_server *server ATTRIBUTE_UNUS
     virStoragePoolFree(pool);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_val);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4852,26 +4272,23 @@ remoteDispatchStoragePoolListVolumes (struct qemud_server *server ATTRIBUTE_UNUS
 
 
 static int
-remoteDispatchStoragePoolNumOfVolumes (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchStoragePoolNumOfVolumes (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_storage_pool_num_of_volumes_args *args,
                                        remote_storage_pool_num_of_volumes_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     ret->num = virStoragePoolNumOfVolumes (pool);
     virStoragePoolFree(pool);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4886,27 +4303,24 @@ remoteDispatchStoragePoolNumOfVolumes (struct qemud_server *server ATTRIBUTE_UNU
 
 
 static int
-remoteDispatchStorageVolCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchStorageVolCreateXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_storage_vol_create_xml_args *args,
                                    remote_storage_vol_create_xml_ret *ret)
 {
     virStoragePoolPtr pool;
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     vol = virStorageVolCreateXML (pool, args->xml, args->flags);
     virStoragePoolFree(pool);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4916,27 +4330,24 @@ remoteDispatchStorageVolCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStorageVolCreateXmlFrom (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchStorageVolCreateXmlFrom (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_storage_vol_create_xml_from_args *args,
                                        remote_storage_vol_create_xml_from_ret *ret)
 {
     virStoragePoolPtr pool;
     virStorageVolPtr clonevol, newvol;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
-    clonevol = get_nonnull_storage_vol (conn, args->clonevol);
+    clonevol = get_nonnull_storage_vol (priv->conn, args->clonevol);
     if (clonevol == NULL) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4945,7 +4356,6 @@ remoteDispatchStorageVolCreateXmlFrom (struct qemud_server *server ATTRIBUTE_UNU
     virStorageVolFree(clonevol);
     virStoragePoolFree(pool);
     if (newvol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -4955,25 +4365,21 @@ remoteDispatchStorageVolCreateXmlFrom (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchStorageVolDelete (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
-                                remote_storage_vol_delete_args *args,
-                                void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStorageVolDelete (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                remote_storage_vol_delete_args *args)
 {
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    vol = get_nonnull_storage_vol (conn, args->vol);
+    vol = get_nonnull_storage_vol (priv->conn, args->vol);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStorageVolDelete (vol, args->flags) == -1) {
         virStorageVolFree(vol);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStorageVolFree(vol);
@@ -4981,25 +4387,21 @@ remoteDispatchStorageVolDelete (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStorageVolWipe(struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
-                             remote_storage_vol_wipe_args *args,
-                             void *ret ATTRIBUTE_UNUSED)
+remoteDispatchStorageVolWipe(virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                             remote_storage_vol_wipe_args *args)
 {
     int retval = -1;
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    vol = get_nonnull_storage_vol(conn, args->vol);
+    vol = get_nonnull_storage_vol(priv->conn, args->vol);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         goto out;
     }
 
     if (virStorageVolWipe(vol, args->flags) == -1) {
-        remoteDispatchConnError(rerr, conn);
         goto out;
     }
 
@@ -5013,26 +4415,23 @@ out:
 }
 
 static int
-remoteDispatchStorageVolGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchStorageVolGetInfo (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_storage_vol_get_info_args *args,
                                  remote_storage_vol_get_info_ret *ret)
 {
     virStorageVolPtr vol;
     virStorageVolInfo info;
+    CHECK_CONN(client);
 
-    vol = get_nonnull_storage_vol (conn, args->vol);
+    vol = get_nonnull_storage_vol (priv->conn, args->vol);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virStorageVolGetInfo (vol, &info) == -1) {
         virStorageVolFree(vol);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5046,19 +4445,17 @@ remoteDispatchStorageVolGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchStorageVolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchStorageVolDumpXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_storage_vol_dump_xml_args *args,
                                  remote_storage_vol_dump_xml_ret *ret)
 {
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    vol = get_nonnull_storage_vol (conn, args->vol);
+    vol = get_nonnull_storage_vol (priv->conn, args->vol);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5066,7 +4463,6 @@ remoteDispatchStorageVolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
     ret->xml = virStorageVolGetXMLDesc (vol, args->flags);
     if (!ret->xml) {
         virStorageVolFree(vol);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStorageVolFree(vol);
@@ -5075,19 +4471,17 @@ remoteDispatchStorageVolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchStorageVolGetPath (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchStorageVolGetPath (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_storage_vol_get_path_args *args,
                                  remote_storage_vol_get_path_ret *ret)
 {
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    vol = get_nonnull_storage_vol (conn, args->vol);
+    vol = get_nonnull_storage_vol (priv->conn, args->vol);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5095,7 +4489,6 @@ remoteDispatchStorageVolGetPath (struct qemud_server *server ATTRIBUTE_UNUSED,
     ret->name = virStorageVolGetPath (vol);
     if (!ret->name) {
         virStorageVolFree(vol);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virStorageVolFree(vol);
@@ -5104,27 +4497,24 @@ remoteDispatchStorageVolGetPath (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchStorageVolLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
+remoteDispatchStorageVolLookupByName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_storage_vol_lookup_by_name_args *args,
                                       remote_storage_vol_lookup_by_name_ret *ret)
 {
     virStoragePoolPtr pool;
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool (conn, args->pool);
+    pool = get_nonnull_storage_pool (priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     vol = virStorageVolLookupByName (pool, args->name);
     virStoragePoolFree(pool);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5134,19 +4524,17 @@ remoteDispatchStorageVolLookupByName (struct qemud_server *server ATTRIBUTE_UNUS
 }
 
 static int
-remoteDispatchStorageVolLookupByKey (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                     struct qemud_client *client ATTRIBUTE_UNUSED,
-                                     virConnectPtr conn,
-                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                     remote_error *rerr,
+remoteDispatchStorageVolLookupByKey (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                      remote_storage_vol_lookup_by_key_args *args,
                                      remote_storage_vol_lookup_by_key_ret *ret)
 {
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    vol = virStorageVolLookupByKey (conn, args->key);
+    vol = virStorageVolLookupByKey (priv->conn, args->key);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5157,19 +4545,17 @@ remoteDispatchStorageVolLookupByKey (struct qemud_server *server ATTRIBUTE_UNUSE
 
 
 static int
-remoteDispatchStorageVolLookupByPath (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
+remoteDispatchStorageVolLookupByPath (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_storage_vol_lookup_by_path_args *args,
                                       remote_storage_vol_lookup_by_path_ret *ret)
 {
     virStorageVolPtr vol;
+    CHECK_CONN(client);
 
-    vol = virStorageVolLookupByPath (conn, args->path);
+    vol = virStorageVolLookupByPath (priv->conn, args->path);
     if (vol == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5184,21 +4570,18 @@ remoteDispatchStorageVolLookupByPath (struct qemud_server *server ATTRIBUTE_UNUS
  **************************************************************/
 
 static int
-remoteDispatchNodeNumOfDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
+remoteDispatchNodeNumOfDevices (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_node_num_of_devices_args *args,
                                 remote_node_num_of_devices_ret *ret)
 {
     CHECK_CONN(client);
 
-    ret->num = virNodeNumOfDevices (conn,
+    ret->num = virNodeNumOfDevices (priv->conn,
                                     args->cap ? *args->cap : NULL,
                                     args->flags);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5207,34 +4590,31 @@ remoteDispatchNodeNumOfDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeListDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
+remoteDispatchNodeListDevices (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_node_list_devices_args *args,
                                remote_node_list_devices_ret *ret)
 {
     CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
-        remoteDispatchFormatError(rerr,
-                                  "%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virNodeListDevices (conn,
+        virNodeListDevices (priv->conn,
                             args->cap ? *args->cap : NULL,
                             ret->names.names_val, args->maxnames, args->flags);
     if (ret->names.names_len == -1) {
-        remoteDispatchConnError(rerr, conn);
         VIR_FREE(ret->names.names_val);
         return -1;
     }
@@ -5244,11 +4624,9 @@ remoteDispatchNodeListDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
+remoteDispatchNodeDeviceLookupByName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_node_device_lookup_by_name_args *args,
                                       remote_node_device_lookup_by_name_ret *ret)
 {
@@ -5256,9 +4634,8 @@ remoteDispatchNodeDeviceLookupByName (struct qemud_server *server ATTRIBUTE_UNUS
 
     CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName (conn, args->name);
+    dev = virNodeDeviceLookupByName (priv->conn, args->name);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5269,27 +4646,23 @@ remoteDispatchNodeDeviceLookupByName (struct qemud_server *server ATTRIBUTE_UNUS
 
 
 static int
-remoteDispatchNodeDeviceDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchNodeDeviceDumpXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_node_device_dump_xml_args *args,
                                  remote_node_device_dump_xml_ret *ret)
 {
     virNodeDevicePtr dev;
     CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName(conn, args->name);
+    dev = virNodeDeviceLookupByName(priv->conn, args->name);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     /* remoteDispatchClientRequest will free this. */
     ret->xml = virNodeDeviceGetXMLDesc (dev, args->flags);
     if (!ret->xml) {
-        remoteDispatchConnError(rerr, conn);
         virNodeDeviceFree(dev);
         return -1;
     }
@@ -5299,11 +4672,9 @@ remoteDispatchNodeDeviceDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceGetParent (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchNodeDeviceGetParent (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_node_device_get_parent_args *args,
                                    remote_node_device_get_parent_ret *ret)
 {
@@ -5311,9 +4682,8 @@ remoteDispatchNodeDeviceGetParent (struct qemud_server *server ATTRIBUTE_UNUSED,
     const char *parent;
     CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName(conn, args->name);
+    dev = virNodeDeviceLookupByName(priv->conn, args->name);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5325,14 +4695,14 @@ remoteDispatchNodeDeviceGetParent (struct qemud_server *server ATTRIBUTE_UNUSED,
         /* remoteDispatchClientRequest will free this. */
         char **parent_p;
         if (VIR_ALLOC(parent_p) < 0) {
+            virReportOOMError();
             virNodeDeviceFree(dev);
-            remoteDispatchOOMError(rerr);
             return -1;
         }
         *parent_p = strdup(parent);
         if (*parent_p == NULL) {
+            virReportOOMError();
             virNodeDeviceFree(dev);
-            remoteDispatchOOMError(rerr);
             return -1;
         }
         ret->parent = parent_p;
@@ -5344,27 +4714,23 @@ remoteDispatchNodeDeviceGetParent (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceNumOfCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *rerr,
+remoteDispatchNodeDeviceNumOfCaps (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_node_device_num_of_caps_args *args,
                                    remote_node_device_num_of_caps_ret *ret)
 {
     virNodeDevicePtr dev;
     CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName(conn, args->name);
+    dev = virNodeDeviceLookupByName(priv->conn, args->name);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     ret->num = virNodeDeviceNumOfCaps(dev);
     if (ret->num < 0) {
         virNodeDeviceFree(dev);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5374,34 +4740,30 @@ remoteDispatchNodeDeviceNumOfCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchNodeDeviceListCaps (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_node_device_list_caps_args *args,
                                   remote_node_device_list_caps_ret *ret)
 {
-    virNodeDevicePtr dev;
+    virNodeDevicePtr dev = NULL;
     CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName(conn, args->name);
-    if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
+    if (args->maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
         return -1;
     }
 
-    if (args->maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
-        virNodeDeviceFree(dev);
-        remoteDispatchFormatError(rerr,
-                                  "%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
+    dev = virNodeDeviceLookupByName(priv->conn, args->name);
+    if (dev == NULL) {
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
+        virReportOOMError();
         virNodeDeviceFree(dev);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
@@ -5410,7 +4772,6 @@ remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
                                args->maxnames);
     if (ret->names.names_len == -1) {
         virNodeDeviceFree(dev);
-        remoteDispatchConnError(rerr, conn);
         VIR_FREE(ret->names.names_val);
         return -1;
     }
@@ -5421,26 +4782,21 @@ remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceDettach (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
-                                 remote_node_device_dettach_args *args,
-                                 void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNodeDeviceDettach (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                 remote_node_device_dettach_args *args)
 {
     virNodeDevicePtr dev;
     CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName(conn, args->name);
+    dev = virNodeDeviceLookupByName(priv->conn, args->name);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNodeDeviceDettach(dev) == -1) {
         virNodeDeviceFree(dev);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5450,26 +4806,21 @@ remoteDispatchNodeDeviceDettach (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceReAttach (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
-                                  remote_node_device_re_attach_args *args,
-                                  void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNodeDeviceReAttach (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                  remote_node_device_re_attach_args *args)
 {
     virNodeDevicePtr dev;
     CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName(conn, args->name);
+    dev = virNodeDeviceLookupByName(priv->conn, args->name);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNodeDeviceReAttach(dev) == -1) {
         virNodeDeviceFree(dev);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5479,26 +4830,21 @@ remoteDispatchNodeDeviceReAttach (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceReset (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *rerr,
-                               remote_node_device_reset_args *args,
-                               void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNodeDeviceReset (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                               remote_node_device_reset_args *args)
 {
     virNodeDevicePtr dev;
     CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName(conn, args->name);
+    dev = virNodeDeviceLookupByName(priv->conn, args->name);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNodeDeviceReset(dev) == -1) {
         virNodeDeviceFree(dev);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5508,19 +4854,17 @@ remoteDispatchNodeDeviceReset (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceCreateXml(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchNodeDeviceCreateXml(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_node_device_create_xml_args *args,
                                   remote_node_device_create_xml_ret *ret)
 {
     virNodeDevicePtr dev;
+    CHECK_CONN(client);
 
-    dev = virNodeDeviceCreateXML (conn, args->xml_desc, args->flags);
+    dev = virNodeDeviceCreateXML (priv->conn, args->xml_desc, args->flags);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5532,25 +4876,21 @@ remoteDispatchNodeDeviceCreateXml(struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNodeDeviceDestroy(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
-                                remote_node_device_destroy_args *args,
-                                void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNodeDeviceDestroy(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                remote_node_device_destroy_args *args)
 {
     virNodeDevicePtr dev;
+    CHECK_CONN(client);
 
-    dev = virNodeDeviceLookupByName(conn, args->name);
+    dev = virNodeDeviceLookupByName(priv->conn, args->name);
     if (dev == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNodeDeviceDestroy(dev) == -1) {
         virNodeDeviceFree(dev);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -5564,136 +4904,109 @@ remoteDispatchNodeDeviceDestroy(struct qemud_server *server ATTRIBUTE_UNUSED,
  * Register / deregister events
  ***************************/
 static int
-remoteDispatchDomainEventsRegister (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr ATTRIBUTE_UNUSED,
-                                    void *args ATTRIBUTE_UNUSED,
+remoteDispatchDomainEventsRegister (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_domain_events_register_ret *ret ATTRIBUTE_UNUSED)
 {
     CHECK_CONN(client);
     int callbackID;
 
-    if (client->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] != -1) {
-        remoteDispatchFormatError(rerr, _("domain event %d already registered"), VIR_DOMAIN_EVENT_ID_LIFECYCLE);
+    virMutexLock(&priv->lock);
+    if (priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] != -1) {
+        virNetError(VIR_ERR_RPC,
+                    _("domain event %d already registered"),
+                    VIR_DOMAIN_EVENT_ID_LIFECYCLE);
+        virMutexUnlock(&priv->lock);
         return -1;
     }
 
-    if ((callbackID = virConnectDomainEventRegisterAny(conn,
+    if ((callbackID = virConnectDomainEventRegisterAny(priv->conn,
                                                        NULL,
                                                        VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                                                        VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
                                                        client, NULL)) < 0) {
-        remoteDispatchConnError(rerr, conn);
+        virMutexUnlock(&priv->lock);
         return -1;
     }
 
-    client->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] = callbackID;
+    priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] = callbackID;
 
+    virMutexUnlock(&priv->lock);
     return 0;
 }
 
 static int
-remoteDispatchDomainEventsDeregister (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr ATTRIBUTE_UNUSED,
-                                      void *args ATTRIBUTE_UNUSED,
+remoteDispatchDomainEventsDeregister (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                       remote_domain_events_deregister_ret *ret ATTRIBUTE_UNUSED)
 {
     CHECK_CONN(client);
 
-    if (client->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] == -1) {
-        remoteDispatchFormatError(rerr, _("domain event %d not registered"), VIR_DOMAIN_EVENT_ID_LIFECYCLE);
+    virMutexLock(&priv->lock);
+    if (priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] == -1) {
+        virNetError(VIR_ERR_RPC,
+                    _("domain event %d not registered"),
+                    VIR_DOMAIN_EVENT_ID_LIFECYCLE);
+        virMutexUnlock(&priv->lock);
         return -1;
     }
 
-    if (virConnectDomainEventDeregisterAny(conn,
-                                           client->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE]) < 0) {
-        remoteDispatchConnError(rerr, conn);
+    if (virConnectDomainEventDeregisterAny(priv->conn,
+                                           priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE]) < 0) {
+        virMutexUnlock(&priv->lock);
         return -1;
     }
 
-    client->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] = -1;
+    priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] = -1;
+    virMutexUnlock(&priv->lock);
     return 0;
 }
 
 static void
-remoteDispatchDomainEventSend (struct qemud_client *client,
-                               int procnr,
-                               xdrproc_t proc,
-                               void *data)
+remoteDispatchDomainEventSend(virNetServerClientPtr client,
+                              virNetServerProgramPtr program,
+                              int procnr,
+                              xdrproc_t proc,
+                              void *data)
 {
-    struct qemud_client_message *msg = NULL;
-    XDR xdr;
-    unsigned int len;
+    virNetMessagePtr msg;
 
-    if (VIR_ALLOC(msg) < 0)
+    if (!(msg = virNetMessageNew()))
         return;
 
-    msg->hdr.prog = REMOTE_PROGRAM;
-    msg->hdr.vers = REMOTE_PROTOCOL_VERSION;
-    msg->hdr.proc = procnr;
-    msg->hdr.type = REMOTE_MESSAGE;
-    msg->hdr.serial = 1;
-    msg->hdr.status = REMOTE_OK;
+    msg->header.prog = virNetServerProgramGetID(program);
+    msg->header.vers = virNetServerProgramGetVersion(program);
+    msg->header.proc = procnr;
+    msg->header.type = VIR_NET_MESSAGE;
+    msg->header.serial = 1;
+    msg->header.status = VIR_NET_OK;
 
-    if (remoteEncodeClientMessageHeader(msg) < 0)
+    if (virNetMessageEncodeHeader(msg) < 0)
         goto error;
 
-    /* Serialise the return header and event. */
-    xdrmem_create (&xdr,
-                   msg->buffer,
-                   msg->bufferLength,
-                   XDR_ENCODE);
-
-    /* Skip over the header we just wrote */
-    if (xdr_setpos (&xdr, msg->bufferOffset) == 0)
-        goto xdr_error;
-
-    if (!(proc)(&xdr, data)) {
-        VIR_WARN("Failed to serialize domain event %d", procnr);
-        goto xdr_error;
-    }
-
-    /* Update length word to include payload*/
-    len = msg->bufferOffset = xdr_getpos (&xdr);
-    if (xdr_setpos (&xdr, 0) == 0)
-        goto xdr_error;
-
-    if (!xdr_u_int (&xdr, &len))
-        goto xdr_error;
+    if (virNetMessageEncodePayload(msg, proc, data) < 0)
+        goto error;
 
-    /* Send it. */
-    msg->async = 1;
-    msg->bufferLength = len;
-    msg->bufferOffset = 0;
-    qemudClientMessageQueuePush(&client->tx, msg);
-    qemudUpdateClientEvent(client);
+    virNetServerClientSendMessage(client, msg);
 
-    xdr_destroy (&xdr);
     return;
 
-xdr_error:
-    xdr_destroy(&xdr);
 error:
-    VIR_FREE(msg);
+    virNetMessageFree(msg);
 }
 
 static int
-remoteDispatchNumOfSecrets (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *err,
-                            void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfSecrets (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                             remote_num_of_secrets_ret *ret)
 {
-    ret->num = virConnectNumOfSecrets (conn);
+    CHECK_CONN(client);
+
+    ret->num = virConnectNumOfSecrets (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError (err, conn);
         return -1;
     }
 
@@ -5701,30 +5014,29 @@ remoteDispatchNumOfSecrets (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchListSecrets (struct qemud_server *server ATTRIBUTE_UNUSED,
-                           struct qemud_client *client ATTRIBUTE_UNUSED,
-                           virConnectPtr conn,
-                           remote_message_header *hdr ATTRIBUTE_UNUSED,
-                           remote_error *err,
+remoteDispatchListSecrets (virNetServerPtr server ATTRIBUTE_UNUSED,
+                           virNetServerClientPtr client,
+                           virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                            remote_list_secrets_args *args,
                            remote_list_secrets_ret *ret)
 {
+    CHECK_CONN(client);
+
     if (args->maxuuids > REMOTE_SECRET_UUID_LIST_MAX) {
-        remoteDispatchFormatError (err, "%s",
-                                   _("maxuuids > REMOTE_SECRET_UUID_LIST_MAX"));
+        virNetError(VIR_ERR_RPC, "%s",
+                    _("maxuuids > REMOTE_SECRET_UUID_LIST_MAX"));
         return -1;
     }
 
     if (VIR_ALLOC_N (ret->uuids.uuids_val, args->maxuuids) < 0) {
-        remoteDispatchOOMError (err);
+        virReportOOMError();
         return -1;
     }
 
-    ret->uuids.uuids_len = virConnectListSecrets (conn, ret->uuids.uuids_val,
+    ret->uuids.uuids_len = virConnectListSecrets (priv->conn, ret->uuids.uuids_val,
                                                   args->maxuuids);
     if (ret->uuids.uuids_len == -1) {
         VIR_FREE (ret->uuids.uuids_val);
-        remoteDispatchConnError (err, conn);
         return -1;
     }
 
@@ -5732,19 +5044,17 @@ remoteDispatchListSecrets (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchSecretDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                               struct qemud_client *client ATTRIBUTE_UNUSED,
-                               virConnectPtr conn,
-                               remote_message_header *hdr ATTRIBUTE_UNUSED,
-                               remote_error *err,
+remoteDispatchSecretDefineXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                               virNetServerClientPtr client,
+                               virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                remote_secret_define_xml_args *args,
                                remote_secret_define_xml_ret *ret)
 {
     virSecretPtr secret;
+    CHECK_CONN(client);
 
-    secret = virSecretDefineXML (conn, args->xml, args->flags);
+    secret = virSecretDefineXML (priv->conn, args->xml, args->flags);
     if (secret == NULL) {
-        remoteDispatchConnError (err, conn);
         return -1;
     }
 
@@ -5754,27 +5064,24 @@ remoteDispatchSecretDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchSecretGetValue (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *err,
+remoteDispatchSecretGetValue (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                               remote_secret_get_value_args *args,
                               remote_secret_get_value_ret *ret)
 {
     virSecretPtr secret;
     size_t value_size;
     unsigned char *value;
+    CHECK_CONN(client);
 
-    secret = get_nonnull_secret (conn, args->secret);
+    secret = get_nonnull_secret (priv->conn, args->secret);
     if (secret == NULL) {
-        remoteDispatchConnError (err, conn);
         return -1;
     }
 
     value = virSecretGetValue (secret, &value_size, args->flags);
     if (value == NULL) {
-        remoteDispatchConnError (err, conn);
         virSecretFree(secret);
         return -1;
     }
@@ -5786,24 +5093,21 @@ remoteDispatchSecretGetValue (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchSecretGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *err,
+remoteDispatchSecretGetXmlDesc (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_secret_get_xml_desc_args *args,
                                 remote_secret_get_xml_desc_ret *ret)
 {
     virSecretPtr secret;
+    CHECK_CONN(client);
 
-    secret = get_nonnull_secret (conn, args->secret);
+    secret = get_nonnull_secret (priv->conn, args->secret);
     if (secret == NULL) {
-        remoteDispatchConnError (err, conn);
         return -1;
     }
     ret->xml = virSecretGetXMLDesc (secret, args->flags);
     if (ret->xml == NULL) {
-        remoteDispatchConnError (err, conn);
         virSecretFree(secret);
         return -1;
     }
@@ -5812,19 +5116,17 @@ remoteDispatchSecretGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchSecretLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *err,
+remoteDispatchSecretLookupByUuid (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_secret_lookup_by_uuid_args *args,
                                   remote_secret_lookup_by_uuid_ret *ret)
 {
     virSecretPtr secret;
+    CHECK_CONN(client);
 
-    secret = virSecretLookupByUUID (conn, (unsigned char *)args->uuid);
+    secret = virSecretLookupByUUID (priv->conn, (unsigned char *)args->uuid);
     if (secret == NULL) {
-        remoteDispatchConnError (err, conn);
         return -1;
     }
 
@@ -5834,24 +5136,20 @@ remoteDispatchSecretLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchSecretSetValue (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *err,
-                              remote_secret_set_value_args *args,
-                              void *ret ATTRIBUTE_UNUSED)
+remoteDispatchSecretSetValue (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              remote_secret_set_value_args *args)
 {
     virSecretPtr secret;
+    CHECK_CONN(client);
 
-    secret = get_nonnull_secret (conn, args->secret);
+    secret = get_nonnull_secret (priv->conn, args->secret);
     if (secret == NULL) {
-        remoteDispatchConnError (err, conn);
         return -1;
     }
     if (virSecretSetValue (secret, (const unsigned char *)args->value.value_val,
                            args->value.value_len, args->flags) < 0) {
-        remoteDispatchConnError (err, conn);
         virSecretFree(secret);
         return -1;
     }
@@ -5861,23 +5159,19 @@ remoteDispatchSecretSetValue (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchSecretUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *err,
-                              remote_secret_undefine_args *args,
-                              void *ret ATTRIBUTE_UNUSED)
+remoteDispatchSecretUndefine (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              remote_secret_undefine_args *args)
 {
     virSecretPtr secret;
+    CHECK_CONN(client);
 
-    secret = get_nonnull_secret (conn, args->secret);
+    secret = get_nonnull_secret (priv->conn, args->secret);
     if (secret == NULL) {
-        remoteDispatchConnError (err, conn);
         return -1;
     }
     if (virSecretUndefine (secret) < 0) {
-        remoteDispatchConnError (err, conn);
         virSecretFree(secret);
         return -1;
     }
@@ -5887,19 +5181,17 @@ remoteDispatchSecretUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchSecretLookupByUsage (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                   struct qemud_client *client ATTRIBUTE_UNUSED,
-                                   virConnectPtr conn,
-                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                   remote_error *err,
+remoteDispatchSecretLookupByUsage (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                   virNetServerClientPtr client,
+                                   virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                    remote_secret_lookup_by_usage_args *args,
                                    remote_secret_lookup_by_usage_ret *ret)
 {
     virSecretPtr secret;
+    CHECK_CONN(client);
 
-    secret = virSecretLookupByUsage (conn, args->usageType, args->usageID);
+    secret = virSecretLookupByUsage (priv->conn, args->usageType, args->usageID);
     if (secret == NULL) {
-        remoteDispatchConnError (err, conn);
         return -1;
     }
 
@@ -5909,19 +5201,17 @@ remoteDispatchSecretLookupByUsage (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 
-static int remoteDispatchDomainIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                        struct qemud_client *client ATTRIBUTE_UNUSED,
-                                        virConnectPtr conn,
-                                        remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                        remote_error *err,
+static int remoteDispatchDomainIsActive(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                        virNetServerClientPtr client,
+                                        virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                         remote_domain_is_active_args *args,
                                         remote_domain_is_active_ret *ret)
 {
     virDomainPtr domain;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->dom);
+    domain = get_nonnull_domain(priv->conn, args->dom);
     if (domain == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -5929,7 +5219,6 @@ static int remoteDispatchDomainIsActive(struct qemud_server *server ATTRIBUTE_UN
 
     if (ret->active < 0) {
         virDomainFree(domain);
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -5937,19 +5226,17 @@ static int remoteDispatchDomainIsActive(struct qemud_server *server ATTRIBUTE_UN
     return 0;
 }
 
-static int remoteDispatchDomainIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                                            virConnectPtr conn,
-                                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                            remote_error *err,
+static int remoteDispatchDomainIsPersistent(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                            virNetServerClientPtr client,
+                                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                             remote_domain_is_persistent_args *args,
                                             remote_domain_is_persistent_ret *ret)
 {
     virDomainPtr domain;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->dom);
+    domain = get_nonnull_domain(priv->conn, args->dom);
     if (domain == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -5957,7 +5244,6 @@ static int remoteDispatchDomainIsPersistent(struct qemud_server *server ATTRIBUT
 
     if (ret->persistent < 0) {
         virDomainFree(domain);
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -5965,19 +5251,17 @@ static int remoteDispatchDomainIsPersistent(struct qemud_server *server ATTRIBUT
     return 0;
 }
 
-static int remoteDispatchDomainIsUpdated(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                                            virConnectPtr conn,
-                                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                            remote_error *err,
+static int remoteDispatchDomainIsUpdated(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                            virNetServerClientPtr client,
+                                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                             remote_domain_is_updated_args *args,
                                             remote_domain_is_updated_ret *ret)
 {
     virDomainPtr domain;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->dom);
+    domain = get_nonnull_domain(priv->conn, args->dom);
     if (domain == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -5985,7 +5269,6 @@ static int remoteDispatchDomainIsUpdated(struct qemud_server *server ATTRIBUTE_U
 
     if (ret->updated < 0) {
         virDomainFree(domain);
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -5993,19 +5276,17 @@ static int remoteDispatchDomainIsUpdated(struct qemud_server *server ATTRIBUTE_U
     return 0;
 }
 
-static int remoteDispatchInterfaceIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                           struct qemud_client *client ATTRIBUTE_UNUSED,
-                                           virConnectPtr conn,
-                                           remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                           remote_error *err,
+static int remoteDispatchInterfaceIsActive(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                           virNetServerClientPtr client,
+                                           virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                            remote_interface_is_active_args *args,
                                            remote_interface_is_active_ret *ret)
 {
     virInterfacePtr iface;
+    CHECK_CONN(client);
 
-    iface = get_nonnull_interface(conn, args->iface);
+    iface = get_nonnull_interface(priv->conn, args->iface);
     if (iface == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6013,7 +5294,6 @@ static int remoteDispatchInterfaceIsActive(struct qemud_server *server ATTRIBUTE
 
     if (ret->active < 0) {
         virInterfaceFree(iface);
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6021,19 +5301,17 @@ static int remoteDispatchInterfaceIsActive(struct qemud_server *server ATTRIBUTE
     return 0;
 }
 
-static int remoteDispatchNetworkIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                         struct qemud_client *client ATTRIBUTE_UNUSED,
-                                         virConnectPtr conn,
-                                         remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                         remote_error *err,
+static int remoteDispatchNetworkIsActive(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                         virNetServerClientPtr client,
+                                         virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                          remote_network_is_active_args *args,
                                          remote_network_is_active_ret *ret)
 {
     virNetworkPtr network;
+    CHECK_CONN(client);
 
-    network = get_nonnull_network(conn, args->net);
+    network = get_nonnull_network(priv->conn, args->net);
     if (network == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6041,7 +5319,6 @@ static int remoteDispatchNetworkIsActive(struct qemud_server *server ATTRIBUTE_U
 
     if (ret->active < 0) {
         virNetworkFree(network);
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6049,19 +5326,17 @@ static int remoteDispatchNetworkIsActive(struct qemud_server *server ATTRIBUTE_U
     return 0;
 }
 
-static int remoteDispatchNetworkIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                                             virConnectPtr conn,
-                                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                             remote_error *err,
+static int remoteDispatchNetworkIsPersistent(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                             virNetServerClientPtr client,
+                                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                              remote_network_is_persistent_args *args,
                                              remote_network_is_persistent_ret *ret)
 {
     virNetworkPtr network;
+    CHECK_CONN(client);
 
-    network = get_nonnull_network(conn, args->net);
+    network = get_nonnull_network(priv->conn, args->net);
     if (network == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6069,7 +5344,6 @@ static int remoteDispatchNetworkIsPersistent(struct qemud_server *server ATTRIBU
 
     if (ret->persistent < 0) {
         virNetworkFree(network);
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6077,19 +5351,17 @@ static int remoteDispatchNetworkIsPersistent(struct qemud_server *server ATTRIBU
     return 0;
 }
 
-static int remoteDispatchStoragePoolIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                                             virConnectPtr conn,
-                                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                             remote_error *err,
+static int remoteDispatchStoragePoolIsActive(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                             virNetServerClientPtr client,
+                                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                              remote_storage_pool_is_active_args *args,
                                              remote_storage_pool_is_active_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool(conn, args->pool);
+    pool = get_nonnull_storage_pool(priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6097,7 +5369,6 @@ static int remoteDispatchStoragePoolIsActive(struct qemud_server *server ATTRIBU
 
     if (ret->active < 0) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6105,19 +5376,17 @@ static int remoteDispatchStoragePoolIsActive(struct qemud_server *server ATTRIBU
     return 0;
 }
 
-static int remoteDispatchStoragePoolIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                                 virConnectPtr conn,
-                                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                                 remote_error *err,
+static int remoteDispatchStoragePoolIsPersistent(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                                 virNetServerClientPtr client,
+                                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                                  remote_storage_pool_is_persistent_args *args,
                                                  remote_storage_pool_is_persistent_ret *ret)
 {
     virStoragePoolPtr pool;
+    CHECK_CONN(client);
 
-    pool = get_nonnull_storage_pool(conn, args->pool);
+    pool = get_nonnull_storage_pool(priv->conn, args->pool);
     if (pool == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6125,7 +5394,6 @@ static int remoteDispatchStoragePoolIsPersistent(struct qemud_server *server ATT
 
     if (ret->persistent < 0) {
         virStoragePoolFree(pool);
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6134,18 +5402,16 @@ static int remoteDispatchStoragePoolIsPersistent(struct qemud_server *server ATT
 }
 
 
-static int remoteDispatchIsSecure(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *err,
-                                  void *args ATTRIBUTE_UNUSED,
+static int remoteDispatchIsSecure(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_is_secure_ret *ret)
 {
-    ret->secure = virConnectIsSecure(conn);
+    CHECK_CONN(client);
+
+    ret->secure = virConnectIsSecure(priv->conn);
 
     if (ret->secure < 0) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6154,19 +5420,17 @@ static int remoteDispatchIsSecure(struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchCpuCompare(struct qemud_server *server ATTRIBUTE_UNUSED,
-                         struct qemud_client *client ATTRIBUTE_UNUSED,
-                         virConnectPtr conn,
-                         remote_message_header *hdr ATTRIBUTE_UNUSED,
-                         remote_error *err,
+remoteDispatchCpuCompare(virNetServerPtr server ATTRIBUTE_UNUSED,
+                         virNetServerClientPtr client,
+                         virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                          remote_cpu_compare_args *args,
                          remote_cpu_compare_ret *ret)
 {
     int result;
+    CHECK_CONN(client);
 
-    result = virConnectCompareCPU(conn, args->xml, args->flags);
+    result = virConnectCompareCPU(priv->conn, args->xml, args->flags);
     if (result == VIR_CPU_COMPARE_ERROR) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6176,22 +5440,20 @@ remoteDispatchCpuCompare(struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchCpuBaseline(struct qemud_server *server ATTRIBUTE_UNUSED,
-                          struct qemud_client *client ATTRIBUTE_UNUSED,
-                          virConnectPtr conn,
-                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                          remote_error *err,
+remoteDispatchCpuBaseline(virNetServerPtr server ATTRIBUTE_UNUSED,
+                          virNetServerClientPtr client,
+                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                           remote_cpu_baseline_args *args,
                           remote_cpu_baseline_ret *ret)
 {
     char *cpu;
+    CHECK_CONN(client);
 
-    cpu = virConnectBaselineCPU(conn,
+    cpu = virConnectBaselineCPU(priv->conn,
                                 (const char **) args->xmlCPUs.xmlCPUs_val,
                                 args->xmlCPUs.xmlCPUs_len,
                                 args->flags);
     if (cpu == NULL) {
-        remoteDispatchConnError(err, conn);
         return -1;
     }
 
@@ -6202,26 +5464,23 @@ remoteDispatchCpuBaseline(struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchDomainGetJobInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
+remoteDispatchDomainGetJobInfo (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                 remote_domain_get_job_info_args *args,
                                 remote_domain_get_job_info_ret *ret)
 {
     virDomainPtr dom;
     virDomainJobInfo info;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainGetJobInfo (dom, &info) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6245,25 +5504,21 @@ remoteDispatchDomainGetJobInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchDomainAbortJob (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
-                              remote_domain_abort_job_args *args,
-                              void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainAbortJob (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              remote_domain_abort_job_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainAbortJob (dom) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6274,25 +5529,21 @@ remoteDispatchDomainAbortJob (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchDomainMigrateSetMaxDowntime(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                          struct qemud_client *client ATTRIBUTE_UNUSED,
-                                          virConnectPtr conn,
-                                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                          remote_error *rerr,
-                                          remote_domain_migrate_set_max_downtime_args *args,
-                                          void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainMigrateSetMaxDowntime(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                          virNetServerClientPtr client,
+                                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                          remote_domain_migrate_set_max_downtime_args *args)
 {
     virDomainPtr dom;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain(conn, args->dom);
+    dom = get_nonnull_domain(priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainMigrateSetMaxDowntime(dom, args->downtime, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6302,27 +5553,24 @@ remoteDispatchDomainMigrateSetMaxDowntime(struct qemud_server *server ATTRIBUTE_
 }
 
 static int
-remoteDispatchDomainSnapshotCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchDomainSnapshotCreateXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_domain_snapshot_create_xml_args *args,
                                        remote_domain_snapshot_create_xml_ret *ret)
 {
     virDomainSnapshotPtr snapshot;
     virDomainPtr domain;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->domain);
+    domain = get_nonnull_domain(priv->conn, args->domain);
     if (domain == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     snapshot = virDomainSnapshotCreateXML(domain, args->xml_desc, args->flags);
     if (snapshot == NULL) {
         virDomainFree(domain);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6335,19 +5583,18 @@ remoteDispatchDomainSnapshotCreateXml (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchDomainSnapshotDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                     struct qemud_client *client ATTRIBUTE_UNUSED,
-                                     virConnectPtr conn,
-                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                     remote_error *rerr,
+remoteDispatchDomainSnapshotDumpXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                      remote_domain_snapshot_dump_xml_args *args,
                                      remote_domain_snapshot_dump_xml_ret *ret)
 {
     virDomainPtr domain = NULL;
     virDomainSnapshotPtr snapshot = NULL;
     int rc = -1;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->snap.domain);
+    domain = get_nonnull_domain(priv->conn, args->snap.domain);
     if (domain == NULL)
         goto cleanup;
 
@@ -6367,33 +5614,28 @@ cleanup:
         virDomainSnapshotFree(snapshot);
     if (domain)
         virDomainFree(domain);
-    if (rc < 0)
-        remoteDispatchConnError(rerr, conn);
 
     return rc;
 }
 
 static int
-remoteDispatchDomainSnapshotNum (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchDomainSnapshotNum (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_domain_snapshot_num_args *args,
                                  remote_domain_snapshot_num_ret *ret)
 {
     virDomainPtr domain;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->domain);
+    domain = get_nonnull_domain(priv->conn, args->domain);
     if (domain == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     ret->num = virDomainSnapshotNum(domain, args->flags);
     if (ret->num == -1) {
         virDomainFree(domain);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6403,32 +5645,30 @@ remoteDispatchDomainSnapshotNum (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchDomainSnapshotListNames (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchDomainSnapshotListNames (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_domain_snapshot_list_names_args *args,
                                        remote_domain_snapshot_list_names_ret *ret)
 {
     virDomainPtr domain;
+    CHECK_CONN(client);
 
     if (args->nameslen > REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX) {
-        remoteDispatchFormatError (rerr, "%s",
-                                   _("nameslen > REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX"));
+        virNetError(VIR_ERR_RPC, "%s",
+                    _("nameslen > REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX"));
         return -1;
     }
 
-    domain = get_nonnull_domain(conn, args->domain);
+    domain = get_nonnull_domain(priv->conn, args->domain);
     if (domain == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->nameslen) < 0) {
+        virReportOOMError();
         virDomainFree(domain);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
@@ -6439,7 +5679,6 @@ remoteDispatchDomainSnapshotListNames (struct qemud_server *server ATTRIBUTE_UNU
     if (ret->names.names_len == -1) {
         virDomainFree(domain);
         VIR_FREE(ret->names.names_val);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6449,27 +5688,24 @@ remoteDispatchDomainSnapshotListNames (struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchDomainSnapshotLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                          struct qemud_client *client ATTRIBUTE_UNUSED,
-                                          virConnectPtr conn,
-                                          remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                          remote_error *rerr,
+remoteDispatchDomainSnapshotLookupByName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                          virNetServerClientPtr client,
+                                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                           remote_domain_snapshot_lookup_by_name_args *args,
                                           remote_domain_snapshot_lookup_by_name_ret *ret)
 {
     virDomainSnapshotPtr snapshot;
     virDomainPtr domain;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->domain);
+    domain = get_nonnull_domain(priv->conn, args->domain);
     if (domain == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     snapshot = virDomainSnapshotLookupByName(domain, args->name, args->flags);
     if (snapshot == NULL) {
         virDomainFree(domain);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6482,27 +5718,24 @@ remoteDispatchDomainSnapshotLookupByName (struct qemud_server *server ATTRIBUTE_
 }
 
 static int
-remoteDispatchDomainHasCurrentSnapshot(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr,
+remoteDispatchDomainHasCurrentSnapshot(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                        remote_domain_has_current_snapshot_args *args,
                                        remote_domain_has_current_snapshot_ret *ret)
 {
     virDomainPtr domain;
     int result;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->domain);
+    domain = get_nonnull_domain(priv->conn, args->domain);
     if (domain == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     result = virDomainHasCurrentSnapshot(domain, args->flags);
     if (result < 0) {
         virDomainFree(domain);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6514,27 +5747,24 @@ remoteDispatchDomainHasCurrentSnapshot(struct qemud_server *server ATTRIBUTE_UNU
 }
 
 static int
-remoteDispatchDomainSnapshotCurrent(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchDomainSnapshotCurrent(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_domain_snapshot_current_args *args,
                                     remote_domain_snapshot_current_ret *ret)
 {
     virDomainSnapshotPtr snapshot;
     virDomainPtr domain;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->domain);
+    domain = get_nonnull_domain(priv->conn, args->domain);
     if (domain == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     snapshot = virDomainSnapshotCurrent(domain, args->flags);
     if (snapshot == NULL) {
         virDomainFree(domain);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6547,19 +5777,17 @@ remoteDispatchDomainSnapshotCurrent(struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchDomainRevertToSnapshot (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                      struct qemud_client *client ATTRIBUTE_UNUSED,
-                                      virConnectPtr conn,
-                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                      remote_error *rerr,
-                                      remote_domain_revert_to_snapshot_args *args,
-                                      void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainRevertToSnapshot (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                      virNetServerClientPtr client,
+                                      virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                      remote_domain_revert_to_snapshot_args *args)
 {
     virDomainPtr domain = NULL;
     virDomainSnapshotPtr snapshot = NULL;
     int rc = -1;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->snap.domain);
+    domain = get_nonnull_domain(priv->conn, args->snap.domain);
     if (domain == NULL)
         goto cleanup;
 
@@ -6577,26 +5805,22 @@ cleanup:
         virDomainSnapshotFree(snapshot);
     if (domain)
         virDomainFree(domain);
-    if (rc < 0)
-        remoteDispatchConnError(rerr, conn);
 
     return rc;
 }
 
 static int
-remoteDispatchDomainSnapshotDelete (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
-                                    remote_domain_snapshot_delete_args *args,
-                                    void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainSnapshotDelete (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                    remote_domain_snapshot_delete_args *args)
 {
     virDomainPtr domain = NULL;
     virDomainSnapshotPtr snapshot = NULL;
     int rc = -1;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->snap.domain);
+    domain = get_nonnull_domain(priv->conn, args->snap.domain);
     if (domain == NULL)
         goto cleanup;
 
@@ -6614,100 +5838,99 @@ cleanup:
         virDomainSnapshotFree(snapshot);
     if (domain)
         virDomainFree(domain);
-    if (rc < 0)
-        remoteDispatchConnError(rerr, conn);
 
     return rc;
 }
 
 
 static int
-remoteDispatchDomainEventsRegisterAny (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                       struct qemud_client *client ATTRIBUTE_UNUSED,
-                                       virConnectPtr conn,
-                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                       remote_error *rerr ATTRIBUTE_UNUSED,
-                                       remote_domain_events_register_any_args *args,
-                                       void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainEventsRegisterAny (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                       virNetServerClientPtr client,
+                                       virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                       remote_domain_events_register_any_args *args)
 {
     CHECK_CONN(client);
     int callbackID;
 
     if (args->eventID >= VIR_DOMAIN_EVENT_ID_LAST ||
         args->eventID < 0) {
-        remoteDispatchFormatError(rerr, _("unsupported event ID %d"), args->eventID);
+        virNetError(VIR_ERR_RPC,
+                    _("unsupported event ID %d"), args->eventID);
         return -1;
     }
 
-    if (client->domainEventCallbackID[args->eventID] != -1)  {
-        remoteDispatchFormatError(rerr, _("domain event %d already registered"), args->eventID);
+    virMutexLock(&priv->lock);
+    if (priv->domainEventCallbackID[args->eventID] != -1)  {
+        virNetError(VIR_ERR_RPC,
+                    _("domain event %d already registered"), args->eventID);
+        virMutexUnlock(&priv->lock);
         return -1;
     }
 
-    if ((callbackID = virConnectDomainEventRegisterAny(conn,
+    if ((callbackID = virConnectDomainEventRegisterAny(priv->conn,
                                                        NULL,
                                                        args->eventID,
                                                        domainEventCallbacks[args->eventID],
                                                        client, NULL)) < 0) {
-        remoteDispatchConnError(rerr, conn);
+        virMutexUnlock(&priv->lock);
         return -1;
     }
 
-    client->domainEventCallbackID[args->eventID] = callbackID;
+    priv->domainEventCallbackID[args->eventID] = callbackID;
+    virMutexUnlock(&priv->lock);
 
     return 0;
 }
 
 
 static int
-remoteDispatchDomainEventsDeregisterAny (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                         struct qemud_client *client ATTRIBUTE_UNUSED,
-                                         virConnectPtr conn,
-                                         remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                         remote_error *rerr ATTRIBUTE_UNUSED,
-                                         remote_domain_events_deregister_any_args *args,
-                                         void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainEventsDeregisterAny (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                         virNetServerClientPtr client,
+                                         virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                         remote_domain_events_deregister_any_args *args)
 {
     CHECK_CONN(client);
     int callbackID = -1;
 
     if (args->eventID >= VIR_DOMAIN_EVENT_ID_LAST ||
         args->eventID < 0) {
-        remoteDispatchFormatError(rerr, _("unsupported event ID %d"), args->eventID);
+        virNetError(VIR_ERR_RPC,
+                    _("unsupported event ID %d"), args->eventID);
         return -1;
     }
 
-    callbackID = client->domainEventCallbackID[args->eventID];
+    virMutexLock(&priv->lock);
+    callbackID = priv->domainEventCallbackID[args->eventID];
     if (callbackID < 0) {
-        remoteDispatchFormatError(rerr, _("domain event %d not registered"), args->eventID);
+        virNetError(VIR_ERR_RPC,
+                    _("domain event %d not registered"), args->eventID);
+        virMutexUnlock(&priv->lock);
         return -1;
     }
 
-    if (virConnectDomainEventDeregisterAny(conn, callbackID) < 0) {
-        remoteDispatchConnError(rerr, conn);
+    if (virConnectDomainEventDeregisterAny(priv->conn, callbackID) < 0) {
         return -1;
     }
 
-    client->domainEventCallbackID[args->eventID] = -1;
+    priv->domainEventCallbackID[args->eventID] = -1;
+    virMutexUnlock(&priv->lock);
     return 0;
 }
 
 
 
 static int
-remoteDispatchNwfilterLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchNwfilterLookupByName (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_nwfilter_lookup_by_name_args *args,
                                     remote_nwfilter_lookup_by_name_ret *ret)
 {
     virNWFilterPtr nwfilter;
+    CHECK_CONN(client);
 
-    nwfilter = virNWFilterLookupByName (conn, args->name);
+    nwfilter = virNWFilterLookupByName (priv->conn, args->name);
     if (nwfilter == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6717,19 +5940,17 @@ remoteDispatchNwfilterLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED
 }
 
 static int
-remoteDispatchNwfilterLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                    struct qemud_client *client ATTRIBUTE_UNUSED,
-                                    virConnectPtr conn,
-                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                    remote_error *rerr,
+remoteDispatchNwfilterLookupByUuid (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                    virNetServerClientPtr client,
+                                    virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                     remote_nwfilter_lookup_by_uuid_args *args,
                                     remote_nwfilter_lookup_by_uuid_ret *ret)
 {
     virNWFilterPtr nwfilter;
+    CHECK_CONN(client);
 
-    nwfilter = virNWFilterLookupByUUID (conn, (unsigned char *) args->uuid);
+    nwfilter = virNWFilterLookupByUUID (priv->conn, (unsigned char *) args->uuid);
     if (nwfilter == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6740,19 +5961,17 @@ remoteDispatchNwfilterLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED
 
 
 static int
-remoteDispatchNwfilterDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                 struct qemud_client *client ATTRIBUTE_UNUSED,
-                                 virConnectPtr conn,
-                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                 remote_error *rerr,
+remoteDispatchNwfilterDefineXml (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                 virNetServerClientPtr client,
+                                 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                  remote_nwfilter_define_xml_args *args,
                                  remote_nwfilter_define_xml_ret *ret)
 {
     virNWFilterPtr nwfilter;
+    CHECK_CONN(client);
 
-    nwfilter = virNWFilterDefineXML (conn, args->xml);
+    nwfilter = virNWFilterDefineXML (priv->conn, args->xml);
     if (nwfilter == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6763,25 +5982,21 @@ remoteDispatchNwfilterDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNwfilterUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client ATTRIBUTE_UNUSED,
-                                virConnectPtr conn,
-                                remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                remote_error *rerr,
-                                remote_nwfilter_undefine_args *args,
-                                void *ret ATTRIBUTE_UNUSED)
+remoteDispatchNwfilterUndefine (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                remote_nwfilter_undefine_args *args)
 {
     virNWFilterPtr nwfilter;
+    CHECK_CONN(client);
 
-    nwfilter = get_nonnull_nwfilter (conn, args->nwfilter);
+    nwfilter = get_nonnull_nwfilter (priv->conn, args->nwfilter);
     if (nwfilter == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virNWFilterUndefine (nwfilter) == -1) {
         virNWFilterFree(nwfilter);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNWFilterFree(nwfilter);
@@ -6789,33 +6004,31 @@ remoteDispatchNwfilterUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchListNwfilters (struct qemud_server *server ATTRIBUTE_UNUSED,
-                             struct qemud_client *client ATTRIBUTE_UNUSED,
-                             virConnectPtr conn,
-                             remote_message_header *hdr ATTRIBUTE_UNUSED,
-                             remote_error *rerr,
+remoteDispatchListNwfilters (virNetServerPtr server ATTRIBUTE_UNUSED,
+                             virNetServerClientPtr client,
+                             virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                              remote_list_nwfilters_args *args,
                              remote_list_nwfilters_ret *ret)
 {
+    CHECK_CONN(client);
 
     if (args->maxnames > REMOTE_NWFILTER_NAME_LIST_MAX) {
-        remoteDispatchFormatError (rerr,
-                                   "%s", _("maxnames > REMOTE_NWFILTER_NAME_LIST_MAX"));
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("maxnames > REMOTE_NWFILTER_NAME_LIST_MAX"));
         return -1;
     }
 
     /* Allocate return buffer. */
     if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
-        remoteDispatchOOMError(rerr);
+        virReportOOMError();
         return -1;
     }
 
     ret->names.names_len =
-        virConnectListNWFilters (conn,
+        virConnectListNWFilters (priv->conn,
                                  ret->names.names_val, args->maxnames);
     if (ret->names.names_len == -1) {
         VIR_FREE(ret->names.names_len);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6824,19 +6037,17 @@ remoteDispatchListNwfilters (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNwfilterGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
-                              remote_nwfilter_get_xml_desc_args *args,
-                              remote_nwfilter_get_xml_desc_ret *ret)
+remoteDispatchNwfilterGetXmlDesc (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                                  remote_nwfilter_get_xml_desc_args *args,
+                                  remote_nwfilter_get_xml_desc_ret *ret)
 {
     virNWFilterPtr nwfilter;
+    CHECK_CONN(client);
 
-    nwfilter = get_nonnull_nwfilter (conn, args->nwfilter);
+    nwfilter = get_nonnull_nwfilter (priv->conn, args->nwfilter);
     if (nwfilter == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6844,7 +6055,6 @@ remoteDispatchNwfilterGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
     ret->xml = virNWFilterGetXMLDesc (nwfilter, args->flags);
     if (!ret->xml) {
         virNWFilterFree(nwfilter);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
     virNWFilterFree(nwfilter);
@@ -6853,18 +6063,15 @@ remoteDispatchNwfilterGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchNumOfNwfilters (struct qemud_server *server ATTRIBUTE_UNUSED,
-                              struct qemud_client *client ATTRIBUTE_UNUSED,
-                              virConnectPtr conn,
-                              remote_message_header *hdr ATTRIBUTE_UNUSED,
-                              remote_error *rerr,
-                              void *args ATTRIBUTE_UNUSED,
+remoteDispatchNumOfNwfilters (virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                               remote_num_of_nwfilters_ret *ret)
 {
+    CHECK_CONN(client);
 
-    ret->num = virConnectNumOfNWFilters (conn);
+    ret->num = virConnectNumOfNWFilters (priv->conn);
     if (ret->num == -1) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6873,26 +6080,23 @@ remoteDispatchNumOfNwfilters (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchDomainGetBlockInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
-                                  struct qemud_client *client ATTRIBUTE_UNUSED,
-                                  virConnectPtr conn,
-                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
-                                  remote_error *rerr,
+remoteDispatchDomainGetBlockInfo (virNetServerPtr server ATTRIBUTE_UNUSED,
+                                  virNetServerClientPtr client,
+                                  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                                   remote_domain_get_block_info_args *args,
                                   remote_domain_get_block_info_ret *ret)
 {
     virDomainPtr dom;
     virDomainBlockInfo info;
+    CHECK_CONN(client);
 
-    dom = get_nonnull_domain (conn, args->dom);
+    dom = get_nonnull_domain (priv->conn, args->dom);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainGetBlockInfo (dom, args->path, &info, args->flags) == -1) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6906,26 +6110,23 @@ remoteDispatchDomainGetBlockInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 static int
-qemuDispatchMonitorCommand (struct qemud_server *server ATTRIBUTE_UNUSED,
-                            struct qemud_client *client ATTRIBUTE_UNUSED,
-                            virConnectPtr conn,
-                            remote_message_header *hdr ATTRIBUTE_UNUSED,
-                            remote_error *rerr,
+qemuDispatchMonitorCommand (virNetServerPtr server ATTRIBUTE_UNUSED,
+                            virNetServerClientPtr client,
+                            virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                             qemu_monitor_command_args *args,
                             qemu_monitor_command_ret *ret)
 {
     virDomainPtr domain;
+    CHECK_CONN(client);
 
-    domain = get_nonnull_domain(conn, args->domain);
+    domain = get_nonnull_domain(priv->conn, args->domain);
     if (domain == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
     if (virDomainQemuMonitorCommand(domain, args->cmd, &ret->result,
                                     args->flags) == -1) {
         virDomainFree(domain);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -6936,49 +6137,49 @@ qemuDispatchMonitorCommand (struct qemud_server *server ATTRIBUTE_UNUSED,
 
 
 static int
-remoteDispatchDomainOpenConsole(struct qemud_server *server ATTRIBUTE_UNUSED,
-                                struct qemud_client *client,
-                                virConnectPtr conn,
-                                remote_message_header *hdr,
-                                remote_error *rerr,
-                                remote_domain_open_console_args *args,
-                                void *ret ATTRIBUTE_UNUSED)
+remoteDispatchDomainOpenConsole(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                virNetServerClientPtr client,
+                                virNetMessageHeaderPtr hdr,
+                                remote_domain_open_console_args *args)
 {
     int r;
-    struct qemud_client_stream *stream;
+    daemonClientStreamPtr stream;
     virDomainPtr dom;
+    virStreamPtr st;
 
     CHECK_CONN (client);
 
-    dom = get_nonnull_domain (conn, args->domain);
+    dom = get_nonnull_domain (priv->conn, args->domain);
     if (dom == NULL) {
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
-    stream = remoteCreateClientStream(conn, hdr);
+    st = virStreamNew(priv->conn, VIR_STREAM_NONBLOCK);
+    if (!st) {
+        return -1;
+    }
+
+    stream = daemonCreateClientStream(client, st, remoteProgram, hdr);
     if (!stream) {
+        virStreamFree(st);
         virDomainFree(dom);
-        remoteDispatchOOMError(rerr);
         return -1;
     }
 
     r = virDomainOpenConsole(dom,
                              args->devname ? *args->devname : NULL,
-                             stream->st,
+                             st,
                              args->flags);
     if (r == -1) {
         virDomainFree(dom);
-        remoteFreeClientStream(client, stream);
-        remoteDispatchConnError(rerr, conn);
+        daemonFreeClientStream(client, stream);
         return -1;
     }
 
-    if (remoteAddClientStream(client, stream, 1) < 0) {
+    if (daemonAddClientStream(client, stream, 1) < 0) {
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
-        virStreamAbort(stream->st);
-        remoteFreeClientStream(client, stream);
+        virStreamAbort(st);
+        daemonFreeClientStream(client, stream);
         return -1;
     }
 
@@ -7117,3 +6318,4 @@ make_nonnull_domain_snapshot (remote_nonnull_domain_snapshot *snapshot_dst, virD
     snapshot_dst->name = strdup(snapshot_src->name);
     make_nonnull_domain(&snapshot_dst->domain, snapshot_src->domain);
 }
+
diff --git a/daemon/remote.h b/daemon/remote.h
index 1eb8386..c9bf5d7 100644
--- a/daemon/remote.h
+++ b/daemon/remote.h
@@ -24,62 +24,20 @@
 #ifndef __LIBVIRTD_REMOTE_H__
 # define __LIBVIRTD_REMOTE_H__
 
+# include "remote_protocol.h"
+# include "rpc/virnetserverprogram.h"
+# include "rpc/virnetserverclient.h"
 
-# include "libvirtd.h"
 
-typedef union {
-# include "remote_dispatch_args.h"
-} dispatch_args;
-verify(sizeof(dispatch_args) > 0);
-
-typedef union {
-# include "remote_dispatch_ret.h"
-} dispatch_ret;
-verify(sizeof(dispatch_ret) > 0);
-
-typedef union {
-# include "qemu_dispatch_args.h"
-} qemu_dispatch_args;
-verify(sizeof(qemu_dispatch_args) > 0);
-
-typedef union {
-# include "qemu_dispatch_ret.h"
-} qemu_dispatch_ret;
-verify(sizeof(qemu_dispatch_ret) > 0);
-
-
-
-/**
- * When the RPC handler is called:
- *
- *  - Server object is unlocked
- *  - Client object is unlocked
- *
- * Both must be locked before use. Server lock must
- * be held before attempting to lock client.
- *
- * Without any locking, it is safe to use:
- *
- *   'conn', 'rerr', 'args and 'ret'
- */
-typedef int (*dispatch_fn) (struct qemud_server *server,
-                            struct qemud_client *client,
-                            virConnectPtr conn,
-                            remote_message_header *hdr,
-                            remote_error *err,
-                            dispatch_args *args,
-                            dispatch_ret *ret);
-
-typedef struct {
-    dispatch_fn fn;
-    xdrproc_t args_filter;
-    xdrproc_t ret_filter;
-} dispatch_data;
-
-
-const dispatch_data const *remoteGetDispatchData(int proc);
-const dispatch_data const *qemuGetDispatchData(int proc);
+extern virNetServerProgramProc remoteProcs[];
+extern size_t remoteNProcs;
+extern virNetServerProgramErrorHander remoteErr;
 
+extern virNetServerProgramProc qemuProcs[];
+extern size_t qemuNProcs;
+extern virNetServerProgramErrorHander qemuErr;
 
+int remoteClientInitHook(virNetServerPtr srv,
+                         virNetServerClientPtr client);
 
 #endif /* __LIBVIRTD_REMOTE_H__ */
diff --git a/daemon/stream.c b/daemon/stream.c
index cac54ea..a946026 100644
--- a/daemon/stream.c
+++ b/daemon/stream.c
@@ -24,29 +24,56 @@
 #include <config.h>
 
 #include "stream.h"
+#include "remote.h"
 #include "memory.h"
-#include "dispatch.h"
 #include "logging.h"
+#include "virnetserverclient.h"
+#include "virterror_internal.h"
+
+#define virNetError(code, ...)                                    \
+    virReportErrorHelper(NULL, VIR_FROM_RPC, code, __FILE__,      \
+                         __FUNCTION__, __LINE__, __VA_ARGS__)
+
+struct daemonClientStream {
+    daemonClientPrivatePtr priv;
+
+    virNetServerProgramPtr prog;
+
+    virStreamPtr st;
+    int procedure;
+    int serial;
+
+    unsigned int recvEOF : 1;
+    unsigned int closed : 1;
+
+    int filterID;
+
+    virNetMessagePtr rx;
+    int tx;
+
+    daemonClientStreamPtr next;
+};
+
 
 static int
-remoteStreamHandleWrite(struct qemud_client *client,
-                        struct qemud_client_stream *stream);
+daemonStreamHandleWrite(virNetServerClientPtr client,
+                        daemonClientStream *stream);
 static int
-remoteStreamHandleRead(struct qemud_client *client,
-                       struct qemud_client_stream *stream);
+daemonStreamHandleRead(virNetServerClientPtr client,
+                       daemonClientStream *stream);
 static int
-remoteStreamHandleFinish(struct qemud_client *client,
-                         struct qemud_client_stream *stream,
-                         struct qemud_client_message *msg);
+daemonStreamHandleFinish(virNetServerClientPtr client,
+                         daemonClientStream *stream,
+                         virNetMessagePtr msg);
 static int
-remoteStreamHandleAbort(struct qemud_client *client,
-                        struct qemud_client_stream *stream,
-                        struct qemud_client_message *msg);
+daemonStreamHandleAbort(virNetServerClientPtr client,
+                        daemonClientStream *stream,
+                        virNetMessagePtr msg);
 
 
 
 static void
-remoteStreamUpdateEvents(struct qemud_client_stream *stream)
+daemonStreamUpdateEvents(daemonClientStream *stream)
 {
     int newEvents = 0;
     if (stream->rx)
@@ -62,19 +89,15 @@ remoteStreamUpdateEvents(struct qemud_client_stream *stream)
  * Callback that gets invoked when a stream becomes writable/readable
  */
 static void
-remoteStreamEvent(virStreamPtr st, int events, void *opaque)
+daemonStreamEvent(virStreamPtr st, int events, void *opaque)
 {
-    struct qemud_client *client = opaque;
-    struct qemud_client_stream *stream;
+    virNetServerClientPtr client = opaque;
+    daemonClientStream *stream;
+    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
 
-    /* XXX sub-optimal - we really should be taking the server lock
-     * first, but we have no handle to the server object
-     * We're lucky to get away with it for now, due to this callback
-     * executing in the main thread, but this should really be fixed
-     */
-    virMutexLock(&client->lock);
+    virMutexLock(&priv->lock);
 
-    stream = remoteFindClientStream(client, st);
+    stream = daemonFindClientStream(client, st);
 
     if (!stream) {
         VIR_WARN("event for client=%p stream st=%p, but missing stream state", client, st);
@@ -85,9 +108,9 @@ remoteStreamEvent(virStreamPtr st, int events, void *opaque)
     DEBUG("st=%p events=%d", st, events);
 
     if (events & VIR_STREAM_EVENT_WRITABLE) {
-        if (remoteStreamHandleWrite(client, stream) < 0) {
-            remoteRemoveClientStream(client, stream);
-            qemudDispatchClientFailure(client);
+        if (daemonStreamHandleWrite(client, stream) < 0) {
+            daemonRemoveClientStream(client, stream);
+            virNetServerClientClose(client);
             goto cleanup;
         }
     }
@@ -95,9 +118,9 @@ remoteStreamEvent(virStreamPtr st, int events, void *opaque)
     if (!stream->recvEOF &&
         (events & (VIR_STREAM_EVENT_READABLE | VIR_STREAM_EVENT_HANGUP))) {
         events = events & ~(VIR_STREAM_EVENT_READABLE | VIR_STREAM_EVENT_HANGUP);
-        if (remoteStreamHandleRead(client, stream) < 0) {
-            remoteRemoveClientStream(client, stream);
-            qemudDispatchClientFailure(client);
+        if (daemonStreamHandleRead(client, stream) < 0) {
+            daemonRemoveClientStream(client, stream);
+            virNetServerClientClose(client);
             goto cleanup;
         }
     }
@@ -105,30 +128,41 @@ remoteStreamEvent(virStreamPtr st, int events, void *opaque)
     if (!stream->closed &&
         (events & (VIR_STREAM_EVENT_ERROR | VIR_STREAM_EVENT_HANGUP))) {
         int ret;
-        remote_error rerr;
-        memset(&rerr, 0, sizeof rerr);
+        virNetMessagePtr msg;
         stream->closed = 1;
         virStreamEventRemoveCallback(stream->st);
         virStreamAbort(stream->st);
         if (events & VIR_STREAM_EVENT_HANGUP)
-            remoteDispatchFormatError(&rerr, "%s", _("stream had unexpected termination"));
+            virNetError(VIR_ERR_RPC,
+                        "%s", _("stream had unexpected termination"));
         else
-            remoteDispatchFormatError(&rerr, "%s", _("stream had I/O failure"));
-        ret = remoteSerializeStreamError(client, &rerr, stream->procedure, stream->serial);
-        remoteRemoveClientStream(client, stream);
+            virNetError(VIR_ERR_RPC,
+                        "%s", _("stream had I/O failure"));
+
+        msg = virNetMessageNew();
+        if (!msg) {
+            ret = -1;
+        } else {
+            ret = virNetServerProgramSendStreamError(remoteProgram,
+                                                     client,
+                                                     msg,
+                                                     stream->procedure,
+                                                     stream->serial);
+        }
+        daemonRemoveClientStream(client, stream);
         if (ret < 0)
-            qemudDispatchClientFailure(client);
+            virNetServerClientClose(client);
         goto cleanup;
     }
 
     if (stream->closed) {
-        remoteRemoveClientStream(client, stream);
+        daemonRemoveClientStream(client, stream);
     } else {
-        remoteStreamUpdateEvents(stream);
+        daemonStreamUpdateEvents(stream);
     }
 
 cleanup:
-    virMutexUnlock(&client->lock);
+    virMutexUnlock(&priv->lock);
 }
 
 
@@ -141,88 +175,68 @@ cleanup:
  * -1 on fatal client error
  */
 static int
-remoteStreamFilter(struct qemud_client *client,
-                   struct qemud_client_message *msg, void *opaque)
+daemonStreamFilter(virNetServerClientPtr client ATTRIBUTE_UNUSED,
+                   virNetMessagePtr msg,
+                   void *opaque)
 {
-    struct qemud_client_stream *stream = opaque;
-
-    if (msg->hdr.serial == stream->serial &&
-        msg->hdr.proc == stream->procedure &&
-        msg->hdr.type == REMOTE_STREAM) {
-        DEBUG("Incoming rx=%p serial=%d proc=%d status=%d",
-              stream->rx, msg->hdr.proc, msg->hdr.serial, msg->hdr.status);
-
-        /* If there are queued packets, we need to queue all further
-         * messages, since they must be processed strictly in order.
-         * If there are no queued packets, then OK/ERROR messages
-         * should be processed immediately. Data packets are still
-         * queued to only be processed when the stream is marked as
-         * writable.
-         */
-        if (stream->rx) {
-            qemudClientMessageQueuePush(&stream->rx, msg);
-            remoteStreamUpdateEvents(stream);
-        } else {
-            int ret = 0;
-            switch (msg->hdr.status) {
-            case REMOTE_OK:
-                ret = remoteStreamHandleFinish(client, stream, msg);
-                if (ret == 0)
-                    qemudClientMessageRelease(client, msg);
-                break;
-
-            case REMOTE_CONTINUE:
-                qemudClientMessageQueuePush(&stream->rx, msg);
-                remoteStreamUpdateEvents(stream);
-                break;
-
-            case REMOTE_ERROR:
-            default:
-                ret = remoteStreamHandleAbort(client, stream, msg);
-                if (ret == 0)
-                    qemudClientMessageRelease(client, msg);
-                break;
-            }
-
-            if (ret < 0)
-                return -1;
-        }
-        return 1;
-    }
-    return 0;
+    daemonClientStream *stream = opaque;
+    int ret = 0;
+
+    virMutexLock(&stream->priv->lock);
+
+    if (msg->header.type != VIR_NET_STREAM)
+        goto cleanup;
+
+    if (!virNetServerProgramMatches(stream->prog, msg))
+        goto cleanup;
+
+    if (msg->header.proc != stream->procedure ||
+        msg->header.serial != stream->serial)
+        goto cleanup;
+
+    DEBUG("Incoming rx=%p serial=%d proc=%d status=%d",
+          stream->rx, msg->header.proc, msg->header.serial, msg->header.status);
+
+    virNetMessageQueuePush(&stream->rx, msg);
+    daemonStreamUpdateEvents(stream);
+    ret = 1;
+
+cleanup:
+    virMutexUnlock(&stream->priv->lock);
+    return ret;
 }
 
 
 /*
  * @conn: a connection object to associate the stream with
- * @hdr: the method call to associate with the stram
+ * @header: the method call to associate with the stram
  *
  * Creates a new stream for this conn
  *
  * Returns a new stream object, or NULL upon OOM
  */
-struct qemud_client_stream *
-remoteCreateClientStream(virConnectPtr conn,
-                         remote_message_header *hdr)
+daemonClientStream *
+daemonCreateClientStream(virNetServerClientPtr client,
+                         virStreamPtr st,
+                         virNetServerProgramPtr prog,
+                         virNetMessageHeaderPtr header)
 {
-    struct qemud_client_stream *stream;
+    daemonClientStream *stream;
+    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
 
-    DEBUG("proc=%d serial=%d", hdr->proc, hdr->serial);
+    DEBUG("proc=%d serial=%d", header->proc, header->serial);
 
     if (VIR_ALLOC(stream) < 0)
         return NULL;
 
-    stream->procedure = hdr->proc;
-    stream->serial = hdr->serial;
-
-    stream->st = virStreamNew(conn, VIR_STREAM_NONBLOCK);
-    if (!stream->st) {
-        VIR_FREE(stream);
-        return NULL;
-    }
+    stream->priv = priv;
+    stream->prog = prog;
+    stream->procedure = header->proc;
+    stream->serial = header->serial;
+    stream->filterID = -1;
+    stream->st = st;
 
-    stream->filter.query = remoteStreamFilter;
-    stream->filter.opaque = stream;
+    virNetServerProgramRef(prog);
 
     return stream;
 }
@@ -233,25 +247,36 @@ remoteCreateClientStream(virConnectPtr conn,
  * Frees the memory associated with this inactive client
  * stream
  */
-void remoteFreeClientStream(struct qemud_client *client,
-                            struct qemud_client_stream *stream)
+int daemonFreeClientStream(virNetServerClientPtr client,
+                           daemonClientStream *stream)
 {
-    struct qemud_client_message *msg;
+    virNetMessagePtr msg;
+    int ret = 0;
 
     if (!stream)
-        return;
+        return 0;
 
     DEBUG("proc=%d serial=%d", stream->procedure, stream->serial);
 
+    virNetServerProgramFree(stream->prog);
+
     msg = stream->rx;
     while (msg) {
-        struct qemud_client_message *tmp = msg->next;
-        qemudClientMessageRelease(client, msg);
+        virNetMessagePtr tmp = msg->next;
+        /* Send a dummy reply to free up 'msg' & unblock client rx */
+        memset(msg, 0, sizeof(*msg));
+        if (virNetServerClientSendMessage(client, msg) < 0) {
+            virNetServerClientMarkClose(client);
+            virNetMessageFree(msg);
+            ret = -1;
+        }
         msg = tmp;
     }
 
     virStreamFree(stream->st);
     VIR_FREE(stream);
+
+    return ret;
 }
 
 
@@ -259,33 +284,32 @@ void remoteFreeClientStream(struct qemud_client *client,
  * @client: a locked client to add the stream to
  * @stream: a stream to add
  */
-int remoteAddClientStream(struct qemud_client *client,
-                          struct qemud_client_stream *stream,
+int daemonAddClientStream(virNetServerClientPtr client,
+                          daemonClientStream *stream,
                           int transmit)
 {
-    struct qemud_client_stream *tmp = client->streams;
-
     DEBUG("client=%p proc=%d serial=%d", client, stream->procedure, stream->serial);
 
+    if (stream->filterID != -1) {
+        VIR_WARN("Filter already added to client %p", client);
+        return -1;
+    }
+
     if (virStreamEventAddCallback(stream->st, 0,
-                                  remoteStreamEvent, client, NULL) < 0)
+                                  daemonStreamEvent, client, NULL) < 0)
         return -1;
 
-    if (tmp) {
-        while (tmp->next)
-            tmp = tmp->next;
-        tmp->next = stream;
-    } else {
-        client->streams = stream;
+    if ((stream->filterID = virNetServerClientAddFilter(client,
+                                                        daemonStreamFilter,
+                                                        stream)) < 0) {
+        virStreamEventRemoveCallback(stream->st);
+        return -1;
     }
 
-    stream->filter.next = client->filters;
-    client->filters = &stream->filter;
-
     if (transmit)
         stream->tx = 1;
 
-    remoteStreamUpdateEvents(stream);
+    daemonStreamUpdateEvents(stream);
 
     return 0;
 }
@@ -300,11 +324,12 @@ int remoteAddClientStream(struct qemud_client *client,
  *
  * Returns a stream object matching the procedure+serial number, or NULL
  */
-struct qemud_client_stream *
-remoteFindClientStream(struct qemud_client *client,
+daemonClientStream *
+daemonFindClientStream(virNetServerClientPtr client,
                        virStreamPtr st)
 {
-    struct qemud_client_stream *stream = client->streams;
+    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
+    daemonClientStream *stream = priv->streams;
 
     while (stream) {
         if (stream->st == st)
@@ -325,25 +350,18 @@ remoteFindClientStream(struct qemud_client *client,
  * Returns 0 if the stream was removd, -1 if it doesn't exist
  */
 int
-remoteRemoveClientStream(struct qemud_client *client,
-                         struct qemud_client_stream *stream)
+daemonRemoveClientStream(virNetServerClientPtr client,
+                         daemonClientStream *stream)
 {
     DEBUG("client=%p proc=%d serial=%d", client, stream->procedure, stream->serial);
-
-    struct qemud_client_stream *curr = client->streams;
-    struct qemud_client_stream *prev = NULL;
-    struct qemud_client_filter *filter = NULL;
-
-    if (client->filters == &stream->filter) {
-        client->filters = client->filters->next;
-    } else {
-        filter = client->filters;
-        while (filter) {
-            if (filter->next == &stream->filter) {
-                filter->next = filter->next->next;
-                break;
-            }
-        }
+    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
+    daemonClientStream *curr = priv->streams;
+    daemonClientStream *prev = NULL;
+
+    if (stream->filterID != -1) {
+        virNetServerClientRemoveFilter(client,
+                                       stream->filterID);
+        stream->filterID = -1;
     }
 
     if (!stream->closed) {
@@ -356,9 +374,8 @@ remoteRemoveClientStream(struct qemud_client *client,
             if (prev)
                 prev->next = curr->next;
             else
-                client->streams = curr->next;
-            remoteFreeClientStream(client, stream);
-            return 0;
+                priv->streams = curr->next;
+            return daemonFreeClientStream(client, stream);
         }
         prev = curr;
         curr = curr->next;
@@ -374,17 +391,15 @@ remoteRemoveClientStream(struct qemud_client *client,
  *    1  if message is still being processed
  */
 static int
-remoteStreamHandleWriteData(struct qemud_client *client,
-                            struct qemud_client_stream *stream,
-                            struct qemud_client_message *msg)
+daemonStreamHandleWriteData(virNetServerClientPtr client,
+                            daemonClientStream *stream,
+                            virNetMessagePtr msg)
 {
-    remote_error rerr;
     int ret;
 
-    DEBUG("stream=%p proc=%d serial=%d len=%d offset=%d",
-          stream, msg->hdr.proc, msg->hdr.serial, msg->bufferLength, msg->bufferOffset);
-
-    memset(&rerr, 0, sizeof rerr);
+    DEBUG("stream=%p proc=%d serial=%d len=%zu offset=%zu",
+          stream, msg->header.proc, msg->header.serial,
+          msg->bufferLength, msg->bufferOffset);
 
     ret = virStreamSend(stream->st,
                         msg->buffer + msg->bufferOffset,
@@ -396,14 +411,20 @@ remoteStreamHandleWriteData(struct qemud_client *client,
         /* Partial write, so indicate we have more todo later */
         if (msg->bufferOffset < msg->bufferLength)
             return 1;
+
+        /* A dummy 'send' just to free up 'msg' object */
+        memset(msg, 0, sizeof(*msg));
+        return virNetServerClientSendMessage(client, msg);
     } else if (ret == -2) {
         /* Blocking, so indicate we have more todo later */
         return 1;
     } else {
         VIR_INFO0("Stream send failed");
         stream->closed = 1;
-        remoteDispatchConnError(&rerr, client->conn);
-        return remoteSerializeReplyError(client, &rerr, &msg->hdr);
+        return virNetServerProgramSendReplyError(stream->prog,
+                                                 client,
+                                                 msg,
+                                                 &msg->header);
     }
 
     return 0;
@@ -413,38 +434,39 @@ remoteStreamHandleWriteData(struct qemud_client *client,
 /*
  * Process an finish handshake from the client.
  *
- * Returns a REMOTE_OK confirmation if successful, or a REMOTE_ERROR
+ * Returns a VIR_NET_OK confirmation if successful, or a VIR_NET_ERROR
  * if there was a stream error
  *
  * Returns 0 if successfully sent RPC reply, -1 upon fatal error
  */
 static int
-remoteStreamHandleFinish(struct qemud_client *client,
-                         struct qemud_client_stream *stream,
-                         struct qemud_client_message *msg)
+daemonStreamHandleFinish(virNetServerClientPtr client,
+                         daemonClientStream *stream,
+                         virNetMessagePtr msg)
 {
-    remote_error rerr;
     int ret;
 
     DEBUG("stream=%p proc=%d serial=%d",
-          stream, msg->hdr.proc, msg->hdr.serial);
-
-    memset(&rerr, 0, sizeof rerr);
+          stream, msg->header.proc, msg->header.serial);
 
     stream->closed = 1;
     virStreamEventRemoveCallback(stream->st);
     ret = virStreamFinish(stream->st);
 
     if (ret < 0) {
-        remoteDispatchConnError(&rerr, client->conn);
-        return remoteSerializeReplyError(client, &rerr, &msg->hdr);
+        return virNetServerProgramSendReplyError(stream->prog,
+                                                 client,
+                                                 msg,
+                                                 &msg->header);
     } else {
         /* Send zero-length confirm */
-        if (remoteSendStreamData(client, stream, NULL, 0) < 0)
-            return -1;
+        return virNetServerProgramSendStreamData(stream->prog,
+                                                 client,
+                                                 msg,
+                                                 stream->procedure,
+                                                 stream->serial,
+                                                 NULL, 0);
     }
-
-    return 0;
 }
 
 
@@ -454,30 +476,31 @@ remoteStreamHandleFinish(struct qemud_client *client,
  * Returns 0 if successfully aborted, -1 upon error
  */
 static int
-remoteStreamHandleAbort(struct qemud_client *client,
-                        struct qemud_client_stream *stream,
-                        struct qemud_client_message *msg)
+daemonStreamHandleAbort(virNetServerClientPtr client,
+                        daemonClientStream *stream,
+                        virNetMessagePtr msg)
 {
-    remote_error rerr;
-
     DEBUG("stream=%p proc=%d serial=%d",
-          stream, msg->hdr.proc, msg->hdr.serial);
-
-    memset(&rerr, 0, sizeof rerr);
+          stream, msg->header.proc, msg->header.serial);
 
     stream->closed = 1;
     virStreamEventRemoveCallback(stream->st);
     virStreamAbort(stream->st);
 
-    if (msg->hdr.status == REMOTE_ERROR)
-        remoteDispatchFormatError(&rerr, "%s", _("stream aborted at client request"));
+    if (msg->header.status == VIR_NET_ERROR)
+        virNetError(VIR_ERR_RPC,
+                    "%s", _("stream aborted at client request"));
     else {
-        VIR_WARN("unexpected stream status %d", msg->hdr.status);
-        remoteDispatchFormatError(&rerr, _("stream aborted with unexpected status %d"),
-                                  msg->hdr.status);
+        VIR_WARN("unexpected stream status %d", msg->header.status);
+        virNetError(VIR_ERR_RPC,
+                    _("stream aborted with unexpected status %d"),
+                    msg->header.status);
     }
 
-    return remoteSerializeReplyError(client, &rerr, &msg->hdr);
+    return virNetServerProgramSendReplyError(remoteProgram,
+                                             client,
+                                             msg,
+                                             &msg->header);
 }
 
 
@@ -490,41 +513,39 @@ remoteStreamHandleAbort(struct qemud_client *client,
  * Returns 0 on success, or -1 upon fatal error
  */
 static int
-remoteStreamHandleWrite(struct qemud_client *client,
-                        struct qemud_client_stream *stream)
+daemonStreamHandleWrite(virNetServerClientPtr client,
+                        daemonClientStream *stream)
 {
-    struct qemud_client_message *msg, *tmp;
-
     DEBUG("stream=%p", stream);
 
-    msg = stream->rx;
-    while (msg && !stream->closed) {
+    while (stream->rx && !stream->closed) {
+        virNetMessagePtr msg = stream->rx;
         int ret;
-        switch (msg->hdr.status) {
-        case REMOTE_OK:
-            ret = remoteStreamHandleFinish(client, stream, msg);
+
+        switch (msg->header.status) {
+        case VIR_NET_OK:
+            ret = daemonStreamHandleFinish(client, stream, msg);
             break;
 
-        case REMOTE_CONTINUE:
-            ret = remoteStreamHandleWriteData(client, stream, msg);
+        case VIR_NET_CONTINUE:
+            ret = daemonStreamHandleWriteData(client, stream, msg);
             break;
 
-        case REMOTE_ERROR:
+        case VIR_NET_ERROR:
         default:
-            ret = remoteStreamHandleAbort(client, stream, msg);
+            ret = daemonStreamHandleAbort(client, stream, msg);
             break;
         }
 
-        if (ret == 0)
-            qemudClientMessageQueueServe(&stream->rx);
-        else if (ret < 0)
-            return -1;
-        else
-            break; /* still processing data */
+        if (ret > 0)
+            break;  /* still processing data from msg */
 
-        tmp = msg->next;
-        qemudClientMessageRelease(client, msg);
-        msg = tmp;
+        virNetMessageQueueServe(&stream->rx);
+        if (ret < 0) {
+            virNetMessageFree(msg);
+            virNetServerClientMarkClose(client);
+            return -1;
+        }
     }
 
     return 0;
@@ -543,11 +564,11 @@ remoteStreamHandleWrite(struct qemud_client *client,
  * be killed
  */
 static int
-remoteStreamHandleRead(struct qemud_client *client,
-                       struct qemud_client_stream *stream)
+daemonStreamHandleRead(virNetServerClientPtr client,
+                       daemonClientStream *stream)
 {
     char *buffer;
-    size_t bufferLen = REMOTE_MESSAGE_PAYLOAD_MAX;
+    size_t bufferLen = VIR_NET_MESSAGE_PAYLOAD_MAX;
     int ret;
 
     DEBUG("stream=%p", stream);
@@ -566,16 +587,29 @@ remoteStreamHandleRead(struct qemud_client *client,
          * we're readable, but hey things change... */
         ret = 0;
     } else if (ret < 0) {
-        remote_error rerr;
-        memset(&rerr, 0, sizeof rerr);
-        remoteDispatchConnError(&rerr, NULL);
-
-        ret = remoteSerializeStreamError(client, &rerr, stream->procedure, stream->serial);
+        virNetMessagePtr msg;
+        if (!(msg = virNetMessageNew()))
+            ret = -1;
+        else
+            ret = virNetServerProgramSendStreamError(remoteProgram,
+                                                     client,
+                                                     msg,
+                                                     stream->procedure,
+                                                     stream->serial);
     } else {
+        virNetMessagePtr msg;
         stream->tx = 0;
         if (ret == 0)
             stream->recvEOF = 1;
-        ret = remoteSendStreamData(client, stream, buffer, ret);
+        if (!(msg = virNetMessageNew()))
+            ret = -1;
+        else
+            ret = virNetServerProgramSendStreamData(remoteProgram,
+                                                    client,
+                                                    msg,
+                                                    stream->procedure,
+                                                    stream->serial,
+                                                    buffer, ret);
     }
 
     VIR_FREE(buffer);
@@ -591,22 +625,23 @@ remoteStreamHandleRead(struct qemud_client *client,
  * fast stream, but slow client
  */
 void
-remoteStreamMessageFinished(struct qemud_client *client,
-                            struct qemud_client_message *msg)
+daemonStreamMessageFinished(virNetServerClientPtr client,
+                            virNetMessagePtr msg)
 {
-    struct qemud_client_stream *stream = client->streams;
+    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
+    daemonClientStream *stream = priv->streams;
 
     while (stream) {
-        if (msg->hdr.proc == stream->procedure &&
-            msg->hdr.serial == stream->serial)
+        if (msg->header.proc == stream->procedure &&
+            msg->header.serial == stream->serial)
             break;
         stream = stream->next;
     }
 
-    DEBUG("Message client=%p stream=%p proc=%d serial=%d", client, stream, msg->hdr.proc, msg->hdr.serial);
+    DEBUG("Message client=%p stream=%p proc=%d serial=%d", client, stream, msg->header.proc, msg->header.serial);
 
     if (stream) {
         stream->tx = 1;
-        remoteStreamUpdateEvents(stream);
+        daemonStreamUpdateEvents(stream);
     }
 }
diff --git a/daemon/stream.h b/daemon/stream.h
index 767a763..3855c89 100644
--- a/daemon/stream.h
+++ b/daemon/stream.h
@@ -28,27 +28,29 @@
 
 
 
-struct qemud_client_stream *
-remoteCreateClientStream(virConnectPtr conn,
-                         remote_message_header *hdr);
+daemonClientStream *
+daemonCreateClientStream(virNetServerClientPtr client,
+                         virStreamPtr st,
+                         virNetServerProgramPtr prog,
+                         virNetMessageHeaderPtr hdr);
 
-void remoteFreeClientStream(struct qemud_client *client,
-                            struct qemud_client_stream *stream);
+int daemonFreeClientStream(virNetServerClientPtr client,
+                           daemonClientStream *stream);
 
-int remoteAddClientStream(struct qemud_client *client,
-                          struct qemud_client_stream *stream,
+int daemonAddClientStream(virNetServerClientPtr client,
+                          daemonClientStream *stream,
                           int transmit);
 
-struct qemud_client_stream *
-remoteFindClientStream(struct qemud_client *client,
+daemonClientStream *
+daemonFindClientStream(virNetServerClientPtr client,
                        virStreamPtr stream);
 
 int
-remoteRemoveClientStream(struct qemud_client *client,
-                         struct qemud_client_stream *stream);
+daemonRemoveClientStream(virNetServerClientPtr client,
+                         daemonClientStream *stream);
 
 void
-remoteStreamMessageFinished(struct qemud_client *client,
-                            struct qemud_client_message *msg);
+daemonStreamMessageFinished(virNetServerClientPtr client,
+                            virNetMessagePtr msg);
 
 #endif /* __LIBVIRTD_STREAM_H__ */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0595adf..0c1e887 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,4 +1,3 @@
-daemon/dispatch.c
 daemon/libvirtd.c
 daemon/remote.c
 daemon/stream.c
-- 
1.7.2.3




More information about the libvir-list mailing list