All iOS apps must support IPv6-only (repost)

Monkey Forums/Monkey Bug Reports/All iOS apps must support IPv6-only (repost)

Trion(Posted 2016) [#1]
http://appleinsider.com/articles/16/05/04/apple-says-all-apps-must-support-ipv6-only-networking-by-june

We have first rejection on this month already because brl.socket support only ipv4 connections. This is big problem for development on Monkey-X for iOS. All apps using network will reject by Apple. How to rewrite brl.socket for support both protocols IPv4 and IPv6?
P.S.: We use Monkey-X for client and server.


marksibly(Posted 2016) [#2]
Are both client and server built for the ios target?

Or is only the client ios?


Trion(Posted 2016) [#3]
Client - iOS, server - C++ tool target build


marksibly(Posted 2016) [#4]
Ok, I spent some time on this today and it seems to be working OK on the simulator.

I've only done ipv6 for ios for now, so cpptool will continue to be a ipv4 server but that should be OK as ipv6 clients can connect to ipv4 servers. I've tested it with the echoserver demo over a LAN (server on windows PC;client on ios simulator), and with a simple connect to blitzbasic.com:80.

It seems to work just like the old API, the only difference being instead of socket.LocalAddress.Host giving you an ipv4 dotted IP, it now produces funky ipv6 names with '::'s and other stuff in them. Apart from that, it seems to work OK when connecting to ipv4 dotted ips - but using the server name might be a better idea here.

You'll need to update/add these files:

https://github.com/blitz-research/monkey/blob/develop/modules/brl/socket.monkey
https://github.com/blitz-research/monkey/blob/develop/modules/brl/native/socket_ipv6.cpp

I've made sure it doesn't use any of the incompatible stuff listed here:

https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW1

Let me know if it works for your app.


Trion(Posted 2016) [#5]
Yes, thank you very much, it works. We were a little modified socket_ipv6.cpp for normal operation through ipv4-only network.If the network does not support ipv6 we must create ipv4 socket instead ipv6.

Function setsockaddr
static int setsockaddr( sockaddr_storage *sa,String host,int port ){
    
    memset( sa,0,sizeof(*sa) );
    
    if( host.Length()>1023 ) return 0;
    
    char buf[1024],*bufp=0;
    buf[host.Length()]=0;
    
    if( host.Length() ){
        for( int i=0;i<host.Length();++i ) buf[i]=host[i];
        bufp=buf;
    }
    
    char buf2[1024];
    sprintf( buf2,"%i",port );
    
    addrinfo hints;
    
    memset( &hints,0,sizeof( hints ) );
    hints.ai_family=PF_INET6;
    hints.ai_flags|=AI_V4MAPPED;
    if( !bufp ) hints.ai_flags|=AI_PASSIVE;
    
    addrinfo *res;
    getaddrinfo( bufp,buf2,&hints,&res );
    if( !res ){
        
        memset( &hints,0,sizeof( hints ) );
        hints.ai_family=PF_INET;
        if( !bufp ) hints.ai_flags|=AI_PASSIVE;
        
        if( getaddrinfo( bufp,buf2,&hints,&res )<0 ) return 0;
        if( !res ) return 0;}
    
    int len=res->ai_addrlen;
    memcpy( sa,res->ai_addr,len );
    
    freeaddrinfo( res );
    
    return len;
}


Method BBSocket::Open
bool BBSocket::Open( int proto ){
    
    if( _sock>=0 ) return false;
    
    addrinfo hints;
    addrinfo *res, *rp;
    int family = PF_INET;
    
    memset( &hints,0,sizeof( hints ) );
    hints.ai_family=PF_UNSPEC;
    
    getaddrinfo( "server.name", NULL,&hints,&res ); //paste your ipv4 address or hostname without ipv6 adress DNS
    if(res != NULL) family = res->ai_family;
    for(rp = res;rp != NULL; rp = rp->ai_next){
        if(rp->ai_family == PF_INET6){
            //res = rp;
            family = rp->ai_family;
            break;
        }
        
    }
    
    switch( proto ){
        case PROTOCOL_CLIENT:
        case PROTOCOL_SERVER:
            _sock=socket( family,SOCK_STREAM,IPPROTO_TCP );
            if( _sock>=0 ){
                
                //nodelay
                int nodelay=1;
                setsockopt( _sock,IPPROTO_TCP,TCP_NODELAY,(const char*)&nodelay,sizeof(nodelay) );
                
                //Do this on Mac so server ports can be quickly reused...
#if __APPLE__ || __linux
                int flag=1;
                setsockopt( _sock,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag) );
#endif
            }
            break;
        case PROTOCOL_DATAGRAM:
            _sock=socket( family,SOCK_DGRAM,IPPROTO_UDP );
            break;
    }
    
    if( _sock<0 ) return false;
    
    _proto=proto;
    return true;
}



Xaron(Posted 2016) [#6]
So far so good, what about the fact that iOS requests HTTPS in the near future?


EdzUp(Posted 2016) [#7]
Maybe releasing a new 'ipv6' compatible monkeyX build should be in order :)


marksibly(Posted 2016) [#8]
> We were a little modified socket_ipv6.cpp for normal operation through ipv4-only network.

Hmm, I had assumed that it was ios network stack that made IP4 connections 'look' like IP6 ones, so you could always just use IP6 sockets.

But this is not the case? if so, socket creation should probably be moved to the 'Connect' and 'Listen' methods.

Will have another go soon, but I'm glad you got it working!