Open snej opened 8 years ago
I think the best solution is to use CFHost
to do the hostname resolution — it will return the IP address(es) already wrapped in NSData, in the form that CFSocket wants them. It'll probably be less code, too.
@snej It'll be interesting to see how they enforce this, but yea I think CFHost will have to be the way it's done. I'll take a look into exactly what this may entail.
@robertjpayne Is there any progress on this issue? I'm currently looking to make a decision on which web socket library to use for a major new telecoms company project, and the "approvability" will definitely make a difference as to which I choose.
@NightIsland are you looking to use the Server or Client code? The client code is IPv6 ready, the server code was never really intended much for App Store apps and is the questionable piece.
I doubt Apple will be scanning for ipv4 API's as they are still very valid, rather they probably turn off ipv4 DNS while they test your app.
So looking at this right now, I currently take an IPv4 address and CFHost isn't really helpful here as that is more around DNS queries.
The main reason I locked the server code to IPv4 is because hardly anyone is going to IPv6 solely and you'd need to create two servers one for IPv4 and one for IPv6 to get both connections.
To avoid that I'll have to rejig a bit of the internal code to accept an ipv4 and ipv6 address for binding/listening on.
@snej There isn't really an issue with the clients is there? At least from your end? The issue is solely the server that is hardcoded to IPv4.
Ah, I wasn't certain whether the mentioned code was used by any part of the client or just within the server - you're right that it's only the client that I'll be using.
I appreciate your rapid response: I'm going to use PocketSocket for our new app on this basis.
Right, the issue is only with the server/listener code.
I currently take an IPv4 address and CFHost isn't really helpful here as that is more around DNS queries.
I'm assuming CFHost will resolve numeric hostnames. But a better approach may be inet_pton
, which sounds like it does the same job as inet_addr
but supports both IPv6 and IPv4. You'd probably have to call it with both AF_INET
and then AF_INET6
and use the result for which it succeeds.
The inet_pton() function converts a presentation format address (that is,
printable form as held in a character string) to network format (usually
a struct in_addr or some other internal binary representation, in network
byte order). It returns 1 if the address was valid for the specified
address family, or 0 if the address was not parseable in the specified
address family, or -1 if some system error occurred (in which case errno
will have been set). This function is presently valid for AF_INET and
AF_INET6.
@snej for server code there really isn't a need to resolve addresses, since you're binding to a interface and port, just a need to convert the string address to the in_addr structure.
The problem with supporting ipv4 and ipv6 simultaneously is you have to run two sockets and listen for connections on either.
Alternatively I may use something like NSSetService which has the added bonus of being discoverable from clients that support bonjour.
:+1: for NSNetService.
I use server code. I wanna know how to fix this issue
I made it able to listen on both IPv4 and IPv6 address by changing several lines of code. I paste the code here since it's just a simple change without respect to allow user to specify an address on which listens.
The changes on method "initWithHost" (briefly, add "6" to each line):
struct sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr)); // this line is not modified
addr.sin6_len = sizeof(addr);
addr.sin6_family = AF_INET6;
addr.sin6_addr = in6addr_any; // the parameter "host" is ignored
addr.sin6_port = htons(port);
The change in method "connect":
_socket = CFSocketCreate(kCFAllocatorDefault,
PF_INET6, // only this line, appending a "6"
Tested on both OSX 10.10 and iPhone 5s.
@afbytes any chance you'd be willing to PR this? I just don't have time at the moment to implement it myself.
Is anyone getting app store rejections on the basis of IPV6 support in server code? My gut feeling says Apple doesn't test device to device and thus a server only listening on IPV4 wont make a huge difference right now.
I created a pull-request just now. According to my test, it works in these ways when the "host" parameter is:
Yes, people are getting App Store rejections:
"I have a client with two CBL lite apps on the store. One was just approved and the other was rejected due to sync failing to start on Apple's IPv6 network. I've been able to replicate the issue by creating a local ad-hoc network with Internet Sharing and NAT 64 enabled." *
The PR is https://github.com/zwopple/PocketSocket/pull/53, but it needs a fix (as noted in my line comment) to declare an instance variable properly, otherwise it may behave incorrectly if multiple listeners are opened.
Hi! Any news about this? Are apps using the server code having any trouble on the app aprovation? I'm interested to use the Server code from PocketSocket, but I need to know if this is really an issue for app aprovation. Thanks
@asabino I have the macOS app which uses PocketSocket as a server. It is binding only one port at localhost
and everything is fine, app was approved. You just need to select proper app sandbox permissions,
Apple just announced that starting in June 2016, apps that don't support IPv6-only networks will be rejected from the App Stores. "If your app uses IPv4-specific APIs or hard-coded IP addresses, you will need to make some changes."
There is some code in PSWebSocketServer.m that constructs an IPv4
sockaddr_in
from a hostname, which is then used to bind a listening socket using CFSocket.I don't know a lot about POSIX networking APIs, so I'm not sure if this code will fail in the default case where there's no hostname given, but I'm pretty sure it will fail if a hostname is given, since it won't be able to resolve to an IPv4 address.