|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|