/* Pure Load Balancer - (C)opyleft 2003 Jedi/Sector One */ #include #include "plb.h" #include "plb_globals.h" #ifdef WITH_DMALLOC # include #endif void server_forward_request(int evfd, short event, void *client_) { Client * const client = client_; ssize_t written; (void) evfd; if (handle_timeout(event, client) != 0) { return; } if (client->postbuf == NULL) { client_disconnect(client); return; } if (client->postbuf_len <= (size_t) 0U) { goto already_written; } if ((written = write(client->server_fd, client->postbuf + client->postbuf_written, client->postbuf_len - client->postbuf_written)) != (ssize_t) (client->postbuf_len - client->postbuf_written)) { if (written <= (ssize_t) 0) { if (errno == EINTR) { event_add(&client->server_write_ev, &timeout_forward_server_write); return; } plb_log(LL_NOTIFY, "Error while sending a forwarded request : [%s]", strerror(errno)); client_disconnect(client); return; } client->postbuf_written += written; event_add(&client->server_write_ev, &timeout_forward_server_write); return; } client->postbuf_len = (size_t) 0U; already_written: (void) client; } void client_forward_request(Client * const client) { ssize_t readen; if (client->postbuf == NULL) { if ((client->postbuf = malloc(POSTBUF_CHUNKS)) == NULL) { plb_log(LL_ERROR, "Out of memory for the forwarding buffer : [%s]", strerror(errno)); client_disconnect(client); return; } client->postbuf_len = (size_t) 0U; client->postbuf_written = (size_t) 0U; } if ((readen = read(client->client_fd, client->postbuf, POSTBUF_CHUNKS)) <= (ssize_t) 0) { if (readen < (ssize_t) 0) { if (errno == EINTR) { return; } plb_log(LL_NOTIFY, "Error while reading to-be-forwarded data : [%s]", strerror(errno)); } client_disconnect(client); return; } client->postbuf_len = (size_t) readen; client->postbuf_written = (size_t) 0U; event_set(&client->server_write_ev, client->server_fd, EV_WRITE, server_forward_request, client); event_add(&client->server_write_ev, &timeout_forward_server_write); event_add(&client->client_read_ev, &timeout_forward_client_read); } void server_forward_reply(int evfd, short event, void *client_) { Client * const client = client_; ssize_t readen; (void) evfd; if (handle_timeout(event, client) != 0) { return; } if (client->replybuf == NULL) { if ((client->replybuf = malloc(REPLYBUF_CHUNKS)) == NULL) { plb_log(LL_ERROR, "Out of memory when trying to get a reply buffer : [%s]", strerror(errno)); client_disconnect(client); return; } client->replybuf_len = (size_t) 0U; client->replybuf_written = (size_t) 0U; } if ((readen = read(client->server_fd, client->replybuf, REPLYBUF_CHUNKS)) <= (ssize_t) 0) { if (errno == EINTR) { event_add(&client->server_read_ev, &timeout_forward_server_read); return; } if (readen < (ssize_t) 0) { plb_log(LL_NOTIFY, "Error while reading the data to be forwarded : [%s]", strerror(errno)); } client_disconnect(client); return; } client->replybuf_len = (size_t) readen; client->replybuf_written = (size_t) 0U; event_set(&client->client_write_ev, client->client_fd, EV_WRITE, client_forward_reply, client); event_add(&client->client_write_ev, &timeout_forward_client_write); } void client_forward_reply(int evfd, short event, void *client_) { Client * const client = client_; ssize_t written; (void) evfd; if (handle_timeout(event, client) != 0) { return; } if (client->replybuf == NULL) { client_disconnect(client); return; } if (client->replybuf_len <= (size_t) 0U) { goto already_written; } if ((written = write(client->client_fd, client->replybuf + client->replybuf_written, client->replybuf_len - client->replybuf_written)) != (ssize_t) (client->replybuf_len - client->replybuf_written)) { if (written <= (ssize_t) 0) { if (errno == EINTR) { event_add(&client->client_write_ev, &timeout_forward_client_write); return; } plb_log(LL_NOTIFY, "Error while sending content data : [%s]", strerror(errno)); client_disconnect(client); return; } client->replybuf_written += written; event_add(&client->client_write_ev, &timeout_forward_client_write); return; } client->replybuf_len = (size_t) 0U; already_written: event_set(&client->server_read_ev, client->server_fd, EV_READ, server_forward_reply, client); event_add(&client->server_read_ev, &timeout_forward_server_read); }