স্যাম
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.
কোন কেন্দ্রীয় কর্তৃপক্ষ নেই, কোন সার্ভারে নির্ভর করতে পারবে না।
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.
মূল ধারণা হলো অংশগ্রহণকারীদের সাথে একটি সিঙ্ক্রোনাইজড মের্কল গাছ তৈরি করা।
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).
চিত্রনাট্য
একটি সমষ্টি তৈরি করুন
বব নতুন একটা ঘোড়া তৈরি করতে চায়
Bob creates a local Git repository.
তারপর, তিনি নিম্নলিখিত সঙ্গে একটি প্রথম স্বাক্ষরিত প্রতিশ্রুতি তৈরিঃ
/adminsএর পাবলিক কীতার ডিভাইস সার্টিফিকেট ̀ / ডিভাইস ]]
তার CRL ̀ /crls`
প্রথম কমেন্টের হ্যাশটি কথোপকথনের আইডি হয়ে যায়
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.
কাউকে যোগ করা
Bob adds Alice
Bob adds Alice to the repo:
/invitedতে আমন্ত্রিত ইউআরআই যোগ করে/crlsতে সিআরএল যোগ করা হয়েছে
Bob sends a request on the DHT.
আমন্ত্রণ গ্রহণ
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
/inviteddirectory, then adds her certificate to the/membersdirectoryOnce 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.
বার্তা পাঠানো
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).
নোট
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.
বার্তা গ্রহণ
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.
একটি প্রতিশ্রুতির বৈধতা
ব্যবহারকারীদের কিছু অপ্রয়োজনীয় কমিট (সমঝোতা, মিথ্যা বার্তা ইত্যাদি সহ) চাপানো এড়াতে, প্রতিটি কমিট (প্রাচীনতম থেকে সর্বশেষতম) একটি দূরবর্তী শাখা একত্রিত করার আগে এইভাবে যাচাই করা আবশ্যকঃ
নোট
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
typefield. Handle eachtypeas 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
votevoteTypeis 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
memberIf
addsProperly 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
joinsProperly signed by the joining device.
Device certificate added under
/devices.Corresponding invite removed from
/invitedand certificate added to/members.No unexpected files are added or removed.
If
bannedVote is valid per the
voterules 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.
ডিভাইস নিষিদ্ধ
গুরুত্বপূর্ণ
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 are unable to be relied upon for ordering the ban events, as any device can forge or replay the 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 are unable to manipulate their certificate or commit timestamps to send unauthorized messages or falsify their expiration status.
অনুরূপ সিস্টেম (বিকৃত গ্রুপ সিস্টেম সহ) খুব বেশি নয়, তবে এগুলি কয়েকটি উদাহরণঃ
[mpOTR কাউকে নিষিদ্ধ করার উপায় নির্ধারণ করে না]
গ্রুপ চ্যাটের জন্য কোন কেন্দ্রীয় সার্ভার ছাড়া সিগন্যাল (এডিআইটিঃ তারা সম্প্রতি যে পয়েন্ট পরিবর্তন), একটি গ্রুপ থেকে কাউকে নিষিদ্ধ করার ক্ষমতা দেয় না।
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).
কথোপকথন থেকে ডিভাইস সরান
এই অংশটিই একমাত্র অংশ যা কথোপকথনের বিভক্ততা এড়াতে একমত হতে হবে, যেমন যদি দুই সদস্য কথোপকথন থেকে একে অপরকে ছুঁড়ে দেয়, তাহলে তৃতীয়টি কী দেখবে?
এটি প্রত্যাহার করা ডিভাইসগুলি সনাক্ত করতে বা কেবলমাত্র একটি পাবলিক রুমে অযাচিত ব্যক্তিদের উপস্থিত করা এড়াতে প্রয়োজন। সদস্য এবং ডিভাইসের মধ্যে প্রক্রিয়াটি বেশ অনুরূপঃ
আলিস ববকে সরিয়ে দেয়
গুরুত্বপূর্ণ
Alice MUST be an admin to vote.
প্রথমত, তিনি বব নিষিদ্ধ করার পক্ষে ভোট দেন। এটি করার জন্য, তিনি ফাইলটি /votes/ban/members/uri_bob/uri_alice (অর্থাত্ সদস্যদের ডিভাইসের জন্য ডিভাইস দ্বারা প্রতিস্থাপন করা যেতে পারে, অথবা আমন্ত্রণের জন্য আমন্ত্রিত বা অ্যাডমিনদের জন্য অ্যাডমিন) এবং প্রতিশ্রুতিবদ্ধ
তারপরে তিনি ভোটের সমাধান হয়েছে কিনা তা পরীক্ষা করেন। এর অর্থ হল যে প্রশাসকদের 50% বা তার বেশি ববকে নিষিদ্ধ করার জন্য সম্মত হন (যদি তিনি একা থাকেন, তবে এটি নিশ্চিত যে এটি 50% এরও বেশি) ।
যদি ভোটটি সমাধান হয়, তাহলে /votes/ban ফাইলগুলি সরানো যেতে পারে, /members, /admins, /invited, /CRLs, /devices এর সমস্ত ফাইলগুলি সরানো যেতে পারে (বা কেবলমাত্র /devices যদি এটি একটি নিষিদ্ধ ডিভাইস হয়) এবং বব এর শংসাপত্রটি /banned/members/bob_uri.crt (বা /banned/devices/uri.crt যদি কোনও ডিভাইস নিষিদ্ধ হয়) এবং repo এ জমা দেওয়া যেতে পারে
তারপর, অ্যালিস অন্যান্য ব্যবহারকারীদের (বব এর বাইরে) অবহিত
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
তারপরে তিনি ভোটের সমাধান হয়েছে কিনা তা পরীক্ষা করেন। এর অর্থ হল যে প্রশাসকদের 50% বা তার বেশি ববকে নিষিদ্ধ করার জন্য সম্মত হন (যদি তিনি একা থাকেন, তবে এটি নিশ্চিত যে এটি 50% এরও বেশি) ।
যদি ভোট সমাধান হয়, ফাইলগুলি /ভোট / আনব্যানে সরানো যেতে পারে, সমস্ত ফাইলগুলি / সদস্য, / অ্যাডমিন, / আমন্ত্রিত, / সিআরএলগুলিতে বব, পুনরায় যোগ করা যেতে পারে (বা কেবলমাত্র / ডিভাইসে যদি এটি একটি ডিভাইস হয় যা নিষিদ্ধ নয়) এবং রিপোতে প্রতিশ্রুতিবদ্ধ করা যেতে পারে
কথোপকথন মুছে ফেলুন
convInfos remove=time::now() (যেমন removeContact সংরক্ষণ করে পরিচিতিতে) সংরক্ষণ করুন যে কথোপকথনটি সরানো হয় এবং অন্য ব্যবহারকারীর ডিভাইসের সাথে সিঙ্ক করা হয়
এখন, যদি এই কথোপকথনের জন্য নতুন কমিটমেন্ট পাওয়া যায় তাহলে তা উপেক্ষা করা হয়
এখন, যদি জামি স্টার্টআপ এবং রিপো এখনও উপস্থিত থাকে, কথোপকথন ক্লায়েন্টদের ঘোষণা করা হয় না
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.
যখন আমরা নিশ্চিত যে কেউ সিঙ্ক করা হয়েছে, মুছে ফেলুন মুছে ফেলা=time::now() এবং অন্যান্য ব্যবহারকারীর ডিভাইস সঙ্গে সিঙ্ক
ব্যবহারকারীর মালিকানাধীন সমস্ত ডিভাইস এখন রিপোজিটরি এবং সম্পর্কিত ফাইল মুছে ফেলতে পারে
মোড কিভাবে নির্দিষ্ট করবেন
মোডগুলি সময়ের সাথে পরিবর্তন করা যায় না। অথবা এটি অন্য একটি কথোপকথন। সুতরাং, এই তথ্যটি প্রাথমিক কমিট বার্তায় সংরক্ষণ করা হয়। কমিট বার্তাটি নিম্নরূপ হবেঃ
{
"type": "initial",
"mode": 0,
}
এখন, "মোড" মান গ্রহণ 0 (ONE_TO_ONE), 1 (ADMIN_INVITES_ONLY), 2 (INVITES_ONLY), 3 (পাবলিক)
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 are unable to be ignored:
প্রক্রিয়াটি এখনও একই, একটি অ্যাকাউন্ট addContact এর মাধ্যমে একটি যোগাযোগ যুক্ত করতে পারে, তারপর DHT এর মাধ্যমে একটি TrustRequest পাঠাতে পারে। কিন্তু দুটি পরিবর্তন প্রয়োজনঃ
TrustRequest একটি "conversationId" এম্বেড করে যা প্রতিযোগীকে অনুরোধ গ্রহণের সময় কোন কথোপকথন ক্লোন করতে হবে তা জানায়
TrustRequest পুনরায় চেষ্টা করা হয় যখন যোগাযোগ ফিরে আসে অনলাইন. এটি আজ নয় (আমরা যদি প্রতিযোগী প্রথমটি ফেলে দেয় তবে আমরা একটি নতুন TrustRequest তৈরি করতে চাই না) সুতরাং, যদি কোনও অ্যাকাউন্ট একটি বিশ্বাস অনুরোধ গ্রহণ করে তবে এটি স্বয়ংক্রিয়ভাবে উপেক্ষা করা হবে যদি সম্পর্কিত কথোপকথন সহ অনুরোধটি প্রত্যাখ্যান করা হয় (যেমন convRequests সিঙ্ক করা হয়)
তারপর, যখন একজন যোগাযোগকারী অনুরোধটি গ্রহণ করে, তখন একটি সিঙ্কিং সময়কাল প্রয়োজন, কারণ যোগাযোগকারীকে এখন কথোপকথনটি ক্লোন করতে হবে।
removeContact() যোগাযোগ এবং সম্পর্কিত 1: 1 কথোপকথন সরিয়ে ফেলবে (একই প্রক্রিয়া দিয়ে "একটি কথোপকথন সরান") এখানে একমাত্র নোট হল যে যদি আমরা একটি যোগাযোগ নিষিদ্ধ করি, আমরা সিঙ্ক করার জন্য অপেক্ষা করি না, আমরা কেবল সম্পর্কিত সমস্ত ফাইল সরিয়ে ফেলি।
জটিল পরিস্থিতি
কিছু ক্ষেত্রে, দুটি কথোপকথন তৈরি করা যায়। এই দুটি দৃশ্যের মধ্যে অন্তত দুটিঃ
Alice adds Bob.
Bob accepts.
Alice removes Bob.
Alice adds Bob.
অথবা
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)).
গুরুত্বপূর্ণ
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() যদি সিঙ্ক হয় তবে {{"সমন্বয়": "সত্য"}} ফেরত দেবে।
ConfigurationManager::getConversationMembers() will return a map of two URIs (the current account and the peer who sent the request).
আলোচনা নির্দিষ্টকরণ চাইছে
কথোপকথন অনুরোধগুলি ** মানচিত্র < স্ট্রিং, স্ট্রিং>** এর মাধ্যমে নিম্নলিখিত কীগুলির সাথে প্রতিনিধিত্ব করা হয়ঃ
id: the conversation ID
from: URI of the sender
প্রাপ্তিঃ সময়সীমা
শিরোনামঃ কথোপকথনের নাম (ঐচ্ছিক)
বর্ণনাঃ (ঐচ্ছিক)
avatar: (optional) the profile picture
কথোপকথনের প্রোফাইল সিঙ্ক্রোনাইজেশন
একটি কথোপকথন সনাক্তযোগ্য হওয়ার জন্য সাধারণত একটি শিরোনাম (উদাহরণস্বরূপ, জামি), একটি বর্ণনা (উদাহরণস্বরূপঃ কিছু লিঙ্ক, প্রকল্পটি কী, ইত্যাদি) এবং একটি চিত্র (প্রকল্পের লোগো) এর মতো কিছু মেটাডেটা প্রয়োজন। এই মেটাডেটাগুলি ঐচ্ছিক তবে সমস্ত সদস্যের মধ্যে ভাগ করা হয়, তাই অনুরোধগুলিতে সিঙ্ক করা এবং অন্তর্ভুক্ত করা দরকার।
সংগ্রহস্থলে সঞ্চয়
কথোপকথনের প্রোফাইলটি মূল (/profile.vcf) এর মতো একটি ক্লাসিক vCard ফাইলে সংরক্ষণ করা হয়ঃ
BEGIN:VCARD
VERSION:2.1
FN:TITLE
DESCRIPTION:DESC
END:VCARD
সিঙ্ক্রোনাইজেশন
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).
সর্বশেষ প্রদর্শিত
সিঙ্ক্রোনাইজড ডেটাতে, প্রতিটি ডিভাইস অন্যান্য ডিভাইসে কথোপকথনের অবস্থা প্রেরণ করে। এই অবস্থায়, শেষ প্রদর্শিত হয়। তবে, যেহেতু প্রতিটি ডিভাইসের প্রতিটি কথোপকথনের জন্য নিজস্ব অবস্থা থাকতে পারে এবং সম্ভবত একই শেষ কমিট না করেই কোনও সময়ে, বিবেচনায় নেওয়া উচিত বেশ কয়েকটি পরিস্থিতিঃ
৫টি পরিস্থিতির জন্য সমর্থন রয়েছেঃ
যদি অন্য ডিভাইসের দ্বারা পাঠানো শেষ প্রদর্শন বর্তমানের মতো হয়, তাহলে কিছুই করা যায় না।
যদি বর্তমান ডিভাইসের জন্য শেষ প্রদর্শিত হয় না, তাহলে রিমোট প্রদর্শিত বার্তা ব্যবহার করা হয়।
যদি রিমোটটি সর্বশেষ প্রদর্শিত হয় তবে রিপোতে উপস্থিত না থাকে, এর অর্থ হল যে কমাইটটি পরে নেওয়া হবে, তাই ফলাফলটি ক্যাশে করা হবে
যদি রিমোটটি ইতিমধ্যে আনা হয়, আমরা এটি প্রতিস্থাপন করার জন্য ইতিহাসের মধ্যে সর্বশেষ প্রদর্শিত স্থানীয়টি আগে কিনা তা পরীক্ষা করি
অবশেষে যদি একই লেখক থেকে একটি বার্তা ঘোষণা করা হয়, এর অর্থ হল যে আমাদের সর্বশেষ প্রদর্শিত বার্তাটি আপডেট করতে হবে।
পছন্দসমূহ
প্রতিটি কথোপকথনে ব্যবহারকারীর দ্বারা সেট করা পছন্দগুলি সংযুক্ত করা হয়। সেই পছন্দগুলি ব্যবহারকারীর ডিভাইস জুড়ে সিঙ্ক করা হয়। এটি কথোপকথনের রঙ হতে পারে, যদি ব্যবহারকারী বিজ্ঞপ্তিগুলি উপেক্ষা করতে চান, ফাইল স্থানান্তর আকারের সীমা ইত্যাদি ইত্যাদি। এখন পর্যন্ত, স্বীকৃত কীগুলি হ'লঃ
"color" - the color of the conversation (#RRGGBB format)
"অজ্ঞাত বিজ্ঞপ্তি" - এই কথোপকথনে নতুন বার্তাগুলির বিজ্ঞপ্তিগুলি উপেক্ষা করতে
"চিম্কল" - একটি ডিফল্ট ইমোজি সংজ্ঞায়িত করতে.
এই পছন্দগুলি MapStringString প্যাকেটে সংরক্ষণ করা হয়, accountDir/conversation_data/conversationId/preferences এ সংরক্ষণ করা হয় এবং শুধুমাত্র SyncMsg এর মাধ্যমে একই ব্যবহারকারীর ডিভাইসগুলিতে প্রেরণ করা হয়।
পছন্দগুলির সাথে ইন্টারঅ্যাক্ট করার জন্য API হলঃ
// 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*/);
};
মার্জ সংঘাত ব্যবস্থাপনা
যেহেতু দুটি প্রশাসক একই সময়ে বর্ণনা পরিবর্তন করতে পারে, তাই profile.vcf এ একত্রিতকরণের দ্বন্দ্ব ঘটতে পারে। এই ক্ষেত্রে, উচ্চ হ্যাশ সহ কমিশনটি নির্বাচিত হবে (উদাহরণস্বরূপ ffffff > 000000) ।
এপিআই
ব্যবহারকারী 2 পদ্ধতিতে কথোপকথনের মেটাডেটা পেতে এবং সেট করতে পারেনঃ
<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>
যেখানে infos হল map<str, str> নিম্নলিখিত কী সহঃ
মোডঃ শুধুমাত্র পাঠযোগ্য
শিরোনাম
বর্ণনা
avatar: the profile picture
অ্যাকাউন্ট পুনরায় আমদানি করা (লিঙ্ক/বিক্রয়)
সংরক্ষণাগারটি পুনরায় আমদানির পরে নতুন কমিটগুলিতে কথোপকথন পুনরুদ্ধার করতে সক্ষম হওয়ার জন্য কথোপকথন আইডি থাকতে হবে (কারণ এই মুহুর্তে কোনও আমন্ত্রণ নেই) যদি কোনও কথোপকথনের জন্য একটি কমিট আসে তবে দুটি সম্ভাবনা রয়েছেঃ
কথোপকথনটি আছে, এই ক্ষেত্রে, ডেমোন এই কথোপকথনটি পুনরায় ক্লোন করতে সক্ষম
কথোপকথনId অনুপস্থিত, তাই ডেমোনটি (বার্তা
{{"অ্যাপ্লিকেশন/আমন্ত্রণ", কথোপকথনId}}) একটি নতুন আমন্ত্রণ জিজ্ঞাসা করে যা ব্যবহারকারীকে (পুনরায়) গ্রহণ করতে হবে
গুরুত্বপূর্ণ
A conversation can only be retrieved if a contact or another device is there, else it will be lost. There is no magic.
ব্যবহৃত প্রোটোকল
গিট
কেন এই পছন্দ
Each conversation will be a Git repository. This choice is motivated by:
আমরা বার্তা সিঙ্ক এবং অর্ডার করতে হবে. Merkle গাছ এটি করার জন্য নিখুঁত কাঠামো এবং শাখা মার্জিং দ্বারা লাইনীভূত করা যেতে পারে. উপরন্তু, এটি ব্যাপকভাবে Git দ্বারা ব্যবহৃত হয়, এটা ডিভাইস মধ্যে সিঙ্ক করা সহজ.
প্রকৃতি দ্বারা বিতরণ করা, ব্যাপকভাবে ব্যবহৃত, অনেক ব্যাক-এন্ড এবং প্লাগযোগ্য।
হুক এবং ব্যাপকভাবে ব্যবহৃত ক্রিপ্টো মাধ্যমে প্রতিশ্রুতি যাচাই করতে পারেন
প্রয়োজন হলে ডাটাবেসে সংরক্ষণ করা যাবে
ফাইল নয়, কমিট মেসেজ ব্যবহার করে দ্বন্দ্ব এড়ানো যায়।
যা আমাদের যাচাই করতে হবে
পারফরম্যান্স?
git.lockকম হতে পারেlibgit2 এর হুকস
একই সময়ে একাধিক টান?
সীমা
ইতিহাস মুছে ফেলা যাবে না। একটি কথোপকথন মুছে ফেলার জন্য, ডিভাইসটি কথোপকথনটি ছেড়ে অন্য একটি তৈরি করতে হবে।
তবে অস্থায়ী বার্তা (যেমন বার্তা যা কয়েক মিনিটের জন্য কেবল পাঠ্যযোগ্য) একটি বিশেষ বার্তা মাধ্যমে ডিআরটি (যেমন টাইপিং বা পড়ুন বিজ্ঞপ্তি) মাধ্যমে পাঠানো যেতে পারে।
কাঠামো
/
- 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
ফাইল স্থানান্তর
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.
প্রোটোকল
প্রেরক নিম্নলিখিত ফরম্যাটে কথোপকথনে একটি নতুন কমিট যোগ করেঃ
value["tid"] = "RANDOMID";
value["displayName"] = "DISPLAYNAME";
value["totalSize"] = "SIZE OF THE FILE";
value["sha3sum"] = "SHA3SUM OF THE FILE";
value["type"] = "application/data-transfer+json";
এবং ${data_path}/conversation_data/${conversation_id}/${file_id} যেখানে file_id=${commitid}_${value["টাইড"]}.${extension}
তারপর, প্রাপক এখন ফাইলটি ডাউনলোড করতে পারেন name="data-transfer://" + conversationId + "/" + currentDeviceId() + "/" + fileId এবং ${data_path}/conversation_data/${conversation_id}/waiting এ ফাইলটি অপেক্ষা করছে এমন তথ্য সংরক্ষণ করে
সংযোগটি গ্রহণকারী ডিভাইসটি ফাইলটি প্রেরণ করা যায় কিনা তা যাচাই করে চ্যানেলটি গ্রহণ করবে (যদি sha3sum সঠিক এবং ফাইলটি বিদ্যমান কিনা) । প্রাপক প্রথম খোলা চ্যানেলটি রাখবে, অন্যগুলি বন্ধ করবে এবং প্রেরকের মতো একই পথের সাথে একটি ফাইলে লিখবে ( ${data_path}/conversation_data/${conversation_id}/${file_id}) সমস্ত আগত ডেটা।
যখন স্থানান্তর শেষ হয় বা চ্যানেলটি বন্ধ হয়ে যায়, তখন ফাইলটি সঠিক কিনা তা যাচাই করার জন্য sha3sum যাচাই করা হয় (অন্যথায় এটি মুছে ফেলা হয়) । যদি এটি বৈধ হয় তবে ফাইলটি অপেক্ষা থেকে সরানো হবে।
ব্যর্থতার ক্ষেত্রে, যখন কথোপকথনের একটি ডিভাইস আবার অনলাইনে থাকবে, আমরা একইভাবে সমস্ত অপেক্ষার ফাইলগুলি জিজ্ঞাসা করব।
Call in Swarm
ধারণা
A swarm conversation can have multiple rendez-vous. A rendez-vous is defined by the following URI:
"accountUri/deviceId/conversationId/confId" যেখানে accountUri/deviceId হোস্ট বর্ণনা করে।
হোস্ট দুটি উপায়ে নির্ধারণ করা যায়ঃ
In the swarm metadatas. Where it's stored like the title/desc/avatar (profile picture) of the room
অথবা প্রথম কলার।
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)
সুতরাং প্রতিটি অংশে কল শুরু হয়েছে বলে তথ্য পাবেন এবং কল করে এটিতে যোগ দিতে সক্ষম হবেন।
আক্রমণ?
Avoid Git bombs
নোট
একটি কমাইটের টাইমস্ট্যাম্প বিশ্বাসযোগ্য কারণ এটি সম্পাদনাযোগ্য। শুধুমাত্র ব্যবহারকারীর টাইমস্ট্যাম্প বিশ্বাসযোগ্য।
TLS
Git অপারেশন, কন্ট্রোল বার্তা, ফাইল, এবং অন্যান্য জিনিস শুধুমাত্র এনক্রিপশন যা PFS গ্যারান্টি ব্যবহার করে একটি p2p TLS v1.3 লিঙ্ক ব্যবহার করবে। তাই প্রতিটি নতুন সংযোগের জন্য প্রতিটি কী পুনরায় আলোচনা করা হয়।
DHT (UDP)
মোবাইলের জন্য বার্তা পাঠাতে (পশ বিজ্ঞপ্তি ট্রিগার করতে) এবং টিসিপি সংযোগ শুরু করতে ব্যবহৃত হয়।
নেটওয়ার্ক কার্যকলাপ
কাউকে আমন্ত্রণ জানানোর প্রক্রিয়া
আলিস ববকে আমন্ত্রণ জানাতে চায়:
আলিস কথোপকথনে ববকে যুক্ত করে
Alice generates an invite: { "application/invite+json" : { "conversationId": "$id", "members": [{...}] }}
বার্তা পাঠানোর জন্য দুটি সম্ভাবনা a. যদি সংযোগ না থাকে, DHT b. অন্যথায়, Alice SIP চ্যানেল পাঠায়
বব a এর জন্য দুটি সম্ভাবনা। আমন্ত্রণ গ্রহণ করে, ক্লায়েন্ট b এর জন্য একটি সংকেত প্রেরণ করা হয়। সংযুক্ত নয়, তাই কখনই অনুরোধটি গ্রহণ করবে না কারণ অ্যালিসকে জানতে হবে না বব কেবল অ্যালিসকে উপেক্ষা করেছেন বা ব্লক করেছেন কিনা। একমাত্র উপায় হল একটি নতুন বার্তার মাধ্যমে নতুন আমন্ত্রণ পুনরুদ্ধার করা (পরবর্তী দৃশ্যকল্প দেখুন)
কাউকে বার্তা পাঠানোর প্রক্রিয়া
আলিস ববকে একটা বার্তা পাঠাতে চায়:
অ্যালিস রিপোতে একটি বার্তা যোগ করে, একটি আইডি দেয়
অ্যালিস একটি বার্তা পায় (স্বয়ং থেকে) যদি সফল
দুটি সম্ভাবনা, অ্যালিস এবং বব সংযুক্ত বা না। উভয় ক্ষেত্রে একটি বার্তা তৈরি করা হয়ঃ { "অ্যাপ্লিকেশন/আইএম-জিটমেসেজ-আইডি" : "{"আইডি":"\( কনভিল্ড", "কমিট":"\) কমিটআইডি", "ডিভাইসআইডি": "$আলিস_ডিভাইস_হ্যাশ"}"}.
চারটি সম্ভাব্যতা ববঃ a. বব আলিসের সাথে সংযুক্ত নয়, সুতরাং যদি তিনি আলিসে বিশ্বাস করেন তবে একটি নতুন সংযোগের জন্য জিজ্ঞাসা করুন এবং বি-এ যান। যদি সংযুক্ত হন তবে আলিসের কাছ থেকে নতুন বার্তা আনুন এবং ঘোষণা করুন। বব সেই কথোপকথনটি জানেন না। DHT এর মাধ্যমে প্রথমে একটি আমন্ত্রণ পেতে জিজ্ঞাসা করুন যাতে সেই কথোপকথনটি গ্রহণ করতে সক্ষম হতে পারে ({"অ্যাপ্লিকেশন / আমন্ত্রণ", কথোপকথনId}) d. বব সংযোগ বিচ্ছিন্ন (কোন নেটওয়ার্ক নেই, বা কেবল বন্ধ) । তিনি নতুন বার্তা পাবেন না তবে পরবর্তী সংযোগটি যখন ঘটবে তখন সিঙ্ক করার চেষ্টা করবেন
বাস্তবায়ন
! [আর্কিটঃ স্ওয়ারম চ্যাট ক্লাস](ছবি/স্ওয়ারম চ্যাট-ক্লাস-আর্কিট.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"
}
কল
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"
}
**!! পুরোনো খসড়া!
নোট
Following notes are not organized yet. Just some line of thoughts.
ক্রিপ্টো উন্নতি।
একটি গুরুতর গ্রুপ চ্যাট বৈশিষ্ট্য জন্য, আমরা গুরুতর ক্রিপ্টো প্রয়োজন. বর্তমান নকশা সঙ্গে, যদি একটি সার্টিফিকেট একটি কথোপকথনের পূর্ববর্তী DHT মান হিসাবে চুরি করা হয়, কথোপকথন বিচ্ছিন্ন করা যেতে পারে. হয়তো আমরা ** ডাবল ratchet** মত কিছু যেতে হবে.
নোট
A lib might exist to implement group conversations.
ওপেনডিএইচটি-তে ইসিসি সমর্থন প্রয়োজন
ব্যবহার
রোল যোগ করা?
গ্রুপ চ্যাটের জন্য দুটি প্রধান ব্যবহারের ক্ষেত্রে রয়েছেঃ
একটি কোম্পানির মধ্যে একটি Mattermost এর মতো কিছু, ব্যক্তিগত চ্যানেল এবং কিছু ভূমিকা (অ্যাডমিন/দর্শক/বট/ইত্যাদি) বা শিক্ষার জন্য (যদি কেবল কয়েকজন সক্রিয় থাকে) ।
অনুভূমিক কথোপকথন বন্ধুদের মধ্যে কথোপকথনের মতো।
Jami will be for which one?
বাস্তবায়ন ধারণা
একটি গ্রুপের জন্য একটি শংসাপত্র যা ব্যবহারকারীকে একটি ভূমিকা জন্য একটি পতাকা দিয়ে স্বাক্ষর করে। যোগ বা প্রত্যাহার করাও করা যেতে পারে।
কথোপকথনে যোগ দিন
শুধুমাত্র সরাসরি আমন্ত্রণের মাধ্যমে
একটি লিঙ্ক/কিউআর কোড/যদি
রুমের নাম দিয়ে?
আমাদের যা দরকার
গোপনীয়তাঃ গ্রুপ চ্যাটের বাইরে থাকা সদস্যরা গ্রুপের বার্তাগুলি পড়তে পারবে না
গোপনীয়তাঃ যদি গ্রুপের কোন কী হুমকি হয়, তাহলে পূর্ববর্তী বার্তাগুলির গোপনীয়তা বজায় রাখা উচিত (যতটা সম্ভব)
বার্তা অর্ডার করাঃ বার্তাগুলি সঠিক ক্রমে থাকা দরকার
সিঙ্ক্রোনাইজেশনঃ যত তাড়াতাড়ি সম্ভব সমস্ত বার্তা পেতে নিশ্চিত হওয়াও প্রয়োজন।
ধারাবাহিকতাঃ আসলে, DHT-এ একটি বার্তা মাত্র 10 মিনিট স্থায়ী হয়। কারণ এটি এই ধরণের DHT-এর জন্য হিসাব করা সেরা সময়। ডেটা ধারাবাহিকতা করতে, নোডকে প্রতি 10 মিনিটে DHT-এর মান পুনরায় সেট করতে হবে। যখন নোডটি অফলাইন থাকে তখন এটি করার আরেকটি উপায় হ'ল নোডগুলিকে ডেটা পুনরায় সেট করতে দেওয়া। তবে, যদি 10 মিনিটের পরে, 8 টি নোড এখনও এখানে থাকে তবে তারা 64 টি অনুরোধ করবে (এবং এটি এক্সপোজেনশিয়াল) । এর জন্য স্প্যামিং এড়ানোর বর্তমান উপায়টি অনুসন্ধান করা হয়। এটি এখনও 64 টি অনুরোধ করবে তবে সর্বোচ্চ পুনর্নির্মাণ 8 টি নোডকে সীমাবদ্ধ করবে।
অন্যান্য বিতরণ পদ্ধতি
আইপিএফএসঃ কিছু তদন্তের প্রয়োজন
কিছু তদন্তের দরকার
Maidsafe: Need some investigation
বর্তমান কাজ অনুযায়ী আমাদের
গ্রুপ চ্যাট একই কাজ উপর ভিত্তি করে করা যেতে পারে যা আমরা ইতিমধ্যে মাল্টি ডিভাইসের জন্য আছে (কিন্তু এখানে, একটি গ্রুপ সার্টিফিকেট সঙ্গে) । সমাধানের জন্য সমস্যাঃ
এই ডাটাবেসকে ক্লায়েন্ট থেকে ডেমোনের মধ্যে স্থানান্তর করতে হবে।
কেউ যদি সংযুক্ত না হয়, তাহলে সিঙ্ক্রোনাইজেশন করা সম্ভব হবে না, এবং ব্যক্তি কখনোই কথোপকথন দেখতে পাবে না
আরেকটি ডেডিকেটেড ডিএইচটি
সুপার ইউজার দিয়ে ডিএইচটি-র মতো।
What's next for file transfers
Currently, the file transfer algorithm is based on a TURN connection (See ফাইল স্থানান্তর). 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)