“রেসিডেন্ট সার্ভিস ও সেটিংস UI-এর মধ্যে কমান্ড বিনিময় করতে চাই।” “শুধু অ্যাডমিনিস্ট্রেটর সুবিধা দরকার এমন কাজ আলাদা প্রক্রিয়ায় আলাদা করতে চাই।” “একই PC-এর টুলগুলো পরস্পর ডেটা পাঠাতে চাই।” — Windows-এ এই ধরনের আন্তঃপ্রক্রিয়া যোগাযোগ (IPC) দরকার হলে প্রথমে বিবেচনা করার মানক হলো নেমড পাইপ।
Windows আন্তঃপ্রক্রিয়া যোগাযোগ বেছে নেওয়ার নিবন্ধ নেমড পাইপকে “একই-মেশিন IPC-এর প্রথম প্রার্থী” হিসেবে রেখেছিল। এই নিবন্ধ সেই বিস্তারিত আলোচনা। কেন সেগুলো প্রথম প্রার্থী, মোড ও সার্ভার আকৃতি কীভাবে বেছে নেবেন, আর সুবিধাপ্রাপ্ত সার্ভিস ব্যবহার করলে কী রক্ষা করতেই হবে — Windows-এ ব্যবসায়িক অ্যাপ ও সার্ভিস লেখা ডেভেলপারদের লক্ষ্য করে প্রাথমিক উৎস থেকে সেই ডিজাইন-বিচার সাজায়।
১. আগে উপসংহার
- নেমড পাইপ হলো
\\.\pipe\nameআকারের নেমস্পেসযুক্ত দ্বিমুখী আন্তঃপ্রক্রিয়া চ্যানেল। একই নামে একাধিক ইনস্ট্যান্স তৈরি করে একসঙ্গে কয়েকজন ক্লায়েন্ট গ্রহণ করা যায়।1 - একই-মেশিন IPC-এর প্রথম প্রার্থী হওয়ার কারণ নিরাপত্তা মডেল। ACL দিয়ে কে সংযোগ করবে তা নিয়ন্ত্রণ করা যায়, আর সার্ভার ক্লায়েন্টের Windows অ্যাকাউন্ট দেখতে ও ধার (ইমপারসোনেট) করতে পারে। Localhost TCP-এ এর কোনোটাই নেই।2
- “একটি লেখা = একটি মেসেজ” ধরতে চাইলে মেসেজ মোড; নিজের ফ্রেমিং থাকলে বাইট মোড। মেসেজ মোডেও ছোট বাফারে স্প্লিট রিড (ERROR_MORE_DATA) সামলাতে হয়।3
- একাধিক ক্লায়েন্ট “কয়েকটি ইনস্ট্যান্স + overlapped I/O” অথবা “.NET async/await” দিয়ে সামলান। অফিসিয়াল নমুনা একটি থ্রেডে একাধিক ইনস্ট্যান্স প্রক্রিয়া করার আকৃতি দেখায়।4
- নিরাপত্তার ন্যূনতম চারটি বিষয়: রিমোট প্রত্যাখ্যান (PIPE_REJECT_REMOTE_CLIENTS), ACL স্পষ্ট করা, FILE_FLAG_FIRST_PIPE_INSTANCE দিয়ে হাইজ্যাক ধরা, আর ক্লায়েন্ট পাশে ইমপারসোনেশন লেভেল কমানো।56
ImpersonateNamedPipeClient-এ রিটার্ন মান যাচাইই জীবনরেখা। ব্যর্থতা উপেক্ষা করলে প্রক্রিয়া সার্ভারের সুবিধায় চলতে থাকে।6
২. নেমড পাইপ কী — নেমস্পেস, ইনস্ট্যান্স ও সংযোগ কীভাবে হয়
নেমড পাইপ \\.\pipe\MyCompany.MyApp.Control-এর মতো নামে চিহ্নিত চ্যানেল। সার্ভার CreateNamedPipe দিয়ে তৈরি করে, ক্লায়েন্ট একই নাম CreateFile দিয়ে খোলে। খোলার পর দুই পাশ ReadFile / WriteFile দিয়ে পড়ে ও লেখে — বিশেষত্ব হলো ফাইল I/O-এর একই আকৃতিতে ব্যবহার করা যায়।1
গুরুত্বপূর্ণ ধারণা ইনস্ট্যান্স। একই নামের পাইপের একাধিক ইনস্ট্যান্স তৈরি করা যায়, আর একটি ইনস্ট্যান্স একটি ক্লায়েন্টের সাথে একটি চ্যানেল। প্রথম CreateNamedPipe কল সর্বোচ্চ ইনস্ট্যান্স সংখ্যা (অথবা সীমাহীন) ঠিক করে।3
ক্লায়েন্ট-পাশের সংযোগের একটি মানক রেসিপি আছে। সব ইনস্ট্যান্স ব্যবহৃত থাকলে CreateFile ERROR_PIPE_BUSY দিয়ে ব্যর্থ হয়, তাই WaitNamedPipe দিয়ে খালিটির জন্য অপেক্ষা করে আবার চেষ্টা করুন। আর খোলার সময় যে অ্যাক্সেস নির্দিষ্ট করেন তা সার্ভার যে দিক তৈরি করেছে তার সাথে মেলাতে হয় — দ্বিমুখী পাইপ রিড বা রাইট যেকোনোটা দিয়ে খোলা যায়, কিন্তু সার্ভার শুধু লেখে এমন আউটবাউন্ড পাইপ রিড-ওনলি খুলতে হয়, আর সার্ভার শুধু পড়ে এমন ইনবাউন্ড পাইপ রাইট-ওনলি খুলতে হয়, নাহলে CreateFile ব্যর্থ হয়।7
flowchart TB
accTitle: পাইপের দিক ও ক্লায়েন্টের অ্যাক্সেস নির্দিষ্টকরণ
accDescr: ক্লায়েন্ট দ্বিমুখী পাইপ রিড বা রাইট যেকোনোটা দিয়ে খুলতে পারে, কিন্তু সার্ভার শুধু লেখে এমন আউটবাউন্ড পাইপ রিড-ওনলি, আর সার্ভার শুধু পড়ে এমন ইনবাউন্ড পাইপ রাইট-ওনলি খুলতে হয়
q{"সার্ভার যে দিক তৈরি করেছে?"} -->|"দ্বিমুখী"| dc["রিড বা রাইট দুটোই চলে"]
q -->|"আউটবাউন্ড"| oc["রিড-ওনলি খুলুন"]
q -->|"ইনবাউন্ড"| ic["রাইট-ওনলি খুলুন"]
চিত্র ১: দিক ও অ্যাক্সেস নির্দিষ্টকরণের অমিল CreateFile ব্যর্থতা হয়ে ওঠে। সংযোগ ত্রুটি অনুসন্ধানে প্রথমে এখানে দেখুন।
flowchart TB
accTitle: নেমড পাইপের মৌলিক কাঠামো
accDescr: সার্ভার একই নামের একাধিক পাইপ ইনস্ট্যান্স তৈরি করে ConnectNamedPipe দিয়ে সংযোগের অপেক্ষা করে; প্রতিটি ক্লায়েন্ট CreateFile দিয়ে নাম খোলে এবং একটি ইনস্ট্যান্সের সাথে এক-এক দ্বিমুখী চ্যানেল পায়
s["সার্ভার"] --> i1["ইনস্ট্যান্স ১"]
s --> i2["ইনস্ট্যান্স ২"]
s --> i3["ইনস্ট্যান্স ৩"]
c1["ক্লায়েন্ট A"] <--> i1
c2["ক্লায়েন্ট B"] <--> i2
c3["ক্লায়েন্ট C"] <--> i3
চিত্র ২: একই নামের কয়েকটি ইনস্ট্যান্স ধরে একটি সার্ভার একসঙ্গে কয়েকজন ক্লায়েন্টের সাথে এক-এক করে কথা বলতে পারে।
নেমড পাইপ SMB-এর উপর দিয়ে রিমোটও খোলা যায় (\\server\pipe\name), কিন্তু আধুনিক ডিজাইনে তা সক্রিয়ভাবে ব্যবহার করার প্রায় কোনো কারণ নেই; বিষয়টি বরং ব্যবহার না করলে খোলা না রাখা (অধ্যায় ৫)।
৩. বাইট মোড ও মেসেজ মোড
পাইপের দুটি ট্রান্সফার মোড আছে।3
- বাইট মোড (PIPE_TYPE_BYTE): TCP-এর মতো “অবিচ্ছিন্ন বাইট স্ট্রিম”। একটি মেসেজ কোথায় শেষ তা আপনিই ঠিক করেন (দৈর্ঘ্য-প্রিফিক্সের মতো ফ্রেমিং ডিজাইন করেন)।
- মেসেজ মোড (PIPE_TYPE_MESSAGE + PIPE_READMODE_MESSAGE): একটি লেখা একটি মেসেজ হিসেবে ধরা হয়, আর রিডার সেই এককেই পায়। রিকোয়েস্ট/রেসপন্স বিনিময়ের জন্য এটা সহজ।
মেসেজ মোডের একটি সুবিধাজনক সঙ্গীও আছে, TransactNamedPipe, যা একটি কলেই অনুরোধ পাঠায় ও উত্তর পায়।8 তবে একটি ফাঁদ আছে। রিসিভ বাফার পুরো মেসেজের চেয়ে ছোট হলে রিড ERROR_MORE_DATA ফেরায় এবং স্প্লিট রিড হয়ে যায়। মেসেজ মোড মানে “একটি Read সবসময় পুরোটা আনে” ধরে নেবেন না; বাকিটা পড়ার লুপ এখনও লিখতে হয়। লক্ষ করুন, রিড মোড হ্যান্ডেলপ্রতি সেটিং, আর CreateNamedPipe শুধু সার্ভার পাশে সেটা ঠিক করে। ক্লায়েন্ট CreateFile-এর পর SetNamedPipeHandleState দিয়ে নির্দিষ্ট করে (.NET-এ সংযোগের পর ReadMode)।7
flowchart TB
accTitle: মেসেজ মোডে স্প্লিট-রিড লুপ
accDescr: ReadFile সফল হলে মেসেজ সম্পূর্ণ; ERROR_MORE_DATA ফেরালে বাফারে না-ধরা বাকিটা পড়ে জোড়া লাগান; অন্য যেকোনো ত্রুটি বিচ্ছিন্নতা হিসেবে ধরুন
read["ReadFile দিয়ে পড়ুন"] --> r{"ফলাফল?"}
r -->|"সফল"| done["মেসেজ সম্পূর্ণ"]
r -->|"ERROR_MORE_DATA"| more["বাকিটা পড়ে জোড়া লাগান"]
more --> read
r -->|"অন্য যেকোনো ত্রুটি"| dis["বিচ্ছিন্নতা হিসেবে ধরুন"]
চিত্র ৩: মেসেজ মোডেও “বাকিটা-পড়ার লুপ” দরকার; না থাকলে শুধু বড় মেসেজই ভাঙে।
flowchart TB
accTitle: বাইট মোড ও মেসেজ মোডের পার্থক্য
accDescr: বাইট মোডে তিনটি লেখা অবিচ্ছিন্ন বাইট স্ট্রিম হয়ে যায় এবং প্রাপককে ভাগ করতে হয়; মেসেজ মোডে প্রতিটি লেখার একক সংরক্ষিত থাকে এবং প্রাপকের কাছে সেভাবেই পৌঁছায়
bw["বাইট মোড: AAA, BB, CCCC লেখা"] --> br["বাইট স্ট্রিম AAABBCCCC হিসেবে প্রাপ্ত"]
br --> bf["ফ্রেমিং নিজে ডিজাইন করুন"]
mw["মেসেজ মোড: একই তিনটি লেখা"] --> mr["তিন মেসেজ: AAA, BB, CCCC"]
mr --> mf["লেখার একক সংরক্ষিত"]
চিত্র ৪: মেসেজ মোড “একটি লেখার একক” সংরক্ষণ করে পৌঁছে দেয়। ফ্রেমিং ডিজাইন অপ্রয়োজনীয় হয়ে যায়; শুধু স্প্লিট রিড সামলাতে ভুলবেন না।
কোনটি বেছে নেওয়ার ব্যবহারিক নিয়ম সরল। বিনিময় “অনুরোধ ও উত্তর” আকৃতির হলে মেসেজ মোড। ইতিমধ্যে ফ্রেমিংযুক্ত রূপ বহন করলে (দৈর্ঘ্য-প্রিফিক্সযুক্ত সিরিয়ালাইজড ডেটা বা স্ট্রিম ট্রান্সফার)** বাইট মোড ব্যবহার করুন**। .NET-এ PipeTransmissionMode.Message নির্দিষ্ট করা আগেরটির সমতুল্য।9
৪. সার্ভার ডিজাইন — প্রতি ক্লায়েন্টে একটি থ্রেড, নাকি Overlapped?
সার্ভারের মৌলিক কাজ হলো “ইনস্ট্যান্স তৈরি → ConnectNamedPipe দিয়ে ক্লায়েন্টের অপেক্ষা → পড়া ও লেখা → বিচ্ছিন্ন করে পরের ক্লায়েন্টে যাওয়া” লুপ। একসঙ্গে কয়েকজন ক্লায়েন্টের সাথে কথা বলার দুটি আকৃতি আছে।
সিঙ্ক্রোনাস, প্রতি ইনস্ট্যান্সে একটি থ্রেড। প্রতিটি ইনস্ট্যান্সে একটি থ্রেড দেন, আর প্রত্যেকে সিঙ্ক্রোনাস I/O দিয়ে নিজের ক্লায়েন্টের সাথে কথা বলে। কোড সরল, কিন্তু প্রতি ক্লায়েন্টে একটি থ্রেড খরচ হয়, আর পুরো জিনিস বন্ধ করার সময় ব্লকিং I/O থেকে বেরোনোর উপায়ও লাগে।
Overlapped (অ্যাসিঙ্ক্রোনাস)। FILE_FLAG_OVERLAPPED দিয়ে ইনস্ট্যান্স তৈরি করেন, ConnectNamedPipe / ReadFile / WriteFile অ্যাসিঙ্ক্রোনাস ইস্যু করেন, আর অল্প কয়েকটি থ্রেড প্রতিটি ইনস্ট্যান্সের সম্পূর্ণি গ্রহণ করে। Microsoft-এর অফিসিয়াল নমুনা WaitForMultipleObjects দিয়ে ইভেন্ট অ্যারের অপেক্ষা করে একটি থ্রেডে একাধিক ইনস্ট্যান্স প্রক্রিয়া করা সার্ভার দেখায়।4 অ্যাসিঙ্ক্রোনাস I/O-এর সাধারণ বর্ণনা I/O সিরিজের নিবন্ধে আছে, আর বড় স্কেলে IOCP বা থ্রেড-পুল I/Oও জোড়া যায়।
flowchart TB
accTitle: overlapped সার্ভারের কাঠামো
accDescr: প্রতিটি ইনস্ট্যান্সের অ্যাসিঙ্ক্রোনাস অপারেশনের সম্পূর্ণি ইভেন্ট অ্যারেতে আসে, অল্প কয়েকটি থ্রেড WaitForMultipleObjects দিয়ে অপেক্ষা করে সম্পূর্ণ ইনস্ট্যান্স এগোয়, থ্রেড সংখ্যা ক্লায়েন্ট সংখ্যা থেকে আলাদা হয়
i1["ইনস্ট্যান্স ১ অ্যাসিঙ্ক কাজ"] --> ev["ইভেন্টের অ্যারে"]
i2["ইনস্ট্যান্স ২ অ্যাসিঙ্ক কাজ"] --> ev
i3["ইনস্ট্যান্স ৩ অ্যাসিঙ্ক কাজ"] --> ev
ev --> wait["WaitForMultipleObjects-এ অপেক্ষা"]
wait --> proc["সম্পূর্ণ ইনস্ট্যান্স এগোান"]
proc --> wait
চিত্র ৫: overlapped আকৃতি থ্রেড সংখ্যাকে ক্লায়েন্ট সংখ্যা থেকে আলাদা করে। অফিসিয়াল নমুনা এই চক্র একটি থ্রেডে ঘোরায়।
.NET প্রায় এই পছন্দ মুছে দেয়। NamedPipeServerStream-এর WaitForConnectionAsync / ReadAsync / WriteAsync async/await-এর সাথে ব্যবহার করে সিঙ্ক্রোনাস আকৃতির মতোই সরল কোডে overlapped দক্ষতা পাওয়া যায়।9
// C#: skeleton of a server that accepts multiple clients
while (!token.IsCancellationRequested)
{
var server = new NamedPipeServerStream(
"MyCompany.MyApp.Control",
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Message,
PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly);
try
{
await server.WaitForConnectionAsync(token);
}
catch
{
await server.DisposeAsync(); // dispose yourself when leaving before a connection
throw;
}
_ = HandleClientAsync(server, token); // ownership after connect goes to the handler
}
PipeOptions.CurrentUserOnly হলো “শুধু একই ব্যবহারকারীর প্রক্রিয়া থেকে সংযোগ অনুমোদন” স্পেসিফিকেশন, ACL নিজে না লিখেও সুবিধাজনক ও নিরাপদ ডিফল্ট।10 ব্যবহারকারী পেরিয়ে যাওয়া সেটআপে (সার্ভিস ↔ ইউজার সেশনের অ্যাপ ইত্যাদি) ব্যবহার করা যায় না, তাই সেক্ষেত্রে পরের অধ্যায়ের ACL ডিজাইনে যান।
flowchart TB
accTitle: .NET অ্যাসিঙ্ক্রোনাস সার্ভারের অ্যাকসেপ্ট লুপ
accDescr: অ্যাকসেপ্ট লুপ NamedPipeServerStream তৈরি করে, WaitForConnectionAsync দিয়ে সংযোগের অপেক্ষা করে, এলে ক্লায়েন্ট হ্যান্ডলিং অ্যাসিঙ্ক্রোনাস আলাদা করে সঙ্গে সঙ্গে পরের অ্যাকসেপ্টে ফেরে, তাই সমকালীন সংযোগ সরল কোডে সামলানো যায়
mk["সার্ভার স্ট্রিম তৈরি"] --> wc["WaitForConnectionAsync-এ অপেক্ষা"]
wc --> got["সংযোগ আসে"]
got --> hd["ক্লায়েন্ট হ্যান্ডলিং আলাদা করুন"]
hd --> mk
চিত্র ৬: অ্যাকসেপ্ট লুপ “অপেক্ষা → আলাদা → পরেরটা” চক্রেই থাকে, আর প্রতিটি ক্লায়েন্টের প্রক্রিয়া সমান্তরালে চলে।
৫. নিরাপত্তা — সুবিধাপ্রাপ্ত সার্ভিস পাইপ ব্যবহার করলে চারটি অবশ্যকর্তব্য
নেমড পাইপ একই-মেশিন IPC-এর প্রথম প্রার্থী হওয়ার সবচেয়ে বড় কারণ নিরাপত্তা মডেল, কিন্তু তা শুধু সঠিকভাবে কনফিগার করলে। বিশেষ করে “অ্যাডমিনিস্ট্রেটর-সুবিধা সার্ভিস + নিম্ন-সুবিধা UI অ্যাপ” ব্রোকার ডিজাইনে পাইপই সুবিধার সীমানা। চারটি বিষয় পেরেক গেড়ে রাখুন।
(১) রিমোট প্রত্যাখ্যান করুন। স্থানীয় IPC হিসেবে ভাবা পাইপ নেটওয়ার্ক থেকে খোলা যাওয়াই আক্রমণপৃষ্ঠ। CreateNamedPipe-এ PIPE_REJECT_REMOTE_CLIENTS নির্দিষ্ট করলে রিমোট-ক্লায়েন্ট সংযোগ স্বয়ংক্রিয় প্রত্যাখ্যাত হয়।5
(২) ACL স্পষ্ট করুন। SECURITY_ATTRIBUTES-এ সিকিউরিটি ডেস্ক্রিপ্টর পাস করে সংযোগ অনুমোদিত ব্যবহারকারী ও গ্রুপ সংকুচিত করুন। ক্লায়েন্টকে GENERIC_WRITE দেবেন না — তার ভেতরের FILE_CREATE_PIPE_INSTANCE অধিকার অনুমোদিত ক্লায়েন্টকেই একই নামের সার্ভার ইনস্ট্যান্স তৈরি করে পরের সংযোগ চুরি করতে দেয়। রিড ও রাইট আলাদা অধিকার হিসেবে দিন, ইনস্ট্যান্স-তৈরির অধিকার দেবেন না।11
(৩) নাম হাইজ্যাক ঠেকান। পাইপের নাম আগে-আসা আগে-পাওয়া। ক্ষতিকর প্রক্রিয়া একই নামের পাইপ আগে তৈরি করে অপেক্ষা করলে ক্লায়েন্ট নকল সার্ভারে সংযোগ করে। সার্ভার প্রথম ইনস্ট্যান্স তৈরির সময় FILE_FLAG_FIRST_PIPE_INSTANCE নির্দিষ্ট করে “আমিই প্রথম” নিশ্চিত করে, আর তা ব্যর্থ হলে হাইজ্যাক সন্দেহ করে থামে। এই ফ্ল্যাগ শুধু নাম দাবি করা প্রথম ইনস্ট্যান্সের জন্য; দ্বিতীয় ও পরের ইনস্ট্যান্সে দিলে তৈরি ব্যর্থ হয়।3
(৪) ক্লায়েন্ট ইমপারসোনেশন লেভেল প্রয়োজনমতো কমায়। পক্ষ নকল সার্ভার হলে সেই প্রস্তুতি। ক্লায়েন্ট CreateFile-এ **SECURITY_SQOS_PRESENT |
SECURITY_IDENTIFICATION** নির্দিষ্ট করলে সার্ভার ক্লায়েন্ট চিনতে পারে কিন্তু সেই সুবিধা ধার করে কাজ করতে পারে না।2 তবে ইমপারসোনেশন ওয়ার্কফ্লোর সাথে এটি ট্রেড-অফ — যে ব্রোকার ডিজাইনে সার্ভার ক্লায়েন্টের সুবিধায় সত্যিকারের অ্যাক্সেস করে, সেখানে আইডেন্টিফিকেশন লেভেলে ইমপারসোনেশন সফল হয় না, SECURITY_IMPERSONATION অনুমোদন করতে হয়। সেই অনুমোদন শর্তসাপেক্ষ: সত্যিকারের সার্ভারেই সংযুক্ত আছেন নিশ্চিত হলে। সার্ভার-পাশের অ্যান্টি-হাইজ্যাক শুধু ব্যর্থ স্টার্ট দিয়ে খেয়াল করার যন্ত্র; আসল সার্ভিস অনুপস্থিত থাকলে আক্রমণকারী একই-নামের পাইপ আগে তৈরি করলে ক্লায়েন্ট এখনও নকল সার্ভারে সংযোগ করতে পারে। নিশ্চিত সার্ভিস স্টার্ট বা সংযোগের পর পারস্পরিক অথেন্টিকেশন দিয়ে পক্ষ নিশ্চিত করতে পারলেই অনুমোদন দিন। |
সার্ভার-পাশের পরিচয় যাচাই ও সুবিধা ধার ImpersonateNamedPipeClient। পাইপ থেকে অনুরোধ পড়ার পর এটি ডাকলে কলিং থ্রেড শেষ পড়া মেসেজের প্রেরকের সিকিউরিটি প্রেক্ষাপটে চলতে শুরু করে। ক্লায়েন্টের সুবিধায় ফাইল খুললে অ্যাক্সেস চেক ক্লায়েন্টের বিপরীতে হয় — সুবিধাপ্রাপ্ত সার্ভিস “অনুরোধকৃত কাজ, অনুরোধকারীর সুবিধায়” চালানোর যন্ত্র।6 ব্যবহারের পরম শর্ত রিটার্ন মান যাচাই। ইমপারসোনেশন ব্যর্থ হওয়ার পরও চললে পরের কাজ সার্ভারের নিজস্ব উচ্চ সুবিধায় চলে। অফিসিয়াল ডকুমেন্টেশন স্পষ্ট বলে “ব্যর্থ হলে ক্লায়েন্টের অনুরোধ চালাবেন না”। কাজ শেষে RevertToSelf-এর সাথে ইমপারসোনেশন টোকেনের নিবন্ধের অনুশীলন হুবহু প্রযোজ্য।
sequenceDiagram
accTitle: ইমপারসোনেশন ব্যবহার করা অনুরোধ হ্যান্ডলিংয়ের প্রবাহ
accDescr: সার্ভার পাইপ থেকে অনুরোধ পড়ে, ImpersonateNamedPipeClient সফল হয়েছে নিশ্চিত করে, তারপর ক্লায়েন্টের সুবিধায় কাজ করে RevertToSelf দিয়ে নিজের প্রেক্ষাপটে ফেরে। ইমপারসোনেশন ব্যর্থ হলে অনুরোধ না চালিয়ে প্রত্যাখ্যান করে
participant C as ক্লায়েন্ট
participant S as সার্ভার
C->>S: অনুরোধ পাঠান
S->>S: অনুরোধ পড়ুন
S->>S: ImpersonateNamedPipeClient
Note over S: ব্যর্থ হলে অনুরোধ না চালিয়ে প্রত্যাখ্যান
S->>S: ক্লায়েন্টের সুবিধায় কাজ করুন
S->>S: RevertToSelf দিয়ে আগের প্রেক্ষাপট ফেরান
S->>C: ফলাফল পাঠান
চিত্র ৭: ইমপারসোনেশন সফল হয়েছে নিশ্চিত করা ও নির্ভরযোগ্য RevertToSelf এক প্যাকেজ। ব্যর্থতার পর চললে তা সার্ভারের সুবিধায় চলে।
flowchart TB
accTitle: সুবিধাপ্রাপ্ত সার্ভিসের পাইপ রক্ষার চারটি বিষয়
accDescr: সার্ভার পাশ রিমোট প্রত্যাখ্যান, স্পষ্ট ACL ও প্রথম-ইনস্ট্যান্স নিশ্চয়তা দিয়ে প্রবেশশক্ত করে; ক্লায়েন্ট পাশ ন্যূনতম ইমপারসোনেশন লেভেল নির্দিষ্ট করে যাতে নকল সার্ভার সুবিধা ধার করতে না পারে(ডিজাইন সার্ভারকে সুবিধা ধার করতে না দিলে আইডেন্টিফিকেশন লেভেলে সংকুচিত করুন)
subgraph sv["সার্ভার পাশ"]
r1["PIPE_REJECT_REMOTE_CLIENTS"]
r2["ACL দিয়ে সংযোগকারী সীমিত করুন"]
r3["FIRST_PIPE_INSTANCE(শুধু প্রথম)"]
end
subgraph cl["ক্লায়েন্ট পাশ"]
r4["ন্যূনতম ইমপারসোনেশন লেভেল"]
end
sv --> safe["সুবিধার সীমানা হিসেবে পাইপ"]
cl --> safe
চিত্র ৮: যে ডিজাইনে পাইপই সুবিধার সীমানা, সেখানে সার্ভার-পাশের তিনটি বিষয় ও ক্লায়েন্ট-পাশের একটি বিষয় একসেট হিসেবে বাস্তবায়ন করুন।
৬. ব্যবহারিক ফাঁদ
স্টার্টআপ ক্রমের রেস। সার্ভার পাইপ তৈরি করার আগে ক্লায়েন্ট সংযোগ করতে এলে “পাইপ নেই” ত্রুটি হয়। ক্লায়েন্ট পাশে “নেই → একটু অপেক্ষা করে আবার চেষ্টা” গড়ে তুলুন। উল্টোদিকে সার্ভার পাশের নীতি: ক্লায়েন্ট শুরুর আগেই ConnectNamedPipe দিয়ে শোনা শুরু করা।8
flowchart TB
accTitle: ক্লায়েন্ট সংযোগ পুনঃচেষ্টার প্রবাহ
accDescr: CreateFile দিয়ে পাইপ খুলুন; পাইপ না থাকলে সংক্ষিপ্ত অপেক্ষা করে আবার চেষ্টা করুন; সব ইনস্ট্যান্স ব্যবহৃত থাকলে(ERROR_PIPE_BUSY) WaitNamedPipe দিয়ে খালিটির অপেক্ষা করে আবার চেষ্টা করুন; সফল হলে যোগাযোগে ঢুকুন
cf["CreateFile দিয়ে খুলুন"] --> ok{"ফলাফল?"}
ok -->|"সফল"| go["যোগাযোগ শুরু"]
ok -->|"পাইপ নেই"| wait1["সংক্ষিপ্ত অপেক্ষা(সার্ভার শুরু হয়নি)"]
ok -->|"ERROR_PIPE_BUSY"| wnp["WaitNamedPipe দিয়ে খালি ইনস্ট্যান্সের অপেক্ষা"]
wait1 --> cf
wnp --> cf
চিত্র ৯: ক্লায়েন্ট সংযোগ হ্যান্ডলিং “নেই” ও “পূর্ণ” দুই ধরনের ব্যর্থতা আলাদা করে দুটোকেই পুনঃচেষ্টায় জোড়ে।
বিচ্ছিন্নতা শনাক্ত করা। পক্ষ বেরিয়ে গেলে Read/Write ERROR_BROKEN_PIPE ইত্যাদি দিয়ে ব্যর্থ হয়। তা অস্বাভাবিক নয়; দৈনন্দিন যোগাযোগ। সার্ভার বিচ্ছিন্নতা ধরে ইনস্ট্যান্স DisconnectNamedPipe করে পরের সংযোগের প্রস্তুতি নেয়; ক্লায়েন্ট পুনঃসংযোগ করে — sleep/resume নিবন্ধে বর্ণিত “আইডেমপোটেন্ট পুনঃসংযোগ” ধারণা এখানেও প্রযোজ্য।
মেসেজ আকারের অনুমান। মেসেজ মোডের স্প্লিট রিডের (অধ্যায় ৩) উপরে, প্রোটোকলের অংশ হিসেবে “একটি মেসেজের সর্বোচ্চ বাইট কত” ঠিক না করলে ক্ষতিকর (বা বাগযুক্ত) পক্ষ বিশাল মেসেজ দিয়ে মেমরি নষ্ট করতে পারে। উর্ধ্বসীমা ঠিক করুন, অতিক্রম করলে বিচ্ছিন্ন করুন; সেটাই নিরাপদ পথ।
লেখা সম্পূর্ণ হওয়া আর পক্ষ গ্রহণ করা ভিন্ন জিনিস। WriteFile-এর সাফল্য মানে পক্ষের অ্যাপ ডেটা প্রক্রিয়া করেছে নয়। নিশ্চয়তা দরকার এমন কাজ উত্তর মেসেজ দিয়ে নিশ্চিত করা, আর অনুরোধ ও উত্তরের মিল প্রোটোকলে রাখা — এমন ডিজাইনে দাঁড়ায়।
৭. সারসংক্ষেপ
- নেমড পাইপ একই-মেশিন IPC-এর প্রথম প্রার্থী। কারণ ফাইল I/O-এর মতোই ব্যবহারের সহজতা, আর ACL ও ইমপারসোনেশনের Windows নিরাপত্তা মডেলের সাথে মিল।
- মোড পছন্দ “অনুরোধ ও উত্তরের জন্য মেসেজ মোড, নিজের ফ্রেমিং থাকলে বাইট মোড”। মেসেজ মোডেও স্প্লিট রিড (ERROR_MORE_DATA) সামলাতে হয়।
- একাধিক ক্লায়েন্ট কয়েকটি ইনস্ট্যান্স + overlapped, অথবা .NET async/await। নতুন কাজের জন্য .NET অ্যাসিঙ্ক্রোনাস আকৃতিই সরল।
- সুবিধার সীমানা যে পাইপে, সেখানে রিমোট প্রত্যাখ্যান, স্পষ্ট ACL, FIRST_PIPE_INSTANCE (শুধু প্রথম ইনস্ট্যান্স) ও ক্লায়েন্ট-পাশের ইমপারসোনেশন লেভেল কমানো একসেট হিসেবে নিন।
ImpersonateNamedPipeClient-এ রিটার্ন মান যাচাই ওRevertToSelfজীবনরেখা।- স্টার্টআপ ক্রম, বিচ্ছিন্নতা, মেসেজ উর্ধ্বসীমা, উত্তর নিশ্চিতকরণ — “যোগাযোগের দৈনন্দিন” প্রোটোকল ডিজাইনে বুনে দিন।
নেমড পাইপ পুরোনো API, কিন্তু “একই মেশিনে Windows অ্যাকাউন্ট সীমানা মেনে প্রক্রিয়াগুলোকে কথা বলানো” ব্যবহারে এখনও সবচেয়ে স্বাভাবিক হাতিয়ার। ডিজাইন-বিচারের বিষয়গুলো প্রায় এই নিবন্ধের পরিসরেই শেষ। তার পর নিজের প্রোটোকল এক পাতায় লিখে তারপর বাস্তবায়ন শুরু করুন।
সম্পর্কিত নিবন্ধ
- Windows আন্তঃপ্রক্রিয়া যোগাযোগ বেছে নেওয়া ── নেমড পাইপ / TCP / gRPC / শেয়ার্ড মেমরি / COM-এর সিদ্ধান্ত সারণি
- Windows অ্যাপে “শুধু যে কাজগুলোর অ্যাডমিনিস্ট্রেটর সুবিধা দরকার” কংক্রিটভাবে কীভাবে আলাদা করবেন
- Windows ইমপারসোনেশন টোকেন সঠিকভাবে সামলানো — থ্রেডপ্রতি সুবিধা ধার ও নিরাপদে ফেরানো
- Windows I/O-এর গভীরতা (পর্ব ২) — সিঙ্ক্রোনাস ও অ্যাসিঙ্ক্রোনাস I/O: OVERLAPPED আসলে কী
- শেয়ার্ড মেমরির ফাঁদ ও ব্যবহারিক সেরা অনুশীলন
সম্পর্কিত পরামর্শ ক্ষেত্র
KomuraSoft LLC আন্তঃপ্রক্রিয়া যোগাযোগ জড়িত ডিজাইন ও বাস্তবায়ন সামলায় — সার্ভিসকে UI অ্যাপ থেকে আলাদা করা, অ্যাডমিনিস্ট্রেটর সুবিধা আলাদা করা ইত্যাদি — বিদ্যমান IPC (শেয়ার্ড মেমরি, ঘরোয়া সকেট, COM ইত্যাদি) নেমড পাইপে বদলানো, আর সুবিধাপ্রাপ্ত সার্ভিসের পাইপ যোগাযোগের নিরাপত্তা পর্যালোচনা। প্রোটোকল ডিজাইন আমাদের সাথে মিলিয়ে দেখা থেকেও পরামর্শ স্বাগত।
- Windows অ্যাপ্লিকেশন ডেভেলপমেন্ট
- টেকনিক্যাল কনসালটিং ও ডিজাইন রিভিউ
- বাগ অনুসন্ধান ও মূল কারণ বিশ্লেষণ
- যোগাযোগ করুন
তথ্যসূত্র
-
Microsoft Learn, Named Pipes। নেমড পাইপ পাইপ সার্ভার ও এক বা একাধিক পাইপ ক্লায়েন্টের মধ্যে একমুখী বা দ্বিমুখী চ্যানেল হওয়া; প্রতিটি ইনস্ট্যান্স একই নাম ভাগ করে অথচ স্বাধীন বাফার ও হ্যান্ডেল রাখা; এবং স্থানীয় ও রিমোট প্রক্রিয়া থেকে ব্যবহারযোগ্য হওয়া সম্পর্কে। ↩ ↩2
-
Microsoft Learn, Impersonating a Named Pipe Client। ইমপারসোনেশন সার্ভার থ্রেডকে ক্লায়েন্টের সুবিধার ভেতরে কাজ করতে দেওয়া; ডিফল্ট ইমপারসোনেশন লেভেল SecurityImpersonation হওয়া; এবং ক্লায়েন্ট CreateFile-এ SECURITY_SQOS_PRESENT ফ্ল্যাগ দিয়ে ইমপারসোনেশন লেভেল নিয়ন্ত্রণ করতে পারা (SECURITY_IDENTIFICATION শুধু পরিচয় অনুমোদন করে) সম্পর্কে। ↩ ↩2
-
Microsoft Learn, CreateNamedPipeW function (namedpipeapi.h)। পাইপের দিক (ইনবাউন্ড, আউটবাউন্ড, দ্বিমুখী), বাইট টাইপ ও মেসেজ টাইপ (PIPE_TYPE_BYTE / PIPE_TYPE_MESSAGE) ও রিড মোড (PIPE_READMODE_MESSAGE), সর্বোচ্চ ইনস্ট্যান্স সংখ্যা (PIPE_UNLIMITED_INSTANCES), FILE_FLAG_OVERLAPPED দিয়ে অ্যাসিঙ্ক্রোনাস মোড, FILE_FLAG_FIRST_PIPE_INSTANCE দিয়ে প্রথম-ইনস্ট্যান্স নিশ্চয়তা, এবং WaitNamedPipe-এর ডিফল্ট টাইমআউট সম্পর্কে। ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Named Pipe Server Using Overlapped I/O। overlapped অপারেশন দিয়ে একাধিক ক্লায়েন্টের সমকালীন সংযোগ প্রক্রিয়া করা এক-থ্রেড সার্ভারের অফিসিয়াল নমুনা সম্পর্কে। প্রতিটি ইনস্ট্যান্সের OVERLAPPED স্ট্রাকচার ও ইভেন্ট WaitForMultipleObjects দিয়ে অপেক্ষা করে সম্পূর্ণ ইনস্ট্যান্সের স্টেট মেশিন এগোানোর আকৃতি, এবং GetOverlappedResult দিয়ে অপেক্ষমাণ I/O-এর সম্পূর্ণি নিশ্চিত করা সম্পর্কে। ↩ ↩2
-
Microsoft Learn, CreateNamedPipeW function (namedpipeapi.h)। দুটি রিমোট-ক্লায়েন্ট মোড, PIPE_ACCEPT_REMOTE_CLIENTS (রিমোট সংযোগ গ্রহণ করে সিকিউরিটি ডেস্ক্রিপ্টরের বিপরীতে যাচাই) ও PIPE_REJECT_REMOTE_CLIENTS (রিমোট-ক্লায়েন্ট সংযোগ স্বয়ংক্রিয় প্রত্যাখ্যান) সম্পর্কে। ↩ ↩2
-
Microsoft Learn, ImpersonateNamedPipeClient function (namedpipeapi.h)। সার্ভার-পাশের থ্রেড পাইপ থেকে শেষ পড়া মেসেজের ক্লায়েন্টের সিকিউরিটি প্রেক্ষাপটে ইমপারসোনেশন শুরু করা; সম্পূর্ণির পর RevertToSelf দিয়ে ফেরা; এবং ইমপারসোনেশন ব্যর্থ হওয়ার পর চললে সার্ভার প্রক্রিয়ার নিজস্ব (সুবিধাপ্রাপ্ত) প্রেক্ষাপটে চলা, তাই রিটার্ন মান সবসময় যাচাই করতে হয় এবং ব্যর্থ হলে ক্লায়েন্টের অনুরোধ চালানো যায় না সম্পর্কে। ↩ ↩2 ↩3
-
Microsoft Learn, Named Pipe Client। ক্লায়েন্ট CreateFile দিয়ে পাইপ খোলা; সব ইনস্ট্যান্স ব্যবহৃত থাকলে ERROR_PIPE_BUSY, WaitNamedPipe দিয়ে খালিটির অপেক্ষা; এবং খোলা হ্যান্ডেল ডিফল্টে বাইট-রিড, ব্লকিং ও নন-overlapped হওয়া, SetNamedPipeHandleState দিয়ে মেসেজ-রিড মোডে বদলানো যাওয়া সম্পর্কে। ↩ ↩2
-
Microsoft Learn, Named Pipe Operations। ReadFileEx / WriteFileEx দিয়ে overlapped অপারেশন, PeekNamedPipe দিয়ে নন-কনজিউমিং রিড, মেসেজ-টাইপ দ্বিমুখী পাইপে TransactNamedPipe একটি কলে অনুরোধ পাঠানো ও উত্তর পাওয়া, এবং ক্লায়েন্ট শুরুর আগে ব্লকিং রিড রেস ঘটাতে পারা সম্পর্কে। ↩ ↩2
-
Microsoft Learn, How to: Use Named Pipes for Network Interprocess Communication (.NET)। NamedPipeServerStream / NamedPipeClientStream দিয়ে সংযোগ ও পড়া/লেখা, PipeTransmissionMode.Message দিয়ে মেসেজ-একক ট্রান্সফার, এবং অ্যাসিঙ্ক্রোনাস মেথড দিয়ে একাধিক ক্লায়েন্ট সামলানো সম্পর্কে। ↩ ↩2
-
Microsoft Learn, PipeOptions Enum (System.IO.Pipes)। Asynchronous দিয়ে অ্যাসিঙ্ক্রোনাস I/O চালু করা, এবং CurrentUserOnly শুধু একই ব্যবহারকারীর (ও একই এলিভেশন লেভেলের) প্রক্রিয়ার সাথে সংযোগ অনুমোদন করতে পারা সম্পর্কে। ↩
-
Microsoft Learn, Named Pipe Security and Access Rights। নেমড-পাইপ অ্যাক্সেস অধিকারের গঠন; GENERIC_WRITE-এ FILE_CREATE_PIPE_INSTANCE থাকা, তাই ক্লায়েন্টকে জেনেরিক রাইট দিলে সার্ভার ইনস্ট্যান্স তৈরিও অনুমোদিত হয়ে যাওয়া; এবং ডেটার রিড ও রাইট আলাদা অ্যাক্সেস অধিকার হিসেবে দেওয়া সম্পর্কে। ↩
সম্পর্কিত নিবন্ধ
কাছাকাছি বিষয়ে গভীরে যেতে একই ট্যাগযুক্ত সাম্প্রতিক নিবন্ধ।
Win32 থ্রেড পুল API — CreateThreadpoolWork দিয়ে থ্রেড তৈরি না করে কনকারেন্সি
নেটিভ কোডে চারদিকে CreateThread ডাকছেন? এই নিবন্ধ Vista-তে নতুন করে সাজানো Win32 থ্রেড পুল API ব্যাখ্যা করে — work, timer, wait ও io চারট...
Windows ভার্চুয়ালাইজেশনের গভীরতা (পর্ব ২) — কার্নেলও দেখতে পায় না এমন মেমরি: VBS, HVCI ও Credential Guard কীভাবে কাজ করে
সামঞ্জস্যপূর্ণ হার্ডওয়্যারে ক্লিন ইনস্টলে VBS ডিফল্টে চালু থাকে এবং হাইপারভাইজার ও SLAT দিয়ে কার্নেলের চেয়ে শক্তিশালী আইসোলেশন তৈরি কর...
Windows ভার্চুয়ালাইজেশনের গভীরতা (পর্ব ৩) — সেকেন্ডে বুট হওয়া ভার্চুয়াল মেশিন: WSL2, Windows Sandbox ও কন্টেইনার এত হালকা কেন
WSL2 ও Windows Sandbox সেকেন্ডে শুরু হয়ে এত হালকা মনে হয় কেন? এই নিবন্ধ ডায়নামিক বেস ইমেজ ও ডাইরেক্ট ম্যাপ থেকে ডায়নামিক মেমরি বরাদ্দ...
Windows ভার্চুয়ালাইজেশনের গভীরতা (পর্ব ১) — আপনার Windows আসলে কোথায় চলছে? হাইপারভাইজার ও পার্টিশন
Hyper-V চালু করলে হোস্ট Windows নিজেই রুট পার্টিশন হিসেবে হাইপারভাইজারের উপর চলে। এই নিবন্ধ VT-x, SLAT ও VMBus-এর ভূমিকা দিয়ে ভার্চুয়াল...
এলাকার নাম দিয়ে অনুসন্ধানে দৃশ্যমান হোন — ছোট ও মাঝারি ব্যবসার জন্য লোকাল SEO-এর ব্যবহারিক গাইড (এলাকা পৃষ্ঠা ও Google Business Profile)
সেসব ছোট ও মাঝারি ব্যবসার জন্য যাদের সাইট "এলাকার নাম + খাত" খুঁজলে দেখা যায় না। এই নিবন্ধ লোকাল SEO ঠিক করার ক্রম সাজায়: Google Busine...
সম্পর্কিত বিষয়
এই পৃষ্ঠাগুলো বিষয়টিকে সেবা ও সিদ্ধান্তের বৃহত্তর প্রেক্ষাপটে স্থাপন করে।
Windows-এর প্রযুক্তিগত বিষয়
Windows ডেভেলপমেন্ট, বাগ তদন্ত ও বিদ্যমান সম্পদ ব্যবহারের প্রবেশদ্বার।
এই বিষয়ের সাথে সম্পর্কিত সেবা
নিবন্ধটি নিচের সেবাগুলোর সাথে সরাসরি সম্পর্কিত।
Windows অ্যাপ ডেভেলপমেন্ট
ব্যবসায়িক অ্যাপ, ডিভাইস ইন্টিগ্রেশন ও যোগাযোগ টুল, চাহিদা থেকে ডেভেলপমেন্ট পর্যন্ত।
প্রায়শ জিজ্ঞাসিত প্রশ্ন
এই নিবন্ধের বিষয়ে পরামর্শে প্রায়ই আসা প্রশ্ন।
- নেমড পাইপ ও TCP (localhost সকেট)-এর মধ্যে কীভাবে বেছে নেব?
- একই মেশিনে আন্তঃপ্রক্রিয়া যোগাযোগের জন্য নেমড পাইপই প্রথম প্রার্থী। কারণ নিরাপত্তা মডেল। পাইপ Windows সিকিউরিটি ডেস্ক্রিপ্টর (ACL) দিয়ে OS স্তরে নিয়ন্ত্রণ করতে পারে কে সংযোগ করতে পারবে, আর সার্ভার ImpersonateNamedPipeClient দিয়ে সংযোগকারী পক্ষের Windows অ্যাকাউন্ট দেখতে ও ধার করতে পারে। localhost TCP পোর্টের বিপরীত চিত্র: সেখানে যে কেউ সংযোগ করতে পারে, তাই পক্ষ কে তা নিজের অথেন্টিকেশন দিয়ে প্রতিষ্ঠা করতে হয়। অন্যদিকে পরে রিমোট যোগাযোগ হওয়ার সম্ভাবনা থাকলে, অন্য OS-এর প্রক্রিয়ার সাথেও কথা বলতে হলে, অথবা gRPC-এর মতো বিদ্যমান প্রোটোকল অ্যাসেট পুনর্ব্যবহার করতে চাইলে TCP-ভিত্তিক বিকল্প সুবিধাজনক। এই বিচার Windows আন্তঃপ্রক্রিয়া যোগাযোগ বেছে নেওয়ার নিবন্ধেও সাজানো আছে।
- বাইট মোড নাকি মেসেজ মোড ব্যবহার করব?
- যদি "একটি লেখা = একটি অর্থের একক" হিসেবে ধরতে চান, মেসেজ মোড (PIPE_TYPE_MESSAGE + PIPE_READMODE_MESSAGE) সুবিধাজনক। প্রাপক প্রেরক যা লিখেছে সেই এককেই পড়তে পারে, তাই সীমানা নিজে সামলাতে হয় না। বাইট মোড TCP-এর মতো "অবিচ্ছিন্ন বাইট স্ট্রিম", আর ফ্রেমিং নিজে ডিজাইন করতে হয় — যেমন দৈর্ঘ্য-প্রিফিক্স। যে প্রোটোকলে ইতিমধ্যে ফ্রেমিং আছে (যেমন দৈর্ঘ্য-প্রিফিক্সযুক্ত সিরিয়ালাইজড রূপ) সেটা বহন করলে বাইট মোডই যথেষ্ট। সতর্কতা: মেসেজ মোডেও রিসিভ বাফার মেসেজের চেয়ে ছোট হলে স্প্লিট রিড (ERROR_MORE_DATA) আসে, তাই সেটাও সামলাতে হয়। আর রিড মোড হ্যান্ডেলপ্রতি সেটিং, CreateNamedPipe শুধু সার্ভার পাশে সেট করে। ক্লায়েন্টকে CreateFile-এর পর SetNamedPipeHandleState দিয়ে PIPE_READMODE_MESSAGE নির্দিষ্ট করতে হয়। .NET-এ সার্ভার PipeTransmissionMode.Message বলে, আর ক্লায়েন্ট সংযোগের পর NamedPipeClientStream.ReadMode-কে Message করে।
- একাধিক ক্লায়েন্টের সাথে একসঙ্গে কথা বলা সার্ভার কীভাবে বানাব?
- নেমড পাইপ একই নামে একাধিক ইনস্ট্যান্স তৈরি করতে পারে, আর একটি ইনস্ট্যান্স একটি ক্লায়েন্ট সামলায়। দুটি আকৃতি আছে। একটি সিঙ্ক্রোনাস ডিজাইন যা প্রতি ক্লায়েন্টে একটি থ্রেড দেয়; বাস্তবায়ন সরল, কিন্তু প্রতি ক্লায়েন্টে একটি থ্রেড খরচ হয়। অন্যটি FILE_FLAG_OVERLAPPED দিয়ে অ্যাসিঙ্ক্রোনাস I/O ব্যবহার করে অল্প কয়েকটি থ্রেড দিয়ে প্রতিটি ইনস্ট্যান্সের ConnectNamedPipe, ReadFile ও WriteFile সামলানো; Microsoft-এর অফিসিয়াল নমুনায় একটি থ্রেডে একাধিক ইনস্ট্যান্স প্রক্রিয়া করার বাস্তবায়নও দেখানো আছে। .NET-এ NamedPipeServerStream.WaitForConnectionAsync ও async/await দিয়ে অ্যাসিঙ্ক্রোনাস আকৃতি প্রায় সিঙ্ক্রোনাসের মতোই সরলভাবে লেখা যায়। বিশেষ কারণ না থাকলে নতুন বাস্তবায়নের জন্য .NET অ্যাসিঙ্ক্রোনাস আকৃতিই সুপারিশ করি।
- নেমড-পাইপ নিরাপত্তায় ন্যূনতম কী করা উচিত?
- চারটি বিষয়। প্রথম, রিমোট সংযোগ দরকার না হলে PIPE_REJECT_REMOTE_CLIENTS নির্দিষ্ট করে নেটওয়ার্কের সংযোগ স্পষ্টভাবে প্রত্যাখ্যান করুন। দ্বিতীয়, SECURITY_ATTRIBUTES দিয়ে উপযুক্ত ACL সেট করে সংযোগ করতে পারা ব্যবহারকারী ও গ্রুপ সংকুচিত করুন (ডিফল্ট ACL কিছু ব্যবহারে খুব ঢিলে)। তৃতীয়, প্রথম ইনস্ট্যান্স তৈরির সময় FILE_FLAG_FIRST_PIPE_INSTANCE নির্দিষ্ট করুন, যাতে একই নামের পাইপ আগে তৈরি হয়ে যাওয়া "নাম হাইজ্যাক" ধরা পড়ে (দ্বিতীয় ও পরের ইনস্ট্যান্সে এই ফ্ল্যাগ দেবেন না)। চতুর্থ, যে ক্লায়েন্ট শুধু সার্ভারকে নিজেকে চেনাতে চায় সে CreateFile-এ SECURITY_SQOS_PRESENT|SECURITY_IDENTIFICATION নির্দিষ্ট করুক, যাতে নকল সার্ভার তার সুবিধা ধার (ইমপারসোনেট) করতে না পারে। যে ব্রোকার ডিজাইনে সার্ভার ক্লায়েন্টের সুবিধায় সত্যিকারের অ্যাক্সেস করে, সেখানে ইমপারসোনেশন অনুমোদিত থাকতে হয়, তাই সার্ভার সুবিধা ধার করতে পারবে কি না তার উপর এই সীমাবদ্ধতা লাগানো বা না লাগানো নির্ভর করে।
- ImpersonateNamedPipeClient ব্যবহারের সতর্কতা কী?
- সবচেয়ে গুরুত্বপূর্ণ রিটার্ন মান যাচাই। ইমপারসোনেশন ব্যর্থ হওয়ার পরও এগোলে পরের কাজ সার্ভার প্রক্রিয়ার নিজস্ব (প্রায়ই উচ্চ) সুবিধায় চলে, আর ক্লায়েন্টকে যা অনুমোদিত নয় তাও পাস হয়ে যায়। অফিসিয়াল ডকুমেন্টেশনও স্পষ্ট বলে ব্যর্থ হলে ক্লায়েন্টের অনুরোধ চালাবেন না। আর কিছু পড়ার পরেই ডাকতে হয় — ইমপারসোনেশন হয় "পাইপ থেকে শেষ যে মেসেজ পড়া হয়েছে" তার প্রেক্ষাপটে — এবং কাজ শেষে RevertToSelf দিয়ে নির্ভরযোগ্যভাবে আগের প্রেক্ষাপটে ফিরতে হয়। ইমপারসোনেশনের যন্ত্রপাতি (টোকেন, ইমপারসোনেশন লেভেল, SeImpersonatePrivilege) ইমপারসোনেশন টোকেনের নিবন্ধে বিস্তারিত আছে।