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ı Sarımsak Çiftliği kablo protokolü için spesifikasyondur, TCP üzerinden uygulama için “exts” kodu ve “dmprinter” örnek uygulaması JRAFT. JRaft, Raft protokolünün bir uygulamasıdır RAFT.

Belgelenmiş bir kablo protokolü olan bir uygulama bulamadık. Ancak, JRaft uygulaması, kodun incelenebileceği ve ardından protokolün belgelenebileceği kadar basittir. Bu öneri bu çabanın sonucudur.

Bu, Meta LeaseSet içindeki girdilerin yayınlanmasında yönlendiricilerin eşgüdümü için arka plan olacak. Teklif 123’e bakın.

Hedefler

  • Küçük kod boyutu
  • Mevcut uygulama tabanlı
  • Seri hale getirilmiş Java nesneleri veya herhangi bir Java’ya özgü özellikler veya kodlama yok
  • Herhangi bir bootstrapping bu protokolün kapsamı dışındadır. En az bir diğer sunucunun sabit kodlanmış veya bu protokolün dışında yapılandırılmış olduğu varsayılır.
  • Band dışı ve I2P kullanım durumlarını destekleyin.

Tasarım

Raft protokolü somut bir protokol değildir; yalnızca bir durum makinesi tanımlar. Bu nedenle, JRaft’ın somut protokolünü belgeleriz ve protokolümüzü buna dayandırırız. Bir kimlik doğrulama el sıkışmasının eklenmesi dışında JRaft protokolünde hiçbir değişiklik yoktur.

Raft bir günlük yayınlamakla görevli bir Lider seçer. Bu 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ınlayıcısını ve içeriğini belirlemek için ortak bir algoritma kullanır. Meta LS2’nin yayıncısı mutlaka Raft Lideri değildir.

Teknik Şartname

Kablo protokolü SSL soketler veya SSL olmayan I2P soketleri üzerinden çalışır. I2P soketleri HTTP Proxy üzerinden yönlendirilir. Temiz ağ SSL olmayan soketlere destek yoktur.

El Sıkışma ve Kimlik Doğrulama

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

Hedefler:

  • Kullanıcı/parola kimlik doğrulama yöntemi
  • Sürüm tanımlayıcısı
  • Küme tanımlayıcısı
  • Genişletilebilir
  • I2P soketleri için kullanıldığında proxying kolaylığı
  • Sunucuyu gereksiz yere bir Sarımsak Çiftliği sunucusu olarak ifşa etmeyin
  • Tam bir web sunucusu uygulamasının gerekli olmadığı basit protokol
  • Yaygın standartlarla uyumlu, böylece istenirse standart kütüphaneler kullanılabilir

Bir WebSocket benzeri el sıkışması WEBSOCKET ve HTTP Özeti kimlik doğrulaması RFC-2617 kullanacağız. RFC 2617 Temel kimlik doğrulaması desteklenmemektedir. HTTP proxy üzerinden yönlendirilirken, RFC-2616‘da belirtildiği gibi proxy ile iletişim kurun.

Kimlik Bilgileri

Kullanıcı adları ve parolalar küme başına mı yoksa sunucu başına mı olduğuna uygulamaya bağlıdır.

HTTP İsteği 1

Başlatan taraf aşağıdaki gibi gönderir.

Tüm satırlar HTTP tarafından gerekli görüldüğü 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 başlıklar yok sayılır)
  (boş satır)

  CLUSTER kümenin adıdır (varsayılan "farm")
  VERSION ise Sarımsak Çiftliği sürümüdür (şimdi "1")

HTTP Yanıtı 1

Eğer yol doğru değilse, alıcı RFC-2616‘da belirtildiği gibi standart bir “HTTP/1.1 404 Not Found” yanıtı gönderir.

Eğer yol doğruysa, alıcı RFC-2617‘da belirtildiği gibi standart bir “HTTP/1.1 401 Unauthorized” yanıtı gönderir ve WWW-Authenticate HTTP özeti kimlik doğrulama başlığını içerir.

Her iki taraf da daha sonra soketi kapatır.

HTTP İsteği 2

Başlatan taraf aşağıdaki gibi gönderir, RFC-2617 ve WEBSOCKET gibi.

Tüm satırlar HTTP tarafından gerekli görüldüğü 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
  (Daha proxyli ise Sec-Websocket-* başlıkları)
  Authorization: (RFC 2617'de olduğu gibi HTTP özeti yetkilendirme başlığı)
  (diğer başlıklar yok sayılır)
  (boş satır)

  CLUSTER kümenin adıdır (varsayılan "farm")
  VERSION ise Sarımsak Çiftliği sürümüdür (şimdi "1")

HTTP Yanıtı 2

Eğer kimlik doğrulama doğru değilse, alıcı RFC-2617‘da belirtildiği gibi başka bir standart “HTTP/1.1 401 Unauthorized” yanıtı gönderir.

Eğer kimlik doğrulama doğruysa, alıcı WEBSOCKET‘da olduğu gibi aşağıdaki yanıtı gönderir.

Tüm satırlar HTTP tarafından gerekli görüldüğü gibi CRLF ile sonlandırılır.

HTTP/1.1 101 Switching Protocols
  Connection: Upgrade
  Upgrade: websocket
  (Sec-Websocket-* başlıkları)
  (diğer başlıklar yok sayılır)
  (boş satır)

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

Önbellekleme

Kimlik bilgilerinin en az bir saat boyunca önbelleğe alınması gerekir, böylece ilerleyen bağlantılar doğrudan yukarıdaki “HTTP İsteği 2"e atlanabilir.

Mesaj Türleri

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

Mesaj tipleri 1-4, Raft tarafından tanımlanan standart RPC mesajlarıdır. Bu, çekirdek Raft protokolüdür.

Mesaj tipleri 5-15, JRaft tarafından tanımlanan, istemcileri, dinamik sunucu değişikliklerini ve verimli günlük senkronizasyonunu desteklemek için genişletilmiş RPC mesajlarıdır.

Mesaj tipleri 16-17, Raft bölüm 7’de tanımlanan Günlük Sıkıştırma RPC mesajlarıdır.

MesajNumarasıGönderenGönderilen TarafNotlar
RequestVoteRequest1AdayTakipçiStandart Raft RPC; Günlük girdileri içermemelidir
RequestVoteResponse2TakipçiAdayStandart Raft RPC
AppendEntriesRequest3LiderTakipçiStandart Raft RPC
AppendEntriesResponse4TakipçiLider / İstemciStandart Raft RPC
ClientRequest5İstemciLider / TakipçiYanıt AppendEntriesResponse’dir; Sadece Uygulama günlük girdilerini içermelidir
AddServerRequest6İstemciLiderYalnızca tek bir ClusterServer günlük girdisi içermelidir
AddServerResponse7LiderİstemciLider ayrıca JoinClusterRequest gönderir
RemoveServerRequest8TakipçiLiderYalnızca tek bir ClusterServer günlük girdisi içermelidir
RemoveServerResponse9LiderTakipçi
SyncLogRequest10LiderTakipçiUygulamaya sadece bir LogPack günlük girdisi içermelidir
SyncLogResponse11TakipçiLider
JoinClusterRequest12LiderYeni SunucuKatılma daveti; yalnızca bir Yapılandırma günlük girdisi içermelidir
JoinClusterResponse13Yeni SunucuLider
LeaveClusterRequest14LiderTakipçiAyrılma komutu
LeaveClusterResponse15TakipçiLider
InstallSnapshotRequest16LiderTakipçiRaft Bölümü 7; Sadece bir SnapshotSyncRequest günlük girdisi içermelidir
InstallSnapshotResponse17TakipçiLiderRaft Bölümü 7

Kurulum

HTTP el sıkışmasının ardından, kurulum sırası şu şekildedir:

Yeni Sunucu Alice              Rastgele Takipçi Bob

  İstemci İsteği   ------->
          <---------   AppendEntries Yanıtı

  Bob lider olduğunu söylerse, aşağıdaki şekilde devam edin.
  Aksi takdirde, Alice Bob'dan bağlantıyı kesmelidir ve lider ile bağlantı kurmalıdır.


  Yeni Sunucu Alice              Lider Charlie

  İstemci İsteği   ------->
          <---------   AppendEntries Yanıtı
  AddServer İsteği   ------->
          <---------   AddServer Yanıtı
          <---------   JoinCluster İsteği
  JoinCluster Yanıtı  ------->
          <---------   SyncLog İsteği
                       VEYA InstallSnapshot İsteği
  SyncLog Yanıtı  ------->
  VEYA InstallSnapshot Yanıtı

Bağlantıyı Kesme Sırası:

Takipçi Alice              Lider Charlie

  RemoveServer İsteği   ------->
          <---------   RemoveServer Yanıtı
          <---------   LeaveCluster İsteği
  LeaveCluster Yanıtı  ------->

Seçim Sırası:

Aday Alice               Takipçi Bob

  RequestVote İsteği   ------->
          <---------   RequestVote Yanıtı

  Alice seçim kazandıysa:

  Lider Alice                Takipçi Bob

  AppendEntries İsteği   ------->
  (kalp atışı)
          <---------   AppendEntries Yanıtı

Tanımlar

  • Kaynak: Mesajın kökenini tanımlar
  • Hedef: Mesajın alıcısını tanımlar
  • Dönemler: Raft’a bakın. 0 ile başlatılır, monoton artar
  • İndeksler: Raft’a bakın. 0 ile başlatılır, monoton artar

İstekler

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

İstek Başlığı

İstek başlığı 45 bayttır, aşağıdaki gibi. Tüm değerler işaretsiz big-endian’dir.

Mesaj tipi:      1 bayt
  Kaynak:          Kimlik, 4 bayt tamsayı
  Hedef:           Kimlik, 4 bayt tamsayı
  Dönem:           Mevcut dönem (notlara bakın), 8 bayt tamsayı
  Son Günlük Dönemi:  8 bayt tamsayı
  Son Günlük İndeksi:  8 bayt tamsayı
  Onaylı İndeks:   8 bayt tamsayı
  Günlük girdileri boyutu:  Toplam bayt cinsinden boyut, 4 bayt tamsayı
  Günlük girdileri:       aşağıda belirtildiği gibi, belirtilen toplam uzunluk

Notlar

RequestVote İsteğinde, Dönem adayın dönemidir. Diğerlerinde, liderin mevcut dönemidir.

AppendEntries İsteğinde, günlük girdileri boyutu sıfır olduğunda, bu mesaj bir kalp atışı (canlı tutma) mesajıdır.

Günlük Girdileri

Günlük sıfır veya daha fazla günlük girdisi içerir. Her günlük girdisi aşağıdaki gibidir. Tüm değerler işaretsiz big-endian’dir.

Dönem:           8 bayt tamsayı
  Değer türü:     1 bayt
  Girdi boyutu:   Bayt olarak, 4 bayt tamsayı
  Girdi:          belirlenen uzunlukta

Günlük İçeriği

Tüm değerler işaretsiz big-endian’dir.

Günlük Değer TürüSayı
Uygulama1
Yapılandırma2
Küme Sunucusu3
Günlük Paketi4
Anlık Görüntü Eşitleme İsteği5

Uygulama

Uygulama içeriği, basitlik ve genişletilebilirlik için UTF-8 kodlamalı JSON formatındadır. Aşağıdaki Uygulama Katmanı bölümüne bakın.

Yapılandırma

Bu, liderin yeni bir küme yapılandırmasını seri hale getirmesi ve 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 bayt tamsayı
  Son Günlük İndeksi:  8 bayt tamsayı
  Her sunucu için ClusterServer Verileri:
    Kimlik:                4 bayt tamsayı
    Uç nokta veri boyutu:  Bayt olarak, 4 bayt tamsayı
    Uç nokta verisi:       "tcp://localhost:9001" şeklinde ASCII dizesi, belirtilen uzunlukta

Küme Sunucusu

Bir kümedeki bir sunucu için yapılandırma bilgileri. Bu yalnızca bir AddServerRequest veya RemoveServerRequest mesajında dahil edilir.

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

Kimlik:                4 bayt tamsayı
  Uç nokta veri boyutu:  Bayt olarak, 4 bayt tamsayı
  Uç nokta verisi:       "tcp://localhost:9001" şeklinde ASCII dizesi, belirtilen uzunlukta

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

Kimlik:                4 bayt tamsayı

Günlük Paketi

Bu yalnızca bir SyncLogRequest mesajında dahil edilir.

Aşağıdaki veriler sıkıştırılmış (gzipped) olarak iletilir:

İndeks veri boyutu: Bayt olarak, 4 bayt tamsayı
  Günlük veri boyutu: Bayt olarak, 4 bayt tamsayı
  İndeks verisi:     Her indeks için 8 bayt, belirtilen uzunlukta
  Günlük veri:       belirtilen uzunlukta

Anlık Görüntü Eşitleme İsteği

Bu yalnızca bir InstallSnapshotRequest mesajında dahil edilir.

Son Günlük İndeksi:  8 bayt tamsayı
  Son Günlük Dönemi:   8 bayt tamsayı
  Yapılandırma veri boyutu: Bayt olarak, 4 bayt tamsayı
  Yapılandırma verisi:     belirtilen uzunlukta
  Ofset:          Verinin veritabanındaki ofseti, bayt olarak, 8 bayt tamsayı
  Veri boyutu:        Bayt olarak, 4 bayt tamsayı
  Veri:            belirtilen uzunlukta
  Tamamlandı Mı:         eğer tamamlandıysa 1, değilse 0 (1 bayt)

Yanıtlar

Tüm yanıtlar 26 bayttır, aşağıdaki gibi. Tüm değerler işaretsiz big-endian’dir.

Mesaj tipi:   1 bayt
  Kaynak:         Kimlik, 4 bayt tamsayı
  Hedef:          Genellikle gerçek hedef kimliği (notlara bakın), 4 bayt tamsayı
  Dönem:          Mevcut dönem, 8 bayt tamsayı
  Sonraki İndeks: Liderin son günlük indeksi + 1'ye başlanır, 8 bayt tamsayı
  Kabul Edildi Mi: Eğer kabul edildiyse 1, değilse 0 (notları inceleyin), 1 bayt

Notlar

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

RequestVoteResponse’ta, Kabul Edildi Mi 1 ise aday için bir oy (istek sahibi), ve 0 ise oy yoktur.

Uygulama Katmanı

Her Sunucu, bir İstemci İsteği içinde periyodik olarak Uygulama verilerini güncel olarak gönderir. Uygulama verileri her Sunucunun Router’ının 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ırlar. Günlükteki “en iyi” son duruma sahip sunucu Meta LS2 yayıncısıdır. Meta LS2’nin yayıncısı mutlaka Raft Lideri değildir.

Uygulama Veri İçeriği

Uygulama içeriği, basitlik ve genişletilebilirlik için UTF-8 kodlamalı JSON formatındadır. Tam spesifikasyon TBD (Henüz Belirlenmedi). Amaç, Meta LS2’yi yayınlamak için “en iyi” yönlendiriciyi belirlemek üzere bir algoritma yazmak için yeterli veriyi sağlamak ve yayıncının Meta LS2’deki Hedefleri ağırlıklandırması için yeterli bilgiye sahip olmasını sağlamaktır. Veriler hem yönlendirici hem de Hedef istatistiklerini içerecektir.

Veriler, diğer sunucuların sağlığı ve Meta LS’nin alınma kabiliyeti hakkında uzaktan algılama verileri içerebilir. Bu veriler ilk sürümde desteklenmeyecektir.

Veriler, bir yönetici istemcisi tarafından yayınlanan yapılandırma bilgilerini içerebilir. Bu veriler ilk sürümde desteklenmeyecektir.

“Eşleme: değer” belirtilmişse, bu JSON eşleme anahtarını ve değerini belirtir. Aksi takdirde, belirleme TBD.

Küme verileri (en üst düzey):

  • küme: Küme ismi
  • tarih: Bu verilerin tarihi (uzun, epoch’tan itibaren milisaniye cinsinden)
  • kimlik: Raft Kimliği (tamsayı)

Yapılandırma verileri (config):

  • Herhangi bir yapılandırma parametreleri

MetaLS yayınlama durumu (meta):

  • hedef: metals hedefi, base64
  • sonYayınlananLS: mevcutsa, son yayımlanan metals’in base64 kodlaması
  • sonYayınlanmaZamanı: milisaniye olarak veya hiç olmazsa 0
  • yayınlamaYapılandırması: Yayıncı yapılandırma durumu kapalı/açık/otomatik
  • yayınlıyor: metals yayıncı durumu boolean doğru/yanlış

Yönlendirici verileri (router):

  • sonYayınlananRI: mevcutsa, son yayımlanan yönlendirici bilgisinin base64 kodlaması
  • çalışma süresi: Milisaniye cinsinden çalışma süresi
  • İş gecikmesi
  • Keşif tünelleri
  • Katılımcı tüneller
  • Yapılandırılmış bant genişliği
  • Mevcut bant genişliği

Hedefler (destinasyonlar): Liste

Hedef verileri:

  • hedef: hedef, base64
  • çalışma süresi: Milisaniye cinsinden çalışma süresi
  • Yapılandırılmış tüneller
  • Mevcut tüneller
  • Yapılandırılmış bant genişliği
  • Mevcut bant genişliği
  • Yapılandırılmış bağlantılar
  • Mevcut bağlantılar
  • Kara liste verileri

Uzak yönlendirici algılama verileri:

  • Görülen Son RI sürümü
  • LS Alma zamanı
  • Bağlantı testi verileri
  • En yakın floodfills profil verileri dünkü, bugünkü ve yarınki zaman aralıkları için

Uzak hedef algılama verileri:

  • Görülen Son LS sürümü
  • LS Alma zamanı
  • Bağlantı testi verileri
  • En yakın floodfills profil verileri dünkü, bugünkü ve yarınki zaman aralıkları için

Meta LS algılama verileri:

  • Görülen son sürüm
  • Alma zamanı
  • En yakın floodfills profil verileri dünkü, bugünkü ve yarınki zaman aralıkları için

Yönetim Arayüzü

TBD, muhtemelen ayrı bir teklif. İlk sürüm için gerekli değildir.

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

  • Birden fazla ana hedefi destekleme, yani birden fazla sanal küme (çiftlik)
  • Paylaşılan küme durumunun kapsamlı görünümünü sağlama - üyeler tarafından yayınlanan tüm istatistikler, mevcut lider kim vb.
  • Kümedeki bir katılımcıyı veya lideri zorla çıkarma yeteneği
  • MetaLS’yi zorla yayınlama yeteneği (mevcut düğüm yayıncı ise)
  • Exclude karmaşıklarını metaLS’den çıkarma yeteneği (mevcut düğüm yayıncı ise)
  • Toplu dağıtımlar için yapılandırma içe/dışa aktarma işlevselliği

Yönlendirici Arayüzü

TBD, muhtemelen ayrı bir teklif. i2pcontrol ilk sürüm için gerekli değildir ve detaylı değişiklikler ayrı bir teklifte bulunacaktır.

Sarımsak Çiftliği için yönlendirici API gereksinimleri (JVM içi Java veya i2pcontrol)

  • getLocalRouterStatus()
  • getLocalLeafHash(Hash masterHash)
  • getLocalLeafStatus(Hash leaf)
  • getRemoteMeasuredStatus(Hash masterOrLeaf) // muhtemelen MVP’de yok
  • publishMetaLS(Hash masterHash, List contents) // veya imzalı MetaLeaseSet? Kim imzalıyor?
  • stopPublishingMetaLS(Hash masterHash)
  • kimlik doğrulama TBD?

Gerekçe

Atomix çok büyük ve protokolü I2P üzerinden yönlendirme özelleştirmesine izin vermiyor. Ayrıca, kablo formatı belgelenmemiştir ve Java serileştirmesine bağlıdır.

Notlar

Sorunlar

  • Bir müşterinin bilinmeyen bir lidere nasıl ulaşabileceği ve onunla bağlantı kurabileceği bir yol yok. Bir Takipçi’nin AppendEntries Yanıtında Konfigürasyonu bir Günlük Girdisi olarak göndermesi için bir değişiklik küçük olurdu.

Geçiş

Geriye dönük uyumluluk sorunları yoktur.

Referanslar