Ok, discount this answer. It turns out that while IPv6 was enabled in 4.12, it wasn’t properly setup for iOS. There is a fix for this, but it is pretty involved and will require modifying several file. Further, it doesn’t auto detect whether the network is IPv4 vs. IPv6. Pulled from a UDN post:
To those interested in getting IPv6 sockets working:
For IOS to use IPv6, have the /sockets/IOS/SocketSubsystemIOS.h derive from SocketSubsystemBSDIPv6:
SocketSubsystemIOS.h:
#include "BSDIPv6Sockets/SocketSubsystemBSDIPv6.h"
...
class FSocketSubsystemIOS : public FSocketSubsystemBSDIPv6
{
...
};
SocketSubsystemIOS.cpp:
FSocket* FSocketSubsystemIOS::CreateSocket(const FName& SocketType, const FString& SocketDescription, bool bForceUDP)
{
FSocketBSDIPv6* NewSocket = (FSocketBSDIPv6*)FSocketSubsystemBSDIPv6::CreateSocket(SocketType, SocketDescription, bForceUDP);
if (NewSocket)
{
// disable the SIGPIPE exception
int bAllow = 1;
setsockopt(NewSocket->GetNativeSocket(), SOL_SOCKET, SO_NOSIGPIPE, &bAllow, sizeof(bAllow));
}
return NewSocket;
}
However, this isn’t the only change needed. There is a bug that happens when you try to connect to the same URL twice (maybe consecutive games?), where the first time successfully resolves to an IPv6 IP, but the second time comes back as an IPv4 IP which has been forced into IPv6 notation. This is due to the constructor for FResolveInfoCached, specifically FResolveInfoCached(const FInternetAddr& InAddr). It only takes the uint32 portion of the IP from the InAddr.
This fix is a bit more involved, since in the current system FResolveInfoCached is only defined in IPAddress.h. Here are the steps used to resolve this issue:
in IPAddress.h:
class FResolveInfoCached : public FResolveInfo
{
protected:
/** Hidden on purpose */
FResolveInfoCached() {}
/** The address that was resolved */
TSharedPtr<FInternetAddr> Addr;
...
};
Next, add in SocketSubsystem.h in ISocketSubsystem:
virtual FResolveInfoCached *CreateResolveInfoCached(TSharedPtr<FInternetAddr> Addr) const;
in SocketSubsystem.cpp:
add:
FResolveInfoCached *ISocketSubsystem::CreateResolveInfoCached(TSharedPtr<FInternetAddr> Addr) const
{
return new FResolveInfoCached(*Addr);
}
and modify FResolveInfo* ISocketSubsystem::GetHostByName(const ANSICHAR* HostName)
{
...
if (GetHostByNameFromCache(HostName, Addr))
{
Result = CreateResolveInfoCached(Addr);
}
...
}
Now we need to add the BSDIPv6 support:
In IPAddressBSDIPv6.h:
add the following class
class FResolveInfoCachedBSDIPv6 : public FResolveInfoCached
{
FResolveInfoCachedBSDIPv6();
public:
FResolveInfoCachedBSDIPv6(const FInternetAddr& InAddr)
{
const FInternetAddrBSDIPv6 *InAddrAsIPv6 = static_cast< const FInternetAddrBSDIPv6* >(&InAddr);
if(InAddrAsIPv6)
{
Addr = ISocketSubsystem::Get()->CreateInternetAddr();
FInternetAddrBSDIPv6 *AddrAsIPv6 = static_cast<FInternetAddrBSDIPv6*>(Addr.Get());
if(AddrAsIPv6)
{
AddrAsIPv6->SetPort(InAddr.GetPort());
in6_addr temp;
InAddrAsIPv6->GetIpv6(temp);
AddrAsIPv6->SetIp(temp);
}
}
else
{
uint32 IpAddr;
InAddr.GetIp(IpAddr);
Addr = ISocketSubsystem::Get()->CreateInternetAddr(IpAddr, InAddr.GetPort());
}
}
};
And finally, modify SocketSubsystemBSDIPv6.h, adding:
virtual FResolveInfoCached *CreateResolveInfoCached(TSharedPtr<FInternetAddr> Addr) const override;
to FSocketSubsystemBSDIPv6.
In SocketSubsystemBSDIPv6.cpp:
FResolveInfoCached *FSocketSubsystemBSDIPv6::CreateResolveInfoCached(TSharedPtr<FInternetAddr> Addr) const
{
return new FResolveInfoCachedBSDIPv6(*Addr);
}
This should allow you to use BSD ipv6 sockets in IOS.
(Courtesy of Nik of iNiS Corporation).