ytcast
ytcast copied to clipboard
sendto: operation not permitted
Arch Linux linux 6.6.3.arch1-1 ytcast-bin 1.3.0-1 go 2:1.21.5-1
$ ytcast -s -verbose
13:08:42 ytcast.go:91: ytcast v1.3.0
13:08:42 ytcast.go:224: mkdir -p /home/james/.cache/ytcast
13:08:42 ytcast.go:233: loading cache /home/james/.cache/ytcast/ytcast.json
13:08:42 ssdp.go:70: M-SEARCH udp 239.255.255.250:1900 ST "urn:dial-multiscreen-org:service:dial:1" MX 3 timeout 4s
13:08:42 ytcast.go:253: saving cache /home/james/.cache/ytcast/ytcast.json
13:08:42 ytcast.go:94: Discover: write udp4 0.0.0.0:54096->239.255.255.250:1900: sendto: operation not permitted
ytcast: Discover: write udp4 0.0.0.0:54096->239.255.255.250:1900: sendto: operation not permitted
$ sudo ytcast -s -verbose
13:10:32 ytcast.go:91: ytcast v1.3.0
13:10:32 ytcast.go:224: mkdir -p /root/.cache/ytcast
13:10:32 ytcast.go:233: loading cache /root/.cache/ytcast/ytcast.json
13:10:32 ssdp.go:70: M-SEARCH udp 239.255.255.250:1900 ST "urn:dial-multiscreen-org:service:dial:1" MX 3 timeout 4s
13:10:32 ytcast.go:253: saving cache /root/.cache/ytcast/ytcast.json
13:10:32 ytcast.go:94: Discover: write udp4 0.0.0.0:46330->239.255.255.250:1900: sendto: operation not permitted
ytcast: Discover: write udp4 0.0.0.0:46330->239.255.255.250:1900: sendto: operation not permitted
$ java RokuDialDiscoverySample
*** sending ROKU m-search req
Exception in thread "main" java.net.SocketException: Operation not permitted
at java.base/sun.nio.ch.DatagramChannelImpl.send0(Native Method)
at java.base/sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(DatagramChannelImpl.java:953)
at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:914)
at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:872)
at java.base/sun.nio.ch.DatagramChannelImpl.blockingSend(DatagramChannelImpl.java:904)
at java.base/sun.nio.ch.DatagramSocketAdaptor.send(DatagramSocketAdaptor.java:220)
at java.base/java.net.DatagramSocket.send(DatagramSocket.java:662)
at RokuDialDiscoverySample.discoverDevice(RokuDialDiscoverySample.java:57)
at RokuDialDiscoverySample.main(RokuDialDiscoverySample.java:36)
Any suggestions?
How does ytcast
know which network interface to use?
hi, thank you for reporting this!
Any suggestions?
i've never seen this error before, but looks like some problem with the network/firewall, from a quick google search:
https://stackoverflow.com/questions/6240951/sendto-operation-not-permitted-netsnmp https://stackoverflow.com/questions/23859164/linux-udp-socket-sendto-operation-not-permitted
do you have any "particular" firewall/iptables config? what does syslog
say when you try to run ytcast
?
How does ytcast know which network interface to use?
ytcast
uses the net.ListenUDP
function to get a "connection" for ssdp m-search like this:
conn, err := net.ListenUDP("udp4", nil)
and from the docs:
func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) ... If the IP field of laddr is nil or an unspecified IP address, ListenUDP listens on all available IP addresses of the local system except multicast IP addresses.
so i guess it binds on all available interfaces
If the IP field of laddr is nil or an unspecified IP address, ListenUDP listens on all available IP addresses of the local system except multicast IP addresses.
so i guess it binds on all available interfaces
That would be the problem. I configure nftables to block the 239.0.0.0/8 range on the WAN interface. Wikipedia summarizes:
The 239.0.0.0/8 range is assigned by RFC 2365 for private use within an organization. Per the RFC, packets destined to administratively scoped IPv4 multicast addresses do not cross administratively defined organizational boundaries ...
Might I suggest: https://pkg.go.dev/net#Interfaces and https://pkg.go.dev/net#Interface.Addrs, and a new ytcast
option -i <string>
, with "restrict ytcast to the specified network interface. if not specified, defaults to all network interfaces. the option can be specified more than once"? That would be backward compatible, and should avoid potential problems with hosts having multiple network interfaces and with hosts acting as routers. You can just select the first or last IP address associated with each network interface specified, or use nil
if none is specified, and then still use net.ListenUDP
.
a new ytcast option -i <string>, with "restrict ytcast to the specified network interface. if not specified, defaults to all network interfaces. the option can be specified more than once"? That would be backward compatible, and should avoid potential problems with hosts having multiple network interfaces and with hosts acting as routers.
yes allowing the user to specify the network interface to use seems a reasonable solution, but i'm not sure what would be the benefit of "specifying the option more than once"? i.e. i'm not sure if there is "simple" api to "bind to multiple selected addresses" and if it's worth it to implement such a feature.
You can just select the first or last IP address associated with each network interface specified, or use nil if none is specified, and then still use net.ListenUDP.
ok, i'll go with the first IP address, maybe in the future we could add some syntax to specify also the IP address of the interface to use, or we could do like curl does:
--interface <name>
Perform an operation using a specified interface. You can enter interface name, IP address or host name
also, it's not just the net.ListenUDP()
call: if we implement such option, i
expect that all connections made by ytcast
(i.e. even http calls etc..) go
through the provided network interface/address.
i'm not sure what would be the benefit of "specifying the option more than once"? i.e. i'm not sure if there is "simple" api to "bind to multiple selected addresses"
That would just be to accommodate some host with many different interfaces, each with different sub-networks. So only to be "completely configurable", but not a likely use case.
and if it's worth it to implement such a feature.
Ha! Only if it were easy. But, I suppose that would require iterating through every listed interface, for every operation.
Most likely, there is only ever going to be one interface using ytcast
. And the original issue is avoiding sending on multiple interfaces, not how to send on multiple interfaces. And, I suppose that multiple instances of ytcast
could be run, specifying different individual interfaces, if someone actually needed to do that.
So, yeah, just ignore that idea about "specified more than once".
hi @thx1111, i finally found the time to work on this!
the new version of ytcast
(v1.4.0)
adds the -i
flag which allows to specify the local network interface (or ip address
or hostname) that ytcast
must use for network operations.
example passing a network interface name (ytcast
will choose the first ip
address of the interface):
$ ytcast -i wlp3s0 -s -verbose
21:52:50 ytcast.go:94: ytcast v1.4.0
...
21:52:50 ytcast.go:122: using local address 192.168.1.42 for network operations
21:52:50 ssdp.go:77: M-SEARCH udp 239.255.255.250:1900 ST "urn:dial-multiscreen-org:service:dial:1" MX 3 timeout 4s
...
21:52:54 ssdp.go:92: read udp4 192.168.1.42:56827: i/o timeout
...
or directly an ip address:
$ ytcast -i 192.168.1.42 -s -verbose
21:55:34 ytcast.go:94: ytcast v1.4.0
...
21:55:34 ytcast.go:119: 192.168.1.42: addrFromInterface: route ip+net: no such network interface
21:55:34 ytcast.go:122: using local address 192.168.1.42 for network operations
21:55:34 ssdp.go:77: M-SEARCH udp 239.255.255.250:1900 ST "urn:dial-multiscreen-org:service:dial:1" MX 3 timeout 4s
...
21:55:38 ssdp.go:92: read udp4 192.168.1.42:58277: i/o timeout
...
i hope that this solves your problems, if so, please close this issue, otherwise, feel free to report other things.
Sorry about the delay - other commitments.
Yes! That seems to do the magic. Thanks!
I do have one other suggestion to offer, to make using the "specify network interface" option easier to use, for anyone using ytcast
for the first time. That is, whenever ytcast
encounters the error,
13:32:55 ytcast.go:97: Discover: write udp4 0.0.0.0:41549->239.255.255.250:1900: sendto: operation not permitted
then, in addition to reporting the corresponding error message,
ytcast: Discover: write udp4 0.0.0.0:41549->239.255.255.250:1900: sendto: operation not permitted
ytcast
should also output a second line, a "friendly suggestion," such as, "Do you need to ..." or "You may need to..." or simply "Try ...", as for instance:
Try specifying a local network interface with the '-i string' option
Otherwise, very likely, a new user is not going to immediately know how to respond to the sendto: operation not permitted
error.
BTW, off on a tangent, to my surprise, a "TCL Roku TV" apparently knows how to do DIAL. I see it may take over 20 seconds for ytcast
to receive a "screenId", but, with patience, it works! According to mDNS/DNS-SD/Zeroconf/"Rendezvous"/"Bonjour", this TCL Roku TV also knows '_spotify-connect._tcp' and '_airplay._tcp'.
glad to hear your issue is fixed and that it works on a "TCL Roku TV" too :)
as for the error "hint", while it could be a nice feature to have (not only for this specific error but in general), i don't want to "bloat" the code too much. also, this seems to be a rather "remote" case and i assume that if a user is skilled enough to tinker with his firewall, he can certainly do a google search for "ytcast sendto operation not permitted" and find this issue.
Thanks Marco