|
|
|
@ -138,24 +138,46 @@ URIHANDLER_FUNC(mod_evasive_uri_handler) {
|
|
|
|
|
/* no limit set, nothing to block */
|
|
|
|
|
if (p->conf.max_conns == 0) return HANDLER_GO_ON;
|
|
|
|
|
|
|
|
|
|
switch (con->dst_addr.plain.sa_family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
default: // Address family not supported
|
|
|
|
|
return HANDLER_GO_ON;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < srv->conns->used; j++) {
|
|
|
|
|
connection *c = srv->conns->ptr[j];
|
|
|
|
|
|
|
|
|
|
/* check if other connections are already actively serving data for the same IP
|
|
|
|
|
* we can only ban connections which are already behind the 'read request' state
|
|
|
|
|
* */
|
|
|
|
|
if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr &&
|
|
|
|
|
c->state > CON_STATE_REQUEST_END) {
|
|
|
|
|
conns_by_ip++;
|
|
|
|
|
|
|
|
|
|
if (conns_by_ip > p->conf.max_conns) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "ss",
|
|
|
|
|
inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
|
|
|
|
|
"turned away. Too many connections.");
|
|
|
|
|
|
|
|
|
|
con->http_status = 403;
|
|
|
|
|
return HANDLER_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
if (c->dst_addr.plain.sa_family != con->dst_addr.plain.sa_family) continue;
|
|
|
|
|
if (c->state <= CON_STATE_REQUEST_END) continue;
|
|
|
|
|
|
|
|
|
|
switch (con->dst_addr.plain.sa_family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
if (c->dst_addr.ipv4.sin_addr.s_addr != con->dst_addr.ipv4.sin_addr.s_addr) continue;
|
|
|
|
|
break;
|
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
if (0 != memcmp(c->dst_addr.ipv6.sin6_addr.s6_addr, con->dst_addr.ipv6.sin6_addr.s6_addr, 16)) continue;
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
default: /* Address family not supported, should never be reached */
|
|
|
|
|
continue;
|
|
|
|
|
};
|
|
|
|
|
conns_by_ip++;
|
|
|
|
|
|
|
|
|
|
if (conns_by_ip > p->conf.max_conns) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "ss",
|
|
|
|
|
inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
|
|
|
|
|
"turned away. Too many connections.");
|
|
|
|
|
|
|
|
|
|
con->http_status = 403;
|
|
|
|
|
return HANDLER_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|