[core] move con throttling to connections-glue.c
move write throttling code from network.c:network_write_chunkqueue() to connections-glue.c:connection_write_chunkqueue() and fix the code to use TCP_CORK only on TCP sockets.personal/stbuehler/mod-csrf
parent
afce434e0b
commit
82feb70588
|
@ -1,5 +1,6 @@
|
|||
#include "first.h"
|
||||
|
||||
#include "sys-socket.h"
|
||||
#include "base.h"
|
||||
#include "connections.h"
|
||||
#include "log.h"
|
||||
|
@ -263,6 +264,81 @@ static handler_t connection_handle_read_post_chunked(server *srv, connection *co
|
|||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
static off_t connection_write_throttle(server *srv, connection *con, off_t max_bytes) {
|
||||
UNUSED(srv);
|
||||
if (con->conf.global_kbytes_per_second) {
|
||||
off_t limit = con->conf.global_kbytes_per_second * 1024 - *(con->conf.global_bytes_per_second_cnt_ptr);
|
||||
if (limit <= 0) {
|
||||
/* we reached the global traffic limit */
|
||||
con->traffic_limit_reached = 1;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
if (max_bytes > limit) max_bytes = limit;
|
||||
}
|
||||
}
|
||||
|
||||
if (con->conf.kbytes_per_second) {
|
||||
off_t limit = con->conf.kbytes_per_second * 1024 - con->bytes_written_cur_second;
|
||||
if (limit <= 0) {
|
||||
/* we reached the traffic limit */
|
||||
con->traffic_limit_reached = 1;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
if (max_bytes > limit) max_bytes = limit;
|
||||
}
|
||||
}
|
||||
|
||||
return max_bytes;
|
||||
}
|
||||
|
||||
int connection_write_chunkqueue(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) {
|
||||
int ret = -1;
|
||||
off_t written = 0;
|
||||
#ifdef TCP_CORK
|
||||
int corked = 0;
|
||||
#endif
|
||||
|
||||
max_bytes = connection_write_throttle(srv, con, max_bytes);
|
||||
if (0 == max_bytes) return 1;
|
||||
|
||||
written = cq->bytes_out;
|
||||
|
||||
#ifdef TCP_CORK
|
||||
/* Linux: put a cork into the socket as we want to combine the write() calls
|
||||
* but only if we really have multiple chunks, and only if TCP socket
|
||||
*/
|
||||
if (cq->first && cq->first->next) {
|
||||
const int sa_family = con->srv_socket->addr.plain.sa_family;
|
||||
if (sa_family == AF_INET || sa_family == AF_INET6) {
|
||||
corked = 1;
|
||||
(void)setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = con->network_write(srv, con, cq, max_bytes);
|
||||
if (ret >= 0) {
|
||||
chunkqueue_remove_finished_chunks(cq);
|
||||
ret = chunkqueue_is_empty(cq) ? 0 : 1;
|
||||
}
|
||||
|
||||
#ifdef TCP_CORK
|
||||
if (corked) {
|
||||
corked = 0;
|
||||
(void)setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
|
||||
}
|
||||
#endif
|
||||
|
||||
written = cq->bytes_out - written;
|
||||
con->bytes_written += written;
|
||||
con->bytes_written_cur_second += written;
|
||||
*(con->conf.global_bytes_per_second_cnt_ptr) += written;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
handler_t connection_handle_read_post_state(server *srv, connection *con) {
|
||||
chunkqueue *cq = con->read_queue;
|
||||
chunkqueue *dst_cq = con->request_content_queue;
|
||||
|
|
|
@ -476,7 +476,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
|
|||
}
|
||||
|
||||
static int connection_handle_write(server *srv, connection *con) {
|
||||
switch(network_write_chunkqueue(srv, con, con->write_queue, MAX_WRITE_LIMIT)) {
|
||||
switch(connection_write_chunkqueue(srv, con, con->write_queue, MAX_WRITE_LIMIT)) {
|
||||
case 0:
|
||||
con->write_request_ts = srv->cur_ts;
|
||||
if (con->file_finished) {
|
||||
|
|
|
@ -18,6 +18,7 @@ const char * connection_get_short_state(connection_state_t state);
|
|||
int connection_state_machine(server *srv, connection *con);
|
||||
handler_t connection_handle_read_post_state(server *srv, connection *con);
|
||||
handler_t connection_handle_read_post_error(server *srv, connection *con, int http_status);
|
||||
int connection_write_chunkqueue(server *srv, connection *con, chunkqueue *c, off_t max_bytes);
|
||||
void connection_response_reset(server *srv, connection *con);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -591,68 +591,3 @@ int network_register_fdevents(server *srv) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) {
|
||||
int ret = -1;
|
||||
off_t written = 0;
|
||||
#ifdef TCP_CORK
|
||||
int corked = 0;
|
||||
#endif
|
||||
|
||||
if (con->conf.global_kbytes_per_second) {
|
||||
off_t limit = con->conf.global_kbytes_per_second * 1024 - *(con->conf.global_bytes_per_second_cnt_ptr);
|
||||
if (limit <= 0) {
|
||||
/* we reached the global traffic limit */
|
||||
con->traffic_limit_reached = 1;
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
if (max_bytes > limit) max_bytes = limit;
|
||||
}
|
||||
}
|
||||
|
||||
if (con->conf.kbytes_per_second) {
|
||||
off_t limit = con->conf.kbytes_per_second * 1024 - con->bytes_written_cur_second;
|
||||
if (limit <= 0) {
|
||||
/* we reached the traffic limit */
|
||||
con->traffic_limit_reached = 1;
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
if (max_bytes > limit) max_bytes = limit;
|
||||
}
|
||||
}
|
||||
|
||||
written = cq->bytes_out;
|
||||
|
||||
#ifdef TCP_CORK
|
||||
/* Linux: put a cork into the socket as we want to combine the write() calls
|
||||
* but only if we really have multiple chunks
|
||||
*/
|
||||
if (cq->first && cq->first->next) {
|
||||
corked = 1;
|
||||
(void)setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = con->network_write(srv, con, cq, max_bytes);
|
||||
if (ret >= 0) {
|
||||
chunkqueue_remove_finished_chunks(cq);
|
||||
ret = chunkqueue_is_empty(cq) ? 0 : 1;
|
||||
}
|
||||
|
||||
#ifdef TCP_CORK
|
||||
if (corked) {
|
||||
corked = 0;
|
||||
(void)setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
|
||||
}
|
||||
#endif
|
||||
|
||||
written = cq->bytes_out - written;
|
||||
con->bytes_written += written;
|
||||
con->bytes_written_cur_second += written;
|
||||
|
||||
*(con->conf.global_bytes_per_second_cnt_ptr) += written;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
void network_accept_tcp_nagle_disable(int fd);
|
||||
|
||||
int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c, off_t max_bytes);
|
||||
|
||||
int network_init(server *srv);
|
||||
int network_close(server *srv);
|
||||
|
||||
|
|
Loading…
Reference in New Issue