Support outgoing connections bound to a specific local address.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@18953 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2004-03-29 14:53:37 +00:00
parent 3c85fee35b
commit 1a0cf15c79
7 changed files with 108 additions and 17 deletions

View file

@ -10,6 +10,15 @@
contigure.ac:
Add --enable-xslt option to require stylesheet support (in case we want
to start uisng it to generate documentation)
* Headers/Foundation/NSURLHandle.h:
* Source/GSFileHandle.m:
* Source/GSHTTPURLHandle.m:
* Source/NSFileHandle.m:
* Source/NSURLHandle.m:
Support binding to specific local ip address for outgoing connections
in gnustep extensions.
* Source/GSMime.m: ([-setContent:]), ([-addContent:]) Check that
content of a multipart document consists of GSMimeDocument objects.
2004-03-29 Adrian Robert <arobert@cogsci.ucsd.edu>

View file

@ -42,6 +42,7 @@ GS_EXPORT NSString * const NSHTTPPropertyRedirectionHeadersKey;
GS_EXPORT NSString * const NSHTTPPropertyErrorPageDataKey;
#ifndef NO_GNUSTEP
GS_EXPORT NSString * const GSHTTPPropertyLocalHostKey;
GS_EXPORT NSString * const GSHTTPPropertyMethodKey;
GS_EXPORT NSString * const GSHTTPPropertyProxyHostKey;
GS_EXPORT NSString * const GSHTTPPropertyProxyPortKey;

View file

@ -3317,6 +3317,11 @@ static NSCharacterSet *tokenSet = nil;
*/
- (void) addContent: (id)newContent
{
if ([newContent isKindOfClass: [GSMimeDocument class]] == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"Content to add is not a GSMimeDocument"];
}
if (content == nil)
{
content = [NSMutableArray new];
@ -4469,6 +4474,18 @@ static NSCharacterSet *tokenSet = nil;
{
if (newContent != content)
{
unsigned c = [newContent count];
while (c-- > 0)
{
id o = [newContent objectAtIndex: c];
if ([o isKindOfClass: [GSMimeDocument class]] == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"Content contains non-GSMimeDocument"];
}
}
newContent = [newContent mutableCopy];
ASSIGN(content, newContent);
RELEASE(newContent);

View file

@ -685,6 +685,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
static BOOL beenHere = NO;
SOCKET net;
struct sockaddr_in sin;
struct sockaddr_in lsin;
NSString *lhost = nil;
NSString *shost = nil;
NSString *sport = nil;
@ -720,6 +722,30 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
return nil;
}
if ([p hasPrefix: @"bind-"] == YES)
{
NSRange r;
lhost = [p substringFromIndex: 5];
r = [lhost rangeOfString: @":"];
if (r.length > 0)
{
p = [lhost substringFromIndex: NSMaxRange(r)];
lhost = [lhost substringToIndex: r.location];
}
else
{
p = nil;
}
if (getAddr(lhost, p, @"tcp", &lsin) == NO)
{
NSLog(@"bad bind address specification");
RELEASE(self);
return nil;
}
p = @"tcp";
}
/**
* A protocol fo the form 'socks-...' controls socks operation,
* overriding defaults and environment variables.<br />
@ -795,6 +821,21 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
RELEASE(self);
return nil;
}
if (lhost != nil)
{
if (bind(net, (struct sockaddr *)&lsin, sizeof(lsin)) == SOCKET_ERROR)
{
NSLog(@"unable to bind to port %s:%d - %s", inet_ntoa(lsin.sin_addr),
GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno));
#if defined(__MINGW__)
(void) closesocket(net);
#else
(void) close(net);
#endif
RELEASE(self);
return nil;
}
}
#if defined(__MINGW__)
self = [self initWithNativeHandle: (void*)net closeOnDealloc: YES];

View file

@ -161,6 +161,12 @@ char emp[64] = {
* secure connection when a proxy is specified, GSHTTPURLHandle will
* attempt to open an SSL Tunnel through the proxy.
* </p>
* <p>
* Requests to the remote server may be forced to be bound to a
* particular local IP address by using the key
* &quot;GSHTTPPropertyLocalHostKey&quot; which must contain the
* IP address of a network interface on the local host.
* </p>
*/
@implementation GSHTTPURLHandle
@ -450,6 +456,7 @@ static void debugWrite(NSData *data)
NSNotificationCenter *nc;
NSString *host = nil;
NSString *port = nil;
NSString *s;
/*
* Don't start a load if one is in progress.
@ -471,6 +478,20 @@ static void debugWrite(NSData *data)
[sock closeFile];
DESTROY(sock);
}
/*
* If we have a local address specified, tell the file handle to bind to it.
*/
s = [request objectForKey: GSHTTPPropertyLocalHostKey];
if ([s length] > 0)
{
s = [NSString stringWithFormat: @"bind-%@", s];
}
else
{
s = @"tcp"; // Bind to any.
}
if ([[request objectForKey: GSHTTPPropertyProxyHostKey] length] == 0)
{
NSNumber *p;
@ -493,17 +514,15 @@ static void debugWrite(NSData *data)
@"https not supported ... needs SSL bundle"];
return;
}
sock = [sslClass
fileHandleAsClientInBackgroundAtAddress: host
sock = [sslClass fileHandleAsClientInBackgroundAtAddress: host
service: port
protocol: @"tcp"];
protocol: s];
}
else
{
sock = [NSFileHandle
fileHandleAsClientInBackgroundAtAddress: host
sock = [NSFileHandle fileHandleAsClientInBackgroundAtAddress: host
service: port
protocol: @"tcp"];
protocol: s];
}
}
else
@ -522,19 +541,17 @@ static void debugWrite(NSData *data)
}
host = [request objectForKey: GSHTTPPropertyProxyHostKey];
port = [request objectForKey: GSHTTPPropertyProxyPortKey];
sock = [sslClass
fileHandleAsClientInBackgroundAtAddress: host
sock = [sslClass fileHandleAsClientInBackgroundAtAddress: host
service: port
protocol: @"tcp"];
protocol: s];
}
else
{
host = [request objectForKey: GSHTTPPropertyProxyHostKey];
port = [request objectForKey: GSHTTPPropertyProxyPortKey];
sock = [NSFileHandle
fileHandleAsClientInBackgroundAtAddress: host
sock = [NSFileHandle fileHandleAsClientInBackgroundAtAddress: host
service: port
protocol: @"tcp"];
protocol: s];
}
}
if (sock == nil)

View file

@ -428,7 +428,10 @@ NSString * const NSFileHandleOperationException
* is <em>not</em> made via a socks server.<br />
* Otherwise, the text '...' must be the name of the host on which the
* socks5 server is running, with an optional port number separated
* from the host name by a colon.
* from the host name by a colon.<br />
* Alternatively a prefix of the form 'bind-' forllowed by an IP address
* may be used (for non-socks connections) to ensure that the connection
* is made from the specified address.
* </item>
* <item>
* If modes is nil or empty, uses NSDefaultRunLoopMode.

View file

@ -64,6 +64,9 @@ NSString * const NSHTTPPropertyErrorPageDataKey
NSString * const GSHTTPPropertyMethodKey
= @"GSHTTPPropertyMethodKey";
NSString * const GSHTTPPropertyLocalHostKey
= @"GSHTTPPropertyLocalHostKey";
NSString * const GSHTTPPropertyProxyHostKey
= @"GSHTTPPropertyProxyHostKey";