Fixes for failure of connect() system call

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@39862 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2016-06-14 07:10:44 +00:00
parent fc41ffdc4b
commit 6ec2add2b3
4 changed files with 73 additions and 43 deletions

View file

@ -1,3 +1,29 @@
2016-06-14 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSSocketStream.m: Fix for failure of connect() call.
* Source/GSStream.m: Fix event handling for failed streams.
* Tests/NSURLConnection/test01.m: Add testcases, fix reset of delegate.
Fixes for kfreebsd network stack being clever enough to fail the
connect() call if the remote port is on the same machine and has
no process listening on it. Reported by Heintzmann
2016-06-08 Richard Frith-Macdonald <rfm@gnu.org>
* Documentation/Base.gsdoc:
* Documentation/ReleaseNotes.gsdoc:
* Documentation/news.texi:
Documentation/release notes preparation for next release.
* Source/Makefile.postamble:
* Source/NSBundle.m:
* Source/NSPathUtilities.m:
* Source/NSString.m:
* Source/NSTask.m:
* configure.ac:
Changes to use the new multiarch path component cpu-host rather
than a host subdirectory inside a cpu directory.
* configure: Regenerate
2016-06-07 Richard Frith-Macdonald <rfm@gnu.org>
* Source/Additions/GSMime.m:

View file

@ -1714,6 +1714,11 @@ setNonBlocking(SOCKET fd)
// could be opened because of sibling
if ([self _isOpened])
return;
if (_sibling && [_sibling streamStatus] == NSStreamStatusError)
{
[self _setStatus: NSStreamStatusError];
return;
}
if (_passive || (_sibling && [_sibling _isOpened]))
goto open_ok;
// check sibling status, avoid double connect
@ -1722,11 +1727,6 @@ setNonBlocking(SOCKET fd)
[self _setStatus: NSStreamStatusOpening];
return;
}
else if (_sibling && [_sibling streamStatus] == NSStreamStatusError)
{
[self _setStatus: NSStreamStatusError];
return;
}
else
{
int result;
@ -1771,13 +1771,10 @@ setNonBlocking(SOCKET fd)
}
else
{
/* Had an immediate connect error, so record it and remove
* any handlers because we want higher level code to be
* told about it.
/* Had an immediate connect error.
*/
[self _setHandler: nil];
[_sibling _setHandler: nil];
[self _recordError];
[_sibling _recordError];
}
#if defined(_WIN32)
WSAEventSelect(_sock, _loopID, FD_ALL_EVENTS);
@ -1787,7 +1784,7 @@ setNonBlocking(SOCKET fd)
[self _schedule];
return;
}
else
else if (NSStreamStatusOpening == _currentStatus)
{
NSRunLoop *r;
NSDate *d;
@ -1976,6 +1973,10 @@ setNonBlocking(SOCKET fd)
@"Received event for closed stream");
[_sibling _dispatch];
}
else if ([self streamStatus] == NSStreamStatusError)
{
[self _sendEvent: NSStreamEventErrorOccurred];
}
else
{
WSANETWORKEVENTS events;
@ -2103,6 +2104,10 @@ setNonBlocking(SOCKET fd)
{
myEvent = NSStreamEventEndEncountered;
}
else if ([self streamStatus] == NSStreamStatusError)
{
myEvent = NSStreamEventErrorOccurred;
}
else
{
[self _setStatus: NSStreamStatusOpen];
@ -2196,6 +2201,11 @@ setNonBlocking(SOCKET fd)
// could be opened because of sibling
if ([self _isOpened])
return;
if (_sibling && [_sibling streamStatus] == NSStreamStatusError)
{
[self _setStatus: NSStreamStatusError];
return;
}
if (_passive || (_sibling && [_sibling _isOpened]))
goto open_ok;
// check sibling status, avoid double connect
@ -2204,11 +2214,6 @@ setNonBlocking(SOCKET fd)
[self _setStatus: NSStreamStatusOpening];
return;
}
else if (_sibling && [_sibling streamStatus] == NSStreamStatusError)
{
[self _setStatus: NSStreamStatusError];
return;
}
else
{
int result;
@ -2254,13 +2259,10 @@ setNonBlocking(SOCKET fd)
}
else
{
/* Had an immediate connect error, so record it and remove
* any handlers because we want higher level code to be
* told about it.
/* Had an immediate connect error.
*/
[self _setHandler: nil];
[_sibling _setHandler: nil];
[self _recordError];
[_sibling _recordError];
}
#if defined(_WIN32)
WSAEventSelect(_sock, _loopID, FD_ALL_EVENTS);
@ -2270,7 +2272,7 @@ setNonBlocking(SOCKET fd)
[self _schedule];
return;
}
else
else if (NSStreamStatusOpening == _currentStatus)
{
NSRunLoop *r;
NSDate *d;
@ -2300,7 +2302,6 @@ setNonBlocking(SOCKET fd)
WSAEventSelect(_sock, _loopID, FD_ALL_EVENTS);
#endif
[super open];
}
@ -2409,6 +2410,10 @@ setNonBlocking(SOCKET fd)
@"Received event for closed stream");
[_sibling _dispatch];
}
else if ([self streamStatus] == NSStreamStatusError)
{
[self _sendEvent: NSStreamEventErrorOccurred];
}
else
{
WSANETWORKEVENTS events;
@ -2534,6 +2539,10 @@ setNonBlocking(SOCKET fd)
{
myEvent = NSStreamEventEndEncountered;
}
else if ([self streamStatus] == NSStreamStatusError)
{
myEvent = NSStreamEventErrorOccurred;
}
else
{
[self _setStatus: NSStreamStatusOpen];

View file

@ -88,29 +88,22 @@ NSString * const NSStreamSOCKSProxyVersionKey
*/
static RunLoopEventType typeForStream(NSStream *aStream)
{
NSStreamStatus status = [aStream streamStatus];
if (NSStreamStatusError == status
|| [aStream _loopID] == (void*)aStream)
{
return ET_TRIGGER;
}
#if defined(_WIN32)
if ([aStream _loopID] == (void*)aStream)
{
return ET_TRIGGER;
}
else
{
return ET_HANDLE;
}
return ET_HANDLE;
#else
if ([aStream _loopID] == (void*)aStream)
{
return ET_TRIGGER;
}
else if ([aStream isKindOfClass: [NSOutputStream class]] == NO
&& [aStream streamStatus] != NSStreamStatusOpening)
if ([aStream isKindOfClass: [NSOutputStream class]] == NO
&& status != NSStreamStatusOpening)
{
return ET_RDESC;
}
else
{
return ET_WDESC;
}
return ET_WDESC;
#endif
}

View file

@ -62,7 +62,6 @@ int main(int argc, char **argv, char **env)
urlString = @"http://127.0.0.1:19750";
req = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString]];
del = [[Delegate new] autorelease];
[del reset];
[NSURLConnection connectionWithRequest: req
delegate: del];
while (![del done] && duration < 3.0)
@ -71,23 +70,26 @@ int main(int argc, char **argv, char **env)
runUntilDate: [NSDate dateWithTimeIntervalSinceNow: timing]];
duration += timing;
}
PASS([del done], "http test completes");
PASS([del done] && nil != [del error],
"connection to dead(not-listening) HTTP service");
[del reset];
duration = 0.0;
urlString = @"https://127.0.0.1:19750";
req = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString]];
[NSURLConnection connectionWithRequest: req
delegate: del];
[del reset];
while (![del done] && duration < 3.0)
{
[[NSRunLoop currentRunLoop]
runUntilDate: [NSDate dateWithTimeIntervalSinceNow: timing]];
duration += timing;
}
PASS([del done], "https test completes");
PASS([del done] && nil != [del error],
"connection to dead(not-listening) HTTPS service");
[del reset];
[arp release]; arp = nil;