این رو توی وبلاگم کسی سوال کرده بود ولی چون نسبتا مفصل هست و توی کامنت های وبلاگ جای مناسبی برای این کار نیست گفتم اینجا مطرح میکنم بیاد اینجا جوابشو بخونه ضمنا میشه اینجا بحث رو ادامه داد دیگران هم اگر خواستن بتونن شرکت کنن.
خب من با زبان ساده و بصورت عملی با مثال براتون توضیح میدم، البته بعضی جزییات خیلی ریز فرعی رو ممکنه فراموش کرده باشم ولی کلیتش بقدر کافی روشنه.
فرض کنید سیستم A و سیستم B هر دو از طریق مودم ADSL به اینترنت متصل هستن.
خب حالا سیستم B میخواد با سیستم A ارتباط مستقیم (P2P) برقرار کنه. الان باس چکار کنه؟
آفرین خرگوش باهوش
اول باید IP سیستم A رو گیر بیاره. خب از کجا گیر بیاره؟ پس ما نیاز به یک سیستم واسط داریم که هر دو سیستم یجوری بشناسن و بتونن باهاش ارتباط برقرار کنن و IP خودشون رو بهش بدن و IP سیستم دیگر رو ازش دریافت کنن، و بعد از اینکه IP سیستم دیگر رو بدست آوردن میتونن باهاش ارتباط مستقیم برقرار کنن.
اما متاسفانه در عمل مسئله از این هم پیچیده تره. فرض کنید سیستم B آدرس IP سیستم A رو هم داشت و یک پکت UDP بهش فرستاد، حالا چی میشه؟ پکت میاد پشت درب مودم میگه تق تق، مودم میگه برو گم شو!!
مودم این پکت رو نادیده میگیره، چرا؟ خب این مسئله هم جنبه های امنیتی داره و هم بخاطر مسئلهء دیگری. اولا که اغلب مودم ها و فایروال ها، اجازهء ورود پکت های IP که از اینترنت بی در و پیکر میان رو نمیدن. مثلا شما میتونید در مرورگر خودتون یک وبسایت در اینترنت رو باز کنید، ولی در این حالت اول سیستم شماست که پکت هایی رو به آدرس IP سایت مورد نظر ارسال میکنه، مودم که وسیله و رابط این ارتباط است این مسئله رو تحت نظر داره و آدرس IP و پورتی رو که این پکت ها بهش ارسال میشن رو بیاد میسپاره و بنابراین وقتی پکت هایی از اون آدرس و پورت به آدرس IP خودش ارسال میشن به اونا اجازهء ورود میده چون میدونه که این قبلا سیستم خود شما بوده که با اون سیستم ارتباط برقرار کرده.
البته میشه مودم رو بصورت دستی تنظیم کرد که اجازهء ورود پکت ها با مشخصات خاصی (مثلا پورت هدف خاصی) رو بده، ولی این کار رو معمولا تا میتونن از روش دیگه استفاده کنن نمیکنن چون دردسر داره و نیاز به دخالت مستقیم کاربر هست و باید دستی با ورود به کنترل پنل و تنظیمات مودم انجام بشه و کار فنی است و ممکنه برای کاربر مشکل باشه یا دچار اشتباه بشه، گذشته از تبعات امنیتی که ممکنه داشته باشه.
و اما دلیل دومی که مودم پکت هایی رو که از بیرون میان به پشت خودش یعنی شبکهء داخلی شما راه نمیده اینه که ممکنه چند سیستم به مودم شما وصل باشن که هرکدام آدرس IP شبکهء داخلی خودشون رو دارن (مثلا 192.168.1.21 و 192.168.1.33 و ...)، خب الان اینجا مودم چطوری بفهمه این بسته رو باید به کدوم یک از این سیستم ها/IP ها تحویل بده؟ حتی اونی هم که اون بسته رو فرستاده طبیعتا نمیدونسته که آدرس IP سیستم مورد نظر در شبکهء داخلی شما چیه!
پس نتیجه میگیریم که ارتباط P2P تنها وقتی امکان پذیر است که هر دوی سیستمهایی که میخوان با هم ارتباط مستقیم برقرار کنن، قبلا پکت هایی رو به آدرس IP و شماره پورت همدیگر ارسال کرده باشن. بنابراین سیستم ها باید ابتدا آدرس IP و شماره پورت سوکت برنامهء طرف مقابل رو بدست بیارن، بعد هر دو همزمان شروع میکنن به ارسال پکت هایی به آدرس IP و شماره Port طرف مقابل، که در نتیجه در نهایت پکت های هر دو طرف از مودم ها عبور میکنه و اتصال بین دو برنامه برقرار میشه. البته اگر مدتی پکتی به این پورت ها ارسال نشه، مودم یا فایروال مجددا اون پورت رو مسدود میکنه، بنابراین اینطور برنامه ها معمولا حتی اگر دیتایی برای تبادل نداشته باشن ولی میان و مثلا هر 10 ثانیه یا 20 ثانیه هرچی خلاصه پکتی رو به همدیگر ارسال میکنن تا پورت ها بسته نشن و نیازی به تکرار عملیات اتصال اولیه که مقداری زمانبر هم هست نباشه.
خب به این ترفند میگن port punching/hole punching و این حرفا چون مثل این میمونه که دو طرف برای ارتباط، در مودم یا فایروال حفره ای رو ایجاد میکنن.
روشن بود؟
خب من با زبان ساده و بصورت عملی با مثال براتون توضیح میدم، البته بعضی جزییات خیلی ریز فرعی رو ممکنه فراموش کرده باشم ولی کلیتش بقدر کافی روشنه.
فرض کنید سیستم A و سیستم B هر دو از طریق مودم ADSL به اینترنت متصل هستن.
خب حالا سیستم B میخواد با سیستم A ارتباط مستقیم (P2P) برقرار کنه. الان باس چکار کنه؟

آفرین خرگوش باهوش

اول باید IP سیستم A رو گیر بیاره. خب از کجا گیر بیاره؟ پس ما نیاز به یک سیستم واسط داریم که هر دو سیستم یجوری بشناسن و بتونن باهاش ارتباط برقرار کنن و IP خودشون رو بهش بدن و IP سیستم دیگر رو ازش دریافت کنن، و بعد از اینکه IP سیستم دیگر رو بدست آوردن میتونن باهاش ارتباط مستقیم برقرار کنن.
اما متاسفانه در عمل مسئله از این هم پیچیده تره. فرض کنید سیستم B آدرس IP سیستم A رو هم داشت و یک پکت UDP بهش فرستاد، حالا چی میشه؟ پکت میاد پشت درب مودم میگه تق تق، مودم میگه برو گم شو!!
مودم این پکت رو نادیده میگیره، چرا؟ خب این مسئله هم جنبه های امنیتی داره و هم بخاطر مسئلهء دیگری. اولا که اغلب مودم ها و فایروال ها، اجازهء ورود پکت های IP که از اینترنت بی در و پیکر میان رو نمیدن. مثلا شما میتونید در مرورگر خودتون یک وبسایت در اینترنت رو باز کنید، ولی در این حالت اول سیستم شماست که پکت هایی رو به آدرس IP سایت مورد نظر ارسال میکنه، مودم که وسیله و رابط این ارتباط است این مسئله رو تحت نظر داره و آدرس IP و پورتی رو که این پکت ها بهش ارسال میشن رو بیاد میسپاره و بنابراین وقتی پکت هایی از اون آدرس و پورت به آدرس IP خودش ارسال میشن به اونا اجازهء ورود میده چون میدونه که این قبلا سیستم خود شما بوده که با اون سیستم ارتباط برقرار کرده.
البته میشه مودم رو بصورت دستی تنظیم کرد که اجازهء ورود پکت ها با مشخصات خاصی (مثلا پورت هدف خاصی) رو بده، ولی این کار رو معمولا تا میتونن از روش دیگه استفاده کنن نمیکنن چون دردسر داره و نیاز به دخالت مستقیم کاربر هست و باید دستی با ورود به کنترل پنل و تنظیمات مودم انجام بشه و کار فنی است و ممکنه برای کاربر مشکل باشه یا دچار اشتباه بشه، گذشته از تبعات امنیتی که ممکنه داشته باشه.
و اما دلیل دومی که مودم پکت هایی رو که از بیرون میان به پشت خودش یعنی شبکهء داخلی شما راه نمیده اینه که ممکنه چند سیستم به مودم شما وصل باشن که هرکدام آدرس IP شبکهء داخلی خودشون رو دارن (مثلا 192.168.1.21 و 192.168.1.33 و ...)، خب الان اینجا مودم چطوری بفهمه این بسته رو باید به کدوم یک از این سیستم ها/IP ها تحویل بده؟ حتی اونی هم که اون بسته رو فرستاده طبیعتا نمیدونسته که آدرس IP سیستم مورد نظر در شبکهء داخلی شما چیه!
پس نتیجه میگیریم که ارتباط P2P تنها وقتی امکان پذیر است که هر دوی سیستمهایی که میخوان با هم ارتباط مستقیم برقرار کنن، قبلا پکت هایی رو به آدرس IP و شماره پورت همدیگر ارسال کرده باشن. بنابراین سیستم ها باید ابتدا آدرس IP و شماره پورت سوکت برنامهء طرف مقابل رو بدست بیارن، بعد هر دو همزمان شروع میکنن به ارسال پکت هایی به آدرس IP و شماره Port طرف مقابل، که در نتیجه در نهایت پکت های هر دو طرف از مودم ها عبور میکنه و اتصال بین دو برنامه برقرار میشه. البته اگر مدتی پکتی به این پورت ها ارسال نشه، مودم یا فایروال مجددا اون پورت رو مسدود میکنه، بنابراین اینطور برنامه ها معمولا حتی اگر دیتایی برای تبادل نداشته باشن ولی میان و مثلا هر 10 ثانیه یا 20 ثانیه هرچی خلاصه پکتی رو به همدیگر ارسال میکنن تا پورت ها بسته نشن و نیازی به تکرار عملیات اتصال اولیه که مقداری زمانبر هم هست نباشه.
خب به این ترفند میگن port punching/hole punching و این حرفا چون مثل این میمونه که دو طرف برای ارتباط، در مودم یا فایروال حفره ای رو ایجاد میکنن.
روشن بود؟

God knows