From cd2df1e3082a6dec5c39c3e93cdbe6c8a11e246e Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
Date: Mon, 23 Jun 2008 21:26:05 +0200
Subject: [PATCH] Fix mod_evasive IPv6 (#1579)
---
src/mod_evasive.c | 46 ++++++++++++++++++++++++++++++++++------------
1 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/src/mod_evasive.c b/src/mod_evasive.c
index 3415953..e415f88 100644
|
a
|
b
|
|
| 138 | 138 | /* no limit set, nothing to block */ |
| 139 | 139 | if (p->conf.max_conns == 0) return HANDLER_GO_ON; |
| 140 | 140 | |
| | 141 | switch (con->dst_addr.plain.sa_family) { |
| | 142 | case AF_INET: |
| | 143 | #ifdef HAVE_IPV6 |
| | 144 | case AF_INET6: |
| | 145 | #endif |
| | 146 | break; |
| | 147 | default: // Address family not supported |
| | 148 | return HANDLER_GO_ON; |
| | 149 | }; |
| | 150 | |
| 141 | 151 | for (j = 0; j < srv->conns->used; j++) { |
| 142 | 152 | connection *c = srv->conns->ptr[j]; |
| 143 | 153 | |
| 144 | 154 | /* check if other connections are already actively serving data for the same IP |
| 145 | 155 | * we can only ban connections which are already behind the 'read request' state |
| 146 | 156 | * */ |
| 147 | | if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr && |
| 148 | | c->state > CON_STATE_REQUEST_END) { |
| 149 | | conns_by_ip++; |
| 150 | | |
| 151 | | if (conns_by_ip > p->conf.max_conns) { |
| 152 | | log_error_write(srv, __FILE__, __LINE__, "ss", |
| 153 | | inet_ntop_cache_get_ip(srv, &(con->dst_addr)), |
| 154 | | "turned away. Too many connections."); |
| 155 | | |
| 156 | | con->http_status = 403; |
| 157 | | return HANDLER_FINISHED; |
| 158 | | } |
| | 157 | if (c->dst_addr.plain.sa_family != con->dst_addr.plain.sa_family) continue; |
| | 158 | if (c->state <= CON_STATE_REQUEST_END) continue; |
| | 159 | |
| | 160 | switch (con->dst_addr.plain.sa_family) { |
| | 161 | case AF_INET: |
| | 162 | if (c->dst_addr.ipv4.sin_addr.s_addr != con->dst_addr.ipv4.sin_addr.s_addr) continue; |
| | 163 | break; |
| | 164 | #ifdef HAVE_IPV6 |
| | 165 | case AF_INET6: |
| | 166 | if (0 != memcmp(c->dst_addr.ipv6.sin6_addr.s6_addr, con->dst_addr.ipv6.sin6_addr.s6_addr, 16)) continue; |
| | 167 | break; |
| | 168 | #endif |
| | 169 | default: /* Address family not supported, should never be reached */ |
| | 170 | continue; |
| | 171 | }; |
| | 172 | conns_by_ip++; |
| | 173 | |
| | 174 | if (conns_by_ip > p->conf.max_conns) { |
| | 175 | log_error_write(srv, __FILE__, __LINE__, "ss", |
| | 176 | inet_ntop_cache_get_ip(srv, &(con->dst_addr)), |
| | 177 | "turned away. Too many connections."); |
| | 178 | |
| | 179 | con->http_status = 403; |
| | 180 | return HANDLER_FINISHED; |
| 159 | 181 | } |
| 160 | 182 | } |
| 161 | 183 | |