jbagg / QtZeroConf

Qt wrapper class for ZeroConf libraries across various platforms.
Other
69 stars 51 forks source link

qzeroconfigservice ipv4 property assigned ipv6 address #22

Closed bozo91 closed 4 years ago

bozo91 commented 6 years ago

I set the browser to ipv4 only. When a new service is added, sometimes the ipv4 property "ip" in the qzeroconfservice-object is assigned an ipv6 address.

I tested this by adding a qDebug() output to the setIp function:

void QZeroConfService::setIp(QHostAddress &ip) { data->ip = ip; qDebug() << "set ip" << ip; }

The output:

/qtzeroconf/qzeroconfservice.cpp:89 (void QZeroConfService::setIp(QHostAddress&)): set ip QHostAddress("fe80::f55c:ea97:334e:b8c8")

System hosting the service is a Windows machine. The browser is running on Android.

jbagg commented 6 years ago

Hi, Can you tell me what platform / OS this is happening on? Can you define sometimes, for example happens every 1 in 10, 1 in 20....1 in 100? Thanks.

jbagg commented 6 years ago

Sorry, I just say what machine. For some reason I didn't see this in the email?

jbagg commented 6 years ago

Can you apply this patch (for Android build) and show me the output when the issue happens? Does the windows machine happen to have two network interfaces by chance?

show_protocol.patch.txt

bozo91 commented 6 years ago

I applied the patch but the part of the code it changed is not getting executed. (on Android) Currently i get an ipv6 address in about 50% of the tries. The Windows computer hosting the service does have multible interfaces, but the ipv4 and ipv6 addresses im getting are from the same interface.

jbagg commented 6 years ago

Sorry, I diffed the wrong file. Can you try with this one? show_protocol.patch.txt

Do you happen to have a linux PC on the same network? If so, can you run a program called avahi-discover. It show all the zeroconf services on the network. You can compare it to what QZeroConf is saying.

bozo91 commented 6 years ago

I get the following output: /qtzeroconf/avahicore.cpp:196 (static void QZeroConfPrivate::resolveCallback(AvahiSServiceResolver*, AvahiIfIndex, AvahiProtocol, AvahiResolverEvent, const char*, const char*, const char*, const char*, const AvahiAddress*, uint16_t, AvahiStringList*, AvahiLookupResultFlags, void*)): 0 fe80::7409:608a:e00f:b9a3

I use the application "Bonjour Discover" to see available services. My service is listed with an ipv4 address.

jbagg commented 6 years ago

This suggests the issue is in the Android build of QtZeroConf. I've tried to reproduce using win7 + Android 6.0.1 using the test app included in QtZeroConf, but I am unable to.

  1. Do you see this issue happening in the test / example app included in QtZeroConf?
  2. What are your versions of Android and Windows?
bozo91 commented 6 years ago
  1. The example is not having the described issue when running on a windows (Windows 7) or on an Android device (7.0).
  2. The Client is running on a Windows 7, the browser on a Galaxy Tab S3 with Android 7.

The issue is not happening when running my application with the browser on a computer with Windows 7, so it really seems to be Android realated.

jbagg commented 6 years ago

ok, thanks. I just pulled in some updates form the avahi project. Do a pull and see if the problem still exists. You could also try checking out these two commits... 639050b600c70a6b893284cc53f46eb28174e91f c9148b19dd3fa7869eb87dd200a5d2e1b20c13c9 and see if the problem still happens. These commits are before multi threading & before QZeroConfService was a shared data object. QZeroConfService will be a pointer in these commits.

bozo91 commented 6 years ago

The version with the updates from the avahi project also produces the error. I now also manage to reproduce the error with the example project using the commit 639050b. From my understanding the example project should only show ipv4 addresses in the list since it uses the ip() method. Is that correct? screenshot_20180524-132951 1 In this screenshot an ipv6 is visible. Again running on an Galaxy tab S3 with Android 7.

jbagg commented 6 years ago

That is correct, the example should only show ipv4 addresses. I don't think the avahi resolveCallback() should have protocol set to AVAHI_PROTO_INET (=0) with an ipv6 address. I will try to find an android 7 device to reproduce the issue. I'll need to get as much info as possible before filing a bug with avahi.

Something to try..... In avahicore.cpp, in function browserCallback() in the call to avahi_s_service_resolver_new(), use AVAHI_PROTO_INET instead of AVAHI_PROTO_UNSPEC and see if you still get the ipv6 address.

bozo91 commented 6 years ago

After changing AVAHI_PROTO_UNSPEC to AVAHI_PROTO_INET I only get ipv4 addresses, so that fixes it for me.

mzanetti commented 6 years ago

Hi, I've just ran into this too. Android 8.0, but I've only started to observe it after I got reports from iOS about my app showing IPv6 addresses where it should not. While it seems to happen most of the times if not all the time on iOS (sorry, don't have an iOS device at hand myself), I get it sometimes (maybe one in 10) on Android. Even more strange, that I have tracked it down to the avahi-core itself on Android.

I've added the following qDebug() in avahicore.cpp:198

            char a[AVAHI_ADDRESS_STR_MAX];
            avahi_address_snprint(a, sizeof(a), address);
            QHostAddress addr(a);
            qDebug() <<"AvahiClilent:" << protocol << a;
            if (protocol == AVAHI_PROTO_INET6)
                zcs.setIpv6(addr);
            else if (protocol == AVAHI_PROTO_INET)
                zcs.setIp(addr);

and it prints:

D nymea-app: ../../nymea-app/QtZeroConf/avahicore.cpp:198 (static void QZeroConfPrivate::resolveCallback(AvahiSServiceResolver*, AvahiIfIndex, AvahiProtocol, AvahiResolverEvent, const char*, const char*, const char*, const char*, const AvahiAddress*, uint16_t, AvahiStringList*, AvahiLookupResultFlags, void*)): AvahiClilent: 0 2a02:8070:d185:82f0:4a03:c75d:ae9b:3421

So protocol is AVAHI_PROTO_INET, but the address itself is clearly a v6 one.

Some other things worth mentioning:

So putting all of this together it seems to be in avahi-core itself, but only if using the core directly, not when using the avahi-client lib. Also for some reason I can only reproduce it with servers on ubuntu xenial (0.6.32), I've never seen it with servers on debian stretch (0.6.32.2) or ubuntu bionic (0.7).


Now, for iOS one thing that I managed to debug is that if the devices have at least a link-local scoped ipv6 connection, QtZerconf will always have the ipv6 field filled with the link-local ipv6 address, most of the times along with the ipv4 address in the same entry. This is also wrong as the server explicitly exports that service with AVAHI_PROTO_INET. This also happens regardless of the server avahi version and could be reproduced much easier than the one happening on android. Couldn't really go further than this with just getting logs and not being able to reproduce it myself. But in any case, while it seems somewhat related having a similar effect on the app, it's likely a different issue in the bonjour related code.

jbagg commented 6 years ago

Yes, the Android issue is definitely an avahi-core issue. Some time ago I did just as you did, dump the address at the point where avahi-core gives it to QtZeroConf and it was and IPv6 address with the IPv4 id flag. Maybe it is a bug in avahi-core, or maybe its the way it is complied on Android. Maybe it is because there are multiple mDNS servers running. My long term plan is to investigate replacing avahi-core on Android with Android's network service discovery through JNI as it is better to only have one mDNS server.

For the iOS issue.

  1. In your iOS app, when you start the browser, are you using QAbstractSocket::AnyIPProtocol, AnyIPProtocol or IPv4Protocol? The single parameter startBrowser uses IPv4Protocol. If you are using AnyIPProtocol, try IPv4Protocol. This is the work around for the avahi-core issue, maybe worth trying.
  2. We should open a separate ticket once we reproduce it. I have some iOS devices I can try with
mzanetti commented 6 years ago
  1. Yes, I had been using AnyIPProtocol. This was actually done in an effort to add IPv6 support to my app so switching it back to IPv4Protocol kinda defeats the purpose, but yes, that's what I did for now.

  2. So, if you'd really want to try and reproduce with my setup, it's all open source. Start up a nymea:core somewhere (https://github.com/guh/nymea, prebuild packages are available for Ubuntu Debian and Snap, see https://wiki.nymea.io) somewhere and run nymea:app (https://github.com/guh/nymea-app, prebuild packages available in app stores and https://downloads.nymea.io/nymea-app/). It should build and run on your iPhone if you just click the play button in QtCreator (Qt >= 5.9) (perhaps some signing magic is needed, depending on your setup) and the app will directly start QtZeroconf browsing at startup.

Grepping for QtZeroconf in nymea:app and QtAvahiService in nymea:core should directly get you to the related code. There's also a xenial based raspberry pi image we might even be able to reproduce the android issue with.

jbagg commented 5 years ago

Michael, Can you try and reproduce your iOS issue with the latest QtZeroConf? This issue is fixed for Android / Linux. It should be fixed for iOS as well.

mzanetti commented 5 years ago

Hey, I have upgraded my app to the latest of your version and will give it a run now. I'll report back if something happens. Thanks.

jbagg commented 5 years ago

Please also reply back if nothing happens (works correctly) so we can close this ticket.

On 2019-07-05 12:08 p.m., Michael Zanetti wrote:

Hey, I have upgraded my app to the latest of your version and will give it a run now. I'll report back if something happens. Thanks.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/jbagg/QtZeroConf/issues/22?email_source=notifications&email_token=ADFEL4ZDBEFF37IUQRUQNL3P55WW7A5CNFSM4E74OJM2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZJ362Q#issuecomment-508804970, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFEL47ENYKRIPIBYZ2OBULP55WW7ANCNFSM4E74OJMQ.