summaryrefslogtreecommitdiff
path: root/fw/doc/todo.md
diff options
context:
space:
mode:
Diffstat (limited to 'fw/doc/todo.md')
-rw-r--r--fw/doc/todo.md103
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.