Skarm
A swarm (group chat) is a set of participants capable of resilient, decentralized communication. For example, if two participants lose connectivity with the rest of the group (e.g., during an Internet outage) but can still reach each other over a LAN or subnetwork, they can exchange messages locally and then synchronize with the rest of the group once connectivity is restored.
A swarm is defined by the following properties:
Ability to split and merge based on network connectivity.
History synchronization. Every participant must be able to send a message to the entire group.
Ingen central myndighet, ingen server.
Non-repudiation. Devices must be able to verify past messages’ validity and to replay the entire history.
Perfect Forward Secrecy (PFS) is provided on the transport channels. Storage is handled by each device.
Huvudideen är att få ett synkroniserat Merkle-träd med deltagarna.
We identified four modes for swarms that we want to implement:
ONE_TO_ONE: A private conversation between two endpoints—either between two users or with yourself.
ADMIN_INVITES_ONLY: A swarm in which only the administrator can invite members (for example, a teacher-managed classroom).
INVITES_ONLY: A closed swarm that admits members strictly by invitation; no one may join without explicit approval.
PUBLIC: A public swarm that anyone can join without prior invitation (For example a forum).
Scenarier
Skapa en släkta
Bob vill skapa en ny svärm
Bob creates a local Git repository.
Han skapar sedan ett initialt undertecknat åtagande med följande:
Hans offentliga nyckel i
/admins
Hans enhetsertifikat i ̀ /apparater `
Hans CRL i ̀ /crls`
Hashet i det första inlägget blir konversationsidenten.
Bob announces to his other devices that he created a new conversation. This is done via an invite to join the group sent through the DHT to other devices linked to that account.
Att lägga till någon
Bob adds Alice
Bob adds Alice to the repo:
Lägger till den inbjudna URI i
/invited
Lägger till CRL i
/crls
Bob sends a request on the DHT.
Att få en inbjudan
Alice gets the invite to join the previously created swarm
Alice accepts the invite (if she declines, nothing happens; she will remain in the ”invited” list, and will never receive any messages)
A peer-to-peer connection is established between Alice and Bob.
Alice pulls the Git repository from Bob. WARNING this means that messages require a connection, not from the DHT as it is today.
Alice validates the commits from Bob.
To validate that Alice is a member, she removes the invite from
/invited
directory, then adds her certificate to the/members
directoryOnce all commits are validated and syncronized to her device, Alice discovers other members of the group. with these peers, she will then construct the DRT with Bob as a bootstrap.
Skicka ett meddelande
Alice sends a message to Bob
Alice creates a commit message. She constructs a JSON payload containing the MIME type and message body. For example:
{
"type": "text/plain",
"body": "hello"
}
Alice ensure her device credentials are present. If Alice’s device certificate or its associated CRL isn’t already stored in the repository, she adds them so that other participants can verify the commit.
Alice commits to the repository (Because Jami relies primarily on commit-message metadata rather than file contents, merge conflicts are rare; the only potential conflicts would involve CRLs or certificates, which are versioned in a dedicated location).
Alice announces the commit via the DRT with a service message and pings the DHT for mobile devices (they must receive a push notification).
Observera
To notify other devices, the sender transmits a SIP message with type: application/im-gitmessage-id
.
The JSON payload includes the deviceId (the sender’s), the conversationId and the reference (hash) of the new commit.
Att få ett meddelande
Bob receives a message from Alice
Bob performs a Git pull on Alice’s repository.
All incoming commits MUST be verified by a hook.
If all commits are valid, commits are stored and displayed.Bob then announces the message via the DRT for other devices.
If any commit is invalid, pull is aborted. Alice must restore her repository to a correct state before retrying.
Validering av ett åtagande
För att undvika att användare driver några oönskade commits (med konflikter, falska meddelanden, etc.), är det så här varje commit (från den äldsta till den nyaste) MÅS vara validerad innan en fjärrgrenas sammanslagning:
Observera
If the validation fails, the fetch is ignored and we do not merge the branch (and remove the data), and the user should be notified.
If a fetch is too big, it’s not merged.
For each incoming commit, ensure that the sending device is currently authorized and that the issuer’s certificate exists under /members or /admins, and the device’s certificate under /devices.
Then handle one of three cases, based on the commit’s parent count:
Merge Commit (2 parents). No further validation is required, merges are always accepted.
Initial Commit (0 parents). Validate that this is the very first repository snapshot:
Admin certificate is added.
Device certificate is added.
CRLs (Certificate Revocation Lists) are added.
No other files are present.
Ordinary Commit (1 parent). The commit message must be JSON with a top‑level
type
field. Handle eachtype
as follows:If
text
(or any non–file‑modifying MIME type)Signature is valid against the author’s certificate in the repo.
No unexpected files are added or removed.
If
vote
voteType
is one of the supported values (e.g. ”ban”, ”unban”).The vote matches the signing user.
The signer is an admin, their device is present, and not themselves banned.
No unexpected files are added or removed.
If
member
If
adds
Properly signed by the inviter.
New member’s URI appears under
/invited
.No unexpected files are added or removed.
If ONE_TO_ONE, ensure exactly one admin and one member.
If ADMIN_INVITES_ONLY, the inviter must be an admin.
If
joins
Properly signed by the joining device.
Device certificate added under
/devices
.Corresponding invite removed from
/invited
and certificate added to/members
.No unexpected files are added or removed.
If
banned
Vote is valid per the
vote
rules above.Ban is issued by an admin.
Target’s certificate moved to /banned.
Only files related to the ban vote are removed.
No unexpected files are added or removed.
Fallback. If the commit’s type or structure is unrecognized, reject it and notify the peer (or user) that they may be running an outdated version or attempting unauthorized changes.
Banning av en enhet
Viktigt
Jami source code tends to use the terms (un)ban, while the user interface uses the terms (un)block.
Alice, Bob, Carla, Denys are in a swarm. Alice issues a ban against Denys.
In a fully peer‑to‑peer system with no central authority, this simple action exposes three core challenges:
Untrusted Timestamps: Commit timestamps cannot be relied upon for ordering ban events, as any device can forge or replay commits with arbitrary dates.
Conflicting bans: In cases where multiple admin devices exist, network partitions can result in conflicting ban decisions. For instance, if Alice can communicate with Bob but not with Denys and Carla, while Carla can communicate with Denys, conflicting bans may occur. If Denys bans Alice while Alice bans Denys, the group’s state becomes unclear when all members eventually reconnect and merge their conversation histories.
Compromised or expired devices: Devices can be compromised, stolen, or have their certificates expire. The system must allow banning such devices and ensure they cannot manipulate their certificate or commit timestamps to send unauthorized messages or falsify their expiration status.
Liknande system (med distribuerade gruppsystem) är inte så många, men dessa är några exempel:
[mpOTR definierar inte hur man förbjuder någon]
Signal, utan någon central server för gruppchat (EDIT: de har nyligen ändrat den punkten), ger inte möjligheten att förbjuda någon från en grupp.
This voting system needs a human action to ban someone or must be based on the CRLs info from the repository (because we can not trust external CRLs).
Ta bort en enhet från ett samtal
Det här är den enda delen som måste ha en konsensus för att undvika att samtalet splittras, som om två medlemmar sparkar varandra ur samtalet, vad kommer att se den tredje?
Detta behövs för att upptäcka återkallade enheter, eller helt enkelt för att undvika att få oönskade personer närvarande i ett offentligt rum.
Alice tar bort Bob.
Viktigt
Alice MUST be an admin to vote.
Först röstar hon för att förbjuda Bob. För att göra det skapar hon filen i /votes/ban/members/uri_bob/uri_alice (medlemmar kan ersättas med enheter för en enhet, eller inbjudas till inbjudningar eller admins för admins) och förbinder
Det betyder att >50% av administratörerna håller med om att förbjuda Bob (om hon är ensam är det säkert mer än 50%).
Om röstningen är löst kan filer i /votes/ban tas bort, alla filer för Bob i /members, /admins, /invited, /CRLs, /devices kan tas bort (eller bara i /devices om det är en enhet som är förbjuden) och Bobs certifikat kan placeras i /banned/members/bob_uri.crt (eller /banned/devices/uri.crt om en enhet är förbjuden) och commits till repo
Sedan informerar Alice andra användare (utanför Bob)
Alice (admin) re-adds Bob (banned member)
If she votes for unbanning Bob. To do that, she creates the file in /votes/unban/members/uri_bob/uri_alice (members can be replaced by devices for a device, or invited for invites or admins for admins) and commits
Det betyder att >50% av administratörerna håller med om att förbjuda Bob (om hon är ensam är det säkert mer än 50%).
Om röstningen är löst kan filer i /votes/unban tas bort, alla filer för Bob i /members, /admins, /invited, /CRLs, kan läggas till (eller bara i /devices om det är en enhet som är obannat) och commits till repo
Ta bort ett samtal
Spara i convInfos bort = tid:: nu() (som bortKontakt sparar i kontakter) att konversationen tas bort och synkroniseras med andra användares enheter
Om en ny kommitté mottas för det här samtalet ignoreras den
Om Jami startar och repo är fortfarande närvarande, meddelas inte konversationen till kunderna.
Two cases: a. If no other member in the conversation we can immediately remove the repository b. If still other members, commit that we leave the conversation, and now wait that at least another device sync this message. This avoids the fact that other members will still detect the user as a valid member and still sends new message notifications.
När vi är säkra på att någon är synkroniserad, ta bort bort bort bort = time::now() och synkronisera med andra användares enheter
Alla enheter som ägs av användaren kan nu radera arkivet och relaterade filer
Hur man anger ett läge
Moden kan inte ändras genom tiden. Eller det är en annan konversation. Så, dessa data lagras i det ursprungliga commit meddelandet.
{
"type": "initial",
"mode": 0,
}
För närvarande accepterar ”mode” värden 0 (ONE_TO_ONE), 1 (ADMIN_INVITES_ONLY), 2 (INVITES_ONLY), 3 (PUBLIC)
Processes for 1:1 chats
The goal here is to keep the old API (addContact/removeContact, sendTrustRequest/acceptTrustRequest/discardTrustRequest) to create a chat with a peer and its contact. This still implies some changes that we cannot ignore:
Processen är fortfarande densamma, ett konto kan lägga till en kontakt via addContact, och sedan skicka en TrustRequest via DHT. Men två förändringar är nödvändiga:
TrustRequest innehåller en ”conversationId” för att informera peer vilken konversation att klona när de accepterar begäran
TrustRequest återförsökas när kontakten återvänder online. Det är inte fallet idag (som vi inte vill generera en ny TrustRequest om kamratet avvisar den första). Så om ett konto får en förtroendeförfrågan, kommer det automatiskt att ignoreras om begäran med en relaterad konversation avvisas (som convRequests synkroniseras)
När en kontakt accepterar begäran är en synkroniseringsperiod nödvändig, eftersom kontakten nu behöver klona samtalet.
removeContact() kommer att ta bort kontakten och relaterade 1:1-samtal (med samma process som ”Ta bort en konversation”).
Svårt scenarie
Det finns vissa fall där två samtal kan skapas.
Alice adds Bob.
Bob accepts.
Alice removes Bob.
Alice adds Bob.
eller
Alice adds Bob and Bob adds Alice at the same time, but both are not connected together.
In this case, two conversations are generated. We don’t want to remove messages from users or choose one conversation here. So, sometimes two conversations between the same members will be shown. It will generate some bugs during the transition time (as we don’t want to break API, the inferred conversation will be one of the two shown conversations, but for now it’s ”ok-ish”, will be fixed when clients will fully handle conversationId for all APIs (calls, file transfer, etc)).
Viktigt
After accepting a conversation’s request, there is a time the daemon needs to retrieve the distant repository. During this time, clients MUST show a syncing view to give informations to the user. While syncing:
ConfigurationManager::getConversations() will return the conversation’s id even while syncing.
ConfigurationManager::conversationInfos() kommer att returnera {{”synkronisering”: ”true”}} om synkronisering.
ConfigurationManager::getConversationMembers() will return a map of two URIs (the current account and the peer who sent the request).
Samtal kräver specifikation
Förfrågningar om samtal visas med en Map<String, String> med följande tangenter:
id: the conversation ID
from: URI of the sender
mottagit: tidsstämpel
Titel: (valfri) namn för samtalet
Beskrivning: (valfri)
avatar: (optional) the profile picture
Sammanställning av samtalens profil
För att kunna identifieras behöver en konversation i allmänhet metadata, som en titel (t.ex. Jami), en beskrivning (t.ex. några länkar, vad projektet är, etc.) och en bild (projektets logo).
Lagring i lagret
Profilen för konversationen lagras i en klassisk vCard-fil vid roten (/profile.vcf
) som:
BEGIN:VCARD
VERSION:2.1
FN:TITLE
DESCRIPTION:DESC
END:VCARD
Synkronisering
To update the vCard, a user with enough permissions (by default: =ADMIN) needs to edit /profile.vcf
and will commit the file with the mimetype application/update-profile
.
The new message is sent via the same mechanism and all peers will receive the MessageReceived signal from the daemon.
The branch is dropped if the commit contains other files or too big or if done by a non-authorized member (by default: <ADMIN).
Sista visningen
I de synkroniserade data skickar varje enhet till andra enheter konversationstillståndet. I detta tillstånd skickas den sista som visas.
Det finns fem scenarier som stöds:
Om den sista visningen som skickats av andra enheter är samma som den nuvarande, är det inget att göra.
Om det inte finns något sista meddelande för den aktuella enheten, används det fjärrbildade meddelandet.
Om det fjärrkontroll som visas senast inte finns i repo, betyder det att commit kommer att hämtas senare, så cache resultatet
Om fjärrkontrollen redan hämtas, kontrollerar vi att den sista lokal som visas är tidigare i historien för att ersätta den
Slutligen, om ett meddelande meddelas från samma författare, betyder det att vi måste uppdatera det senaste som visas.
Inställningar
Varje samtal har bifogade preferenser som inställts av användaren. Dessa preferenser synkroniseras över användarens enheter. Detta kan vara färgen på samtalet, om användaren vill ignorera meddelanden, filöverföringsstorleksgräns, etc. För tillfället är de erkända nycklarna:
”color” - the color of the conversation (#RRGGBB format)
”ignoreNotifications” - att ignorera meddelanden om nya meddelanden i denna konversation
”symbol” - för att definiera en standard emoji.
Dessa preferenser lagras i ett paket MapStringString, lagras i accountDir/conversation_data/conversationId/preferences
och skickas endast över enheter av samma användare via SyncMsg.
API för att interagera med preferenserna är:
// Update preferences
void setConversationPreferences(const std::string& accountId,
const std::string& conversationId,
const std::map<std::string, std::string>& prefs);
// Retrieve preferences
std::map<std::string, std::string> getConversationPreferences(const std::string& accountId,
const std::string& conversationId);
// Emitted when preferences are updated (via setConversationPreferences or by syncing with other devices)
struct ConversationPreferencesUpdated
{
constexpr static const char* name = "ConversationPreferencesUpdated";
using cb_type = void(const std::string& /*accountId*/,
const std::string& /*conversationId*/,
std::map<std::string, std::string> /*preferences*/);
};
Förvaltning av sammanslagningskonflikter
Eftersom två administratörer kan ändra beskrivningen samtidigt kan en fusionkonflikt uppstå på profile.vcf
. I detta fall väljs commit med högre hash (t.ex. ffffff > 000000).
API:er
Användaren fick 2 metoder för att få och ställa in konversationsmetadata:
<method name="updateConversationInfos" tp:name-for-bindings="updateConversationInfos">
<tp:added version="10.0.0"/>
<tp:docstring>
Update conversation's infos (supported keys: title, description, avatar)
</tp:docstring>
<arg type="s" name="accountId" direction="in"/>
<arg type="s" name="conversationId" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="VectorMapStringString"/>
<arg type="a{ss}" name="infos" direction="in"/>
</method>
<method name="conversationInfos" tp:name-for-bindings="conversationInfos">
<tp:added version="10.0.0"/>
<tp:docstring>
Get conversation's infos (mode, title, description, avatar)
</tp:docstring>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
<arg type="a{ss}" name="infos" direction="out"/>
<arg type="s" name="accountId" direction="in"/>
<arg type="s" name="conversationId" direction="in"/>
</method>
där infos
är en map<str, str>
med följande nycklar:
Modus: LÄS-ONLY
Titel
Beskrivning
avatar: the profile picture
Återimport av ett konto (länk/export)
Arkivet MÅSTA innehålla conversationId för att kunna hämta samtal på nya commits efter en återimport (eftersom det inte finns någon inbjudan vid denna punkt).
Samtalet är där, i det här fallet kan demonen klona om samtalet.
KonversationenID saknas, så daemon ber (via ett meddelande
{{"applikation/invitera", conversationId}}
) om en ny inbjudan som användaren behöver (åter) acceptera
Viktigt
A conversation can only be retrieved if a contact or another device is there, else it will be lost. There is no magic.
Användda protokoll
Git
Varför detta val
Each conversation will be a Git repository. This choice is motivated by:
Merkle Tree är den perfekta strukturen för att göra det och kan linjeras genom att slå ihop grenar. Dessutom, eftersom det används massivt av Git, är det lätt att synkronisera mellan enheter.
Det är distribuerat av naturen, massivt använt, mycket backend och pluggable.
Kan verifiera åtaganden via hakar och massivt använda kryptotjänster
Kan lagras i en databas om det behövs
Konflikter undvikes genom att använda commit-meddelanden, inte filer.
Vad vi måste bekräfta
Performance?
git.lock
kan vara lågHäklar i libgit2
Många dragningar samtidigt?
Gränser
För att ta bort ett samtal måste enheten lämna samtalet och skapa ett nytt.
Men icke-permanenta meddelanden (som meddelanden som endast kan läsas under några minuter) kan skickas via ett speciellt meddelande via DRT (som typ- eller läsmeddelanden).
Struktur
/
- invited
- admins (public keys)
- members (public keys)
- devices (certificates of authors to verify commits)
- banned
- devices
- invited
- admins
- members
- votes
- ban
- members
- uri
- uriAdmin
- devices
- uri
- uriAdmin
- unban
- members
- uri
- uriAdmin
- CRLs
Fileröverföring
This new system overhauls file sharing: the entire history is now kept in sync, so any device in the conversation can instantly access past files. Rather than forcing the sender to push files directly—an approach that was fragile in the face of connection drops and often required manual retries—devices simply download files when they need them. Moreover, once one device has downloaded a file, it can act as a host for others, ensuring files remain available even if the original sender goes offline.
Protokoll
Sändaren lägger till ett nytt commit i samtalet med följande format:
value["tid"] = "RANDOMID";
value["displayName"] = "DISPLAYNAME";
value["totalSize"] = "SIZE OF THE FILE";
value["sha3sum"] = "SHA3SUM OF THE FILE";
value["type"] = "application/data-transfer+json";
och skapar en länk i ${data_path}/conversation_data/${conversation_id}/${file_id}
där file_id=${commitid}_${value["tid"]}.${extension}
Sedan kan mottagaren nu ladda ner filerna genom att kontakta de enheter som värdar filen genom att öppna en kanal med name="data-transfer://" + conversationId + "/" + currentDeviceId() + "/" + fileId
och lagra informationen om att filen väntar i ${data_path}/conversation_data/${conversation_id}/waiting
Enheten som tar emot anslutningen accepterar kanalen genom att kontrollera om filen kan skickas (om sha3sum är korrekt och om filen finns).
När överföringen är klar eller kanalen stängs verifieras sha3sum för att bekräfta att filen är korrekt (eller det raderas).
Om det inte går, när en enhet i samtalet kommer att vara online igen, kommer vi att be om alla väntande filer på samma sätt.
Call in Swarm
Idé
A swarm conversation can have multiple rendez-vous. A rendez-vous is defined by the following URI:
”accountUri/deviceId/conversationId/confId” där accountUri/deviceId beskriver värden.
Värden kan bestämmas på två sätt:
In the swarm metadatas. Where it’s stored like the title/desc/avatar (profile picture) of the room
Eller den första som ringde.
When starting a call, the host will add a new commit to the repository, with the URI to join (accountUri/deviceId/conversationId/confId). This will be valid till the end of the call (announced by a commit with the duration to show)
Så varje del kommer att få informationen om att ett samtal har startat och kan ansluta sig till det genom att ringa det.
Attacks?
Avoid Git bombs
Noter
Tidsstampen på ett commit kan litas på eftersom den är redigerabel. Endast användarens tidsstamp kan litas på.
TLS
Git-operationer, kontrollmeddelanden, filer och andra saker kommer att använda en p2p TLS v1.3 länk med endast cipper som garanterar PFS. Så varje nyckel förhandlas om för varje ny anslutning.
DHT (UDP)
Används för att skicka meddelanden till mobiltelefoner (för att utlösa push-meddelanden) och för att initiera TCP-anslutningar.
Nätverksverksamhet
Förfarande för att bjuda in någon
Alice vill bjuda in Bob:
Alice lägger till Bob i ett samtal
Alice generates an invite: { ”application/invite+json” : { ”conversationId”: ”$id”, ”members”: [{…}] }}
Två möjligheter för att skicka meddelandet a. Om inte ansluten, via DHT b. Annars, Alice skickar på SIP-kanalen
Två möjligheter för Bob a. När han får inbjudan skickas en signal till klienten b. Han är inte ansluten, så han kommer aldrig att få begäran eftersom Alice inte får veta om Bob bara ignorerade eller blockerade Alice.
Process för att skicka ett meddelande till någon
Alice vill skicka ett meddelande till Bob:
Alice lägger till ett meddelande i repo, ger en ID
Alice får ett meddelande om det lyckas
I båda fallen skapas ett meddelande: { ”applikation/im-gitmessage-id” : ”{”id”:”\(convId", "commit":"\)commitId”, ”deviceId”: ”$alice_device_hash”}”}. a. Om inte ansluten, via DHT b. Annars skickar Alice på SIP-kanalen
Bob har fyra möjligheter: a. Bob är inte ansluten till Alice, så om han litar på Alice, be om en ny anslutning och gå till b. b. Om ansluten, hämta från Alice och meddela nya meddelanden c. Bob känner inte till det samtalet. Be genom DHT att få en inbjudan först för att kunna acceptera det samtalet ({”applikation/ inbjudan”, samtalId}) d. Bob är avkopplade (ingen nätverk, eller bara stängt). Han kommer inte att ta emot det nya meddelandet men kommer att försöka synkronisera när nästa anslutning kommer att inträffa
Genomförande
! [Diagram: swarm chat klasser](bilder/ swarm chat-klass-diagram.jpg)
Supported messages
Initial message
{
"type": "initial",
"mode": 0,
"invited": "URI"
}
Represents the first commit of a repository and contains the mode:
enum class ConversationMode : int { ONE_TO_ONE = 0, ADMIN_INVITES_ONLY, INVITES_ONLY, PUBLIC }
and invited
if mode = 0.
Text message
{
"type": "text/plain",
"body": "content",
"react-to": "id (optional)"
}
Or for an edition:
{
"type": "application/edited-message",
"body": "content",
"edit": "id of the edited commit"
}
Samtal
Show the end of a call (duration in milliseconds):
{
"type": "application/call-history+json",
"to": "URI",
"duration": "3000"
}
Or for hosting a call in a group (when it starts)
{
"type": "application/call-history+json",
"uri": "host URI",
"device": "device of the host",
"confId": "hosted confId"
}
A second commit with the same JSON + duration
is added at the end of the call when hosted.
Add a file
{
"type": "application/data-transfer+json",
"tid": "unique identifier of the file",
"displayName": "File name",
"totalSize": "3000",
"sha3sum": "a sha3 sum"
}
totalSize
is in bits,
Updating profile
{
"type": "application/update-profile",
}
Member event
{
"type": "member",
"uri": "member URI",
"action": "add/join/remove/ban"
}
When a member is invited, join or leave or is kicked from a conversation
Vote event
Generated by administrators to add a vote for kicking or un-kicking someone.
{
"type": "vote",
"uri": "member URI",
"action": "ban/unban"
}
!! Gammal utkast!!
Observera
Following notes are not organized yet. Just some line of thoughts.
Kryptovalutaförbättringar.
För en seriös gruppchat funktion behöver vi också seriös kryptografi. Med den nuvarande designen, om ett certifikat stjäls som tidigare DHT-värden i en konversation, kan konversationen decrypteras. Kanske måste vi gå till något som Double ratchet.
Observera
A lib might exist to implement group conversations.
Behöver ECC-stöd i OpenDHT
Användning
Add Roles?
Det finns två viktiga användningsfall för gruppchat:
Något som en Mattermost i ett företag, med privata kanaler, och vissa roller (admin/spektator/bot/etc) eller för utbildning (där bara några är aktiva).
Horisontella samtal som en samtal mellan vänner.
Jami will be for which one?
Genomförandeide
Ett intyg för en grupp som skriver in användare med en flagga för en roll.
Följ med i ett samtal
Endast genom en direkt inbjudan
Genom en länk/QR-kod/vad som helst
Via a room name? (a hash on the DHT)
Vad vi behöver
Sekretess: medlemmar utanför gruppchatten ska inte kunna läsa meddelanden i gruppen
Förhandshemlighet: Om någon nyckel från gruppen är kompromissad, bör tidigare meddelanden förbli konfidentiella (så långt som möjligt)
Meddelandeordnande: Det behövs meddelanden i rätt ordning
Synkronisering: Det är också nödvändigt att se till att alla meddelanden kommer att komma till dig så snart som möjligt.
Persistens: I själva verket, ett meddelande på DHT lever bara 10 minuter. Eftersom det är den bästa tidpunkten beräknad för denna typ av DHT. För att behålla data måste noden sätta värdet på DHT var 10:e minut. Ett annat sätt att göra när noden är offline är att låta noderna sätta data igen. Men om efter 10 minuter, 8 noder är fortfarande här, kommer de att göra 64 förfrågningar (och det är exponentiellt). Det aktuella sättet att undvika spamming för det är frågeställt. Detta kommer fortfarande att göra 64 förfrågningar men begränsa max redundansen till 8 noder.
Andra fördelade vägar
Jag behöver utredning.
Jag behöver lite utredning.
Maidsafe: Need some investigation
Baserat på det arbete vi har nu
Gruppenchat kan baseras på samma arbete som vi redan har för flera enheter (men här med ett gruppcertifikat).
Det här måste flytta databasen från klienten till demonen.
Om ingen är ansluten kan synkroniseringen inte göras och personen kommer aldrig att se samtalet
En annan dedikerad DHT
Som en DHT med en superanvändare.
What’s next for file transfers
Currently, the file transfer algorithm is based on a TURN connection (See Fileröverföring). In the case of a big group, this will be bad. We first need a P2P connection for the file transfer. Implement the RFC for P2P transfer.
Other problem: currently there is no implementation for TCP support for ICE in PJSIP. This is mandatory for this point (in PJSIP or homemade)