124 lines
3.5 KiB
Forth
124 lines
3.5 KiB
Forth
\ Denial of service protection.
|
|
\ TODO: Use hash table instead?
|
|
|
|
require util.4th
|
|
|
|
[UNDEFINED] MAX_CONNECTIONS [IF] 32 constant MAX_CONNECTIONS [THEN]
|
|
|
|
10 constant DOS_UPDATE_INTERVAL
|
|
1024 constant DOS_BYTES_PER_INTERVAL
|
|
10 constant DOS_LINES_PER_INTERVAL
|
|
3 constant DOS_MAX_CONNECTIONS
|
|
MAX_CONNECTIONS constant DOS_MAX_MAPPINGS
|
|
|
|
\ TODO: is 0 a valid circuit id?
|
|
\ TODO: if not, then we could use the circuit id instead of dos.set
|
|
0
|
|
cell +field dos.set
|
|
cell +field dos.circuit-id
|
|
cell +field dos.handled
|
|
cell +field dos.connections
|
|
cell +field dos.total-bytes
|
|
cell +field dos.total-lines
|
|
cell +field dos.bytes
|
|
cell +field dos.lines
|
|
constant /DOS
|
|
|
|
/DOS DOS_MAX_MAPPINGS * constant DOS_ARRAY_SIZE
|
|
create dos DOS_ARRAY_SIZE alloterase
|
|
|
|
\ Lookup table: connection index -> dos stats
|
|
create doslt DOS_MAX_MAPPINGS cells alloterase
|
|
|
|
: (translate) ( index-n -- dos-addr )
|
|
/DOS * dos + ;
|
|
: (init-dos) ( free-addr circuit-id-n -- dos-addr )
|
|
over dos.circuit-id !
|
|
true over dos.set ! ;
|
|
: (find) ( circuit-id-n -- dos-addr )
|
|
0 swap dos DOS_ARRAY_SIZE + dos DO ( -- free-addr circuit-id-n )
|
|
I dos.set @ IF
|
|
dup I dos.circuit-id @ = IF
|
|
2drop I UNLOOP EXIT
|
|
THEN
|
|
ELSE
|
|
over 0= IF
|
|
nip I swap
|
|
THEN
|
|
THEN
|
|
/DOS +LOOP
|
|
(init-dos) ;
|
|
: (lttranslate) ( connection-index-n -- lookup-addr )
|
|
cells doslt + ;
|
|
: (lookup) ( connection-index-n -- dos-addr )
|
|
(lttranslate) @ ;
|
|
|
|
: (mod-connections) ( n dos-addr -- ) dos.connections +! ;
|
|
: (inc-connections) ( dos-addr -- ) 1 swap (mod-connections) ;
|
|
: (dec-connections) ( dos-addr -- ) -1 swap (mod-connections) ;
|
|
: dos-add-connection ( circuit-id-n connection-index-n -- )
|
|
(lttranslate) dup @ 0= IF
|
|
swap (find) tuck (inc-connections) !
|
|
ELSE
|
|
2drop EXIT
|
|
THEN ;
|
|
: dos-remove-connection ( connection-index-n -- )
|
|
\ erase if last connection
|
|
(lttranslate) dup 0<> IF
|
|
dup @ >r 0 swap ! r>
|
|
dup (dec-connections)
|
|
dup dos.connections @ 0= IF
|
|
/DOS erase
|
|
ELSE
|
|
drop
|
|
THEN
|
|
ELSE
|
|
drop
|
|
THEN ;
|
|
: dos-add-bytes ( bytes-n connection-index-n -- )
|
|
(lookup) dos.bytes +! ;
|
|
: dos-add-lines ( lines-n connection-index-n -- )
|
|
(lookup) dos.lines +! ;
|
|
: (update) ( dos-addr -- )
|
|
dup dos.bytes @ over dos.total-bytes +!
|
|
dup dos.lines @ over dos.total-lines +!
|
|
0 over dos.bytes !
|
|
0 over dos.lines !
|
|
drop ;
|
|
: dos-update ( -- )
|
|
\ add time interval bytes and lines to total and set to 0
|
|
dos DOS_ARRAY_SIZE + dos DO
|
|
I dos.set @ IF
|
|
I (update)
|
|
THEN
|
|
/DOS +LOOP ;
|
|
|
|
: (check-bytes) ( dos-addr -- flag ) dos.bytes @ DOS_BYTES_PER_INTERVAL > ;
|
|
: (check-lines) ( dos-addr -- flag ) dos.lines @ DOS_LINES_PER_INTERVAL > ;
|
|
: (check-connections) ( dos-addr -- flag ) dos.connections @ DOS_MAX_CONNECTIONS > ;
|
|
: dos-handled! ( flag connection-index-n -- )
|
|
(lttranslate) @ dos.handled ! ;
|
|
: dos-handled? ( connection-index-n -- flag )
|
|
(lttranslate) @ dos.handled @ ;
|
|
: dos? ( connection-index-n -- flag )
|
|
(lttranslate) @
|
|
dup (check-bytes) over (check-lines)
|
|
rot (check-connections) or or ;
|
|
|
|
: (.dos-info) ( dos-addr -- )
|
|
dup ." CircuitID: " dos.circuit-id @ . cr
|
|
dup ." Connections: " dos.connections @ . cr
|
|
dup ." Total bytes: " dos.total-bytes @ . cr
|
|
dup ." Total lines: " dos.total-lines @ . cr
|
|
dup ." Bytes: " dos.bytes @ . cr
|
|
dup ." Lines: " dos.lines @ . cr
|
|
drop ;
|
|
: .dos-info ( connection-index-u -- )
|
|
(lttranslate) @ (.dos-info) ;
|
|
: .dos ( -- )
|
|
dos DOS_ARRAY_SIZE + dos DO
|
|
I dos.set @ IF
|
|
cr I (.dos-info)
|
|
THEN
|
|
/DOS +LOOP ;
|