clean up initiation of streams handlers

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25919 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2008-01-10 13:53:07 +00:00
parent b68f5383b4
commit f4f0f94439

View file

@ -77,6 +77,7 @@ GSPrivateSockaddrLength(struct sockaddr *addr)
BOOL handshake; BOOL handshake;
BOOL active; BOOL active;
} }
+ (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o;
- (id) initWithInput: (GSSocketInputStream*)i - (id) initWithInput: (GSSocketInputStream*)i
output: (GSSocketOutputStream*)o; output: (GSSocketOutputStream*)o;
- (GSSocketInputStream*) istream; - (GSSocketInputStream*) istream;
@ -93,6 +94,11 @@ GSPrivateSockaddrLength(struct sockaddr *addr)
@implementation GSStreamHandler @implementation GSStreamHandler
+ (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o
{
[self subclassResponsibility: _cmd];
}
- (void) bye - (void) bye
{ {
[self subclassResponsibility: _cmd]; [self subclassResponsibility: _cmd];
@ -280,6 +286,35 @@ static gnutls_anon_client_credentials_t anoncred;
} }
} }
+ (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o
{
NSString *tls;
tls = [i propertyForKey: NSStreamSocketSecurityLevelKey];
if (tls == nil)
{
tls = [o propertyForKey: NSStreamSocketSecurityLevelKey];
if (tls != nil)
{
[i setProperty: tls forKey: NSStreamSocketSecurityLevelKey];
}
}
else
{
[o setProperty: tls forKey: NSStreamSocketSecurityLevelKey];
}
if (tls != nil)
{
GSTLS *h;
h = [[GSTLS alloc] initWithInput: i output: o];
[i _setHandler: h];
[o _setHandler: h];
RELEASE(h);
}
}
- (void) bye - (void) bye
{ {
if (active == YES || handshake == YES) if (active == YES || handshake == YES)
@ -342,8 +377,13 @@ static gnutls_anon_client_credentials_t anoncred;
if (GSDebugSet(@"NSStream") == YES) if (GSDebugSet(@"NSStream") == YES)
{ {
gnutls_global_set_log_level (11); gnutls_global_set_log_level (11); // Full debug output
} }
else
{
gnutls_global_set_log_level (0); // No debug
}
if ([[o propertyForKey: NSStreamSocketSecurityLevelKey] isEqual: proto] == NO) if ([[o propertyForKey: NSStreamSocketSecurityLevelKey] isEqual: proto] == NO)
{ {
DESTROY(self); DESTROY(self);
@ -550,54 +590,66 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
@end @end
@implementation GSSOCKS @implementation GSSOCKS
+ (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o
{
NSDictionary *conf;
conf = [i propertyForKey: NSStreamSOCKSProxyConfigurationKey];
if (conf == nil)
{
conf = [o propertyForKey: NSStreamSOCKSProxyConfigurationKey];
if (conf != nil)
{
[i setProperty: conf forKey: NSStreamSOCKSProxyConfigurationKey];
}
}
else
{
[o setProperty: conf forKey: NSStreamSOCKSProxyConfigurationKey];
}
if (conf != nil)
{
GSSOCKS *h;
h = [[GSSOCKS alloc] initWithInput: i output: o];
[i _setHandler: h];
[o _setHandler: h];
RELEASE(h);
}
}
- (void) bye - (void) bye
{ {
if (handshake == YES) if (handshake == YES)
{ {
NSString *tls; GSSocketInputStream *is = RETAIN(istream);
GSTLS *t = nil; GSSocketOutputStream *os = RETAIN(ostream);
handshake = NO; handshake = NO;
tls = [ostream propertyForKey: NSStreamSocketSecurityLevelKey];
if (tls == nil && istream != nil)
{
tls = [istream propertyForKey: NSStreamSocketSecurityLevelKey];
if (tls != nil)
{
[ostream setProperty: tls forKey: NSStreamSocketSecurityLevelKey];
}
}
if (tls != nil)
{
t = [[GSTLS alloc] initWithInput: istream output: ostream];
}
if (t == nil)
{
GSSocketInputStream *is = RETAIN(istream);
GSSocketOutputStream *os = RETAIN(ostream);
/* No TLS required ... simply remove SOCKS handler from streams [is _setHandler: nil];
* and let the streams know that the open has completed. [os _setHandler: nil];
* NB. Removing SOCKS handle from streams may cause it to be [GSTLS tryInput: is output: os];
* deallocated, so we work with local variables to hold the if ([is streamStatus] == NSStreamStatusOpen)
* streams long enough to send events to them. {
*/
[is _setHandler: nil];
[os _setHandler: nil];
[is _sendEvent: NSStreamEventOpenCompleted]; [is _sendEvent: NSStreamEventOpenCompleted];
[os _sendEvent: NSStreamEventOpenCompleted]; }
RELEASE(is);
RELEASE(os);
}
else else
{ {
/* Replace SOCKS handler wth TLS handler and start TLS handshake. [is _sendEvent: NSStreamEventErrorOccurred];
*/ }
[istream _setHandler: t]; if ([os streamStatus] == NSStreamStatusOpen)
[ostream _setHandler: t]; {
[t hello]; [os _sendEvent: NSStreamEventOpenCompleted];
RELEASE(t); [os _sendEvent: NSStreamEventHasSpaceAvailable];
} }
else
{
[os _sendEvent: NSStreamEventErrorOccurred];
}
RELEASE(is);
RELEASE(os);
} }
} }
@ -904,7 +956,8 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
{ {
int result; int result;
result = [istream _read: rbuffer + roffset maxLength: rwant - roffset]; result = [istream _read: rbuffer + roffset
maxLength: rwant - roffset];
if (result == 0) if (result == 0)
{ {
error = @"SOCKS end-of-file during negotiation"; error = @"SOCKS end-of-file during negotiation";
@ -1021,7 +1074,7 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
[ostream setProperty: a [ostream setProperty: a
forKey: GSStreamRemotePortKey]; forKey: GSStreamRemotePortKey];
/* Return immediately after calling -bye as it /* Return immediately after calling -bye as it
* will cause this instance to be deallocted. * will cause this instance to be deallocated.
*/ */
[self bye]; [self bye];
return; return;
@ -1466,6 +1519,10 @@ setNonBlocking(SOCKET fd)
{ {
SOCKET s; SOCKET s;
if (_handler == nil)
{
[GSSOCKS tryInput: self output: _sibling];
}
s = socket(_address->sa_family, SOCK_STREAM, 0); s = socket(_address->sa_family, SOCK_STREAM, 0);
if (BADSOCKET(s)) if (BADSOCKET(s))
{ {
@ -1481,27 +1538,7 @@ setNonBlocking(SOCKET fd)
if (_handler == nil) if (_handler == nil)
{ {
NSString *tls; [GSTLS tryInput: self output: _sibling];
tls = [self propertyForKey: NSStreamSocketSecurityLevelKey];
if (tls == nil && _sibling != nil)
{
tls = [_sibling propertyForKey: NSStreamSocketSecurityLevelKey];
if (tls != nil)
{
[self setProperty: tls
forKey: NSStreamSocketSecurityLevelKey];
}
}
if (tls != nil)
{
GSTLS *t;
t = [[GSTLS alloc] initWithInput: self output: _sibling];
[_sibling _setHandler: t];
[self _setHandler: t];
RELEASE(t);
}
} }
result = connect([self _sock], _address, result = connect([self _sock], _address,
GSPrivateSockaddrLength(_address)); GSPrivateSockaddrLength(_address));
@ -1952,6 +1989,10 @@ setNonBlocking(SOCKET fd)
{ {
SOCKET s; SOCKET s;
if (_handler == nil)
{
[GSSOCKS tryInput: _sibling output: self];
}
s = socket(_address->sa_family, SOCK_STREAM, 0); s = socket(_address->sa_family, SOCK_STREAM, 0);
if (BADSOCKET(s)) if (BADSOCKET(s))
{ {
@ -1967,27 +2008,7 @@ setNonBlocking(SOCKET fd)
if (_handler == nil) if (_handler == nil)
{ {
NSString *tls; [GSTLS tryInput: _sibling output: self];
tls = [self propertyForKey: NSStreamSocketSecurityLevelKey];
if (tls == nil && _sibling != nil)
{
tls = [_sibling propertyForKey: NSStreamSocketSecurityLevelKey];
if (tls != nil)
{
[self setProperty: tls
forKey: NSStreamSocketSecurityLevelKey];
}
}
if (tls != nil)
{
GSTLS *t;
t = [[GSTLS alloc] initWithInput: _sibling output: self];
[_sibling _setHandler: t];
[self _setHandler: t];
RELEASE(t);
}
} }
result = connect([self _sock], _address, result = connect([self _sock], _address,