Up to Main Index Up to Journal for March, 2019 JOURNAL FOR FRIDAY 8TH MARCH, 2019 ______________________________________________________________________________ SUBJECT: Connection quotas DATE: Fri 8 Mar 04:02:02 GMT 2019 After what seems like ages, I’ve finally pushed out connection quotas to the public dev branch. This is my attempt to fight off this one-liner: seq 1000000 | xargs -P8 -n1 -i@ netcat -z 172.16.1.1 4001 Actually, that is a lie. This is my umpteenth attempt at fighting the one-liner, but the first I’ve made public. At one point I had connection tracking, then a connection limiter, others I’ve already forgotten. I’ve gone back and forth between simple implementations and ones only a parent could love. Sometimes I’d scrap the code and start over, other times I’d slowly morph the code from one idea into the next idea. Along the way I’ve nearly finished each implementation before starting over — including rewriting all of the tests and documentation. It wasn’t that the code didn’t work, it wasn’t ‘clean’. I’d mixed up several ideas, or the code had become a convoluted mess, or I’d just not expressed my ideas very well in code. Writing code and documentation that is simple, and makes sense to others as well as yourself, can be hard. Finding the right default values to tune this feature has been even harder… I’ve finally settled on an implementation I call connection quotas. So what is it and how does it work? Every IP address connecting to the server has a quota of 4 connection attempts, unless quotas are disabled. If an IP address uses up its quota it will be banned from connecting until its quota is reset. The configuration file has a new Quota section with three new values that can be set to control quotas:Quota.Window, Quota.Timeout and Quota.Stats. Quota.Window is the minimum period that an IP address can use up its quota in. If the IP address goes over its quota within this period it will be banned from connecting until its quota is reset. Setting Quota.Window to 0 disables quotas. Quota.Window is the period it takes for an IP address’s quota to be reset. In other words, the IP address will be banned for this amount of time. If Quota.Window is set to 0 then the IP address’s quota will not be reset until it has not attempted to connect to the server for the Quota.Window period. The Quota.Stats value controls how often statistics are logged for quotas. Statistics are logged when the next non-banned IP address connects after the Quota.Stats period has passed. Setting Quota.Stats to 0 turns off logging. A quota log line looks like this: quota cache: 6 entries [3 evicted, 2 over quota, 1 recent] Some configuration examples. Given: Quota.Window: 10s Quota.Timeout: 30m Quota.Stats: 10m An IP address can connect to the server up to 4 times in 10 seconds. If it tries a fifth time within 10 seconds it will be banned for 30 minutes. Quota.Window: 10s Quota.Timeout: 0 Quota.Stats: 10m If an IP address connects more than 4 times in 10s it will be banned until it has made no connection attempts in the last 10 seconds. So if the IP address is banned, waits 5 seconds and tries to connect it will be banned for another 10 seconds. If the IP address persistently tries to connect it will be persistently banned. Connection quotas require that connection attempts be cached per IP address. However, if an IP address connects and then goes away the cached entry for the IP address will become stale after the Quota.Window period passes. After a period twice that of Quota.Window has passed the next non-banned IP address connecting will cause stale quota to be evicted from the cache. I think that this approach is simple, yet flexible enough for a lot of users. For the time being the default configuration disables quotas. To enable them edit the configuration file and set appropriate values for Quota.Window, Quota.Timeout and Quota.Stats. You will need to experiment to see what values work for you. I’m still not sure what values I should set as defaults, but I’d suggest using a Quota.Window of 10s and Quota.Timeout of 30m to start with. If you enable quotas I would appreciate knowing what values work for you. I’d be especially interested in hearing from you if you need to set the constant ringSize — in comms/ring.go — to something other than 4: diddymus@wolfmud.org I can now get back to improving the current player commands with the new search and matching code. But it's 4am. Guess I should at least try and get some sleep… -- Diddymus Up to Main Index Up to Journal for March, 2019