From 894fa1e77ca23a8ce99098ed8f2198e9e9a35a0c Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Tue, 6 Dec 2016 13:44:12 -0800 Subject: [PATCH] Added rx/tx doc --- docs/rxtx.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 docs/rxtx.md diff --git a/docs/rxtx.md b/docs/rxtx.md new file mode 100644 index 0000000..6a786d7 --- /dev/null +++ b/docs/rxtx.md @@ -0,0 +1,71 @@ +picoTCP Driver + + +### How data is RX'd and TX'd by an application using the SDK. Note, all of this complexity is hidden from you and your app and you don't really even need to know. But just in case you're curious, here it is: + +## Receiving data + +--------- +RX Packet +--------- + +The ZeroTier SDK tap service monitors incoming packets, when one destined for us is detected it notifies the stack driver via `put()`. Then `pico_rx()` is called, its job is re-encapsulate the ethernet frame and copy it onto the RX I/O buffer. This buffer is locked since it is accessed via the tap service thread and the network stack thread. + +``` +SERVICE_THREAD +wire + put() + pico_rx() ---> +``` + +Periodically the stack thread will call `pico_eth_poll()`, this is responsible for reading the frames from the aformentioned RX I/O frame buffer and feeding it into the stack via `pico_stack_recv()`. + +``` +STACK_THREAD +pico_eth_poll() + ---> pico_stack_recv +``` + +After some time has passed and the stack has processed the incoming frames a `PICO_SOCK_EV_RD` event will be triggered which calls `pico_cb_socket_activity()`, and ultimately `pico_cb_tcp_read()`. This is where we copy the incoming data from the `pico_socket` to the `Connection`'s `rxbuf`. We then notify the ZeroTier tap service that the `PhySocket` (a wrapped file descriptor with one end visible to the application) associated with with this `Connection` has data in the `rxbuf` that needs to be written to it. + +``` +STACK_THREAD +pico_cb_socket_activity() + pico_cb_tcp_read() ---> conn->rxbuf + setNotifyWritable=TRUE +``` + +After some (more) time, the ZeroTier tap service thread will call `pico_handleRead()`, this will copy the data from the `rxbuf` to the `AF_UNIX` socket which links the service and your application. After this point it's up to you application to read the data via a conventional `read()`, `recv()`, or `recvfrom()` call. + +``` +SERVICE_THREAD +pico_handleRead() + streamSend(): conn->rxbuf --- conn->sock +``` + +... + + +APP_THREAD + read() + + +## Sending data +--------- +TX Packet +--------- + +APP_THREAD + write(): ---> fd + +SERVICE_THREAD + I/O loop PhySocket + phyOnUnixData() + handleWrite() + pico_socket_write(): conn->txbuf ---> conn->picosock + +STACK_THREAD + pico_cb_socket_activity + pico_cb_tcp_write() + pico_socket_write() +