Subj : Патч для apache httpd для ограничения числа соединений с одного IP.
-------------------------------------------------------------------------------
Limits for MaxDaemons serving a single address
MaxServers - Deprecated equivalent to MaxSpareServers
MaxServersPerIP - Maximum number of connections from a single IP address
MaxServersPerIPRead - Maximum number of connection from a single IP address in read state at any time.
ServersSafetyLimit - Deprecated equivalent to MaxClients
-----------------------------------------------------------------------------
ВЕРСИЯ 1: -------------
diff -ur apache_1.3.14rusPL30.0/src/include/http_conf_globals.h apache_1.3.14rusPL30.0-patch/src/include/http_conf_globals.h
--- apache_1.3.14rusPL30.0/src/include/http_conf_globals.h Sat Aug 21 02:44:56 1999
+++ apache_1.3.14rusPL30.0-patch/src/include/http_conf_globals.h Tue Sep 21 17:34:52 1999
@@ -86,6 +86,8 @@
extern int ap_daemons_limit;
extern MODULE_VAR_EXPORT int ap_suexec_enabled;
extern int ap_listenbacklog;
+extern int ap_daemons_max_by_ip;
+extern int ap_daemons_max_by_ip_read;
extern int ap_dump_settings;
extern API_VAR_EXPORT int ap_extended_status;
+void update_child_status_remote_ip (int, conn_rec *);
+int count_connections (conn_rec *, int);
+
#ifndef NO_OTHER_CHILD
/*
* register an other_child -- a child which the main loop keeps track of
diff -ur apache_1.3.14rusPL30.0/src/include/httpd.h apache_1.3.14rusPL30.0-patch/src/include/httpd.h
--- apache_1.3.14rusPL30.0/src/include/httpd.h Thu Sep 2 22:59:02 1999
+++ apache_1.3.14rusPL30.0-patch/src/include/httpd.h Tue Sep 21 17:34:53 1999
@@ -297,6 +297,12 @@
#define DEFAULT_MIN_FREE_DAEMON 5
#endif
+/* Define default limits for MaxDaemons serving a single address */
+
+#define DEFAULT_MAX_DAEMONS_BY_IP 150
+#define DEFAULT_MAX_DAEMONS_BY_IP_READ 75
+#define LIMIT_CONNECTIONS_BY_IP_ERROR HTTP_SERVICE_UNAVAILABLE
+
/* Limit on the total --- clients will be locked out if more servers than
* this are needed. It is intended solely to keep the server from crashing
* when things get out of hand.
diff -ur apache_1.3.14rusPL30.0/src/include/scoreboard.h apache_1.3.14rusPL30.0-patch/src/include/scoreboard.h
--- apache_1.3.14rusPL30.0/src/include/scoreboard.h Sat Aug 21 02:45:00 1999
+++ apache_1.3.14rusPL30.0-patch/src/include/scoreboard.h Tue Sep 21 17:34:53 1999
@@ -159,6 +159,7 @@
char request[64]; /* We just want an idea... */
server_rec *vhostrec; /* What virtual host is being accessed? */
/* SEE ABOVE FOR SAFE USAGE! */
+ unsigned long remoteip;
} short_score;
+int count_connections (conn_rec * current_conn, int state)
+{
+ unsigned long remote_ip = current_conn->remote_addr.sin_addr.s_addr;
+ int res = 0, i;
+
+ for (i = 0; i < HARD_SERVER_LIMIT; i++)
+ {
+ if ((ap_scoreboard_image->servers[i].status == SERVER_DEAD) ||
+ (state > 0 && ap_scoreboard_image->servers[i].status != state))
+ {
+ continue;
+ }
+ if (ap_scoreboard_image->servers[i].remoteip == remote_ip)
+ {
+ res++;
+ }
+ }
+ return res;
+}
+
void ap_time_process_request(int child_num, int status)
{
short_score *ss;
@@ -4021,12 +4075,15 @@
* until no requests are left or we decide to close.
*/
- while ((r = ap_read_request(current_conn)) != NULL) {
+ for (;;){
+ if (ap_daemons_max_by_ip || ap_daemons_max_by_ip_read)
+ update_child_status_remote_ip (my_child_num, (conn_rec *)current_conn);
+
+ if ((r = ap_read_request(current_conn)) == NULL) break;
/* read_request_line has already done a
* signal (SIGUSR1, SIG_IGN);
*/
-
(void) ap_update_child_status(my_child_num, SERVER_BUSY_WRITE, r);
/* process the request if it was read without error */
@@ -5248,7 +5305,10 @@
* until no requests are left or we decide to close.
*/
- while ((r = ap_read_request(current_conn)) != NULL) {
+ for (;;){
+ if (daemons_max_by_ip || daemons_max_by_ip_read)
+ update_child_status_remote_ip (child_num, (conn_rec *)current_conn);
+ if ((r = ap_read_request(current_conn)) == NULL) break;
(void) ap_update_child_status(child_num, SERVER_BUSY_WRITE, r);
if (r->status == HTTP_OK)
@@ -5273,6 +5333,10 @@
* client has ACKed our FIN and/or has stopped sending us data.
*/
ap_kill_cleanups_for_socket(ptrans, csd);
+
+ if (daemons_max_by_ip || daemons_max_by_ip_read)
+ update_child_status_remote_ip (child_num, (conn_rec *)NULL);
+
#ifdef NO_LINGCLOSE
ap_bclose(conn_io); /* just close it */
diff -ur apache_1.3.14rusPL30.0/src/main/http_protocol.c apache_1.3.14rusPL30.0-patch/src/main/http_protocol.c
--- apache_1.3.14rusPL30.0/src/main/http_protocol.c Thu Sep 2 22:59:02 1999
+++ apache_1.3.14rusPL30.0-patch/src/main/http_protocol.c Tue Sep 21 17:34:55 1999
@@ -73,6 +73,15 @@
#include "http_log.h" /* For errors detected in basic auth common
* support code... */
#include "util_date.h" /* For parseHTTPdate and BAD_DATE */
+
+#include "scoreboard.h" /* for limiting connections by IP */
+#ifndef LONG_STRING_LEN
+#define LONG_STRING_LEN 2048
+#endif /* LONG_STRING_LEN */
+extern int ap_daemons_max_by_ip;
+extern int ap_daemons_max_by_ip_read;
+extern void ap_die();
+
#include <stdarg.h>
#include "http_conf_globals.h"
@@ -935,6 +944,8 @@
pool *p;
const char *expect;
int access_status;
+ int current_connections;
+ char *reject_state = NULL;
p = ap_make_sub_pool(conn->pool);
r = ap_pcalloc(p, sizeof(request_rec));
@@ -966,6 +977,33 @@
r->read_length = 0;
r->read_body = REQUEST_NO_BODY;
+ if (ap_daemons_max_by_ip && ((current_connections = count_connections(conn,0))
+ > ap_daemons_max_by_ip))
+ {
+ r->request_time=time(NULL);
+ reject_state = "total";
+ }
+ else if (ap_daemons_max_by_ip_read &&
+ ((current_connections = count_connections(conn,SERVER_BUSY_READ))
+ > ap_daemons_max_by_ip_read))
+ {
+ reject_state = "read state";
+ }
+ if (reject_state) {
+ r->status = HTTP_OK;
+ r->request_time = time(NULL);
+ r->proto_num = 1000; /* or something */
+ r->assbackwards = 0; /* who knows... */
+ r->protocol = "HTTP/1.0"; /* just not empty */
+ r->the_request = NULL;
+ r->method = NULL;
+ r->method_number = M_INVALID;
+ ap_die(LIMIT_CONNECTIONS_BY_IP_ERROR, r);
+ ap_log_transaction(r);
+ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, conn->server, "Client at %s for %s with %d %s current connections", conn->remote_ip, conn->server->server_hostname, current_connections, reject_state);
+ return NULL;
+ }
+
r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
r->the_request = NULL;
----------------------------------------------------------------------------
ВЕРСИЯ 2: -------------
diff -ur apache_1.3.14rusPL30.0/src/include/http_conf_globals.h apache.patched/src/include/http_conf_globals.h
--- apache_1.3.14rusPL30.0/src/include/http_conf_globals.h Sat Oct 14 13:10:59 2000
+++ apache.patched/src/include/http_conf_globals.h Tue Nov 28 18:24:51 2000
@@ -89,6 +89,8 @@
extern API_VAR_EXPORT int ap_daemons_limit;
extern API_VAR_EXPORT int ap_suexec_enabled;
extern int ap_listenbacklog;
+extern int ap_daemons_max_by_ip;
+extern int ap_daemons_max_by_ip_read;
extern int ap_dump_settings;
extern API_VAR_EXPORT int ap_extended_status;
diff -ur apache_1.3.14rusPL30.0/src/include/http_main.h apache.patched/src/include/http_main.h
--- apache_1.3.14rusPL30.0/src/include/http_main.h Sat Oct 14 13:11:00 2000
+++ apache.patched/src/include/http_main.h Tue Nov 28 18:24:51 2000
@@ -129,6 +129,9 @@
void setup_signal_names(char *prefix);
+void update_child_status_remote_ip (int, conn_rec *);
+int count_connections (conn_rec *, int);
+
#ifndef NO_OTHER_CHILD
/*
* register an other_child -- a child which the main loop keeps track of
diff -ur apache_1.3.14rusPL30.0/src/include/httpd.h apache.patched/src/include/httpd.h
--- apache_1.3.14rusPL30.0/src/include/httpd.h Sat Oct 14 18:16:51 2000
+++ apache.patched/src/include/httpd.h Tue Nov 28 18:24:51 2000
@@ -299,6 +299,12 @@
#define DEFAULT_MIN_FREE_DAEMON 5
#endif
+/* Define default limits for MaxDaemons serving a single address */
+
+#define DEFAULT_MAX_DAEMONS_BY_IP 150
+#define DEFAULT_MAX_DAEMONS_BY_IP_READ 75
+#define LIMIT_CONNECTIONS_BY_IP_ERROR HTTP_SERVICE_UNAVAILABLE
+
/* Limit on the total --- clients will be locked out if more servers than
* this are needed. It is intended solely to keep the server from crashing
* when things get out of hand.
diff -ur apache_1.3.14rusPL30.0/src/include/scoreboard.h apache.patched/src/include/scoreboard.h
--- apache_1.3.14rusPL30.0/src/include/scoreboard.h Sat Oct 14 12:56:05 2000
+++ apache.patched/src/include/scoreboard.h Tue Nov 28 18:24:51 2000
@@ -160,6 +160,7 @@
char request[64]; /* We just want an idea... */
server_rec *vhostrec; /* What virtual host is being accessed? */
/* SEE ABOVE FOR SAFE USAGE! */
+ unsigned long remoteip;
} short_score;
+int count_connections (conn_rec * current_conn, int state)
+{
+ unsigned long remote_ip = current_conn->remote_addr.sin_addr.s_addr;
+ int res = 0, i;
+
+ for (i = 0; i < HARD_SERVER_LIMIT; i++)
+ {
+ if ((ap_scoreboard_image->servers[i].status == SERVER_DEAD) ||
+ (state > 0 && ap_scoreboard_image->servers[i].status != state))
+ {
+ continue;
+ }
+ if (ap_scoreboard_image->servers[i].remoteip == remote_ip)
+ {
+ res++;
+ }
+ }
+ return res;
+}
+
void ap_time_process_request(int child_num, int status)
{
short_score *ss;
@@ -4189,12 +4243,15 @@
* until no requests are left or we decide to close.
*/
- while ((r = ap_read_request(current_conn)) != NULL) {
+ for (;;){
+ if (ap_daemons_max_by_ip || ap_daemons_max_by_ip_read)
+ update_child_status_remote_ip (my_child_num, (conn_rec *)current_conn);
+
+ if ((r = ap_read_request(current_conn)) == NULL) break;
/* read_request_line has already done a
* signal (SIGUSR1, SIG_IGN);
*/
-
(void) ap_update_child_status(my_child_num, SERVER_BUSY_WRITE, r);
/* process the request if it was read without error */
@@ -5463,6 +5520,10 @@
* client has ACKed our FIN and/or has stopped sending us data.
*/
ap_kill_cleanups_for_socket(ptrans, csd);
+
+ if (daemons_max_by_ip || daemons_max_by_ip_read)
+ update_child_status_remote_ip (child_num, (conn_rec *)NULL);
+
#ifdef NO_LINGCLOSE
ap_bclose(conn_io); /* just close it */
Only in apache.patched/src/main: http_main.c.rej
Only in apache.patched/src/main: http_main.c~
diff -ur apache_1.3.14rusPL30.0/src/main/http_protocol.c apache.patched/src/main/http_protocol.c
--- apache_1.3.14rusPL30.0/src/main/http_protocol.c Sat Oct 14 18:16:51 2000
+++ apache.patched/src/main/http_protocol.c Tue Nov 28 18:24:52 2000
@@ -73,6 +73,15 @@
#include "http_log.h" /* For errors detected in basic auth common
* support code... */
#include "util_date.h" /* For parseHTTPdate and BAD_DATE */
+
+#include "scoreboard.h" /* for limiting connections by IP */
+#ifndef LONG_STRING_LEN
+#define LONG_STRING_LEN 2048
+#endif /* LONG_STRING_LEN */
+extern int ap_daemons_max_by_ip;
+extern int ap_daemons_max_by_ip_read;
+extern void ap_die();
+
#include <stdarg.h>
#include "http_conf_globals.h"
@@ -1039,6 +1048,8 @@
pool *p;
const char *expect;
int access_status;
+ int current_connections;
+ char *reject_state = NULL;
p = ap_make_sub_pool(conn->pool);
r = ap_pcalloc(p, sizeof(request_rec));
@@ -1070,6 +1081,33 @@
r->read_length = 0;
r->read_body = REQUEST_NO_BODY;
+ if (ap_daemons_max_by_ip && ((current_connections = count_connections(conn,0))
+ > ap_daemons_max_by_ip))
+ {
+ r->request_time=time(NULL);
+ reject_state = "total";
+ }
+ else if (ap_daemons_max_by_ip_read &&
+ ((current_connections = count_connections(conn,SERVER_BUSY_READ))
+ > ap_daemons_max_by_ip_read))
+ {
+ reject_state = "read state";
+ }
+ if (reject_state) {
+ r->status = HTTP_OK;
+ r->request_time = time(NULL);
+ r->proto_num = 1000; /* or something */
+ r->assbackwards = 0; /* who knows... */
+ r->protocol = "HTTP/1.0"; /* just not empty */
+ r->the_request = NULL;
+ r->method = NULL;
+ r->method_number = M_INVALID;
+ ap_die(LIMIT_CONNECTIONS_BY_IP_ERROR, r);
+ ap_log_transaction(r);
+ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, conn->server, "Client at %s for %s with %d %s current connections", conn->remote_ip, conn->server->server_hostname, current_connections, reject_state);
+ return NULL;
+ }
+
r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
r->the_request = NULL;
945 Прочтений • [Патч для apache httpd для ограничения числа соединений с одного IP. (apache patch limit web suexec)] [08.05.2012] [Комментариев: 0]