webrtc
webrtc copied to clipboard
Permission issue with PION WebRTC under GOMOBILE Android >= 11 (SDK 30) - EDIT: SOLVED BY https://github.com/golang/go/pull/61089
Your environment.
- Version: latest
- Browser: doesn't matter
- Other Information -none
What did you do?
I did choose https://github.com/pion/webrtc/tree/master/examples/custom-logger
Took the code from main.go and used it to build an *.AAR to import that into my Android app. Main was exported
Android called Main and this is what I got:
I/GoLog: Creating logger for pc
I/GoLog: Creating logger for ice
I/GoLog: Creating logger for ortc
I/GoLog: Creating logger for DTLSTransport
I/GoLog: Creating logger for ortc
I/GoLog: Creating logger for pc
I/GoLog: Creating logger for ice
I/GoLog: Creating logger for ortc
I/GoLog: Creating logger for DTLSTransport
I/GoLog: Creating logger for ortc
I/GoLog: Creating logger for ice
W/Thread-2: type=1400 audit(0.0:48): avc: denied { bind } for scontext=u:r:untrusted_app:s0:c157,c256,c512,c768 tcontext=u:r:untrusted_app:s0:c157,c256,c512,c768 tclass=netlink_route_socket permissive=0 bug=b/155595000 app=com.vx.myapplication
E/Go: panic: failed to create network: route ip+net: netlinkrib: permission denied
A/libc: Fatal signal 6 (SIGABRT), code -6 (SI_TKILL) in tid 28814 (Thread-2), pid 28615 (x.myapplication)
What did you expect?
I think there should be no permission issue. This permission thing btw is only affecting Android devices with Android > 10 (as documented in the Android SDK). I don't know who has to work around, I would just like to raise this problem (and of course get a solution on a longer run, if possible)
What happened?
Permission issue as shown above, likely because of the new restrictions introduced by Android SDK 30. More details in discussions:
#2636 Permission issue with PION WebRTC under GOMOBILE Android >= 11 https://github.com/[pion/webrtc](https://github.com/pion/webrtc)|pion/webrtcpion/webrtc | 13. Dez. | Hinzugefügt von GitHub
same problem. but after did some research, it's a golang issue. to fix it, maybe we need modify golang source code and build a new binary to build our aar.
Yes, you might be right. I was just "knocking on the bush". However, even there is a patch, this seems to introduce a circular reference, if I get that right. Other than that I don't know where to patch these files on my local machine
ok...just clone golang source code, modify files as mentioned on this, fix the circular reference issue by remove os.IsPermission(err), build a new version of go and replace your local binaries. see install go from souce.
Did you already try that? Did it work?
Did you already try that? Did it work?
No, But worth to try. I removed webrtc communication from my application temporarily. after other work finished i will try it.
OK, I'm on it right now. GOLANG compilation ok. Patching now. Will report
Stuck. It started well. Initial compilation on Ubuntu 20.04 fine. Then I patched the code. I have the feeling that the patch of this file can be omitted at all https://go-review.googlesource.com/c/go/+/507415/5/src/syscall/netlink_linux.go, but for now I just dropped the permission error check. Additional compilation fine.
I replaced the two binaries found in /usr/local/go/bin by the newly generated in ./goroot/bin. Basically go and gofmt.
Now when I run my gomobile command I'm getting a new error. Seems, I'm missing some architectures support now.
(base) ubuntu@simulator:~/AndroidStudioProjects/me/MyApplication/app/golang$ gomobile bind -target=android -o livekit.aar
gomobile: err: exit status 1: stderr: compile: invalid GOARM: must be 5, 6, 7
go: error obtaining buildID for go tool compile: exit status 2
EDIT: Seems it was a version mismatch. I initially patched master, but my previous binary installation was 1.21.5. I then checked out 1.21.5 and made the changes again. This time my gomobile command went through, but at runtime the same problem appeared: Permission issue, panic.
Either this patch doesn't change anything or there are still other places to change or I'm unable to make use of the changed version somehow (not sure, how go dependencies are bound, but I could imagine I would have to change some dependencies in my go.mod too in order to use the patched stuff)
Update. I believe I will have to build the packages net and sys instead of the compiler itself...
sorry. after some testing. i had modified GO_ROOT/libexec/src/net/interface_linux.go, in this way we don't need compile go or gomobile, but result is same, still got route ip+net: netlinkrib: permission denied error. maybe we should dig it deeper by adding some debug info.
OK, the error comes from syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC), so we can say, the RTM_GETADDR + ioctl approach to obtain network card information not working.
Happy new year to you.
OK, the error comes from syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC), so we can say, the RTM_GETADDR + ioctl approach to obtain network card information not working.
I'm not that confident to find the problem in the compiler itself. I have changed the signature of the panic in interfaceTableAndroid:
func interfaceTableAndroid(ifindex int) ([]Interface, error) {
tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
if err != nil {
// return nil, os.NewSyscallError("netlinkrib", err)
return nil, os.NewSyscallError("BlaBla", err)
}
expecting to see that "blabla" instead of "netlinkrib" to no avail.
I more believe to find the root of the problem somewhere in these modules, which are bound to my project implicitly:
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.16.0 // indirect
is interfaceTableAndroid in your GOROOT/libexec/src/interface_linux.go ? i'm pretty sure logs in interface_linux.go will print out because that's exactly what i did.
Can you post your changed interface_linux.go please?
Confused. Where is GOROOT/libexec/src/interface_linux.go? I'm not having that path. Mine is goroot/src/interface_linux.go. Are we talking about different things?
basically, GOROOT should be your golang install path. I installed golang with homebrew, and the path is /opt/homebrew/Cellar/go/1.21.5/libexec/src/net, if you are using ubuntu, it should be /usr/local/go
Can you post your changed interface_linux.go please?
i just reset the code when i found it's not working as excepted. but it's same with this, to resolve build issue, change:
os.IsPermission(err)
to
if e, ok := err.(Errno); !ok && !e.Is(oserror.ErrPermission) {
return nil, err
}
as netlink_linux.go did
I really have doubts that this is the right place for the change. I can't see any reaction of the code other than that permission error, regardless of how I change the things.
basically,
GOROOTshould be your golang install path. I installedgolangwithhomebrew, and the path is/opt/homebrew/Cellar/go/1.21.5/libexec/src/net, if you are using ubuntu, it should be/usr/local/go
I agree, /usr/local/go is the path for Ubuntu, but there is no libexec.
One thing is maybe wrong on my side. I cloned the sources to ~/home/goroot. I applied the changes in that dir and ran from src/all.bash. The results are two binaries in ~/home/goroot/bin: go and gofmt. I just copied those two bins to /usr/local/go/bin.
Should I apply the changes in /usr/local/go instead?
No, not working either...
(base) ubuntu@simulator:/usr/local/go/src$ ./all.bash ERROR: Cannot find /home/ubuntu/go1.4/bin/go. Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.17.13. (base) ubuntu@simulator:/usr/local/go/src$ ^C
I'm going to drop this. I'm not the go expert, it is just a means to reach some target, don't like that either.
Thanks for your efforts
@neilyoung fixed android 11 netlink issue by modify transport package and created a PR. before code merged, you can modify code by yourself as PR did.
You fixed it for pion by replacing net by a fork anet, right? I think I tried that anet too already, it didn't fix my issue (discussion here https://github.com/golang/go/issues/40569). I was using net.Listen, which is not covered by the anet fix. Thanks anyway.
@neilyoung i don't know if tcp listen will works, but if you are using UDP, just change l, mdnsErr := n.ListenUDP("udp4", addr) to l, mdnsErr := net.Listen("unixgram", mdns.DefaultAddress) at createMulticastDNS in github.com/pion/ice/[email protected]/mdns.go, and listen will works.
func createMulticastDNS(n transport.Net, mDNSMode MulticastDNSMode, mDNSName string, log logging.LeveledLogger) (*mdns.Conn, MulticastDNSMode, error) {
if mDNSMode == MulticastDNSModeDisabled {
return nil, mDNSMode, nil
}
// addr, mdnsErr := n.ResolveUDPAddr("udp4", mdns.DefaultAddress)
// if mdnsErr != nil {
// return nil, mDNSMode, mdnsErr
// }
l, mdnsErr := net.Listen("unixgram", mdns.DefaultAddress)
// l, mdnsErr := n.ListenUDP("udp4", addr)
if mdnsErr != nil {
// If ICE fails to start MulticastDNS server just warn the user and continue
log.Errorf("Failed to enable mDNS, continuing in mDNS disabled mode: (%s)", mdnsErr)
return nil, MulticastDNSModeDisabled, nil
}
switch mDNSMode {
case MulticastDNSModeQueryOnly:
conn, err := mdns.Server(ipv4.NewPacketConn(l.(net.PacketConn)), &mdns.Config{})
return conn, mDNSMode, err
case MulticastDNSModeQueryAndGather:
conn, err := mdns.Server(ipv4.NewPacketConn(l.(net.PacketConn)), &mdns.Config{
LocalNames: []string{mDNSName},
})
return conn, mDNSMode, err
default:
return nil, mDNSMode, nil
}
}
Thanks for your patience, very much appreciated.
I need to listen to a UnixSocket.
BTW: This link doesn't work for me github.com/pion/ice/[email protected]/mdns.go, could you please double check?
github.com/pion/ice
sorry, that's my local path, the package is github.com/pion/ice, i'm forked it and creating PR now.
Not a problem. What I can't currently see is this:
- I'm using the LifeKit Server GO SDK in my Android GO module
- This in turn utilizes PION webrtc
Say, I would be able to have a local copy of the PION webrtc which is patched with your PRs. How could I make LifeKit server SDK use this version instead of the web based versions? Would that be only a matter of replacing some dependencies in my go.mod?
This is my current go.mod (which doesn't work with Android 11+ devices):
module [github.com/neilyoung/livekit](http://github.com/neilyoung/livekit)
go 1.21.5
require (
[github.com/livekit/protocol](http://github.com/livekit/protocol) v1.9.3
[github.com/livekit/server-sdk-go](http://github.com/livekit/server-sdk-go) v1.1.4
[github.com/pion/webrtc/v3](http://github.com/pion/webrtc/v3) v3.2.24
)
require (
[github.com/beorn7/perks](http://github.com/beorn7/perks) v1.0.1 // indirect
[github.com/bep/debounce](http://github.com/bep/debounce) v1.2.1 // indirect
[github.com/cespare/xxhash/v2](http://github.com/cespare/xxhash/v2) v2.2.0 // indirect
[github.com/davecgh/go-spew](http://github.com/davecgh/go-spew) v1.1.1 // indirect
[github.com/dgryski/go-rendezvous](http://github.com/dgryski/go-rendezvous) v0.0.0-20200823014737-9f7001d12a5f // indirect
[github.com/eapache/channels](http://github.com/eapache/channels) v1.1.0 // indirect
[github.com/eapache/queue](http://github.com/eapache/queue) v1.1.0 // indirect
[github.com/frostbyte73/core](http://github.com/frostbyte73/core) v0.0.9 // indirect
[github.com/gammazero/deque](http://github.com/gammazero/deque) v0.2.1 // indirect
[github.com/go-jose/go-jose/v3](http://github.com/go-jose/go-jose/v3) v3.0.1 // indirect
[github.com/go-logr/logr](http://github.com/go-logr/logr) v1.3.0 // indirect
[github.com/go-logr/stdr](http://github.com/go-logr/stdr) v1.2.2 // indirect
[github.com/golang/protobuf](http://github.com/golang/protobuf) v1.5.3 // indirect
[github.com/google/uuid](http://github.com/google/uuid) v1.3.1 // indirect
[github.com/gorilla/websocket](http://github.com/gorilla/websocket) v1.5.1 // indirect
[github.com/jxskiss/base62](http://github.com/jxskiss/base62) v1.1.0 // indirect
[github.com/klauspost/compress](http://github.com/klauspost/compress) v1.17.2 // indirect
[github.com/klauspost/cpuid/v2](http://github.com/klauspost/cpuid/v2) v2.2.5 // indirect
[github.com/lithammer/shortuuid/v4](http://github.com/lithammer/shortuuid/v4) v4.0.0 // indirect
[github.com/livekit/mageutil](http://github.com/livekit/mageutil) v0.0.0-20230125210925-54e8a70427c1 // indirect
[github.com/livekit/mediatransportutil](http://github.com/livekit/mediatransportutil) v0.0.0-20231130090133-bd1456add80a // indirect
[github.com/livekit/psrpc](http://github.com/livekit/psrpc) v0.5.2 // indirect
[github.com/mackerelio/go-osstat](http://github.com/mackerelio/go-osstat) v0.2.4 // indirect
[github.com/magefile/mage](http://github.com/magefile/mage) v1.15.0 // indirect
[github.com/matttproud/golang_protobuf_extensions](http://github.com/matttproud/golang_protobuf_extensions) v1.0.4 // indirect
[github.com/nats-io/nats.go](http://github.com/nats-io/nats.go) v1.31.0 // indirect
[github.com/nats-io/nkeys](http://github.com/nats-io/nkeys) v0.4.6 // indirect
[github.com/nats-io/nuid](http://github.com/nats-io/nuid) v1.0.1 // indirect
[github.com/pion/datachannel](http://github.com/pion/datachannel) v1.5.5 // indirect
[github.com/pion/dtls/v2](http://github.com/pion/dtls/v2) v2.2.8 // indirect
[github.com/pion/ice/v2](http://github.com/pion/ice/v2) v2.3.11 // indirect
[github.com/pion/interceptor](http://github.com/pion/interceptor) v0.1.25 // indirect
[github.com/pion/logging](http://github.com/pion/logging) v0.2.2 // indirect
[github.com/pion/mdns](http://github.com/pion/mdns) v0.0.9 // indirect
[github.com/pion/randutil](http://github.com/pion/randutil) v0.1.0 // indirect
[github.com/pion/rtcp](http://github.com/pion/rtcp) v1.2.12 // indirect
[github.com/pion/rtp](http://github.com/pion/rtp) v1.8.3 // indirect
[github.com/pion/sctp](http://github.com/pion/sctp) v1.8.9 // indirect
[github.com/pion/sdp/v3](http://github.com/pion/sdp/v3) v3.0.6 // indirect
[github.com/pion/srtp/v2](http://github.com/pion/srtp/v2) v2.0.18 // indirect
[github.com/pion/stun](http://github.com/pion/stun) v0.6.1 // indirect
[github.com/pion/transport/v2](http://github.com/pion/transport/v2) v2.2.4 // indirect
[github.com/pion/turn/v2](http://github.com/pion/turn/v2) v2.1.3 // indirect
[github.com/pmezard/go-difflib](http://github.com/pmezard/go-difflib) v1.0.0 // indirect
[github.com/prometheus/client_golang](http://github.com/prometheus/client_golang) v1.17.0 // indirect
[github.com/prometheus/client_model](http://github.com/prometheus/client_model) v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
[github.com/prometheus/common](http://github.com/prometheus/common) v0.44.0 // indirect
[github.com/prometheus/procfs](http://github.com/prometheus/procfs) v0.11.1 // indirect
[github.com/redis/go-redis/v9](http://github.com/redis/go-redis/v9) v9.3.0 // indirect
[github.com/stretchr/testify](http://github.com/stretchr/testify) v1.8.4 // indirect
[github.com/thoas/go-funk](http://github.com/thoas/go-funk) v0.9.3 // indirect
[github.com/twitchtv/twirp](http://github.com/twitchtv/twirp) v8.1.3+incompatible // indirect
[github.com/zeebo/xxh3](http://github.com/zeebo/xxh3) v1.0.2 // indirect
[go.uber.org/atomic](http://go.uber.org/atomic) v1.11.0 // indirect
[go.uber.org/multierr](http://go.uber.org/multierr) v1.11.0 // indirect
[go.uber.org/zap](http://go.uber.org/zap) v1.26.0 // indirect
[golang.org/x/crypto](http://golang.org/x/crypto) v0.16.0 // indirect
[golang.org/x/exp](http://golang.org/x/exp) v0.0.0-20231110203233-9a3e6036ecaa // indirect
[golang.org/x/net](http://golang.org/x/net) v0.19.0 // indirect
[golang.org/x/sync](http://golang.org/x/sync) v0.5.0 // indirect
[golang.org/x/sys](http://golang.org/x/sys) v0.15.0 // indirect
[golang.org/x/text](http://golang.org/x/text) v0.14.0 // indirect
[google.golang.org/genproto/googleapis/rpc](http://google.golang.org/genproto/googleapis/rpc) v0.0.0-20231106174013-bbf56f31fb17 // indirect
[google.golang.org/grpc](http://google.golang.org/grpc) v1.59.0 // indirect
[google.golang.org/protobuf](http://google.golang.org/protobuf) v1.31.0 // indirect
[gopkg.in/yaml.v3](http://gopkg.in/yaml.v3) v3.0.1 // indirect
)
As said, I'm an absolute GO newbie. I suppose I would have to replace at least this [github.com/pion/webrtc/v3](http://github.com/pion/webrtc/v3) v3.2.24 by the file system version then. But what about all the other, indirect references?
append to your go.mod file:
replace github.com/pion/transport/v2 => /local/path/to/transport/v2
replace github.com/pion/transport/v3 => /local/path/to/transport/v3
replace github.com/pion/ice/v2 => /local/path/to/ice/v2
replace github.com/pion/ice/v3 => /local/path/to/ice/v3
webRTC deps was not clean, so we need clone both v2 and v3 and replace them.
or you just modify package which go get downloaded. i test my code with that way, it's simple, but not elegant.
or you just modify package which go get downloaded. i test my code with that way, it's simple, but not elegant.
I suppose those would be overwritten with each go mod tidy?
or you just modify package which go get downloaded. i test my code with that way, it's simple, but not elegant.
I suppose those would be overwritten with each
go mod tidy?
not really, you can append replace code or find transport and ice package in your local and modify source code directly.
or you just modify package which go get downloaded. i test my code with that way, it's simple, but not elegant.
I suppose those would be overwritten with each
go mod tidy?not really, you can append replace code or find transport and ice package in your local and modify source code directly.
Thanks. Learning something.
BTW: The initial compiler change is off the table, right? I mean the interfaceTableAndroid thingy?