Skarm

Viktigt

Jami source code tends to use the terms (un)ban, while the user interface uses the terms (un)block.

Synospis

Syftet med detta dokument är att beskriva hur gruppchat (a.k.a. ** swarm chat**) kommer att implementeras i Jami.

En swarm är en grupp som kan diskutera utan någon central myndighet på ett motståndskraftigt sätt. Om två personer inte har någon anslutning till resten av gruppen (dvs. Internetutbrott) men de kan kontakta varandra (i ett LAN till exempel eller i ett subnätverk), kommer de att kunna skicka meddelanden till varandra och sedan, kommer att kunna synkronisera med resten av gruppen när det är möjligt.

Så, den swarm definieras av:

  1. Förmåga att dela och slå samman efter anslutningen.

  2. Syncing of the history. Anyone must be able to send a message to the whole group.

  3. Ingen central myndighet, ingen server.

  4. Enheter måste kunna verifiera giltigheten av gamla meddelanden och spela upp hela historien.

  5. Lagring förvaltas av enheten.

Huvudideen är att få ett synkroniserat Merkle-träd med deltagarna.

Vi har identifierat fyra sätt att prata med folk som vi vill implementera:

  • Det är i princip det vi har idag när du diskuterar med en vän.

  • ADMIN_INVITES_ONLY i allmänhet en klass där läraren kan bjuda in människor, men inte studenter

  • INVITES_ONLY en privat grupp vänner

  • Public i princip ett öppet forum

Scenarier

Skapa en släkta

Bob vill skapa en ny svärm

  1. Bob creates a local Git repository.

  2. Han skapar sedan ett initialt undertecknat åtagande med följande:

    • Hans offentliga nyckel i /admins

    • Hans enhetsertifikat i ̀ /apparater `

    • Hans CRL i ̀ /crls`

  3. Hashet i det första inlägget blir konversationsidenten.

  4. Bob meddelar sina andra enheter att han skapar en ny konversation. Detta görs via en inbjudan att gå med i swarmen skickas via DHT till andra enheter som är kopplade till det kontot.

Att lägga till någon

Alice lägger till Bob

  1. Alice lägger till Bob i repo:

    • Lägger till den inbjudna URI i /invited

    • Lägger till CRL i /crls

  2. Alice skickar en begäran om DHT

Att få en inbjudan

Alice får bjudan att bli med i den tidigare skapade swarmen

  1. Hon accepterar inbjudan (om hon vägrar, gör ingenting, så stannar den bara i inbjudan och Alice får aldrig något meddelande)

  2. En peer-to-peer-anslutning mellan Alice och Bob är klar.

  3. Alice pull the Git repo of Bob. WARNING this means that messages need a connection, not from the DHT like today.

  4. Alice bekräftar att Bob har gjort sina åtaganden.

  5. För att bekräfta att Alice är medlem tar hon ut inbjudan från /invited-kataloget och lägger sedan till sitt intyg i /members-kataloget.

  6. När alla åtaganden är validerade och på hennes enhet upptäcks andra medlemmar av gruppen av Alice.

Skicka ett meddelande

Alice skickar ett meddelande

Att skicka ett meddelande är ganska enkelt. Alice skriver ett commit-meddelande i följande format:

{
    "type": "text/plain",
    "body": "coucou"
}

and adds her device and CRL to the repository if missing (others must be able to verify the commit). Merge conflicts are avoided because we are mostly based on commit messages, not files (unless CRLS + certificates but they are located). Then she announces the new commit via the DRT with a service message (explained later) and pings the DHT for mobile devices (they must receive a push notification).

För pingning av andra enheter skickar avsändaren ett SIP-meddelande till andra medlemmar med mimetype = ”applikation/im-gitmessage-id” som innehåller en JSON med ”deviceId” som skickar meddelandet, ”id” för konversationen relaterad, och ”kommit”

Att få ett meddelande

Bob får meddelandet från Alice.

  1. Bob do a Git pull on Alice

  2. Åtaganden måste verifieras via en krok

  3. Om alla commits är giltiga lagras och visas commits.

  4. If all commits are not valid, pull is canceled. Alice must reestablish her state to a correct state.

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

  1. 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.

  2. If a fetch is too big, it’s not merged.

  • Kontrollera för varje commit att den enhet som försöker skicka commit är auktoriserad vid detta tillfälle och att intygen finns (i/tillbehör för enheten och i/medlemmar eller/administratörer för emittenten).

  • Det är ett sammanslagning, inget mer att bekräfta här.

  • Kommitten har 0 föräldrar, det är den ursprungliga kommitten:

    • Kontrollera att admincertifikatet är läget

    • Kontrollera att enhetcertifikatet är läget

    • Kontroll CRL:er läggs till

    • Kontrollera att ingen annan fil läggs till

  • Commit har 1 förälder, commit meddelande är en JSON med en typ:

    • Om text (eller annan mime-typ som inte ändrar filer)

      • Kontroll undertecknande från certifikat i repo

      • Kontrollera att ingen konstig fil läggs till utanför enhet certifierad eller tas bort

    • Om man röstar

      • Kontrollera att voteType stöds (förbud, avbud)

      • Kontrollera att rösten är för användaren som skriver under commit

      • Check that vote is from an admin and device present and not banned

      • Kontrollera att ingen konstig fil läggs till eller tas bort

    • Om medlem

      • Om läggs till

        • Kontrollera att commit är korrekt undertecknat

        • Kontrollera att intyget läggs till i /inbjuds

        • Kontrollera att ingen konstig fil läggs till eller tas bort

        • Om ONE_TO_ONE, kontrollera att vi bara har en administratör, en medlem

        • Om ADMIN_INVITES_ONLY, kontrollera att inbjudan är från en admin

      • Om det ansluter sig

        • Kontrollera att commit är korrekt undertecknat

        • Kontrollera att enheten är läggs till

        • Kontrollera att inbjudan är överförd till medlemmar

        • Kontrollera att ingen konstig fil läggs till eller tas bort

      • Om det är förbjudet

        • Kontrollera om rösten är giltig

        • Kontrollera att användaren är förbjuden via en admin

        • Kontrollera att lednings- eller anordningscertifikatet har flyttats till förbjudet.

        • Kontrollera att endast filer relaterade till röstningen tas bort

        • Kontrollera att ingen konstig fil läggs till eller tas bort

    • Anmäl användaren att de kan vara med en gammal version eller att den kamrat försökte skicka oönskade commits

Banning av en enhet

Alice, Bob, Carla, Denys är i en svärm.

Det är ett av de svåraste scenarierna i vårt sammanhang.

  1. Tidstämplar för de genererade åtagandena

  2. Om flera admin-enheter är närvarande och om Alice kan prata med Bob men inte Denys och Carla; Carla kan prata med Denys; Denys förbjuder Alice, Alice förbjuder Denys, vad blir tillståndet när de fyra medlemmarna kommer att slå samman samtalen.

  3. En enhet kan komma att kompromissas, stjälas eller dess certifikat kan löpa ut. Vi bör kunna förbjuda en enhet och undvika att den ljuger om dess löptid eller skickar meddelanden i det förflutna ( genom att ändra sitt certifikat eller tidstampeln för sitt commit).

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.

Detta röstningssystem behöver en mänsklig åtgärd för att förbjuda någon eller måste baseras på CRL-information från arkivet (eftersom vi inte kan lita på externa CRL)

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

  1. Spara i convInfos bort = tid:: nu() (som bortKontakt sparar i kontakter) att konversationen tas bort och synkroniseras med andra användares enheter

  2. Om en ny kommitté mottas för det här samtalet ignoreras den

  3. Om Jami startar och repo är fortfarande närvarande, meddelas inte konversationen till kunderna.

  4. 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.

  5. 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

  6. 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 swarms

Målet här är att behålla det gamla API (addContact/removeContact, sendTrustRequest/acceptTrustRequest/discardTrustRequest) för att generera swarm med en peer och dess kontakt.

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:

  1. TrustRequest innehåller en ”conversationId” för att informera peer vilken konversation att klona när de accepterar begäran

  2. 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.

  1. Alice adds Bob.

  2. Bob accepts.

  3. Alice removes Bob.

  4. Alice adds Bob.

eller

  1. Alice adds Bob and Bob adds Alice at the same time, but both are not connected together.

I detta fall genereras två samtal. Vi vill inte ta bort meddelanden från användare eller välja en samtal här. Så ibland kommer två 1:1-svärm mellan samma medlemmar att visas. Det kommer att generera några fel under övergångstiden (som vi inte vill bryta API, kommer den härda samtalet att vara en av de två visade samtal, men för närvarande är det ”ok-ish”, kommer att åtgärdas när klienten kommer att fullt ut hantera samtalId för alla API (samtal, filöverföring, 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: (valfri)

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

Användda protokoll

Git

Varför detta val

Each conversation will be a Git repository. This choice is motivated by:

  1. 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.

  2. Det är distribuerat av naturen, massivt använt, mycket backend och pluggable.

  3. Kan verifiera åtaganden via hakar och massivt använda kryptotjänster

  4. Kan lagras i en databas om det behövs

  5. Konflikter undvikes genom att använda commit-meddelanden, inte filer.

Vad vi måste bekräfta

  • Performance? git.lock kan vara låg

  • Hä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

Swarm förändrar massivt filöverföring. Nu synkroniseras hela historien, vilket gör det möjligt för alla enheter i samtalet att enkelt hämta gamla filer. Dessa förändringar gör det möjligt för oss att flytta från en logik där avsändaren tryckte filen på andra enheter, via att försöka ansluta till sina enheter (det var dåligt eftersom det inte var riktigt motståndskraftigt mot anslutningsförändringar / misslyckanden och behövde en manuell återförsök) till en logik där avsändaren tillåter andra enheter att ladda ner. Dessutom kan alla enheter med filen vara värd för andra enheter, vilket gör det möjligt att hämta filer även om avsändaren inte är där.

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.

Ring 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:

  • I en svärm med metadata, där det lagras som rummets titel/desk/avatar.

  • Eller den första som ringde.

När ett samtal startas lägger värden ett nytt commit till swarmen, med URI att ansluta (accountUri/deviceId/conversationId/confId).

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:

  1. Alice lägger till Bob i ett samtal

  2. Alice generates an invite: { ”application/invite+json” : { ”conversationId”: ”$id”, ”members”: [{…}] }}

  3. Två möjligheter för att skicka meddelandet a. Om inte ansluten, via DHT b. Annars, Alice skickar på SIP-kanalen

  4. 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:

  1. Alice lägger till ett meddelande i repo, ger en ID

  2. Alice får ett meddelande om det lyckas

  3. 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

  4. 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:

  1. 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).

  2. 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).

  1. Det här måste flytta databasen från klienten till demonen.

  2. 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.

Fileröverföring

För närvarande baseras filöverföringsalgorithmen på en TURN-anslutning (se Fileröverföring). För en stor grupp kommer detta att vara dåligt. Vi behöver först ett p2p-implement för filöverföring.

Ett annat problem: för närvarande finns det inget implementering av TCP-stöd för ICE i PJSIP. Detta är obligatoriskt för denna punkt (i pjsip eller hemlagd)

Resurser

  • Det är en del av den här typen av tjänster.

  • Robust distribuerad synkronisering av nätverkslinjärt system med intermitterande information (Sean Phillips och Ricardo G.Sanfelice)