diff options
Diffstat (limited to 'fw/doc/todo.md')
| -rw-r--r-- | fw/doc/todo.md | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/fw/doc/todo.md b/fw/doc/todo.md new file mode 100644 index 0000000..97d1d71 --- /dev/null +++ b/fw/doc/todo.md @@ -0,0 +1,103 @@ +# fw: open items + +Ranked. Item 1 is the only thing between this and running it on a +machine you care about. + +## 1. A dead fw takes the network with it + +**Severity: blocks use.** + +Taking a card is destructive and is not undone. The `pkt` interface that +replaces it is `unbindonclose`, so when `fw` stops the interface goes and +the address goes with it. The machine is left with a card bound to +nothing and no network. + +Worse, `fw` cannot restart unaided: the address it would read off the +card is the address that just vanished. So it exits, and a supervisor +with `restart=always` would spin. + +`fw` tries to put the card back as it exits (`putback`, via `atexit` and +`threadnotify`). That covers an orderly stop. **It did not fire on a kill +in testing** and I did not chase it further — a cleanup that works +sometimes is worse than none, because you would trust it. + +The fix is probably not more note handling. Whatever restarts `fw` has to +be able to configure the card first, which means the address has to +survive somewhere `fw` does not own. That is a supervisor's job. + +This is also what blocks `svc` supervision (item 3), so one fix, two +payoffs. + +## 2. Broadcast handling is written but unwitnessed + +Broadcast and multicast are addressed directly rather than resolved: +`255.255.255.255` and the subnet broadcast to `ff:ff:ff:ff:ff:ff`, +`224/4` to `01:00:5e:...`, `ff00::/8` to `33:33:...`. Without this a +DHCP renewal would be ARPed for the gateway and unicast there, and the +lease would quietly never renew. + +The mapping is the standard one and normal traffic is unaffected, but +**I never managed to get a broadcast to cross `fw` to confirm it.** +Reviewed, not observed. + +Related and unfixed: `fw` reads the address once at startup, so a lease +that *changes* the address goes unnoticed until restart. + +## 3. fw daemonizes, so svc cannot supervise it + +The process you exec returns immediately and leaves the server behind. +`svc` would see an instant exit and, with `restart=always`, spin. + +Needs a foreground mode where the process started is the process that +stays. `svc`'s `ready=srv:name` fits: `fw -s fw.ether0` already posts to +`/srv`. + +`fwstart` is the wrong shape and should probably go. `svc` already does +dependency ordering and per-service supervision; `fwstart` re-implements +the loop in rc and then exits, so `svc` would be supervising a process +that has already gone. One service per card is the right shape. + +## 4. One card per fw, and rules cannot name a card + +Two cards means two `fw`s with two rule files. Tested and it works, but +a rule cannot say `ifc=ether0`, so one file cannot express different +policy for different cards. Wants repeatable `-e` and an `ifc=` +attribute, and those go together. + +## 5. Tflush is not implemented + +A request `fw` is blocked on cannot be abandoned, so killing a program +that is waiting for an inbound connection does not reach `fw`. Only +affects the namespace mode; nothing in packet mode blocks indefinitely. + +Doable: record the worker's pid against the Req, post an `interrupt` +note on flush, catch it with `threadnotify` so the syscall returns +`interrupted` rather than killing the proc. Maybe 80 lines. There is a +race that cannot be fully closed — between the syscall returning and the +handler clearing its entry, a note may already be in flight and land on +a worker that has moved on, failing an unrelated request. Rare, +unreproducible, and the reason to do it deliberately. + +## 6. Positional delete renumbers + +`delete n` counts lines of `rules`, so numbers shift after each delete +and `delete 3` twice removes two different rules. Inherent to positional +deletion — iptables has it too — but it should be said out loud. + +## 7. Untested at the edges + +- The gateway has only been tested between two synthetic stacks on one + machine. `run.sh` has `-gw`/`-lan` for a two-VM test; the client VM + was never built. +- No IPv6 traffic has been pushed through any mode. The code paths + exist and parse v6, but nothing has exercised them. +- No test with a real second NIC carrying real traffic. + +## Deliberately not doing + +**NAT.** See design.md. A 9front client imports `/net`; anything else +behind an IPv4 gateway with one address is the only case that needs it, +and that case can wait for someone who actually has it. + +**Rate limiting, fragment logic, ICMP type matching, deep IPv6.** Scope, +not difficulty. The useful firewall is the one that ships. |
