On 08/01/2023 16:14, Sjoerd Mullender wrote:
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@lists.fedoraproject.org
To unsubscribe send an email tousers-le...@lists.fedoraproject.org
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@lists.fedoraproject.org
Do not reply to spam, report
it:https://pagure.io/fedora-infrastructure/new_issue
_______________________________________________
users mailing list -- users@lists.fedoraproject.org
To unsubscribe send an email to users-le...@lists.fedoraproject.org
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@lists.fedoraproject.org
Do not reply to spam, report it:
https://pagure.io/fedora-infrastructure/new_issue