instead of sharing the wifi buffer loopback has its own buffer.
this eliminates a race condition that happens whenever an Rx
happens to happen on the wifi interface while there's loopback
traffic in progress.
also, i see a lot of opportunities to optimize the net stack now
that i have tweaked this path; it might be interesting to break
the receive interrupt out directly into the COM crate instead
of passing it through LLIO then NET then COM and having COM
drain the RX buffer immediately into a local "infinite" sized
queue.
The llio->net->com loop exists because the interrupt handler
for all the i/o is shared within one hardware block, but maybe
i can create an additional interrupt responder for the com
interface just to optimize things a bit in a future SOC update.
Alternatively, I could move all the interrupts into COM and not
have them resident in LLIO. This would optimize for COM latency
at the expence of I2C latency, but that's probably OK because
I2C is much less latency sensitive (i2c and com interrupt, as
mentioned above, share the same hardware block for external
pin-based interrupts).
- Peek now has a handler for reads that can't be met immediately
- add a count to the number of times a close socket has been polled,
if it exceeds a threshold close the socket anyways. This is a compromise
between trying to figure out how to implement a fully non-blocking TcpClose,
and having an interlocked one that cleans up state but ends up blocking
the case where you have, in the same thread, a sender and receiver
(which is ironically somehow legal and does not cause deadlock,
because the TcpClose in Unix is not blocking on internal state
being cleared up).
0 is a "valid" port and it means OS please give me a port.
This implements a method where a random port is chosen until
you find one that's not occupied.
If a Stream is opened and a process isn't constantly polling it,
it'll never close if the remote side goes away -- you'll just
end up hanging in a FIN-WAIT-2 condition.
Add some logic to detect this and close out streams automatically
where the remote has hung up.
I'm not actually sure this is what you're *supposed* to do, but,
lacking a formal specification, all I can do is try to get
this thing to pass the test bench. And pass it does.
TcpClose should not immediately remove the socket. It
has to wait until the FIN comes. Add a fin waiter state.
Also rewrite to use "retain". Woo. I'm starting to get
the hang of Rust closures. Only took a couple years.
RxWait gets stuck in CLOSE_WAIT state. It's a state where
you "could" transmit, but you can't receive anymore.
In this case respond with a 0-length receive? That seems
to be what leads to the right behavior. I would have thought
you'd want to respond with a timeout error but that doesn't
match what's in the test bench.
- add 127.0.0.1 to the list of IPs listened to by smoltcp
- add some static Atomic types to store the IP and MAC address
so we can process packets in other areas to detect the loopback
state
- add a routine to extract the loopback packets when they happen
- bunch of debug visibility tweaks
loopback packets are intercepted on the way to the COM and
re-injected directly into the Rx queue, along with a message
sent back to the main loop to pump the Rx buffer to extract the
loopback packet.
this patch moves us off the branch we had to hop on for cipher
API compatibility to the one that's officially published by
RustCrypto. This closes#168.
turns out, they're pretty useless. I mean, for debugging actual
running code. it tells us basically what we know already which is
99.99% of the time is spent waiting on inter-thread messaging
in hosted mode.
noticed it's hitting exactly when NTP updates because it also
happens on a 24-hour schedule, staggering a bit to try and keep
everything from hitting exactly at the same time once a day.
The crate we originally grabbed for AES-KWP seems to be non-compliant
(or I'm an idiot and I can't figure out how to call it in a way
that is compliant).
See https://github.com/jedisct1/rust-aes-keywrap/issues/9
Turns out that `aes_kw` *is* compliant, but unfortunately, it didn't
exist back when the PDDB was being written. The PDDB started in October
2021, and `aes_kw` was pushed in Jan 2022. *just* barely missed it.
Anyways, caught this error while trying to implement some CI for
backups. Hurray for testing!
This patch removes the encryption path using the incorrect version
of the algorithm, but leaves the decryption path in place. The
system will try to decrypt initially with the correct version,
but if that fails, it will fall back and try the incorrect version.
If that succeeds, it returns an error code with the correct key and
an updated wrapped key, which the caller can store so that future
calls do not fail. Thus, we have a seamless migration from the
incorrect version to the correct version.
Have verified that the aes_kw version *does* work with the CI
script, insofar as it has been written (we just got to that point
and got stuck). So, full speed ahead. Users shouldn't notice this
change.
Also, fwiw, I did take a look at the "incorrect" implementation,
and it doesn't look obviously insecure. Printing out the various
rounds of the wrapping function looks like the first couple rounds
match, but it diverges somewhere probably due to an off-by-one
in a counter or something like that. I didn't chase it out -- just
wanted to make sure that nothing looked like a huge data compromise.
Good news is this comes right on the heels of v0.9.9 release, so
this will be pushed as a hotfix right away.
this facility is necessary in case a worker accidentally picks
the wrong setting, disabling the feature for the device. When
the factory test completes, a call is made to reset the parameter.
This was a slightly complicated affair because the the don't ask
flag is contained within the rootkeys enclave itself, and we can't
just give access to rootkeys willy-nilly. So the flag is passed
through the PDDB and then to the rootkeys enclave. It's not harmful
to have it reset by an unauthorized actor; the pop-up will not
happen if passwords are, in fact, already set.