OpenVPN হুক ইভেন্ট: নাম ও টাইমস্ট্যাম্প কেন চাবি নয়
ডিসকানেক্ট হুক সংযোগের সময় জানায়, বিচ্ছিন্ন হওয়ার সময় নয়। ব্যবহারকারীর নামের সঙ্গে মিলিয়ে এটি ভুল সেশন বন্ধ করতে পারে; বরং একটি পরিচয়ের মালিক হোন।
একই নামে দ্বিতীয় সংযোগ শুরু হয়ে যাওয়ার পর একটি ডিসকানেক্ট রেকর্ড আসে, আর যে হ্যান্ডলার ওই ব্যবহারকারীর সবচেয়ে নতুন সারি হালনাগাদ করে সে ভুল সেশন বন্ধ করে। ভুলটি টাইমস্ট্যাম্প তুলনায় নয়। ভুলটি এই ধারণায় যে একটি নাম আর একটি পূর্ণ সেকেন্ড মিলে একটি সেশন চিহ্নিত করে। হুক ইভেন্ট সংযোগের বর্ণনা দেয়, আর একটি সংযোগের এমন একটি চাবি দরকার যা কেবল তারই।
ডিসকানেক্ট ভেরিয়েবলগুলোর প্রকৃত অর্থ দিয়ে শুরু করুন। কেবল তখনই শনাক্তকারীর পছন্দ অর্থবহ হয়।
ডিসকানেক্ট হুক আসলে কী বহন করে
Community OpenVPN 2.6-এ হুক রেফারেন্স time_unix কে সেই মুহূর্ত হিসেবে সংজ্ঞায়িত করে যখন ক্লায়েন্ট সংযুক্ত হয়; এটি কানেক্ট হুক চলার আগে সেট হয় এবং পরে ডিসকানেক্ট হুক চালু হলে পুনরায় সংজ্ঞায়িত হয় না। time_duration সেই সেশনের দৈর্ঘ্য সেকেন্ডে দেয়, তাই শেষটি মোটামুটি সংযোগের সময় যোগ স্থায়িত্ব। দুটিই পূর্ণ সেকেন্ড, এবং কোনোটিই সেই মুহূর্ত নয় যখন আপনার ডেটাবেস ইভেন্টটি প্রক্রিয়া করেছে। এই তিনটি সময় আলাদা রাখাই একটি সম্পর্ককে টিকে থাকতে দেয়, কেবল পরীক্ষার সময় ঠিক দেখাতে দেয় না।
এই গণিতটি লিখে রাখার যোগ্য, কারণ এটি হুক নিজেই যে একমাত্র সমাপ্তি সময় দেয়। প্রক্রিয়াকরণের বিলম্ব এবং হোস্টগুলোর মধ্যে ঘড়ির পার্থক্য এখনও এর বাইরে থাকে।
কেন সুস্পষ্ট জোড়াটি অনন্য নয়
নামের সঙ্গে সংযোগের সময় জোড়া দিলে অনুসন্ধান সংকুচিত হয়, তবুও সেশন শনাক্ত হয় না। ক্লায়েন্ট একই সেকেন্ডের মধ্যে আবার সংযুক্ত হতে পারে, তাই দুটি সেশন দুই মানই ভাগ করতে পারে। দুটি ডেমন ইনস্ট্যান্স, বা একই কনফিগারেশন ধরে রাখা একটি সার্ভার প্রতিস্থাপন, ভিন্ন প্রসেস থেকে ওই জোড়া তৈরি করতে পারে। টানেল ঠিকানাগুলোও একই কারণে পুনর্ব্যবহৃত হয়, যা সেগুলোকে সেশনের বৈশিষ্ট্য করে তোলে, সেশনের শনাক্তকারী নয়।
ব্যর্থতার ধরনটি নীরব। প্রথম সেশনের জন্য দেরিতে আসা ডিসকানেক্ট সবচেয়ে নতুন সারির সঙ্গে মেলে এবং দ্বিতীয় সেশন যে বরাদ্দ এখনও ব্যবহার করছে তা অবসর দেয়, ফলে ব্যবহারকারী এলোমেলোভাবে অ্যাক্সেস হারায় যা ঘটানোর জন্য সে কিছু করেনি। পরে সারির সংখ্যা ঠিক দেখালে সমস্যাটি ধরা আরও কঠিন হয়।
স্থিতিশীল পরিচয় কোথা থেকে আসে
ম্যানেজমেন্ট ইন্টারফেস প্রতিটি ক্লায়েন্টকে একটি ক্লায়েন্ট-ইনস্ট্যান্স শনাক্তকারী দেয়, এবং সেই শনাক্তকারী কেবল সেই ডেমন ইনস্ট্যান্সে সীমিত যা এটি জারি করেছে। কার্যকর বাহ্যিক চাবি একটি স্থিতিশীল সার্ভার শনাক্তকারী, ডেমন শুরু হলে বদলে যাওয়া একটি ইপক এবং সেই ক্লায়েন্ট ID একত্র করে। ইপক গুরুত্বপূর্ণ কারণ প্রসেসের সঙ্গে শনাক্তকারী পুনরায় শুরু হয়, আর একটি খালি প্রসেস ID পরে অসম্পর্কিত কিছু দ্বারা পুনর্ব্যবহৃত হতে পারে।
একটি চাইল্ড কানেক্ট স্ক্রিপ্টের ভিতরে সেট করা পরিবেশ চলক প্যারেন্ট ডেমনের পরবর্তী ডিসকানেক্ট স্ক্রিপ্টে যায় না, কারণ সেই স্ক্রিপ্টগুলো নিজস্ব পরিবেশসহ আলাদা প্রসেস হিসেবে চলে। তাই সংযোগের সময় UUID তৈরি করা সমাধানের অর্ধেক মাত্র। ডিসকানেক্ট দিকটিকে একই UUID নাম দিতে সক্ষম হতে হবে, যার অর্থ পরিচয়টিকে এমন জায়গায় থাকতে হবে যেখানে উভয় ইভেন্ট পৌঁছাতে পারে।
অবসরকে শর্তসাপেক্ষ ও ইডেম্পোটেন্ট করুন
সেশন মালিকের ভিত্তিতে অবসর দিন, ব্যবহারকারীর ভিত্তিতে নয়। যে হ্যান্ডলার কোনো একটি নামের অধীনে থাকা যেকোনো বরাদ্দ মুছে ফেলে সে শেষ পর্যন্ত ভুলটিই মুছে ফেলবে, আর একমাত্র প্রতিরক্ষা হলো যাচাই করা যে যে রেকর্ডটি সরানো হচ্ছে সেটিই এই ইভেন্টের বর্ণিত রেকর্ড।
ম্যানেজমেন্ট ইন্টারফেস একসঙ্গে কেবল একটি সংযুক্ত ম্যানেজমেন্ট ক্লায়েন্ট গ্রহণ করে, তাই একই সকেটের জন্য প্রতিযোগী দ্বিতীয় পর্যবেক্ষক যোগ না করে যার কাছে এটি ইতিমধ্যে আছে তার সঙ্গে সংহত হোন।
পুনরাবৃত্ত ইভেন্টগুলো ফলাফল দুইবার না বদলে সামলান, এবং জোড়াহীন ইভেন্টগুলো ফেলে না দিয়ে পুনর্মিলনের জন্য রাখুন। ডিসকানেক্ট কলব্যাকের জীবনচক্রের শর্তগুলো নথিভুক্ত এবং ক্র্যাশ বা জোরপূর্বক বন্ধের পরে সেটি কখনও নাও আসতে পারে, তাই ডিজাইনে এমন একটি সেশন উপস্থাপনের উপায় দরকার যার সমাপ্তি ইভেন্ট অনুপস্থিত।
অসুবিধাজনক কেসগুলো ইচ্ছাকৃতভাবে পরীক্ষা করুন: এক সেকেন্ডের মধ্যে দুটি পুনঃসংযোগ, দুটি ডেমন ইনস্ট্যান্স, একটি সংযোগ যার প্রক্রিয়াকরণ ব্যর্থ হয়েছে, এবং সেশনের মাঝখানে ডেমন পুনরায় চালু। যে চাবি চারটিকেই টিকিয়ে রাখে সেটিই আস্থার যোগ্য।