گروه

Synospis

هدف این سند توصیف چگونگی اجرای چت های گروهی (به عنوان swarm chat) در Jami است.

یک swarm گروهی است که بدون هیچ مقام مرکزی می توانند به شیوه ای انعطاف پذیر بحث کنند. در واقع، اگر دو نفر هیچ ارتباطی با بقیه گروه ندارند (به عنوان مثال قطع اینترنت) اما می توانند با یکدیگر تماس بگیرند (به عنوان مثال در یک LAN یا در یک زیر شبکه) ، آنها قادر خواهند بود پیام ها را به یکدیگر ارسال کنند و سپس، وقتی ممکن است، قادر خواهند بود با بقیه گروه همغږي شوند.

پس، سوارم توسط:

  1. توانایی تقسیم و ادغام در پی اتصال

  2. هم زماني از تاريخ هر کسي بايد بتواند پيامي به کل گروه بفرستد

  3. هيچ مقام مركزي وجود نداره، نمي تونم به هيچ سروري اعتماد کنم

  4. عدم انکار. دستگاه ها باید بتوانند اعتبار پیام های قدیمی را تایید کنند و کل تاریخ را باز کنند.

  5. PFS در حمل و نقل.

ایده اصلی اینه که یک درخت مرکل هم وقت ساز با شرکت کنندگان داشته باشیم.

ما چهار حالت برای چت سور را شناسایی کردیم که می خواهیم اجرا کنیم:

  • ** ONE_TO_ONE**، اساساً پرونده ای که امروز داریم وقتی با یه دوست صحبت می کنی

  • ADMIN_INVITES_ONLY معمولا یک کلاس است که معلم می تواند مردم را دعوت کند، اما نه دانش آموزان

  • ** دعوت ميکنه فقط** يه گروه خصوصی از دوستان

  • ** عوامی** اساسا یک انجمن باز

سناریوهای

یک گروه را ایجاد کنید

بوب ميخواد يه دسته جديد بسازد

  1. باب يه مخزن موجودي محلی رو ميسازد

  2. بعد، او یک تعهد اولیه امضا می کند که شامل موارد زیر است:

    • کلید عمومی اش در /admins

    • گواهی دستگاهش در ̀ / دستگاه `

    • CRLش در ̀ /crls`

  3. هشتگ اولي که انجام ميده، به اسم "ID" صحبت مي کنه

  4. باب به دستگاه های دیگر خود اعلام می کند که او یک مکالمه جدید ایجاد می کند. این کار از طریق دعوت به پیوستن به سوره ای که از طریق DHT به دستگاه های دیگر مرتبط با آن حساب ارسال می شود انجام می شود.

اضافه کردن کسی

آليس"بوب" رو اضافه ميکنه

  1. آليس باب رو به بازيابي اضافه ميکنه:

    • اضافه کردن URI دعوت شده به /invited

    • اضافه کردن CRL به /crls

  2. آليس درخواستي در مورد DHT ارسال ميکنه

دعوت گرفتن

*آليس دعوت شده که به گروه "کريست" ملحق بشه *

  1. او دعوت را قبول می کند (اگر رد کند، کاری نکند، فقط در دعوت باقی می ماند و آلیس هرگز پیام دریافت نخواهد کرد)

  2. ارتباط همساني بين آليس و باب تموم شده

  3. آليس از "بوب" گزارش داده شده

  4. آليس تعهدات بوب رو تائيد ميکنه

  5. برای تأیید اینکه آلیس عضو است، او دعوت را از دایرکتوری /invited حذف می کند، سپس گواهی خود را به دایرکتوری /members اضافه می کند

  6. هنگامی که همه تعهدات تایید شده و در دستگاه خود، اعضای دیگر گروه توسط آلیس کشف می شوند. با این همسالان، او DRT را با باب به عنوان یک بوترپ ساخت (که در زیر توضیح داده شده است).

ارسال پيام

آليس پيام مي فرستد

ارسال پيام بسيار ساده است. آليس پيام پيامك را به شکل زیر مي نويسد:

فورمات TODO مشخص نیست

و دستگاه خود را و CRL را به مخزن اضافه می کند اگر از دست رفته باشد (دیگر ها باید بتوانند کمیت را تأیید کنند). درگیری های ادغام اجتناب می شود زیرا ما عمدتا بر پیام های کمیت مبتنی هستیم، نه فایل ها (مگر اینکه گواهینامه های CRLS + اما آنها موجود باشند). سپس او از طریق DRT با یک پیام سرویس اعلام می کند (بیمار بعدا) و DHT را برای دستگاه های تلفن همراه (آن ها باید اطلاعیه ای را دریافت کنند).

برای پیینگ کردن دستگاه های دیگر، فرستنده به سایر اعضای یک پیام SIP با mimetype = "app/im-gitmessage-id" حاوی یک JSON با "deviceId" که پیام را ارسال می کند، "id" مکالمه مرتبط، و "commit" ارسال می کند

دریافت یک پیام

بوب پيام از آليس رو دریافت ميکنه

  1. باب يه جفت از "آليس" بکشه

  2. تعهدات باید از طریق یک هک تایید شوند

  3. اگر همه کمیت ها معتبر باشند، کمیت ها ذخیره و نمایش داده می شوند. سپس * باب * پیام را از طریق DRT برای دستگاه های دیگر اعلام می کند.

  4. اگر همه تعهدات درست نباشند، pull رد می شود. آلیس باید حالتش را به حالت درست بازگرداند. تودو

اعتبارگذاری تعهد

برای جلوگیری از اینکه کاربران برخی از تعهدات ناخواسته را (با تعارضات، پیام های غلط و غیره) فشار دهند، این گونه هر تعهد (از قدیمی ترین تا جدیدترین) باید قبل از ادغام شاخه های دور از خود تأیید شود:

توجه: اگر اعتبارنامه ناکام باشد، جمع آوری نادیده گرفته می شود و ما شاخه را ترکیب نمی کنیم (و داده ها را حذف می کنیم) و کاربر باید اطلاع داده شود توجه2: اگر جمع آوری بیش از حد بزرگ باشد، انجام نشده است (TODO)

  • برای هر تعهد، بررسی کنید که دستگاه که سعی می کند ارسال تعهد را در این لحظه مجاز کند و گواهینامه ها در دسترس باشند (در دستگاه های دستگاه و در اعضای یا مدیران صادر کننده).

  • 3 مورد. کمیت 2 پدر و مادر دارد، پس این یک ادغام است، چیزی بیشتر برای تایید اینجا

  • تعهد صفر پدر و مادر دارد، تعهد اولیه است:

    • چک کنید که تاییدیه ی مدیر اضافه شده است

    • چک کنید که دستگاه تصدیق شده است

    • اضافه شده CRL ها را چک کنید

    • چک کنید که هیچ فایل دیگری اضافه نشده است

  • پیام commit دارای یک والدین است، پیام commit یک JSON با یک نوع است:

    • اگر متن (یا دیگر نوع mime که فایل ها را تغییر نمی دهد)

      • امضای چک از گواهی در ریپو

      • چک کنید که هیچ فایل عجیب و غریب خارج از دستگاه تایید شده و یا حذف شده است

    • اگه رأی بدم

      • بررسی کنید که voteType پشتیبانی شده است (منع، غیرمنع)

      • چک کنید که رای کاربر که قرارداد را امضا می کند

      • چک کنید که رای دادن از یک مدیر و دستگاه موجود و ممنوع نیست

      • چک کنید که هیچ فایل عجیب اضافه شده و یا حذف شده است

    • اگر عضو

      • اگر اضافه شود

        • چک کنید که تعهد به درستی امضا شده است

        • بررسی کنید که گواهی در / دعوت شده اضافه شده است

        • چک کنید که هیچ فایل عجیب اضافه شده و یا حذف شده است

        • اگر ONE_TO_ONE، بررسی کنید که ما فقط یک مدیر، یک عضو داریم

        • اگر ADMIN_INVITES_ONLY، بررسی کنید که دعوت از یک مدیر است

      • اگر همگام

        • چک کنید که تعهد به درستی امضا شده است

        • چک کنید که دستگاه اضافه شده است

        • بررسی کنید که دعوت به اعضای منتقل شده است

        • چک کنید که هیچ فایل عجیب اضافه شده و یا حذف شده است

      • اگر ممنوع باشد

        • چک کن که رأی درست است

        • بررسی کنید که آیا کاربر از طریق یک مدیر ممنوع است

        • بررسی کنید که گواهی عضو یا دستگاه به ممنوع منتقل شده است

        • بررسی کنید که فقط پرونده های مربوط به رای گیری حذف شده است

        • چک کنید که هیچ فایل عجیب اضافه شده و یا حذف شده است

    • به کاربر اطلاع دهید که ممکن است با یک نسخه قدیمی باشد یا آن همتایان سعی کرده اند به ارسال پیام های نامطلوب

دستگاه رو ممنوع کن

"آليس، باب، کارلا، دنيس" در دسته اي هستن

این یکی از سخت ترین سناریوهای ما است.

  1. زمان بندی تعهدات ایجاد شده

  2. در این حالت اگر چندین دستگاه ادمین وجود داشته باشد و آلیس می تواند با باب صحبت کند اما نه دنیس و کارلا؛ کارلا می تواند با دنیس صحبت کند؛ دنیس آلیس را ممنوع می کند، آلیس دنیس را ممنوع می کند، چه وضعیت زمانی خواهد بود که 4 عضو مکالمه را ترکیب کنند.

  3. یک دستگاه می تواند در معرض خطر قرار گیرد، دزدیده شود یا گواهی اش به پایان برسد. ما باید قادر باشیم یک دستگاه را ممنوع کنیم و از دروغ گفتن در مورد انقضاء آن یا ارسال پیام ها در گذشته (با تغییر گواهی یا زمان مهر تعهدش) جلوگیری کنیم.

سیستم های مشابه (با سیستم های گروه توزیع شده) زیاد نیستند، اما اینها چند مثال هستند:

  • [mpOTR نمی داند چگونه به شخص ممنوعیت]

  • سیگنال، بدون هیچ سرور مرکزی برای چت گروهی (EDIT: اخیراً این نکته را تغییر داده اند) ، توانایی ممنوعیت کسی از یک گروه را نمی دهد.

این سیستم رای دادن به یک اقدام انسانی برای ممنوعیت شخص نیاز دارد یا باید بر اساس اطلاعات CRL از مخزن (چون ما نمی توانیم به CRL های خارجی اعتماد کنیم)

دستگاهی را از مکالمه حذف کنید

اين تنها بخشيه که بايد توافق داشته باشيم تا از تفرقه ي مکالمه اجتناب کنيم مثل اين که اگر دو عضو از مکالمه همديگه رو رد کنن، چه چيزي به سومين نفر مياد؟

این برای تشخیص دستگاه های منسوخ شده یا به سادگی جلوگیری از حضور افراد ناخواسته در یک اتاق عمومی مورد نیاز است. این فرآیند بین یک عضو و یک دستگاه بسیار مشابه است:

"آليس" باب رو از دست داد

توجه: آليس بايد ادميني باشد تا رأي دهد

  • اول، او برای ممنوعیت باب رای می دهد. برای انجام این کار، او فایل را در /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 اختصاص داده شود

  • بعد، آلیس کاربران دیگر را (به جز باب) اطلاع می دهد

*آليس (مدير) دوباره باب (عضو ممنوع) رو اضافه ميکنه

  • برای این کار، او فایل را در /votes/unban/members/uri_bob/uri_alice ایجاد می کند (متعلمان می توانند با دستگاه های یک دستگاه جایگزین شوند، یا برای دعوت ها یا مدیران برای مدیران دعوت شوند) و تعهدات را به اشتراک می گذارد.

  • بعد او بررسی می کند که آیا رای گیری حل شده است. این بدان معنی است که >50٪ از مدیران موافق به ممنوعیت باب هستند (اگر او تنها باشد، مطمئناً بیش از 50٪ است).

  • اگر رای گیری حل شود، فایل های داخل /votes/unban می توانند حذف شوند، تمام فایل های برای Bob در /members، /admins، /invited، /CRLs، می توانند دوباره اضافه شوند (یا فقط در /devices اگر دستگاهی است که ممنوع است) و به repo اختصاص داده می شود

مکالمه رو حذف کن

  1. ذخیره کردن در convInfos removed=time::now() (مانند حذفContact در تماس ها ذخیره می کند) که مکالمه حذف شده و با دستگاه های کاربر دیگر همگام است

  2. حالا اگه يه پيام جديد براي اين مکالمه به دست مياد اون نادیده گرفته ميشه

  3. حالا، اگه جامي شروع کرده و بازي بازي هنوز موجود باشه، اين مکالمه به مشتريان اعلام نمي شه

  4. دو مورد: a. اگر هیچ عضو دیگری در مکالمه وجود نداشته باشد ما می توانیم ذخیره را بلافاصله حذف کنیم b. اگر هنوز اعضای دیگر هستند، تعهد کنید که ما مکالمه را ترک کنیم و اکنون منتظر باشید تا حداقل دستگاه دیگری این پیام را همبستگی کند. این از این واقعیت جلوگیری می کند که اعضای دیگر هنوز کاربر را به عنوان یک عضو معتبر تشخیص می دهند و هنوز اطلاعیه های پیام جدید را ارسال می کنند.

  5. وقتی مطمئن هستیم که کسی هم وقت سازی شده است، حذف حذف شده=زمان::حالا() و هم وقت سازی با دستگاه های کاربر دیگر

  6. تمام دستگاه های متعلق به کاربر اکنون می توانند مخزن و فایل های مرتبط را پاک کنند

نحوه مشخص کردن حالت

در زمان نمی توان حالت را تغییر داد. یا این یک مکالمه دیگر است. بنابراین، این داده ها در پیام شروعاتی ذخیره می شوند. پیام شروعاتی به انجام این کار خواهد بود:

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

در حال حاضر، "موډ" مقادیر 0 (ONE_TO_ONE) ، 1 (ADMIN_INVITES_ONLY) ، 2 (INVITES_ONLY) ، 3 (PUBLIC) را پذیرفته است

فرآیند برای سورهای 1:1

هدف اینجا حفظ API قدیمی (addContact/removeContact، sendTrustRequest/acceptTrustRequest/discardTrustRequest) برای تولید سوار با یک همتایان و تماس آن است. این هنوز هم شامل برخی از تغییرات است که ما نمی توانیم نادیده بگیریم:

فرآیند هنوز همان است، یک حساب می تواند یک تماس را از طریق addContact اضافه کند، سپس یک درخواست اعتماد را از طریق DHT ارسال کند. اما دو تغییر ضروری است:

  1. TrustRequest یک "گوششId" را برای اطلاع دادن به همسال که چه مکالمه ای را برای کلان کردن در هنگام پذیرش درخواست

  2. TrustRequest زمانی که تماس به اینترنت باز می گردد دوباره آزمایش می شود. این امروز مورد نیست (چون ما نمی خواهیم یک TrustRequest جدید ایجاد کنیم اگر همتایان اولین مورد را رد کنند). بنابراین، اگر یک حساب درخواست اعتماد را دریافت کند، اگر درخواست با یک مکالمه مرتبط رد شود، به طور خودکار نادیده گرفته می شود (چون convRequests هم وقت ساز می شود)

سپس، وقتی یک تماس درخواست را قبول می کند، یک دوره همگام سازی لازم است، زیرا تماس اکنون نیاز به کلون مکالمه دارد.

حذف کنتاکت (Contact) تماس و مکالمات مربوطه 1:1 را حذف می کند (با همان فرآیند "کابراتوار را حذف کنید"). تنها نکته اینجا این است که اگر یک تماس را ممنوع کنیم، منتظر همگام سازی نیستیم، فقط تمام فایل های مرتبط را حذف می کنیم.

سناریوهای پیچیده

در بعضی موارد می توان دو مکالمه ایجاد کرد. این حداقل دو مورد از این سناریو ها است:

  1. آليس باب رو اضافه ميکنه

  2. باب قبول کرد

  3. آليس باب رو از دست داد

  4. آليس باب رو اضافه ميکنه

یا

1، آلیس اضافه می کند باب و باب اضافه می کند آلیس در همان زمان، اما هر دو با هم متصل نیستند

در این مورد، دو مکالمه تولید می شود. ما نمی خواهیم پیام ها را از کاربران حذف کنیم یا یک مکالمه را در اینجا انتخاب کنیم. بنابراین، گاهی اوقات دو سور 1:1 بین اعضای مشابه نشان داده می شود. این باعث ایجاد برخی اشکال در طول زمان انتقال می شود (چون ما نمی خواهیم API را شکسته، مکالمه نتیجه گیری شده یکی از دو مکالمه نشان داده می شود، اما برای حال "ok-ish" است، زمانی که مشتریان به طور کامل مکالمه ID را برای تمام API ها (دعوات، انتقال فایل ها، و غیره) اداره کنند، اصلاح خواهد شد).

يادداشت در هنگام همگام سازی

پس از پذیرش درخواست مکالمه، زمانی وجود دارد که دیمون نیاز به بازیافت مخزن دور دارد. در طول این زمان، مشتریان باید یک نمای همگام سازی را برای ارائه اطلاعات به کاربر نشان دهند. توجه داشته باشید، در هنگام همگام سازی:

  • ConfigurationManager::getConversations() حتی در هنگام همگام سازی، آدرس مکالمه را بازمی گرداند

  • ConfigurationManager::conversationInfos() اگر هم وقت سازی شود {{"موافق سازی": "واقعی"}} را بازمی گرداند.

  • ConfigurationManager::getConversationMembers() یک نقشه دو URI (حساب جاری و همتایان که درخواست را ارسال کرده اند) را بازگردانده است

گفتگوها درخواست مشخصه

درخواست های مکالمه با Map<String, String> با کلید های زیر نمایش داده می شوند:

  • ID: ID مکالمه

  • از: uri فرستنده

  • دریافت: زمان

  • عنوان: (اختيار) نام مکالمه

  • توضیحات: (اختیاری)

  • آواتار: (اختیاری)

همگام سازی پروفایل مکالمه

برای شناسایی، مکالمه به طور کلی به برخی از متاداتا نیاز دارد، مانند عنوان (به عنوان مثال: Jami) ، توصیف (به عنوان مثال: برخی از لینک ها، پروژه چیست و غیره) و یک تصویر (لوگو پروژه). این متاداتا اختیاری است اما در میان همه اعضای به اشتراک گذاشته می شود، بنابراین باید هماهنگ و در درخواست ها گنجانده شود.

ذخیره سازی در مخزن

پروفایل مکالمه در یک فایل vCard کلاسیک در ریشه (/profile.vcf) ذخیره می شود مانند:

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

هم زمان سازی

برای بروزرسانی vCard، کاربر با مجوزهای کافی (به طور پیش فرض: =ADMIN) باید /profile.vcf. را ویرایش کند و فایل را با mimetype application/update-profile. پیام جدید از طریق مکانیسم مشابه ارسال می شود و همه همتایان سیگنال MessageReceived را از دیمون دریافت می کنند. شاخه حذف می شود اگر commit شامل فایل های دیگر یا بیش از حد بزرگ باشد یا توسط یک عضو غیر مجاز انجام شود (به طور پیش فرض: <ADMIN).

آخرین نمایش

در داده های همگام سازی، هر دستگاه به دستگاه های دیگر وضعیت مکالمه را ارسال می کند. در این حالت، آخرین نمایش داده شده ارسال می شود. با این حال، از آنجا که هر دستگاه می تواند برای هر مکالمه وضعیت خاص خود را داشته باشد و احتمالا بدون همان تعهد آخر در برخی موارد، چندین سناریو وجود دارد که باید در نظر گرفته شود:

5 سناریو پشتیبانی می شود:

  • اگر آخرین نمایش داده شده توسط دستگاه های دیگر مشابه دستگاه فعلی باشد، کاری نیست.

  • اگر آخرین نمایش برای دستگاه فعلی وجود نداشته باشد، پیام نمایش در راه دور استفاده می شود.

  • اگر آخرین راه دور نمایش داده شده در repo وجود ندارد، این بدان معنی است که کمیت بعداً به دست می آید، بنابراین نتیجه را ذخیره کنید

  • اگر راه دور قبلاً به دست آمده باشد، ما بررسی می کنیم که آخرین نمایش محلی قبل از تاریخچه است تا جایگزین آن شود

  • در نهایت اگر یک پیام از همان نویسنده اعلام شود، این بدان معنی است که ما باید آخرین پیام نمایش داده شده را به روز کنیم.

اولویت ها

هر مکالمه دارای اولویت هایی است که توسط کاربر تنظیم شده است. این اولویت ها در سراسر دستگاه های کاربر همگام سازی می شوند. این می تواند رنگ مکالمه باشد، اگر کاربر می خواهد به اطلاعیه ها، محدودیت اندازه انتقال فایل ها و غیره نادیده بگیرد. برای حال، کلید های شناخته شده عبارتند از:

  • "color" - the color of the conversation (#RRGGBB format)

  • "ignoreNotifications" - برای نادیده گرفتن اطلاعیه های پیام های جدید در این مکالمه

  • "سمبول" - برای تعریف یک اموجی پیش فرض.

این اولویت ها در یک بسته 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 یک تضاد ادغام ایجاد شود. در این صورت، commit با hash بالاتر (به عنوان مثال ffffff > 000000) انتخاب می شود.

API ها

کاربر دو روش برای بدست آوردن و تنظیم متادتا مکالمه را دارد:

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

جایی که info یک map<str, str> با کلید های زیر است:

  • حالت: فقط برای خواندن

  • عنوان

  • توضیحات

  • اوتار

پروتکل های مورد استفاده

گیت

چرا اين انتخاب

هر مکالمه یک مخزن گیت خواهد بود. این انتخاب توسط:

  1. ما باید پیام ها را همگام سازی کنیم و ترتیب دهیم. درخت مرکل ساختار عالی برای انجام این کار است و می تواند با ادغام شاخه ها خطی شود. علاوه بر این، از آنجا که توسط Git به طور گسترده ای استفاده می شود، همگام سازی بین دستگاه ها آسان است.

  2. از طرف طبیعت پخش شده، به طور گسترده ای استفاده شده، پشت سرانه های زیادی و قابل وصل.

  3. می تواند از طریق هک ها و رمزنگاری های گسترده ای که استفاده می شود، تعهدات را تأیید کند

  4. در صورت لزوم می تواند در یک پایگاه داده ذخیره شود

  5. از طریق استفاده از پیام های متعهد، نه فایل ها از تعارض جلوگیری می شود.

آنچه که باید تایید کنیم

  • عملکرد؟ git.lock می تواند کم باشد

  • هک ها در libgit2

  • چند تا کشش همزمان؟

محدودیت ها

برای حذف مکالمه، دستگاه باید مکالمه را ترک کند و مکالمه دیگری ایجاد کند.

با این حال، پیام های غیر دائمی (مانند پیام هایی که فقط برای چند دقیقه قابل خواندن هستند) می توانند از طریق یک پیام ویژه از طریق DRT (مانند اطلاعیه تایپ یا خواندن) ارسال شوند.

ساختار

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

انتقال فایل

Swarm انتقال فایل را به طور گسترده ای تغییر می دهد. اکنون، تمام تاریخچه هم وقت سازی می شود، به همه دستگاه های در مکالمه اجازه می دهد تا فایل های قدیمی را به راحتی بازیابی کنند. این تغییرات به ما اجازه می دهد از منطق جایی که فرستنده فایل را در دستگاه های دیگر فشار داده است، از طریق تلاش برای اتصال به دستگاه های خود (این بد بود زیرا واقعاً در برابر تغییرات یا شکست های اتصال مقاومت نمی کرد و به یک آزمایش دستی نیاز داشت) به منطق جایی که فرستنده اجازه می دهد دستگاه های دیگر برای دانلود. علاوه بر این، هر دستگاهی که دارای فایل می تواند میزبان دستگاه های دیگر باشد، اجازه می دهد تا فایل ها را حتی اگر فرستنده در آنجا نباشد، بازیابی کند.

پروتکل

فرستنده یک تعهد جدید را در مکالمه با فرمت زیر اضافه می کند:

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["tid"]}.${extension}

سپس، گیرنده می تواند اکنون فایل ها را با تماس با دستگاه های میزبان فایل با باز کردن کانال با name="data-transfer://" + conversationId + "/" + currentDeviceId() + "/" + fileId دانلود کند و اطلاعات را که فایل در انتظار است در ${data_path}/conversation_data/${conversation_id}/waiting ذخیره کند

دستگاه دریافت کننده اتصال کانال را با تأیید اینکه آیا می توان فایل را ارسال کرد (اگر sha3sum درست است و اگر فایل وجود دارد) پذیرفته می شود. گیرنده اولین کانال باز شده را نگه می دارد، بقیه را می کند و در یک فایل می نویسد (با همان مسیر فرستنده: ${data_path}/conversation_data/${conversation_id}/${file_id}) تمام داده های وارد شده.

وقتی انتقال به پایان رسیده یا کانال بسته شده است، sha3sum برای تأیید اینکه فایل درست است (یا حذف شده است) تأیید می شود. اگر معتبر باشد، فایل از انتظار حذف می شود.

در صورت شکست، وقتی دستگاه مکالمه دوباره به کار می رود، از همه فایل های منتظر به همان روش درخواست می کنیم.

زنگ بزن

تمام: بخش نام سرور

ایده

یک مکالمه ی سور می تواند چندین ملاقات داشته باشد. یک ملاقات توسط uri های زیر تعریف می شود:

"accountUri/deviceId/conversationId/confId" جایی که accountUri/deviceId میزبان را توصیف می کند.

میزبان را می توان از طریق دو روش مشخص کرد:

  • در ميتا اطلاعات سوره اي که مثل عنوان / ميز / اوتار اتاق ذخیره شده

  • یا اولین تماس گیرنده

در هنگام شروع تماس، میزبان یک تعهد جدید را به سور اضافه می کند، با URI برای پیوستن (accountUri/deviceId/conversationId/confId). این تا پایان تماس معتبر خواهد بود (به وسیله یک تعهد با مدت زمان نشان داده می شود)

بنابراین هر بخش اطلاعات را دریافت می کند که تماس شروع شده است و می تواند با تماس با آن به آن پیوسته شود.

حمله؟

  • از بمب های گیت اجتناب کنید

یادداشت ها

زمان بندی یک کامیت قابل اعتماد است چون قابل ویرایش است. تنها زمان بندی کاربر قابل اعتماد است.

TLS

عملیات Git، پیام های کنترل، فایل ها و چیزهای دیگر از یک پی 2 پی TLS v1.3 لینک با فقط رمزگذاری که تضمین PFS استفاده می کنند. بنابراین هر کلید برای هر اتصال جدید تجدید نظر می شود.

DHT (udp)

برای ارسال پیام ها برای تلفن همراه (برای تگ کردن اطلاعیه های پش) و برای شروع اتصال های TCP استفاده می شود.

فعالیت شبکه

پروسه دعوت کردن کسی

آليس مي خواد باب رو دعوت کنه:

  1. آليس باب رو به مکالمه مي افزايد

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

  3. دو امکان برای ارسال پیام a. اگر متصل نباشد، از طریق DHT b. در غیر این صورت، آلیس از طریق کانال SIP ارسال می کند

  4. دو امکان برای باب a. دعوت دریافت می کند، سیگنال برای مشتری b. متصل نیست، بنابراین هرگز درخواست را دریافت نخواهد کرد زیرا آلیس نباید بداند که آیا باب آلیس را نادیده گرفته یا مسدود کرده است. تنها راه بازسازی دعوت جدید از طریق یک پیام جدید است (بخش به سناریو بعدی)

پروسه ارسال پيام به کسي

آليس مي خواد پيامي به باب بفرستد

  1. آليس يه پيام اضافه ميکنه توي بازپرداخت، يه شناسايي ميده

  2. آليس پيامي ميگيره (از خودش) اگر موفق بشه

  3. دو احتمال، آلیس و باب متصل هستند یا نه. در هر دو مورد یک پیام ایجاد می شود: { "برنامه / im-gitmessage-id" : "{"id":"$convId"، "commit":"$commitId"، "deviceId": "$alice_device_hash"}"}.

  4. چهار امکان برای باب: a. باب با آلیس متصل نیست، بنابراین اگر به آلیس اعتماد کند، از یک اتصال جدید بخواهید و به b. b بروید. اگر متصل باشد، از آلیس بخواهید و پیام های جدیدی را اعلام کنید c. باب این مکالمه را نمی داند. از طریق DHT بخواهید تا ابتدا دعوت نامه دریافت کنید تا بتوانید این مکالمه را بپذیرید ({"تطبيق/دعوت"، مکالمهId}) d. باب قطع شده است (هیچ شبکه ای، یا فقط بسته شده است). او پیام جدید را دریافت نخواهد کرد اما سعی خواهد کرد هنگام اتصال بعدی همگام سازی کند

اجرای

! [ نمودار: کلاس های چت سوار ]

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": "uri of the host",
    "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": "uri of the member",
    "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": "uri of the member",
    "action": "ban/unban"
}

!! مسودات قدیمی!!

يادداشت: يادداشت هاي بعد هنوز مرتب نشده اند فقط چند خط فکر

بهبودي در رمزنگاري

برای یک ویژگی چت گروهی جدی، ما همچنین به رمزنگاری جدی نیاز داریم. با طراحی فعلی، اگر گواهی به عنوان ارزش های DHT قبلی یک مکالمه دزدیده شود، مکالمه می تواند رمزگذاری شود. شاید ما باید به چیزی مانند ** دوگانه ratchet** برویم.

توجه: يه ليب ممکنه براي اجرا کردن مکالمهاي گروه وجود داشته باشه

نیاز به حمایت ECC در OpenDHT

استفاده

نقش اضافه کردن؟

دو مورد مهم برای چت های گروهی وجود دارد:

  1. چیزی شبیه یک Mattermost در یک شرکت، با کانال های خصوصی، و برخی نقش ها (admin/spectator/bot/etc) یا برای آموزش (که فقط چند نفر فعال هستند).

  2. مکالمهاي افقي مثل مکالمهاي بين دوستان

Jami will be for which one?

ایده اجرای

گواهی برای گروهی که کاربر را با پرچم برای یک نقش امضا می کند. اضافه کردن یا لغو نیز می تواند انجام شود.

به حرف زدن پیوست

  • فقط از طریق دعوت مستقیم

  • از طریق لینک/ کد QR/ هرچیزی

  • از طریق نام اتاق؟

آنچه که ما نیاز داریم

  • رازداری: اعضای خارج از چت گروه نباید بتوانند پیام ها را در گروه بخوانند

  • رازداری: اگر هر کلید از گروه به خطر افتاده باشد، پیام های قبلی باید محرمانه باقی بمانند (در هر اندازه ممکن)

  • دستور پیام: نیاز به ترتیب پیام ها وجود دارد

  • هم زمان سازی: همچنین لازم است مطمئن شوید که تمام پیام ها به زودی به دست می آیند.

  • دوام: در واقع، یک پیام در DHT تنها 10 دقیقه طول می کشد. چون بهترین زمان محاسبه شده برای این نوع DHT است. برای حفظ داده ها، گره باید هر 10 دقیقه ارزش DHT را دوباره وارد کند. راه دیگری برای انجام آن زمانی که گره غیر فعال است، اجازه دادن به گره ها برای وارد کردن داده ها است. اما اگر پس از 10 دقیقه، 8 گره هنوز در اینجا هستند، آنها 64 درخواست را انجام می دهند (و این نمایی است). راه فعلی برای جلوگیری از اسپام برای آن سوال شده است. این هنوز 64 درخواست را انجام می دهد اما حداکثر بازخورد به 8 گره را محدود می کند.

سایر روش های توزیع شده

  • IPFS: به يه تحقیق نياز دارم

  • بايد يه کم تحقيق کنيم

  • .بايد يه کم تحقيق کنيم

بر اساس کار فعلی که داریم

چت گروهی می تواند بر اساس همان کار ما در حال حاضر برای دستگاه های متعدد (اما در اینجا، با گواهی گروهی) است. مشکلات برای حل:

  1. هم وقت سازي تاريخ اين بايد ديتابيس رو از كلينده به ديمون منتقل کنه

  2. اگر هیچ کس متصل نباشد، همگام سازی نمی تواند انجام شود و فرد هرگز مکالمه را نمی بیند

يه DHT ديگه اختصاصي

مثل يه DHT با يه سوپر کاربری

انتقال فایل

در حال حاضر الگوریتم انتقال فایل بر اساس اتصال TURN (ببینید انتقال فایل) است. در مورد یک گروه بزرگ، این کار بد خواهد بود. ما ابتدا برای انتقال فایل به یک ابزار p2p نیاز داریم. RFC را برای انتقال p2p پیاده سازی کنید.

مشکل دیگر: در حال حاضر هیچ اجرای پشتیبانی TCP برای ICE در PJSIP وجود ندارد. این برای این نقطه (در pjsip یا خانگی) ضروری است

منابع

  • https://eprint.iacr.org/2017/666.pdf

  • همگام سازی توزیع شده قوی سیستم های خطی شبکه ای با اطلاعات متقطع (Sean Phillips و Ricardo G.Sanfelice)