/* Pure Load Balancer - (C)opyleft 2003 Jedi/Sector One */ #include #include "plb.h" #include "plb_globals.h" #ifdef WITH_DMALLOC # include #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; }