mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-12 09:09:17 +00:00
virnetserverclient: Use automatic mutex management
Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
db16792aa9
commit
122efa6a07
@ -234,14 +234,12 @@ int virNetServerClientAddFilter(virNetServerClient *client,
|
|||||||
virNetServerClientFilterFunc func,
|
virNetServerClientFilterFunc func,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virNetServerClientFilter *filter;
|
virNetServerClientFilter *filter;
|
||||||
virNetServerClientFilter **place;
|
virNetServerClientFilter **place;
|
||||||
int ret;
|
|
||||||
|
|
||||||
filter = g_new0(virNetServerClientFilter, 1);
|
filter = g_new0(virNetServerClientFilter, 1);
|
||||||
|
|
||||||
virObjectLock(client);
|
|
||||||
|
|
||||||
filter->id = client->nextFilterID++;
|
filter->id = client->nextFilterID++;
|
||||||
filter->func = func;
|
filter->func = func;
|
||||||
filter->opaque = opaque;
|
filter->opaque = opaque;
|
||||||
@ -251,21 +249,16 @@ int virNetServerClientAddFilter(virNetServerClient *client,
|
|||||||
place = &(*place)->next;
|
place = &(*place)->next;
|
||||||
*place = filter;
|
*place = filter;
|
||||||
|
|
||||||
ret = filter->id;
|
return filter->id;
|
||||||
|
|
||||||
virObjectUnlock(client);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void virNetServerClientRemoveFilter(virNetServerClient *client,
|
void virNetServerClientRemoveFilter(virNetServerClient *client,
|
||||||
int filterID)
|
int filterID)
|
||||||
{
|
{
|
||||||
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virNetServerClientFilter *tmp;
|
virNetServerClientFilter *tmp;
|
||||||
virNetServerClientFilter *prev;
|
virNetServerClientFilter *prev;
|
||||||
|
|
||||||
virObjectLock(client);
|
|
||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
tmp = client->filters;
|
tmp = client->filters;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
@ -281,8 +274,6 @@ void virNetServerClientRemoveFilter(virNetServerClient *client,
|
|||||||
prev = tmp;
|
prev = tmp;
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -322,19 +313,19 @@ virNetServerClientCheckAccess(virNetServerClient *client)
|
|||||||
static void virNetServerClientDispatchMessage(virNetServerClient *client,
|
static void virNetServerClientDispatchMessage(virNetServerClient *client,
|
||||||
virNetMessage *msg)
|
virNetMessage *msg)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_WITH_OBJECT_LOCK_GUARD(client) {
|
||||||
if (!client->dispatchFunc) {
|
if (!client->dispatchFunc) {
|
||||||
virNetMessageFree(msg);
|
virNetMessageFree(msg);
|
||||||
client->wantClose = true;
|
client->wantClose = true;
|
||||||
virObjectUnlock(client);
|
return;
|
||||||
} else {
|
}
|
||||||
virObjectUnlock(client);
|
|
||||||
/* Accessing 'client' is safe, because virNetServerClientSetDispatcher
|
|
||||||
* only permits setting 'dispatchFunc' once, so if non-NULL, it will
|
|
||||||
* never change again
|
|
||||||
*/
|
|
||||||
client->dispatchFunc(client, msg, client->dispatchOpaque);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Accessing 'client' is safe, because virNetServerClientSetDispatcher
|
||||||
|
* only permits setting 'dispatchFunc' once, so if non-NULL, it will
|
||||||
|
* never change again
|
||||||
|
*/
|
||||||
|
client->dispatchFunc(client, msg, client->dispatchOpaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -343,13 +334,14 @@ static void virNetServerClientSockTimerFunc(int timer,
|
|||||||
{
|
{
|
||||||
virNetServerClient *client = opaque;
|
virNetServerClient *client = opaque;
|
||||||
virNetMessage *msg = NULL;
|
virNetMessage *msg = NULL;
|
||||||
virObjectLock(client);
|
|
||||||
virEventUpdateTimeout(timer, -1);
|
VIR_WITH_OBJECT_LOCK_GUARD(client) {
|
||||||
/* Although client->rx != NULL when this timer is enabled, it might have
|
virEventUpdateTimeout(timer, -1);
|
||||||
* changed since the client was unlocked in the meantime. */
|
/* Although client->rx != NULL when this timer is enabled, it might have
|
||||||
if (client->rx)
|
* changed since the client was unlocked in the meantime. */
|
||||||
msg = virNetServerClientDispatchRead(client);
|
if (client->rx)
|
||||||
virObjectUnlock(client);
|
msg = virNetServerClientDispatchRead(client);
|
||||||
|
}
|
||||||
|
|
||||||
if (msg)
|
if (msg)
|
||||||
virNetServerClientDispatchMessage(client, msg);
|
virNetServerClientDispatchMessage(client, msg);
|
||||||
@ -587,53 +579,45 @@ virJSONValue *virNetServerClientPreExecRestart(virNetServerClient *client)
|
|||||||
g_autoptr(virJSONValue) object = virJSONValueNewObject();
|
g_autoptr(virJSONValue) object = virJSONValueNewObject();
|
||||||
g_autoptr(virJSONValue) sock = NULL;
|
g_autoptr(virJSONValue) sock = NULL;
|
||||||
g_autoptr(virJSONValue) priv = NULL;
|
g_autoptr(virJSONValue) priv = NULL;
|
||||||
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
|
|
||||||
if (virJSONValueObjectAppendNumberUlong(object, "id", client->id) < 0)
|
if (virJSONValueObjectAppendNumberUlong(object, "id", client->id) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
if (virJSONValueObjectAppendNumberInt(object, "auth", client->auth) < 0)
|
if (virJSONValueObjectAppendNumberInt(object, "auth", client->auth) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
if (virJSONValueObjectAppendBoolean(object, "auth_pending", client->auth_pending) < 0)
|
if (virJSONValueObjectAppendBoolean(object, "auth_pending", client->auth_pending) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
if (virJSONValueObjectAppendBoolean(object, "readonly", client->readonly) < 0)
|
if (virJSONValueObjectAppendBoolean(object, "readonly", client->readonly) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
if (virJSONValueObjectAppendNumberUint(object, "nrequests_max", client->nrequests_max) < 0)
|
if (virJSONValueObjectAppendNumberUint(object, "nrequests_max", client->nrequests_max) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
if (client->conn_time &&
|
if (client->conn_time &&
|
||||||
virJSONValueObjectAppendNumberLong(object, "conn_time",
|
virJSONValueObjectAppendNumberLong(object, "conn_time",
|
||||||
client->conn_time) < 0)
|
client->conn_time) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
if (!(sock = virNetSocketPreExecRestart(client->sock)))
|
if (!(sock = virNetSocketPreExecRestart(client->sock)))
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
if (virJSONValueObjectAppend(object, "sock", &sock) < 0)
|
if (virJSONValueObjectAppend(object, "sock", &sock) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
if (!(priv = client->privateDataPreExecRestart(client, client->privateData)))
|
if (!(priv = client->privateDataPreExecRestart(client, client->privateData)))
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
if (virJSONValueObjectAppend(object, "privateData", &priv) < 0)
|
if (virJSONValueObjectAppend(object, "privateData", &priv) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
virObjectUnlock(client);
|
|
||||||
return g_steal_pointer(&object);
|
return g_steal_pointer(&object);
|
||||||
|
|
||||||
error:
|
|
||||||
virObjectUnlock(client);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int virNetServerClientGetAuth(virNetServerClient *client)
|
int virNetServerClientGetAuth(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
int auth;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
auth = client->auth;
|
return client->auth;
|
||||||
virObjectUnlock(client);
|
|
||||||
return auth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -647,11 +631,9 @@ virNetServerClientSetAuthLocked(virNetServerClient *client,
|
|||||||
|
|
||||||
bool virNetServerClientGetReadonly(virNetServerClient *client)
|
bool virNetServerClientGetReadonly(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
bool readonly;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
readonly = client->readonly;
|
return client->readonly;
|
||||||
virObjectUnlock(client);
|
|
||||||
return readonly;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -659,9 +641,9 @@ void
|
|||||||
virNetServerClientSetReadonly(virNetServerClient *client,
|
virNetServerClientSetReadonly(virNetServerClient *client,
|
||||||
bool readonly)
|
bool readonly)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
client->readonly = readonly;
|
client->readonly = readonly;
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -677,52 +659,48 @@ long long virNetServerClientGetTimestamp(virNetServerClient *client)
|
|||||||
|
|
||||||
bool virNetServerClientHasTLSSession(virNetServerClient *client)
|
bool virNetServerClientHasTLSSession(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
bool has;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
has = client->tls ? true : false;
|
return !!client->tls;
|
||||||
virObjectUnlock(client);
|
|
||||||
return has;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virNetTLSSession *virNetServerClientGetTLSSession(virNetServerClient *client)
|
virNetTLSSession *virNetServerClientGetTLSSession(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
virNetTLSSession *tls;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
tls = client->tls;
|
return client->tls;
|
||||||
virObjectUnlock(client);
|
|
||||||
return tls;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int virNetServerClientGetTLSKeySize(virNetServerClient *client)
|
int virNetServerClientGetTLSKeySize(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
int size = 0;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
if (client->tls)
|
if (!client->tls)
|
||||||
size = virNetTLSSessionGetKeySize(client->tls);
|
return 0;
|
||||||
virObjectUnlock(client);
|
|
||||||
return size;
|
return virNetTLSSessionGetKeySize(client->tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
int virNetServerClientGetFD(virNetServerClient *client)
|
int virNetServerClientGetFD(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
if (client->sock)
|
if (!client->sock)
|
||||||
fd = virNetSocketGetFD(client->sock);
|
return -1;
|
||||||
virObjectUnlock(client);
|
|
||||||
return fd;
|
return virNetSocketGetFD(client->sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool virNetServerClientIsLocal(virNetServerClient *client)
|
bool virNetServerClientIsLocal(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
bool local = false;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
if (client->sock)
|
if (!client->sock)
|
||||||
local = virNetSocketIsLocal(client->sock);
|
return false;
|
||||||
virObjectUnlock(client);
|
|
||||||
return local;
|
return virNetSocketIsLocal(client->sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -730,14 +708,12 @@ int virNetServerClientGetUNIXIdentity(virNetServerClient *client,
|
|||||||
uid_t *uid, gid_t *gid, pid_t *pid,
|
uid_t *uid, gid_t *gid, pid_t *pid,
|
||||||
unsigned long long *timestamp)
|
unsigned long long *timestamp)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
if (client->sock)
|
if (!client->sock)
|
||||||
ret = virNetSocketGetUNIXIdentity(client->sock,
|
return -1;
|
||||||
uid, gid, pid,
|
|
||||||
timestamp);
|
return virNetSocketGetUNIXIdentity(client->sock, uid, gid, pid, timestamp);
|
||||||
virObjectUnlock(client);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -806,56 +782,60 @@ virNetServerClientCreateIdentity(virNetServerClient *client)
|
|||||||
|
|
||||||
virIdentity *virNetServerClientGetIdentity(virNetServerClient *client)
|
virIdentity *virNetServerClientGetIdentity(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
virIdentity *ret = NULL;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
if (!client->identity)
|
if (!client->identity)
|
||||||
client->identity = virNetServerClientCreateIdentity(client);
|
client->identity = virNetServerClientCreateIdentity(client);
|
||||||
if (client->identity)
|
|
||||||
ret = g_object_ref(client->identity);
|
if (!client->identity)
|
||||||
virObjectUnlock(client);
|
return NULL;
|
||||||
return ret;
|
|
||||||
|
return g_object_ref(client->identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void virNetServerClientSetIdentity(virNetServerClient *client,
|
void virNetServerClientSetIdentity(virNetServerClient *client,
|
||||||
virIdentity *identity)
|
virIdentity *identity)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
g_clear_object(&client->identity);
|
g_clear_object(&client->identity);
|
||||||
client->identity = identity;
|
client->identity = identity;
|
||||||
if (client->identity)
|
if (client->identity)
|
||||||
g_object_ref(client->identity);
|
g_object_ref(client->identity);
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int virNetServerClientGetSELinuxContext(virNetServerClient *client,
|
int virNetServerClientGetSELinuxContext(virNetServerClient *client,
|
||||||
char **context)
|
char **context)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
*context = NULL;
|
*context = NULL;
|
||||||
virObjectLock(client);
|
|
||||||
if (client->sock)
|
if (!client->sock)
|
||||||
ret = virNetSocketGetSELinuxContext(client->sock, context);
|
return 0;
|
||||||
virObjectUnlock(client);
|
|
||||||
return ret;
|
return virNetSocketGetSELinuxContext(client->sock, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool virNetServerClientIsSecure(virNetServerClient *client)
|
bool virNetServerClientIsSecure(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
bool secure = false;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
if (client->tls)
|
if (client->tls)
|
||||||
secure = true;
|
return true;
|
||||||
|
|
||||||
#if WITH_SASL
|
#if WITH_SASL
|
||||||
if (client->sasl)
|
if (client->sasl)
|
||||||
secure = true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (client->sock && virNetSocketIsLocal(client->sock))
|
if (client->sock && virNetSocketIsLocal(client->sock))
|
||||||
secure = true;
|
return true;
|
||||||
virObjectUnlock(client);
|
|
||||||
return secure;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -863,53 +843,47 @@ bool virNetServerClientIsSecure(virNetServerClient *client)
|
|||||||
void virNetServerClientSetSASLSession(virNetServerClient *client,
|
void virNetServerClientSetSASLSession(virNetServerClient *client,
|
||||||
virNetSASLSession *sasl)
|
virNetSASLSession *sasl)
|
||||||
{
|
{
|
||||||
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
/* We don't set the sasl session on the socket here
|
/* We don't set the sasl session on the socket here
|
||||||
* because we need to send out the auth confirmation
|
* because we need to send out the auth confirmation
|
||||||
* in the clear. Only once we complete the next 'tx'
|
* in the clear. Only once we complete the next 'tx'
|
||||||
* operation do we switch to SASL mode
|
* operation do we switch to SASL mode
|
||||||
*/
|
*/
|
||||||
virObjectLock(client);
|
|
||||||
client->sasl = virObjectRef(sasl);
|
client->sasl = virObjectRef(sasl);
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virNetSASLSession *virNetServerClientGetSASLSession(virNetServerClient *client)
|
virNetSASLSession *virNetServerClientGetSASLSession(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
virNetSASLSession *sasl;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
sasl = client->sasl;
|
return client->sasl;
|
||||||
virObjectUnlock(client);
|
|
||||||
return sasl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool virNetServerClientHasSASLSession(virNetServerClient *client)
|
bool virNetServerClientHasSASLSession(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
bool has = false;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
has = !!client->sasl;
|
return !!client->sasl;
|
||||||
virObjectUnlock(client);
|
|
||||||
return has;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void *virNetServerClientGetPrivateData(virNetServerClient *client)
|
void *virNetServerClientGetPrivateData(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
void *data;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
data = client->privateData;
|
return client->privateData;
|
||||||
virObjectUnlock(client);
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void virNetServerClientSetCloseHook(virNetServerClient *client,
|
void virNetServerClientSetCloseHook(virNetServerClient *client,
|
||||||
virNetServerClientCloseFunc cf)
|
virNetServerClientCloseFunc cf)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
client->privateDataCloseFunc = cf;
|
client->privateDataCloseFunc = cf;
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -917,7 +891,8 @@ void virNetServerClientSetDispatcher(virNetServerClient *client,
|
|||||||
virNetServerClientDispatchFunc func,
|
virNetServerClientDispatchFunc func,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
/* Only set dispatcher if not already set, to avoid race
|
/* Only set dispatcher if not already set, to avoid race
|
||||||
* with dispatch code that runs without locks held
|
* with dispatch code that runs without locks held
|
||||||
*/
|
*/
|
||||||
@ -925,7 +900,6 @@ void virNetServerClientSetDispatcher(virNetServerClient *client,
|
|||||||
client->dispatchFunc = func;
|
client->dispatchFunc = func;
|
||||||
client->dispatchOpaque = opaque;
|
client->dispatchOpaque = opaque;
|
||||||
}
|
}
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1042,9 +1016,9 @@ virNetServerClientCloseLocked(virNetServerClient *client)
|
|||||||
void
|
void
|
||||||
virNetServerClientClose(virNetServerClient *client)
|
virNetServerClientClose(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
virNetServerClientCloseLocked(client);
|
virNetServerClientCloseLocked(client);
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1057,16 +1031,16 @@ virNetServerClientIsClosedLocked(virNetServerClient *client)
|
|||||||
|
|
||||||
void virNetServerClientDelayedClose(virNetServerClient *client)
|
void virNetServerClientDelayedClose(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
client->delayedClose = true;
|
client->delayedClose = true;
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void virNetServerClientImmediateClose(virNetServerClient *client)
|
void virNetServerClientImmediateClose(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
client->wantClose = true;
|
client->wantClose = true;
|
||||||
virObjectUnlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1079,49 +1053,46 @@ virNetServerClientWantCloseLocked(virNetServerClient *client)
|
|||||||
|
|
||||||
int virNetServerClientInit(virNetServerClient *client)
|
int virNetServerClientInit(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
virObjectLock(client);
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
if (!client->tlsCtxt) {
|
if (!client->tlsCtxt) {
|
||||||
/* Plain socket, so prepare to read first message */
|
/* Plain socket, so prepare to read first message */
|
||||||
if (virNetServerClientRegisterEvent(client) < 0)
|
if (virNetServerClientRegisterEvent(client) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
return 0;
|
||||||
int ret;
|
}
|
||||||
|
|
||||||
if (!(client->tls = virNetTLSSessionNew(client->tlsCtxt,
|
if (!(client->tls = virNetTLSSessionNew(client->tlsCtxt, NULL)))
|
||||||
NULL)))
|
goto error;
|
||||||
goto error;
|
|
||||||
|
virNetSocketSetTLSSession(client->sock, client->tls);
|
||||||
virNetSocketSetTLSSession(client->sock,
|
|
||||||
client->tls);
|
/* Begin the TLS handshake. */
|
||||||
|
VIR_WITH_OBJECT_LOCK_GUARD(client->tlsCtxt) {
|
||||||
/* Begin the TLS handshake. */
|
ret = virNetTLSSessionHandshake(client->tls);
|
||||||
virObjectLock(client->tlsCtxt);
|
}
|
||||||
ret = virNetTLSSessionHandshake(client->tls);
|
|
||||||
virObjectUnlock(client->tlsCtxt);
|
if (ret == 0) {
|
||||||
if (ret == 0) {
|
/* Unlikely, but ... Next step is to check the certificate. */
|
||||||
/* Unlikely, but ... Next step is to check the certificate. */
|
if (virNetServerClientCheckAccess(client) < 0)
|
||||||
if (virNetServerClientCheckAccess(client) < 0)
|
goto error;
|
||||||
goto error;
|
|
||||||
|
/* Handshake & cert check OK, so prepare to read first message */
|
||||||
/* Handshake & cert check OK, so prepare to read first message */
|
if (virNetServerClientRegisterEvent(client) < 0)
|
||||||
if (virNetServerClientRegisterEvent(client) < 0)
|
goto error;
|
||||||
goto error;
|
} else if (ret > 0) {
|
||||||
} else if (ret > 0) {
|
/* Most likely, need to do more handshake data */
|
||||||
/* Most likely, need to do more handshake data */
|
if (virNetServerClientRegisterEvent(client) < 0)
|
||||||
if (virNetServerClientRegisterEvent(client) < 0)
|
goto error;
|
||||||
goto error;
|
} else {
|
||||||
} else {
|
goto error;
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virObjectUnlock(client);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
client->wantClose = true;
|
client->wantClose = true;
|
||||||
virObjectUnlock(client);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1406,11 +1377,13 @@ virNetServerClientDispatchWrite(virNetServerClient *client)
|
|||||||
static void
|
static void
|
||||||
virNetServerClientDispatchHandshake(virNetServerClient *client)
|
virNetServerClientDispatchHandshake(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = -1;
|
||||||
|
|
||||||
/* Continue the handshake. */
|
/* Continue the handshake. */
|
||||||
virObjectLock(client->tlsCtxt);
|
VIR_WITH_OBJECT_LOCK_GUARD(client->tlsCtxt) {
|
||||||
ret = virNetTLSSessionHandshake(client->tls);
|
ret = virNetTLSSessionHandshake(client->tls);
|
||||||
virObjectUnlock(client->tlsCtxt);
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Finished. Next step is to check the certificate. */
|
/* Finished. Next step is to check the certificate. */
|
||||||
if (virNetServerClientCheckAccess(client) < 0)
|
if (virNetServerClientCheckAccess(client) < 0)
|
||||||
@ -1435,37 +1408,30 @@ virNetServerClientDispatchEvent(virNetSocket *sock, int events, void *opaque)
|
|||||||
virNetServerClient *client = opaque;
|
virNetServerClient *client = opaque;
|
||||||
virNetMessage *msg = NULL;
|
virNetMessage *msg = NULL;
|
||||||
|
|
||||||
virObjectLock(client);
|
VIR_WITH_OBJECT_LOCK_GUARD(client) {
|
||||||
|
if (client->sock != sock) {
|
||||||
if (client->sock != sock) {
|
virNetSocketRemoveIOCallback(sock);
|
||||||
virNetSocketRemoveIOCallback(sock);
|
return;
|
||||||
virObjectUnlock(client);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events & (VIR_EVENT_HANDLE_WRITABLE |
|
|
||||||
VIR_EVENT_HANDLE_READABLE)) {
|
|
||||||
if (client->tls &&
|
|
||||||
virNetTLSSessionGetHandshakeStatus(client->tls) !=
|
|
||||||
VIR_NET_TLS_HANDSHAKE_COMPLETE) {
|
|
||||||
virNetServerClientDispatchHandshake(client);
|
|
||||||
} else {
|
|
||||||
if (events & VIR_EVENT_HANDLE_WRITABLE)
|
|
||||||
virNetServerClientDispatchWrite(client);
|
|
||||||
if (events & VIR_EVENT_HANDLE_READABLE &&
|
|
||||||
client->rx)
|
|
||||||
msg = virNetServerClientDispatchRead(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (events & (VIR_EVENT_HANDLE_WRITABLE | VIR_EVENT_HANDLE_READABLE)) {
|
||||||
|
if (client->tls &&
|
||||||
|
virNetTLSSessionGetHandshakeStatus(client->tls) !=
|
||||||
|
VIR_NET_TLS_HANDSHAKE_COMPLETE) {
|
||||||
|
virNetServerClientDispatchHandshake(client);
|
||||||
|
} else {
|
||||||
|
if (events & VIR_EVENT_HANDLE_WRITABLE)
|
||||||
|
virNetServerClientDispatchWrite(client);
|
||||||
|
if ((events & VIR_EVENT_HANDLE_READABLE) && client->rx)
|
||||||
|
msg = virNetServerClientDispatchRead(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NB, will get HANGUP + READABLE at same time upon disconnect */
|
||||||
|
if (events & (VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP))
|
||||||
|
client->wantClose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NB, will get HANGUP + READABLE at same time upon
|
|
||||||
* disconnect */
|
|
||||||
if (events & (VIR_EVENT_HANDLE_ERROR |
|
|
||||||
VIR_EVENT_HANDLE_HANGUP))
|
|
||||||
client->wantClose = true;
|
|
||||||
|
|
||||||
virObjectUnlock(client);
|
|
||||||
|
|
||||||
if (msg)
|
if (msg)
|
||||||
virNetServerClientDispatchMessage(client, msg);
|
virNetServerClientDispatchMessage(client, msg);
|
||||||
}
|
}
|
||||||
@ -1499,24 +1465,18 @@ virNetServerClientSendMessageLocked(virNetServerClient *client,
|
|||||||
int virNetServerClientSendMessage(virNetServerClient *client,
|
int virNetServerClientSendMessage(virNetServerClient *client,
|
||||||
virNetMessage *msg)
|
virNetMessage *msg)
|
||||||
{
|
{
|
||||||
int ret;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
virObjectLock(client);
|
return virNetServerClientSendMessageLocked(client, msg);
|
||||||
ret = virNetServerClientSendMessageLocked(client, msg);
|
|
||||||
virObjectUnlock(client);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
virNetServerClientIsAuthenticated(virNetServerClient *client)
|
virNetServerClientIsAuthenticated(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
bool authenticated;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virObjectLock(client);
|
|
||||||
authenticated = virNetServerClientAuthMethodImpliesAuthenticated(client->auth);
|
return virNetServerClientAuthMethodImpliesAuthenticated(client->auth);
|
||||||
virObjectUnlock(client);
|
|
||||||
return authenticated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1556,57 +1516,44 @@ virNetServerClientInitKeepAlive(virNetServerClient *client,
|
|||||||
int interval,
|
int interval,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
virKeepAlive *ka;
|
virKeepAlive *ka;
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
virObjectLock(client);
|
|
||||||
|
|
||||||
if (!(ka = virKeepAliveNew(interval, count, client,
|
if (!(ka = virKeepAliveNew(interval, count, client,
|
||||||
virNetServerClientKeepAliveSendCB,
|
virNetServerClientKeepAliveSendCB,
|
||||||
virNetServerClientKeepAliveDeadCB,
|
virNetServerClientKeepAliveDeadCB,
|
||||||
virObjectFreeCallback)))
|
virObjectFreeCallback)))
|
||||||
goto cleanup;
|
return -1;
|
||||||
|
|
||||||
/* keepalive object has a reference to client */
|
/* keepalive object has a reference to client */
|
||||||
virObjectRef(client);
|
virObjectRef(client);
|
||||||
|
|
||||||
client->keepalive = ka;
|
client->keepalive = ka;
|
||||||
ret = 0;
|
return 0;
|
||||||
cleanup:
|
|
||||||
virObjectUnlock(client);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
virNetServerClientStartKeepAlive(virNetServerClient *client)
|
virNetServerClientStartKeepAlive(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
|
|
||||||
virObjectLock(client);
|
|
||||||
|
|
||||||
/* The connection might have been closed before we got here and thus the
|
/* The connection might have been closed before we got here and thus the
|
||||||
* keepalive object could have been removed too.
|
* keepalive object could have been removed too.
|
||||||
*/
|
*/
|
||||||
if (!client->keepalive) {
|
if (!client->keepalive) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
|
||||||
_("connection not open"));
|
return -1;
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = virKeepAliveStart(client->keepalive, 0, 0);
|
return virKeepAliveStart(client->keepalive, 0, 0);
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virObjectUnlock(client);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
virNetServerClientGetTransport(virNetServerClient *client)
|
virNetServerClientGetTransport(virNetServerClient *client)
|
||||||
{
|
{
|
||||||
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
virObjectLock(client);
|
|
||||||
|
|
||||||
if (client->sock && virNetSocketIsLocal(client->sock))
|
if (client->sock && virNetSocketIsLocal(client->sock))
|
||||||
ret = VIR_CLIENT_TRANS_UNIX;
|
ret = VIR_CLIENT_TRANS_UNIX;
|
||||||
else
|
else
|
||||||
@ -1615,8 +1562,6 @@ virNetServerClientGetTransport(virNetServerClient *client)
|
|||||||
if (client->tls)
|
if (client->tls)
|
||||||
ret = VIR_CLIENT_TRANS_TLS;
|
ret = VIR_CLIENT_TRANS_TLS;
|
||||||
|
|
||||||
virObjectUnlock(client);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1625,16 +1570,15 @@ virNetServerClientGetInfo(virNetServerClient *client,
|
|||||||
bool *readonly, char **sock_addr,
|
bool *readonly, char **sock_addr,
|
||||||
virIdentity **identity)
|
virIdentity **identity)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
VIR_LOCK_GUARD lock = virObjectLockGuard(client);
|
||||||
const char *addr;
|
const char *addr;
|
||||||
|
|
||||||
virObjectLock(client);
|
|
||||||
*readonly = client->readonly;
|
*readonly = client->readonly;
|
||||||
|
|
||||||
if (!(addr = virNetServerClientRemoteAddrStringURI(client))) {
|
if (!(addr = virNetServerClientRemoteAddrStringURI(client))) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("No network socket associated with client"));
|
_("No network socket associated with client"));
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sock_addr = g_strdup(addr);
|
*sock_addr = g_strdup(addr);
|
||||||
@ -1642,15 +1586,11 @@ virNetServerClientGetInfo(virNetServerClient *client,
|
|||||||
if (!client->identity) {
|
if (!client->identity) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("No identity information available for client"));
|
_("No identity information available for client"));
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*identity = g_object_ref(client->identity);
|
*identity = g_object_ref(client->identity);
|
||||||
|
return 0;
|
||||||
ret = 0;
|
|
||||||
cleanup:
|
|
||||||
virObjectUnlock(client);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user