Mengapa koneksi IPv4 TCP ditampilkan sebagai tcp6?


30

Inilah output dari netsat -tupnpada server Debian Jessie saya:

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 10.0.0.12:445           10.0.0.20:49729         ESTABLISHED 26277/smbd      
tcp        0      0 10.0.0.12:443           10.0.0.21:44162         ESTABLISHED 1400/nginx: worker 
tcp        0      0 10.0.0.12:445           10.0.0.21:46650         ESTABLISHED 23039/smbd      
tcp        0      0 10.0.0.12:443           10.0.0.20:54584         ESTABLISHED 1400/nginx: worker 
tcp        0      0 10.0.0.12:139           10.0.0.225:10425        ESTABLISHED 23701/smbd      
tcp        0      0 10.0.0.12:445           10.0.0.217:49179        ESTABLISHED 21535/smbd      
tcp        0      0 10.0.0.12:445           10.0.0.217:49178        ESTABLISHED 21534/smbd      
tcp        0      0 10.0.0.12:445           10.0.0.20:64636         ESTABLISHED 21470/smbd      
tcp        0      0 10.0.0.12:443           10.0.0.21:44198         ESTABLISHED 1400/nginx: worker 
tcp        0      0 10.0.0.12:2049          10.0.0.16:752           ESTABLISHED -               
tcp        0      0 10.0.0.12:222           10.0.0.21:55514         ESTABLISHED 23111/sshd: redacted
tcp6       0      0 10.0.0.12:4243          10.0.0.20:64702         ESTABLISHED 31307/java      
tcp6       0      0 10.0.0.12:48932         162.222.40.93:443       ESTABLISHED 31307/java      
tcp6       0      0 10.0.0.12:49093         216.17.8.47:443         ESTABLISHED 31307/java 

PID 31307 adalah mesin cadangan CrashPlan , versi Java 1.7.0_45. Dua alamat IPv4 non-RFC1918 adalah server CrashPlan dan 10.0.0.20:64702merupakan komputer saya yang menjalankan klien.

Mengapa tiga koneksi terakhir menunjukkan tcp6 meskipun itu alamat IPv4?

Jawaban:


33

Ini terjadi karena secara default, soket AF_INET6 sebenarnya akan berfungsi untuk IPv4 dan IPv6. Lihat bagian 3.7 - Kompatibilitas dengan Node IPv4 dari RFC 3493 - Ekstensi Dasar Antarmuka Socket untuk IPv6

Berikut adalah contoh singkat kode yang dapat menghasilkan situasi seperti ini:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define TEST_PORT 5555

#define xstr(s) str(s)
#define str(x) #x

int main (int argc, char **argv)
{
    int v6server;
    int v4client;
    int rc;

    struct sockaddr_in6 s6addr = {
        .sin6_family = AF_INET6,
        .sin6_flowinfo = 0,
        .sin6_port = htons(TEST_PORT),
        .sin6_addr = in6addr_any
    };

    struct sockaddr_in c4addr = {
        .sin_family = AF_INET,
        .sin_port = htons(TEST_PORT),
        .sin_addr = inet_addr("127.0.0.1")
    };

    // Open an IPv6 listener
    v6server = socket(AF_INET6, SOCK_STREAM, 0);
    if (v6server < 0) perror("socket()");

    rc = bind(v6server, (struct sockaddr *)&s6addr, sizeof(s6addr));
    if (rc != 0) perror("bind()");

    rc = listen(v6server, 0);
    if (rc != 0) perror("listen()");

    // Connect to the listener with an IPv4 socket
    v4client = socket(AF_INET, SOCK_STREAM, 0);
    if (v4client < 0) perror("socket()");

    rc = connect(v4client, (struct sockaddr *)&c4addr, sizeof(c4addr));
    if (rc != 0) perror("connect()");

    // inspect open sockets
    system("netstat -tan | grep " xstr(TEST_PORT));

    close(v4client);
    close(v6server);
}

Output pada mesin Ubuntu saya adalah:

$ make v4v6
cc     v4v6.c   -o v4v6
$ ./v4v6 
tcp        0      0 127.0.0.1:46518         127.0.0.1:5555          ESTABLISHED
tcp6       0      0 :::5555                 :::*                    LISTEN     
tcp6       0      0 127.0.0.1:5555          127.0.0.1:46518         ESTABLISHED
$ 
  • The tcp6 LISTENentri untuk mendengarkan socket pada port 5555. Perhatikan bahwa itu adalah soket AF_INET6, sehingga akan menerima IPv4 dan IPv6 koneksi masuk.
  • The tcp ESTABLISHEDentri adalah hasil dari menghubungkan soket AF_INET4 ke pendengar (sambungan aktif).
  • The tcp6 ESTABLISHEDentri untuk koneksi pasif melahirkan dari soket pendengar. Itu muncul sebagai tcp6, karena itu muncul dari tcp6pendengar; namun itu mewakili koneksi dari IPv4.

Perlu dicatat hal berikut:

  • Perilaku ini khusus untuk soket AF_INET6. Soket AF_INET (IPv4) tidak bisa dan tidak akan berurusan dengan IPv6 apa pun.
  • Perilaku ini dapat diganti dengan opsi soket IPV6_V6ONLY . Pengaturan opsi ini akan menyebabkan soket hanya menangani IPv6 dan tidak mengizinkan IPv4 apa pun.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.