diff -r -d -u -N squid-1.1.22/README.MIME_INTERCEPT squid-1.1.22-mint/README.MIME_INTERCEPT --- squid-1.1.22/README.MIME_INTERCEPT Thu Jan 1 01:00:00 1970 +++ squid-1.1.22-mint/README.MIME_INTERCEPT Sun Aug 2 13:00:50 1998 @@ -0,0 +1,67 @@ +If you have a fast internet connection, users tend to abuse it - +for loading large pictures, listening to real audio streams and other +bandwidth- and money-wasting activities. Denying special user agents like +"RealPlayer" helps only until the next player appears, disabling images +makes many sites unusable. + +The solution is filtering and bandwidth limiting on mime type after the +connection has been established. The mime intercept patch adds this feature +to the squid cache. After installing, you get a new configuration keyword: + +mime_intercept regex free_bytes bytes_sec + +regex allows you to specify a regular expression that is matched on the mime +type, free_bytes is the number of bytes that will be transferred without +delay, bytes_sec contains the number of bytes that will be transferred per +second after free_bytes is exhausted. Multiple mime_intercept lines will +be interpreted bottom to top, so put the most exact expression at the end. +An unknown mime type will be transferred without delay. + +Example: + +mime_intercept ^audio/.*$ 8192 512 +mime_intercept ^image/.*$ 32768 4096 +mime_intercept ^image/jpeg$ 16384 1024 + +All images will be limited to 4K/sec after 32K has been transferred except +JPEGs. Here you get 1K/sec after 16K. Audio files will almost get stuck +within the cable at 512 Bytes/sec. Everything else is left alone. + + +Caveats and TODOs: + +-This is *ALPHA* stuff! The code comes without any warranties, so use at + your own risk. Look at the GNU public license for further information. + +-Allow aborting a transfer by setting bytes_sec to zero. I don't know if + it is safe to call comm_close within icpSendMoreData, I have to try. + +-Better integration into squid. + +-Squid starts delaying the connected server after the client is about 300K + back. So the cache won't be a nice internet citizen if users insist on + downloading large files with a low bytes_sec. Anyway, those people + penetrating the net with real audio shit deserve it. ;-) + +-Squid cannot determine the mime type of very small files, so my patch cannot + kick in here. This shouldn't be an issue. + +-Don't set bytes_sec too low. Squid cannot realize that a client has + aborted when it does not send data. + +-You might need more filedescriptors as connections stay active for a longer + period. + +-Don't trust me. Try to understand what I coded. + +The primary site of this patch is http://techwww.telemation.de/bofh/. You +can reach me via email at srompf@telemation.de. Hope this software is +useful for somebody. + +Stefan + + + + + + diff -r -d -u -N squid-1.1.22/src/Makefile.in squid-1.1.22-mint/src/Makefile.in --- squid-1.1.22/src/Makefile.in Thu Jun 25 19:15:29 1998 +++ squid-1.1.22-mint/src/Makefile.in Sat Aug 1 16:46:38 1998 @@ -20,13 +20,14 @@ UNDERSCORES_OPT = # -DALLOW_HOSTNAME_UNDERSCORES RETRY_PATCH = -DRETRY_PATCH NO_CACHE_ACL = # -DNO_CACHE_ACL=1 +MIME_INTERCEPT = -DMIME_INTERCEPT DEFINES = $(HOST_OPT) $(AUTH_OPT) $(LOG_HDRS_OPT) \ $(ICMP_OPT) $(DELAY_HACK) $(USERAGENT_OPT) \ $(KILL_PARENT_OPT) $(USE_POLL_OPT) \ $(USE_SPLAY_TREE) $(USE_BIN_TREE) \ $(RELOAD_INTO_IMS) $(UNDERSCORES_OPT) \ - $(RETRY_PATCH) $(NO_CACHE_ACL) + $(RETRY_PATCH) $(NO_CACHE_ACL) $(MIME_INTERCEPT) prefix = @prefix@ exec_prefix = @exec_prefix@ diff -r -d -u -N squid-1.1.22/src/cache_cf.c squid-1.1.22-mint/src/cache_cf.c --- squid-1.1.22/src/cache_cf.c Sat May 2 01:20:58 1998 +++ squid-1.1.22-mint/src/cache_cf.c Sun Aug 2 11:14:17 1998 @@ -1031,6 +1031,39 @@ *iptr = ANONYMIZER_STANDARD; } +#if MIME_INTERCEPT +static void +parseMimeIntercept(void) { + mime_intlist *nml; + char *token; + int i; + + nml = xcalloc(1,sizeof(mime_intlist)); + token = strtok(NULL, w_space); + if (token == NULL) + self_destruct(); + if (regcomp(&nml->rex,token,0)) /* Compile token */ + self_destruct(); + GetInteger(i); + nml->sendok = i; + GetInteger(i); + nml->bsek = i; + nml->next = Config.mime_int; /* Put into list */ + Config.mime_int = nml; +} + +static void mime_int_destroy(void) { + mime_intlist *ml; + + while (Config.mime_int) { + ml = Config.mime_int; + Config.mime_int = ml->next; + regfree(&ml->rex); + safe_free(ml); + } +} +#endif + int parseConfigFile(const char *file_name) { @@ -1419,7 +1452,10 @@ else if (!strcmp(token, "maximum_single_addr_tries")) parseIntegerValue(&Config.Retry.max_single_addr); #endif /* RETRY_PATCH */ - +#if MIME_INTERCEPT + else if (!strcmp(token, "mime_intercept")) + parseMimeIntercept(); +#endif /* If unknown, treat as a comment line */ else { debug(3, 0, "parseConfigFile: line %d unrecognized: '%s'\n", @@ -1563,6 +1599,9 @@ ip_acl_destroy(&Config.local_ip_list); ip_acl_destroy(&Config.firewall_ip_list); objcachePasswdDestroy(&Config.passwd_list); +#if MIME_INTERCEPT + mime_int_destroy(); +#endif refreshFreeMemory(); } diff -r -d -u -N squid-1.1.22/src/cache_cf.h squid-1.1.22-mint/src/cache_cf.h --- squid-1.1.22/src/cache_cf.h Thu Apr 9 06:58:14 1998 +++ squid-1.1.22-mint/src/cache_cf.h Sat Aug 1 19:42:49 1998 @@ -137,6 +137,15 @@ struct _ip_acl *next; } ip_acl; +#if MIME_INTERCEPT +typedef struct _mime_intlist { + regex_t rex; + int sendok; + int bsek; + struct _mime_intlist *next; +} mime_intlist; +#endif + struct SquidConfig { struct { int maxSize; @@ -290,6 +299,9 @@ int max_single_addr; } Retry; #endif /* RETRY_PATCH */ +#if MIME_INTERCEPT + mime_intlist *mime_int; +#endif }; extern struct SquidConfig Config; @@ -314,3 +326,5 @@ #endif /* ndef _CACHE_CONFIG_H_ */ + + diff -r -d -u -N squid-1.1.22/src/comm.c squid-1.1.22-mint/src/comm.c --- squid-1.1.22/src/comm.c Thu Apr 9 06:58:15 1998 +++ squid-1.1.22-mint/src/comm.c Sat Aug 1 16:55:31 1998 @@ -840,6 +840,15 @@ fd_table[fd].stall_until = squid_curtime + delta; } +#ifdef MIME_INTERCEPT +void +comm_set_wstall(int fd, int delta) +{ + if (fd < 0) + return; + fd_table[fd].wstall_until = squid_curtime + delta; +} +#endif #ifdef USE_POLL @@ -1012,6 +1021,9 @@ if (fd_table[i].read_handler && fd_table[i].stall_until <= squid_curtime) events |= POLLRDNORM; if (fd_table[i].write_handler) +#ifdef MIME_INTERCEPT + if (fd_table[i].wstall_until <= squid_curtime) +#endif events |= POLLWRNORM; if (events) { if (i == theHttpConnection) @@ -1202,8 +1214,14 @@ } } if (fd_table[i].write_handler) { +#ifdef MIME_INTERCEPT + if (fd_table[i].wstall_until <= squid_curtime) { +#endif nfds++; FD_SET(i, &writefds); +#ifdef MIME_INTERCEPT + } +#endif } } if (!fdstat_are_n_free_fd(RESERVED_FD) && theHttpConnection >= 0) { diff -r -d -u -N squid-1.1.22/src/comm.h squid-1.1.22-mint/src/comm.h --- squid-1.1.22/src/comm.h Thu Apr 9 06:58:16 1998 +++ squid-1.1.22-mint/src/comm.h Sat Aug 1 17:09:17 1998 @@ -181,6 +181,9 @@ char ascii_note[FD_ASCII_NOTE_SZ]; unsigned int comm_type; time_t stall_until; /* don't select for read until this time reached */ +#if MIME_INTERCEPT + time_t wstall_until; /* don't select for write */ +#endif RWStateData *rwstate; /* State data for comm_write */ } FD_ENTRY; @@ -209,6 +212,9 @@ extern int comm_udp_sendto _PARAMS((int fd, const struct sockaddr_in *, int size, const char *buf, int len)); extern int fd_of_first_client _PARAMS((StoreEntry *)); extern void comm_set_stall _PARAMS((int, int)); +#if MIME_INTERCEPT +extern void comm_set_wstall _PARAMS((int, int)); +#endif extern void comm_write _PARAMS((int fd, char *buf, int size, diff -r -d -u -N squid-1.1.22/src/icp.c squid-1.1.22-mint/src/icp.c --- squid-1.1.22/src/icp.c Sat May 2 01:21:00 1998 +++ squid-1.1.22-mint/src/icp.c Sun Aug 2 11:49:03 1998 @@ -570,6 +570,33 @@ } #endif /* LOG_FULL_HEADERS */ + +#ifdef MIME_INTERCEPT +/* Setup delay for specific MIME type. This might be an ugly hack.. */ +static void +icpSetupIntercept(icpStateData *icpState) +{ + if (icpState->entry->mem_obj) { /* icpSendMoreData looks as this might + unset at some time... */ + char *mime=icpState->entry->mem_obj->reply->content_type; + mime_intlist *ml = Config.mime_int; + short inset = 1; + + icpState->mint_setup = 1; /* We did setup for this connection */ + while (ml && inset) { + if (!regexec(&ml->rex,mime,0,0,0)) { + icpState->mint_sendok = ml->sendok; + icpState->mint_bsek = ml->bsek; + inset = 0; + } + ml = ml->next; + } + if (inset) icpState->mint_sendok = INT_MAX; /* Nothing found... */ + /* printf("Mime-Type %s, %d, %d\n",mime,icpState->mint_sendok,icpState->mint_bsek); */ + } +} +#endif + /* Send available data from an object in the cache. This is called either * on select for write or directly by icpHandleStore. */ @@ -620,6 +647,19 @@ if (hack) *(buf + size++) = C; } +#if MIME_INTERCEPT + if (!icpState->mint_setup) icpSetupIntercept(icpState); + icpState->mint_sent += len; + if (icpState->mint_sent > icpState->mint_sendok) { + int delay = 0; + if (icpState->mint_bsek) + delay = (icpState->mint_sent-icpState->mint_sendok) / icpState->mint_bsek; + icpState->mint_sendok=icpState->mint_sent; + /* printf ("Delay = %d, Mime %s\n",delay, + entry->mem_obj?entry->mem_obj->reply->content_type:"Leer"); */ + comm_set_wstall(fd,delay); + } +#endif comm_write(fd, buf, len, diff -r -d -u -N squid-1.1.22/src/icp.h squid-1.1.22-mint/src/icp.h --- squid-1.1.22/src/icp.h Mon Dec 15 09:43:21 1997 +++ squid-1.1.22-mint/src/icp.h Sat Aug 1 19:59:36 1998 @@ -201,6 +201,12 @@ } ident; int ip_lookup_pending; int redirect_state; +#if MIME_INTERCEPT + int mint_sendok; + int mint_bsek; + int mint_sent; + int mint_setup; +#endif } icpStateData; extern void *icpCreateMessage _PARAMS((icp_opcode opcode,