virNetServerClientPtr *clients; /* Clients */
size_t nclients_max; /* Max allowed clients count */
size_t nclients_unauth; /* Unauthenticated clients count */
+ size_t nclients_unauth_max; /* Max allowed unauth clients count */
int keepaliveInterval;
unsigned int keepaliveCount;
if (virNetServerClientNeedAuth(client))
virNetServerTrackPendingAuthLocked(srv);
+ if (srv->nclients_unauth_max &&
+ srv->nclients_unauth == srv->nclients_unauth_max) {
+ /* Temporarily stop accepting new clients */
+ VIR_DEBUG("Temporarily suspending services "
+ "due to max_anonymous_clients");
+ virNetServerUpdateServicesLocked(srv, false);
+ }
+
if (srv->nclients == srv->nclients_max) {
/* Temporarily stop accepting new clients */
VIR_DEBUG("Temporarily suspending services due to max_clients");
size_t max_workers,
size_t priority_workers,
size_t max_clients,
+ size_t max_anonymous_clients,
int keepaliveInterval,
unsigned int keepaliveCount,
bool keepaliveRequired,
goto error;
srv->nclients_max = max_clients;
+ srv->nclients_unauth_max = max_anonymous_clients;
srv->keepaliveInterval = keepaliveInterval;
srv->keepaliveCount = keepaliveCount;
srv->keepaliveRequired = keepaliveRequired;
unsigned int max_workers;
unsigned int priority_workers;
unsigned int max_clients;
+ unsigned int max_anonymous_clients;
unsigned int keepaliveInterval;
unsigned int keepaliveCount;
bool keepaliveRequired;
_("Missing max_clients data in JSON document"));
goto error;
}
+ if (virJSONValueObjectHasKey(object, "max_anonymous_clients") &&
+ virJSONValueObjectGetNumberUint(object, "max_anonymous_clients",
+ &max_anonymous_clients) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Malformed max_anonymous_clients data in JSON document"));
+ goto error;
+ }
if (virJSONValueObjectGetNumberUint(object, "keepaliveInterval", &keepaliveInterval) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing keepaliveInterval data in JSON document"));
if (!(srv = virNetServerNew(min_workers, max_clients,
priority_workers, max_clients,
+ max_anonymous_clients,
keepaliveInterval, keepaliveCount,
keepaliveRequired, mdnsGroupName,
clientPrivNew, clientPrivPreExecRestart,
_("Cannot set max_clients data in JSON document"));
goto error;
}
+ if (virJSONValueObjectAppendNumberUint(object, "max_anonymous_clients",
+ srv->nclients_unauth_max) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot set max_anonymous_clients data in JSON document"));
+ goto error;
+ }
if (virJSONValueObjectAppendNumberUint(object, "keepaliveInterval", srv->keepaliveInterval) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot set keepaliveInterval data in JSON document"));
virObjectUnlock(srv);
}
+/**
+ * virNetServerCheckLimits:
+ * @srv: server to check limits on
+ *
+ * Check if limits like max_clients or max_anonymous_clients
+ * are satisfied and if so, re-enable accepting new clients.
+ * The @srv must be locked when this function is called.
+ */
+static void
+virNetServerCheckLimits(virNetServerPtr srv)
+{
+ /* Enable services if we can accept a new client.
+ * The new client can be accepted if both max_clients and
+ * max_anonymous_clients wouldn't get overcommitted by
+ * accepting it. */
+ VIR_DEBUG("Considering re-enabling services: "
+ "nclients=%zu nclients_max=%zu "
+ "nclients_unauth=%zu nclients_unauth_max=%zu",
+ srv->nclients, srv->nclients_max,
+ srv->nclients_unauth, srv->nclients_unauth_max);
+ if (srv->nclients < srv->nclients_max &&
+ (!srv->nclients_unauth_max ||
+ srv->nclients_unauth < srv->nclients_unauth_max)) {
+ /* Now it makes sense to accept() a new client. */
+ VIR_DEBUG("Re-enabling services");
+ virNetServerUpdateServicesLocked(srv, true);
+ }
+}
void virNetServerRun(virNetServerPtr srv)
{
if (virNetServerClientNeedAuth(client))
virNetServerTrackCompletedAuthLocked(srv);
- /* Enable services if we can accept a new client.
- * The new client can be accepted if we are at the limit. */
- if (srv->nclients == srv->nclients_max - 1) {
- /* Now it makes sense to accept() a new client. */
- VIR_DEBUG("Re-enabling services");
- virNetServerUpdateServicesLocked(srv, true);
- }
+ virNetServerCheckLimits(srv);
virObjectUnlock(srv);
virObjectUnref(client);
size_t ret;
virObjectLock(srv);
ret = virNetServerTrackCompletedAuthLocked(srv);
+ virNetServerCheckLimits(srv);
virObjectUnlock(srv);
return ret;
}