connection-manager.md (3355B)
1 # connection manager 2 3 The connection manager is the first piece of the group chat features. This class manages connections to peers and offer to the user multiplexed sockets to devices they want to connect. For example, if Alice wants to be connected to one of Bob's device to transfer 2 files, she will ask the ConnectionManager to open 2 channels (one per file) to Bob. This will give: 4 5 ```cpp 6 aliceAccount->connectionManager().connectDevice(bobDeviceId, "file://file1", 7 [](std::shared_ptr<ChannelSocket> socket) { 8 if (socket) { 9 // transfer first file 10 } 11 }); 12 13 aliceAccount->connectionManager().connectDevice(bobDeviceId, "file://file2", 14 [](std::shared_ptr<ChannelSocket> socket) { 15 if (socket) { 16 // transfer second file 17 } 18 }); 19 ``` 20 21 Behind that, the ConnectionManager will first connect to Bob's device via the DHT (via ICE) and setup a TLS Socket. Then, it will ask for a channel, and when the channel is ready, inform Alice via a callback. For the second file, it will use the first socket and will just open a new channel (only needs 2 TLS packet, so it's fast) 22 23 ## DHT side 24 25 It's the same as [calls](https://git.jami.net/savoirfairelinux/ring-project/wikis/technical/2.4.%20Let's%20do%20a%20call), see **Exchange ICE candidates**, **ICE negotiation**, **Encrypt the control socket** but only in TCP. 26 27 However, when a side receives a new ICE request, the callback set by ` void onICERequest(onICERequestCallback&& cb);` is triggered. 28 29 ## Negotiating a new channel 30 31 A channel is defined by an id (unique) and a uri (not unique). For example (1, 'git://*') 32 33 When ready, the ConnectionManager considers that the channel 0 exists. This channel is called the *CONTROL* channel and is used to ask for new channels. 34 35 The protocol used is pretty simple and looks like the RTP protocol: 36 37 1. 16 bits are used to store the length of the body. 38 2. 16 bits for the channel id (destination) 39 3. body 40 41 So all packets have a 32 bits len header. 42 43 To ask for a new channel, the ConnectionManager will send a `ChannelRequest` object (msgpack is used to serialize the struct) in the channel 0 to send the id and the name of the new channel to the peer (with `isAnswer = false`). The peer will call the callback givenn with `void onChannelRequest(ChannelRequestCallBack&& cb);` and will refuse or accept the request. If accepted, the peer will answer with a ChannelRequest with the same data (and ̀`isAnswer = true`) and then both peers callbacks will be triggered to inform that the ChannelSock is usable. 44 45 ## Closing a channel 46 47 A *EOF* is transmitted for a channel if the length of the content is 0. 48 49 ## Structure of the connectionManager 50 51 ### Ownership 52 53 1. A JamiAccount owns the ConnectionManager and have access to the ChannelSocket objects (shared_ptr owned with the MultiplexedSocket. 54 2. The ConnectionManager owns MultiplexedSockets and ICE objects 55 3. MultiplexedSockets owns the TLS transport and the ChannelSocket objects 56 4. ChannelSocket owns the data buffers 57 58 ### Roles 59 60 1. ConnectionManager is used to manage connections to peers. 61 2. MultiplexedSockets are used to send data over the TLSSocket, read the incoming packets and manage channels. 62 3. ChannelSockets are used by the client to interact with the other peer. 63 64 ## Usage 65 66 Scenarios are described in the corresponding unit tests (`test/unitTest/connectionManager/connectionManager.cpp`)