updated docs
This commit is contained in:
@@ -3,6 +3,23 @@ Under the Hood
|
||||
|
||||
*Note: It is not necessary for you to understand anything in this document, this is merely for those curious about the inner workings of the intercept, tap service, stack driver, and network stack.*
|
||||
|
||||
In this document we will walk you through what happens when your ZeroTier-enabled app does things like accepting a connection, receiving data, etc. But before we get into specific cases it's worth understanding the three major components which work together to produce this magic:
|
||||
|
||||
- Intercept Library: Mates to your app and allows us to re-implement classic network calls such as `socket()`, `bind()`, etc
|
||||
- Tap Service / Stack Driver: Mediates communication between the Intercept Library and the Network Stack.
|
||||
- Network Stack: Handles incoming ethernet frames and generates outgoing frames.
|
||||
|
||||
So now that we've clarified what these components do, here's the general idea:
|
||||
|
||||
You make a network call, the intercept routes that to our tap service which uses the user-space network stack to generate ethernet frames which is then sent out onto your ZeroTier virtual network.
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Creating a socket
|
||||
|
||||
Your app requests a socket:
|
||||
@@ -14,13 +31,16 @@ socket()
|
||||
Our library's implementation of `socket()` is executed instead of the kernel's. We automatically establish an `AF_UNIX` socket connection with the **tap service**. This is how your app will communicate with ZeroTier. An `RPC_SOCKET` message is sent to the **tap service**. The **tap service** receives the `RPC_SOCKET` message and requests the allocation of a new `Connection` object from the **stack driver** which represents the new socket. The **tap service** then repurposes the socket used for the RPC message and returns its file descriptor to your app for it to use as the new socket.
|
||||
|
||||
From your app's perspective nothing out of the ordinary has happened. It called `socket()`, and got a file descriptor back.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Establishing a connection
|
||||
|
||||
You app connects to a remote host:
|
||||
@@ -36,14 +56,15 @@ phyOnUnixData()
|
||||
pico_handleConnect()
|
||||
pico_socket_connect()
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Accepting a connection
|
||||
|
||||
Your app places a socket into a listen state:
|
||||
@@ -62,15 +83,15 @@ accept()
|
||||
The **network stack** raises a `PICO_SOCK_EV_CONN` event which calls `pico_cb_socket_activity()`. From here we request a new `pico_socket` be created to represent the new connection. This is done via `pico_socket_accept()`. Once we have a valid `pico_socket`, we create an `AF_UNIX` socket pair. We associate one end with the newly-created `pico_socket` via a `Connection` object. And we send the other end of the socket pair to the app.
|
||||
|
||||
Our library's implementation of `accept()` will read and return the new file descriptor representing one end of the socket pair. From your app's prespective this is a normal file descriptor.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Receiving data
|
||||
|
||||
The **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 to re-encapsulate the ethernet frame and copy it onto the guarded `pico_frame_rxbuf`. This buffer is guarded because it is accessed via the **tap service** thread and the **network stack** thread.
|
||||
@@ -108,16 +129,14 @@ After this point it's up to your application to read the data via a conventional
|
||||
```
|
||||
read()
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Sending data
|
||||
|
||||
Your app performs a `write()`, `send()`, or `sendto()` call.
|
||||
@@ -145,4 +164,6 @@ After some time, the **network stack** will emit an ethernet frame via `pico_eth
|
||||
```
|
||||
pico_eth_send()
|
||||
tap->_handler()
|
||||
```
|
||||
```
|
||||
***
|
||||
|
||||
|
||||
Reference in New Issue
Block a user