On 07/01/2023 01.38, Gordon Messmer wrote:
On 2023-01-06 06:17, Sjoerd Mullender wrote:
I have a program that is supposed to listen to the same port on both IPv4 and IPv6 sockets. In the past, what it did, was basically: create new socket for IPv6, set option IPV6_V6ONLY to off, bind, listen; then create a new socket for IPv4, and also bind and listen.
Do you have sample code that demonstrates this process?
I'm confused by your description, because setting IPV6_V6ONLY to 0 with setsockopt should result in a socket that's bound to a port that accepts both IPv4 and IPv6 connections. You shouldn't have ever been able to bind to that port in IPv4 in the past.
See the attached program. Can be compiled without any extra options.
This program creates an IPv6 listening socket and tells it to also do IPv4. Then it executes "netstat -anp | grep <pid>" to show what it did.
After that it tries to create an IPv4 listening socket for the port that was assigned in the first round and if successful again executes netstat. If not successful, it will tell why.
When trying to bind to the wildcard address (specify "all" on the command line), the behavior is very different from when specifying "localhost".
Run as
$ ./a.out all 0
$ ./a.out localhost 0
and see the difference in behavior. When using "all", the second round (IPv4) says that bind returns 1 unexpectedly, and the port is also unexpected. When using "localhost", both IPv6 and IPv4 succeed and listen to the same port, but using two different sockets internally.
The behavior for the "all" case is different with the older kernel 6.0.15-300.fc37.x86_64 where bind will say "Address already in use".
I made a small change like this:
snprintf(command, sizeof(command),
"netstat -tanp | grep ' %d/'", (int) getpid());
system(command);
snprintf(command, sizeof(command), "lsof
-p %d", (int) getpid());
system(command);
and here:
default:
fprintf(stderr, "bind: unexpected
return: %d\n", e);
perror("bind");
break;
I netstat line is not going to return false matches and lsof is a 2nd way to see what is bound.
THis works as you expected:
$ ./a.out
localhost 0
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp6 0 0 ::1:41787 :::*
LISTEN 36315/./a.out
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
a.out 36315 barry cwd DIR 0,37 2644 877499
/home/barry/Downloads
a.out 36315 barry rtd DIR 0,33 184 256 /
a.out 36315 barry txt REG 0,37 25968 3258908
/home/barry/Downloads/a.out
a.out 36315 barry mem REG 0,31 3258908
/home/barry/Downloads/a.out (path dev=0,37)
a.out 36315 barry mem REG 0,31 3693988
/usr/lib64/libc.so.6 (path dev=0,33)
a.out 36315 barry mem REG 0,31 3693985
/usr/lib64/ld-linux-x86-64.so.2 (path dev=0,33)
a.out 36315 barry 0u CHR 136,5 0t0 8
/dev/pts/5
a.out 36315 barry 1u CHR 136,5 0t0 8
/dev/pts/5
a.out 36315 barry 2u CHR 136,5 0t0 8
/dev/pts/5
a.out 36315 barry 3u IPv6 565528 0t0 TCP
localhost:41787 (LISTEN)
a.out 36315 barry 66r a_inode 0,14 0 3098
inotify
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:41787 0.0.0.0:*
LISTEN 36315/./a.out
tcp6 0 0 ::1:41787 :::*
LISTEN 36315/./a.out
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
a.out 36315 barry cwd DIR 0,37 2644 877499
/home/barry/Downloads
a.out 36315 barry rtd DIR 0,33 184 256 /
a.out 36315 barry txt REG 0,37 25968 3258908
/home/barry/Downloads/a.out
a.out 36315 barry mem REG 0,31 3258908
/home/barry/Downloads/a.out (path dev=0,37)
a.out 36315 barry mem REG 0,31 3693988
/usr/lib64/libc.so.6 (path dev=0,33)
a.out 36315 barry mem REG 0,31 3693985
/usr/lib64/ld-linux-x86-64.so.2 (path dev=0,33)
a.out 36315 barry 0u CHR 136,5 0t0 8
/dev/pts/5
a.out 36315 barry 1u CHR 136,5 0t0 8
/dev/pts/5
a.out 36315 barry 2u CHR 136,5 0t0 8
/dev/pts/5
a.out 36315 barry 3u IPv6 565528 0t0 TCP
localhost:41787 (LISTEN)
a.out 36315 barry 4u IPv4 565531 0t0 TCP
localhost:41787 (LISTEN)
a.out 36315 barry 66r a_inode 0,14 0 3098
inotify
But this does not:
$ ./a.out all
0
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp6 0 0 :::42243 :::*
LISTEN 36396/./a.out
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
a.out 36396 barry cwd DIR 0,37 2644 877499
/home/barry/Downloads
a.out 36396 barry rtd DIR 0,33 184 256 /
a.out 36396 barry txt REG 0,37 25968 3258908
/home/barry/Downloads/a.out
a.out 36396 barry mem REG 0,31 3258908
/home/barry/Downloads/a.out (path dev=0,37)
a.out 36396 barry mem REG 0,31 3693988
/usr/lib64/libc.so.6 (path dev=0,33)
a.out 36396 barry mem REG 0,31 3693985
/usr/lib64/ld-linux-x86-64.so.2 (path dev=0,33)
a.out 36396 barry 0u CHR 136,5 0t0 8
/dev/pts/5
a.out 36396 barry 1u CHR 136,5 0t0 8
/dev/pts/5
a.out 36396 barry 2u CHR 136,5 0t0 8
/dev/pts/5
a.out 36396 barry 3u IPv6 565577 0t0 TCP
*:42243 (LISTEN)
a.out 36396 barry 66r a_inode 0,14 0 3098
inotify
bind: unexpected return: 1
bind: Success
bound to unexpected port 0, expected 42243
And strace shows this for the bad bind:
socket(AF_INET, SOCK_STREAM,
IPPROTO_TCP) = 4
bind(4, {sa_family=AF_INET, sin_port=htons(43925),
sin_addr=inet_addr("0.0.0.0")}, 16) = 1
That bind() return 1 looks like a bug, that is not a documented return value.
I think you are right and its a regression.I'm running the code with kernel 6.0.16-300.fc37.x86_64
Barry
_______________________________________________ users mailing list -- users@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to users-leave@xxxxxxxxxxxxxxxxxxxxxxx Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/users@xxxxxxxxxxxxxxxxxxxxxxx Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue
_______________________________________________ users mailing list -- users@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to users-leave@xxxxxxxxxxxxxxxxxxxxxxx Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/users@xxxxxxxxxxxxxxxxxxxxxxx Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue