mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
Make code more efficient and andd diagnostics
This commit is contained in:
parent
18024cdc8e
commit
dded8a90e8
2 changed files with 168 additions and 69 deletions
215
Source/NSHost.m
215
Source/NSHost.m
|
@ -52,7 +52,7 @@ extern int WSAAPI inet_pton(int , const char *, void *);
|
||||||
#endif /* !_WIN32 */
|
#endif /* !_WIN32 */
|
||||||
|
|
||||||
// Temporary hack ... dusable new code because it seems to break CI
|
// Temporary hack ... dusable new code because it seems to break CI
|
||||||
#undef HAVE_RESOLV_H
|
//#undef HAVE_RESOLV_H
|
||||||
|
|
||||||
#if defined(HAVE_RESOLV_H)
|
#if defined(HAVE_RESOLV_H)
|
||||||
#include <resolv.h>
|
#include <resolv.h>
|
||||||
|
@ -75,12 +75,35 @@ static BOOL _hostCacheEnabled = YES;
|
||||||
static NSMutableDictionary *_hostCache = nil;
|
static NSMutableDictionary *_hostCache = nil;
|
||||||
static id null = nil;
|
static id null = nil;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Max hostname length in line with RFC 1123
|
* Max hostname length in line with RFC 1123
|
||||||
*/
|
*/
|
||||||
#define GSMAXHOSTNAMELEN 255
|
#define GSMAXHOSTNAMELEN 255
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
isName(const char *n)
|
||||||
|
{
|
||||||
|
if (NULL == n
|
||||||
|
|| (isdigit(n[0]) && sscanf(n, "%*d.%*d.%*d.%*d") == 4)
|
||||||
|
|| 0 != strchr(n, ':'))
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
getName(NSString *str)
|
||||||
|
{
|
||||||
|
const char *n = [str UTF8String];
|
||||||
|
|
||||||
|
if (isName(n))
|
||||||
|
{
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the current host name ... may change if we are using dhcp etc
|
* Return the current host name ... may change if we are using dhcp etc
|
||||||
*/
|
*/
|
||||||
|
@ -195,6 +218,74 @@ myHostName()
|
||||||
|
|
||||||
#if defined(HAVE_GETADDRINFO) && defined(HAVE_RESOLV_H)
|
#if defined(HAVE_GETADDRINFO) && defined(HAVE_RESOLV_H)
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
getCNames(NSString *host, NSMutableSet *cnames)
|
||||||
|
{
|
||||||
|
unsigned char response[NS_PACKETSZ];
|
||||||
|
extern int h_errno;
|
||||||
|
const char *name;
|
||||||
|
unsigned added = 0;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if ([cnames member: host] != nil)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (NULL == (name = getName(host)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform DNS query for CNAME records so that we can get
|
||||||
|
* any name pointed to by this one.
|
||||||
|
*/
|
||||||
|
len = res_query(name, ns_c_in, ns_t_cname, response, sizeof(response));
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
if (h_errno != NO_DATA)
|
||||||
|
{
|
||||||
|
herror(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ns_msg msg;
|
||||||
|
int count;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ns_initparse(response, len, &msg);
|
||||||
|
count = ns_msg_count(msg, ns_s_an);
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
ns_rr rr;
|
||||||
|
|
||||||
|
ns_parserr(&msg, ns_s_an, i, &rr);
|
||||||
|
|
||||||
|
// Check if the record is a CNAME
|
||||||
|
if (ns_rr_type(rr) == ns_t_cname)
|
||||||
|
{
|
||||||
|
char cname[NS_MAXDNAME];
|
||||||
|
|
||||||
|
if (ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg),
|
||||||
|
ns_rr_rdata(rr), cname, sizeof(cname)) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to uncompress CNAME\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
NSDebugFLLog(@"NSHost", @"res_query for '%@' found '%s'",
|
||||||
|
host, cname);
|
||||||
|
[cnames addObject: [NSString stringWithUTF8String: cname]];
|
||||||
|
added++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 == added)
|
||||||
|
{
|
||||||
|
NSDebugFLLog(@"NSHost", @"res_query for '%@' found no CNAMEs", host);
|
||||||
|
}
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
- (id) _initWithKey: (NSString*)key
|
- (id) _initWithKey: (NSString*)key
|
||||||
{
|
{
|
||||||
ENTER_POOL
|
ENTER_POOL
|
||||||
|
@ -205,6 +296,7 @@ myHostName()
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
struct addrinfo *tmp;
|
struct addrinfo *tmp;
|
||||||
int err;
|
int err;
|
||||||
|
BOOL keyIsName;
|
||||||
|
|
||||||
memset(&hints, '\0', sizeof(hints));
|
memset(&hints, '\0', sizeof(hints));
|
||||||
hints.ai_flags = AI_CANONNAME;
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
@ -214,12 +306,19 @@ myHostName()
|
||||||
{
|
{
|
||||||
[addresses unionSet: [hostClass _localAddresses]];
|
[addresses unionSet: [hostClass _localAddresses]];
|
||||||
ptr = "localhost";
|
ptr = "localhost";
|
||||||
|
keyIsName = NO;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getCNames(key, names);
|
||||||
|
ptr = [key UTF8String];
|
||||||
|
keyIsName = isName(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = getaddrinfo(ptr, 0, &hints, &entry);
|
err = getaddrinfo(ptr, 0, &hints, &entry);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(err));
|
fprintf(stderr, "getaddrinfo '%s' failed: %s\n", ptr, gai_strerror(err));
|
||||||
entry = NULL;
|
entry = NULL;
|
||||||
}
|
}
|
||||||
for (tmp = entry; tmp != NULL; tmp = tmp->ai_next)
|
for (tmp = entry; tmp != NULL; tmp = tmp->ai_next)
|
||||||
|
@ -227,6 +326,7 @@ myHostName()
|
||||||
char ipstr[INET6_ADDRSTRLEN];
|
char ipstr[INET6_ADDRSTRLEN];
|
||||||
char host[NI_MAXHOST];
|
char host[NI_MAXHOST];
|
||||||
void *addr;
|
void *addr;
|
||||||
|
NSString *a;
|
||||||
|
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wcast-align"
|
#pragma clang diagnostic ignored "-Wcast-align"
|
||||||
|
@ -246,85 +346,71 @@ myHostName()
|
||||||
}
|
}
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
inet_ntop(tmp->ai_family, addr, ipstr, sizeof(ipstr));
|
inet_ntop(tmp->ai_family, addr, ipstr, sizeof(ipstr));
|
||||||
[addresses addObject: [NSString stringWithUTF8String: ipstr]];
|
a = [NSString stringWithUTF8String: ipstr];
|
||||||
|
if (nil == [addresses member: a])
|
||||||
/* Possibly a reverse lookup of the address will give us a different
|
|
||||||
* result to our key (if the key was an address or an alias) so we
|
|
||||||
* might be able to get a new name for the host.
|
|
||||||
*/
|
|
||||||
if (getnameinfo(tmp->ai_addr, tmp->ai_addrlen, host, sizeof(host),
|
|
||||||
NULL, 0, NI_NAMEREQD) == 0)
|
|
||||||
{
|
{
|
||||||
[names addObject: [NSString stringWithUTF8String: host]];
|
[addresses addObject: a];
|
||||||
}
|
|
||||||
|
|
||||||
/* If we have a conaonical name for the host, use it.
|
/* Possibly a reverse lookup of the address will give us a different
|
||||||
*/
|
* result to our key (if the key was an address or an alias) so we
|
||||||
if (tmp->ai_canonname && *tmp->ai_canonname)
|
* might be able to get a new name for the host.
|
||||||
{
|
*/
|
||||||
unsigned char response[NS_PACKETSZ];
|
if (getnameinfo(tmp->ai_addr, tmp->ai_addrlen, host, sizeof(host),
|
||||||
extern int h_errno;
|
NULL, 0, NI_NAMEREQD) == 0)
|
||||||
ns_msg msg;
|
|
||||||
int count;
|
|
||||||
int len;
|
|
||||||
int i;
|
|
||||||
NSString *n;
|
|
||||||
|
|
||||||
n = [NSString stringWithUTF8String: tmp->ai_canonname];
|
|
||||||
[names addObject: n];
|
|
||||||
|
|
||||||
/* Perform DNS query for CNAME records so that we can get
|
|
||||||
* any name pointed to by this one.
|
|
||||||
*/
|
|
||||||
len = res_query(tmp->ai_canonname, ns_c_in, ns_t_cname,
|
|
||||||
response, sizeof(response));
|
|
||||||
if (len < 0)
|
|
||||||
{
|
{
|
||||||
if (h_errno != NO_DATA)
|
NSString *n = [NSString stringWithUTF8String: host];
|
||||||
|
|
||||||
|
NSDebugMLog(@"NSHost", @"getnameinfo for '%s' found '%s'",
|
||||||
|
ipstr, host);
|
||||||
|
if (nil == [names member: n])
|
||||||
{
|
{
|
||||||
herror("res_query");
|
[names addObject: n];
|
||||||
|
getCNames(n, names);
|
||||||
}
|
}
|
||||||
continue;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSDebugMLog(@"NSHost", @"getnameinfo for '%s' found nothing",
|
||||||
|
ipstr);
|
||||||
|
*host = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
ns_initparse(response, len, &msg);
|
/* If we have a canonical name for the host, use it.
|
||||||
count = ns_msg_count(msg, ns_s_an);
|
*/
|
||||||
for (i = 0; i < count; i++)
|
if (tmp->ai_canonname && *tmp->ai_canonname
|
||||||
|
&& strcmp(tmp->ai_canonname, host) != 0)
|
||||||
{
|
{
|
||||||
ns_rr rr;
|
NSString *n = [NSString stringWithUTF8String: tmp->ai_canonname];
|
||||||
|
|
||||||
ns_parserr(&msg, ns_s_an, i, &rr);
|
if (nil == [names member: n])
|
||||||
|
|
||||||
// Check if the record is a CNAME
|
|
||||||
if (ns_rr_type(rr) == ns_t_cname)
|
|
||||||
{
|
{
|
||||||
char cname[NS_MAXDNAME];
|
[names addObject: n];
|
||||||
|
getCNames(n, names);
|
||||||
if (ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg),
|
|
||||||
ns_rr_rdata(rr), cname, sizeof(cname)) < 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Failed to uncompress CNAME\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
[names addObject: [NSString stringWithUTF8String: cname]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if (nil == [addresses member: key])
|
|
||||||
{
|
|
||||||
/* The key was not an address ... so it must be a host name
|
|
||||||
*/
|
|
||||||
[names addObject: key];
|
|
||||||
}
|
|
||||||
freeaddrinfo(entry);
|
freeaddrinfo(entry);
|
||||||
}
|
}
|
||||||
if ([names count] || [addresses count])
|
if ([names count] || [addresses count])
|
||||||
{
|
{
|
||||||
_names = [names copy];
|
|
||||||
_addresses = [addresses copy];
|
_addresses = [addresses copy];
|
||||||
|
if (keyIsName)
|
||||||
|
{
|
||||||
|
[names addObject: key];
|
||||||
|
}
|
||||||
|
if ([names count])
|
||||||
|
{
|
||||||
|
_names = [names copy];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No names, so we duplicate addresses as names
|
||||||
|
*/
|
||||||
|
_names = [_addresses copy];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -490,7 +576,6 @@ myHostName()
|
||||||
+ (NSHost*) hostWithName: (NSString*)name
|
+ (NSHost*) hostWithName: (NSString*)name
|
||||||
{
|
{
|
||||||
NSHost *host = nil;
|
NSHost *host = nil;
|
||||||
const char *n;
|
|
||||||
|
|
||||||
if (name == nil)
|
if (name == nil)
|
||||||
{
|
{
|
||||||
|
@ -506,9 +591,7 @@ myHostName()
|
||||||
/* If this looks like an address rather than a host name ...
|
/* If this looks like an address rather than a host name ...
|
||||||
* call the correct method instead of this one.
|
* call the correct method instead of this one.
|
||||||
*/
|
*/
|
||||||
n = [name UTF8String];
|
if (NULL == getName(name))
|
||||||
if ((isdigit(n[0]) && sscanf(n, "%*d.%*d.%*d.%*d") == 4)
|
|
||||||
|| 0 != strchr(n, ':'))
|
|
||||||
{
|
{
|
||||||
return [self hostWithAddress: name];
|
return [self hostWithAddress: name];
|
||||||
}
|
}
|
||||||
|
@ -536,7 +619,7 @@ myHostName()
|
||||||
{
|
{
|
||||||
struct hostent *h;
|
struct hostent *h;
|
||||||
|
|
||||||
h = gethostbyname((char*)n);
|
h = gethostbyname((char*)[name UTF8String]);
|
||||||
if (0 == h)
|
if (0 == h)
|
||||||
{
|
{
|
||||||
if ([name isEqualToString: myHostName()] == YES)
|
if ([name isEqualToString: myHostName()] == YES)
|
||||||
|
|
|
@ -6,35 +6,51 @@
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||||
|
NSString *s;
|
||||||
NSHost *current;
|
NSHost *current;
|
||||||
NSHost *localh;
|
NSHost *localh;
|
||||||
NSHost *tmp;
|
NSHost *tmp;
|
||||||
|
|
||||||
|
tmp = [NSHost hostWithName: @"www.w3.org"];
|
||||||
|
PASS(tmp != nil, "NSHost gets www.w3.org");
|
||||||
|
NSLog(@"www.w3.org is %@", tmp);
|
||||||
|
|
||||||
|
tmp = [NSHost hostWithName: @"www.gnustep.org"];
|
||||||
|
PASS(tmp != nil, "NSHost gets www.gnustep.org");
|
||||||
|
NSLog(@"www.gnustep.org is %@", tmp);
|
||||||
|
|
||||||
current = [NSHost currentHost];
|
current = [NSHost currentHost];
|
||||||
PASS(current != nil && [current isKindOfClass: [NSHost class]],
|
PASS(current != nil && [current isKindOfClass: [NSHost class]],
|
||||||
"NSHost understands +currentHost");
|
"NSHost understands +currentHost");
|
||||||
|
NSLog(@"+currentHost is %@", current);
|
||||||
|
|
||||||
#if defined(GNUSTEP_BASE_LIBRARY)
|
#if defined(GNUSTEP_BASE_LIBRARY)
|
||||||
localh = [NSHost localHost];
|
localh = [NSHost localHost];
|
||||||
PASS(localh != nil && [localh isKindOfClass: [NSHost class]],
|
PASS(localh != nil && [localh isKindOfClass: [NSHost class]],
|
||||||
"NSHost understands +localHost");
|
"NSHost understands +localHost");
|
||||||
NSLog(@"localHost: %@", localh);
|
NSLog(@"+localHost is %@", localh);
|
||||||
#else
|
#else
|
||||||
localh = current;
|
localh = current;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tmp = [NSHost hostWithName: @"::1"];
|
tmp = [NSHost hostWithName: @"::1"];
|
||||||
PASS([[tmp address] isEqual: @"::1"], "+hostWithName: works for IPV6 addr");
|
PASS([[tmp address] isEqual: @"::1"], "+hostWithName: works for IPV6 addr");
|
||||||
|
NSLog(@"::1 is %@", tmp);
|
||||||
|
|
||||||
tmp = [NSHost hostWithName: [current name]];
|
s = [current name];
|
||||||
|
tmp = [NSHost hostWithName: s];
|
||||||
PASS([tmp isEqualToHost: current], "NSHost understands +hostWithName:");
|
PASS([tmp isEqualToHost: current], "NSHost understands +hostWithName:");
|
||||||
|
NSLog(@"+hostWithName: %@ is %@", s, tmp);
|
||||||
|
|
||||||
tmp = [NSHost hostWithAddress: [current address]];
|
s = [current address];
|
||||||
|
tmp = [NSHost hostWithAddress: s];
|
||||||
PASS([tmp isEqualToHost: current], "NSHost understands +hostWithAddress:");
|
PASS([tmp isEqualToHost: current], "NSHost understands +hostWithAddress:");
|
||||||
|
NSLog(@"+hostWithAddress: %@ is %@", s, tmp);
|
||||||
|
|
||||||
tmp = [NSHost hostWithName: @"127.0.0.1"];
|
tmp = [NSHost hostWithName: @"127.0.0.1"];
|
||||||
PASS(tmp != nil && [tmp isEqualToHost: localh],
|
PASS(tmp != nil && [tmp isEqualToHost: localh],
|
||||||
"NSHost understands [+hostWithName: 127.0.0.1]");
|
"NSHost understands [+hostWithName: 127.0.0.1]");
|
||||||
|
NSLog(@"127.0.0.1 is %@", tmp);
|
||||||
|
|
||||||
[arp release]; arp = nil;
|
[arp release]; arp = nil;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue