1# Understanding asockets
2
3The data structure of asocket, with their queue, amessage, and apackets are described
4in [internals.md](internals.md). But understanding asocket, how they are used, and how they are
5paired is non-trivial. This document hopefully explains how bytes flow through them.
6
7## Why ADB needs asocket
8
9The concept of `asocket` was created to achieve two things.
10
11- Carry multiple streams over a single pipe (originally that meant USB only).
12- Manage congestion (propagate back-pressure).
13
14With the introduction of TCP support, an abstraction layer (transport) was created
15but TCP multiplexing was not leveraged. Even when using TCP, a transport still uses `asocket`
16to multiplex streams.
17
18## Data direction and asocket peers
19
20- A asocket is uni-directional. It only allows data to be `enqueue`d.
21- A asocket is paired with a peer asocket which handles traffic in the opposite direction.
22
23## Types of asocket
24
25There are several types of `asocket`. Some are easy to understand because they
26extend `asocket`.
27
28- JdwpSocket
29- JdwpTracker
30- SinkSocket
31- SourceSocket
32
33However there are "undeclared" types, whose behavior differs only via the `asocket`
34function pointers.
35
36- Local Socket (LS)
37- Remote Socket (RS)
38- Smart Socket (SS)
39- Local Service Socket (LSS)
40
41
42## Local socket (abbreviated LS)
43
44A LS interfaces with a file descriptor to forward a stream of bytes
45without altering it (as opposed to a LSS).
46To perform its task, a LS leverages fdevent to request FDE_READ/FDE_WRITE notification.
47
48```
49                                  LOCAL SOCKET                                TRANSPORT
50                   ┌────────────────────────────────────────────────┐           ┌──┐
51     ┌──┐ write(3) │  ┌─────┐                                   enqueue()       │  │
52     │  │◄─────────┼──┤Queue├─────────────◄──────────────◄──────────┼─────────(A_WRTE)◄──
53     │fd│          │  └─────┘                                       │           │  │
54     │  ├──────────►─────────────────┐                              │           │  │
55     └──┘ read(3)  └─────────────────┼──────────────────────────────┘           │  │
56                                     ▼                                          └──┘
57                                 peer.enqueue()
58```
59
60A_WRTE apackets are forwarded directly to the LS by the transport. The transport
61is able to route the apacket to the local asocket by using `apacket.msg1` which
62points to the target local asocket `id`.
63
64### Write to fd and Back-pressure
65
66When a payload is enqueued, an LS tries to write as much as possible to its `fd`.
67After the write attempt, the LS stores in its queue what could not be written.
68Based on the volume of data in the queue, it sets `FDE_WRITE` and allows/forbids
69more data to come.
70
71- If there is data in the queue, the LS always requests `FDE_WRITE` events so it
72can write the outstanding data.
73- If there is less than `MAX_PAYLOAD` in the queue, LS calls ready on its peer (a RS),
74so an A_OKAY apacket is sent (which trigger another A_WRTE packet to be send).
75- If there is more than `MAX_PAYLOAD` in the queue, back-pressure is propagated by not
76calling `peer->ready`. This will trigger the other side to not send more A_WRTE until
77the volume of data in the queue has decreased.
78
79### Read from fd and Back-pressure
80
81When it is created, a LS requests FDE_READ from fdevent. When it triggers, it reads
82as much as possible from the `fd` (within MAX_PAYLOAD to make sure transport will take it).
83The data is then enqueueed on the peer.
84
85If `peer.enqueue` indicates that the peer cannot take more updates, the LS deletes
86the FDE_READ request.
87It is re-installed when A_OKAY is received by transport.
88
89## Remote socket (abbreviated RS)
90
91A RS handles outbound traffic and interfaces with a transport. It is simple
92compared to a LS since it merely translates function calls into transport packets.
93
94- enqueue -> A_WRTE
95- ready   -> A_OKAY
96- close   -> A_CLSE on RS and peer.
97- shutdown-> A_CLSE
98
99A RS is often paired with a LS  or a LSS.
100```
101                                    LOCAL SOCKET (THIS)                      TRANSPORT
102                   ┌────────────────────────────────────────────────┐           ┌──┐
103     ┌──┐ write(3) │  ┌─────┐                      enqueue()        │           │  │
104     │  │◄─────────┼──┤Queue├─────────────◄──────────────◄──────────┼─────────(A_WRTE)◄──
105     │fd│          │  └─────┘                                       │           │  │
106     │  ├──────────►─────────────────┐                              │        ─  │  │
107     └──┘ read(3)  └─────────────────┼──────────────────────────────┘           │  │
108                                     │                                          │  │
109                   ┌─────────────────▼─────────────────▲────────────┐           │  │
110                   │                 │                              │           │  │
111                   │                 │                              │           │  │
112                   │                 └─────────────────────►──────────────────(A_WRTE)───►
113                   │                enqueue()                       │           │  │
114                   └────────────────────────────────────────────────┘           └──┘
115                                    REMOTE SOCKET (PEER)
116```
117
118### RS creation
119
120A RS is always created by the transport layer (on A_OKAY or A_OPEN) and paired with a LS or LSS.
121
122- Upon A_OPEN: The transport creates a LSS to handle inbound traffic and peers it with
123a RS to handle outbound traffic.
124
125- Upon A_OKAY: When receiving this packet, the transport always checks if there is a
126LS with the id matching `msg1`. If there is and it does not have a peer yet, a RS is
127created, which completes a bi-directional chain.
128
129## Local Service Socket (LSS)
130
131A LSS is a wrapper around a `fd` (which is used to build a LS). The purpose is to process
132inbound and outbound traffic when it needs modification. e.g.: The "framebuffer" service
133involves invoking executable `screencap` and generating a header describing the payload
134before forwarding the color payload. This could not be done with a "simple" LS.
135
136The `fd` created by the LSS is often a pipe backed by a thread.
137
138## Smart Socket (abbreviated SS)
139
140These Smart sockets are only created on the host by adb server on accept(3) by the listener
141service. They interface with a TCP socket.
142
143Upon creation, a SS enqueue does not forward anything until the [smart protocol](services.md)
144has provided a target device and a service to invoke.
145
146When these two conditions are met, the SS selects a transport and A_OPEN the service
147on the device. It gives the TCP socket fd to a LS and creates a RS to build a data flow
148similar to what was described in the Local Socket section.
149
150## Examples of dataflow
151
152### Package Manager (Device service)
153
154Let's take the example of the command `adb install -S <SIZE> -`. There are several install
155strategies but for the sake of simplicity, let's focus on the one resulting in invoking
156`pm install -S <SIZE> -` on the device and then streaming the content of the APK.
157
158In the beginning there is only a listener service, waiting for `connect(3)` on the server.
159
160```
161      ADB Client                   ADB Server       TRANSPORT        ADBd
162┌──────────────────────┐      ┌─────────────────┐      │     ┌─────────────────┐
163│                      │      │                 │      │     │                 │
164│                      │      │                 │      │     │                 │
165│                      │      │                 │      │     │                 │
166│                     tcp * ───►* alistener     │      │     │                 │
167│                      │      │                 │      │     │                 │
168│                      │      │                 │      │     │                 │
169└──────────────────────┘      └─────────────────┘      │     └─────────────────┘
170
171┌──────────┐   ┌───────┐
172│    APK   │   │Console│
173└──────────┘   └───────┘
174```
175
176Upon `accept(3)`, the listener service creates a SS and gives it the socket `fd`.
177Then the client starts writing to the socket `|host:transport:XXXXXXX| |exec:pm pm install -S <SIZE> ->|`.
178
179```
180      ADB Client                   ADB Server       TRANSPORT        ADBd
181┌──────────────────────┐      ┌─────────────────┐      │     ┌─────────────────┐
182│                      │      │                 │      │     │                 │
183│                      │      │                 │      │     │                 │
184│                      │      │                 │      │     │                 │
185│                     tcp * ───►* SS            │      │     │                 │
186│                      │      │                 │      │     │                 │
187│                      │      │                 │      │     │                 │
188└──────────────────────┘      └─────────────────┘      │     └─────────────────┘
189
190┌──────────┐   ┌───────┐
191│    APK   │   │Console│
192└──────────┘   └───────┘
193```
194
195The SS buffers the smart protocol requests until it has everything it needs from
196the client.
197The first part, `host:transport:XXXXXXX` lets the SS know which transport to use (it
198contains the device identified `XXXXXXX`). The second part is the service to execute
199`exec:pm pm install -S <SIZE> -`.
200
201When it has both, the SS creates a LS to handle the TCP `fd`, and creates a RS to let
202the LS talk to the transport. The last thing the SS does before replacing itself with a
203LS (and giving it its socket fd) is sending an A_OPEN apacket.
204
205```
206      ADB Client                   ADB Server       TRANSPORT        ADBd
207┌──────────────────────┐      ┌─────────────────┐      │     ┌─────────────────┐
208│                      │      │                 │      │     │                 │
209│                      │      │                 │      │     │                 │
210│                      │      │                 │      │     │                 │
211│                  tcp * ◄───►* LS              │      │     │                 │
212│                      │      │  │              │      │     │                 │
213│                      │      │  └─────────► RS─┼──────┼─►───┼──────►A_OPEN    │
214└──────────────────────┘      └─────────────────┘      │     └─────────────────┘
215
216┌──────────┐   ┌───────┐
217│   APK    │   │Console│
218└──────────┘   └───────┘
219```
220So far only one side of the pipeline has been set up.
221
222Upon reception of the A_OPEN on the device side, `pm` is invoked via `fork/exec`.
223A socket pair end is given to a LS. A RS is also created to handle bytes generated by `pm`.
224Now we have a full pipeline able to handle bidirectional streams.
225
226```
227      ADB Client                   ADB Server       TRANSPORT        ADBd
228┌──────────────────────┐      ┌─────────────────┐      │     ┌─────────────────┐
229│                      │      │                 │      │     │                 │
230│                      │      │  ┌──────────────┼──◄───┼─────┼─RS ◄───┐        │
231│                      │      │  ▼              │      │     │        │        │
232│     ┌───────────►tcp * ◄───►* LS              │      │     │        │        │
233│     │             │  │      │  │              │      │     │        │        │
234│     │             │  │      │  └─────────► RS─┼──────┼─►───┼──────►LS        │
235└─────┼─────────────┼──┘      └─────────────────┘      │     └────────▲────────┘
236      │             │                                                 │
237┌─────┴────┐   ┌────▼──┐                                        ┌─────▼────┐
238│    APK   │   │Console│                                        │    PM    │
239└──────────┘   └───────┘                                        └──────────┘
240```
241
242At this point the client can `write(3)` the content of the apk to feed it to `pm`.
243It is also able to `read(3)` to show the output of `pm` in the console.
244
245