From 88148c9c0d3638daef215b88325ba8c29d25dfae Mon Sep 17 00:00:00 2001 From: sosherof Date: Tue, 26 Oct 2021 11:13:56 -0700 Subject: [PATCH 1/8] Updated fixes for Windows timer resolution. Added client bandwidth tracking to bypass sleeping if client's bandwidth is already less than available. --- .gitattributes | 63 +++++++++ .gitignore | 363 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 426 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file From 4598bcff9f8fdd67fb31e6dffcb8332f8d6179c0 Mon Sep 17 00:00:00 2001 From: sosherof Date: Tue, 26 Oct 2021 11:27:43 -0700 Subject: [PATCH 2/8] Updated fixes for Windows timer resolution. Added client bandwidth tracking to bypass sleeping if client's bandwidth is already less than available. --- .gitignore | 366 +---------------------------------------------------- 1 file changed, 4 insertions(+), 362 deletions(-) diff --git a/.gitignore b/.gitignore index 9491a2f..eaf39de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,363 +1,5 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Oo]ut/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +/.vs/mod_bw/v16 From 794ee8d1fbe55eed26455b6cd20bb0bca31c304a Mon Sep 17 00:00:00 2001 From: Sam Osheroff Date: Tue, 26 Oct 2021 11:29:26 -0700 Subject: [PATCH 3/8] Delete .gitattributes --- .gitattributes | 63 -------------------------------------------------- 1 file changed, 63 deletions(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 1ff0c42..0000000 --- a/.gitattributes +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto - -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp - -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain From b0eba9cde8771a9136a09f277c45d9649ffb3c80 Mon Sep 17 00:00:00 2001 From: Sam Osheroff Date: Tue, 26 Oct 2021 11:29:41 -0700 Subject: [PATCH 4/8] Delete .gitignore --- .gitignore | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index eaf39de..0000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -################################################################################ -# This .gitignore file was automatically created by Microsoft(R) Visual Studio. -################################################################################ - -/.vs/mod_bw/v16 From 2406866ca6281d93cb18781f4ffa611df82a89bd Mon Sep 17 00:00:00 2001 From: sosherof Date: Tue, 26 Oct 2021 11:33:30 -0700 Subject: [PATCH 5/8] Updated fix for Windows sleep time resolution. Added client bandwidth calcuations to avoid sleeping if client bandwidth is less than available. --- mod_bw.c | 582 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 322 insertions(+), 260 deletions(-) diff --git a/mod_bw.c b/mod_bw.c index 2b24696..33959ad 100644 --- a/mod_bw.c +++ b/mod_bw.c @@ -24,11 +24,11 @@ Platform : Linux/x86 (Tested with Fedora Core 4, Suse, etc) Notes : This is a stable version of mod_bw. It should work with almost any MPM (tested with WinNT/prefork/Worker MPM). - We are reaching the End of mod_bw series 0.x. As soon as this + We are reaching the End of mod_bw series 0.x. As soon as this last changes are confirmed by the users (perhaps some changes at request), i'll set this release to version 1.0 final. -Limitations : This mod doesn't know how fast the client is +Limitations : This mod doesn't know how fast the client is downloading a file, so it just divides the bw assigned between the users. MaxConnections works only for the given scope. (i.e , all @@ -39,8 +39,8 @@ Changelog : 2010-07-20 : Fixed ap_get_server_banner unknown on older apache version 2010-05-27 : Fixed weird behaviour on Windows Hosts. (mod_bw.txt) Added high resolution timers for windows. (speed improvements) - Fixed stupid bug that caused crash when mod is enabled but there is - not a single limit. + Fixed stupid bug that caused crash when mod is enabled but there is + not a single limit. 2010-05-24 : Code Cleanup. No more warnings or stuff in Visual Studio 2010-04-28 : Bruce's Birthday Gift : A callback to the stats of the mod :) 2010-04-06 : Fixed "Invisible" memory leak. Only seen when serving HUGE streams. @@ -71,11 +71,11 @@ Changelog : #include "scoreboard.h" #if defined(WIN32) - #include - #include +#include +#include +#include #endif - #define MIN_BW 256 /* Minimal bandwidth 256 bytes */ #define PACKET 8192 /* Default packet at 8192 bytes */ #define MAX_VHOSTS 1024 /* Default number of vhosts to show in stats */ @@ -86,23 +86,23 @@ Changelog : /* Compatibility with regex on apache less than 2.1 */ #if !AP_MODULE_MAGIC_AT_LEAST(20050127,0) - typedef regex_t ap_regex_t; - #define AP_REG_EXTENDED REG_EXTENDED - #define AP_REG_ICASE REG_ICASE +typedef regex_t ap_regex_t; +#define AP_REG_EXTENDED REG_EXTENDED +#define AP_REG_ICASE REG_ICASE #endif /* Compatibility with obsolete ap_get_server_version() */ #if !AP_MODULE_MAGIC_AT_LEAST(20051115,4) - #define ap_get_server_banner ap_get_server_version +#define ap_get_server_banner ap_get_server_version #endif /* Compatibility for APR < 1 */ #if ( defined(APR_MAJOR_VERSION) && (APR_MAJOR_VERSION < 1) ) - #define apr_atomic_inc32 apr_atomic_inc - #define apr_atomic_dec32 apr_atomic_dec - #define apr_atomic_add32 apr_atomic_add - #define apr_atomic_cas32 apr_atomic_cas - #define apr_atomic_set32 apr_atomic_set +#define apr_atomic_inc32 apr_atomic_inc +#define apr_atomic_dec32 apr_atomic_dec +#define apr_atomic_add32 apr_atomic_add +#define apr_atomic_cas32 apr_atomic_cas +#define apr_atomic_set32 apr_atomic_set #endif /* Enum types of "from address" */ @@ -113,7 +113,7 @@ enum from_type { T_AGENT }; -/* +/* - Stats of each conf - - id = Configuration ID @@ -127,10 +127,10 @@ enum from_type { typedef struct { apr_uint32_t id; - char *v_name; + char* v_name; apr_uint32_t connection_count; apr_uint32_t bandwidth; - apr_uint32_t bytes_count; + unsigned long long bytes_count; apr_uint32_t counter; volatile apr_uint32_t lock; apr_time_t time; @@ -139,16 +139,19 @@ typedef struct /* A temporal context to save our splitted brigade */ typedef struct ctx_struct_t { - apr_bucket_brigade *bb; + apr_bucket_brigade* bb; struct timeval wait; + unsigned long long bw_interval_bytes, bw_interval_slept, client_bw; + apr_time_t bw_interval_start_time; + long sleep_bypasses_left, sleep_bypasses_total; } ctx_struct; -/* With sid we count the shared memory needed. +/* With sid we count the shared memory needed. BwBase, is a holder to the shared memory base addres */ -static char *vnames[MAX_VHOSTS]; +static char* vnames[MAX_VHOSTS]; static int sid = 0; -bw_data *bwbase; -apr_shm_t *shm; +bw_data* bwbase; +apr_shm_t* shm; /* Limits for MaxConnections based on directory */ @@ -156,10 +159,10 @@ typedef struct { apr_uint32_t sid; union { - char *from; - apr_ipsubnet_t *ip; + char* from; + apr_ipsubnet_t* ip; } x; - ap_regex_t *agent; + ap_regex_t* agent; enum from_type type; apr_uint32_t max; } bw_maxconn; @@ -169,10 +172,10 @@ typedef struct { apr_uint32_t sid; union { - char *from; - apr_ipsubnet_t *ip; + char* from; + apr_ipsubnet_t* ip; } x; - ap_regex_t *agent; + ap_regex_t* agent; enum from_type type; apr_int32_t rate; } bw_entry; @@ -181,7 +184,7 @@ typedef struct typedef struct { apr_uint32_t sid; - char *file; + char* file; apr_uint32_t size; apr_uint32_t rate; } bw_sizel; @@ -189,13 +192,13 @@ typedef struct /* Per directory configuration structure */ typedef struct { - apr_array_header_t *limits; - apr_array_header_t *minlimits; - apr_array_header_t *sizelimits; - apr_array_header_t *maxconnection; - int packet; + apr_array_header_t* limits; + apr_array_header_t* minlimits; + apr_array_header_t* sizelimits; + apr_array_header_t* maxconnection; + unsigned int packet; int error; - char *directory; + char* directory; } bandwidth_config; /* Per server configuration structure */ @@ -211,39 +214,39 @@ module AP_MODULE_DECLARE_DATA bw_module; /*---------------------------------------------------------------------* * Configurations Directives * *---------------------------------------------------------------------*/ -/* Set the mod enabled ... or disabled */ -static const char *bandwidthmodule(cmd_parms * cmd, void *dconf, int flag) + /* Set the mod enabled ... or disabled */ +static const char* bandwidthmodule(cmd_parms* cmd, void* dconf, int flag) { - bandwidth_server_config *sconf; + bandwidth_server_config* sconf; sconf = - (bandwidth_server_config *) ap_get_module_config(cmd->server-> - module_config, - &bw_module); + (bandwidth_server_config*)ap_get_module_config(cmd->server-> + module_config, + &bw_module); sconf->state = (flag ? BANDWIDTH_ENABLED : BANDWIDTH_DISABLED); return NULL; } /* Set force mode enabled ... or disabled */ -static const char *forcebandwidthmodule(cmd_parms * cmd, void *dconf, - int flag) +static const char* forcebandwidthmodule(cmd_parms* cmd, void* dconf, + int flag) { - bandwidth_server_config *sconf; + bandwidth_server_config* sconf; sconf = - (bandwidth_server_config *) ap_get_module_config(cmd->server-> - module_config, - &bw_module); + (bandwidth_server_config*)ap_get_module_config(cmd->server-> + module_config, + &bw_module); sconf->force = (flag ? BANDWIDTH_ENABLED : BANDWIDTH_DISABLED); return NULL; } /* Set the packetsize used in the context */ -static const char *setpacket(cmd_parms * cmd, void *s, const char *pack) +static const char* setpacket(cmd_parms* cmd, void* s, const char* pack) { - bandwidth_config *conf = (bandwidth_config *) s; + bandwidth_config* conf = (bandwidth_config*)s; int temp; if (pack && *pack && apr_isdigit(*pack)) @@ -260,9 +263,9 @@ static const char *setpacket(cmd_parms * cmd, void *s, const char *pack) } /* Set the error to send when maxconnections is reached */ -static const char *bandwidtherror(cmd_parms * cmd, void *s, const char *err) +static const char* bandwidtherror(cmd_parms* cmd, void* s, const char* err) { - bandwidth_config *conf = (bandwidth_config *) s; + bandwidth_config* conf = (bandwidth_config*)s; int temp; if (err && *err && apr_isdigit(*err)) @@ -279,14 +282,14 @@ static const char *bandwidtherror(cmd_parms * cmd, void *s, const char *err) } /* Set the maxconnections on a per host basis */ -static const char *maxconnection(cmd_parms * cmd, void *s, const char *from, - const char *maxc) +static const char* maxconnection(cmd_parms* cmd, void* s, const char* from, + const char* maxc) { - bandwidth_config *conf = (bandwidth_config *) s; - bw_maxconn *a; + bandwidth_config* conf = (bandwidth_config*)s; + bw_maxconn* a; int temp; - char *str; - char *where = (char *) apr_pstrdup(cmd->pool, from); + char* str; + char* where = (char*)apr_pstrdup(cmd->pool, from); apr_status_t rv; char msgbuf[MAX_BUF]; @@ -297,19 +300,19 @@ static const char *maxconnection(cmd_parms * cmd, void *s, const char *from, if (temp < 0) return - "Connections must be a number of simultaneous connections allowed/s"; + "Connections must be a number of simultaneous connections allowed/s"; - a = (bw_maxconn *) apr_array_push(conf->maxconnection); + a = (bw_maxconn*)apr_array_push(conf->maxconnection); a->x.from = where; - if (!strncasecmp(where,"u:",2)) - { + if (!strncasecmp(where, "u:", 2)) + { /* Do not limit based on origin, but on user agent */ a->type = T_AGENT; - a->agent = ap_pregcomp(cmd->pool, where+2, 0); + a->agent = ap_pregcomp(cmd->pool, where + 2, 0); if (a->agent == NULL) return "Regular expression could not be compiled."; - + } else if (!strcasecmp(where, "all")) { a->type = T_ALL; @@ -317,7 +320,7 @@ static const char *maxconnection(cmd_parms * cmd, void *s, const char *from, else if ((str = strchr(where, '/'))) { *str++ = '\0'; rv = apr_ipsubnet_create(&a->x.ip, where, str, cmd->pool); - if(APR_STATUS_IS_EINVAL(rv)) { + if (APR_STATUS_IS_EINVAL(rv)) { /* looked nothing like an IP address */ return "An IP address was expected"; } @@ -326,14 +329,14 @@ static const char *maxconnection(cmd_parms * cmd, void *s, const char *from, return apr_pstrdup(cmd->pool, msgbuf); } a->type = T_IP; - } + } else if (!APR_STATUS_IS_EINVAL(rv = apr_ipsubnet_create(&a->x.ip, where, NULL, cmd->pool))) { if (rv != APR_SUCCESS) { apr_strerror(rv, msgbuf, sizeof msgbuf); return apr_pstrdup(cmd->pool, msgbuf); } a->type = T_IP; - } + } else { /* no slash, didn't look like an IP address => must be a host */ a->type = T_HOST; } @@ -344,14 +347,14 @@ static const char *maxconnection(cmd_parms * cmd, void *s, const char *from, } /* Set the bandwidth on a per host basis */ -static const char *bandwidth(cmd_parms * cmd, void *s, const char *from, - const char *bw) +static const char* bandwidth(cmd_parms* cmd, void* s, const char* from, + const char* bw) { - bandwidth_config *conf = (bandwidth_config *) s; - bw_entry *a; + bandwidth_config* conf = (bandwidth_config*)s; + bw_entry* a; long int temp; - char *str; - char *where = (char *) apr_pstrdup(cmd->pool, from); + char* str; + char* where = (char*)apr_pstrdup(cmd->pool, from); apr_status_t rv; char msgbuf[MAX_BUF]; @@ -364,16 +367,16 @@ static const char *bandwidth(cmd_parms * cmd, void *s, const char *from, if (temp < 0) return "BandWidth must be a number of bytes/s"; - a = (bw_entry *) apr_array_push(conf->limits); + a = (bw_entry*)apr_array_push(conf->limits); a->x.from = where; - if (!strncasecmp(where,"u:",2)) + if (!strncasecmp(where, "u:", 2)) { /* Do not limit based on origin, but on user agent */ a->type = T_AGENT; - a->agent = ap_pregcomp(cmd->pool, where+2, 0); + a->agent = ap_pregcomp(cmd->pool, where + 2, 0); if (a->agent == NULL) - return "Regular expression could not be compiled."; - + return "Regular expression could not be compiled."; + } else if (!strcasecmp(where, "all")) { a->type = T_ALL; @@ -381,7 +384,7 @@ static const char *bandwidth(cmd_parms * cmd, void *s, const char *from, else if ((str = strchr(where, '/'))) { *str++ = '\0'; rv = apr_ipsubnet_create(&a->x.ip, where, str, cmd->pool); - if(APR_STATUS_IS_EINVAL(rv)) { + if (APR_STATUS_IS_EINVAL(rv)) { /* looked nothing like an IP address */ return "An IP address was expected"; } @@ -403,8 +406,8 @@ static const char *bandwidth(cmd_parms * cmd, void *s, const char *from, } if (sid < MAX_VHOSTS) { - vnames[sid] = apr_pcalloc(cmd->pool,apr_snprintf(msgbuf,MAX_BUF,"%s,%s",cmd->server->server_hostname,where) ); - vnames[sid] = (char *) apr_pstrdup(cmd->pool, msgbuf); + vnames[sid] = apr_pcalloc(cmd->pool, apr_snprintf(msgbuf, MAX_BUF, "%s,%s", cmd->server->server_hostname, where)); + vnames[sid] = (char*)apr_pstrdup(cmd->pool, msgbuf); } a->rate = temp; a->sid = sid++; @@ -414,14 +417,14 @@ static const char *bandwidth(cmd_parms * cmd, void *s, const char *from, } /* Set the minimum bandwidth to send */ -static const char *minbandwidth(cmd_parms * cmd, void *s, const char *from, - const char *bw) +static const char* minbandwidth(cmd_parms* cmd, void* s, const char* from, + const char* bw) { - bandwidth_config *conf = (bandwidth_config *) s; - bw_entry *a; + bandwidth_config* conf = (bandwidth_config*)s; + bw_entry* a; long int temp; - char *str; - char *where = (char *) apr_pstrdup(cmd->pool, from); + char* str; + char* where = (char*)apr_pstrdup(cmd->pool, from); apr_status_t rv; char msgbuf[MAX_BUF]; @@ -430,13 +433,13 @@ static const char *minbandwidth(cmd_parms * cmd, void *s, const char *from, else return "Invalid argument"; - a = (bw_entry *) apr_array_push(conf->minlimits); + a = (bw_entry*)apr_array_push(conf->minlimits); a->x.from = where; - if (!strncasecmp(where,"u:",2)) + if (!strncasecmp(where, "u:", 2)) { /* Do not limit based on origin, but on user agent */ a->type = T_AGENT; - a->agent = ap_pregcomp(cmd->pool, where+2, 0); + a->agent = ap_pregcomp(cmd->pool, where + 2, 0); if (a->agent == NULL) return "Regular expression could not be compiled."; @@ -447,7 +450,7 @@ static const char *minbandwidth(cmd_parms * cmd, void *s, const char *from, else if ((str = strchr(where, '/'))) { *str++ = '\0'; rv = apr_ipsubnet_create(&a->x.ip, where, str, cmd->pool); - if(APR_STATUS_IS_EINVAL(rv)) { + if (APR_STATUS_IS_EINVAL(rv)) { /* looked nothing like an IP address */ return "An IP address was expected"; } @@ -474,11 +477,11 @@ static const char *minbandwidth(cmd_parms * cmd, void *s, const char *from, } /* Set the large file bandwidth limit */ -static const char *largefilelimit(cmd_parms * cmd, void *s, const char *file, - const char *size, const char *bw) +static const char* largefilelimit(cmd_parms* cmd, void* s, const char* file, + const char* size, const char* bw) { - bandwidth_config *conf = (bandwidth_config *) s; - bw_sizel *a; + bandwidth_config* conf = (bandwidth_config*)s; + bw_sizel* a; long int temp, tsize; char msgbuf[MAX_BUF]; @@ -501,14 +504,14 @@ static const char *largefilelimit(cmd_parms * cmd, void *s, const char *file, if (tsize < 0) return "File size must be a number of Kbytes"; - a = (bw_sizel *) apr_array_push(conf->sizelimits); - a->file = (char *) file; + a = (bw_sizel*)apr_array_push(conf->sizelimits); + a->file = (char*)file; a->size = tsize; a->rate = temp; if (sid < MAX_VHOSTS) { - vnames[sid] = apr_pcalloc(cmd->pool,apr_snprintf(msgbuf,MAX_BUF,"%s,%s",cmd->server->server_hostname,file) ); - vnames[sid] = (char *) apr_pstrdup(cmd->pool, msgbuf); + vnames[sid] = apr_pcalloc(cmd->pool, apr_snprintf(msgbuf, MAX_BUF, "%s,%s", cmd->server->server_hostname, file)); + vnames[sid] = (char*)apr_pstrdup(cmd->pool, msgbuf); } a->sid = sid++; @@ -520,11 +523,11 @@ static const char *largefilelimit(cmd_parms * cmd, void *s, const char *file, * Helper Functions * *----------------------------------------------------------------------------*/ -/* Match the input, as part of a domain */ -static int in_domain(const char *domain, const char *what) + /* Match the input, as part of a domain */ +static int in_domain(const char* domain, const char* what) { - int dl = strlen(domain); - int wl = strlen(what); + size_t dl = strlen(domain); + size_t wl = strlen(what); if ((wl - dl) >= 0) { if (strcasecmp(domain, &what[wl - dl]) != 0) @@ -544,27 +547,27 @@ static int in_domain(const char *domain, const char *what) } /* Get the bandwidth limit based on from address */ -static long get_bw_rate(request_rec * r, apr_array_header_t * a) +static long get_bw_rate(request_rec* r, apr_array_header_t* a) { - bw_entry *e = (bw_entry *) a->elts; - const char *remotehost = NULL; + bw_entry* e = (bw_entry*)a->elts; + const char* remotehost = NULL; int i; int gothost = 0; - const char *uastr = NULL; + const char* uastr = NULL; for (i = 0; i < a->nelts; i++) { switch (e[i].type) { case T_AGENT: uastr = apr_table_get(r->headers_in, "User-Agent"); - if (e[i].agent && uastr && ap_regexec(e[i].agent, uastr, 0, NULL, 0)==0 ) + if (e[i].agent && uastr && ap_regexec(e[i].agent, uastr, 0, NULL, 0) == 0) return (e[i].rate); break; case T_ALL: return e[i].rate; case T_IP: - if (apr_ipsubnet_test(e[i].x.ip, r->connection->remote_addr)) { + if (apr_ipsubnet_test(e[i].x.ip, r->connection->client_addr)) { return e[i].rate; } break; @@ -573,7 +576,7 @@ static long get_bw_rate(request_rec * r, apr_array_header_t * a) int remotehost_is_ip; remotehost = ap_get_remote_host(r->connection, r->per_dir_config, - REMOTE_DOUBLE_REV, &remotehost_is_ip); + REMOTE_DOUBLE_REV, &remotehost_is_ip); if ((remotehost == NULL) || remotehost_is_ip) gothost = 1; @@ -585,16 +588,16 @@ static long get_bw_rate(request_rec * r, apr_array_header_t * a) return (e[i].rate); break; } - + } return 0; } -/* - Match the pattern with the last digist from filename - An asterisk means any. +/* + Match the pattern with the last digist from filename + An asterisk means any. */ -static int match_ext(const char *file, char *match) +static int match_ext(const char* file, char* match) { if (file == NULL || match == NULL) return 0; @@ -611,10 +614,10 @@ static int match_ext(const char *file, char *match) } /* Get the bandwidth limit based on filesize */ -static long get_bw_filesize(request_rec * r, apr_array_header_t * a, - apr_uint32_t filesize, const char *filename) +static long get_bw_filesize(request_rec* r, apr_array_header_t* a, + apr_uint32_t filesize, const char* filename) { - bw_sizel *e = (bw_sizel *) a->elts; + bw_sizel* e = (bw_sizel*)a->elts; int i; apr_uint32_t tmpsize = 0, tmprate = 0; @@ -635,27 +638,27 @@ static long get_bw_filesize(request_rec * r, apr_array_header_t * a, } /* Get the MaxConnections allowed */ -static int get_maxconn(request_rec * r, apr_array_header_t * a) +static int get_maxconn(request_rec* r, apr_array_header_t* a) { - bw_maxconn *e = (bw_maxconn *) a->elts; - const char *remotehost = NULL; + bw_maxconn* e = (bw_maxconn*)a->elts; + const char* remotehost = NULL; int i; int gothost = 0; - const char *uastr = NULL; + const char* uastr = NULL; for (i = 0; i < a->nelts; i++) { switch (e[i].type) { case T_AGENT: uastr = apr_table_get(r->headers_in, "User-Agent"); - if (e[i].agent && uastr && ap_regexec(e[i].agent, uastr, 0, NULL, 0)==0 ) + if (e[i].agent && uastr && ap_regexec(e[i].agent, uastr, 0, NULL, 0) == 0) return (e[i].max); break; case T_ALL: return e[i].max; case T_IP: - if (apr_ipsubnet_test(e[i].x.ip, r->connection->remote_addr)) { + if (apr_ipsubnet_test(e[i].x.ip, r->connection->client_addr)) { return e[i].max; } break; @@ -664,7 +667,7 @@ static int get_maxconn(request_rec * r, apr_array_header_t * a) int remotehost_is_ip; remotehost = ap_get_remote_host(r->connection, r->per_dir_config, - REMOTE_DOUBLE_REV, &remotehost_is_ip); + REMOTE_DOUBLE_REV, &remotehost_is_ip); if ((remotehost == NULL) || remotehost_is_ip) gothost = 1; @@ -682,31 +685,31 @@ static int get_maxconn(request_rec * r, apr_array_header_t * a) } /* Get an id based on bandwidth limit */ -static int get_sid(request_rec * r, apr_array_header_t * a) +static int get_sid(request_rec* r, apr_array_header_t* a) { - bw_entry *e = (bw_entry *) a->elts; - const char *remotehost = NULL; + bw_entry* e = (bw_entry*)a->elts; + const char* remotehost = NULL; int i; int gothost = 0; - const char *uastr; + const char* uastr; remotehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_HOST, - NULL); + NULL); for (i = 0; i < a->nelts; i++) { switch (e[i].type) { case T_AGENT: uastr = apr_table_get(r->headers_in, "User-Agent"); - if (e[i].agent && uastr && ap_regexec(e[i].agent, uastr, 0, NULL, 0)==0 ) + if (e[i].agent && uastr && ap_regexec(e[i].agent, uastr, 0, NULL, 0) == 0) return (e[i].sid); break; case T_ALL: return e[i].sid; case T_IP: - if (apr_ipsubnet_test(e[i].x.ip, r->connection->remote_addr)) { + if (apr_ipsubnet_test(e[i].x.ip, r->connection->client_addr)) { return e[i].sid; } break; @@ -715,7 +718,7 @@ static int get_sid(request_rec * r, apr_array_header_t * a) int remotehost_is_ip; remotehost = ap_get_remote_host(r->connection, r->per_dir_config, - REMOTE_DOUBLE_REV, &remotehost_is_ip); + REMOTE_DOUBLE_REV, &remotehost_is_ip); if ((remotehost == NULL) || remotehost_is_ip) gothost = 1; @@ -733,10 +736,10 @@ static int get_sid(request_rec * r, apr_array_header_t * a) } /* Get an id based on filesize limit */ -static int get_f_sid(request_rec * r, apr_array_header_t * a, apr_uint32_t filesize, - const char *filename) +static int get_f_sid(request_rec* r, apr_array_header_t* a, apr_uint32_t filesize, + const char* filename) { - bw_sizel *e = (bw_sizel *) a->elts; + bw_sizel* e = (bw_sizel*)a->elts; int i; apr_uint32_t tmpsize = 0, tmpsid = -1; @@ -759,7 +762,7 @@ static int get_f_sid(request_rec * r, apr_array_header_t * a, apr_uint32_t files } /* Update memory (shm) counters, which holds the bw data per context */ -static void update_counters(bw_data * bwstat, ap_filter_t * f) +static void update_counters(bw_data* bwstat, ap_filter_t* f) { apr_time_t nowtime; @@ -770,8 +773,8 @@ static void update_counters(bw_data * bwstat, ap_filter_t * f) if (apr_atomic_cas32(&bwstat->lock, 1, 0) == 0) { /* Calculate bw used in the last timeinterval */ - bwstat->bandwidth = (apr_uint32_t) ( - (bwstat->bytes_count / (double) (nowtime - bwstat->time)) * + bwstat->bandwidth = (apr_uint32_t)( + (bwstat->bytes_count / (double)(nowtime - bwstat->time)) * 1000000); /* Reset counters */ @@ -786,29 +789,29 @@ static void update_counters(bw_data * bwstat, ap_filter_t * f) } } -static int callback(request_rec * r) +static int callback(request_rec* r) { int t; - bw_data *bwstat; + bw_data* bwstat; if (r->header_only) { return OK; } - if (r->args && !strncasecmp(r->args,"csv",3)) + if (r->args && !strncasecmp(r->args, "csv", 3)) { ap_set_content_type(r, "text/plain"); - ap_rputs("id,vhost,scope,lock,count,bw,bytes,hits\n",r); - + ap_rputs("id,vhost,scope,lock,count,bw,bytes,hits\n", r); + for (t = 0; t < sid; t++) { bwstat = bwbase + t; - ap_rprintf(r,"%d,%s,%d,%d,%d,%d,%d\n",t,bwstat->v_name,bwstat->lock,bwstat->connection_count,bwstat->bandwidth,bwstat->bytes_count,bwstat->counter); + ap_rprintf(r, "%d,%s,%d,%d,%d,%d,%d\n", t, bwstat->v_name, bwstat->lock, bwstat->connection_count, bwstat->bandwidth, bwstat->bytes_count, bwstat->counter); } return OK; } - + ap_set_content_type(r, "text/html"); ap_rputs(DOCTYPE_HTML_3_2, r); @@ -821,7 +824,7 @@ static int callback(request_rec * r) ap_rputs(" \n", r); ap_rputs("

\n", r); ap_rprintf(r, " Apache HTTP Server version: \"%s\"\n", - ap_get_server_banner()); + ap_get_server_banner()); ap_rputs("
\n", r); ap_rprintf(r, " Server built: \"%s\"\n", ap_get_server_built()); ap_rputs("

\n", r);; @@ -831,20 +834,20 @@ static int callback(request_rec * r) bwstat = bwbase + t; /* This inits the struct that will contain current bw use */ - ap_rputs("
",r); - ap_rprintf(r,"id : %d
",t); - ap_rprintf(r,"name : %s
",bwstat->v_name); - ap_rprintf(r,"lock : %d
",bwstat->lock); - ap_rprintf(r,"count: %d
",bwstat->connection_count); - ap_rprintf(r,"bw : %d
",bwstat->bandwidth); - ap_rprintf(r,"bytes: %d
",bwstat->bytes_count); - ap_rprintf(r,"hits : %d
",bwstat->counter); + ap_rputs("
", r); + ap_rprintf(r, "id : %d
", t); + ap_rprintf(r, "name : %s
", bwstat->v_name); + ap_rprintf(r, "lock : %d
", bwstat->lock); + ap_rprintf(r, "count: %d
", bwstat->connection_count); + ap_rprintf(r, "bw : %d
", bwstat->bandwidth); + ap_rprintf(r, "bytes: %d
", bwstat->bytes_count); + ap_rprintf(r, "hits : %d
", bwstat->counter); } ap_rputs(" \n", r); ap_rputs("\n", r); - return OK; + return OK; } @@ -852,25 +855,25 @@ static int callback(request_rec * r) /*----------------------------------------------------------------------------* * The Handler and the Output Filter. Core of the mod. * *----------------------------------------------------------------------------*/ -/* With this handler, we can *force* the use of the mod. */ -static int handle_bw(request_rec * r) + /* With this handler, we can *force* the use of the mod. */ +static int handle_bw(request_rec* r) { - bandwidth_server_config *sconf = - (bandwidth_server_config *) ap_get_module_config(r->server-> - module_config, - &bw_module); - bandwidth_config *conf = - (bandwidth_config *) ap_get_module_config(r->per_dir_config, - &bw_module); - bw_data *bwstat; + bandwidth_server_config* sconf = + (bandwidth_server_config*)ap_get_module_config(r->server-> + module_config, + &bw_module); + bandwidth_config* conf = + (bandwidth_config*)ap_get_module_config(r->per_dir_config, + &bw_module); + bw_data* bwstat; apr_int32_t confid; /* Only work on main request/no subrequests */ if (r->main) return DECLINED; - if (strcmp(r->handler, "modbw-handler")==0) return callback(r); + if (strcmp(r->handler, "modbw-handler") == 0) return callback(r); /* Return if module is not enabled */ @@ -889,7 +892,7 @@ static int handle_bw(request_rec * r) /* If we are too busy, deny connection */ confid = get_maxconn(r, conf->maxconnection); - if ((bwstat->connection_count >= (apr_uint32_t) confid) && (confid > 0)) + if ((bwstat->connection_count >= (apr_uint32_t)confid) && (confid > 0)) return conf->error; } @@ -901,25 +904,27 @@ static int handle_bw(request_rec * r) return DECLINED; } -static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) +static int bw_filter(ap_filter_t* f, apr_bucket_brigade* bb) { - request_rec *r = f->r; - bandwidth_config *conf = - (bandwidth_config *) ap_get_module_config(r->per_dir_config, - &bw_module); - bandwidth_server_config *sconf = - (bandwidth_server_config *) ap_get_module_config(r->server-> - module_config, - &bw_module); - ctx_struct *ctx = f->ctx; - apr_bucket *b = APR_BRIGADE_FIRST(bb); - bw_data *bwstat, *bwmaxconn; + request_rec* r = f->r; + bandwidth_config* conf = + (bandwidth_config*)ap_get_module_config(r->per_dir_config, + &bw_module); + bandwidth_server_config* sconf = + (bandwidth_server_config*)ap_get_module_config(r->server-> + module_config, + &bw_module); + ctx_struct* ctx = f->ctx; + apr_bucket* b = APR_BRIGADE_FIRST(bb); + bw_data* bwstat, * bwmaxconn; int confid = -1, connid = -1; apr_size_t packet = conf->packet, bytes = 0; apr_off_t bblen = 0; - long int bw_rate, bw_min, bw_f_rate, cur_rate = 0, sleep; - const char *buf; - const char *filename; + apr_size_t bw_rate, bw_min, bw_f_rate, cur_rate = 0; + apr_interval_time_t sleep; + const char* buf; + const char* filename; + long current_sleep_bypasses = 0; /* Only work on main request/no subrequests */ if (r->main) { @@ -945,7 +950,7 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) /* Get the File Rate. r->finfo.size is not used anymore. */ bblen = r->bytes_sent; - bw_f_rate = get_bw_filesize(r, conf->sizelimits, (off_t) bblen, filename); + bw_f_rate = get_bw_filesize(r, conf->sizelimits, (off_t)bblen, filename); /* Check if we've got an ilimited client */ @@ -960,7 +965,7 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) - If file size is zero, all files apply */ if (bw_f_rate && (bw_rate > bw_f_rate || !bw_rate)) { - confid = get_f_sid(r, conf->sizelimits, (off_t) bblen, filename); + confid = get_f_sid(r, conf->sizelimits, (off_t)bblen, filename); bw_rate = bw_f_rate; } @@ -969,11 +974,17 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) else if (!bw_min) bw_min = MIN_BW; - /* Initialize our temporal space */ + /* Initialize our temporal space, which survives multiple invokations for the same request */ if (ctx == NULL) { - apr_bucket_alloc_t *bucket_alloc = apr_bucket_alloc_create(f->r->pool); + apr_bucket_alloc_t* bucket_alloc = apr_bucket_alloc_create(f->r->pool); f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); ctx->bb = apr_brigade_create(f->r->pool, bucket_alloc); + + ctx->bw_interval_start_time = apr_time_now(); + ctx->bw_interval_slept = 0; + ctx->bw_interval_bytes = 0; + ctx->sleep_bypasses_left = 0; + ctx->sleep_bypasses_total = 0; } /* We "get" the data of the current configuration */ @@ -990,13 +1001,12 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) /* Verbose Output */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "ID: %i Directory : %s Rate : %ld Minimum : %ld Size rate : %ld", - confid, conf->directory, bw_rate, bw_min, bw_f_rate); + "ID: %i; Directory : %s; File : %s; Rate : %ld; Minimum : %ld; Size rate : %ld;", + confid, conf->directory, filename, bw_rate, bw_min, bw_f_rate); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "clients : %d/%d rate/min : %ld,%ld", bwmaxconn->connection_count, - (connid >= 0) ? get_maxconn(r, conf->maxconnection) : 0, - bw_rate, bw_min); - + "clients : %d/%d; rate/min : %ld,%ld", bwmaxconn->connection_count, + (connid >= 0) ? get_maxconn(r, conf->maxconnection) : 0, + bw_rate, bw_min); /* - We get buckets until a sentinel appears @@ -1009,6 +1019,7 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) APR_BUCKET_REMOVE(b); APR_BRIGADE_INSERT_TAIL(ctx->bb, b); ap_pass_brigade(f->next, ctx->bb); + apr_brigade_cleanup(ctx->bb); /* Delete 1 active connection */ apr_atomic_dec32(&bwmaxconn->connection_count); @@ -1017,15 +1028,16 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) if (apr_bucket_read(b, &buf, &bytes, APR_NONBLOCK_READ) == APR_SUCCESS) { + /* This changed, cause of the limit handling error.. see below */ while (bytes > 0) { /* - - Ok, i'm doing lots of things here. The bw the client will have, is + - Ok, i'm doing lots of things here. The bw the client will have, is the bw available divided by the number of clients. - - The minimum bw, will always be MIN_BW. If all bw is used, and new + - The minimum bw, will always be MIN_BW. If all bw is used, and new connections arrives, they'll have MIN_BW bw available. */ - cur_rate = (long int) bw_rate / bwmaxconn->connection_count; + cur_rate = (long int)bw_rate / bwmaxconn->connection_count; if (cur_rate > bw_rate) cur_rate = bw_rate; @@ -1050,21 +1062,58 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) /* Here we get the time we need to sleep to get the specified bw */ sleep = - (long int) (1000000 / - ((double) cur_rate / (double) packet)); + (unsigned long)(1000000 / + ((double)cur_rate / (double)packet)); + + /* if more than 15ms has elapsed, roughly calculate client's actual bandwidth */ + if ((apr_time_now() - ctx->bw_interval_slept) - ctx->bw_interval_start_time > 15000) { + ctx->client_bw = (ctx->bw_interval_bytes * 1000 / (unsigned long long)((apr_time_now() - ctx->bw_interval_slept) - ctx->bw_interval_start_time)) * 1000; + ctx->bw_interval_bytes = 0; + ctx->bw_interval_slept = 0; + ctx->bw_interval_start_time = apr_time_now(); + /* Verbose logging */ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Client BW is ~%ld B/s. This %s than available BW (%ld). %s", ctx->client_bw, (ctx->client_bw > cur_rate ? "More" : "Less"), cur_rate, (ctx->client_bw > cur_rate ? "BW Limiting!" : "Not BW limiting!")); + } + #if defined(WIN32) - if (sleep < 200000 && cur_rate > 1024) - { - sleep = 200000; - packet = cur_rate/5; - if (bytes < packet) - packet = bytes; - } + /* For Windows, assume the minimum sleep time is 10ms. If the needed sleep time is less than 10ms, calculate + how many packets to send before sleeping for 10ms. For very small buckets, this can result in an + absurdly high number of packets to send, probably more than there are buckets, so it doesn't matter. */ + if (sleep < 10000 && ctx->client_bw > cur_rate) + { + /* calculate, based on available bandwidth right now, how many packets can be sent in 10 ms */ + current_sleep_bypasses = (long)((double)10000 / (double)(sleep + 1)); /* plus 1 microsecond to avoid divide by zero errors */ + + sleep = 10000; + + if (ctx->sleep_bypasses_left == 0) { /* If not currently counting down packets... */ + ctx->sleep_bypasses_total = current_sleep_bypasses; /* setup counters */ + ctx->sleep_bypasses_left = current_sleep_bypasses; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "File: %s. BW: %ld B/s. Packet: %ld bytes. Bypassing sleep for %i packet(s).", filename, cur_rate, packet, ctx->sleep_bypasses_left); + } + else { + /* If number of packets to send in 10ms has changed since last calc because available bandwidth changed, recalcuate */ + if (ctx->sleep_bypasses_total != current_sleep_bypasses) { + /* new packet counter = packets_per_10ms minus packets already sent */ + ctx->sleep_bypasses_left = current_sleep_bypasses - (ctx->sleep_bypasses_total - ctx->sleep_bypasses_left); + + if (ctx->sleep_bypasses_left < 0) { + ctx->sleep_bypasses_left = 0; /* if new packets to send is less than zero, reset to zero so we sleep now*/ + } + ctx->sleep_bypasses_total = current_sleep_bypasses; /* Update the total packets to send in this period */ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "File: %s. Available BW changed to %ld B/s. Now bypassing sleep for %ld more packet(s).", filename, cur_rate, ctx->sleep_bypasses_left); + } + } + } + else { + ctx->sleep_bypasses_left = 0; + } #endif - - /* + /* Here, we are going to split the bucket, and send it on piece at a time, - doing a "delay" between each piece. That way, we send the data at the + doing a "delay" between each piece. That way, we send the data at the specified rate. */ apr_bucket_split(b, packet); @@ -1073,25 +1122,36 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) /* Decrease our counter */ bytes -= packet; + ctx->bw_interval_bytes += packet; /* Flush and move to the next bucket */ ap_pass_brigade(f->next, ctx->bb); + apr_brigade_cleanup(ctx->bb); b = APR_BRIGADE_FIRST(bb); /* Add the number of bytes transferred, so we can get an estimated bw usage */ - apr_atomic_add32(&bwstat->bytes_count, packet); + apr_atomic_add64(&bwstat->bytes_count, packet); /* If the connection goes to hell... go with it ! */ if (r->connection->aborted) { /* Verbose. Tells when the connection was ended */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, - 0, r->server, "Connection to hell"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, + 0, r, "Connection to hell"); apr_atomic_dec32(&bwmaxconn->connection_count); return APR_SUCCESS; } - /* Sleep ... zZZzZzZzzzz */ - apr_sleep(sleep); + /* Sleep ... but only if the time is right (see Windows clock resolution fix above) */ + if (ctx->sleep_bypasses_left > 0) { + ctx->sleep_bypasses_left--; + } + else { + if (ctx->client_bw > cur_rate) { /* Only sleep if the client's calculated bw is greater than available */ + apr_sleep(sleep); /* bandwidth, otherwise there's no reason to sleep. */ + ctx->bw_interval_slept += sleep; + } + ctx->sleep_bypasses_left = 0; + } /* Refresh counters, so we can keep working :) */ update_counters(bwstat, f); @@ -1102,11 +1162,12 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) APR_BRIGADE_INSERT_TAIL(ctx->bb, b); b = APR_BRIGADE_FIRST(bb); - /* Add the number of bytes to the counter */ - apr_atomic_add32(&bwstat->bytes_count, bytes); + /* Add the number of bytes to the counter - switched to the 64bit counter for bigger files */ + apr_atomic_add64(&bwstat->bytes_count, bytes); /* Pass the final brigade */ ap_pass_brigade(f->next, ctx->bb); + apr_brigade_cleanup(ctx->bb); } /* Delete 1 active connection to the record */ @@ -1121,26 +1182,26 @@ static int bw_filter(ap_filter_t * f, apr_bucket_brigade * bb) /*----------------------------------------------------------------------------* * Module Init functions * *----------------------------------------------------------------------------*/ -static int bw_init(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, - server_rec * s) +static int bw_init(apr_pool_t* p, apr_pool_t* plog, apr_pool_t* ptemp, + server_rec* s) { apr_status_t status; apr_size_t retsize; apr_size_t shm_size; - bw_data *bwstat; + bw_data* bwstat; int t; #if defined(WIN32) - TIMECAPS resolution; + TIMECAPS resolution; #endif /* These two help ensure that we only init once. */ - void *data; - const char *userdata_key = "ivn_shm_bw_limit_module"; + void* data; + const char* userdata_key = "ivn_shm_bw_limit_module"; apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!data) { - apr_pool_userdata_set((const void *) 1, userdata_key, - apr_pool_cleanup_null, s->process->pool); + apr_pool_userdata_set((const void*)1, userdata_key, + apr_pool_cleanup_null, s->process->pool); return OK; } @@ -1149,7 +1210,7 @@ static int bw_init(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, if (status != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; - shm_size = (apr_size_t) sizeof(bw_data) * sid; + shm_size = (apr_size_t)sizeof(bw_data) * sid; /* If there was a memory block already assigned.. destroy it */ @@ -1157,11 +1218,12 @@ static int bw_init(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, status = apr_shm_destroy(shm); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "mod_bw : Couldn't destroy old memory block\n"); + "mod_bw : Couldn't destroy old memory block\n"); return status; - } else { + } + else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "mod_bw : Old Shared memory block, destroyed."); + "mod_bw : Old Shared memory block, destroyed."); } } @@ -1169,32 +1231,32 @@ static int bw_init(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, status = apr_shm_create(&shm, shm_size, NULL, p); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "mod_bw : Error creating shm block\n"); + "mod_bw : Error creating shm block\n"); return status; } /* Check size of shared memory block */ retsize = apr_shm_size_get(shm); if (retsize != shm_size) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "mod_bw : Error allocating shared memory block\n"); + "mod_bw : Error allocating shared memory block\n"); return status; } /* Init shm block */ bwbase = apr_shm_baseaddr_get(shm); if (bwbase == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "mod_bw : Error creating status block.\n"); + "mod_bw : Error creating status block.\n"); return status; } memset(bwbase, 0, retsize); ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, - "mod_bw : Memory Allocated %d bytes (each conf takes %d bytes)", - (int) retsize, (int) sizeof(bw_data)); + "mod_bw : Memory Allocated %d bytes (each conf takes %d bytes)", + (int)retsize, (int)sizeof(bw_data)); if (retsize < (sizeof(bw_data) * sid)) { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, - "mod_bw : Not enough memory allocated!! Giving up"); + "mod_bw : Not enough memory allocated!! Giving up"); return HTTP_INTERNAL_SERVER_ERROR; } @@ -1212,66 +1274,66 @@ static int bw_init(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, } ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, - "mod_bw : Version %s - Initialized [%d Confs]", VERSION, - sid); + "mod_bw : Version %s - Initialized [%d Confs]", VERSION, + sid); #if defined(WIN32) - // Set the timer resolution to its minimum - if (timeGetDevCaps (&resolution, sizeof (TIMECAPS)) == TIMERR_NOERROR) + // Set the timer resolution to its minimum + if (timeGetDevCaps(&resolution, sizeof(TIMECAPS)) == TIMERR_NOERROR) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, - "mod_bw : Supported resolution for Timers [ Min: %d Max: %d ]",resolution.wPeriodMin,resolution.wPeriodMax); - - - if (timeBeginPeriod (resolution.wPeriodMin) == TIMERR_NOERROR) ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, - "mod_bw : Enabling High resolution timers [ %d ms ]",resolution.wPeriodMin); - else - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "mod_bw : Can't enable High Resolution timers. Speed might be reduced."); - } + "mod_bw : Supported resolution for Timers [ Min: %d Max: %d ]", resolution.wPeriodMin, resolution.wPeriodMax); + + + if (timeBeginPeriod(resolution.wPeriodMin) == TIMERR_NOERROR) + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, + "mod_bw : Enabling High resolution timers [ %d ms ]", resolution.wPeriodMin); + else + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "mod_bw : Can't enable High Resolution timers. Speed might be reduced."); + } #endif return OK; } -static void *create_bw_config(apr_pool_t * p, char *path) +static void* create_bw_config(apr_pool_t* p, char* path) { - bandwidth_config *new = - (bandwidth_config *) apr_palloc(p, sizeof(bandwidth_config)); + bandwidth_config* new = + (bandwidth_config*)apr_palloc(p, sizeof(bandwidth_config)); new->limits = apr_array_make(p, 20, sizeof(bw_entry)); new->minlimits = apr_array_make(p, 20, sizeof(bw_entry)); new->sizelimits = apr_array_make(p, 10, sizeof(bw_sizel)); new->maxconnection = apr_array_make(p, 10, sizeof(bw_maxconn)); - new->directory = (char *) apr_pstrdup(p, path); + new->directory = (char*)apr_pstrdup(p, path); new->packet = PACKET; new->error = HTTP_SERVICE_UNAVAILABLE; - return (void *) new; + return (void*) new; } -static void *create_bw_server_config(apr_pool_t * p, server_rec * s) +static void* create_bw_server_config(apr_pool_t* p, server_rec* s) { - bandwidth_server_config *new; + bandwidth_server_config* new; new = - (bandwidth_server_config *) apr_pcalloc(p, - sizeof - (bandwidth_server_config)); + (bandwidth_server_config*)apr_pcalloc(p, + sizeof + (bandwidth_server_config)); new->state = BANDWIDTH_DISABLED; new->force = BANDWIDTH_DISABLED; - return (void *) new; + return (void*) new; } /*----------------------------------------------------------------------------* * Apache register functions * *----------------------------------------------------------------------------*/ -static void register_hooks(apr_pool_t * p) +static void register_hooks(apr_pool_t* p) { /* - Register a handler, which enforces mod_bw if needed From 069863957f27b9424d6ae49adcd25131452ac688 Mon Sep 17 00:00:00 2001 From: sosherof Date: Tue, 26 Oct 2021 11:38:15 -0700 Subject: [PATCH 6/8] Removed math.h include that wasn't needed. --- mod_bw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mod_bw.c b/mod_bw.c index 33959ad..cb1b5f4 100644 --- a/mod_bw.c +++ b/mod_bw.c @@ -73,7 +73,6 @@ Changelog : #if defined(WIN32) #include #include -#include #endif #define MIN_BW 256 /* Minimal bandwidth 256 bytes */ From 44dac2a08e33a57ddc74a344915db8bfba3c59b8 Mon Sep 17 00:00:00 2001 From: sosherof Date: Tue, 26 Oct 2021 11:38:15 -0700 Subject: [PATCH 7/8] VS 2019 "corrected" some formatting, making more changes appear in diff than there actually are. Reverted some of these.Removed math.h include that wasn't needed. --- mod_bw.c | 203 +++++++++++++++++++++++++++---------------------------- 1 file changed, 98 insertions(+), 105 deletions(-) diff --git a/mod_bw.c b/mod_bw.c index 33959ad..dec7f29 100644 --- a/mod_bw.c +++ b/mod_bw.c @@ -73,7 +73,6 @@ Changelog : #if defined(WIN32) #include #include -#include #endif #define MIN_BW 256 /* Minimal bandwidth 256 bytes */ @@ -127,7 +126,7 @@ enum from_type { typedef struct { apr_uint32_t id; - char* v_name; + char *v_name; apr_uint32_t connection_count; apr_uint32_t bandwidth; unsigned long long bytes_count; @@ -139,7 +138,7 @@ typedef struct /* A temporal context to save our splitted brigade */ typedef struct ctx_struct_t { - apr_bucket_brigade* bb; + apr_bucket_brigade *bb; struct timeval wait; unsigned long long bw_interval_bytes, bw_interval_slept, client_bw; apr_time_t bw_interval_start_time; @@ -160,7 +159,7 @@ typedef struct apr_uint32_t sid; union { char* from; - apr_ipsubnet_t* ip; + apr_ipsubnet_t *ip; } x; ap_regex_t* agent; enum from_type type; @@ -173,7 +172,7 @@ typedef struct apr_uint32_t sid; union { char* from; - apr_ipsubnet_t* ip; + apr_ipsubnet_t *ip; } x; ap_regex_t* agent; enum from_type type; @@ -192,10 +191,10 @@ typedef struct /* Per directory configuration structure */ typedef struct { - apr_array_header_t* limits; - apr_array_header_t* minlimits; - apr_array_header_t* sizelimits; - apr_array_header_t* maxconnection; + apr_array_header_t *limits; + apr_array_header_t *minlimits; + apr_array_header_t *sizelimits; + apr_array_header_t *maxconnection; unsigned int packet; int error; char* directory; @@ -215,7 +214,7 @@ module AP_MODULE_DECLARE_DATA bw_module; * Configurations Directives * *---------------------------------------------------------------------*/ /* Set the mod enabled ... or disabled */ -static const char* bandwidthmodule(cmd_parms* cmd, void* dconf, int flag) +static const char *bandwidthmodule(cmd_parms* cmd, void* dconf, int flag) { bandwidth_server_config* sconf; @@ -232,10 +231,10 @@ static const char* bandwidthmodule(cmd_parms* cmd, void* dconf, int flag) static const char* forcebandwidthmodule(cmd_parms* cmd, void* dconf, int flag) { - bandwidth_server_config* sconf; + bandwidth_server_config *sconf; sconf = - (bandwidth_server_config*)ap_get_module_config(cmd->server-> + (bandwidth_server_config *)ap_get_module_config(cmd->server-> module_config, &bw_module); sconf->force = (flag ? BANDWIDTH_ENABLED : BANDWIDTH_DISABLED); @@ -244,9 +243,9 @@ static const char* forcebandwidthmodule(cmd_parms* cmd, void* dconf, } /* Set the packetsize used in the context */ -static const char* setpacket(cmd_parms* cmd, void* s, const char* pack) +static const char *setpacket(cmd_parms* cmd, void* s, const char* pack) { - bandwidth_config* conf = (bandwidth_config*)s; + bandwidth_config *conf = (bandwidth_config *)s; int temp; if (pack && *pack && apr_isdigit(*pack)) @@ -263,9 +262,9 @@ static const char* setpacket(cmd_parms* cmd, void* s, const char* pack) } /* Set the error to send when maxconnections is reached */ -static const char* bandwidtherror(cmd_parms* cmd, void* s, const char* err) +static const char *bandwidtherror(cmd_parms * cmd, void *s, const char *err) { - bandwidth_config* conf = (bandwidth_config*)s; + bandwidth_config *conf = (bandwidth_config *)s; int temp; if (err && *err && apr_isdigit(*err)) @@ -282,14 +281,14 @@ static const char* bandwidtherror(cmd_parms* cmd, void* s, const char* err) } /* Set the maxconnections on a per host basis */ -static const char* maxconnection(cmd_parms* cmd, void* s, const char* from, - const char* maxc) +static const char *maxconnection(cmd_parms * cmd, void *s, const char *from, + const char *maxc) { - bandwidth_config* conf = (bandwidth_config*)s; - bw_maxconn* a; + bandwidth_config *conf = (bandwidth_config *)s; + bw_maxconn *a; int temp; - char* str; - char* where = (char*)apr_pstrdup(cmd->pool, from); + char *str; + char *where = (char *)apr_pstrdup(cmd->pool, from); apr_status_t rv; char msgbuf[MAX_BUF]; @@ -300,16 +299,16 @@ static const char* maxconnection(cmd_parms* cmd, void* s, const char* from, if (temp < 0) return - "Connections must be a number of simultaneous connections allowed/s"; + "Connections must be a number of simultaneous connections allowed/s"; - a = (bw_maxconn*)apr_array_push(conf->maxconnection); + a = (bw_maxconn *)apr_array_push(conf->maxconnection); a->x.from = where; if (!strncasecmp(where, "u:", 2)) { /* Do not limit based on origin, but on user agent */ a->type = T_AGENT; - a->agent = ap_pregcomp(cmd->pool, where + 2, 0); + a->agent = ap_pregcomp(cmd->pool, where+2, 0); if (a->agent == NULL) return "Regular expression could not be compiled."; @@ -347,14 +346,14 @@ static const char* maxconnection(cmd_parms* cmd, void* s, const char* from, } /* Set the bandwidth on a per host basis */ -static const char* bandwidth(cmd_parms* cmd, void* s, const char* from, - const char* bw) +static const char *bandwidth(cmd_parms * cmd, void *s, const char *from, + const char *bw) { - bandwidth_config* conf = (bandwidth_config*)s; - bw_entry* a; + bandwidth_config *conf = (bandwidth_config *)s; + bw_entry *a; long int temp; - char* str; - char* where = (char*)apr_pstrdup(cmd->pool, from); + char *str; + char *where = (char *)apr_pstrdup(cmd->pool, from); apr_status_t rv; char msgbuf[MAX_BUF]; @@ -367,7 +366,7 @@ static const char* bandwidth(cmd_parms* cmd, void* s, const char* from, if (temp < 0) return "BandWidth must be a number of bytes/s"; - a = (bw_entry*)apr_array_push(conf->limits); + a = (bw_entry *)apr_array_push(conf->limits); a->x.from = where; if (!strncasecmp(where, "u:", 2)) { @@ -412,19 +411,17 @@ static const char* bandwidth(cmd_parms* cmd, void* s, const char* from, a->rate = temp; a->sid = sid++; - return NULL; } /* Set the minimum bandwidth to send */ -static const char* minbandwidth(cmd_parms* cmd, void* s, const char* from, - const char* bw) +static const char *minbandwidth(cmd_parms * cmd, void *s, const char *from, const char *bw) { - bandwidth_config* conf = (bandwidth_config*)s; - bw_entry* a; + bandwidth_config *conf = (bandwidth_config *)s; + bw_entry *a; long int temp; - char* str; - char* where = (char*)apr_pstrdup(cmd->pool, from); + char *str; + char *where = (char *)apr_pstrdup(cmd->pool, from); apr_status_t rv; char msgbuf[MAX_BUF]; @@ -433,7 +430,7 @@ static const char* minbandwidth(cmd_parms* cmd, void* s, const char* from, else return "Invalid argument"; - a = (bw_entry*)apr_array_push(conf->minlimits); + a = (bw_entry *)apr_array_push(conf->minlimits); a->x.from = where; if (!strncasecmp(where, "u:", 2)) { @@ -477,11 +474,11 @@ static const char* minbandwidth(cmd_parms* cmd, void* s, const char* from, } /* Set the large file bandwidth limit */ -static const char* largefilelimit(cmd_parms* cmd, void* s, const char* file, - const char* size, const char* bw) +static const char *largefilelimit(cmd_parms * cmd, void *s, const char *file, + const char *size, const char *bw) { - bandwidth_config* conf = (bandwidth_config*)s; - bw_sizel* a; + bandwidth_config *conf = (bandwidth_config *)s; + bw_sizel *a; long int temp, tsize; char msgbuf[MAX_BUF]; @@ -504,14 +501,14 @@ static const char* largefilelimit(cmd_parms* cmd, void* s, const char* file, if (tsize < 0) return "File size must be a number of Kbytes"; - a = (bw_sizel*)apr_array_push(conf->sizelimits); + a = (bw_sizel *)apr_array_push(conf->sizelimits); a->file = (char*)file; a->size = tsize; a->rate = temp; if (sid < MAX_VHOSTS) { vnames[sid] = apr_pcalloc(cmd->pool, apr_snprintf(msgbuf, MAX_BUF, "%s,%s", cmd->server->server_hostname, file)); - vnames[sid] = (char*)apr_pstrdup(cmd->pool, msgbuf); + vnames[sid] = (char *)apr_pstrdup(cmd->pool, msgbuf); } a->sid = sid++; @@ -524,7 +521,7 @@ static const char* largefilelimit(cmd_parms* cmd, void* s, const char* file, *----------------------------------------------------------------------------*/ /* Match the input, as part of a domain */ -static int in_domain(const char* domain, const char* what) +static int in_domain(const char *domain, const char *what) { size_t dl = strlen(domain); size_t wl = strlen(what); @@ -547,13 +544,13 @@ static int in_domain(const char* domain, const char* what) } /* Get the bandwidth limit based on from address */ -static long get_bw_rate(request_rec* r, apr_array_header_t* a) +static long get_bw_rate(request_rec *r, apr_array_header_t *a) { - bw_entry* e = (bw_entry*)a->elts; - const char* remotehost = NULL; + bw_entry *e = (bw_entry *)a->elts; + const char *remotehost = NULL; int i; int gothost = 0; - const char* uastr = NULL; + const char *uastr = NULL; for (i = 0; i < a->nelts; i++) { @@ -597,7 +594,7 @@ static long get_bw_rate(request_rec* r, apr_array_header_t* a) Match the pattern with the last digist from filename An asterisk means any. */ -static int match_ext(const char* file, char* match) +static int match_ext(const char *file, char *match) { if (file == NULL || match == NULL) return 0; @@ -614,10 +611,10 @@ static int match_ext(const char* file, char* match) } /* Get the bandwidth limit based on filesize */ -static long get_bw_filesize(request_rec* r, apr_array_header_t* a, - apr_uint32_t filesize, const char* filename) +static long get_bw_filesize(request_rec *r, apr_array_header_t *a, + apr_uint32_t filesize, const char *filename) { - bw_sizel* e = (bw_sizel*)a->elts; + bw_sizel *e = (bw_sizel *)a->elts; int i; apr_uint32_t tmpsize = 0, tmprate = 0; @@ -638,13 +635,13 @@ static long get_bw_filesize(request_rec* r, apr_array_header_t* a, } /* Get the MaxConnections allowed */ -static int get_maxconn(request_rec* r, apr_array_header_t* a) +static int get_maxconn(request_rec *r, apr_array_header_t *a) { - bw_maxconn* e = (bw_maxconn*)a->elts; - const char* remotehost = NULL; + bw_maxconn *e = (bw_maxconn *)a->elts; + const char *remotehost = NULL; int i; int gothost = 0; - const char* uastr = NULL; + const char *uastr = NULL; for (i = 0; i < a->nelts; i++) { @@ -685,13 +682,13 @@ static int get_maxconn(request_rec* r, apr_array_header_t* a) } /* Get an id based on bandwidth limit */ -static int get_sid(request_rec* r, apr_array_header_t* a) +static int get_sid(request_rec *r, apr_array_header_t *a) { - bw_entry* e = (bw_entry*)a->elts; - const char* remotehost = NULL; + bw_entry *e = (bw_entry *)a->elts; + const char *remotehost = NULL; int i; int gothost = 0; - const char* uastr; + const char *uastr; remotehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_HOST, @@ -736,10 +733,10 @@ static int get_sid(request_rec* r, apr_array_header_t* a) } /* Get an id based on filesize limit */ -static int get_f_sid(request_rec* r, apr_array_header_t* a, apr_uint32_t filesize, - const char* filename) +static int get_f_sid(request_rec *r, apr_array_header_t *a, apr_uint32_t filesize, + const char *filename) { - bw_sizel* e = (bw_sizel*)a->elts; + bw_sizel *e = (bw_sizel *)a->elts; int i; apr_uint32_t tmpsize = 0, tmpsid = -1; @@ -762,7 +759,7 @@ static int get_f_sid(request_rec* r, apr_array_header_t* a, apr_uint32_t filesiz } /* Update memory (shm) counters, which holds the bw data per context */ -static void update_counters(bw_data* bwstat, ap_filter_t* f) +static void update_counters(bw_data *bwstat, ap_filter_t *f) { apr_time_t nowtime; @@ -789,10 +786,10 @@ static void update_counters(bw_data* bwstat, ap_filter_t* f) } } -static int callback(request_rec* r) +static int callback(request_rec *r) { int t; - bw_data* bwstat; + bw_data *bwstat; if (r->header_only) { return OK; @@ -848,25 +845,23 @@ static int callback(request_rec* r) ap_rputs("\n", r); return OK; - - } /*----------------------------------------------------------------------------* * The Handler and the Output Filter. Core of the mod. * *----------------------------------------------------------------------------*/ /* With this handler, we can *force* the use of the mod. */ -static int handle_bw(request_rec* r) +static int handle_bw(request_rec *r) { - bandwidth_server_config* sconf = - (bandwidth_server_config*)ap_get_module_config(r->server-> + bandwidth_server_config *sconf = + (bandwidth_server_config *)ap_get_module_config(r->server-> module_config, &bw_module); - bandwidth_config* conf = - (bandwidth_config*)ap_get_module_config(r->per_dir_config, + bandwidth_config *conf = + (bandwidth_config *)ap_get_module_config(r->per_dir_config, &bw_module); - bw_data* bwstat; + bw_data * bwstat; apr_int32_t confid; /* Only work on main request/no subrequests */ @@ -875,7 +870,6 @@ static int handle_bw(request_rec* r) if (strcmp(r->handler, "modbw-handler") == 0) return callback(r); - /* Return if module is not enabled */ if (sconf->state == BANDWIDTH_DISABLED) return DECLINED; @@ -904,26 +898,26 @@ static int handle_bw(request_rec* r) return DECLINED; } -static int bw_filter(ap_filter_t* f, apr_bucket_brigade* bb) +static int bw_filter(ap_filter_t *f, apr_bucket_brigade *bb) { - request_rec* r = f->r; - bandwidth_config* conf = - (bandwidth_config*)ap_get_module_config(r->per_dir_config, + request_rec *r = f->r; + bandwidth_config *conf = + (bandwidth_config *)ap_get_module_config(r->per_dir_config, &bw_module); - bandwidth_server_config* sconf = - (bandwidth_server_config*)ap_get_module_config(r->server-> + bandwidth_server_config *sconf = + (bandwidth_server_config *)ap_get_module_config(r->server-> module_config, &bw_module); - ctx_struct* ctx = f->ctx; - apr_bucket* b = APR_BRIGADE_FIRST(bb); - bw_data* bwstat, * bwmaxconn; + ctx_struct *ctx = f->ctx; + apr_bucket *b = APR_BRIGADE_FIRST(bb); + bw_data *bwstat, *bwmaxconn; int confid = -1, connid = -1; apr_size_t packet = conf->packet, bytes = 0; apr_off_t bblen = 0; apr_size_t bw_rate, bw_min, bw_f_rate, cur_rate = 0; apr_interval_time_t sleep; - const char* buf; - const char* filename; + const char *buf; + const char *filename; long current_sleep_bypasses = 0; /* Only work on main request/no subrequests */ @@ -1182,8 +1176,8 @@ static int bw_filter(ap_filter_t* f, apr_bucket_brigade* bb) /*----------------------------------------------------------------------------* * Module Init functions * *----------------------------------------------------------------------------*/ -static int bw_init(apr_pool_t* p, apr_pool_t* plog, apr_pool_t* ptemp, - server_rec* s) +static int bw_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, + server_rec *s) { apr_status_t status; apr_size_t retsize; @@ -1195,12 +1189,12 @@ static int bw_init(apr_pool_t* p, apr_pool_t* plog, apr_pool_t* ptemp, #endif /* These two help ensure that we only init once. */ - void* data; - const char* userdata_key = "ivn_shm_bw_limit_module"; + void *data; + const char *userdata_key = "ivn_shm_bw_limit_module"; apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!data) { - apr_pool_userdata_set((const void*)1, userdata_key, + apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null, s->process->pool); return OK; } @@ -1285,7 +1279,6 @@ static int bw_init(apr_pool_t* p, apr_pool_t* plog, apr_pool_t* ptemp, ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "mod_bw : Supported resolution for Timers [ Min: %d Max: %d ]", resolution.wPeriodMin, resolution.wPeriodMax); - if (timeBeginPeriod(resolution.wPeriodMin) == TIMERR_NOERROR) ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "mod_bw : Enabling High resolution timers [ %d ms ]", resolution.wPeriodMin); @@ -1299,41 +1292,41 @@ static int bw_init(apr_pool_t* p, apr_pool_t* plog, apr_pool_t* ptemp, } -static void* create_bw_config(apr_pool_t* p, char* path) +static void *create_bw_config(apr_pool_t *p, char *path) { - bandwidth_config* new = - (bandwidth_config*)apr_palloc(p, sizeof(bandwidth_config)); + bandwidth_config *new = + (bandwidth_config *)apr_palloc(p, sizeof(bandwidth_config)); new->limits = apr_array_make(p, 20, sizeof(bw_entry)); new->minlimits = apr_array_make(p, 20, sizeof(bw_entry)); new->sizelimits = apr_array_make(p, 10, sizeof(bw_sizel)); new->maxconnection = apr_array_make(p, 10, sizeof(bw_maxconn)); - new->directory = (char*)apr_pstrdup(p, path); + new->directory = (char *)apr_pstrdup(p, path); new->packet = PACKET; new->error = HTTP_SERVICE_UNAVAILABLE; - return (void*) new; + return (void *) new; } -static void* create_bw_server_config(apr_pool_t* p, server_rec* s) +static void *create_bw_server_config(apr_pool_t *p, server_rec *s) { - bandwidth_server_config* new; + bandwidth_server_config *new; new = - (bandwidth_server_config*)apr_pcalloc(p, + (bandwidth_server_config *)apr_pcalloc(p, sizeof (bandwidth_server_config)); new->state = BANDWIDTH_DISABLED; new->force = BANDWIDTH_DISABLED; - return (void*) new; + return (void *) new; } /*----------------------------------------------------------------------------* * Apache register functions * *----------------------------------------------------------------------------*/ -static void register_hooks(apr_pool_t* p) +static void register_hooks(apr_pool_t *p) { /* - Register a handler, which enforces mod_bw if needed From ea0c24f85f5ca3f96c2daf199f377a962e8d0238 Mon Sep 17 00:00:00 2001 From: sosherof Date: Tue, 26 Oct 2021 12:03:45 -0700 Subject: [PATCH 8/8] More revertion of VS "fixes" to formatting. --- mod_bw.c | 59 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/mod_bw.c b/mod_bw.c index dec7f29..22e038c 100644 --- a/mod_bw.c +++ b/mod_bw.c @@ -24,11 +24,11 @@ Platform : Linux/x86 (Tested with Fedora Core 4, Suse, etc) Notes : This is a stable version of mod_bw. It should work with almost any MPM (tested with WinNT/prefork/Worker MPM). - We are reaching the End of mod_bw series 0.x. As soon as this + We are reaching the End of mod_bw series 0.x. As soon as this last changes are confirmed by the users (perhaps some changes at request), i'll set this release to version 1.0 final. -Limitations : This mod doesn't know how fast the client is +Limitations : This mod doesn't know how fast the client is downloading a file, so it just divides the bw assigned between the users. MaxConnections works only for the given scope. (i.e , all @@ -40,7 +40,7 @@ Changelog : 2010-05-27 : Fixed weird behaviour on Windows Hosts. (mod_bw.txt) Added high resolution timers for windows. (speed improvements) Fixed stupid bug that caused crash when mod is enabled but there is - not a single limit. + not a single limit. 2010-05-24 : Code Cleanup. No more warnings or stuff in Visual Studio 2010-04-28 : Bruce's Birthday Gift : A callback to the stats of the mod :) 2010-04-06 : Fixed "Invisible" memory leak. Only seen when serving HUGE streams. @@ -71,8 +71,8 @@ Changelog : #include "scoreboard.h" #if defined(WIN32) -#include -#include + #include + #include #endif #define MIN_BW 256 /* Minimal bandwidth 256 bytes */ @@ -85,23 +85,23 @@ Changelog : /* Compatibility with regex on apache less than 2.1 */ #if !AP_MODULE_MAGIC_AT_LEAST(20050127,0) -typedef regex_t ap_regex_t; -#define AP_REG_EXTENDED REG_EXTENDED -#define AP_REG_ICASE REG_ICASE + typedef regex_t ap_regex_t; + #define AP_REG_EXTENDED REG_EXTENDED + #define AP_REG_ICASE REG_ICASE #endif /* Compatibility with obsolete ap_get_server_version() */ #if !AP_MODULE_MAGIC_AT_LEAST(20051115,4) -#define ap_get_server_banner ap_get_server_version + #define ap_get_server_banner ap_get_server_version #endif /* Compatibility for APR < 1 */ #if ( defined(APR_MAJOR_VERSION) && (APR_MAJOR_VERSION < 1) ) -#define apr_atomic_inc32 apr_atomic_inc -#define apr_atomic_dec32 apr_atomic_dec -#define apr_atomic_add32 apr_atomic_add -#define apr_atomic_cas32 apr_atomic_cas -#define apr_atomic_set32 apr_atomic_set + #define apr_atomic_inc32 apr_atomic_inc + #define apr_atomic_dec32 apr_atomic_dec + #define apr_atomic_add32 apr_atomic_add + #define apr_atomic_cas32 apr_atomic_cas + #define apr_atomic_set32 apr_atomic_set #endif /* Enum types of "from address" */ @@ -112,7 +112,7 @@ enum from_type { T_AGENT }; -/* +/* - Stats of each conf - - id = Configuration ID @@ -147,21 +147,20 @@ typedef struct ctx_struct_t /* With sid we count the shared memory needed. BwBase, is a holder to the shared memory base addres */ -static char* vnames[MAX_VHOSTS]; +static char *vnames[MAX_VHOSTS]; static int sid = 0; -bw_data* bwbase; -apr_shm_t* shm; - +bw_data *bwbase; +apr_shm_t *shm; /* Limits for MaxConnections based on directory */ typedef struct { apr_uint32_t sid; union { - char* from; + char *from; apr_ipsubnet_t *ip; } x; - ap_regex_t* agent; + ap_regex_t *agent; enum from_type type; apr_uint32_t max; } bw_maxconn; @@ -171,10 +170,10 @@ typedef struct { apr_uint32_t sid; union { - char* from; + char *from; apr_ipsubnet_t *ip; } x; - ap_regex_t* agent; + ap_regex_t *agent; enum from_type type; apr_int32_t rate; } bw_entry; @@ -183,7 +182,7 @@ typedef struct typedef struct { apr_uint32_t sid; - char* file; + char *file; apr_uint32_t size; apr_uint32_t rate; } bw_sizel; @@ -197,7 +196,7 @@ typedef struct apr_array_header_t *maxconnection; unsigned int packet; int error; - char* directory; + char *directory; } bandwidth_config; /* Per server configuration structure */ @@ -214,12 +213,12 @@ module AP_MODULE_DECLARE_DATA bw_module; * Configurations Directives * *---------------------------------------------------------------------*/ /* Set the mod enabled ... or disabled */ -static const char *bandwidthmodule(cmd_parms* cmd, void* dconf, int flag) +static const char *bandwidthmodule(cmd_parms * cmd, void *dconf, int flag) { - bandwidth_server_config* sconf; + bandwidth_server_config *sconf; sconf = - (bandwidth_server_config*)ap_get_module_config(cmd->server-> + (bandwidth_server_config *)ap_get_module_config(cmd->server-> module_config, &bw_module); sconf->state = (flag ? BANDWIDTH_ENABLED : BANDWIDTH_DISABLED); @@ -228,7 +227,7 @@ static const char *bandwidthmodule(cmd_parms* cmd, void* dconf, int flag) } /* Set force mode enabled ... or disabled */ -static const char* forcebandwidthmodule(cmd_parms* cmd, void* dconf, +static const char *forcebandwidthmodule(cmd_parms * cmd, void *dconf, int flag) { bandwidth_server_config *sconf; @@ -243,7 +242,7 @@ static const char* forcebandwidthmodule(cmd_parms* cmd, void* dconf, } /* Set the packetsize used in the context */ -static const char *setpacket(cmd_parms* cmd, void* s, const char* pack) +static const char *setpacket(cmd_parms * cmd, void *s, const char *pack) { bandwidth_config *conf = (bandwidth_config *)s; int temp;