Redphone works on ipv6 only network

// FREEBIE
pull/1/head
Michael Kirk 8 years ago
parent ce18be2288
commit a636f0b6af

@ -27,6 +27,9 @@
+(IpAddress*) ipv4AddressFromSockaddr:(struct sockaddr_in)sockaddr;
+(IpAddress*) ipv6AddressFromSockaddr:(struct sockaddr_in6)sockaddr;
@property (nonatomic, readonly) bool isIpv4;
@property (nonatomic, readonly) bool isIpv6;
-(IpEndPoint*) withPort:(in_port_t)port;
-(NSData*) sockaddrData;
-(NSData*) sockaddrDataWithPort:(in_port_t)port;

@ -80,6 +80,16 @@
return a;
}
- (bool)isIpv4
{
return isIpv4;
}
- (bool)isIpv6
{
return isIpv6;
}
-(IpEndPoint*) withPort:(in_port_t)port {
return [IpEndPoint ipEndPointAtAddress:self onPort:port];
}

@ -21,12 +21,15 @@
+(IpEndPoint*) ipEndPointAtAddress:(IpAddress*)address
onPort:(in_port_t)port;
+(IpEndPoint*) ipEndPointAtUnspecifiedAddressOnPort:(in_port_t)port;
+ (IpEndPoint *)ipv4EndPointAtUnspecifiedAddressOnPort:(in_port_t)port;
+ (IpEndPoint *)ipv6EndPointAtUnspecifiedAddressOnPort:(in_port_t)port;
+(IpEndPoint*) ipEndPointFromSockaddrData:(NSData*)sockaddrData;
+(IpEndPoint*) ipv4EndPointFromSockaddrData:(NSData*)sockaddrData;
+(IpEndPoint*) ipv6EndPointFromSockaddrData:(NSData*)sockaddrData;
- (IpEndPoint *)correspondingLocalEndpointWithPort:(in_port_t)specifiedLocalPort;
-(in_port_t) port;
-(IpAddress*) address;
-(NSData*) sockaddrData;

@ -14,7 +14,8 @@
return p;
}
+(IpEndPoint*) ipEndPointAtUnspecifiedAddressOnPort:(in_port_t)port {
+ (IpEndPoint *)ipv4EndPointAtUnspecifiedAddressOnPort:(in_port_t)port
{
struct sockaddr_in s;
memset(&s, 0, sizeof(struct sockaddr_in));
s.sin_len = sizeof(struct sockaddr_in);
@ -27,6 +28,20 @@
return a;
}
+ (IpEndPoint *)ipv6EndPointAtUnspecifiedAddressOnPort:(in_port_t)port
{
struct sockaddr_in6 address;
bzero(&address, sizeof(address));
address.sin6_len = sizeof(address);
address.sin6_family = AF_INET6;
address.sin6_port = htons(port);
IpEndPoint *a = [IpEndPoint new];
a->address = [IpAddress ipv6AddressFromString:@"0:0:0:0:0:0:0:0"];
a->port = port;
return a;
}
+(IpEndPoint*) ipEndPointFromSockaddrData:(NSData*)sockaddrData {
ows_require(sockaddrData != nil);
ows_require(sockaddrData.length >= sizeof(struct sockaddr));
@ -59,6 +74,17 @@
return [[IpAddress ipv6AddressFromSockaddr:s] withPort:ntohs(s.sin6_port)];
}
- (IpEndPoint *)correspondingLocalEndpointWithPort:(in_port_t)specifiedLocalPort
{
if (self.address.isIpv4) {
DDLogDebug(@"%@ Connecting via IPv4", self.tag);
return [IpEndPoint ipv4EndPointAtUnspecifiedAddressOnPort:specifiedLocalPort];
} else {
DDLogDebug(@"%@ Connecting via IPv6", self.tag);
return [IpEndPoint ipv6EndPointAtUnspecifiedAddressOnPort:specifiedLocalPort];
}
}
-(IpAddress*) address {
return address;
}
@ -92,4 +118,16 @@
return [TOCFuture futureWithResult:@[self]];
}
#pragma mark - Logging
+ (NSString *)tag
{
return [NSString stringWithFormat:@"[%@]", self.class];
}
- (NSString *)tag
{
return self.class.tag;
}
@end

@ -1,6 +1,7 @@
#import "Constraints.h"
#import "ThreadManager.h"
#import "UdpSocket.h"
#import "IPAddress.h"
@implementation UdpSocket
@ -131,8 +132,14 @@ void onReceivedData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef add
}
-(void) setupLocalEndPoint {
IpEndPoint* specifiedLocalEndPoint = [IpEndPoint ipEndPointAtUnspecifiedAddressOnPort:specifiedLocalPort];
IpEndPoint *specifiedLocalEndPoint;
if (self.isRemoteEndPointKnown) {
specifiedLocalEndPoint = [specifiedRemoteEndPoint correspondingLocalEndpointWithPort:specifiedLocalPort];
} else {
DDLogWarn(@"%@ no remote end point. This is only used in unit tests.", self.tag);
specifiedLocalEndPoint = [IpEndPoint ipv4EndPointAtUnspecifiedAddressOnPort:specifiedLocalPort];
}
CFSocketError setAddressResult = CFSocketSetAddress(socket, (__bridge CFDataRef)[specifiedLocalEndPoint sockaddrData]);
checkOperationDescribe(setAddressResult == kCFSocketSuccess,
([NSString stringWithFormat:@"CFSocketSetAddress failed with error code: %ld", setAddressResult]));
@ -165,9 +172,16 @@ void onReceivedData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef add
@try {
CFSocketContext socketContext = { 0, (__bridge void *)self, CFRetain, CFRelease, CFCopyDescription };
SInt32 protocolFamily;
if (self.isRemoteEndPointKnown) {
protocolFamily = specifiedRemoteEndPoint.address.isIpv4 ? PF_INET : PF_INET6;
} else {
DDLogWarn(@"Uknown remote endpoint. This is only used in testing.");
protocolFamily = PF_INET;
}
socket = CFSocketCreate(kCFAllocatorDefault,
PF_INET,
protocolFamily,
SOCK_DGRAM,
IPPROTO_UDP,
kCFSocketDataCallBack,
@ -194,4 +208,16 @@ void onReceivedData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef add
}
}
#pragma mark - Logging
+ (NSString *)tag
{
return [NSString stringWithFormat:@"[%@]", self.class];
}
- (NSString *)tag
{
return self.class.tag;
}
@end

Loading…
Cancel
Save