Zwerm

Belangrijk

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

Synospis

Het doel van dit document is om te beschrijven hoe groepschats (ook bekend als ** swarm chat**) in Jami worden geïmplementeerd.

Een swarm is een groep die zonder enige centrale autoriteit op een veerkrachtige manier kan bespreken. Inderdaad, als twee personen geen verbinding hebben met de rest van de groep (dat wil zeggen internetonderbreking), maar ze kunnen contact opnemen met elkaar (in een LAN bijvoorbeeld of in een subnetwerk), zullen ze elkaar berichten kunnen sturen en dan, zullen ze in staat zijn om te synchroniseren met de rest van de groep wanneer het mogelijk is.

De’swarm’ wordt gedefinieerd door:

  1. Vermogen om te splitsen en samen te sluiten na de verbinding.

  2. Iedereen moet een boodschap kunnen sturen aan de hele groep.

  3. Geen centrale autoriteit, geen server.

  4. De apparaten moeten in staat zijn om de geldigheid van oude berichten te verifiëren en de hele geschiedenis te reproduceren.

  5. De opslag wordt beheerd door het apparaat.

Het belangrijkste idee is om een synchroniseerde Merkle boom te krijgen met de deelnemers.

We hebben vier modus voor swarm chat geïdentificeerd die we willen implementeren:

  • EEN_TO_ONE, in feite de zaak die we vandaag hebben als je het bespreekt met een vriend

  • ADMIN_INVITES_ONLY in het algemeen een klas waar de leraar mensen kan uitnodigen, maar niet studenten

  • BEDRINGT_ENIG een privé groep vrienden

  • Public in principe een open forum

Scenario’s

Een Zwerm maken

Bob wil een nieuwe zwerm maken.

  1. Bob creates a local Git repository.

  2. Vervolgens maakt hij een initiële ondertekende verplichting met het volgende:

    • Zijn publieke sleutel in /admins

    • Zijn apparaatcertificaat in ̀ /apparaten `

    • Zijn CRL in ̀ /crls`

  3. De hash van de eerste commit wordt de ID van het gesprek

  4. Bob kondigt aan zijn andere apparaten dat hij een nieuw gesprek opzet.

Iemand toevoegen

Alice voegt Bob toe.

  1. Alice voegt Bob toe aan de repo:

    • Voegt de uitgenodigde URI toe in /invited

    • Voegt de CRL toe aan /crls

  2. Alice stuurt een verzoek op de DHT

Een uitnodiging ontvangen

Alice wordt uitgenodigd om deel te nemen aan de eerder gecreëerde zwerm

  1. Ze accepteert de uitnodiging (als ze weigert, doet ze niets, het blijft gewoon in de uitnodiging en Alice zal nooit een bericht ontvangen)

  2. Een peer-to-peer verbinding tussen Alice en Bob is gedaan.

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

  4. Alice bevestigt de verplichtingen van Bob

  5. Om te bevestigen dat Alice lid is, verwijdert ze de uitnodiging uit de directory /invited, voegt ze haar certificaat vervolgens toe in de directory /members

  6. Zodra alle commits zijn gevalideerd en op haar apparaat, worden andere leden van de groep ontdekt door Alice.

Een bericht sturen

Alice stuurt een bericht

Een bericht sturen is vrij eenvoudig. Alice schrijft een commit-bericht in het volgende formaat:

{
    "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).

Voor het pingen van andere apparaten stuurt de afzender aan andere leden een SIP-bericht met mimetype = “applicatie/im-gitmessage-id” met een JSON met de “deviceId” die het bericht stuurt, de “id” van het gesprek met betrekking tot, en de “commit”

Een bericht ontvangen

Bob ontvangt het bericht van Alice

  1. Bob do a Git pull on Alice

  2. Verplichten MUST via een hoek worden geverifieerd

  3. Als alle commits geldig zijn, worden de commits opgeslagen en weergegeven.

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

Validering van een verplichting

Om te voorkomen dat gebruikers ongewenste commits (met conflicten, valse berichten, enz.) uitvoeren, moet elk commit (van het oudste tot het nieuwste) worden gevalideerd voordat een afstandsfiliaal wordt samengevoegd:

Notitie

  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.

  • Voor elke commit moet worden gecontroleerd of het apparaat dat de commit probeert te verzenden op dit moment is toegelaten en of de certificaten aanwezig zijn (in/in apparaten voor het apparaat en in/leden of/administratoren voor de uitgever).

  • De commit heeft 2 ouders, dus het is een fusie, niets meer te bevestigen hier

  • De commit heeft 0 ouders, het is de eerste commit:

    • Controleer of admincertificaat is toegevoegd

    • Controleer of het apparaat certificering is toegevoegd

    • Controleer toegevoegde CRL’s

    • Controleer of er geen andere bestand is toegevoegd

  • Het commit heeft 1 ouder, het commit bericht is een JSON met een type:

    • Als tekst (of andere mime-type die geen bestanden verandert)

      • Controleer de handtekening van het certificaat in de repo

      • Controleer of geen vreemd bestand buiten het apparaat certificering is toegevoegd of verwijderd

    • Als men stemt

      • Controleer of voteType wordt ondersteund (verbod, ontbod)

      • Controleer of de stem voor de gebruiker is die de commit ondertekent

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

      • Controleer of er geen vreemd bestand is toegevoegd of verwijderd

    • Indien lid

      • Indien toegevoegd

        • Controleer of de commit correct is ondertekend

        • Controleer of het certificaat is toegevoegd in /invitaat

        • Controleer of er geen vreemd bestand is toegevoegd of verwijderd

        • Als ONE_TO_ONE, controleer of we slechts één beheerder, één lid hebben

        • Als ADMIN_INVITES_ONLY, controleer dat de uitnodiging van een beheerder is

      • Indien aansluit

        • Controleer of de commit correct is ondertekend

        • Controleer of het apparaat is toegevoegd

        • Controleer of de uitnodiging naar leden wordt overgebracht

        • Controleer of er geen vreemd bestand is toegevoegd of verwijderd

      • Indien verboden

        • Controleer of de stemming geldig is.

        • Controleer of de gebruiker is verboden via een admin

        • Controleer of het certificaat van het lid of het apparaat is verplaatst naar verboden/

        • Controleer of alleen bestanden met betrekking tot de stemming worden verwijderd

        • Controleer of er geen vreemd bestand is toegevoegd of verwijderd

    • Informeer de gebruiker dat hij of zij een oude versie heeft of dat hij of zij heeft geprobeerd ongewenste commits in te dienen

Verbod op een apparaat

Alice, Bob, Carla, Denys zijn in een zwerm.

Dit is een van de moeilijkste scenario’s in onze context.

  1. Tijdstempels van gecreëerde commits

  2. Als er meerdere beheerapparaten aanwezig zijn en als Alice met Bob kan praten, maar niet met Denys en Carla; Carla kan met Denys praten; Denys verbiedt Alice, Alice verbiedt Denys, wat zal de staat zijn wanneer de 4 leden de gesprekken zullen combineren.

  3. Een apparaat kan worden gecompromitteerd, gestolen of het certificaat kan vervallen.

Gelijkaardige systemen (met gedistribueerde groepssystemen) zijn niet zo veel, maar hier zijn enkele voorbeelden:

  • [mpOTR definieert niet hoe iemand wordt verboden]

  • Signal, zonder centrale server voor groepchat (EDIT: ze hebben onlangs dat punt veranderd), geeft niet de mogelijkheid om iemand uit een groep te verbieden.

Dit stemmingssysteem heeft een menselijke actie nodig om iemand te verbieden of moet gebaseerd zijn op de CRL-informatie uit het register (omdat we externe CRL’s niet kunnen vertrouwen)

Verwijder een apparaat uit een gesprek

Dit is het enige deel dat een consensus moet hebben om een gesprek te vermijden, als twee leden elkaar uit het gesprek schoppen, wat zal de derde zien?

Dit is nodig om herroepde apparaten te detecteren, of om ongewenste personen in een openbare ruimte te voorkomen.

Alice verwijdert Bob.

Belangrijk

Alice MUST be an admin to vote.

  • Om dat te doen, maakt ze het bestand in /votes/ban/members/uri_bob/uri_alice (leden kunnen worden vervangen door apparaten voor een apparaat, of worden uitgenodigd voor uitnodigingen of admins voor admins) en verbindt

  • Dan controleert ze of de stemming is opgelost. Dit betekent dat >50% van de administratoren het ermee eens is om Bob te verbieden (als ze alleen is, is het zeker meer dan 50%).

  • Als de stemming is opgelost, kunnen bestanden in /votes/ban worden verwijderd, alle bestanden voor Bob in /members, /admins, /invited, /CRLs, /devices kunnen worden verwijderd (of alleen in /devices als het een apparaat is dat is verboden) en het certificaat van Bob kan worden geplaatst in /banned/members/bob_uri.crt (of /banned/devices/uri.crt als een apparaat is verboden) en toegezegd aan de repo

  • Dan informeert Alice andere gebruikers (buiten 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

  • Dan controleert ze of de stemming is opgelost. Dit betekent dat >50% van de administratoren het ermee eens is om Bob te verbieden (als ze alleen is, is het zeker meer dan 50%).

  • Als de stemming is opgelost, kunnen bestanden in /votes/unban worden verwijderd, alle bestanden voor Bob in /members, /admins, /invited, /CRLs, kunnen worden toegevoegd (of alleen in /devices als het een apparaat is dat is ongebannen) en toegezegd aan de repo

Verwijder een gesprek

  1. Save in convInfos removed=time::now() (zoals removeContact save in contacten) dat de conversatie wordt verwijderd en wordt gesynchroniseerd met andere apparaten van de gebruiker

  2. Als er een nieuwe commissie wordt ontvangen voor dit gesprek, wordt het genegeerd.

  3. Als Jami opstart en de repo nog aanwezig is, wordt het gesprek niet bekendgemaakt aan klanten.

  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. Als we zeker zijn dat iemand is gesynchroniseerd, verwijder de gesloten = tijd:: nu() en synchroniseren met andere gebruikers apparaten

  6. Alle apparaten die eigendom zijn van de gebruiker kunnen nu het opslagplaats en de bijbehorende bestanden wissen

Hoe een modus wordt gespecificeerd

De modus kan niet worden gewijzigd door de tijd. Of het is een ander gesprek. Dus, deze gegevens worden opgeslagen in de eerste commit bericht.

{
    "type": "initial",
    "mode": 0,
}

Vooralsnog accepteert “mode” waarden 0 (ONE_TO_ONE), 1 (ADMIN_INVITES_ONLY), 2 (INVITES_ONLY), 3 (PUBLIC)

Processes for 1:1 swarms

Het doel is om de oude API (addContact/removeContact, sendTrustRequest/acceptTrustRequest/discardTrustRequest) te houden om een zwerm met een peer en zijn contact te genereren.

Het proces is nog steeds hetzelfde, een account kan een contact via addContact toevoegen, en vervolgens een TrustRequest via de DHT sturen.

  1. De TrustRequest bevat een “conversationId” om de peer te informeren welke gesprek te klonen wanneer hij het verzoek accepteert

  2. TrustRequest wordt opnieuw geprobeerd wanneer contact online komt. Het is niet het geval vandaag (omdat we geen nieuwe TrustRequest willen genereren als de peer de eerste verwijdert). Als een account een vertrouwensverzoek ontvangt, wordt het automatisch genegeerd als het verzoek met een gerelateerd gesprek wordt afgewezen (aangesien convRequests worden gesynchroniseerd)

Wanneer een contact het verzoek aanvaardt, is een synchronisatieperiode nodig, omdat het contact nu het gesprek moet klonen.

removeContact() verwijdert het contact en de gerelateerde 1:1 gesprekken (met hetzelfde proces als “Remove a conversation”).

Moeilijke scenario’s

Er zijn sommige gevallen waarin twee gesprekken kunnen worden gecreëerd.

  1. Alice adds Bob.

  2. Bob accepts.

  3. Alice removes Bob.

  4. Alice adds Bob.

of

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

In dit geval worden twee gesprekken gegenereerd. We willen geen berichten van gebruikers verwijderen of hier één gesprek kiezen. Soms worden dus twee 1:1-swermen tussen dezelfde leden getoond. Het zal tijdens de overgangstijd enkele bugs genereren (aangezien we de API niet willen breken, zal het afgeleide gesprek een van de twee getoonde gesprekken zijn, maar voorlopig is het “ok-ish”, zal het worden opgelost wanneer cliënten volledig met conversatieID voor alle API’s (oproepen, bestandsoverdracht, enz.).

Belangrijk

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() zal {{“sync”: “true”}} teruggeven als het wordt gesynchroniseerd.

  • ConfigurationManager::getConversationMembers() will return a map of two URIs (the current account and the peer who sent the request).

Gesprekken vragen om specificatie

De gesprekken worden aangevraagd door een Map<String, String> met de volgende sleutels:

  • id: the conversation ID

  • from: URI of the sender

  • ontvangen: tijdstempel

  • titel: (optioneel) naam voor het gesprek

  • beschrijving: (optioneel)

  • Avatar: (optioneel)

Synchronisatie van het gespreksprofiel

Om te kunnen worden geïdentificeerd, heeft een gesprek over het algemeen metadata nodig, zoals een titel (bijv. Jami), een beschrijving (bijv. enkele links, wat het project is, enz.) en een afbeelding (het logo van het project).

Opberging in de opslagplaats

Het profiel van het gesprek wordt opgeslagen in een klassiek vCard-bestand bij de root (/profile.vcf) zoals:

BEGIN:VCARD
VERSION:2.1
FN:TITLE
DESCRIPTION:DESC
END:VCARD

Synchronisatie

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

Laatste weergave

In de gesynchroniseerde gegevens stuurt elk apparaat de staat van de gesprekken naar andere apparaten. In deze staat wordt de laatste weergegeven gestuurd.

Er worden vijf scenario’s ondersteund:

  • Als de laatste weergave die door andere apparaten is verzonden, dezelfde is als de huidige, is er niets te doen.

  • indien er geen laatste weergave voor het huidige apparaat is, wordt het bericht dat op afstand wordt weergegeven gebruikt.

  • Als de laatste afstandsbediening niet aanwezig is in de repo, betekent dit dat de commit later wordt opgehaald, dus cache het resultaat

  • Als de afstandsbediening al is opgehaald, controleren we of de laatste lokale weergave eerder is in de geschiedenis om het te vervangen

  • Ten slotte, als er een bericht van dezelfde auteur wordt aangekondigd, betekent dit dat we het laatste bericht moeten bijwerken.

Voorkeuren

Bij elke conversatie zijn voorkeuren bijgevoegd die door de gebruiker zijn ingesteld. Deze voorkeuren worden gesynchroniseerd op de apparaten van de gebruiker. Dit kan de kleur van het gesprek zijn, als de gebruiker meldingen wil negeren, bestandsgrootte limiet, enz. Voorlopig zijn de herkenbare sleutels:

  • “color” - the color of the conversation (#RRGGBB format)

  • “ignore notifications” - om in dit gesprek notificaties voor nieuwe berichten te negeren

  • “symbool” - om een standaard emoji te definiëren.

Deze voorkeuren worden opgeslagen in een MapStringString-pakket, opgeslagen in accountDir/conversation_data/conversationId/preferences en alleen via SyncMsg via dezelfde gebruikersapparatuur verzonden.

De API om met de voorkeuren te communiceren is:

// 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*/);
};

Conflictenbeheer bij fusie

Omdat twee beheerders de beschrijving tegelijkertijd kunnen wijzigen, kan er op profile.vcf een fusieconflict optreden. In dit geval wordt de commit met de hogere hash (bijv. ffffff > 000000) gekozen.

API’s

De gebruiker heeft 2 methoden om metadata van gesprekken te krijgen en te instellen:

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

waar infos een map<str, str> is met de volgende sleutels:

  • Mode: ONLY-LEES

  • titel

  • beschrijving

  • avatar

Gebruikte protocollen

Git

Waarom deze keuze

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

  1. We moeten berichten synchroniseren en bestellen. De Merkle Tree is de perfecte structuur om dat te doen en kan worden lineair gemaakt door takken te smelten. Bovendien, omdat het massaal wordt gebruikt door Git, is het gemakkelijk om te synchroniseren tussen apparaten.

  2. Uit de natuur verspreid, veel gebruikt, veel backends en pluggable.

  3. Kan commits verifiëren via haakjes en massaal gebruikte crypto

  4. Kan indien nodig worden opgeslagen in een database

  5. Conflicten worden vermeden door gebruik te maken van commit-berichten, niet van bestanden.

Wat we moeten bevestigen

  • Performance? git.lock kan laag zijn

  • Hooks in libgit2

  • Meerdere trekkingen tegelijk?

Beperkingen

Om een gesprek te verwijderen, moet het apparaat het gesprek verlaten en een ander gesprek maken.

Niet-permanente berichten (zoals berichten die slechts enkele minuten kunnen worden gelezen) kunnen echter via een speciaal bericht via de DRT (zoals meldingen voor typen of lezen) worden verzonden.

Structuur

/
 - 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

File overdracht

Swarm verandert de file transfer massaal. Nu wordt de geschiedenis gesynchroniseerd, waardoor alle apparaten in het gesprek gemakkelijk oude bestanden kunnen terugvinden. Deze veranderingen stellen ons in staat om te gaan van een logica waar de afzender het bestand op andere apparaten duwde, via het proberen om verbinding te maken met hun apparaten (dit was slecht omdat het niet echt bestand was tegen verbindingswijzigingen / storingen en een handmatige hergebruik nodig had) naar een logica waar de afzender andere apparaten toestaat om te downloaden. Bovendien kan elk apparaat met het bestand de host zijn voor andere apparaten, waardoor bestanden kunnen worden teruggevorderd zelfs als de afzender er niet is.

Protocol

De afzender voegt een nieuwe commit toe in het gesprek met het volgende formaat:

value["tid"] = "RANDOMID";
value["displayName"] = "DISPLAYNAME";
value["totalSize"] = "SIZE OF THE FILE";
value["sha3sum"] = "SHA3SUM OF THE FILE";
value["type"] = "application/data-transfer+json";

en creëert een link in ${data_path}/conversation_data/${conversation_id}/${file_id} waar file_id=${commitid}_${value["tid"]}.${extension}

De ontvanger kan de bestanden dan nu downloaden door contact op te nemen met de apparaten die het bestand hosten door een kanaal te openen met name="data-transfer://" + conversationId + "/" + currentDeviceId() + "/" + fileId en de informatie opslaan dat het bestand wacht in ${data_path}/conversation_data/${conversation_id}/waiting

Het apparaat dat de verbinding ontvangt, accepteert het kanaal door te controleren of het bestand kan worden verzonden (als sha3sum correct is en als het bestand bestaat). De ontvanger houdt het eerste geopende kanaal, sluit de anderen en schrijft in een bestand (met hetzelfde pad als de afzender: ${data_path}/conversation_data/${conversation_id}/${file_id}) alle inkomende gegevens.

Wanneer de overdracht is voltooid of het kanaal gesloten, wordt de sha3sum geverifieerd om te bevestigen dat het bestand correct is (of het is verwijderd).

In geval van falen, wanneer een apparaat van het gesprek weer online is, vragen we alle wachtbestanden op dezelfde manier.

Roep een zwerm in

Idee

A swarm conversation can have multiple rendez-vous. A rendez-vous is defined by the following URI:

“accountUri/deviceId/conversationId/confId” waar accountUri/deviceId de host beschrijft.

De gastheer kan op twee manieren worden bepaald:

  • In de zwerm metadata, waar het opgeslagen is als de titel/desc/avatar van de kamer.

  • Of de eerste beller.

Bij het starten van een oproep voegt de gastheer een nieuwe commit toe aan de zwerm, waarbij de URI wordt toegevoegd (accountUri/deviceId/conversationId/confId).

Elke deel zal de informatie ontvangen dat een oproep is gestart en kan zich erbij aansluiten door het op te roepen.

Aanvallen?

  • Avoid Git bombs

Notities

De tijdstempel van een commit is betrouwbaar omdat het bewerkbaar is. Alleen de tijdstempel van de gebruiker kan worden vertrouwd.

TLS

Git-operaties, controlberichten, bestanden en andere dingen gebruiken een p2p TLS v1.3-link met alleen ciphers die PFS garanderen.

DHT (UDP)

Gebruikt om berichten te sturen voor mobiele telefoons (om push-meldingen te laten starten) en TCP-verbindingen te starten.

Netwerkactiviteit

Proces om iemand uit te nodigen

Alice wil Bob uitnodigen:

  1. Alice voegt Bob toe aan een gesprek

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

  3. Twee mogelijkheden voor het verzenden van de boodschap a. Als niet verbonden, via de DHT b. Anders, Alice stuurt op het SIP-kanaal

  4. Twee mogelijkheden voor Bob a. Ontvangt de uitnodiging, wordt een signaal uitgezonden voor de cliënt b. Niet verbonden, dus zal nooit het verzoek ontvangen omdat Alice niet moet weten of Bob gewoon genegeerd of geblokkeerd Alice. De enige manier is om een nieuwe uitnodiging te regenereren via een nieuw bericht (zie volgende scenario)

Proces om een bericht naar iemand te sturen

Alice wil een boodschap naar Bob sturen:

  1. Alice voegt een bericht toe in de repo, geeft een ID

  2. Alice krijgt een bericht ontvangen (van zichzelf) als succesvol

  3. In beide gevallen wordt een bericht gemaakt: { “applicatie/im-gitmessage-id” : “{“id”:”\(convId", "commit":"\)commitId”, “deviceId”: “$alice_device_hash”}”}. a. Als het niet is aangesloten, via de DHT b. Anders stuurt Alice op het SIP-kanaal

  4. Bob heeft vier mogelijkheden: a. Bob is niet verbonden met Alice, dus als hij Alice vertrouwt, vraag dan een nieuwe verbinding en ga naar b. b. Als hij verbonden is, haal dan van Alice en kondig nieuwe berichten aan c. Bob kent dat gesprek niet. Vraag via de DHT om eerst een uitnodiging te krijgen om dat gesprek te kunnen accepteren ({“toepassing/invite”, conversatieId}) d. Bob is afgesloten (geen netwerk, of gewoon gesloten). Hij zal het nieuwe bericht niet ontvangen, maar zal proberen te synchroniseren wanneer de volgende verbinding zal plaatsvinden

Uitvoering

[Diagram: swarm chat-classes]

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"
}

Oproepen

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"
}

!! OUD DRAFT!!

Notitie

Following notes are not organized yet. Just some line of thoughts.

Crypto verbeteringen.

Voor een serieuze groepshatsfunctie hebben we ook serieuze crypto nodig. Met het huidige ontwerp, als een certificaat wordt gestolen als de vorige DHT-waarden van een gesprek, kan het gesprek worden gedecodeerd. Misschien moeten we naar iets als Double Ratchet gaan.

Notitie

A lib might exist to implement group conversations.

Voor de opstelling van een ECC-ondersteuning in OpenDHT

Gebruik

Rol toevoegen?

Er zijn twee belangrijke gebruiksgevallen voor groepschatten:

  1. Iets als een Mattermost in een bedrijf, met privé-kanalen, en sommige rollen (admin/spectator/bot/etc) of voor onderwijs (waar slechts een paar actief zijn).

  2. Horizontale gesprekken zijn als een gesprek tussen vrienden.

Jami will be for which one?

Uitvoeringsidee

Een certificaat voor een groep die gebruikers met een vlag voor een rol ondertekent.

Neem deel aan een gesprek

  • Alleen via een directe uitnodiging

  • Via een link/QR-code/wat dan ook

  • Via een kamernaam?

Wat we nodig hebben

  • Geheime informatie: leden buiten de groepsklets mogen geen berichten in de groep lezen

  • Geheimheid: indien een sleutel van de groep wordt gecompromitteerd, moeten eerdere berichten vertrouwelijk blijven (zo veel mogelijk)

  • Boodschappenorderen: Boodschappen moeten in de juiste volgorde zijn

  • Synchronisatie: Er is ook een noodzaak om ervoor te zorgen dat alle berichten zo snel mogelijk beschikbaar zijn.

  • De tijdsduur van een bericht op de DHT is slechts 10 minuten. Omdat het de beste tijdsduur is die is berekend voor dit soort DHT. Om gegevens te behouden, moet de knoop de waarde van de DHT elke 10 minuten opnieuw zetten. Een andere manier om te doen wanneer de knoop offline is, is om knooppunten de gegevens opnieuw te laten zetten. Maar als na 10 minuten, 8 knooppunten nog steeds hier zijn, zullen ze 64 verzoeken doen (en het is exponentieel). De huidige manier om spam te voorkomen daarvoor wordt gevraagd. Dit zal nog steeds 64 verzoeken doen, maar beperkt de maximale redundantie tot 8 knooppunten.

Andere verdeelde wegen

  • IPFS: Ik heb onderzoek nodig.

  • Ik heb onderzoek nodig.

  • Ik heb onderzoek nodig.

Op basis van het huidige werk dat we hebben

Groepchat kan gebaseerd zijn op hetzelfde werk dat we al hebben voor multi-apparaten (maar hier, met een groepscertificaat).

  1. Hiermee moet de database van de client naar de daemon worden verplaatst.

  2. Als niemand is aangesloten, kan de synchronisatie niet worden gedaan, en de persoon zal het gesprek nooit zien

Een andere DHT-afdeling

Net als een DHT met een supergebruiker.

File overdracht

De algoritme voor het overbrengen van bestanden is momenteel gebaseerd op een TURN-verbinding (zie File overdracht).

Een ander probleem: momenteel is er geen implementatie van TCP-ondersteuning voor ICE in PJSIP. Dit is verplicht voor dit punt (in pjsip of zelfgemaakt)

Hulpbronnen

  • Het is een van de belangrijkste onderdelen van de Europese Unie.

  • Robuuste gedistribueerde synchronisatie van netwerken met intermitterende informatie (Sean Phillips en Ricardo G. Sanfelice)