[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: traffic shaping bittorrent



On Fri, Feb 13, 2004 at 02:36:50AM -0500, Jake Luck wrote:
> What's the best way to shape multi-user bittorrent traffic with the pf? In
> hope to control the aggregated upload rate, I tried to implement a
> queueing system very similar to the "small home network" example as
> described in the PF faq: http://www.openbsd.org/faq/pf/queueing.html :
> 
> altq on $ext_if priq bandwidth 512Kb queue 
> { qout-rest, qout-ssh, qout-dns, qout-tor, qout-tcpack }
> queue qout-rest                         priq(default)
> queue qout-ssh          priority 4      priq(red)
> queue qout-dns          priority 5              
> queue qout-tcpack       priority 6      
> queue qout-tor          priority 0      priq(red)
> 
> altq on $int_if cbq bandwidth 3Mb queue 
> { qin-rest, qin-ssh, qin-dns, qin-tor, qin-boss }
> queue qin-rest          cbq(default)
> queue qin-ssh           priority 4
> queue qin-dns           priority 5
> queue qin-tor           bandwidth 100Kb cbq
> queue qin-boss          bandwidth 200Kb cbq(borrow)
> 
> ....
> pass out on $ext_if inet proto tcp from any to any port 6881:6889
> keep state queue qout-tor
> pass out on $int_if inet proto tcp from any to any port 6881:6889 
> keep state queue qin-tor

  make sure you queue a pass in rule too.

  i was originally using pass out only, but that was having the result
  of not queueing my traffic outbound from me to whoever, when they
  came into me because i was seeding.

  adding 'pass in blahblah queue bittorrent' levelled my playing 
  field as i had been wanting, so i just use 'pass on' as you 
  will see below ( using the tagging thing from parse.y v1.437 )

  here is the current progress of my pf.conf on my desktop machine
  which does the torrenting, and also the relevant parts of the pf.conf
  from the gateway who does NAT.

  please be warned, i am NOT a pf professional, and i am an INFANT
  at understanding well the nuances of HFSC.  but this conf works, 
  	    ( in so much as it is a work-in-progress ).
  i simply set the '$btqueue' macro to be whatever upload i want to be
  able to push up from the desktop and "HUP" pf.  the rules have the effect
  of, under full load, ensuring that all my seeds are given a fair share
  at the bandwidth.  ( in other words, if i have four seeds running, 
  and all the peers connecting to me could each totally monopolize my
  outbound bandwidth allocation, meaning they all are very "downloady",
  this ensures that i don't have some lopsided affair where one queue
  is pushing up 80% of the bandwidth and leaving the other three straggling. )

  the 'btqueue' is set with consideration of what my actual outbound
  to the world is ( ~540Kb ), but the rest of the queueing allows 
  for me to still be on my 100Mb LAN happily.  i could NOT accomplish
  this gracefully with CBQ due to, afaict, 540Kb being less than 1% of
  100Mb, hence, i made the switch to HFSC, who eats it up happily.

  the 'crapola' queue is something i put in there because i still have
  this REALLY ANNOYING problem of opera ( from port ) randomly 
  pelting the living shit out of my gateway with FIN packets.  i posted
  to misc@ a long long time ago about it, but i gave poor info, and 
  since i have not seen anyone else complain of this, i assume it is
  my own fault and so i have shut up about it.

  pf is so beautiful it makes fools like me able to get away with the
  nonsense which follows below:

[ desktop ]
===========================
e="dc0"

# upload only
#btqueue="384Kb"
btqueue="475Kb"
#btqueue="510Kb"
#btqueue="296Kb"

scrub on dc0 fragment reassemble reassemble tcp

# for hfsc, no need to set both bandwidth and linkshare if they are going to be identical

altq on $e hfsc     bandwidth 100Mb tbrsize 1500 queue { data, ack, bittorrent, crapola }
queue data  hfsc(linkshare 90% default)     priority 1
queue ack   hfsc(linkshare 5%)  priority 7
queue bittorrent    bandwidth $btqueue  hfsc( realtime 64Kb upperlimit $btqueue )   priority 1 \
    { bt_def bt_6881 bt_6882 bt_6883 bt_6884 bt_6885 bt_6886 bt_6887 bt_6888 bt_6889 }
queue   bt_def      bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6881     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6882     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6883     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6884     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6885     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6886     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6887     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6888     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue   bt_6889     bandwidth 10%   priority 2  hfsc( red realtime 5% upperlimit $btqueue linkshare (10% 5000 5%) )
queue crapola   bandwidth 100b  hfsc    priority 0 qlimit 10

pass on $e all keep state queue( data ack )
pass on $e inet proto tcp from any to any keep state queue( data ack )
pass on $e inet6 proto tcp from any to any keep state queue( data ack )
pass out on $e inet proto tcp from ($e) to any port 80 flags F/F keep state queue( crapola )

pass out on $e inet proto tcp from ($e) to any port 6880><6890 modulate state queue( bt_def )
pass out on $e inet proto tcp from ($e) port 6880><6890 to any modulate state queue( bt_def )
pass in on $e inet proto tcp from any to ($e) port 6880><6890 modulate state queue( bt_def )
pass in on $e inet proto tcp from any port 6880><6890 to ($e) modulate state queue( bt_def )
pass on $e inet proto tcp from any to ($e) port 6881 modulate state queue( bt_6881 )
pass on $e inet proto tcp from any to ($e) port 6882 modulate state queue( bt_6882 )
pass on $e inet proto tcp from any to ($e) port 6883 modulate state queue( bt_6883 )
pass on $e inet proto tcp from any to ($e) port 6884 modulate state queue( bt_6884 )
pass on $e inet proto tcp from any to ($e) port 6885 modulate state queue( bt_6885 )
pass on $e inet proto tcp from any to ($e) port 6886 modulate state queue( bt_6886 )
pass on $e inet proto tcp from any to ($e) port 6887 modulate state queue( bt_6887 )
pass on $e inet proto tcp from any to ($e) port 6888 modulate state queue( bt_6888 )
pass on $e inet proto tcp from any to ($e) port 6889 modulate state queue( bt_6889 )
pass out on $e inet proto tcp from ($e) to any port 22 keep state queue( ack ) 
pass out on $e inet6 proto tcp from ($e) to any port 22 keep state queue( ack )
pass in on $ext_if inet proto tcp from any to $
=================================================

[ gateway ]
=================================
e = "fxp0"
e_bw = "520Kb"

HKLOCAL = "{192.168.7.1 192.168.7.2 192.168.7.3 192.168.7.4 192.168.7.5 192.168.7.6 192.168.7.7 192.168.7.8 192.168.7.9 }"

altq on $e hfsc bandwidth $e_bw queue {extdef extack extesp extssh extutil ext-lan extblock }
queue extdef    bandwidth 10% priority 1 hfsc( red realtime( 0% 400 5% ) linkshare( 0% 1000 10% ) upperlimit $e_bw default )
queue extack    bandwidth 10% priority 7 hfsc(   realtime( 0% 100 5% ) linkshare( 0% 100 5% ) upperlimit 5% )
queue extesp    bandwidth 10% priority 6 hfsc( red realtime( 50% 10000 30% ) linkshare( 50% 10000 25% )  upperlimit $e_bw )
queue extssh    bandwidth 10% priority 5 hfsc( red realtime( 0% 100 5% ) linkshare( 0% 50 5% ) upperlimit $e_bw )
queue extutil   bandwidth 10% priority 2 hfsc( red realtime( 0% 100 5% ) linkshare( 0% 50 5% ) upperlimit $e_bw )
queue ext-lan   bandwidth 10% priority 2 \
    { hklocal-1 hklocal-2 hklocal-3 hklocal-4 hklocal-5 hklocal-6 hklocal-7 hklocal-8 hklocal-9 hklocal-dyna }
queue   hklocal-1       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-2       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-3       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-4       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-5       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-6       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-7       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-8       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-9       bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue   hklocal-dyna    bandwidth 10% priority 2    hfsc ( red realtime( 0% 900 5% ) linkshare( 0% 2000 5% ) upperlimit $e_bw )
queue extblock  bandwidth 1024b  priority 0 hfsc( red realtime ( 0% 2000 1% )  linkshare ( 0% 500 1% )  upperlimit 1% )

nat on $e inet proto tcp from 192.168.7.1 port 6881:6889 to any tag 192.168.7.1 -> ($e) static-port
nat on $e inet proto tcp from 192.168.7.1 to any port 6881:6889 tag 192.168.7.1 -> ($e) static-port
nat on $e inet from $HKLOCAL to any tag "$srcaddr" -> ($e)
nat on $e inet from { 192.168.7.10 192.168.7.11 192.168.7.12 192.168.7.13 192.168.7.14 192.168.7.15 192.168.7.16 } \ 
	to any tag 192.168.7.dyna -> ($e)
rdr on $e inet proto tcp from any to ($e) port 6881:6889 tag 192.168.7.1 -> 192.168.7.1 port 6881:*

pass in on $e inet proto tcp from any to 192.168.7.1 port 6880><6890 modulate state tag 192.168.7.1

pass out on $e inet from ($e) to any keep state queue(extdef extack) label "ob_other"
pass in  on $e inet proto tcp           all tagged 192.168.7.1 modulate state queue( hklocal-1 extack ) label "ob_192.168.7.1"
pass out on $e inet proto tcp           all tagged 192.168.7.1 modulate state queue( hklocal-1 extack ) label "ib_192.168.7.1"
pass in  on $e inet proto { udp icmp }  all tagged 192.168.7.1 keep state queue( hklocal-1 extack )     label "ob_192.168.7.1"
pass out on $e inet proto { udp icmp }  all tagged 192.168.7.1 keep state queue( hklocal-1 extack )     label "ib_192.168.7.1"
pass in  on $e inet proto tcp           all tagged 192.168.7.2 modulate state queue( hklocal-2 extack ) label "ob_192.168.7.2"
pass out on $e inet proto tcp           all tagged 192.168.7.2 modulate state queue( hklocal-2 extack ) label "ib_192.168.7.2"
pass in  on $e inet proto { udp icmp }  all tagged 192.168.7.2 keep state queue( hklocal-2 extack )     label "ob_192.168.7.2"
pass out on $e inet proto { udp icmp }  all tagged 192.168.7.2 keep state queue( hklocal-2 extack )     label "ib_192.168.7.2"
<blahblahblah samefor hosts 3-8 blahblah> 
pass in  on $e inet proto tcp           all tagged 192.168.7.9 modulate state queue( hklocal-9 extack ) label "ob_192.168.7.9"
pass out on $e inet proto tcp           all tagged 192.168.7.9 modulate state queue( hklocal-9 extack ) label "ib_192.168.7.9"
pass in  on $e inet proto { udp icmp }  all tagged 192.168.7.9 keep state queue( hklocal-9 extack )     label "ob_192.168.7.9"
pass out on $e inet proto { udp icmp }  all tagged 192.168.7.9 keep state queue( hklocal-9 extack )     label "ib_192.168.7.9"
pass in  on $e inet proto tcp all tagged 192.168.7.dyna modulate state queue( hklocal-dyna extack ) label "ob_192.168.7.dyna"
pass out on $e inet proto tcp all tagged 192.168.7.dyna modulate state queue( hklocal-dyna extack ) label "ib_192.168.7.dyna"
pass in  on $e inet proto { udp icmp } all tagged 192.168.7.dyna keep state queue( hklocal-dyna extack ) \
	label "ob_192.168.7.dyna"
pass out on $e inet proto { udp icmp } all tagged 192.168.7.dyna keep state queue( hklocal-dyna extack ) \
	label "ib_192.168.7.dyna"

===========================================================

  so that config on the gateway ensures that all LAN hosts 1-9 and then
  collectively the ones in the 'dyna' range each can be 
  guaranteed 10% of the outbound bandwidth ( or something like that ).

  it is ugly as sin, and i ought to be able to cut the pf.conf in half 
  with the recent change ryan mcbride did to parse.y, but i am teh lay-z.

  plz don't shoot me for not wrapping those lines.  it looks
  very pretty.

  jared

-- 

[ openbsd 3.4 GENERIC ( jan 31 ) // i386 ]