Próbuję użyć portu z dwóch aplikacji i każdy z nich odbierze pakiet z innego zestawu adresów IP. Aby to osiągnąć, używam opcji gniazd SO_REUSEPORT i SO_ATTACH_REUSEPORT_CBPF. Mój kod wygląda następująco:SO_ATTACH_REUSEPORT_CBPF opcja gniazda nieoczekiwane zachowanie
parentfd = socket(AF_INET, SOCK_STREAM, 0);
if (parentfd < 0)
error("ERROR opening socket");
struct sock_filter code[]={
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 0, 3, 0x00000800 },
{ 0x20, 0, 0, 0x0000001a },
{ 0x15, 2, 0, 0xc0a8ff01 },
{ 0x6, 0, 0, 0x00000000 },
{ 0x6, 0, 0, 0x00040000 },
{ 0x6, 0, 0, 0x00000001 },
};
struct sock_fprog bpf = {
.len = ARRAY_SIZE(code),
.filter = code,
};
if (setsockopt(parentfd, SOL_SOCKET, SO_REUSEPORT, (const void *)&optval,sizeof(optval)))
error("ERROR setting SO_REUSEPORT");
if (setsockopt(parentfd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, (const void *)&bpf, sizeof(bpf)))
error("ERROR setting SO_ATTACH_REUSEPORT_CBPF);
Mam też inny proces, który nasłuchuje do tego samego portu, używając tylko flaga SO_REUSEPORT. Z maszyny z IP 192.168.255.1
używam echo 1234 | ncat 192.168.255.150 1234
. Na podstawie mojego filtru oczekiwałbym, że cały ruch z tego adresu IP zostanie odebrany przez drugi proces. Jednak wszystko jest odbierane przez pierwszego. Kiedy wymienić filtr do prostego:
struct sock_filter code[]={ { 0x6, 0, 0, 0x00000001 }, };
To działa zgodnie z oczekiwaniami i wszystkie pakiety są odbierane przez drugi proces. Jakiś pomysł, dlaczego tak się dzieje?
Jak pan wpadł na oryginalnym filtrem ? –