Skip to content
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

Update IPv6 implementation from keysight #353

Closed
wants to merge 9 commits into from
2 changes: 1 addition & 1 deletion Source/Additions/NSURL+GNUstepBase.m
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ - (id) initWithScheme: (NSString*)scheme
if ([host length] > 0)
{
[urlString appendString:
[host stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
[host stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLHostAllowedCharacterSet]]];
}
if ([port intValue] > 0)
{
Expand Down
18 changes: 9 additions & 9 deletions Source/GSSocketStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#import "GSNetwork.h"

typedef union {
struct sockaddr s;
struct sockaddr_storage s; /* Increased memory allocation for IPv6 addresses*/
struct sockaddr_in i4;
#ifdef AF_INET6
struct sockaddr_in6 i6;
Expand Down Expand Up @@ -62,12 +62,12 @@ SOCKIVARS
/**
* get the sockaddr
*/
- (struct sockaddr*) _address;
- (struct sockaddr_storage*) _address;

/**
* set the sockaddr
*/
- (void) _setAddress: (struct sockaddr*)address;
- (void) _setAddress: (struct sockaddr_storage*)address;

/**
* setter for closing flag ... the remote end has stopped either sending
Expand Down Expand Up @@ -119,8 +119,8 @@ SOCKIVARS
SOCKIVARS
@end
@interface GSSocketInputStream (AddedBehaviors)
- (struct sockaddr*) _address;
- (void) _setAddress: (struct sockaddr*)address;
- (struct sockaddr_storage*) _address;
- (void) _setAddress: (struct sockaddr_storage*)address;
- (NSInteger) _read: (uint8_t *)buffer maxLength: (NSUInteger)len;
- (void) _setClosing: (BOOL)passive;
- (void) _setHandler: (id)h;
Expand Down Expand Up @@ -161,8 +161,8 @@ SOCKIVARS
SOCKIVARS
@end
@interface GSSocketOutputStream (AddedBehaviors)
- (struct sockaddr*) _address;
- (void) _setAddress: (struct sockaddr*)address;
- (struct sockaddr_storage*) _address;
- (void) _setAddress: (struct sockaddr_storage*)address;
- (void) _setClosing: (BOOL)passive;
- (void) _setHandler: (id)h;
- (void) _setPassive: (BOOL)passive;
Expand Down Expand Up @@ -217,8 +217,8 @@ SOCKIVARS

@end
@interface GSSocketServerStream (AddedBehaviors)
- (struct sockaddr*) _address;
- (void) _setAddress: (struct sockaddr*)address;
- (struct sockaddr_storage*) _address;
- (void) _setAddress: (struct sockaddr_storage*)address;
- (void) _setClosing: (BOOL)passive;
- (void) _setHandler: (id)h;
- (void) _setPassive: (BOOL)passive;
Expand Down
52 changes: 31 additions & 21 deletions Source/GSSocketStream.m
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ + (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o
if (conf != nil)
{
GSSOCKS *h;
struct sockaddr *sa = [i _address];
struct sockaddr_storage *sa = [i _address];
NSString *v;
BOOL i6 = NO;

Expand All @@ -958,15 +958,15 @@ + (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o
}

#if defined(AF_INET6)
if (sa->sa_family == AF_INET6)
if (sa->ss_family == AF_INET6)
{
i6 = YES;
}
else
#endif
if (sa->sa_family != AF_INET)
if (sa->ss_family != AF_INET)
{
GSOnceMLog(@"SOCKS not supported for socket type %d", sa->sa_family);
GSOnceMLog(@"SOCKS not supported for socket type %d", sa->ss_family);
return;
}

Expand Down Expand Up @@ -1563,12 +1563,12 @@ - (id) init
#endif
_sock = INVALID_SOCKET;
_handler = nil;
_address.s.sa_family = AF_UNSPEC;
_address.s.ss_family = AF_UNSPEC;
}
return self;
}

- (struct sockaddr*) _address
- (struct sockaddr_storage*) _address
{
return &_address.s;
}
Expand All @@ -1577,7 +1577,7 @@ - (id) propertyForKey: (NSString *)key
{
id result = [super propertyForKey: key];

if (result == nil && _address.s.sa_family != AF_UNSPEC)
if (result == nil && _address.s.ss_family != AF_UNSPEC)
{
SOCKET s = [self _sock];
sockaddr_any sin;
Expand Down Expand Up @@ -1645,6 +1645,11 @@ - (void) _sendEvent: (NSStreamEvent)event
}
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
- (BOOL) _setSocketAddress: (NSString*)address
port: (NSInteger)port
family: (NSInteger)family
Expand All @@ -1670,7 +1675,7 @@ - (BOOL) _setSocketAddress: (NSString*)address
}
else
{
[self _setAddress: (struct sockaddr*)&peer];
[self _setAddress: (struct sockaddr_storage*)&peer];
return YES;
}
}
Expand All @@ -1693,7 +1698,7 @@ - (BOOL) _setSocketAddress: (NSString*)address
}
else
{
[self _setAddress: (struct sockaddr*)&peer];
[self _setAddress: (struct sockaddr_storage*)&peer];
return YES;
}
}
Expand All @@ -1715,7 +1720,7 @@ - (BOOL) _setSocketAddress: (NSString*)address
else
{
strncpy(peer.sun_path, c_addr, sizeof(peer.sun_path)-1);
[self _setAddress: (struct sockaddr*)&peer];
[self _setAddress: (struct sockaddr_storage*)&peer];
return YES;
}
}
Expand All @@ -1726,7 +1731,7 @@ - (BOOL) _setSocketAddress: (NSString*)address
}
}

- (void) _setAddress: (struct sockaddr*)address
- (void) _setAddress: (struct sockaddr_storage*)address
{
memcpy(&_address.s, address, GSPrivateSockaddrLength(address));
}
Expand Down Expand Up @@ -1831,7 +1836,7 @@ - (void) open
{
[GSSOCKS tryInput: self output: _sibling];
}
s = socket(_address.s.sa_family, SOCK_STREAM, 0);
s = socket(_address.s.ss_family, SOCK_STREAM, 0);
if (BADSOCKET(s))
{
[self _recordError];
Expand All @@ -1849,7 +1854,7 @@ - (void) open
[GSTLSHandler tryInput: self output: _sibling];
}

result = connect([self _sock], &_address.s,
result = connect([self _sock], (struct sockaddr*)&_address.s,
GSPrivateSockaddrLength(&_address.s));
if (socketError(result))
{
Expand Down Expand Up @@ -2352,7 +2357,7 @@ - (void) open
{
[GSSOCKS tryInput: _sibling output: self];
}
s = socket(_address.s.sa_family, SOCK_STREAM, 0);
s = socket(_address.s.ss_family, SOCK_STREAM, 0);
if (BADSOCKET(s))
{
[self _recordError];
Expand All @@ -2370,7 +2375,7 @@ - (void) open
[GSTLSHandler tryInput: _sibling output: self];
}

result = connect([self _sock], &_address.s,
result = connect([self _sock], (struct sockaddr*)&_address.s,
GSPrivateSockaddrLength(&_address.s));
if (socketError(result))
{
Expand Down Expand Up @@ -2756,7 +2761,7 @@ - (void) open
return;
}

s = socket(_address.s.sa_family, SOCK_STREAM, 0);
s = socket(_address.s.ss_family, SOCK_STREAM, 0);
if (BADSOCKET(s))
{
[self _recordError];
Expand All @@ -2769,9 +2774,9 @@ - (void) open
}

#ifndef BROKEN_SO_REUSEADDR
if (_address.s.sa_family == AF_INET
if (_address.s.ss_family == AF_INET
#ifdef AF_INET6
|| _address.s.sa_family == AF_INET6
|| _address.s.ss_family == AF_INET6
#endif
)
{
Expand All @@ -2792,7 +2797,7 @@ - (void) open
#endif

bindReturn = bind([self _sock],
&_address.s, GSPrivateSockaddrLength(&_address.s));
(struct sockaddr*)&_address.s, GSPrivateSockaddrLength(&_address.s));
if (socketError(bindReturn))
{
[self _recordError];
Expand Down Expand Up @@ -2854,11 +2859,11 @@ - (void) acceptWithInputStream: (NSInputStream **)inputStream
struct {
uint8_t bytes[BUFSIZ];
} __attribute__((aligned(2)))buf;
struct sockaddr *addr = (struct sockaddr*)&buf;
struct sockaddr_storage *addr = (struct sockaddr_storage*)&buf;
socklen_t len = sizeof(buf);
int acceptReturn;

acceptReturn = accept([self _sock], addr, (OPTLEN*)&len);
acceptReturn = accept([self _sock], (struct sockaddr*)addr, (OPTLEN*)&len);
_events &= ~NSStreamEventHasBytesAvailable;
if (socketError(acceptReturn))
{ // test for real error
Expand Down Expand Up @@ -2934,6 +2939,11 @@ - (void) acceptWithInputStream: (NSInputStream **)inputStream
*/
}

#pragma GCC diagnostic pop // cast align

#pragma GCC diagnostic pop // incompatible pointer types...


- (void) _dispatch
{
#if defined(_WIN32)
Expand Down
9 changes: 9 additions & 0 deletions Source/win32/NSStream.m
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,15 @@ + (void) getStreamsToHost: (NSHost *)host
#endif
}

//IPv6
if(!ins)
{
#if defined(AF_INET6)
ins = (GSSocketStream*)AUTORELEASE([[GSInet6InputStream alloc] initToAddr: address port: port]);
outs = (GSSocketStream*)AUTORELEASE([[GSInet6OutputStream alloc] initToAddr: address port: port]);
#endif
}

/*
* Windows only permits a single event to be associated with a socket
* at any time, but the runloop system only allows an event handle to
Expand Down
84 changes: 84 additions & 0 deletions Tests/base/NSStream/ipv6test.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#if defined(GNUSTEP_BASE_LIBRARY)
/**
* This test tests IPv6 using NSStream
*/
#import <Foundation/Foundation.h>
#import "Testing.h"

@interface IPV6Server : NSObject

- (void) main;

@end

@implementation IPV6Server

- (void) main
{
}

@end

int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];

NSInputStream *inputStream;
NSOutputStream *outputStream;
IPV6Server *svr = [[IPV6Server alloc] init];

NSString *ipv6ServerAddress = @"::1"; // Replace with your actual IPv6 server address
uint16_t port = 12345; // Replace with the actual port number

// Resolve the IPv6 address using NSHost
NSHost *host = [NSHost hostWithName: ipv6ServerAddress];
NSArray *addresses = [host addresses];

PASS([addresses count] > 0, "Resolve IPv6 address");

NSString *ipv6Address = [addresses objectAtIndex: 0];
NSThread *thread = [[NSThread alloc] initWithTarget: svr selector: @selector(main) object: nil];

PASS(thread != nil, "Created thread for server");

[thread start];

[NSStream getStreamsToHost: [NSHost hostWithName: ipv6Address]
port: port
inputStream: &inputStream
outputStream: &outputStream];

[inputStream open];
[outputStream open];

// Perform your tests here to validate the IPv6 stream
// You can write and read data from the stream and assert the expected results
// For example:

NSString *testData = @"Test Data";
NSData *dataToWrite = [testData dataUsingEncoding:NSUTF8StringEncoding];
NSInteger bytesWritten = [outputStream write: [dataToWrite bytes] maxLength: [dataToWrite length]];

PASS(bytesWritten > 0, "Write data to the stream");

uint8_t buffer[1024];
NSInteger bytesRead = [inputStream read:buffer maxLength:1024];
NSString *receivedString = [[NSString alloc] initWithBytes:buffer length:bytesRead encoding:NSUTF8StringEncoding];

PASS(bytesRead > 0, "Read data from the stream");
PASS([receivedString isEqualToString: testData], "Received data matches the expected data");

[inputStream close];
[outputStream close];

[arp release];
arp = nil;

return 0;
}
#else
int main()
{
return 0;
}
#endif
2 changes: 2 additions & 0 deletions base.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -4062,6 +4062,7 @@
);
INFOPLIST_FILE = "Support/Foundation/Foundation-Info.plist";
LIBRARY_SEARCH_PATHS = /opt/local/lib;
MACOSX_DEPLOYMENT_TARGET = 10.14;
OTHER_CFLAGS = (
"-DGNUSTEP",
"-DNeXT_RUNTIME",
Expand Down Expand Up @@ -4100,6 +4101,7 @@
);
INFOPLIST_FILE = "Support/Foundation/Foundation-Info.plist";
LIBRARY_SEARCH_PATHS = /opt/local/lib;
MACOSX_DEPLOYMENT_TARGET = 10.14;
OTHER_CFLAGS = (
"-DGNUSTEP",
"-DNeXT_RUNTIME",
Expand Down
Loading