-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
udpsend error in mac os #175
Comments
Can you give a concrete example? |
I have tested this on macOS 10.13 and found that if you use Didn't test with other configuration: IPv4 only environment or sending to IPv6 address. Here is a simple example: #include <libmill.h>
#include <stdio.h>
int main() {
ipaddr local = iplocal(NULL, 0, IPADDR_PREF_IPV6);
udpsock s = udplisten(local);
ipaddr addr = ipremote("8.8.8.8", 60000, 0, -1);
char* data[10] = {0};
udpsend(s, addr, data, 10);
printf("%d\n", errno);
} Program would print out 22 in this case. If you change |
It looks like the error is coming from here: https://github.com/sustrik/libmill/blob/master/udp.c#L104 22 means EINVAL The man page description doesn't seem to apply: https://www.unix.com/man-page/osx/2/sendto/ Try checking whether udplisten succeeds. |
Upon more testing I've found that the above code works on ipv4-only interfaces such as one of my VPN tunnel utun2, but it fails on interfaces with ipv6 address even if it is link local address (fe80::/64). udplisten succeeded nonetheless. |
Can you trace the execution to udp.c:104 then check the argument values to sendto() function as well as the result value and errno? |
(gdb) r
Starting program: /Users/MrX/test2
[New Thread 0x1403 of process 43440]
warning: unhandled dyld version (15)
Thread 2 hit Breakpoint 1, main () at test2.c:9
9 udpsend(s, addr, data, 10);
(gdb) s
mill_udpsend_ (s=0x100200060, addr=..., buf=0x7ffeefbff600, len=10) at udp.c:103
103 struct sockaddr *saddr = (struct sockaddr*) &addr;
(gdb) s
104 ssize_t ss = sendto(s->fd, buf, len, 0, saddr, saddr->sa_family ==
(gdb) p s->fd
$1 = 3
(gdb) p buf
$2 = (const void *) 0x7ffeefbff600
(gdb) p len
$3 = 10
(gdb) p saddr->sa_family
$4 = 2 '\002'
(gdb) s
106 int _errno = errno;
(gdb) s
107 if(mill_fast(ss == (ssize_t)len)) {
(gdb) p ss
$5 = -1
(gdb) p _errno
$6 = 22 Couldn't check errno in gdb so I modified udp.c a little. Seems that saddr->sa_family is AF_INET. |
sa_family is AF_INET because you pass in IPv4 address (8.8.8.8) Possibly, the problem is that socket, although using "bind to all interfaces" option only binds to IPv6 interfaces and as such it complains when trying to send to IPv4 address. |
I have tried to bind to dual-stack interfaces by using iplocal("en0", 0, IPADDR_PREF_IPV6); but still the same error. en0 have both ipv4 and ipv6 addresses. |
What happens if you try to send the packet to an acutal IPv6 address? |
The packet could be sent successfully with no error. The packet was observed on tcpdump. |
When invoke udpsend method, the error occurs. error code is 22, means invalid argument.
The text was updated successfully, but these errors were encountered: