/* Remove any associated server */
for (srv = srvrq->proxy->srv; srv != NULL; srv = srv->next) {
+ SPIN_LOCK(SERVER_LOCK, &srv->lock);
if (srv->srvrq == srvrq && srv->svc_port == item->port &&
item->data_len == srv->hostname_dn_len &&
!memcmp(srv->hostname_dn, item->target, item->data_len)) {
srv->hostname_dn_len = 0;
dns_unlink_resolution(srv->dns_requester);
}
+ SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
}
}
/* Check if a server already uses that hostname */
for (srv = srvrq->proxy->srv; srv != NULL; srv = srv->next) {
+ SPIN_LOCK(SERVER_LOCK, &srv->lock);
if (srv->srvrq == srvrq && srv->svc_port == item->port &&
item->data_len == srv->hostname_dn_len &&
!memcmp(srv->hostname_dn, item->target, item->data_len)) {
snprintf(weight, sizeof(weight), "%d", item->weight);
server_parse_weight_change_request(srv, weight);
}
+ SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
break;
}
+ SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
}
if (srv)
continue;
/* If not, try to find a server with undefined hostname */
for (srv = srvrq->proxy->srv; srv != NULL; srv = srv->next) {
+ SPIN_LOCK(SERVER_LOCK, &srv->lock);
if (srv->srvrq == srvrq && !srv->hostname_dn)
break;
+ SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
}
/* And update this server, if found */
if (srv) {
srv->check.port = item->port;
snprintf(weight, sizeof(weight), "%d", item->weight);
server_parse_weight_change_request(srv, weight);
+ SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
}
}
}
goto err;
if (srv) {
+ SPIN_LOCK(SERVER_LOCK, &srv->lock);
if (srv->dns_requester == NULL) {
if ((req = calloc(1, sizeof(*req))) == NULL)
goto err;
}
else
req = srv->dns_requester;
+ SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
}
else if (srvrq) {
if (srvrq->dns_requester == NULL) {
if (!srv)
return NULL;
+ SPIN_LOCK(SERVER_LOCK, &srv->lock);
+
be = srv->proxy;
for (tmpsrv = be->srv; tmpsrv; tmpsrv = tmpsrv->next) {
+ /* we found the current server is the same, ignore it */
+ if (srv == tmpsrv)
+ continue;
+
/* We want to compare the IP in the record with the IP of the servers in the
* same backend, only if:
* * DNS resolution is enabled on the server
* one used for the server found in the backend
* * the server found in the backend is not our current server
*/
+ SPIN_LOCK(SERVER_LOCK, &tmpsrv->lock);
if ((tmpsrv->hostname_dn == NULL) ||
(srv->hostname_dn_len != tmpsrv->hostname_dn_len) ||
(strcmp(srv->hostname_dn, tmpsrv->hostname_dn) != 0) ||
- (srv->puid == tmpsrv->puid))
+ (srv->puid == tmpsrv->puid)) {
+ SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
continue;
+ }
/* If the server has been taken down, don't consider it */
- if (tmpsrv->next_admin & SRV_ADMF_RMAINT)
+ if (tmpsrv->next_admin & SRV_ADMF_RMAINT) {
+ SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
continue;
+ }
/* At this point, we have 2 different servers using the same DNS hostname
* for their respective resolution.
memcmp(ip, &((struct sockaddr_in *)&tmpsrv->addr)->sin_addr, 4) == 0) ||
(tmpsrv->addr.ss_family == AF_INET6 &&
memcmp(ip, &((struct sockaddr_in6 *)&tmpsrv->addr)->sin6_addr, 16) == 0))) {
+ SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
+ SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
return tmpsrv;
}
+ SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
}
+ SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
+
return NULL;
}