Last active
April 3, 2020 12:30
-
-
Save sebres/eaed471108560fce2e75497bb0826aec to your computer and use it in GitHub Desktop.
test-concurrent-ipset.tcl -- test script concurrently flooding IPs in ipset(s)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env tclsh | |
package require Thread | |
array set in {-max-threads 4 -single-set 0 -max-ips 255 -iterations 3 -debug 0} | |
array set in $::argv | |
set commoncode { | |
if {$in(-single-set)} { | |
proc thipset {n} {return "f2b-test"} | |
proc thip {i} {return "192.${::thn}.[expr {2 + ($i >> 8)}].[expr {$i & 0xFF}]"} | |
} else { | |
proc thipset {n} {return "f2b-test-$n"} | |
proc thip {i} {return "192.0.[expr {2 + ($i >> 8)}].[expr {$i & 0xFF}]"} | |
} | |
if {$in(-debug)} { | |
set ::logpref [format " # %08s" [regsub {^tid0x} [thread::id] {\1}]] | |
proc log.debug {msg} {puts "$::logpref $msg"} | |
} else { | |
proc log.debug args {} | |
} | |
} | |
eval $commoncode | |
# init thread pool: | |
set i 0; while {[incr i] <= $in(-max-threads)} { | |
set th($i) [thread::create] | |
thread::send -async $th($i) [list set master [thread::id]] | |
thread::send -async $th($i) [list array set in [array get in]] | |
thread::send -async $th($i) $commoncode | |
} | |
time { | |
puts "== iteration [incr iter] ==" | |
# create sets and flood ipset with 255 IPs by every thread: | |
set ::ready 0 | |
set i 0; while {[incr i] <= $in(-max-threads)} { | |
thread::send -async $th($i) [list set ::thn $i] | |
thread::send -async $th($i) { | |
set sn [thipset $::thn]; exec ipset -exist create $sn hash:ip hashsize 8192 timeout 0 | |
} | |
} | |
# add tasks in lock to cause paralleled run of test in all workers (concurrence): | |
tsv::lock commonlock { | |
set i 0; while {[incr i] <= $in(-max-threads)} { | |
thread::send -async $th($i) { | |
tsv::lock commonlock {}; # wait all workers initialized | |
log.debug "begins flood ..." | |
set k 0; while {[incr k] <= $in(-max-ips)} { | |
set ip [thip $k] | |
log.debug " $ip -> $sn" | |
exec ipset add $sn $ip timeout 0 -exist | |
} | |
log.debug "ready." | |
} | |
thread::send -async $th($i) {thread::send -async $master {incr ::ready}} | |
} | |
} | |
# wait all threads are ready with its flooding part: | |
while {$::ready < $in(-max-threads)} {vwait ::ready} | |
# check all ips are present: | |
set i 0; while {[incr i] <= $in(-max-threads)} { | |
set sn [thipset $i] | |
set lst [exec ipset list $sn] | |
set lst [regexp -all -line -inline {^\s*(?:\d+\.){3}\d+} $lst] | |
puts " $sn has [llength $lst] IPs" | |
# check every IP is in the set: | |
set ::thn $i | |
set k 0; while {[incr k] <= $in(-max-ips)} { | |
set ip [thip $k] | |
if {$ip ni $lst} {puts " ** ERROR: $ip is not in set"} | |
} | |
if {$in(-single-set)} break | |
} | |
# remove sets: | |
set i 0; while {[incr i] <= $in(-max-threads)} { | |
set sn [thipset $i] | |
exec ipset flush $sn | |
exec ipset destroy $sn | |
if {$in(-single-set)} break | |
} | |
} $in(-iterations) | |
set i 0; while {[incr i] <= $in(-max-threads)} { | |
thread::release -wait $th($i) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment