dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.23k stars 1.57k forks source link

Supporting IPv6 DNS64/NAT64 Networks #45550

Closed gl-ihorkoblan closed 1 year ago

gl-ihorkoblan commented 3 years ago

We have been developing system where phone connects to camera and control it(like start/stop recording video). client is mobile app(iOS/Android) wrote on Flutter uses GRPC v2.9.0 (grpc uses native dart:io https://github.com/grpc/grpc-dart/issues/467) server is running on camera side. They are communicating via WIFI

CAMERA HOST = '10.42.0.1' CAMERA PORT = 50051

Couple of our clients who uses T-Mobile operator have an issue. The issue is that app can't connect to the camera if cellular data is on. And it connects fine if cellular data is off. It looks like iPhone(who uses T-Mobile) prefer to use LTE over WiFi and automatically switches from WiFi to LTE and that's why couldn't connect to camera. Maybe It might be issue with supporting DNS64/NAT64.

Please take a look and fix it ASAP!

Useful info I found: robbiehanson/CocoaAsyncSocket#429

https://developer.apple.com/forums/thread/77438?fbclid=IwAR0rEiiy_cacZuGT6jHl043OqFWgTFIYoQlrV54VfDAX794UgMy2nBFKpPo

https://developer.apple.com/forums/thread/46941?fbclid=IwAR03mdqJ2KpBG4iCUNDw-TM7NSCc0MIThgju72qX-1Lo1HlFm3tVVeemUjM

mraleph commented 3 years ago

They are communicating via WIFI CAMERA HOST = '10.42.0.1' CAMERA PORT = 50051

Can we also have more information about local Wifi configuration when connection fails? e.g. netmask etc.

Also when you establish connection over gRPC how does your ClientChannel constructor call look like? Do you pass a string in or do you pass InternetAddress value?

/cc @aam

gl-ihorkoblan commented 3 years ago

This is how we initialize ClientChannel:

_channel = ClientChannel(
      '10.42.0.1',
      port: 50051,
      options: const ChannelOptions(
        credentials: ChannelCredentials.insecure(),
      ),
    );

_apiClient = MoveAPIClient(_channel);
gl-ihorkoblan commented 3 years ago

Also I would like to add that REST API is working fine on the same network. Netmask is: 255.255.255.0

mraleph commented 3 years ago

Also I would like to add that REST API is working fine on the same network.

REST API from Dart or from native Objective-C/Swift code?

If it is from Dart then how do you connect to that REST api?

gl-ihorkoblan commented 3 years ago

I checked via browser. Will check via dart and let you know later today

gl-ihorkoblan commented 3 years ago

I've checked REST API via dart. The problem is the same as it was with grpc It doesn't work when cellular data is on. And work fine if cellular data is off

gl-ihorkoblan commented 3 years ago

This is how I tried to make a REST call

import 'package:http/http.dart' as http;

Future<void> makeCall() async {
    try {
      var uriResponse = await client.get(Uri.parse('http://10.42.0.1/api/getState'));
      print(uriResponse.body);
    } catch (err) {
      print(err.toString());
    } finally {}
  }

if cellular data is ON than it fails with time out error: SockedException: OS Error: Operation timed out, errno = 60

if cellular data is OFF than request is success

So it behaves in the same way as grpc

But as I previously wrote it works if I try it in browser

1) connect iphone to camera's network 2) open in browser url http://10.42.0.1/api/getState 3) Result: it works fine in both cases (when cellular data ON and OFF)

gl-ihorkoblan commented 3 years ago

I would like to share some additional information about this bug. And hope it will help you to fix current issue

I think our problem related to https://developer.apple.com/news/?id=05042016a https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW1

Apple recommends to use NSURLSession and CFNetwork

We had the same bug on our another native project: we used CocoaAsyncSocket there to communicate with our camera

They added a fix i order to fix this issue according to apple recommendations: https://github.com/Dede/CocoaAsyncSocket/commit/ed8bfaf30f96bbfc59d79e9f7ea78d16702f964

This are issues which were opened: https://github.com/robbiehanson/CocoaAsyncSocket/issues/429 https://github.com/robbiehanson/CocoaAsyncSocket/issues/626 https://github.com/Dede/CocoaAsyncSocket/commit/ed8bfaf30f96bbfc59d79e9f7ea78d16702f964 - fix

So please take a look. I think you have to take into account this information(Supporting IPv6-only Networks) and fix it soon. It's very critical for us

gl-ihorkoblan commented 3 years ago

@mraleph is there any chance to fix this issue at your side?

mraleph commented 3 years ago

@gl-ihorkoblan as I mentioned to you before you should not expect that this issue is going to be fixed really quick, especially given that you need to setup some really specific environment to reproduce this.

@aam Alex, would you have some cycles to try reproducing/fixing this?

aam commented 3 years ago

Thank you @gl-ihorkoblan for detailed instructions. Yes, @mraleph I have tried reproducing it locally but unsuccessfully so far. I tried with Verizon iphone connected to local wifi network and connections to local http server on local wifi network seems to work fine with/without cell(Verizon) network enabled on the iphone. I tried both with/without ipv6 support for local wifi network, didn't make a difference. I tried setting up local NAT64 network as described on Apple website, but for some reason that didn't work as expected: checking 'Create NAT64 Network' turned wifi connection inoperable. I was planning to find some wifi device(camera or something) that I could try to connect from the iphone that would run on a wifi network without routing to the internet. Haven't tried it yet, haven't found a device yet. If you have some other thoughts on how to try to reproduce it, let me know!

mraleph commented 3 years ago

I have tried reproducing this as well yesterday, so far no success. I had created NAT64 internet sharing network using an older Mac Mini that I have and run the following tests:

Overall I am not even sure if NAT64/DNS64 is a problem here: you are trying to connect to a camera using a resolved IPv4 address on a local WiFi network. It is unclear to me where NAT64/DNS64 come to play here - connection should be just established directly over WiFi, it should not hit internet at all.

I think there is something else broken, but it is next to impossible to diagnose given that we can't reproduce this.

dennisvanmaren commented 3 years ago

Hi All,

We are experiencing the same issue on our mobile network and it happens only when we use our flutter app on our IPv6 only mobile APN and with Apple iPhones (Android is working fine). Below are the different situations, we tested.

  1. Android works in all situations
  2. Apple via WiFi with IPv4 works
  3. Apple via WiFi with IPv6 works
  4. Apple via IPv4 only APN works
  5. Apple via IPv6 only APN (via NAT64) not working (not possible to connect to our proxy, other calls works fine)

Because most of our mobile customers are on the IPv6 APN this is causing a big issue for us.

We have made some network traces which we need to investigate and tomorrow we will try to get some more data from dev tools. If anyone has any idea how to solve this please let me know!

dennisvanmaren commented 3 years ago

@gl-ihorkoblan did you fixed the issue?

gl-ihorkoblan commented 3 years ago

@dennisvanmaren This issue has been disappeared when we moved to Flutter 2.0 and above

dennisvanmaren commented 3 years ago

@gl-ihorkoblan good for you!

Can I ask which video player you are using? We suspect the video player, we are using this implementation https://gist.github.com/fousa/5709fb7c84e5b53dbdae508c9cb4fadc

gl-ihorkoblan commented 3 years ago

I think you didn't understand my issue well. Doesn't matter which player we use(but we use video_player: ^2.2.0). We are connecting to camera as physical device via grpc. The problem was on iOS native networking framework which was pointed from flutter. Flutter 2.0 and above points to another network layer where the issue fixed.

gl-ihorkoblan commented 3 years ago

@dennisvanmaren ^

aam commented 1 year ago

Closing per https://github.com/dart-lang/sdk/issues/45550#issuecomment-931203812