Bu çeviri makine öğrenimi kullanılarak oluşturulmuştur ve %100 doğru olmayabilir. İngilizce versiyonu görüntüle

Sarımsak Çiftliği Protokolü

Proposal 150
Açık
Author zzz
Created 2019-05-02
Last Updated 2019-05-20

Genel Bakış

Bu, JRaft’a dayalı, TCP üzerinden uygulama için “exts” kodunu ve “dmprinter” örnek uygulamasını temel alan Garlic Farm iletişim kuralı (wire protocol) teknik belgesidir JRAFT .

Belgelenmiş bir iletişim kuralına sahip herhangi bir uygulama bulamadık. Ancak, JRaft uygulaması yeterince basit olduğu için kodu inceleyip ardından iletişim kuralını belgeleyebildik. Bu öneri, bu çalışmanın sonucudur.

Bu, Meta LeaseSet’e giriş yayınlayan yönlendiricilerin koordinasyonu için arka uç olacak. Öneri 123’e bakın.

Amaçlar

  • Küçük kod boyutu
  • Mevcut uygulamaya dayalı olmak
  • Serileştirilmiş Java nesneleri veya herhangi bir Java’ya özgü özellik ya da kodlama içermemek
  • Başlangıç (bootstrapping) işlemleri bu protokolün kapsamı dışındadır. En az bir sunucunun sabit kodlanmış ya da bu protokolün dışında yapılandırılmış olduğu varsayılır.
  • Hem dış bant (out-of-band) hem de I2P içinde kullanım senaryolarını desteklemek.

Tasarım

Raft protokolü somut bir protokol değildir; yalnızca bir durum makinesi tanımlar. Bu nedenle, JRaft’ın somut iletişim kuralını belgeleyip protokolumuzu buna dayandırıyoruz. JRaft protokolüne, kimlik doğrulama el sıkışmasının eklenmesi dışında herhangi bir değişiklik yapılmamıştır.

Raft, bir günlük yayınlamaktan sorumlu bir Lider seçer. Günlük, Raft Yapılandırma verilerini ve Uygulama verilerini içerir. Uygulama verileri, her Sunucunun Yönlendiricisinin durumunu ve Meta LS2 kümesi için Hedefi içerir. Sunucular, Meta LS2’nin yayıncısını ve içeriğini belirlemek için ortak bir algoritma kullanır. Meta LS2’nin yayıncısı, Raft Lideri olmak zorunda değildir.

Spesifikasyon

İletişim kuralı, SSL soketleri veya SSL olmayan I2P soketleri üzerinden çalışır. I2P soketleri HTTP Proxy üzerinden yönlendirilir. Açık ağ (clearnet) için SSL olmayan soket desteği yoktur.

El sıkışma ve kimlik doğrulama

JRaft tarafından tanımlanmamıştır.

Amaçlar:

  • Kullanıcı/parola kimlik doğrulama yöntemi
  • Sürüm tanımlayıcısı
  • Küme tanımlayıcısı
  • Genişletilebilirlik
  • I2P soketleri için kullanıldığında proxy üzerinden iletimin kolay olması
  • Sunucuyu gereksiz yere bir Garlic Farm sunucusu olarak ortaya çıkarmamak
  • Tam bir web sunucusu uygulaması gerektirmeyen basit bir protokol
  • Yaygın standartlarla uyumlu olmak, böylece uygulamalar istenirse standart kütüphaneleri kullanabilsin

WebSocket benzeri bir el sıkışma ve HTTP Digest kimlik doğrulaması RFC 2617 kullanılacaktır. RFC 2617 Temel (Basic) kimlik doğrulaması desteklenmez. HTTP proxy üzerinden yönlendirme yapılırken, RFC 2616 ‘ya göre proxy ile iletişim kurulur.

Kimlik Bilgileri

Kullanıcı adlarının ve parolaların küme bazında mı yoksa sunucu bazında mı olduğu, uygulamaya bağlıdır.

HTTP İsteği 1

Başlatıcı aşağıdaki isteği gönderir.

Tüm satırlar HTTP’nin gerektirdiği gibi CRLF ile sonlandırılır.


GET /GarlicFarm/CLUSTER/VERSION/websocket HTTP/1.1
  Host: (ip):(port)
  Cache-Control: no-cache
  Connection: close
  (diğer tüm başlıklar göz ardı edilir)
  (boş satır)

  CLUSTER, kümenin adıdır (varsayılan "farm")
  VERSION, Garlic Farm sürümüdür (şu an "1")

HTTP Yanıtı 1

Yol doğru değilse, alıcı RFC 2616 ‘ya göre standart “HTTP/1.1 404 Not Found” yanıtını gönderir.

Yol doğruysa, alıcı RFC 2617 ‘ye göre WWW-Authenticate HTTP digest kimlik doğrulama başlığını içeren standart “HTTP/1.1 401 Unauthorized” yanıtını gönderir.

İki taraf da ardından soketi kapatır.

HTTP İsteği 2

Başlatıcı aşağıdaki isteği gönderir, RFC 2617 ‘ye göre.

Tüm satırlar HTTP’nin gerektirdiği gibi CRLF ile sonlandırılır.


GET /GarlicFarm/CLUSTER/VERSION/websocket HTTP/1.1
  Host: (ip):(port)
  Cache-Control: no-cache
  Connection: keep-alive, Upgrade
  Upgrade: websocket
  (proxy kullanılıyorsa Sec-Websocket-* başlıkları)
  Authorization: (RFC 2617'ye göre HTTP digest yetkilendirme başlığı)
  (diğer tüm başlıklar göz ardı edilir)
  (boş satır)

  CLUSTER, kümenin adıdır (varsayılan "farm")
  VERSION, Garlic Farm sürümüdür (şu an "1")

HTTP Yanıtı 2

Kimlik doğrulama doğru değilse, alıcı yine RFC 2617 ‘ye göre “HTTP/1.1 401 Unauthorized” yanıtını gönderir.

Kimlik doğrulama doğruysa, alıcı aşağıdaki yanıtı gönderir, WebSocket protokolüne göre.

Tüm satırlar HTTP’nin gerektirdiği gibi CRLF ile sonlandırılır.


HTTP/1.1 101 Switching Protocols
  Connection: Upgrade
  Upgrade: websocket
  (Sec-Websocket-* başlıkları)
  (diğer tüm başlıklar göz ardı edilir)
  (boş satır)

Bu alındıktan sonra soket açık kalır. Aşağıda tanımlanan Raft protokolü, aynı sokette başlar.

Önbelleğe Alma

Kimlik bilgileri en az bir saat önbelleğe alınmalıdır, böylece sonraki bağlantılar doğrudan yukarıdaki “HTTP İsteği 2” aşamasına atlayabilir.

Mesaj Türleri

İki tür mesaj vardır: istekler ve yanıtlar. İstekler Günlük Girişleri içerebilir ve değişken boyutludur; yanıtlar Günlük Girişleri içermeyip sabit boyutludur.

1-4 arası mesaj türleri, Raft tarafından tanımlanan standart RPC mesajlarıdır. Bu, temel Raft protokolüdür.

5-15 arası mesaj türleri, JRaft tarafından tanımlanan, istemcileri, dinamik sunucu değişikliklerini ve verimli günlük eşitlemesini desteklemek için genişletilmiş RPC mesajlarıdır.

16-17 arası mesaj türleri, Raft Bölüm 7’de tanımlanan Günlük Sıkıştırma RPC mesajlarıdır.

MesajNumaraGönderenAlanNotlar
RequestVoteRequest1AdayTakipçiStandart Raft RPC; günlük girişleri içermemelidir
RequestVoteResponse2TakipçiAdayStandart Raft RPC
AppendEntriesRequest3LiderTakipçiStandart Raft RPC
AppendEntriesResponse4TakipçiLider / İstemciStandart Raft RPC
ClientRequest5İstemciLider / TakipçiYanıt AppendEntriesResponse’tir; yalnızca Uygulama günlük girişleri içermelidir
AddServerRequest6İstemciLiderYalnızca tek bir ClusterServer günlük girişi içermelidir
AddServerResponse7LiderİstemciLider ayrıca bir JoinClusterRequest gönderir
RemoveServerRequest8TakipçiLiderYalnızca tek bir ClusterServer günlük girişi içermelidir
RemoveServerResponse9LiderTakipçi
SyncLogRequest10LiderTakipçiYalnızca tek bir LogPack günlük girişi içermelidir
SyncLogResponse11TakipçiLider
JoinClusterRequest12LiderYeni SunucuKatılma daveti; yalnızca tek bir Yapılandırma günlük girişi içermelidir
JoinClusterResponse13Yeni SunucuLider
LeaveClusterRequest14LiderTakipçiAyrılma komutu
LeaveClusterResponse15TakipçiLider
InstallSnapshotRequest16LiderTakipçiRaft Bölüm 7; yalnızca tek bir SnapshotSyncRequest günlük girişi içermelidir
InstallSnapshotResponse17TakipçiLiderRaft Bölüm 7

Kurulum

HTTP el sıkışmasından sonra, kurulum sırası aşağıdaki gibidir:


Yeni Sunucu Alice              Rastgele Takipçi Bob

  ClientRequest   ------->
          <---------   AppendEntriesResponse

  Eğer Bob lider olduğunu söylerse, aşağıda devam edilir.
  Aksi takdirde, Alice Bob'dan ayrılmalı ve liderle bağlantı kurmalıdır.


  Yeni Sunucu Alice              Lider Charlie

  ClientRequest   ------->
          <---------   AppendEntriesResponse
  AddServerRequest   ------->
          <---------   AddServerResponse
          <---------   JoinClusterRequest
  JoinClusterResponse  ------->
          <---------   SyncLogRequest
                       OR InstallSnapshotRequest
  SyncLogResponse  ------->
  OR InstallSnapshotResponse

Ayrılma Sırası:


Takipçi Alice              Lider Charlie

  RemoveServerRequest   ------->
          <---------   RemoveServerResponse
          <---------   LeaveClusterRequest
  LeaveClusterResponse  ------->

Seçim Sırası:


Aday Alice               Takipçi Bob

  RequestVoteRequest   ------->
          <---------   RequestVoteResponse

  eğer Alice seçimleri kazanırsa:

  Lider Alice                Takipçi Bob

  AppendEntriesRequest   ------->
  (kalp atışı)
          <---------   AppendEntriesResponse

Tanımlar

  • Kaynak: Mesajın başlatıcısını tanımlar
  • Hedef: Mesajın alıcısını tanımlar
  • Terimler: Raft’a bakın. 0’dan başlar, monoton artar
  • İndeksler: Raft’a bakın. 0’dan başlar, monoton artar

İstekler

İstekler bir başlık ve sıfır veya daha fazla günlük girişi içerir. İstekler sabit boyutlu bir başlık ve değişken boyutlu isteğe bağlı Günlük Girişleri içerir.

İstek Başlığı

İstek başlığı 45 bayttır ve aşağıdaki gibidir. Tüm değerler işaretsiz büyük endian’dır.


Mesaj türü:      1 bayt
  Kaynak:            Kimlik, 4 baytlık tamsayı
  Hedef:             Kimlik, 4 baytlık tamsayı
  Terim:             Geçerli terim (notlara bakın), 8 baytlık tamsayı
  Son Günlük Terimi: 8 baytlık tamsayı
  Son Günlük İndeksi: 8 baytlık tamsayı
  Onay İndeksi:      8 baytlık tamsayı
  Günlük girişleri boyutu: Toplam bayt cinsinden boyut, 4 baytlık tamsayı
  Günlük girişleri:       aşağıya bakın, belirtilen toplam uzunluk

Notlar

RequestVoteRequest’te, Terim adayın terimidir. Aksi takdirde, liderin geçerli terimidir.

AppendEntriesRequest’te, günlük girişleri boyutu sıfırsa, bu mesaj bir kalp atışı (keepalive) mesajıdır.

Günlük Girişleri

Günlük, sıfır veya daha fazla günlük girişi içerir. Her günlük girişi aşağıdaki gibidir. Tüm değerler işaretsiz büyük endian’dır.


Terim:           8 baytlık tamsayı
  Değer türü:     1 bayt
  Giriş boyutu:   Bayt cinsinden, 4 baytlık tamsayı
  Giriş:          belirtilen uzunlukta

Günlük İçeriği

Tüm değerler işaretsiz büyük endian’dır.

Günlük Değer TürüNumara
Uygulama1
Yapılandırma2
ClusterServer3
LogPack4
SnapshotSyncRequest5

Uygulama

Uygulama içeriği UTF-8 kodlamalı JSON ‘dur. Aşağıdaki Uygulama Katmanı bölümüne bakın.

Yapılandırma

Liderin yeni bir küme yapılandırmasını serileştirip eşlere çoğaltması için kullanılır. Sıfır veya daha fazla ClusterServer yapılandırması içerir.


Günlük İndeksi:  8 baytlık tamsayı
  Son Günlük İndeksi:  8 baytlık tamsayı
  Her sunucu için ClusterServer Verisi:
    Kimlik:                4 baytlık tamsayı
    Uç nokta veri uzunluğu: Bayt cinsinden, 4 baytlık tamsayı
    Uç nokta verisi:     "tcp://localhost:9001" biçiminde ASCII dizesi, belirtilen uzunlukta

ClusterServer

Bir kümedeki sunucunun yapılandırma bilgisi. Bu yalnızca AddServerRequest veya RemoveServerRequest mesajında yer alır.

AddServerRequest Mesajında kullanıldığında:


Kimlik:                4 baytlık tamsayı
  Uç nokta veri uzunluğu: Bayt cinsinden, 4 baytlık tamsayı
  Uç nokta verisi:     "tcp://localhost:9001" biçiminde ASCII dizesi, belirtilen uzunlukta

RemoveServerRequest Mesajında kullanıldığında:


Kimlik:                4 baytlık tamsayı

LogPack

Bu yalnızca SyncLogRequest mesajında yer alır.

İletimden önce gzip ile sıkıştırılır:


İndeks veri uzunluğu: Bayt cinsinden, 4 baytlık tamsayı
  Günlük veri uzunluğu:   Bayt cinsinden, 4 baytlık tamsayı
  İndeks verisi:     Her indeks için 8 bayt, belirtilen uzunlukta
  Günlük verisi:       belirtilen uzunlukta

SnapshotSyncRequest

Bu yalnızca InstallSnapshotRequest mesajında yer alır.


Son Günlük İndeksi:  8 baytlık tamsayı
  Son Günlük Terimi:   8 baytlık tamsayı
  Yapılandırma veri uzunluğu: Bayt cinsinden, 4 baytlık tamsayı
  Yapılandırma verisi:     belirtilen uzunlukta
  Offset:          Veritabanındaki verinin bayt cinsinden ofseti, 8 baytlık tamsayı
  Veri uzunluğu:        Bayt cinsinden, 4 baytlık tamsayı
  Veri:            belirtilen uzunlukta
  Bitti mi:         Bitti ise 1, değilse 0 (1 bayt)

Yanıtlar

Tüm yanıtlar 26 bayttır ve aşağıdaki gibidir. Tüm değerler işaretsiz büyük endian’dır.


Mesaj türü:   1 bayt
  Kaynak:         Kimlik, 4 baytlık tamsayı
  Hedef:          Genellikle gerçek hedef kimliği (notlara bakın), 4 baytlık tamsayı
  Terim:           Geçerli terim, 8 baytlık tamsayı
  Sonraki İndeks: Liderin son günlük indeksi + 1'den başlar, 8 baytlık tamsayı
  Kabul Edildi mi: Kabul edildiyse 1, edilmediyse 0 (notlara bakın), 1 bayt

Notlar

Hedef Kimliği genellikle bu mesajın gerçek alıcısıdır. Ancak, AppendEntriesResponse, AddServerResponse ve RemoveServerResponse için, mevcut liderin kimliğidir.

RequestVoteResponse’te, Kabul Edildi mi alanı, aday (istek sahibi) için oy verildiğinde 1, oy verilmediğinde 0’dır.

Uygulama Katmanı

Her Sunucu, periyodik olarak bir ClientRequest içinde Uygulama verisini günlüğe yazar. Uygulama verisi, her Sunucunun Yönlendiricisinin durumunu ve Meta LS2 kümesi için Hedefi içerir. Sunucular, Meta LS2’nin yayıncısını ve içeriğini belirlemek için ortak bir algoritma kullanır. Günlükte “en iyi” son duruma sahip sunucu, Meta LS2 yayıncısıdır. Meta LS2’nin yayıncısı, Raft Lideri olmak zorunda değildir.

Uygulama Verisi İçeriği

Basitlik ve genişletilebilirlik için uygulama içeriği UTF-8 kodlamalı JSON biçimindedir. Tam spesifikasyonu henüz belirlenmedi. Amaç, Meta LS2’yi yayınlamak için “en iyi” yönlendiriciyi belirleyecek bir algoritma yazmak için yeterli veri sağlamak ve yayıncının Meta LS2’deki Hedefleri ağırlıklandırmak için yeterli bilgiye sahip olmaktır. Veri, hem yönlendirici hem de Hedef istatistiklerini içerecektir.

Veri, isteğe bağlı olarak diğer sunucuların sağlığına dair uzaktan algılama verilerini ve Meta LS’yi çekme yeteneğini içerebilir. Bu veriler ilk sürümde desteklenmeyecektir.

Veri, isteğe bağlı olarak bir yönetici istemcisi tarafından gönderilen yapılandırma bilgilerini içerebilir. Bu veriler ilk sürümde desteklenmeyecektir.

Eğer “ad: değer” listelenmişse, bu JSON harita anahtarını ve değerini belirtir. Aksi takdirde, spesifikasyon henüz belirlenmedi.

Küme verisi (üst düzey):

  • cluster: Küme adı
  • date: Bu verinin tarihi (uzun, epoch’tan bu yana ms)
  • id: Raft Kimliği (tamsayı)

Yapılandırma verisi (config):

  • Herhangi bir yapılandırma parametresi

MetaLS yayınlama durumu (meta):

  • destination: metals hedefi, base64
  • lastPublishedLS: varsa, son yayınlanan metals’in base64 kodlaması
  • lastPublishedTime: ms cinsinden, hiç yayınlanmadıysa 0
  • publishConfig: Yayıncı yapılandırma durumu açık/kapalı/otomatik
  • publishing: metals yayıncı durumu boolean true/false

Yönlendirici verisi (router):

  • lastPublishedRI: varsa, son yayınlanan yönlendirici bilgisinin base64 kodlaması
  • uptime: Çalışma süresi ms cinsinden
  • Job gecikmesi
  • Keşif tüneli
  • Katılımcı tünel
  • Yapılandırılmış bant genişliği
  • Geçerli bant genişliği

Hedefler (destinations): Liste

Hedef verisi:

  • destination: hedef, base64
  • uptime: Çalışma süresi ms cinsinden
  • Yapılandırılmış tünel
  • Geçerli tünel
  • Yapılandırılmış bant genişliği
  • Geçerli bant genişliği
  • Yapılandırılmış bağlantılar
  • Geçerli bağlantılar
  • Karaliste verisi

Uzaktan yönlendirici algılama verisi:

  • Görülen son RI sürümü
  • LS Çekme süresi
  • Bağlantı testi verisi
  • En yakın floodfill’lerin profil verisi dün, bugün ve yarın için zaman dilimleri

Uzaktan hedef algılama verisi:

  • Görülen son LS sürümü
  • LS Çekme süresi
  • Bağlantı testi verisi
  • En yakın floodfill’lerin profil verisi dün, bugün ve yarın için zaman dilimleri

Meta LS algılama verisi:

  • Görülen son sürüm
  • Çekme süresi
  • En yakın floodfill’lerin profil verisi dün, bugün ve yarın için zaman dilimleri

Yönetim Arayüzü

Henüz belirlenmedi, muhtemelen ayrı bir öneri. İlk sürüm için gerekli değildir.

Bir yönetici arayüzünün gereksinimleri:

  • Birden fazla ana hedefi desteklemek, yani birden fazla sanal küme (çiftlik)
  • Üyeler tarafından yayınlanan tüm istatistikler, mevcut lider kim, vb. gibi paylaşılan küme durumuna kapsamlı bir görünüm sağlamak
  • Bir katılımcıyı veya lideri kümeden zorla çıkarma yeteneği
  • MetaLS’yi zorla yayınlama yeteneği (mevcut düğüm yayıncıysa)
  • MetaLS’den hash’leri hariç tutma yeteneği (mevcut düğüm yayıncıysa)
  • Toplu dağıtımlar için yapılandırma içe/dışa aktarma işlevselliği

Yönlendirici Arayüzü

Henüz belirlenmedi, muhtemelen ayrı bir öneri. İlk sürüm için i2pcontrol gerekli değildir ve ayrıntılı değişiklikler ayrı bir öneriye dahil edilecektir.

Garlic Farm’tan yönlendiriciye API gereksinimleri (in-JVM java veya i2pcontrol)

  • getLocalRouterStatus()
  • getLocalLeafHash(Hash masterHash)
  • getLocalLeafStatus(Hash leaf)
  • getRemoteMeasuredStatus(Hash masterOrLeaf) // muhtemelen MVP’de değil
  • publishMetaLS(Hash masterHash, List contents) // ya da imzalı MetaLeaseSet? Kim imzalar?
  • stopPublishingMetaLS(Hash masterHash)
  • kimlik doğrulama henüz belirlenmedi?

Gerekçe

Atomix çok büyük ve protokolü I2P üzerinden yönlendirmemiz için özelleştirmemize izin vermez. Ayrıca, iletişim formatı belgelenmemiştir ve Java serileştirmeye bağlıdır.

Notlar

Sorunlar

  • Bir istemcinin bilinmeyen bir lideri bulup ona bağlanmasının bir yolu yoktur. Bir Takipçinin AppendEntriesResponse’te Yapılandırmayı Günlük Girişi olarak göndermesi için küçük bir değişiklik yapılabilir.

Geçiş

Geriye dönük uyumluluk sorunu yoktur.

Kaynaklar