Closed jwt27 closed 1 year ago
Weird error on CI. Why is grab_localport
undefined on Watcom model=large but not in other configurations?
I'm not even 100% sure if grab_localport
is needed here though.
Watcom/Large-model does not have grab_localport()
since it's inside a USE_BSD_API
section in ports.c
.
Just add a do-nothing version for this:
--- a/src/ports.c
+++ b/src/ports.c
@@ -143,6 +143,13 @@ int grab_localport (WORD port)
FD_SET (port, lport_inuse);
return (rc);
}
+
+#else
+int grab_localport (WORD port)
+{
+ ARGUSED (port);
+ return (-1);
+}
#endif
Ah that makes sense, thanks. But do we need grab_localport()
there in the native API? I think only if a program uses both native and BSD APIs (probably rare).
But do we need grab_localport() there in the native API?
Probably not.
But do we need grab_localport() there in the native API?
Probably not.
I'll remove it then.
Also I realized, it wouldn't be too difficult now to implement non-blocking ARP lookups for UDP sockets. Might be worth looking into.
BTW, these Cygwin warnings:
In function 'gethostbyaddr6_internal',
inlined from 'gethostbyaddr6' at gethost6.c:434:7:
../inc/netinet/in.h:444:10: warning: '__builtin_memcmp_eq' reading 32 bytes from a region of size 16 [-Wstringop-overflow=]
444 | (memcmp ((void*)(a), (void*)(b), sizeof(struct in6_addr)) == 0)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
has been bugging me. I fail to understand what the issue here. No warnings like this for MinGW (!).
I think I see it:
struct in6_addr {
union {
u_char _S6_u8[16];
u_short _S6_u16[8];
u_long _S6_u32[4];
} _S6_un;
};
sizeof(u_long)
will be 8 bytes on x86_64. Better option there is to use <stdint.h>
types.
sizeof(u_long) will be 8 bytes on x86_64.
Ah, yes. Effin LP64 platform.
it wouldn't be too difficult now to implement non-blocking ARP lookups for UDP sockets.
ARP should be pretty fast. Later perhaps. I want to merge this first if you're comfortable with it.
it wouldn't be too difficult now to implement non-blocking ARP lookups for UDP sockets.
ARP should be pretty fast. Later perhaps. I want to merge this first if you're comfortable with it.
Sure, but I haven't done much testing yet, and I don't have any "real-world" UDP code to try with. Any suggestions?
Any suggestions?
C-Ares perhaps (all about UDP you know). I made this djgpp Makefile.dj for it long ago. And with these patches: c-ares.diff.txt
Here bin\adig -s1.1.1.1 -t mx apple.com
gives:
id: 25561
flags: qr rd ra
opcode: QUERY
rcode: NOERROR
Questions:
apple.com . MX
Answers:
apple.com . 3600 MX 20 mx-in-rno.apple.com.
apple.com . 3600 MX 20 mx-in-mdn.apple.com.
apple.com . 3600 MX 10 mx-in.g.apple.com.
apple.com . 3600 MX 20 mx-in-hfd.apple.com.
apple.com . 3600 MX 20 mx-in-vib.apple.com.
(A Winsock2 version)
C-Ares works for me, thanks. I used the current version from git, and configured with --enable-nonblocking
to double-check that too.
I've been trying this test case, sending messages with nc -u 10.0.0.x 12345
from different machines. No issues. I think it's safe to merge.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
const int fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
perror("socket()");
return 1;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(12345);
if (bind(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)))
{
perror("bind()");
goto fail;
}
for (unsigned i = 0; i < 10; ++i)
{
char buf[128];
socklen_t addrlen = sizeof (struct sockaddr_in);
socklen_t n = recvfrom(fd, buf, 128, 0, (struct sockaddr*)&addr, &addrlen);
if (n < 0)
{
perror("recvfrom()");
goto fail;
}
fprintf(stderr, "from %s: ", inet_ntoa(addr.sin_addr));
fwrite(buf, 1, n, stderr);
if (connect(fd, (struct sockaddr*)&addr, addrlen))
{
perror("connect()");
goto fail;
}
if (send(fd, "hello\n", 7, 0) < 0)
{
perror("send()");
goto fail;
}
}
close(fd);
return 0;
fail:
printf("fail");
close(fd);
return 1;
}
No issues. I think it's safe to merge.
Very good. Since here a Watt-32-version\bin\adig.exe -d -s1.1.1.1 -t mx apple.com
hangs even after receiving a good
response. From wattcp.sk:
00:00:00.008: socket: fam:AF_INET type:DGRAM, proto IPPROTO_UDP, 3
00:00:00.008: ioctlsocket:3, file cmd: FIONBIO 1
00:00:00.008: connect:3, auto-binding, src/dest ports: 1355/53
00:00:00.021: send:3, len=27, 1.1.1.1 (53) / UDP
00:00:00.037: select_s: n=0-3, rw-, timeout 4.969000s, cnt=1 (1r/0w/0x)
00:00:00.052: recvfrom:3, 2: remote: 1.1.1.1 (53), len=155
00:00:00.068: recvfrom:3, EWOULDBLOCK, len=-1
00:00:00.083: select_s: n=0-3, rw-, timeout 4.922000s, timeout!: 4.937033s
00:00:05.020: send:3, len=27, 1.1.1.1 (53) / UDP
...
Calling select_s()
over and over again. (this is a Win-version since I have no way to run DOS-programs).
Merging and many thanks again!
Very good. Since here a
Watt-32-version\bin\adig.exe -d -s1.1.1.1 -t mx apple.com
hangs even after receiving a good response. From wattcp.sk:00:00:00.008: socket: fam:AF_INET type:DGRAM, proto IPPROTO_UDP, 3 00:00:00.008: ioctlsocket:3, file cmd: FIONBIO 1 00:00:00.008: connect:3, auto-binding, src/dest ports: 1355/53 00:00:00.021: send:3, len=27, 1.1.1.1 (53) / UDP 00:00:00.037: select_s: n=0-3, rw-, timeout 4.969000s, cnt=1 (1r/0w/0x) 00:00:00.052: recvfrom:3, 2: remote: 1.1.1.1 (53), len=155 00:00:00.068: recvfrom:3, EWOULDBLOCK, len=-1 00:00:00.083: select_s: n=0-3, rw-, timeout 4.922000s, timeout!: 4.937033s 00:00:05.020: send:3, len=27, 1.1.1.1 (53) / UDP ...
Calling
select_s()
over and over again. (this is a Win-version since I have no way to run DOS-programs).
Interesting. I had to reconfigure with CPPFLAGS=-DWATT32
to make -d
work. If it's any help, here is my wattcp.sk for the same command.
It doesn't seem to use non-blocking mode (does use still-broken fcntl()
on djgpp). But as you can see, the reconnect works now:
1193:02:47.268: socket: fam:AF_INET type:DGRAM, proto IPPROTO_UDP, 8
1193:02:47.268: _fsext_demux: fd 8s, func 7 = "fcntl", cmd 00000003, arg 000006E0
1193:02:47.268: fcntlsocket:8, , F_GETFL: blocking
1193:02:47.268: _fsext_demux: fd 8s, func 7 = "fcntl", cmd 00000006, arg 000006E0
1193:02:47.268: fcntlsocket:8, , F_SETFL: blocking
1193:02:47.268: connect:8, auto-binding, src/dest ports: 1360/53
1193:02:46.627: send:8, len=27, flags 0x80
1193:02:46.627: connect:8, reconnecting, 1.1.1.1 (53) / UDP
1193:02:46.628: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.628: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.629: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.629: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.629: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.629: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.630: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.630: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.630: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.631: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.631: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.631: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.632: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.632: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.632: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.632: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.633: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.633: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.633: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.633: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.634: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.634: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
1193:02:46.634: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 00088B80
1193:02:46.635: select_s: n=0-8, rwx, timeout 0.000000s, cnt=2 (1r/1w/0x)
1193:02:46.636: recvfrom:8, 2: remote: 1.1.1.1 (53), len=155
1193:02:46.650: _fsext_demux: fd 8s, func 6 = "close", cmd 00172614, arg 00000000
1193:02:46.650: close_s:8No ETHERS line found in WATTCP.CFG
Local ports still in use:
I had to reconfigure with CPPFLAGS=-DWATT32
Can you post the CFLAGS
used?
I had to reconfigure with CPPFLAGS=-DWATT32
Can you post the
CFLAGS
used?
I had them unset so it used some default, probably -g -O2
.
edit: from the makefile: CFLAGS = -g0 -O2 -Wno-system-headers
It doesn't seem to use non-blocking mode (does use still-broken
fcntl()
on djgpp).
Aaah, just realized didn't use my patched libc. Now it does set non-blocking mode. Doesn't make any difference though since ARPs still always block on UDP.
1193:02:47.268: socket: fam:AF_INET type:DGRAM, proto IPPROTO_UDP, 8
1193:02:47.271: _fsext_demux: fd 8s, func 7 = "fcntl", cmd 00000003, arg 00000000
1193:02:47.271: fcntlsocket:8, , F_GETFL: blocking
1193:02:47.271: _fsext_demux: fd 8s, func 7 = "fcntl", cmd 00000006, arg 00002000
1193:02:47.271: fcntlsocket:8, , F_SETFL: non-blocking
1193:02:47.271: connect:8, auto-binding, src/dest ports: 1118/53
00:00:00.330: send:8, len=27, flags 0x80
00:00:00.330: connect:8, reconnecting, 1.1.1.1 (53) / UDP
00:00:00.332: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.332: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.332: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.332: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.333: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.333: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.333: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.333: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.334: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.334: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.335: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.335: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.335: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.335: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.336: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.336: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.336: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.336: select_s: n=0-8, rwx, timeout 0.000000s, cnt=1 (0r/1w/0x)
00:00:00.337: _fsext_demux: fd 8s, func 5 = "ready", cmd 00000006, arg 0009C400
00:00:00.337: select_s: n=0-8, rwx, timeout 0.000000s, cnt=2 (1r/1w/0x)
00:00:00.338: recvfrom:8, 2: remote: 1.1.1.1 (53), len=155
00:00:00.352: _fsext_demux: fd 8s, func 6 = "close", cmd 00172614, arg 00000000
00:00:00.352: close_s:8No ETHERS line found in WATTCP.CFG
Local ports still in use:
edit: Also, strange timer overflow there.
Noticed this while working on #80. For non-
SOCK_STREAM
sockets, it should be possible to rebind the destination address by callingconnect()
again.https://man7.org/linux/man-pages/man2/connect.2.html
Not tested, but it should work since I just copied the code from
transmit.c
.