client->auth = sock->auth;
memcpy (&client->addr, &addr, sizeof addr);
client->addrlen = addrlen;
- client->server = server;
/* Prepare one for packet receive */
if (VIR_ALLOC(client->rx) < 0)
if (client->type != QEMUD_SOCK_TYPE_TLS) {
/* Plain socket, so prepare to read first message */
- if (qemudRegisterClientEvent (server, client, 0) < 0)
+ if (qemudRegisterClientEvent (server, client) < 0)
goto cleanup;
} else {
int ret;
goto cleanup;
/* Handshake & cert check OK, so prepare to read first message */
- if (qemudRegisterClientEvent(server, client, 0) < 0)
+ if (qemudRegisterClientEvent(server, client) < 0)
goto cleanup;
} 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) < 0)
+ if (qemudRegisterClientEvent (server, client) < 0)
goto cleanup;
} else {
VIR_ERROR(_("TLS handshake failed: %s"),
/* Prepare to read rest of message */
client->rx->bufferLength += len;
- if (qemudRegisterClientEvent(server, client, 1) < 0) {
- qemudDispatchClientFailure(client);
- return;
- }
+ qemudUpdateClientEvent(client);
/* Try and read payload immediately instead of going back
into poll() because chances are the data is already
if (client->rx)
client->rx->bufferLength = REMOTE_MESSAGE_HEADER_XDR_LEN;
- if (qemudRegisterClientEvent(server, client, 1) < 0)
- qemudDispatchClientFailure(client);
- else
- /* Tell one of the workers to get on with it... */
- virCondSignal(&server->job);
+ qemudUpdateClientEvent(client);
+
+ /* Tell one of the workers to get on with it... */
+ virCondSignal(&server->job);
}
}
}
* we would block on I/O
*/
static void
-qemudDispatchClientWrite(struct qemud_server *server,
- struct qemud_client *client) {
+qemudDispatchClientWrite(struct qemud_client *client) {
while (client->tx) {
ssize_t ret;
VIR_FREE(reply);
}
- if (client->closing ||
- qemudRegisterClientEvent (server, client, 1) < 0)
- qemudDispatchClientFailure(client);
+ if (client->closing)
+ qemudDispatchClientFailure(client);
+ else
+ qemudUpdateClientEvent(client);
}
}
}
static void
-qemudDispatchClientHandshake(struct qemud_server *server,
- struct qemud_client *client) {
+qemudDispatchClientHandshake(struct qemud_client *client) {
int ret;
/* Continue the handshake. */
ret = gnutls_handshake (client->tlssession);
/* Finished. Next step is to check the certificate. */
if (remoteCheckAccess (client) == -1)
qemudDispatchClientFailure(client);
- else if (qemudRegisterClientEvent (server, 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 */
- if (qemudRegisterClientEvent (server, client, 1))
- qemudDispatchClientFailure(client);
+ qemudUpdateClientEvent (client);
} else {
/* Fatal error in handshake */
VIR_ERROR(_("TLS handshake failed: %s"),
if (events & (VIR_EVENT_HANDLE_WRITABLE |
VIR_EVENT_HANDLE_READABLE)) {
if (client->handshake) {
- qemudDispatchClientHandshake(server, client);
+ qemudDispatchClientHandshake(client);
} else {
if (events & VIR_EVENT_HANDLE_WRITABLE)
- qemudDispatchClientWrite(server, client);
+ qemudDispatchClientWrite(client);
if (events & VIR_EVENT_HANDLE_READABLE)
qemudDispatchClientRead(server, client);
}
virMutexUnlock(&client->lock);
}
-int qemudRegisterClientEvent(struct qemud_server *server,
- struct qemud_client *client,
- int update) {
+
+/*
+ * @client: a locked client object
+ */
+static int
+qemudCalculateHandleMode(struct qemud_client *client) {
int mode = 0;
if (client->handshake) {
mode |= VIR_EVENT_HANDLE_WRITABLE;
}
- if (update) {
- virEventUpdateHandleImpl(client->watch, mode);
- } else {
- if ((client->watch = virEventAddHandleImpl(client->fd,
- mode,
- qemudDispatchClientEvent,
- server, NULL)) < 0)
- return -1;
- }
+ 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;
/* Prototypes */
static void
remoteDispatchDomainEventSend (struct qemud_client *client,
- virDomainPtr dom,
- int event,
- int detail);
-
-
+ remote_domain_event_msg *data);
int remoteRelayDomainEvent (virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
REMOTE_DEBUG("Relaying domain event %d %d", event, detail);
if (client) {
+ remote_domain_event_msg data;
+
virMutexLock(&client->lock);
- remoteDispatchDomainEventSend (client, dom, event, detail);
+ /* build return data */
+ memset(&data, 0, sizeof data);
+ make_nonnull_domain (&data.dom, dom);
+ data.event = event;
+ data.detail = detail;
- if (qemudRegisterClientEvent(client->server, client, 1) < 0)
- qemudDispatchClientFailure(client);
+ remoteDispatchDomainEventSend (client, &data);
virMutexUnlock(&client->lock);
}
static void
remoteDispatchDomainEventSend (struct qemud_client *client,
- virDomainPtr dom,
- int event,
- int detail)
+ remote_domain_event_msg *data)
{
struct qemud_client_message *msg = NULL;
XDR xdr;
unsigned int len;
- remote_domain_event_msg data;
if (VIR_ALLOC(msg) < 0)
return;
msg->bufferLength - msg->bufferOffset,
XDR_ENCODE);
- /* build return data */
- make_nonnull_domain (&data.dom, dom);
- data.event = event;
- data.detail = detail;
-
- if (!xdr_remote_domain_event_msg(&xdr, &data))
+ if (!xdr_remote_domain_event_msg(&xdr, data))
goto xdr_error;
msg->bufferLength = len;
msg->bufferOffset = 0;
qemudClientMessageQueuePush(&client->tx, msg);
+ qemudUpdateClientEvent(client);
xdr_destroy (&xdr);
return;