/* Pure Load Balancer - (C)opyleft 2003 Jedi/Sector One <j@pureftpd.org> */
#include <config.h>
#include "plb.h"
#include "plb_globals.h"
#ifdef WITH_DMALLOC
# include <dmalloc.h>
#endif
void server_mark_failure(Client * const client)
{
if (client->server->status > 0U) {
client->server->status--;
if (client->server->status <= 0U) {
plb_log(LL_WARNING, "[%s] is down\n", client->server->name);
}
}
}
int connect_server(Client * const client)
{
static int all_servers_down;
const Server * const serverpool_previous = serverpool_current;
int server_fd;
for (;;) {
if (serverpool_current->next == NULL) {
serverpool_current = serverpool_head;
} else {
serverpool_current = serverpool_current->next;
}
if (serverpool_current->status > 0U) {
break;
}
if (serverpool_current == serverpool_previous) {
if (all_servers_down == 0) {
plb_log(LL_WARNING, "All servers are down");
all_servers_down = 1;
}
return -1;
}
}
all_servers_down = 0;
if ((server_fd = socket(serverpool_current->ai_family,
SOCK_STREAM, IPPROTO_TCP)) == -1) {
plb_log(LL_ERROR, "unable to create a backend socket : [%s]",
strerror(errno));
return -1;
}
setsockopt_aggressive(server_fd);
socket_nonblock(server_fd);
client->server = serverpool_current;
for (;;) {
if (connect(server_fd,
(struct sockaddr *) &serverpool_current->ai_addr,
(socklen_t) serverpool_current->ai_addrlen) != 0 &&
errno != EINPROGRESS) {
if (errno == EINTR) {
continue;
}
plb_log(LL_WARNING, "Unable to connect to a backend server : [%s]",
strerror(errno));
while (close(server_fd) != 0 && errno == EINTR);
server_mark_failure(client);
return -1;
}
break;
}
client->server_fd = server_fd;
event_set(&client->server_write_ev, server_fd, EV_WRITE,
server_send_header, client);
event_add(&client->server_write_ev, &timeout_header_server_write);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1