Soket yolu uzunluğu neden yüz karakterle sınırlıdır?


18

Unix sistemlerinde, yol adlarının uzunluk sınırlaması yoktur (Linux'ta 4096 karakter) ... yaklaşık 100 karakterle sınırlı olan soket dosyaları yolları hariç ( Linux'ta 107 karakter ).

  • İlk soru: neden bu kadar düşük bir sınırlama?

Mevcut çalışma dizini değiştirerek ve çeşitli dizinlerde aynı soket kullanarak çeşitli soket dosyaları oluşturarak bu sınırlama etrafında çalışmak mümkün görünüyor kontrol ettim ./myfile.sock: istemci uygulamaları doğru olsa bile beklenen sunucu işlemlerine bağlanmak gibi görünüyor lsoftüm gösterir aynı soket dosya yolunda dinliyor.

  • Bu geçici çözüm güvenilir mi yoksa şanslı mıydım?
  • Bu davranış Linux'a özgü mü yoksa bu geçici çözüm diğer Unix'ler için de geçerli olabilir mi?

Mevcut OpenBSD sistemlerinde veya Mac OS X 10.11'de sınır daha da düşüktür (104).
17'de

Önemli olan, uyumluluk uğruna 108'den daha az olması gerektiğidir :)

AFAIK Linux'ta 108 karakter. Lütfen makinenizde /usr/include/$arch-linux-gnu/sys/un.h adresini kontrol edin.
schaiba

@schaiba: 108 bayt. Bu, boş bir sonlandırıcı tarafından sona eren 107 karakterlik bir dize anlamına gelir.
WhiteWinterWolf

Yanıtlar:


18

Kullanırken diğer platformlar, veya daha eski malzeme ile uyumluluk uyumluluk taşmaları önlemek snprintf()ve strncpy().

Michael Kerrisk açıklamak adlı kitabında at sayfa 1165 - Bölüm 57, Yuva: Unix alan:

SUSv3 sun_path alanının boyutunu belirtmez. Erken BSD uygulamaları 108 ve 104 bayt kullandı ve bir çağdaş uygulama (HP-UX 11) 92 bayt kullanıyor. Taşınabilir uygulamalar bu düşük değeri kodlamalı ve bu alana yazarken arabellek taşmalarını önlemek için snprintf () veya strncpy () kullanmalıdır.

Docker adamları bununla dalga geçti, çünkü bazı soketler 110 karakter uzunluğundaydı:

Bu yüzden LINUX 108 karakterlik bir soket kullanır. Bu değiştirilebilir mi? Elbette. Ve bu, ilk etapta bu sınırlamanın eski İşletim Sistemlerinde yaratılmasının sebebidir:

Cevaptan alıntı:

Kullanışlı bir çekirdek veri yapısındaki alanla eşleşecekti.

McKusick ve ark. Tarafından "4.4BSD İşletim Sisteminin Tasarımı ve Uygulaması" ndan alıntı yapılmaktadır. ark. (sayfa 369):

Bellek yönetimi tesisleri, mbuf adı verilen bir veri yapısı etrafında döner. Mbuflar veya bellek arabellekleri 128 bayt uzunluğundadır ve bu alanın 100 veya 108 baytı veri depolama için ayrılmıştır.

Diğer işletim sistemleri (unix alan soketleri):


1
SUSv3 XNET sessizdi çünkü konu üzerinde fikir birliği yoktu.
fpmurphy

Bakış açınızı ispatlamak için bağlantınız var mı?

Bu cevap için teşekkürler. Farklı çalışma dizinlerine göre özdeş isimler taşıyan birkaç soket dosyası kullanmak güvenilir midir (örneğin, ./my.socketaşağıdaki dizinde adlı A/bir soket dosyası ve ./my.socketaşağıdaki dizinde de adlandırılan başka bir soket dosyası oluşturun B/)? lsofiki soket dosyası arasında herhangi bir ayrım yapmaz, ancak yine de çalışıyor gibi görünüyor ama bunun sadece şanslı olduğum için olup olmadığını merak ediyorum. Bu, izin verilen boyuttan daha uzun bir yolun altında soket dosyaları oluşturmak için iyi bir çözüm olacaktır.
WhiteWinterWolf

lsof -U| grep amavisamavis-se 2708 zimbra 17u unix 0xffff8806c0a95400 0t0 310330411 /opt/zimbra/data/tmp/amavisd-zmq.sock

Evet, bunun olağandışı olduğunu biliyorum, bu yüzden sorum burada;)! Test ettiğim şey için, göreli isimler işe yarıyor, ama yine de bana garip geliyor ... ama işe yarıyor. Uygulamam sistem çapında değil, bu nedenle soket dosyaları ya tüm diğer uygulama verileriyle, çok tercih edilen ancak potansiyel olarak çok uzun bir yolla, kullanıcı tarafından kontrol edilen bir konumda saklanır ya da /tmpher biri tonlarca benzersiz olarak adlandırılmamış silinmemiş dizinle karışabilir tek bir soket dosyası içeren (tamamen çirkin, ancak taşınabilir ve güvenli).
WhiteWinterWolf

5

Nedeniyle ilgili olarak, nwildner zaten mükemmel bir cevap yazdı .

Burada sadece nasıl ve göreceli yol kullanımına odaklanacağım.

Dahili olarak, soket dosyası adıyla da (sanırım) aranabilirken, genellikle inode tarafından aranır. Linux'ta, bu arama net / unix / af_unix.c dosyasındaunix_find_socket_byinode() tanımlanan işlevle sağlanır .

Bu aşağıdaki gibi kolayca kontrol edilebilir:

  • İki dizin A / ve B / oluşturun .
  • Her dizinin altında, aynı adı taşıyan soket dosyalarını bir işlemin dinlemesini sağlayın. Sizinle aşağıdaki socatgibi bir komut kullanırsınız:
$ socat UNIX-LISTEN:./my.sock -
  • Şimdi soket dosyalarını A / my.sock öğesini B / ve tersi yönde taşıyarak değiştirin .
  • Şu andan itibaren, istemci uygulaması bağlandığı takdirde A / my.sock sunucu irtibata geçecektir B ve bağlanıyorsa B / my.sock sunucu irtibata geçecektir A iletişim uçları (not olsa o zaman, sunucu işlemi may kendi soket dosyası olduğunu düşündüğünü meşru bir şekilde silin).

Bu davranışı bir avuç Unix sisteminde (Linux Debian, FreeBSD ve OpenIndiana bazı çeşitlilik elde etmek için) kontrol ettim, bu yüzden bu davranış standart değilse, en azından geniş yayılmış gibi görünüyor.

Mutlak yollar genellikle istemci ve sunucu işlemleri arasında bir kural olarak kullanılır, çünkü istemci işlemi, sunucuyla ilk iletişimin nasıl kurulacağını bilmeyebilir.

Ancak, bu ilk iletişim bir sorun değilse, soket dosyaları oluşturmak için göreli yollar kullanmak güvenli görünüyor ve soket dosyası konumu sunucu işlemi tarafından doğrudan kontrol edilmediğinde yol uzunluğu sorunlarının önlenmesine izin veriyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.