cFosSpeed supports a number of different traffic classes set to different priorities. In effect, this means packets in classes with a higher priority are sent out prior to packets from classes with lower priority - even if low-priority packets arrive before high-class packets in their respective class queues.
That way, cFosSpeed can prioritize specific packets permitting them to take the "fast lane" and zip past "normal" traffic. This priority system can be modified and expanded by the user with what we call "filter expressions." These can be used to filter out packets and assign them to a desired traffic class.
Filter expressions consist of a series of "filter rules" that all need to be true for the entire expression to be true. If the entire expression is true, the packet is put into the corresponding class queue.
A list of filter expressions does allow you to filter for several different packets. This list is checked from top to bottom; the first filter expression found to be true (i.e., consisting only of true filter rules) is employed, ending list traversal.
Packets not matching any particular filter expression are automatically assigned to the "default" class, which is a built-in class with priority 0.
A sample list of filter expressions is given below (the output looks like the "spd filter" output described later in this overview). Note that this sample is provided for illustration purposes only; it has no other use.
0 -p icmp -c fast 1 -tcp-sport 1234 -tcp-dport 5678 -c special
This would mean that if a packet is of IP protocol "icmp", it would be assigned to "fast" class, ending traversal of the list.
If a packet does not match the first expression, then it will be checked for the second expression. In this case, the latter consists of two rules, which must both be true for the entire expression to be true (a boolean AND).
The "-tcp-sport" entry checks the TCP source port number. Accordingy, for this sample rule to be true, the packet must have IP protocol "tcp" and the tcp source port must be 1234.
Then, there is rule 2, which is true if (again) it's a tcp packet and the tcp destination port is 5678.
Thus, all tcp traffic transmitted from port 1234 to port 5678 would be assigned to "special" class.
If neither of the two rules apply to the packet (which should happen fairly often), it would be put into "default" class instead.
Now let's go into more detail.
Each rule can be negated by preceding it with a '!' (exclamation mark) or by putting the '!' in between the option name and value (if such a value does exist). So it has to be "!-f", but you could also use "!-p icmp" or "-p !icmp".
Underlying most rules are one or more implicit assumptions; for instance, -tcp-length assumes it's a tcp packet after all. These assumptions are listed with each rule. If a packet does not match the assumptions, the rule is false. Note that the rule would be false even if you negated it (by using '!').
That is, a !-tcp-length 0 rule would match TCP packets of any length other than zero, but would not match any non-tcp packet.
If you need to specify a number, you can enter the number either in decimal (just type it in as is) or hexadecimal (prefix it with "0x") format. For example, 16 and 0x10 both denote decimal number 16.
For some rules, a range of values can be entered. Allowable value ranges are:
What's more, a list of ranges can be entered for some rules. That is simply a concatenation of several ranges, separated by commas (,). For example, "1:2,3:4" is just another way of writing "1:4".
Details on the IP header can be found in RFC 791 (Internet Protocol), www.ietf.org/rfc/rfc0791.txt.
IP header filter rules apply only to IP packets with a correct checksum. These rules work on any IP packet, fragment or not.
Details on the UDP header can be found in RFC 768 (User Datagram Protocol, www.ietf.org/rfc/rfc0768.txt). Note that each UDP header is prefixed by an IP header, since UDP needs IP for transmission.
UDP header filter rules apply only to packets with correct IP header checksum, UDP-protocol set, and correct UDP-header checksum. In addition, they must either be unfragmented or the last fragment that completes the reassembled datagram.
Details on the TCP header can be found in RFC 793 (Transmission Control Protocol, www.ietf.org/rfc/rfc0793.txt). Note that each TCP header is prefixed by an IP header, since TCP needs IP for transmission.
TCP header filter rules apply only to packets with correct IP header checksum, and TCP protocol set. They must be either unfragmented or the last fragment that completes the reassembled datagram.
Sometimes you have to specify the same rules for UDP and TCP ports. This can be done by the following combo rules.
The assumptions for UDP and TCP packets each still apply.
Details on the ICMP header can be found in RFC 792 (Internet Control Message Protocol, www.ietf.org/rfc/rfc0792.txt). Note that each ICMP header is prefixed by an IP header, since ICMP needs IP for transmission.
ICMP header filter rules apply only to packets with correct IP-header checksum, ICMP protocol set, and correct ICMP checksum. Such packets must also be either unfragmented or the last fragment that completes the unfragmented datagram.
cFosSpeed ships with five traffic classes, called "highest", "higher", "high", "low" and "lowest". To assign traffic to these classes, we have combined individual rules into mega-rules.
If you remove the standard rules, you will most likely disable or damage the traffic-shaping operation of cFosSpeed. So, it's an excellent idea to leave them in place and just add your own rules below these rules!
cFosSpeed has two built-in traffic classes: "default" and "drop". All traffic that isn't matched by anything else goes to "default". Its implicit priority is 0.
You can use "drop" to delete a packet and don't send it at all. This allows you to do your own little firewalling with it (only for outbound traffic). "Drop" has no priority.
Used to order classes, "priority" is entered as an integer. To avoid confusion, no two classes should be assigned the same priority value. Packets of a traffic class with higher priority are sent prior to packets belonging to a traffic class with lower priority.
"Priority" is usually a positive value for regular classes. However, you can specify "low prio" classes with a negative priority value. Packets in low prio classes are only sent out if there is no high and no default class traffic ready for transmission.
This concept is exactly the opposite of high prio class. With high prio classes, you can mark specific packets to be sent out in front of other data. With low prio classes, you can mark specific packets to be sent out after other data. Beware that specifying rules for low classes can easily lead to "starving" connections, because all other data would then take precedence.
In addition, all traffic classes can be assigned a speed setting. The speed setting determines up to how many bytes/second the class priority will remain in effect. Beyond that, packets are treated as being in the default class. That way, for instance, you could prioritize traffic, but only if it does not exceed, say, 1000 bytes/second. Once that speed is exceeded, the traffic would not be prioritized any more.
The speed settings can done in percent as well, where 100% denotes the total speed of the connection. Specifying "-speed 20%" and "-speed 20perc" means the same. Speed settings of low classes must have a priority value that is used in case the speed is exceeded. It looks like this: "-speed 20%,-10".
As an example take the setting "-prio 0 -speed 20%,-10". Traffic in this class is sent out with priority 0 (i.e., default) if it's slower than 20% of the maximum speed and with priority -10 otherwise.
Classes can have a DSCP value as well. If set, this value is set to all outgoing packets of that class. Specify "-dscp X" in the class line to set DSCP value of "X". DSCP values range from 0 to 63. By default, DSCP values are not set for any class. For more details see RFC 2474 (Differentiated Services, www.ietf.org/rfc/rfc2474.txt).
You can set VLAN Identifier (VID) and Priority Code Point (PCP) for traffic classes as well. To set VID, use "-vlan-id X" option for the traffic class, where "X" is the Identifier. VIDs range from 0 to 4095 (0xfff hex). To set PCP, use "-vlan-prio X", respectively, where X is the PCP. PCPs range from 0 to 7. If you set one of these, all outgoing packets will have VID and PCP set. By default, VLAN settings are not changed for the packets of any class. For more details see IEEE 802.1Q (e.g. on Wikipedia).
In order to filter for huge amounts of IP-ranges, cFosSpeed has support for IP-range files like ipfilter.dat the same way IP-Blockers like Protowall and Peerguradian support them. All traffic to or from one of the listed addresses is blocked. We call those lists "iplists".
cFosSpeed supports these iplists through two filter expressions: -s-iplist and -d-iplist. They are already set by default in settings.ini. -s-iplist matches the source IP address against a given list, -d-iplist the destination IP address.
The -s-iplist and -d-iplist filter accept the iplist name as second parameter. The default name used in settings.ini is "ipfilter". In the [iplist] section in settings.ini or user.ini you must specify the iplist names with the corresponding IP block list files that contain the IP-ranges to be blocked. These block lists are not supplied with cFosSpeed.
The [iplist] section contains lines in the format "listname=filename". 'listname' is used to filter for the IP-addresses listed in 'filename'. You can have more than one list with different names and each list can be made up of more than one file. When compiling the lists, duplicate entries are removed and the whole list is sorted and optimized. You can put this section in user.ini, so it will not be overwritten with the next cFosSpeed update.
An example excerpt from settings.ini:
filter=-tx -d-iplist ipfilter -c drop filter=-rx -s-iplist ipfilter -c drop [iplist] ipfilter=c:\text\ipfilter.dat ipfilter=c:\text\my.dat
This will read both files and make them available as iplist named 'ipfilter'. This iplist is used by default to filter packets to the drop queue, i.e. to discard them. However, this rule is not active by default, since no IP block list file is set up.
Currently two IP-range file-formats are supported. This is the Emule format:
from-address - to-address [, rest-ignored...]Example:
0.0.0.1 - 3.255.255.255 , blablaAnd this is the Protowall/Peerguardian format:
ignored-text:from-address - to-addressExample:
blabla:0.0.0.1 - 3.255.255.255
The block lists can be quite big and consume a lot of memory. Each line with an IP-range needs 8 bytes. We worked with lists that needed 2mb of memory. The process of reloading them will, for a short time, allocate three times as much.
Since the lists are so big, they have to be read into memory from disk and compiled. This can take some short time, so it is only done when cFosSpeed is loaded or on demand. To re-load the block lists on demand use "spd reload -iplist".
Blocked packets will be dumped to text file FWLOG.TXT like all other firewalled packets. You can switch off the dumping by setting "spd gset fwlog 0".
Classes can have weights assigned for rx-priorisation. The concept is like this:
Each class (highest, higher, high, default, low, lowest) has a weight assigned. Furthermore, all TCP connections are mapped to a certain class (this only applies for bulk data; e.g. ACKs are always sent out in the higher class; see below for how the class mapping is done), according to filter rules. The class weight is used when TCP windows for rx-shaping are computed. A TCP connection with weight 100 gets a window that is about 4 times bigger than a connection with weight 25. This should usually translate into more speed on that connection, but not necessarily (e.g. the sending server might not be fast enough).
The pre-set weights are:
class highest -weight 400 class higher -weight 400 class high -weight 400 class default -weight 100 class low -weight 25 class lowest -weight 6
I.e. regular browser downloads (class default) should get about 16 times the speed than Torrents (class lowest).
The weighting needs some time (some seconds) to be through, so a newly created higher-than-average TCP connection needs these seconds to come to full speed.
How does cFosSpeed know which TCP connection has which class, since the filters assign classes on a packet-by-packet basis? Well, there are filter expressions that are constant for all packets that belong to a certain connection. The expression might be true or false, but it doesn't change from one packet to the next. You can see which filter expressions have this criterium by using "spd filter":
rt- -highest -c highest rt- -higher -c higher rt- -high -c high rt- -l7-prot @higherprots -c higher rtc -l7-prot @highprots -c high rtc -l7-prot @lowprots -c low rtc -l7-prot @lowestprots -c lowest rt- -prog @higherprogs -c higher rtc -prog @highprogs -c high rt- -prog @lowprogs -c low rtc -prog @lowestprogs -c lowest rt- -low -c low
The first column (with the "rtc") shows this: 'r' means the filter is active when receiving packets, 't' means the same for transmitting packets. 'c' means that it is constant and thus 'c' is set for the -l7-prot and -prog rules, since the l7-protocol and program name are saved on a per-connection basis. The -high etc. filters are packet specific and thus have no 'c' set.
Now what if cFosSpeed is wrong about the constantness of a filter expression? For example you could have DSCP values assigned to certain connections from another machine, but the -dscp rule is a per-packet rule, not a per-connection rule. To force cFosSpeed to set the class even on account of such a filter expression, use the -force-set-class option. By using this, the filter expression will be flagged 'c' and thus considered constant over all packets of that conenction.
cFosSpeed comes preconfigured with five different traffic classes (in addition to the two built-in classes):
If you want to assign a class to your own prioritized traffic, use "high". It's probably best not to use the other two classes, as this may interfere with overall traffic-shaping performance. You may even add a class of your own, but don't use a priority of 90 or more for the same reason mentioned above.
Keep in mind that what the whole prioritization system basically does is reorder packets for transmission. Thus, prioritizing more packets will leave fewer packets "normal". Taken to the extreme, this means that priotizing every single packet indiscriminately would soon slow traffic on the fast lane to little more than stop and go.
The spd utility (see below) and the trace.txt file can be used to show class-usage statistics. As a general rule of thumb, I'd advise you prioritize no more than 10% or 20% of your traffic.
The cFosSpeed installation directory contains a small file called spd.exe for communicating with cFosSpeed. It lets you handle commands and will display results for you.
An easy way to use the spd tool is to click on Start - Programs - cFosSpeed - Open Console. This will bring up a regular command prompt with the cFosSpeed directory as the current one.
Another way would be to copy it to some directory in your PATH.
"spd help" provides a list of commands.
"spd ver" shows cFosSpeed version information.
"spd class" lists all traffic classes. It usually
looks like this:
class highest -prio 100 -weight 400 class higher -prio 90 -weight 400 class high -prio 80 -weight 400 class default -weight 100 class low -prio 0 -speed 25%,-10 -weight 25 class lowest -prio 0 -speed 25%,-30 -weight 6 class drop
If you want to add a class, use "spd class <name> -prio <prio>", where <name> is the class name and <prio> the assigned priority.
If you want to delete a class, use "spd class <name> -D". Classes can only be deleted if there are no expressions referring to them.
You can later change the priority of an already existing class <name> by using "spd class <name> -prio <prio>". However, you cannot change a low into a high class or vice-versa.
Likewise, you can change the speed of a class after it's been created. Just use "spd class <name> -speed <speed>" on an already existing <name>, where <speed> can be any positive number or "inf" for no speed limit.
You can get a list of the active filters by using the "spd filter" command. This will usually read something like this:
0 -highest -c highest 1 -higher -c higher 2 -high -c high 3 -prog @user.ini/highprogs -c high 4 -prog @highprogs -c high 5 -low -c low 6 -prog @user.ini/lowprogs -c low 7 -prog @lowprogs -c low 8 -prog @user.ini/lowestprogs -c lowest 9 -prog @lowestprogs -c lowest
New filter expressions can be appended to the bottom of the expression list by the "spd filter -A <filter> -c <class>" command, where <filter> is a set of filter rules and <class> is the target traffic class.
In the same way, you can use "spd filter -I <pos> ..." to insert a filter at a specific position into the filter list.
"spd filter -R <pos> ..." replaces the filter at position <pos> with the new filter.
"spd filter -M <old> <new>" moves a filter from its old position <old> to a new position <new>.
Finally, "spd filter -D <pos>" deletes a filter at position <pos>.
If you want to review your traffic-class usage, type "spd cstat" to get corresponding statistics. This is an example of what it looked like after a long time transferring:
shaping is currently enabled; txspeed = 139907, max_queue_size = 419,721 class highest -prio 100 -weight 400 sent 320,292 ( 2%) packets 8,968,176 ( 0%) bytes in queue 0 packets 0 bytes class higher -prio 90 -weight 400 sent 1,045,165 ( 8%) packets 42,809,356 ( 0%) bytes in queue 0 packets 0 bytes class high -prio 80 -weight 400 sent 411,963 ( 3%) packets 66,261,691 ( 0%) bytes in queue 0 packets 0 bytes class default -weight 100 sent 103,663 ( 0%) packets 15,722,812 ( 0%) bytes in queue 0 packets 0 bytes class low -prio 0 -speed 25%,-10 -weight 25 sent 4,670 ( 0%) packets 5,979,376 ( 0%) bytes in queue 0 packets 0 bytes class lowest -prio 0 -speed 25%,-30 -weight 6 sent 9,828,143 ( 83%) packets 10,913,999,530 ( 98%) bytes in queue 0 packets 0 bytes class drop dropped 0 packets 0 bytes queue overflow 0 packets 0 bytes
Filter expressions and classes can be modified while cFosSpeed is up and running online. If you want to save the changes you made, use "spd save" with either -class, -filter or -all to specify what to save.
You can change settings.ini from the outside with an editor as well. But you have to reload the new settings after you saved the new version of settings.ini by typing "spd reload". This will, however, only reload the filter settings, not the classes.
To manage lists of programs that are to be filtered with -tcp-prog, -udp-prog or -prog there are three commands:
With the "spd netstat" command, you can review statistics of the total traffic transmitted over your line. After the long time mentioned above, our sample stats looked as follows:
IP statistics sent rcvd bytes sent bytes rcvd Good packets 11,714,403 8,245,216 11,053,999,872 1,874,597,769 Fragments 5,267 4,608 5,781,578 4,195,207 Fragment timeouts 5,191 4,532 Fragments ignored 72 76 47,732 42,236 Protocol 2 (IGMP) 13 0 520 0 ARP statistics sent rcvd bytes sent bytes rcvd Good packets 783 130,384 21,924 5,997,484 ICMP statistics sent rcvd bytes sent bytes rcvd Good packets 320,702 341,119 9,027,507 19,482,227 Bad packets 0 1,085 0 114,283 UDP statistics sent rcvd bytes sent bytes rcvd Good packets 1,479,668 1,256,672 146,482,897 158,899,222 TCP statistics sent rcvd bytes sent bytes rcvd Good segments 9,905,831 6,638,246 10,892,171,744 1,691,413,796 Checksum errors 0 97 0 9,394 Segments w/o connection 1,961 826 223,937 36,904 Invalid RST segments 3 7 ACKs for unset data 0 2 Segments after reset 765 562 78,108 299,641 Filtered resents 193 233,461 Used sequence space 10,304,070,182 1,409,658,307 Resent segments 184,715 23,005 196,810,498 14,087,200 Reordered segments 13 200,175 556 80,270,918 Total sessions 66,765 Active sessions 4 Orderly releases 60,222 Abortive releases 6,091 Timeouted sessions 448 Failed connection attempts 15,905 2,396 Peak sessions 147 Peak half-open sessions 121 RTP statistics sent rcvd bytes sent bytes rcvd RTP Packets 0 0 0 0 RTCP Packets 347 331 9,032 9,552
It's really a lot like the Windows NETSTAT command, except it does only count packets transmitted on the cFosSpeed connection rather than all packets in the system and in some respects it's much more detailed.
The "spd cperf" command will switch on or off class traffic dumping. By setting "spd cperf on" cFosSpeed will dump about once per second how many bytes were sent in what priority class. This can help in testing filter rules or finding performance problems.
"spd fstat" command displays which filters matched how often. Use it to check if your filters are working. "spd fstat -clear" clears the stats.
cFosSpeed tries to auto-detect which technology you use to access the Internet. Sometimes it guesses wrong or the technology used it too esoteric. Here is a list of currently suppoted values:
You can check the value by issuing a "spd set method" command or change it by using "spd set method X", where X is the new value.
cFosSpeed manages your TCP MSS ("MSS clamping") (i.e., the MTU for TCP packets) automatically. The MSS values chosen are chosen so data transfer rates are maximized and ping times are minimized.
But if you want cFosSpeed to leave the MSS alone, you can enter "spd gset handle_mss 0" to instruct it so. Add a "-save" to have the setting saved in cfosspeed.ini.
Switching off MSS handling is not recommended.
Have fun making up your own traffic shaping rules!