Seperti yang saya pahami, inilah yang terjadi ketika klien membuat permintaan koneksi:
- Server akan terikat ke nomor port tertentu. Nomor port selalu terikat dengan proses mendengarkan. Karena hanya server yang mendengarkan koneksi masuk, kami tidak perlu mengikat di sisi klien
- Server akan terus mendengarkan nomor port itu.
- Klien akan mengirim
connect()
permintaan. - Server akan menerima permintaan menggunakan
accept()
. Segera setelah server menerima permintaan klien, kernel mengalokasikan nomor port acak untuk server lebih lanjutsend()
danreceive()
, karena nomor port yang sama pada server tidak dapat digunakan untuk mengirim serta mendengarkan, dan port sebelumnya masih mendengarkan koneksi baru
Mengingat semua itu, bagaimana server mengetahui port apa yang diterima klien? Saya tahu klien akan mengirim segmen TCP dengan port sumber dan port tujuan, sehingga server akan menggunakan port sumber segmen tersebut sebagai port tujuan, tetapi fungsi apa yang dipanggil server untuk mencari tahu tentang port itu? Apakah itu accept()
?
Jawaban:
Itu adalah bagian dari header TCP (atau UDP, dll.), Dalam paket. Jadi server mencari tahu karena klien mengatakannya. Ini mirip dengan bagaimana ia mengetahui alamat IP klien (yang merupakan bagian dari header IP).
Misalnya, setiap paket TCP menyertakan header IP (dengan IP sumber, IP tujuan, dan protokol [TCP], setidaknya). Lalu ada header TCP (dengan port sumber dan tujuan, ditambah lagi).
Ketika kernel menerima paket SYN (awal koneksi TCP) dengan IP jarak jauh 10.11.12.13 (di header IP) dan port jarak jauh 12345 (di header TCP), ia kemudian mengetahui IP jarak jauh dan port . Ini mengirim kembali SYN | ACK. Jika ACK dikembalikan,
listen
panggilan mengembalikan soket baru, yang diatur untuk koneksi itu.Soket TCP diidentifikasi secara unik oleh empat nilai (IP jarak jauh, IP lokal, port jarak jauh, port lokal). Anda dapat memiliki banyak koneksi / soket, selama setidaknya satu dari itu berbeda.
Biasanya, port lokal dan IP lokal akan sama untuk semua koneksi ke proses server (mis. Semua koneksi ke sshd akan berada di local-ip: 22). Jika satu mesin jarak jauh membuat banyak koneksi, masing-masing akan menggunakan port jarak jauh yang berbeda. Jadi segalanya kecuali port jarak jauh akan sama, tetapi tidak apa-apa — hanya satu dari empat yang harus berbeda.
Anda dapat menggunakan, misalnya, wirehsark untuk melihat paket, dan itu akan memberi label semua data untuk Anda. Berikut adalah port sumber yang disorot (perhatikan itu disorot dalam paket yang diterjemahkan, serta hex dump di bagian bawah):
sumber
write
(dll.) Pergi ke tempat yang tepat."Sambungkan permintaan (
connect()
panggilan sistem program klien , biasanya) menyebabkan jabat tangan tiga arah . Paket pertama jabat tangan 3-arah (dari klien ke server) memiliki set bendera SYN, dan termasuk nomor port TCP program klien kernel ditugaskan untuk itu.Anda dapat melihat ini di artikel tentang paket Nmap vs Natural SYN . Decoding paket Nmap SYN memiliki frasa "source.60058> dest.22". Decoding "paket SYN yang sah" memiliki frasa "source.35970> dest.80" di dalamnya. Kedua paket SYN memberi tahu kernel jarak jauh bahwa paket-paket itu masing-masing berasal dari port TCP 60058 dan port 35970.
sumber
getpeername()
harus memungkinkan Anda melakukan itu pada soket yang terbuka. Theaccept()
system call bahwa kode server harus menggunakan untuk mendapatkan file descriptor socket untuk berkomunikasi kembali ke klien memiliki parameter ( "sockaddr" di halaman manual saya) yang berisi alamat IP calon klien dan nomor port TCP.Soket TCP adalah soket berorientasi aliran. Dua deskriptor soket (yang dimiliki oleh Anda dan rekan Anda) terhubung dengan andal. Jadi Anda tidak perlu khawatir tentang port klien - cukup tulis deskriptor soket Anda!
Juga, jangan ragu untuk mendapatkanockockname (2) jika Anda benar-benar ingin tahu itu (untuk logging mungkin).
sumber
Koneksi ditentukan oleh tuple (sumber IP, port sumber, IP tujuan, port tujuan). Jawaban sebaliknya.
sumber