Sandboxed API के साथ शुरू करना

इस पेज पर, आपको Sandboxed API (SAPI) की मदद से, अपनी सैंडबॉक्स की गई C/C++ लाइब्रेरी बनाने का तरीका बताया जाएगा. हेडर फ़ाइलों में मौजूद उदाहरणों और कोड के दस्तावेज़ के साथ-साथ, इसे गाइड के तौर पर इस्तेमाल करें.

बिल्ड डिपेंडेंसी

सिस्टम पर ये डिपेंडेंसी इंस्टॉल होनी चाहिए:

  • Linux कर्नल, जिसमें यूटीएस, आईपीसी, उपयोगकर्ता, पीआईडी, और नेटवर्क नेमस्पेस के लिए सहायता उपलब्ध हो
  • Linux यूज़रस्पेस एपीआई हेडर
  • अपने कोड को कंपाइल करने के लिए: GCC 6 (वर्शन 7 या इसके बाद का वर्शन इस्तेमाल करने का सुझाव दिया जाता है) या Clang 7 (या इसके बाद का वर्शन)
  • हेडर फ़ाइलों को अपने-आप जनरेट करने के लिए: Clang Python Bindings
  • Python 3.5 या इसके बाद का वर्शन
  • Bazel का वर्शन 2.2.0 या CMake का वर्शन 3.12 या इसके बाद का वर्शन.
    • सिर्फ़ CMake के लिए: GNU Make या libcap लाइब्रेरी हेडर का कोई वर्शन और Ninja (सुझाया गया) जैसा कोई बिल्ड टूल.

Bazel का इस्तेमाल करना

Bazel को बिल्ड सिस्टम के तौर पर इस्तेमाल करने का सुझाव दिया जाता है. साथ ही, इसे इंटिग्रेट करना भी सबसे आसान है.

हमारे दस्तावेज़ में Clang कंपाइलर का इस्तेमाल किया जाता है. अगर आपको किसी खास टूलचेन (जैसे, कंपाइलर, लिंकर वगैरह) की ज़रूरत है, तो डिफ़ॉल्ट कंपाइलर टूलचेन को बदलने के तरीके के बारे में जानने के लिए, Bazel दस्तावेज़ देखें.

Debian 10 (Buster)

बिल्ड डिपेंडेंसी इंस्टॉल करने के लिए:

echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
  sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://releases.bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \
  python3-pip libclang-dev
pip3 install clang

Gentoo

कर्नेल के लिए ज़रूरी विकल्प:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

बिल्ड डिपेंडेंसी इंस्टॉल करने के लिए:

emerge dev-util/bazel dev-python/typing dev-python/clang-python

CMake का इस्तेमाल करना

CMake एक लोकप्रिय ओपन-सोर्स मेटा बिल्ड सिस्टम है. यह Ninja या Make जैसे बिल्ड टूल के लिए प्रोजेक्ट फ़ाइलें जनरेट करता है.

Debian 10 (Buster)

बिल्ड डिपेंडेंसी इंस्टॉल करने के लिए:

sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \
  python3 python3-pip libclang-dev libcap-dev
pip3 install absl-py clang

Gentoo

कर्नेल के लिए ज़रूरी विकल्प:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

बिल्ड डिपेंडेंसी इंस्टॉल करने के लिए:

emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python

डेवलपमेंट प्रोसेस

C/C++ लाइब्रेरी को सैंडबॉक्स करने के लिए, आपको अपने प्रोजेक्ट के लिए दो आइटम तैयार करने होंगे:

आपको Sandbox2 के उदाहरणों में मौजूद zlib के बारे में पता होगा. यहां पूरे प्रोग्राम (zpipe.c) को सैंडबॉक्स किया गया था. यहां दिए गए चरणों में, आपको SAPI का इस्तेमाल करके, zlib लाइब्रेरी को सैंडबॉक्स करने और सैंडबॉक्स की गई लाइब्रेरी का इस्तेमाल करने का तरीका बताया गया है.

1. तय करें कि किन फ़ंक्शन की ज़रूरत है

zlib होस्ट कोड (main_zlib.cc) को देखने पर, आपको पता चलेगा कि टूल का काम stdin से डेटा पढ़ना है. साथ ही, EOF मार्कर पढ़े जाने तक डेटा को कंप्रेस करने के लिए, zlib के deflate() फ़ंक्शन का इस्तेमाल करना है. यह प्रोग्राम, zlib के तीन फ़ंक्शन इस्तेमाल करता है:

  • deflateInit_(): कंप्रेस करने के लिए शुरू करें
  • deflate(): डेटा के हिस्से पर कंप्रेस करने की कार्रवाई करने के लिए
  • deflateEnd(): कंप्रेशन को खत्म करने और डाइनैमिक तौर पर असाइन किए गए डेटा स्ट्रक्चर को खाली करने के लिए

असल ज़िंदगी के उदाहरण में, C/C++ लाइब्रेरी की समीक्षा करके यह तय किया जाता है कि किन फ़ंक्शन की ज़रूरत है. एक रणनीति यह हो सकती है कि होस्ट कोड से शुरुआत की जाए और लाइब्रेरी को अनसैंडबॉक्स किया जाए. इसके बाद, दूसरे चरण में सैंडबॉक्स की गई लाइब्रेरी जनरेट की जा सकती है. साथ ही, सैंडबॉक्स किए गए फ़ंक्शन कॉल का इस्तेमाल करने के लिए, होस्ट कोड को अडैप्ट किया जा सकता है.

2. sapi_library के लिए Build Rule लिखना

सैंडबॉक्स की गई zlib लाइब्रेरी से ज़रूरी तीन zlib फ़ंक्शन की पहचान करने के बाद, BUILD फ़ाइल में बिल्ड रूल तय किया जा सकता है. sapi_library बिल्ड के नियम से जुड़ा दस्तावेज़, बिल्ड के नियम पेज पर देखा जा सकता है.

यहां दिए गए कोड स्निपेट में, zlib SAPI के उदाहरण के लिए sapi_library की परिभाषा दी गई है. lib एट्रिब्यूट का इस्तेमाल करके, Bazel को zlib लाइब्रेरी के लिए WORKSPACE फ़ाइल में देखने का निर्देश दिया जाता है.

sapi_library(
    name = "zlib-sapi",
    srcs = [],
    hdrs = [],
    functions = [
        "deflateInit_",
        "deflate",
        "deflateEnd",
    ],
    lib = "@net_zlib//:zlib",
    lib_name = "Zlib",
    namespace = "sapi::zlib",
)

इससे सैंडबॉक्स की गई zlib लाइब्रेरी जनरेट होती है. आउटपुट, SAPI ऑब्जेक्ट होता है. इसे होस्ट कोड में शामिल किया जा सकता है. साथ ही, इसका इस्तेमाल आरपीसी कॉल का इस्तेमाल करके, सैंडबॉक्स की गई लाइब्रेरी से कम्यूनिकेट करने के लिए किया जा सकता है.

इस उदाहरण में, DefaultConfig (sapi::SandboxConfig::DefaultConfig()) से मिले डिफ़ॉल्ट सैंडबॉक्स कॉन्फ़िगरेशन का इस्तेमाल किया गया है.

3. होस्ट कोड लिखना या बदलना

अब जनरेट की गई SAPI लाइब्रेरी को होस्ट कोड में शामिल करें.

सैंडबॉक्स बनाना

सैंडबॉक्स ऑब्जेक्ट बनाने के लिए, sapi::zlib::ZlibSandbox sandbox; का इस्तेमाल करें.

SAPI ऑब्जेक्ट को इंस्टैंशिएट करने के लिए, sapi::zlib::ZlibApi api(&sandbox); का इस्तेमाल करें. इससे सैंडबॉक्स किए गए फ़ंक्शन इस्तेमाल के लिए उपलब्ध हो जाते हैं.

सैंडबॉक्स की नीति, फ़्लैग, एनवायरमेंट वैरिएबल या सीमाओं को पसंद के मुताबिक बनाने के लिए, sapi::SandboxConfig::DefaultConfig() से शुरू करें. इसके बाद, काम के फ़ील्ड में बदलाव करें. इसके लिए, sapi::Sandbox2Config::DefaultPolicyBuilder(), sapi::SandboxConfig::DefaultFlags() या sapi::SandboxConfig::DefaultEnvironmentVariables() का इस्तेमाल करें, ताकि बेसलाइन सेटिंग सुरक्षित रहें. इसके बाद, sapi::SandboxConfig को सैंडबॉक्स कंस्ट्रक्टर को पास करें:

sapi::SandboxConfig config = sapi::SandboxConfig::DefaultConfig();
config.sandbox2.policy = sapi::Sandbox2Config::DefaultPolicyBuilder()
                             .AddFile("/path/to/file")
                             .BuildOrDie();
auto flags = sapi::SandboxConfig::DefaultFlags();
flags["my_flag"] = "value";
config.command_line_flags = std::move(flags);

sapi::zlib::ZlibSandbox sandbox(std::move(config));

SAPI टाइप का इस्तेमाल करना

SAPI टाइप, C++ क्लास के तौर पर खास टाइप होते हैं. इन्हें SAPI उपलब्ध कराता है, क्योंकि कभी-कभी सामान्य C-टाइप काम नहीं करते.

SAPI टाइप का पहली बार इस्तेमाल, strm के एलान में किया गया है. यहां SAPI Struct का इस्तेमाल किया गया है: sapi::v::Struct<sapi::zlib::z_stream> strm;

टेंप्लेट टाइप (sapi::zlib::z_stream), कोड का एक अच्छा उदाहरण है. यह कोड, बिल्ड रूल के ज़रिए अपने-आप जनरेट होता है.

ज़्यादा जानकारी के लिए, वैरिएबल पेज देखें.

एपीआई कॉल करना

defalteInit_, deflate या deflateEnd को कॉल करने के लिए, SAPI ऑब्जेक्ट का इस्तेमाल करें. अगर आपको ‘बदलाव करें' अप्रोच का इस्तेमाल करना है, तो आपको यह पक्का करना होगा कि फ़ंक्शन के पैरामीटर, अनुमानित वैल्यू से मेल खाते हों.

zlib के उदाहरण में हर कॉल का एक उदाहरण:

  • api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
        version.PtrBefore(), sizeof(sapi::zlib::z_stream));
  • api.deflate(strm.PtrBoth(), flush);
  • api.deflateEnd(strm.PtrBoth()).IgnoreError();

SAPI Transactions का इस्तेमाल करना

SAPI, होस्ट कोड को सैंडबॉक्स की गई लाइब्रेरी से अलग करता है. साथ ही, कॉलर को डेटा प्रोसेसिंग के अनुरोधों को रीस्टार्ट करने या रद्द करने की सुविधा देता है. SAPI ट्रांज़ैक्शन एक कदम आगे बढ़कर, फ़ेल हुई प्रोसेस को अपने-आप दोहराता है.

ज़्यादा जानकारी के लिए, SAPI लेन-देन पेज देखें.

उदाहरण

उदाहरण सेक्शन में, आपको कुछ लाइब्रेरी मिल सकती हैं. इन्हें SAPI टीम ने पहले ही तैयार कर लिया है.