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:

  1. Ability to split and merge based on network connectivity.

  2. History synchronization. Every participant must be able to send a message to the entire group.

  3. Ingen central myndighed, ingen server.

  4. Non-repudiation. Devices must be able to verify past messages‹ validity and to replay the entire history.

  5. Perfect Forward Secrecy (PFS) is provided on the transport channels. Storage is handled by each device.

Hovedidéen er at få et synkroniseret Merkle-træ med deltagerne.

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

Skab en flok

Bob vil skabe en ny sværm

  1. Bob creates a local Git repository.

  2. Så opretter han et første underskrevet engagement med følgende:

    • Hans offentlige nøgle i /admins

    • Hans udstyrsertifikat i ̀ /apparater `

    • Hans CRL i ̀ /crls`

  3. Hashet i det første indlæg bliver samtaleens ID

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

Tilføjelse af nogen

Bob adds Alice

  1. Bob adds Alice to the repo:

    • Tilføj den indkaldte URI i /invited

    • Lægger CRL til /crls

  2. Bob sends a request on the DHT.

At modtage en invitation

Alice gets the invite to join the previously created swarm

  1. Alice accepts the invite (if she declines, nothing happens; she will remain in the »invited« list, and will never receive any messages)

  2. A peer-to-peer connection is established between Alice and Bob.

  3. Alice pulls the Git repository from Bob. WARNING this means that messages require a connection, not from the DHT as it is today.

  4. Alice validates the commits from Bob.

  5. To validate that Alice is a member, she removes the invite from /invited directory, then adds her certificate to the /members directory

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

Sende en besked

Alice sends a message to Bob

  1. Alice creates a commit message. She constructs a JSON payload containing the MIME type and message body. For example:

{
    "type": "text/plain",
    "body": "hello"
}
  1. 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.

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

  3. Alice announces the commit via the DRT with a service message and pings the DHT for mobile devices (they must receive a push notification).

Bemærk

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.

Jeg modtager en besked

Bob receives a message from Alice

  1. Bob performs a Git pull on Alice’s repository.

  2. All incoming commits MUST be verified by a hook.

  3. If all commits are valid, commits are stored and displayed.Bob then announces the message via the DRT for other devices.

  4. If any commit is invalid, pull is aborted. Alice must restore her repository to a correct state before retrying.

Validering af et tilsagn

For at undgå, at brugere skubber nogle uønskede commits (med konflikter, falske meddelelser, osv.), er det sådan, at hver commit (fra den ældste til den nyeste) MÅS være valideret før fusion af en fjerngren:

Bemærk

  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.

  • 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 each type 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.

Banned en enhed

Vigtigt

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:

  1. Untrusted Timestamps: Commit timestamps cannot be relied upon for ordering ban events, as any device can forge or replay commits with arbitrary dates.

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

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

Der er ikke så mange lignende systemer (med distribuerede gruppesystemer), men her er nogle eksempler:

  • [mpOTR definerer ikke, hvordan man forbyder nogen]

  • Signal, uden nogen central server til gruppechat (EDIT: de ændrer det punkt for nylig), giver ikke mulighed for at forbyde nogen fra en gruppe.

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

Fjern en enhed fra en samtale

Det er den eneste del, der skal være enighed om at undgå en splittelse, som hvis to medlemmer sparker hinanden fra samtalen, hvad vil det tredje?

Dette er nødvendigt for at opdage tilbagekaldte enheder, eller blot undgå at få uønskede personer til stede i et offentligt rum.

Alice fjerner Bob

Vigtigt

Alice MUST be an admin to vote.

  • For det første stemmer hun for at forbyde Bob. For at gøre det opretter hun filen i /votes/ban/members/uri_bob/uri_alice (medlemmer kan erstattes med enheder til en enhed, eller inviteres til invitationer eller admins til admins) og forpligter

  • Så kontrollerer hun, om afstemningen er afgjort. Det betyder, at >50% af administratorer er enige om at forbyde Bob (hvis hun er alene, er det sikkert mere end 50%).

  • Hvis afstemningen er løst, kan filer i /votes/ban fjernes, alle filer til Bob i /members, /admins, /invited, /CRLs, /devices kan fjernes (eller kun i /devices hvis det er en enhed, der er forbudt) og Bobs certifikat kan placeres i /banned/members/bob_uri.crt (eller /banned/devices/uri.crt hvis en enhed er forbudt) og indsættes til repo

  • Så informerer Alice andre brugere (uden 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

  • Så kontrollerer hun, om afstemningen er afgjort. Det betyder, at >50% af administratorer er enige om at forbyde Bob (hvis hun er alene, er det sikkert mere end 50%).

  • Hvis afstemningen er løst, kan filer i /votes/unban fjernes, alle filer til Bob i /members, /admins, /invited, /CRLs, kan føjes tilbage (eller kun i /devices hvis det er en enhed, der er ubanned) og indsættes til repo

Fjern en samtale

  1. Gem i convInfos fjernet=tid::nu() (som fjernKontakt gemmer i kontakter) at samtalen fjernes og synkroniseres med andre brugerens enheder

  2. Hvis der er en ny besked, ignoreres den.

  3. Hvis Jami starter og repo er stadig til stede, bliver samtalen ikke annonceret til kunderne.

  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 er sikre på, at nogen er synkroniseret, fjern de er slettet = time::now() og synkronisere med andre brugers enheder

  6. Alle enheder ejet af brugeren kan nu slette arkivet og relaterede filer

Sådan angives en modus

Moderne kan ikke ændres gennem tiden. Eller det er en anden samtale. Så, disse data gemmes i den oprindelige commit budskab.

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

For nu accepterer »modus« værdier 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 er stadig den samme, en konto kan tilføje en kontakt via addContact, og derefter sende en TrustRequest via DHT. Men to ændringer er nødvendige:

  1. TrustRequest indlejrer en »conversationId« for at informere peer om hvilken samtale man skal klone, når man accepterer anmodningen

  2. TrustRequest bliver genprøvet, når kontakten kommer tilbage online. Det er ikke tilfældet i dag (som vi ikke ønsker at generere en ny TrustRequest, hvis peer kasserer den første). Så hvis en konto modtager en tillidsforespørgsel, vil den automatisk ignoreres, hvis anmodningen med en relateret samtale afvises (som convRequests synkroniseres)

Når en kontakt accepterer anmodningen, er der en synkroniseringsperiode, fordi kontakten nu skal klone samtalen.

removeContact() fjerner kontakten og relaterede 1:1-samtaler (med samme proces som »Remove a conversation«). Den eneste note her er, at hvis vi forbyder en kontakt, vi ikke venter på synkronisering, vi bare fjerner alle relaterede filer.

Trællige scenarier

Der er nogle tilfælde, hvor der kan ske to samtaler.

  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.

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

Vigtigt

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() returnerer {{»synkronisering«: »rigtig«}} hvis synkronisering.

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

Samtaler kræver specifikation

Forlangelser til samtale er repræsenteret med en Map<String, String> med følgende nøgler:

  • id: the conversation ID

  • from: URI of the sender

  • modtaget: tidsstempel

  • Titel: (valgfrit) navn på samtalen

  • Beskrivelse: (valgfrit)

  • avatar: (optional) the profile picture

Samtalernes profil synkronisering

For at være identificerbar, har en samtale generelt brug for nogle metadata, såsom en titel (f.eks. Jami), en beskrivelse (f.eks. nogle links, hvad projektet er osv.) og et billede (projektets logo).

Lagring i lageret

Profilen af samtalen gemmes i en klassisk vCard-fil i 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).

Sidst vist

I de synkroniserede data sender hver enhed til andre enheder samtalernes tilstand. I denne tilstand sendes den sidste, der vises.

Der er støtte til fem scenarier:

  • Hvis den sidste af de andre enheder, der er sendt, er den samme som den nuværende, er der intet at gøre.

  • Hvis der ikke er en sidste visning for den aktuelle enhed, anvendes den fjernvisede besked.

  • Hvis den fjerntliggende last vises ikke er til stede i repo, betyder det, at commit vil blive hentet senere, så cache resultatet

  • Hvis fjernbetjeningen allerede er hentet, tjekker vi, at den sidste lokale vises er før i historien for at erstatte den

  • Endelig, hvis en meddelelse fra den samme forfatter bliver annonceret, betyder det, at vi skal opdatere den sidste, der er vist.

Fortrinsret

Hver samtale har knyttet præferencer, der er indstillet af brugeren. Disse præferencer synkroniseres på brugerens enheder. Dette kan være samtalen farve, hvis brugeren ønsker at ignorere meddelelser, filoverførsel størrelse grænse, osv. For nu er de anerkendte nøgler:

  • »color« - the color of the conversation (#RRGGBB format)

  • »ignoreNotifications« - at ignorere meddelelser om nye meddelelser i denne samtale

  • »symbol« - at definere en standard emoji.

Disse præferencer gemmes i en MapStringString-pakke, der gemmes i accountDir/conversation_data/conversationId/preferences og kun sendes over enheder af samme bruger via SyncMsg.

API’erne til at interagere med præferencerne er:

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

Fusionskonfliktstyring

Da to admins kan ændre beskrivelsen samtidig, kan der opstå en fusionskonflikt på profile.vcf. I dette tilfælde vil det blive valgt det commit med den højere hash (ffffff > 000000).

API’er

Brugeren fik 2 metoder til at få og indstille samtale metadata:

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

hvor infos er et map<str, str> med følgende nøgler:

  • Modus: LÆS-ENIG

  • Titel

  • Beskrivelse

  • avatar: the profile picture

Brugen af protokoller

Git

Hvorfor dette valg

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

  1. Merkle Tree er den perfekte struktur til at gøre det og kan linearieres ved at smelte grene sammen.

  2. Massivt brugt, mange baggrunde og pluggable.

  3. Kan verificere engagementer via hooks og massivt brugt kryptovaluta

  4. Kan lagres i en database, hvis det er nødvendigt

  5. Konflikter undgårs ved at bruge commit-meddelelser, ikke filer.

Hvad vi skal bekræfte

  • Performance? git.lock kan være lav

  • Højker i libgit2

  • Flere træk på samme tid?

Grænser

For at slette en samtale, må enheden forlade samtalen og oprette en ny.

Ikke-permanente meddelelser (som for eksempel meddelelser, der kun kan læses i nogle minutter) kan dog sendes via en særlig meddelelse via DRT (som for eksempel indtømmelses- eller læse-meddelelser).

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

Fileroverførsel

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.

Protokol

Afsenderen tilføjer et nyt commit i samtalen med følgende 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";

og opretter et link i ${data_path}/conversation_data/${conversation_id}/${file_id} hvor file_id=${commitid}_${value["tid"]}.${extension}

Derefter kan modtageren nu downloade filerne ved at kontakte de enheder, der er vært for filen ved at åbne en kanal med name="data-transfer://" + conversationId + "/" + currentDeviceId() + "/" + fileId og gemme den information, at filen venter i ${data_path}/conversation_data/${conversation_id}/waiting

Enheden, der modtager forbindelsen, accepterer kanalen ved at kontrollere, om filen kan sendes (hvis sha3sum er korrekt og hvis filen eksisterer). Modtageren vil holde den første åbne kanal, lukke de andre og skrive i en fil (med den samme vej som afsenderen: ${data_path}/conversation_data/${conversation_id}/${file_id}) alle indgående data.

Når overførslen er afsluttet eller kanalen lukket, verifiseres sha3sum for at bekræfte, at filen er korrekt (eller det er slettet). Hvis den er gyldig, fjernes filen fra ventetiden.

Hvis vi ikke kan, vil vi, når en enhed i samtalen kommer tilbage, bede om alle ventede filer på samme måde.

Call in Swarm

Ideer

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

»accountUri/deviceId/conversationId/confId«, hvor accountUri/deviceId beskriver værten.

Værten kan bestemmes på to måder:

  • In the swarm metadatas. Where it’s stored like the title/desc/avatar (profile picture) of the room

  • Eller den første opkaldt.

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)

Hver del vil modtage informationen om, at en opkald er startet, og kan deltage ved at ringe til den.

Angreb?

  • Avoid Git bombs

Noter

Tidsstemplet på et commit kan stole på, fordi det kan redigeres. Kun brugernes tidsstemplet kan stole på.

TLS

Git-operationer, kontrolbeskeder, filer og andre ting vil bruge en p2p TLS v1.3 link med kun ciphere, der garanterer PFS. Så hver nøgle bliver genforhandlet for hver ny forbindelse.

DHT (UDP)

Bruges til at sende meddelelser til mobiltelefoner (til at udløse push-meddelelser) og til at initiere TCP-forbindelser.

Netværksaktivitet

Indkaldelse af en person

Alice vil invitere Bob:

  1. Alice tilføjer Bob til en samtale

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

  3. To muligheder for at sende meddelelsen a. Hvis ikke forbundet, via DHT b. Ellers sender Alice på SIP-kanalen

  4. To muligheder for Bob a. Modtager invitationen, udsendes et signal til klienten b. Ikke forbundet, så vil aldrig modtage anmodningen, fordi Alice må ikke vide, om Bob bare ignorerede eller blokerede Alice. Den eneste måde er at regenerere en ny invitation via en ny besked (jf. næste scenario)

Forløb for at sende en besked til nogen

Alice vil sende en besked til Bob:

  1. Alice tilføjer en besked i repo, giver en ID

  2. Alice får en besked modtaget (fra sig selv) hvis det lykkes

  3. I begge tilfælde er der oprettet en besked: { »application/im-gitmessage-id« : »{»id«:«\(convId", "commit":"\)commitId«, »deviceId«: »$alice_device_hash«}«}. a. Hvis ikke forbundet, via DHT b. Ellers sender Alice på SIP-kanalen

  4. Bob har fire muligheder: a. Bob er ikke forbundet med Alice, så hvis han stoler på Alice, så spørg om en ny forbindelse og gå til b. b. Hvis han er forbundet, hent fra Alice og meddel ny meddelelser c. Bob kender ikke den samtale. Spørg gennem DHT for at få en invitation først for at kunne acceptere den samtale ({»ansøgning/invitation«, samtaleId}) d. Bob er afkoblet (ingen netværk, eller bare lukket). Han vil ikke modtage den nye besked, men vil forsøge at synkronisere, når den næste forbindelse vil forekomme

Udførelse

! [Diagram: swarm chat klasser](billeder/ 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"
}

Opkald

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

!! OLD DRAFT!!

Bemærk

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

Kryptoforbedringer.

Hvis et certifikat bliver stjålet som tidligere DHT-værdier i en samtale, kan samtalen decrypteres. Måske skal vi gå til noget som Double Ratchet.

Bemærk

A lib might exist to implement group conversations.

Behov for ECC-støtte i OpenDHT

Brugen

Add Roles?

Der er to vigtige anvendelsesmuligheder for gruppechat:

  1. Et andet eksempel er et Mattermost i et selskab, med private kanaler, og nogle roller (admin/spektor/bot/etc) eller for uddannelse (hvor kun få er aktive).

  2. Horisontale samtaler er som en samtale mellem venner.

Jami will be for which one?

Implementeringsideen

Et certifikat for en gruppe, der signerer en bruger med et flag for en rolle.

Tag med i en samtale

  • Kun via en direkte invitation

  • Ved hjælp af en link/QR-kode/hvad som helst

  • Via a room name? (a hash on the DHT)

Hvad vi har brug for

  • Fortrolighed: medlemmer uden for gruppen bør ikke kunne læse meddelelser i gruppen

  • Forward secrecy: Hvis en nøgle fra gruppen er blevet kompromitteret, bør tidligere meddelelser forblive fortrolige (så vidt muligt)

  • Beskedsløsning: Der er behov for at have beskeder i den rigtige rækkefølge

  • Synkronisering: Der er også behov for at sikre sig at have alle meddelelser så hurtigt som muligt.

  • Persistence: Faktisk varer en besked på DHT kun 10 minutter. Fordi det er den bedste tidsplan beregnet for denne type DHT. For at persist data, må knudelet genindføre værdien på DHT hver 10 minutter. En anden måde at gøre, når knudelet er offline, er at lade knudelet genindføre data. Men hvis efter 10 minutter, 8 knudelet er stadig her, vil de gøre 64 anmodninger (og det er eksponentielt). Den nuværende måde at undgå spam for det er forespørgsel. Dette vil stadig gøre 64 anmodninger, men begrænse max redundance til 8 knudeletter.

Andre fordeltes veje

  • IPFS: Jeg har brug for en undersøgelse

  • Jeg har brug for en undersøgelse.

  • Maidsafe: Need some investigation

På baggrund af det nuværende arbejde, vi har

Gruppenchat kan baseres på det samme arbejde, vi allerede har for flere enheder (men her med et gruppecertifikat).

  1. History sync. This needs to move the database from the client into the daemon.

  2. Hvis ingen er forbundet, kan synkroniseringen ikke ske, og personen vil aldrig se samtalen

Endnu en dedikeret DHT

Som en DHT med en superbruger.

What’s next for file transfers

Currently, the file transfer algorithm is based on a TURN connection (See Fileroverførsel). 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)

Ressourcer