One of the new features in VPOP3 Enterprise v6 is enhanced bandwidth control. This allows you to restrict the speed of VPOP3 connections for different users, services and IP addresses.
VPOP3 Basic has basic bandwidth control, so this article may still be useful, but VPOP3 Basic does not support ‘bandwidth pools’ or scripting.
Because of the flexibility it can get a bit complex, so this article will attempt to explain how the feature can be used.
If you go to the VPOP3 settings, and go to Services and select a service – we’ll choose the IMAP4 service, you’ll see a setting on the General tab called Bandwidth Throttling. The default setting for this is “No Limit”.
In VPOP3 Basic, you will only have two options: “No Limit” and “Custom”, in VPOP3 Enterprise you will have those two options, plus 1000 ‘Bandwidth Pool’ options.
Let’s look at the two basic settings first
The “No Limit” option, as the name suggests, means that there is no bandwidth limiting.
The “Custom” option lets you specify a maximum speed (in bytes/second) for each connection using this service. So, if you set the custom value for the IMAP4 service to 100000, then each connection using the IMAP4 service will be limited to 100,000 bytes per second (800,000 bits per second). If the server is handling 10 IMAP4 connections at once, then each connection is limited to 100,000 bytes per second, so the total throughput could be up to 1,000,000 bytes per second.
For many bandwidth control operations this has limited use, because you may want to throttle the IMAP4 service to only use so much bandwidth regardless of how many connections there are. This is where Bandwidth Pools come into play.
To have access to Bandwidth Pools, you need to have VPOP3 Enterprise.
Bandwidth pools are configured in Settings -> Misc Settings -> Bandwidth Pools. VPOP3 supports 1000 bandwidth pools. By default, they are all configured to allow unlimited bandwidth.
You can easily assign a bandwidth limit to a pool by double-clicking on the ‘Allowed Bandwidth’ column for the pool you want to edit, and typing in the new bandwidth limit (in bytes per second). You can also assign a name to the bandwidth pool for your future reference.
Now, you could go to the IMAP4 service settings, and choose ‘Bandwidth Pool 1’ to be the bandwidth limit for the IMAP4 service. When you have done that, then all the connections using that service will share the bandwidth from the chosen bandwidth pool.
If you wish, you could also choose ‘Bandwidth Pool 1’ to be the bandwidth limit for the POP3 service as well. Now, the bandwidth pool allowance is shared among all POP3 and IMAP4 connections.
If you wish, you can create ‘nested pools’. To do this, use negative numbers as the pool bandwidth limit where the negative number indicates the ‘parent’ pool. For instance, you could create settings as below. In this case, the “POP3” and “IMAP4” pools both share the “VPOP3” pool limit. This is achieved by looking at the ID of the ‘VPOP3’ pool (3), and making it negative, and setting that as the limit for the ‘child’ pools.
The POP3 and IMAP4 pools are not copies of the VPOP3 pool, but share the pool, so all users of the POP3 and IMAP4 pools would be limited to 100,000 bytes per second in total.
In itself this does not give you any functionality you would not otherwise have (you could simply set both the POP3 and IMAP4 services to use the “VPOP3” pool), but it does mean that in the future, you could change the limits from the Bandwidth pool settings without having to edit the services individually. This becomes even more useful when you come to use bandwidth scripting,
The real power of the bandwidth limits becomes apparent when you can use scripting (only in VPOP3 Enterprise) using the Lua programming language.
The reference guide for the bandwidth scripting is on our Wiki, but here are some examples and ideas. The reason we have used scripting rather than discrete settings is that scripting would allow the feature to be used in ways we may not have considered yet.
Every time a new connection starts to a VPOP3 service, or the ‘state’ changes (eg someone logs in), then a Lua function is called. This function is called ‘GetBandwidth’ and is stored in the ‘bandwidth.lua’ file in the VPOP3 directory (you can create/edit this file using a simple text editor such as Notepad). This function is passed several parameters, such as details of which service the connection is for, user details (if any), client IP address, and so on. Then, the function can return a value to indicate the bandwidth limit to be used:
- 0 = no limit
- 1 to 999999999 = limit for this connection (in bytes per second)
- -1 to -1000 = bandwidth pool to be used (as a negative number – “-1” = bandwidth pool 1, etc)
As you can probably imagine by now, there are many ways this can be used. For instance:
- you could give some people a different bandwidth limit from other people,
- external IP addresses could have a low limit, while internal IP addresses are unlimited,
- you could use other Lua function to do things such as check the current time, and give different bandwidth limits based on the time of day (however, note that the function is only called at the start of the connection, not periodically while the connection is active).
External IP addresses are limited
-- pool '1' is set to the limited pool -- This function either returns unlimited for local users (192.168.x.y), or '-1' to assign external users to pool 1
if string.find(params["clientip"], "^192%.168%.") then return 0; -- unlimited else return -1; -- use pool 1 end; end;
Most users are limited, but the boss isn’t
-- pool '1' is set to the limited pool -- This function either returns unlimited for connections from 'theboss', or '-1' to assign other users to the limited pool
if params["username"] == "theboss" then return 0; -- unlimited else return -1; -- use pool 1 end; end;
External IP addresses are limited to different pools depending on time of day. The boss is always unlimited
-- pool '1' is set to the daytime limited pool -- pool '2' is the evening limited pool -- This function either returns unlimited for local users (192.168.x.y), or the boss, or '-1' or '-2' to assign external users to the relevant pool
if string.find(params["clientip"], "^192%.168%.") or params["username"] == "theboss" then return 0; -- unlimited else -- limited users t = os.date("*t"); if (t.hour >= 18) or (t.hour == 17 and t.min >= 30) or (t.hour < 8) or (t.wday == 6) or (t.wday == 0) then return -2; -- use pool 2 after 5:30pm or before 8am or at weekends else return -1; -- use pool 1 at other times of day end;