IPv6 - app connection to server

We are dealing in these day with issue, that our application cannot reach our server. The application was approved, where testing server was miwe-api-demo.netbrick.cz. The production server address is api.mive.de and we are not able to connect to this server. However with release candidate we are able to connect to both server – testing and production as well. Production server is running on IPv4 network. Is Apple changing somehow application during approval process in that way IPv4 is not supported after review? Please note that our servers are:

Testing - https://miwe-api-demo.netbrick.cz

Production: https://api.mive.de

Replies

There seems to be something broken with your DNS. AFAICT this has nothing to do with Apple. For example, from my home network your testing server seems to work:

$ telnet -4 miwe-api-demo.netbrick.cz 443
Trying 77.93.217.20...
Connected to miwe-api-demo.netbrick.cz.
Escape character is '^]'.
^]
telnet> q
Connection closed.
$ telnet -6 miwe-api-demo.netbrick.cz 443
Trying 2a01:430:241::b4c3...
Connected to miwe-api-demo.netbrick.cz.
Escape character is '^]'.
^]
telnet> q
Connection closed.
$

but your product server is not found in the DNS.

$ telnet -4 api.mive.de 443
api.mive.de: nodename nor servname provided, or not known
$ telnet -6 api.mive.de 443
api.mive.de: nodename nor servname provided, or not known

Exploring the

A
record further using
dig
I find that the production zone (
mive.de.
) simply has
A
record for (
api.mive.de.
).
$ # Start at a root name server.
$
$ dig +norecurse @199.7.83.42 api.mive.de.
…
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21946
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 10

;; QUESTION SECTION:
;api.mive.de.          IN  A

;; AUTHORITY SECTION:
de.        172800  IN  NS  a.nic.de.
…
;; ADDITIONAL SECTION:
a.nic.de.      172800  IN  A  194.0.0.53
…
$ # That pointed us to a .de name server; try again there.
$
$ dig +norecurse @194.0.0.53 api.mive.de.
…
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59929
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
;api.mive.de.          IN  A

;; AUTHORITY SECTION:
mive.de.        86400  IN  NS  docks03.rzone.de.
…
$ # That pointed us to docks03.rzone.de.  Try again there.
$
$ dig +norecurse @docks03.rzone.de. api.mive.de.
…
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34461
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;api.mive.de.          IN  A

;; AUTHORITY SECTION:
…
$ # That gave us an authoritative 'no answer'.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hello Eskimo,

As far as I cannot send reply because of some invalid characters, where I spent 30min. to find what is wrong in my message, I uploaded it to Dropbox


https://www.dropbox.com/s/lkdurgecyns5jty/apple%20forum%20-%20eskimo.txt?dl=0


Best regards

Jan

Hi Eskimo,

thx for reply. The fact is that the app behaves differently arter review by apple. Release candidate was able to connect to both servers

Testing - https://miwe-api-demo.netbrick.cz

Production: https://api.mive.de


But after apple review we are not able to connect to server api.miwe.de where we suppport ipv4 only.

None of the code change has been made between RC and Production version

DNS is fixed now, but the isssue continues

As far as I cannot send reply because of some invalid characters …

DevForums is currently having problems where the spam filter is… shall we say… over enthusiastic. I’ve reported this to the relevant folks and I’m hoping for a fix soonen rather than later.

Based on the text you posted it Dropbox it seems like you’re actually rebuilding the app when you submit. This is never a good idea. You should create an Xcode archive that you can both test and submit using the workflow described in QA1764 How to reproduce bugs reported against App Store submissions.

A lot of the time when things fail in App Review the app crashes, in which case the build UUID shows up in the crash report. At that point you can confirm that you submitted the same build you tested by checking UUIDs, as described in QA1765 How to Match a Crash Report to a Build. However, if the app doesn’t crash then you’ll need your own logging to confirm the build UUID.

With regards IPv6 problems that only show up during App Review, my standard advice is hung off FAQ#6 of the Supporting IPv6-only Networks pinned post.

However, before you go down that path you may want to take another look at your DNS. You wrote:

DNS is fixed now, but the isssue continues

My tests still show problems. A basic query for

api.mive.de.
returns ‘no result’.
$ dig api.mive.de.
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63984
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;api.mive.de.          IN  A

;; AUTHORITY SECTION:
mive.de.        3600    IN  SOA docks03.rzone.de. hostmaster.strato-rz.de. …
…

And following down from the root gets me the same answer, but this time authoritatively.

$ dig +norecurse @199.7.83.42 api.mive.de.
…
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43729
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 10

;; QUESTION SECTION:
;api.mive.de.          IN  A

;; AUTHORITY SECTION:
de.        172800  IN  NS  a.nic.de.
…
;; ADDITIONAL SECTION:
a.nic.de.      172800  IN  A  194.0.0.53
…
$ dig +norecurse @194.0.0.53 api.mive.de.
…
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45996
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
;api.mive.de.          IN  A

;; AUTHORITY SECTION:
…
mive.de.        86400  IN  NS  docks03.rzone.de.
…
$ dig +norecurse @docks03.rzone.de. api.mive.de.
…
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49029
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;api.mive.de.          IN  A

;; AUTHORITY SECTION:
mive.de.        3600    IN  SOA docks03.rzone.de. hostmaster.strato-rz.de. …
…

Again, these tests were run on a machine on my home network, so there’s no Apple-specific stuff involved.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hello Eskimo,

thank you for you help so far. Sorry for my fault, but our server address is api.miwe.de. Can you please check again.


Thank you in advance

Jan

… our server address is api.miwe.de.

OK, that produces much better results. To start, this name resolves to both IPv4 and IPv6 addresses:

$ host api.miwe.de.
api.miwe.de has address 77.93.217.22
api.miwe.de has IPv6 address 2a01:430:241::8888

And the server seems to be responding on both:

$ TLSTool s_client -connect 77.93.217.22:443 -noverify
*  input stream did open
* output stream did open
* output stream has space
* protocol: TLS 1.2
* cipher: ECDHE_RSA_WITH_AES_256_GCM_SHA384
* trust result: recoverable trust failure
* certificate info:
*  0 + rsaEncryption 2048 sha256-with-rsa-signature 'miwe-api.netbrick.cz'
*  1 + rsaEncryption 2048 sha256-with-rsa-signature 'Let's Encrypt Authority X3'
*  2  rsaEncryption 2048 sha1-with-rsa-signature 'DST Root CA X3'
^C
$ TLSTool s_client -connect 2a01:430:241::8888:443 -noverify
*  input stream did open
* output stream did open
* output stream has space
* protocol: TLS 1.2
* cipher: ECDHE_RSA_WITH_AES_256_GCM_SHA384
* trust result: recoverable trust failure
* certificate info:
*  0 + rsaEncryption 2048 sha256-with-rsa-signature 'miwe-api.netbrick.cz'
*  1 + rsaEncryption 2048 sha256-with-rsa-signature 'Let's Encrypt Authority X3'
*  2  rsaEncryption 2048 sha1-with-rsa-signature 'DST Root CA X3'
^C

Note I need

-noverify
here because the server’s certificate does not include the server’s IP addresses in its Subject Alternative Name extension. That is only an issue when debugging like this; it is not a problem in a real app, where you start the connection using a DNS name.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

does this mean, that our server is OK right now and everythink should work. The fact is, that we cannot still connect to api.miwe.de with the application, which has been already approved by Apple team.

Do you have any suggesting what to check next?


You can find the app here - https://itunes.apple.com/us/app/miwe-messenger/id1087384613?l=cs&ls=1&mt=8


You can also try to register yourself in very first screen in the app. You do not need PIN, just write api.miwe.de to gateway address, enter random PIN code and if you reveice

1. Wrong gateway - you cannot connet to gateway of wrong address

2. Wronh PIN - you can connect to gateway, but the PIN is wrong


Second state is what we need to achive, where you are able to connect to gateway.


Best r.

Jan

Hello eskimo

I have a similar problem:

My app was rejacted and was told Supporting IPv6 DNS64 / NAT64 Networks:

"If you’re writing a client-side app using high-level networking APIs such as

NSURLSession
and the CFNetwork frameworks and you connect by name, you should not need to change anything for your app to work with IPv6 addresses."


and You says Supporting IPv6-only Networks :

"

#3 — Will I need to update my server?

That depends on where your server is running:

If you have a server running on the wider Internet, the answer is no. Your server will be accessible to IPv6-only devices via DNS64/NAT64.

"


my hoster says:

We do not see any problems, for the server with IPv6 to your server is IPv4 will be available through DNAT / SNAT


My site (server):

http://badroads.info


My code in App (this code was approved in another application a week ago):

func sendToServer(dataFromDictionary: Dictionary<NSString, AnyObject>) {
        let url: NSURL = NSURL(string: "http://badroads.info/t-or-c/****.php"
        let request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
        let session = NSURLSession.sharedSession()
        request.HTTPMethod = "POST"
        do {
            request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(dataFromDictionary, options: [])
        } catch let parseError as NSError {
            request.HTTPBody = nil
            dispatch_async(dispatch_get_main_queue()) {
                EZLoadingActivity.hide()
          
                self.alertMessageSuccessError("Vote error", messageM: "Oops, something went wrong! Try again, please!")
            }
        }
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
            if error != nil {
                dispatch_async(dispatch_get_main_queue()) {
                    EZLoadingActivity.hide()
                    self.alertMessageSuccessError("Vote error", messageM: "Oops, something went wrong! Try again, please!")
                }
                return
            }
            let json: NSDictionary?
            do {
                json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
            } catch let parseError as NSError {
                dispatch_async(dispatch_get_main_queue()) {
                    EZLoadingActivity.hide()
                    self.alertMessageSuccessError("Vote error", messageM: "Oops, something went wrong! Try again, please!")
                }
                return
            }
            if let parseJSON = json {
                if let status = parseJSON["status"] as? String {
                    if status == "200" {
                        dispatch_async(dispatch_get_main_queue()) {
                            EZLoadingActivity.hide()
                            self.defaultsDataLogin.setObject(true, forKey: "isVote")
                            self.alertMessageAdM("You have voted successfully!", messageM: "See  results of voting!")
                        }
                    } else if status == "400" {
                        dispatch_async(dispatch_get_main_queue()) {
                            EZLoadingActivity.hide()
                            self.alertMessageSuccessErrorAdM("Vote error", messageM: "You have already voted!")
                        }
                    } else {
                        dispatch_async(dispatch_get_main_queue()) {
                            EZLoadingActivity.hide()
                            self.alertMessageSuccessError("Vote error", messageM: "Oops, something went wrong! Try again, please!")
                        }
                    }
                } else {
                    dispatch_async(dispatch_get_main_queue()) {
                        EZLoadingActivity.hide()
                        self.alertMessageSuccessError("Vote error", messageM: "Oops, something went wrong! Try again, please!")
                    }
                }
          
            }  else {
                dispatch_async(dispatch_get_main_queue()) {
                    EZLoadingActivity.hide()
                    self.alertMessageSuccessError("Vote error", messageM: "Oops, something went wrong! Try again, please!")
                }
            }
        })
        task.resume()
    }


PLEASE HELP!!!

THANKS!!!

Do you have any suggesting what to check next?

It sounds like you can reproduce this yourself, in which can you can use a packet trace to see what’s going on. QA1176 Getting a Packet Trace shows how to set this up. You may need to run two tests here:

  • Using an RVI packet trace to see what DNS and TCP traffic.

  • If that doesn’t point to an obvious problem, use one of the proxy tools to see the HTTP-level traffic.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I have a similar problem:

I’d be happy to take a quick look but I’d appreciate you creating a new thread for this. If all the IPv6 issues go into a single thread, it’ll grow to gargantuan proportions )-:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi,

can you please send me a link to your topic please

Thx

Jan

Hello eskimo,


My app was rejected 3 more times due to IPv6 issue. When I check the app with my local IPv6 environment, it's working correclty without any error. But apple said that they faced "server error" issue when they launch the app. Kindly check the below apple comments and suggest your idea. I am very frustrating due to this issue for past 1 week.


This is my website url : https://portal.dezdy.com/


Kindly let me know whether the website supports IPv6 or not


Performance - 2.1


We discovered one or more bugs in your app when reviewed on iPad and iPhone running iOS 9.3.5 on Wi-Fi connected to an IPv6 network.

Specifically, we found that upon app launch, an error message is displayed.

We've attached screenshot(s) for your reference.

Consider this:

$ dig portal.dezdy.com AAAA
…
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16825
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;portal.dezdy.com.      IN  AAAA

;; ANSWER SECTION:
portal.dezdy.com.  3600    IN  AAAA    ::ffff:107.180.12.123
…

Your DNS server is returning an IPv6 address for your site site, but that IPv6 address is bogus (

::ffff:107.180.12.123
is a ‘mapped’ form of the IPv4 address). You need to do one of two things:
  • add IPv6 support to your server, and put a real IPv6 address in the

    AAAA
    record in the DNS
  • stick with IPv4 on your server, and remove this

    AAAA
    record from the DNS

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"