Issue #13407 has been updated by ioquatix (Samuel Williams).


Okay, so I found the issue.

Firstly, `sendmsg` doesn't work for UDP sockets, I get `EINVAL` on Darwin OS.

Secondly, `UDPSocket` overrides `#send` but only in a specific case:

~~~
static VALUE
udp_send(int argc, VALUE *argv, VALUE sock)
{
    VALUE flags, host, port;
    struct udp_send_arg arg;
    VALUE ret;

    if (argc == 2 || argc == 3) {
	return rsock_bsock_send(argc, argv, sock);
    }
    rb_scan_args(argc, argv, "4", &arg.sarg.mesg, &flags, &host, &port);

    StringValue(arg.sarg.mesg);
    GetOpenFile(sock, arg.fptr);
    arg.sarg.fd = arg.fptr->fd;
    arg.sarg.flags = NUM2INT(flags);
    arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0);
    ret = rb_ensure(udp_send_internal, (VALUE)&arg,
		    rsock_freeaddrinfo, (VALUE)arg.res);
    if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port);
    return ret;
}
~~~

If you call `udp_socket.send(data, flags, host, port)` it uses `sendto` which works, otherwise it uses `rsock_bsock_send` which fails with `EINVAL`.

If you already constructed a `sockaddr`, for example, trying `udp_socket.send(data, flags, sockaddr)` will fail. It's all a bit confusing. Additionally, for UDPSocket, there is no `send_nonblock` which is my real issue here, and using `sendmsg_nonblock` fails.

----------------------------------------
Bug #13407: We have recv_nonblock but not send_nonblock... can we add it?
https://bugs.ruby-lang.org/issues/13407#change-64099

* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: 
* Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
We have recv_nonblock, read_nonblock, write_nonblock but not BasicSocket#send_nonblock. Is this a mistake?



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>