-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IPv6 Can't assign requested address #429
Comments
Update: Using AsyncSocket instead of GCDAsyncSocket will be OK, I don't know why. |
I also get this problem. when I use the ip4 address like @"192.168.7.31", the error code 49, "Can't assign requested address" is got. when I change the ip address to the host name, it's ok. Through the wifi set like this link "Test for IPv6 DNS64/NAT64 Compatibility Regularly " https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html |
I get this too. |
I fixed it with this |
@chenzhuolin1002 You mean after applying your code, like this?
but the code above don't work for me, can you provide more details or show more code? |
@Smeegol I test the code provided by @chenzhuolin1002 . |
@etring iOS 8.1 cannot work either. I don't know How to fix it. |
@etring It even can't work on the system version 9.3.1while I am using those code as Smeegol used them. Could you tell me more detail about how you test the code? It seems server has to support the IPV6 protocol .Although GCDAsyncSocket has split those two kinds of protocols and connected host-server with different data, the connection is still failed. |
I believe it may be related to the bug mentioned here: https://forums.developer.apple.com/thread/47312 GCDAsyncSocket uses getaddrinfo() on the hostname given, which on iOS 9.2+ should synthesize IPv6 addresses even when given an IPv4 literal. GCDAsyncSocket then uses the socket address returned (IPv4 or IPv6) to connect. However, there currently seems to be a bug with getaddrinfo(), when given a numeric port, that it returns a socket address with ports being 0 (instead the of the port passed in). Trying to send a message to port 0 fails. The workaround is to manually set the port back on all the resulting sockaddr structs after the call to getaddrinfo(). It should be pretty easy to add this workaround into CocoaAsyncSocket. (AsyncSocket doesn't have this problem, because it uses the higher-level CFStream APIs, so it already works works with IPv4 literals on iOS 9.2+ (using IPv6 transparently if necessary). But GCDAsyncSocket uses lower-level socket APIs directly, so needs to use getaddrinfo() to synthesize it.) |
Try changing the following lines in
to
and see if that fixes the problem. |
@newacct Thanks, Bro! Apparently, you solve one of my problem what I was confused with no long before. Now, with your advice, I can get the correct address with port information for the socket connection. However, the client application still can't connect to our server. 0ur situation is like this: Our server only supports IPV4 protocol and I test IPV6 connection with Apple's test method (http://www.jianshu.com/p/8837739251ad), Every time when my application apply to set socket connection, the method of "socketDidDisconnect" will be recalled. We check our server, it didn't get any connection information from the application. That is quit confuse us as we are not master-hands for it. Do you have any suggestions about this situation for us? We are still searching solution for this. Does the server must support IPV6? |
@newacct I found some discussions related to my question here yesterday:http://stackoverflow.com/questions/16480729/connecting-ipv4-client-to-ipv6-server-connection-refused, It cleared my confusion. In their opinions, A listening IPv4 socket can accept incoming connections from only IPv4 clients. But, what is the usage of GCDasyncSocket automatically create IPv4 socket while its destination address is a IPV6 address? I once tried to connect our IPV4 server with a IPV6 client application. the responded error is "Network is unreachable". |
@newacct I tried your solution in GCDAsyncUdpSocket with a NAT64 network,this error didn't occur anymore,and the delegate method udpSocket: didSendDataWithTag: had been called.But another delegate method udpSocket: didReceiveData: fromAddress: withFilterContext: never be called,I don't |
@WuChuming m Hi, I've met this problem too. And I tried to resolve it according to the method above. But not valid. The problem I met like you. Do you resolve it now? |
@afanti100 @newacct I haven't solve it yet, and I got a bad news. Our android team can connect to our server which only has IPV4 address through the Wifi emitted by MAC with NAT64 without doing anything. Meanwhile, our application always fails to connect to server and responds "Network is unreachable". |
If you turn off IPv4PreferredOverIPv6 (which is true by default), then it will work:
Unfortunately, it seems that the getaddrinfo() API gives back both IPv4 and IPv6 addresses, even on IPv6-only networks (I'm not sure why), and if IPv4 is preferred over IPv6, then it will use the non-working IPv4 address. |
@newacct Thanks for your answering! I had set this property, but it still can't connect to the host. I did serval tests. I would like to draw some pictures to explicate different situations in different kinds of connections. In some kinds of connections, The connection can be OK. But I don't know how to show those pictures here. The conclusion is: If host is set in IPV6, Clients in IPV4 and IPV6 can connect to it with literal address, but if host is in IPV4, Clients in IPV6 can't connect to this host and responded "Can't assign requested address".
|
Connecting to an IPv4-only server with IPv4 literals from an client on IPv6-only networks works fine. That's the point of DNS64/NAT64. The error 49 "Can't assign requested address" is caused by using port 0 as returned by getaddrinfo() due to the bug in getaddrinfo(). Didn't you make the changes I mentioned above about putting the ports back in? Then the other problem you had, the "Network is unreachable", that's caused by trying to connect to the IPv4 address anyway, due to the IPv4PreferredOverIPv6 setting in GCDAsyncSocket. You fix this by turning that off as I showed. Did you do both of these things? |
@newacct What a good news! I connected it with hostname. I find hostname in computer reference -> sharing. GCDSocket supports IPV6. I change the address form literals to hostname, then It works. I am so exciting! |
But the IPv4 address literal should work. Are you on iOS 9.2+? |
I was on iOS 8.1. |
Well then it's not going to work. Synthesizing IPv6 address from IPv4 addresses with getaddrinfo only works on iOS 9.2+. Your app only needs to work on IPv6-only networks on those iOS versions. |
@newacct I tested it with an iPhone which is on iOS9.3.1 and a simulator on MAC with version10.11.1 system. The connection is failed. Do I need to upgrade the MAC system to test it? As The article mentions that * The ability to synthesize IPv6 addresses was added to getaddrinfo in iOS 9.2 and OS X 10.11.2* |
@newacct Anyway, I am upgrading the MAC's system. |
Well, thanks @chenzhuolin1002, @newacct and other guys, I finally solve my question by code below:
PS: Don't forget to set socket's |
You should leave it open until it is fixed in CocoaAsyncSocket, as other people may have the same problem. |
@newacct @Smeegol @WuChuming ,yeah, I test your code in my project, but not valid. It looks like the port has value, not zero. But can't connects our server. Have you resolved it yet? |
@afanti100 Did you also set IPv4PreferredOverIPv6 to NO and are you on iOS 9.2+? |
In my understanding, If your Phone is on iOS9.2+,it can connect to server with either address literal or hostname from DNS. But if your phone's system is below iOS9.2, it can only connect to server with hostname. Those two things newacct mentioned are key points, check them and if connection is still failed, it is better you get its error message for analyzing. |
Hmmm, I know. My Phone is iOS9.3 But IPv4PreferredOverIPv6 not set to NO. I set it and is has gone. But I don't know IPv4PreferredOverIPv6. Does it trigger other problems? |
Thanks for friends. |
By the way, Apple said that IPv6-only network support can only be tested on iOS 9.2+, so forget iOS 7 or 8. |
Thanks for all of friends, especially @WuChuming and @Smeegol , I have solved my problem. |
@WuChuming Envy you your English level ^_^ |
Thankyou for the detailed analysis in this thread, it has saved me many hours of headaches. Is anybody going to make a PR for the fix? |
Does this commit plus |
…into ipv6 Credit to @Smeegol: #429 (comment) Confirmed as bug in getaddrinfo by Apple staff (rdar://26365575): https://forums.developer.apple.com/thread/47312#138895
hello,I met a problem different from yours,I use gcdsocket version is 7.5.0,and it test OK with Nat64 network(my iphone wifi DNS prefix is 2001:2,in this case,my app is normal), but rejected by Apple which is declare that our app can't work in IPV6-only network, I only disabled the IPv4PreferredOverIPv6 properity, I notice that Apple always use the latest OS for check, do I need change the code like yours? Thanks very much. |
IPV6 problem resolved but code not work for IPV4. |
Fixes compiler warnings and data type errors, plus these specific fixes: * File descriptor leak - robbiehanson/CocoaAsyncSocket#522 * Fixes UDP connection issues with IPv6: robbiehanson/CocoaAsyncSocket#429 (comment) * Prevents truncating UDP packets: robbiehanson/CocoaAsyncSocket#222 * Allow UDP packet size above iOS default of 9216 bytes: robbiehanson/CocoaAsyncSocket#536 NOTE: We are holding back on updating to GCDAsyncSocket 7.6.2 because of reports that 7.6.1 may have introduced a crash: * see robbiehanson/CocoaAsyncSocket#579
This issue has been marked as stale, it will be closed automatically if there is no further activity. |
…into ipv6 Credit to @Smeegol: robbiehanson/CocoaAsyncSocket#429 (comment) Confirmed as bug in getaddrinfo by Apple staff (rdar://26365575): https://forums.developer.apple.com/thread/47312#138895
As Apple says, tried to connect to IPv4 address in IPv6-only network, here are codes:
Always failed with error:
Error Domain=NSPOSIXErrorDomain Code=49 "Can't assign requested address" UserInfo={NSLocalizedDescription=Can't assign requested address, NSLocalizedFailureReason=Error in connect() function}
I thought CocoaAsyncSocket will Synthesize IPv6 address from IPv4 address automatically, but I was wrong. Can somebody help me?
The text was updated successfully, but these errors were encountered: