यह अनुवाद मशीन लर्निंग का उपयोग करके उत्पन्न किया गया था और 100% सटीक नहीं हो सकता है। अंग्रेज़ी संस्करण देखें

तेज एक्सटेंशन (BEP 6) लक्ष्य-हैश साथी पहचान के साथ तेज की अनुमति दी गई

Proposal 172
प्रारूप
Author dr|z3d
Created 2026-08-10
Last Updated 2026-08-10

अवलोकन

BEP 6 (फास्ट एक्सटेंशन) पाँच सुविधाओं को पैक करता है: हैव ऑल / हैव नोन, रिजेक्ट रिक्वेस्ट, सजेशन, और अलाउड फास्ट। वायर प्रोटोकॉल — नेगोशिएशन बिट, मैसेज आईडी, और चोक सेमेंटिक्स — ट्रांसपोर्ट-एग्नॉस्टिक है और I2P स्ट्रीमिंग के ऊपर जैसा-का-तैसा काम करता है। BEP 6 का एकमात्र हिस्सा जिसे I2P पर सीधे मैप नहीं किया जा सकता, वह है अलाउड फास्ट सेट जनरेशन, क्योंकि इसे पीयर के IPv4 पते के संदर्भ में परिभाषित किया गया है। I2P पीयर्स के पास कोई IP नहीं होते; वे 32-बाइट डेस्टिनेशन हैश द्वारा पहचाने जाते हैं।

यह प्रस्ताव एक I2P-स्वदेशी अनुमति प्राप्त त्वरित समुच्चय (Allowed Fast set) उत्पत्ति को मानकीकृत करता है ताकि सभी I2P टोरेंट क्लाइंट एक ही पीयर और टोरेंट के लिए समान अनुमति प्राप्त त्वरित समुच्चय उत्पन्न करें, जिससे यह सुविधा सभी कार्यान्वयन में उपयोगी (और सत्याप्य) बन जाए।

अभिप्रेरणा

नए पीयर्स को बिटटॉरेंट के ‘आप मुझे, मैं आपको’ (tit-for-tat) के तेज़ होने से पहले पहले कुछ टुकड़ों की आवश्यकता होती है। I2P पर यह प्रक्रिया सामान्य नेटवर्क (clearnet) की तुलना में धीमी होती है: कनेक्शन स्थापित करना और टुकड़े भेजना उच्च-विलंबता वाली कई हॉप्स वाली टनल्स से गुज़रता है, इसलिए कनेक्ट होने और पहली पारस्परिक अनचोक के बीच का समय अधिक लंबा होता है। अनुमति प्राप्त फास्ट (Allowed Fast) इसी समयावधि पर सीधे प्रभाव डालता है — एक शुरुआती पीयर को चोक होने के दौरान भी कुछ सीमित टुकड़े लेने की अनुमति होती है, जिससे उसे तुरंत डेटा मिल जाता है और वह जल्दी पारस्परिकता शुरू कर सकता है।

संदर्भ BEP 6 प्राप्तकर्ता के लिए अद्वितीय टुकड़ों का चयन करने सुनिश्चित करने हेतु पीयर के IPv4 पते से अनुमत त्वरित सेट की गणना करता है (एक उपयोगकर्ता के पास कई आईपी होने पर भी कई सेट एकत्रित नहीं कर सकता)। I2P पर, पीयर का गंतव्य हैश प्रत्येक कनेक्शन के दोनों छोरों पर उपलब्ध बाइंडिंग भूमिका निभाता है, जिससे सेट निर्धारित और स्थानीय रूप से सत्याप्य बन जाता है — जो आईपी-आधारित योजना प्रदान नहीं कर सकती।

BEP 6 में संशोधन

त्वरित एक्सटेंशन नेगोशिएशन और सभी चार संदेश प्रकार बिना किसी परिवर्तन के अपनाए गए हैं:

  • निगोशिएशन: अंतिम आरक्षित बाइट का तीसरा सबसे कम महत्वपूर्ण बिट, reserved[7] |= 0x04, दोनों छोरों पर
  • हैव ऑल <len=0x0001><op=0x0E>, हैव नोन <len=0x0001><op=0x0F>
  • सुझाव पीस <len=0x0005><op=0x0D><index>
  • अनुरोध अस्वीकृत करें <len=0x000D><op=0x10><index><begin><length>
  • अनुमत फास्ट <len=0x0005><op=0x11><index>
  • प्रत्येक अनुरोध का परिणाम ठीक एक प्रतिक्रिया (पीस या अस्वीकृत) होता है; चोक अब लंबित अनुरोधों को अंतर्निहित रूप से अस्वीकार नहीं करता है

एकल विचलन अनुमत त्वरित सेट उत्पादन में है, जहाँ समकक्ष के गंतव्य हैश के बाइट्स के साथ आईपी बाइट्स को प्रतिस्थापित किया जाता है।

विचलन: मास्क किए गए आईपी के बजाय हैश बाइट्स

संदर्भ BEP 6, चरण (1):

x = 0xFFFFFF00 & ip

यह पीयर के IPv4 पते के तीन बाइट लेता है और चौथे बाइट को शून्य कर देता है। यह एक सबनेट ह्यूरिस्टिक है: उन उपयोगकर्ताओं को, जो एक ही /24 पर कई IP प्राप्त कर सकते हैं, कई अनुमति प्राप्त त्वरित सेट प्राप्त नहीं करने चाहिए।

हमारा I2P संस्करण इसे पीयर के 32-बाइट गंतव्य हैश के पहले चार बाइट से बदल देता है:

x = first 4 bytes of peer destination hash

संदर्भ कार्यान्वयन से अंतर:

“यह IP के 3 बाइट्स होते हैं जिसके बाद एक शून्य आता है। आपके पास हैश के 4 बाइट्स होते हैं। यह BEP 6 से अलग है क्योंकि इसमें कोई IP नहीं होता और यह चौथे बाइट को शून्य नहीं करता।”

I2P कनेक्शन के दोनों छोर पहले से ही पीयर के गंतव्य हैश को जानते हैं (यह वह पता है जिसकी ओर/जिसकी तरफ से कनेक्शन बनाया गया था), इसलिए इसके लिए कोई अतिरिक्त आदान-प्रदान, कोई NAT खोज या कोई बाहरी IP का पता लगाने की आवश्यकता नहीं होती — जो भी I2P पर मौजूद नहीं हैं।

अनुमत त्वरित उत्पादन एल्गोरिथ्म

मान लें कि hash प्राप्त करने वाले पीयर का 32-बाइट गंतव्य हैश है, infohash टोरेंट का 20-बाइट इन्फोहैश है, sz टोरेंट में पीसेज़ की संख्या है, k अनुमत त्वरित सेट में पीसेज़ की अंतिम संख्या (BEP 6 के अनुसार 10) है, और a आउटपुट सेट है:

x = hash[0:4]  ++  infohash        (1)
while |a| < k:
    x = SHA1(x)                    (2)
    for i in [0:5] and |a| < k:    (3)
        y = x[i*4 : i*4+4]         (4)
        index = y % sz             (5)
        if index not in a:         (6)
            add index to a         (7)

नोट्स:

  • गंतव्य हैश के 4 बाइट्स 3 मास्क किए गए आईपी बाइट्स को प्रतिस्थापित करते हैं। सभी चार बाइट्स हैश एंट्रॉपी ले जाते हैं; कोई भी शून्य नहीं होता।
  • BEP 6 की तरह, SHA1 श्रृंखला एक लंबी छद्म यादृच्छिक अनुक्रम उत्पन्न करती है, जिसे टुकड़ों के सूचकांक में विभाजित किया जाता है; k = 10 संदर्भ डिफ़ॉल्ट से मेल खाता है।
  • अनुमत त्वरित संदेश सलाहकारी होता है: प्राप्तकर्ता को यह मानना नहीं चाहिए कि प्रेषक के पास वह टुकड़ा है — केवल इतना कि प्रेषक दमित होने के दौरान उस टुकड़े की सेवा करेगा।

लाभ

क्षेत्रलाभ
प्रारंभ देरीनए पीयर चॉक के दौरान पहले टुकड़ों को पुल करते हैं, जिससे मल्टी-हॉप I2P टनल पर धीमे टाइट-फॉर-टैट रैंप को छोटा किया जा सकता है
निश्चिततासेट केवल गंतव्य हैश + इन्फोहैश का शुद्ध फलन है, इसलिए कोई भी लागूकरण समान सेट की गणना करता है — IP-आधारित BEP 6 के विपरीत, जहां प्रेषक का प्राप्तकर्ता के IP का दृश्य अलग हो सकता है (NAT के कारण)
सत्यापन योग्यताप्राप्त करने वाला पीयर अपना गंतव्य हैश जानता है और स्थानीय रूप से सेट की पुनः गणना व मान्यता कर सकता है, जिससे गलत तरीके से काम करने वाले प्रेषकों का पता लगाया जा सकता है
कोई IP तंत्र नहींकोई NAT पारगमन, बाह्य-IP खोज या सबनेट तर्क नहीं — ये सभी I2P पर असंभव या अर्थहीन हैं
पहचान बाइंडिंगएक गंतव्य के लिए केवल एक तेज़ सेट की अनुमति है। कई गंतव्यों वाले उपयोगकर्ता को एक-एक सेट मिलता है — यही एंटी-गेमिंग गुण clearnet पर IP मास्क द्वारा प्रदान किया गया था
गोपनीयताकभी भी कोई IP पता संचारित या गणना में संकेतित नहीं होता है
बैंडविड्थबड़े टोरेंट पर पूरे बिटफील्ड को “हैव ऑल / हैव नोन” प्रतिस्थापित करता है; रिजेक्ट अतिरंजित पुनः-अनुरोधों को हटा देता है

कार्यान्वयन पर विचार

  • पीयर पहचान: पीयर का गंतव्य हैश स्ट्रीमिंग कनेक्शन (सत्र का गंतव्य) से प्राप्त किया जाता है, और दोनों छोरों द्वारा उपयोग किया जाने वाला मान समान होता है। आउटबाउंड कनेक्शन के लिए आपके द्वारा कनेक्ट हुए गंतव्य का उपयोग करें; इनबाउंड के लिए उस गंतव्य का उपयोग करें जहाँ से कनेक्शन आया हो।
  • मार्गदर्शन (Negotiation): हैंडशेक में reserved[7] |= 0x04 भेजें; केवल तभी फ़ास्ट एक्सटेंशन संदेश भेजें जब पीयर के हैंडशेक ने भी उस बिट को सेट किया हो; यदि कोई पीयर बिना मार्गदर्शन के फ़ास्ट एक्सटेंशन संदेश भेजता है, तो कनेक्शन बंद कर दें।
  • हैव ऑल / हैव नोन: हैंडशेक के तुरंत बाद केवल एक ही भेजें—बिटफील्ड / हैव ऑल / हैव नोन। बीज (seeds) के लिए हैव ऑल, पहले पीस तक हैव नोन।
  • अनुमत त्वरित भेजने वाला पक्ष: केवल उन्हीं पीसेज को विज्ञापित करें जो आपके पास वास्तव में हैं; प्राप्तकर्ता उन्हें चोक होने के बावजूद अनुरोध कर सकता है। सर्विस किए गए सेट को सीमित करें (उदाहरण के लिए, एक पीयर से एलाउड-फ़ास्ट अनुरोध अस्वीकार करें जो पहले से ही BEP 6 दिशानिर्देश के अनुसार k पीसेज से अधिक रखता हो)।
  • अनुमत त्वरित प्राप्तकर्ता पक्ष: सेट को स्टोर करें; चोक होने के दौरान उन पीसेज के अनुरोध की अनुमति दें; वैकल्पिक रूप से अपने स्वयं के गंतव्य हैश और इन्फोहैश से सेट की पुनः गणना करके इसकी पुष्टि करें, और गणना किए गए सेट में न आने वाली पीसेज को नजरअंदाज करें।
  • अस्वीकार (Reject): प्रत्येक अनुरोध को ठीक एक प्रतिक्रिया मिलनी चाहिए; चोक होने पर, पीयर को चुपचाप बंद करने के बजाय अनुमत त्वरित सेट में न आने वाली सभी चीजें अस्वीकार करें।
  • सेट आकार: संगतता के लिए k = 10 का उपयोग करें; लोड के तहत पीयर कम k चुनने के लिए स्वतंत्र हैं, लेकिन दोनों छोरों को केवल वही विज्ञापित करना चाहिए जो वे वास्तव में सेव करेंगे।
  • पीस सीमा: index = y % sz के लिए टॉरेंट की कुल पीस संख्या sz का उपयोग किया जाना चाहिए; sz से बड़े इंडेक्स को अनदेखा करें (सावधानी के लिए), क्योंकि हैश श्रृंखला पीस सीमा के अनुसार सीमित नहीं होती।
  • पिछड़ी संगतता: जो क्लाइंट फ़ास्ट बिट का मार्गदर्शन नहीं करते हैं वे इन संदेशों को कभी नहीं देखते; कोई अन्य प्रोटोकॉल परिवर्तन आवश्यक नहीं है।

संदर्भ कार्यान्वयन

यह एल्गोरिदम छोटा और स्वतंत्र है — किसी भी भाषा में कुछ दर्जन पंक्तियाँ। नीचे दिए गए तीनों उदाहरण समान इनपुट (hash[0:4] ++ infohash, SHA1 श्रृंखला, y % sz, कैप k = 10) के लिए समान सेट की गणना करते हैं।

जावा

// I2P: peer.getPeerID().getDestHash() is the 32-byte destination hash.
// Big-endian word reads build each candidate piece index from the SHA1 chain.
import java.security.MessageDigest;
import java.util.HashSet;
import java.util.Set;

public static Set<Integer> generateAllowedFastSet(byte[] destHash, byte[] infohash, int pieces) {
    Set<Integer> rv = new HashSet<>(10);
    if (destHash == null || infohash == null || pieces <= 0) {
        return rv;
    }
    byte[] x = new byte[24];
    System.arraycopy(destHash, 0, x, 0, 4);          // 4 hash bytes, no IP, no zeroed 4th byte
    System.arraycopy(infohash, 0, x, 4, Math.min(20, infohash.length));
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    while (rv.size() < 10) {
        x = md.digest(x);
        for (int i = 0; i < 5 && rv.size() < 10; i++) {
            long y = ((x[i * 4] & 0xFFL) << 24) | ((x[i * 4 + 1] & 0xFFL) << 16)
                   | ((x[i * 4 + 2] & 0xFFL) << 8) | (x[i * 4 + 3] & 0xFFL);
            rv.add((int) (y % pieces));
        }
    }
    return rv;
}

सी++

// Peer identity input is the 32-byte destination hash available on the connection.
#include <cstdint>
#include <set>
#include <vector>

extern std::vector<uint8_t> sha1(const std::vector<uint8_t>& in); // e.g. OpenSSL SHA1()

std::set<int> generate_allowed_fast_set(const std::vector<uint8_t>& dest_hash,
                                        const std::vector<uint8_t>& infohash,
                                        int pieces) {
    std::set<int> rv;
    if (dest_hash.size() < 4 || infohash.size() < 20 || pieces <= 0) { return rv; }
    std::vector<uint8_t> x(dest_hash.begin(), dest_hash.begin() + 4); // 4 hash bytes,
                                                                      // no IP mask
    x.insert(x.end(), infohash.begin(), infohash.begin() + 20);
    while (rv.size() < 10) {
        x = sha1(x);
        for (int i = 0; i < 5 && rv.size() < 10; i++) {
            uint32_t y = (uint32_t(x[i * 4]) << 24) | (uint32_t(x[i * 4 + 1]) << 16) |
                         (uint32_t(x[i * 4 + 2]) << 8) | uint32_t(x[i * 4 + 3]);
            rv.insert(int(y % uint32_t(pieces)));
        }
    }
    return rv;
}

पायथन

import hashlib

def generate_allowed_fast_set(dest_hash: bytes, infohash: bytes, pieces: int) -> set:
    """4 bytes of the destination hash stand in for the masked IP; no byte is zeroed."""
    rv = set()
    if len(dest_hash) < 4 or len(infohash) < 20 or pieces <= 0:
        return rv
    x = dest_hash[:4] + infohash[:20]
    while len(rv) < 10:
        x = hashlib.sha1(x).digest()
        for i in range(5):
            if len(rv) >= 10:
                break
            y = int.from_bytes(x[i * 4 : i * 4 + 4], "big")
            rv.add(y % pieces)
    return rv

सुसंगतता

  • वायर-अनुकूल: सौदेबाजी बिट और संदेश प्रारूप क्लियरनेट BEP 6 के समान बाइट-समान हैं; केवल सेट-उत्पत्ति इनपुट भिन्न होता है।
  • नेटवर्क के पार अनुरूप नहीं: एक I2P क्लाइंट और एक क्लियरनेट क्लाइंट आपस में कनेक्ट नहीं कर सकते इसलिए; विचलन केवल पीयर-पहचान बाइट्स को प्रभावित करता है, कभी भी वायर प्रारूप को नहीं।
  • I2P के भीतर: इस प्रस्ताव को लागू करने वाला कोई भी क्लाइंट समान अनुमत फास्ट सेट की गणना करता है और उन्हें आपस में बदलकर सेवा और सत्यापन कर सकता है। जो क्लाइंट अनुमत फास्ट को अनदेखा करते हैं, वे इसे केवल एक नो-ऑप सलाह के रूप में मानते हैं और केवल प्रारंभ-अप लाभ खो देते हैं।

खुले प्रश्न

  1. क्या सेट आकार k को 10 पर स्थिर रखा जाना चाहिए, या लोड-अनुकूली होना चाहिए (उदाहरण के लिए, भारी अनुरोध भार के तहत कम) जैसा कि BEP 6 अनुमति देता है?
  2. क्या प्राप्तकर्ताओं को अपने स्वयं के गंतव्य हैश के खिलाफ सेट को सत्यापित करना चाहिए और गलत मिलान वाले सूचकांकों को त्याग देना चाहिए (गलत या दुर्भावनापूर्ण प्रेषकों के खिलाफ रक्षा)? अनुशंसित: हां।
  3. दिखाए गए अनुसार 4-बाइट उपसर्ग (बाइट 0-3) चुनें, या अंतिम 4 बाइट — कोई भी निश्चित 4-बाइट विंडो समान गुण प्रदान करती है; उपसर्ग संदर्भ कोड के बाइट क्रम को प्राकृतिक बनाए रखता है (hash[0:4])।

पूर्व कला

  • संदर्भ: BEP 6 फास्ट एक्सटेंशन
  • I2PSnark संदर्भ कार्यान्वयन: apps/i2psnark/java/src/org/klomp/snark/PeerState.java में PeerState.sendAllowedFast() / generateAllowedFastSet() (@since 0.9.71+)
  • यह BEP 40 (मानक पीयर प्राथमिकता) और BEP 21 (आंशिक सीड्स) के साथ संयोजन में काम करता है, जिन दोनों को I2PSnark द्वारा समर्थित किया जाता है