зеркало из https://github.com/mozilla/gecko-dev.git
Basic Mac implementation of async DNS. r=warren, patrick; part of bug:10731.
This commit is contained in:
Родитель
122fb95337
Коммит
67c770c6b8
|
@ -24,6 +24,8 @@
|
|||
typedef struct nsHostEnt
|
||||
{
|
||||
PRHostEnt hostEnt;
|
||||
PRIntn bufLen;
|
||||
char * bufPtr;
|
||||
char buffer[PR_NETDB_BUF_SIZE];
|
||||
} nsHostEnt;
|
||||
%}
|
||||
|
|
|
@ -16,95 +16,115 @@
|
|||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDnsService.h"
|
||||
#include "nsIDNSListener.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsError.h"
|
||||
#include "prnetdb.h"
|
||||
|
||||
#include "nsString2.h"
|
||||
|
||||
|
||||
#if defined(XP_MAC)
|
||||
#include "pprthred.h"
|
||||
|
||||
static pascal void DNSNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
|
||||
|
||||
#if TARGET_CARBON
|
||||
|
||||
#define nsDNS_NOTIFIER_ROUTINE nsDnsServiceNotifierRoutineUPP
|
||||
#define INIT_OPEN_TRANSPORT() InitOpenTransport(mClientContext, kInitOTForExtensionMask)
|
||||
#define OT_OPEN_INTERNET_SERVICES(config, flags, err) OTOpenInternetServices(config, flags, err, mClientContext)
|
||||
#define OT_OPEN_ENDPOINT(config, flags, info, err) OTOpenEndpoint(config, flags, info, err, mClientContext)
|
||||
|
||||
#else
|
||||
|
||||
#define nsDNS_NOTIFIER_ROUTINE nsDnsServiceNotifierRoutine
|
||||
#define INIT_OPEN_TRANSPORT() InitOpenTransport()
|
||||
#define OT_OPEN_INTERNET_SERVICES(config, flags, err) OTOpenInternetServices(config, flags, err)
|
||||
#define OT_OPEN_ENDPOINT(config, flags, info, err) OTOpenEndpoint(config, flags, info, err)
|
||||
#endif /* TARGET_CARBON */
|
||||
#endif /* XP_MAC */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsDNSRequest;
|
||||
class nsDNSLookup;
|
||||
|
||||
class nsDNSLookup
|
||||
|
||||
#if defined(XP_MAC)
|
||||
|
||||
typedef struct nsInetHostInfo {
|
||||
InetHostInfo hostInfo;
|
||||
nsDNSLookup * lookup;
|
||||
} nsInetHostInfo;
|
||||
|
||||
typedef struct nsLookupElement {
|
||||
QElem qElem;
|
||||
nsDNSLookup * lookup;
|
||||
|
||||
} nsLookupElement;
|
||||
|
||||
#endif
|
||||
|
||||
class nsDNSLookup : public nsISupports
|
||||
{
|
||||
public:
|
||||
nsresult AddDNSRequest(nsDNSRequest* request);
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
const char* mHostName;
|
||||
PRHostEnt mHostEntry; // NSPR or platform specific hostent?
|
||||
PRIntn mCount;
|
||||
PRBool mComplete;
|
||||
PRIntn mIndex; // XXX - for round robin
|
||||
void * mListenerQueue; // XXX - maintain a list of nsDNSRequests.
|
||||
nsDNSLookup(nsISupports * clientContext, const char * hostName, nsIDNSListener* listener);
|
||||
~nsDNSLookup(void);
|
||||
|
||||
nsresult AddDNSRequest(nsDNSRequest* request);
|
||||
nsresult FinishHostEntry(void);
|
||||
nsresult CallOnFound(void);
|
||||
const char * HostName(void) { return mHostName; }
|
||||
nsresult InitiateDNSLookup(nsDNSService * dnsService);
|
||||
|
||||
|
||||
protected:
|
||||
friend pascal void nsDnsServiceNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
|
||||
|
||||
char * mHostName;
|
||||
nsHostEnt mHostEntry;
|
||||
PRBool mComplete;
|
||||
nsresult mResult;
|
||||
|
||||
PRIntn mCount;
|
||||
PRIntn mIndex; // XXX - for round robin
|
||||
nsCOMPtr<nsISupportsArray> mRequestQueue; // XXX - maintain a list of nsDNSRequests.
|
||||
|
||||
#if defined(XP_MAC)
|
||||
nsLookupElement mLookupElement;
|
||||
nsInetHostInfo mInetHostInfo;
|
||||
nsIDNSListener * mListener; // belongs with nsDNSRequest
|
||||
nsISupports * mContext; // belongs with nsDNSRequest
|
||||
#endif
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDNSLookup, nsISupports)
|
||||
|
||||
|
||||
class nsDNSRequest : public nsIRequest
|
||||
{
|
||||
nsIDNSListener* mListener;
|
||||
nsDNSLookup* mHostNameLookup;
|
||||
|
||||
// nsIRequest methods:
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIDNSListener> mListener;
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
nsDNSLookup* mHostNameLookup;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDNSRequest, nsIRequest)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsDNSService methods:
|
||||
|
||||
nsDNSService::nsDNSService()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDNSService::Init()
|
||||
{
|
||||
// initialize DNS cache (persistent?)
|
||||
#if defined(XP_MAC)
|
||||
// create Open Transport Service Provider for DNS Lookups
|
||||
#elif defined(_WIN)
|
||||
// create DNS EventHandler Window
|
||||
#elif defined(XP_UNIX)
|
||||
// XXXX - ?
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsDNSService::~nsDNSService()
|
||||
{
|
||||
// deallocate cache
|
||||
#if defined(XP_MAC)
|
||||
// deallocate Open Transport Service Provider
|
||||
#elif defined(_WIN)
|
||||
// dispose DNS EventHandler Window
|
||||
#elif defined(XP_UNIX)
|
||||
// XXXX - ?
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDNSService, NS_GET_IID(nsIDNSService));
|
||||
|
||||
NS_METHOD
|
||||
nsDNSService::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
nsDNSService* ph = new nsDNSService();
|
||||
if (ph == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(ph);
|
||||
nsresult rv = ph->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(ph);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// utility routines:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIDNSService methods:
|
||||
|
||||
//
|
||||
// Allocate space from the buffer, aligning it to "align" before doing
|
||||
// the allocation. "align" must be a power of 2.
|
||||
|
@ -129,47 +149,389 @@ static char *BufAlloc(PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align)
|
|||
return buf;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsDNSLookup methods:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsDNSLookup::nsDNSLookup(nsISupports * clientContext, const char * hostName, nsIDNSListener* listener)
|
||||
{
|
||||
mHostName = new char [PL_strlen(hostName) + 1];
|
||||
PL_strcpy(mHostName, hostName);
|
||||
|
||||
mHostEntry.bufLen = PR_NETDB_BUF_SIZE;
|
||||
mHostEntry.bufPtr = mHostEntry.buffer;
|
||||
|
||||
mCount = 0;
|
||||
mComplete = PR_FALSE;
|
||||
mResult = NS_OK;
|
||||
mIndex = 0;
|
||||
mRequestQueue = nsnull;
|
||||
|
||||
#if defined(XP_MAC)
|
||||
mInetHostInfo.lookup = this;
|
||||
mLookupElement.lookup = this;
|
||||
mContext = clientContext; // belongs with nsDNSRequest
|
||||
mListener = listener; // belongs with nsDNSRequest
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
nsDNSLookup::~nsDNSLookup(void)
|
||||
{
|
||||
if (mHostName)
|
||||
delete [] mHostName;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDNSLookup::AddDNSRequest(nsDNSRequest* request)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDNSLookup::FinishHostEntry(void)
|
||||
{
|
||||
#if defined(XP_MAC)
|
||||
PRIntn len, count, i;
|
||||
|
||||
// convert InetHostInfo to PRHostEnt
|
||||
|
||||
// copy name
|
||||
len = nsCRT::strlen(mInetHostInfo.hostInfo.name);
|
||||
mHostEntry.hostEnt.h_name = BufAlloc(len, &mHostEntry.bufPtr, &mHostEntry.bufLen, 0);
|
||||
NS_ASSERTION(nsnull != mHostEntry.hostEnt.h_name,"nsHostEnt buffer full.");
|
||||
if (mHostEntry.hostEnt.h_name == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsCRT::memcpy(mHostEntry.hostEnt.h_name, mInetHostInfo.hostInfo.name, len);
|
||||
|
||||
// set aliases to nsnull
|
||||
mHostEntry.hostEnt.h_aliases = (char **)BufAlloc(sizeof(char *), &mHostEntry.bufPtr, &mHostEntry.bufLen, sizeof(char *));
|
||||
NS_ASSERTION(nsnull != mHostEntry.hostEnt.h_aliases,"nsHostEnt buffer full.");
|
||||
if (mHostEntry.hostEnt.h_aliases == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
*mHostEntry.hostEnt.h_aliases = nsnull;
|
||||
|
||||
// fill in address type
|
||||
mHostEntry.hostEnt.h_addrtype = AF_INET;
|
||||
|
||||
// set address length
|
||||
mHostEntry.hostEnt.h_length = sizeof(long);
|
||||
|
||||
// count addresses and allocate storage for the pointers
|
||||
for (count = 1; count < kMaxHostAddrs && mInetHostInfo.hostInfo.addrs[count] != nsnull; count++){;}
|
||||
mHostEntry.hostEnt.h_addr_list = (char **)BufAlloc(count * sizeof(char *), &mHostEntry.bufPtr, &mHostEntry.bufLen, sizeof(char *));
|
||||
NS_ASSERTION(nsnull != mHostEntry.hostEnt.h_addr_list,"nsHostEnt buffer full.");
|
||||
if (mHostEntry.hostEnt.h_addr_list == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// copy addresses one at a time
|
||||
len = mHostEntry.hostEnt.h_length;
|
||||
for (i = 0; i < kMaxHostAddrs && mInetHostInfo.hostInfo.addrs[i] != nsnull; i++) {
|
||||
mHostEntry.hostEnt.h_addr_list[i] = BufAlloc(len, &mHostEntry.bufPtr, &mHostEntry.bufLen, len);
|
||||
NS_ASSERTION(nsnull != mHostEntry.hostEnt.h_addr_list[i],"nsHostEnt buffer full.");
|
||||
if (mHostEntry.hostEnt.h_addr_list[i] == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
*(InetHost *)mHostEntry.hostEnt.h_addr_list[i] = mInetHostInfo.hostInfo.addrs[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
mComplete = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDNSLookup::CallOnFound(void)
|
||||
{
|
||||
nsresult result;
|
||||
// iterate through request queue calling listeners
|
||||
|
||||
// but for now just do this
|
||||
if (NS_SUCCEEDED(mResult)) {
|
||||
result = mListener->OnFound(mContext, mHostName, &mHostEntry);
|
||||
}
|
||||
result = mListener->OnStopLookup(mContext, mHostName, mResult);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDNSLookup::InitiateDNSLookup(nsDNSService * dnsService) // I don't want to have to pass this in...
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
#if defined(XP_MAC)
|
||||
OSErr err;
|
||||
|
||||
err = OTInetStringToAddress(dnsService->mServiceRef, (char *)mHostName, (InetHostInfo *)&mInetHostInfo);
|
||||
if (err != noErr)
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsDNSService methods:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(XP_MAC)
|
||||
pascal void nsDnsServiceNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
|
||||
|
||||
pascal void nsDnsServiceNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
|
||||
{
|
||||
#pragma unused(contextPtr)
|
||||
|
||||
if (code == T_DNRSTRINGTOADDRCOMPLETE) {
|
||||
nsDNSService * dnsService = (nsDNSService *)contextPtr;
|
||||
nsDNSLookup * dnsLookup = ((nsInetHostInfo *)cookie)->lookup;
|
||||
PRThread * thread;
|
||||
|
||||
if (result != kOTNoError)
|
||||
dnsLookup->mResult = NS_ERROR_UNKNOWN_HOST;
|
||||
|
||||
// queue result & wake up dns service thread
|
||||
Enqueue((QElem *)&dnsLookup->mLookupElement, &dnsService->mCompletionQueue);
|
||||
|
||||
dnsService->mThread->GetPRThread(&thread);
|
||||
if (thread)
|
||||
PR_Mac_PostAsyncNotify(thread);
|
||||
}
|
||||
// or else we don't handle the event
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
nsDNSService::nsDNSService()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mThreadRunning = PR_FALSE;
|
||||
mThread = nsnull;
|
||||
|
||||
#if defined(XP_MAC)
|
||||
mServiceRef = nsnull;
|
||||
|
||||
mCompletionQueue.qFlags = 0;
|
||||
mCompletionQueue.qHead = nsnull;
|
||||
mCompletionQueue.qTail = nsnull;
|
||||
|
||||
#if TARGET_CARBON
|
||||
mCLientContext = nsnull;
|
||||
#endif /* TARGET_CARBON */
|
||||
#endif /* defined(XP_MAC) */
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDNSService::Init()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// initialize DNS cache (persistent?)
|
||||
#if defined(XP_MAC)
|
||||
// create Open Transport Service Provider for DNS Lookups
|
||||
OSStatus errOT;
|
||||
|
||||
|
||||
#if TARGET_CARBON
|
||||
nsDnsServiceNotifierRoutineUPP = NewOTNotifyUPP(nsDnsServiceNotifierRoutine);
|
||||
|
||||
errOT = OTAllocClientContext((UInt32)0, &clientContext);
|
||||
NS_ASSERTION(err == kOTNoError, "error allocating OTClientContext.");
|
||||
#endif
|
||||
|
||||
|
||||
errOT = INIT_OPEN_TRANSPORT();
|
||||
NS_ASSERTION(errOT == kOTNoError, "InitOpenTransport failed.");
|
||||
|
||||
mServiceRef = OT_OPEN_INTERNET_SERVICES(kDefaultInternetServicesPath, NULL, &errOT);
|
||||
if (errOT != kOTNoError) return NS_ERROR_UNEXPECTED; /* no network -- oh well */
|
||||
NS_ASSERTION((mServiceRef != NULL) && (errOT == kOTNoError), "error opening OT service.");
|
||||
|
||||
/* Install notify function for DNR Address To String completion */
|
||||
errOT = OTInstallNotifier(mServiceRef, nsDNS_NOTIFIER_ROUTINE, this);
|
||||
NS_ASSERTION(errOT == kOTNoError, "error installing dns notification routine.");
|
||||
|
||||
/* Put us into async mode */
|
||||
errOT = OTSetAsynchronous(mServiceRef);
|
||||
NS_ASSERTION(errOT == kOTNoError, "error setting service to async mode.");
|
||||
|
||||
// if either of the two previous calls failed then dealloc service ref and return NS_FAILED
|
||||
|
||||
rv = NS_NewThread(&mThread, this, 0, PR_JOINABLE_THREAD);
|
||||
|
||||
|
||||
|
||||
#elif defined(_WIN)
|
||||
// create DNS EventHandler Window
|
||||
#elif defined(XP_UNIX)
|
||||
// XXXX - ?
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsDNSService::~nsDNSService()
|
||||
{
|
||||
// deallocate cache
|
||||
#if defined(XP_MAC)
|
||||
CloseOpenTransport(); // should be moved to terminate routine
|
||||
// deallocate Open Transport Service Provider
|
||||
#elif defined(_WIN)
|
||||
// dispose DNS EventHandler Window
|
||||
#elif defined(XP_UNIX)
|
||||
// XXXX - ?
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsDNSService, nsIDNSService, nsIRunnable);
|
||||
|
||||
|
||||
NS_METHOD
|
||||
nsDNSService::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (aOuter != nsnull)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsDNSService* dnsService = new nsDNSService();
|
||||
if (dnsService == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(dnsService);
|
||||
rv = dnsService->Init();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = dnsService->QueryInterface(aIID, aResult);
|
||||
}
|
||||
NS_RELEASE(dnsService);
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// nsIRunnable implementation...
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsDNSService::Lookup(nsISupports* ctxt,
|
||||
const char* hostname,
|
||||
nsDNSService::Run(void)
|
||||
{
|
||||
#if defined(XP_MAC)
|
||||
OSErr err;
|
||||
nsLookupElement * lookupElement;
|
||||
nsDNSLookup * lookup;
|
||||
nsresult rv;
|
||||
|
||||
mThreadRunning = PR_TRUE;
|
||||
|
||||
while (mThreadRunning) {
|
||||
|
||||
PR_Mac_WaitForAsyncNotify(PR_INTERVAL_NO_TIMEOUT);
|
||||
// check queue for completed DNS lookups
|
||||
while ((lookupElement = (nsLookupElement *)mCompletionQueue.qHead) != nsnull) {
|
||||
|
||||
err = Dequeue((QElemPtr)lookupElement, &mCompletionQueue);
|
||||
if (err)
|
||||
continue; // assert
|
||||
|
||||
lookup = lookupElement->lookup;
|
||||
// convert InetHostInfo to nsHostEnt
|
||||
rv = lookup->FinishHostEntry();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// put lookup in cache
|
||||
}
|
||||
|
||||
// issue callbacks
|
||||
rv = lookup->CallOnFound();
|
||||
|
||||
delete lookup; // until we start caching them
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIDNSService methods:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDNSService::Lookup(nsISupports* clientContext,
|
||||
const char* hostName,
|
||||
nsIDNSListener* listener,
|
||||
nsIRequest* *DNSRequest)
|
||||
{
|
||||
nsresult rv, result = NS_OK;
|
||||
|
||||
// initateLookupNeeded = false;
|
||||
// lock dns service
|
||||
// search cache for existing nsDNSLookup with matching hostname
|
||||
// if (exists) {
|
||||
// if (complete) {
|
||||
// AddRef lookup
|
||||
// unlock cache
|
||||
// OnStartLookup
|
||||
// OnFound
|
||||
// OnStopLookup
|
||||
// Release lookup
|
||||
// return
|
||||
// }
|
||||
// } else {
|
||||
// create nsDNSLookup
|
||||
// iniateLookupNeeded = true
|
||||
// }
|
||||
// create nsDNSRequest & queue on nsDNSLookup
|
||||
// unlock dns service
|
||||
// OnStartLookup
|
||||
// if (iniateLookupNeeded) {
|
||||
// initiate async lookup
|
||||
// }
|
||||
//
|
||||
|
||||
#if defined(XP_MAC)
|
||||
|
||||
// create nsDNSLookup
|
||||
nsDNSLookup * lookup = new nsDNSLookup(clientContext, hostName, listener);
|
||||
if (lookup == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = listener->OnStartLookup(clientContext, hostName);
|
||||
// what do we do with the return value here?
|
||||
|
||||
// initiate async lookup
|
||||
rv = lookup->InitiateDNSLookup(this);
|
||||
|
||||
return rv;
|
||||
|
||||
#else
|
||||
// temporary SYNC version
|
||||
|
||||
PRStatus status = PR_SUCCESS;
|
||||
nsHostEnt* hostentry;
|
||||
/*
|
||||
check cache for existing nsDNSLookup with matching hostname
|
||||
call OnStartLookup
|
||||
if (nsDNSLookup doesn't exist) {
|
||||
create nsDNSLookup for this hostname
|
||||
kick off DNS Lookup
|
||||
}
|
||||
|
||||
if (nsDNSLookup already has at least one address) {
|
||||
call OnFound
|
||||
}
|
||||
|
||||
if (nsDNSLookup is already complete) {
|
||||
call OnStopLookup
|
||||
return null
|
||||
}
|
||||
|
||||
create nsDNSRequest
|
||||
queue nsDNSRequest on nsDNSLookup // XXXX - potential race condition here
|
||||
return nsDNSRequest
|
||||
*/
|
||||
|
||||
// temporary SYNC version
|
||||
|
||||
hostentry = new nsHostEnt;
|
||||
if (!hostentry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = listener->OnStartLookup(ctxt, hostname);
|
||||
rv = listener->OnStartLookup(ctxt, hostName);
|
||||
|
||||
PRBool numeric = PR_TRUE;
|
||||
for (const char *hostCheck = hostname; *hostCheck; hostCheck++) {
|
||||
for (const char *hostCheck = hostName; *hostCheck; hostCheck++) {
|
||||
if (!nsString2::IsDigit(*hostCheck) && (*hostCheck != '.') ) {
|
||||
numeric = PR_FALSE;
|
||||
break;
|
||||
|
@ -181,17 +543,17 @@ nsDNSService::Lookup(nsISupports* ctxt,
|
|||
if (numeric) {
|
||||
// If it is numeric then try to convert it into an IP-Address
|
||||
netAddr = (PRNetAddr*)nsAllocator::Alloc(sizeof(PRNetAddr));
|
||||
status = PR_StringToNetAddr(hostname, netAddr);
|
||||
status = PR_StringToNetAddr(hostName, netAddr);
|
||||
if (PR_SUCCESS == status) {
|
||||
// slam the IP in and move on.
|
||||
PRHostEnt *ent = &(hostentry->hostEnt);
|
||||
PRIntn bufLen = PR_NETDB_BUF_SIZE;
|
||||
char *buffer = hostentry->buffer;
|
||||
ent->h_name = (char*)BufAlloc(PL_strlen(hostname) + 1,
|
||||
ent->h_name = (char*)BufAlloc(PL_strlen(hostName) + 1,
|
||||
&buffer,
|
||||
&bufLen,
|
||||
0);
|
||||
memcpy(ent->h_name, hostname, PL_strlen(hostname) + 1);
|
||||
memcpy(ent->h_name, hostName, PL_strlen(hostName) + 1);
|
||||
|
||||
ent->h_aliases = (char**)BufAlloc(1 * sizeof(char*),
|
||||
&buffer,
|
||||
|
@ -215,21 +577,21 @@ nsDNSService::Lookup(nsISupports* ctxt,
|
|||
// If the hostname is numeric, but we couldn't create
|
||||
// a net addr out of it, we're dealing w/ a purely numeric
|
||||
// address (no dots), try a regular gethostbyname on it.
|
||||
status = PR_GetHostByName(hostname,
|
||||
status = PR_GetHostByName(hostName,
|
||||
hostentry->buffer,
|
||||
PR_NETDB_BUF_SIZE,
|
||||
&hostentry->hostEnt);
|
||||
}
|
||||
nsAllocator::Free(netAddr);
|
||||
} else {
|
||||
status = PR_GetHostByName(hostname,
|
||||
status = PR_GetHostByName(hostName,
|
||||
hostentry->buffer,
|
||||
PR_NETDB_BUF_SIZE,
|
||||
&hostentry->hostEnt);
|
||||
}
|
||||
|
||||
if (PR_SUCCESS == status) {
|
||||
rv = listener->OnFound(ctxt, hostname, hostentry);
|
||||
rv = listener->OnFound(ctxt, hostName, hostentry);
|
||||
result = NS_OK;
|
||||
}
|
||||
else {
|
||||
|
@ -239,7 +601,8 @@ nsDNSService::Lookup(nsISupports* ctxt,
|
|||
// listener does not need to copy it...
|
||||
delete hostentry;
|
||||
|
||||
rv = listener->OnStopLookup(ctxt, hostname, result);
|
||||
rv = listener->OnStopLookup(ctxt, hostName, result);
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
#define nsDNSService_h__
|
||||
|
||||
#include "nsIDNSService.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsIThread.h"
|
||||
#if defined(XP_MAC)
|
||||
#include <OSUtils.h>
|
||||
#include <OpenTransport.h>
|
||||
#include <OpenTptInternet.h>
|
||||
#elif defined (XP_PC)
|
||||
|
@ -29,11 +32,15 @@
|
|||
|
||||
class nsIDNSListener;
|
||||
class nsICancelable;
|
||||
class nsDNSLookup;
|
||||
|
||||
class nsDNSService : public nsIDNSService,
|
||||
public nsIRunnable
|
||||
|
||||
class nsDNSService : public nsIDNSService
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
// nsDNSService methods:
|
||||
nsDNSService();
|
||||
|
@ -48,11 +55,24 @@ public:
|
|||
NS_DECL_NSIDNSSERVICE
|
||||
|
||||
protected:
|
||||
// nsDNSLookup cache? - list of nsDNSLookups
|
||||
friend class nsDNSLookup;
|
||||
friend pascal void nsDnsServiceNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
|
||||
|
||||
nsIThread * mThread;
|
||||
PRBool mThreadRunning;
|
||||
// nsDNSLookup cache? - list of nsDNSLookups, hash table (nsHashTable, nsStringKey)
|
||||
// list of nsDNSLookups in order of expiration (PRCList?)
|
||||
|
||||
#if defined(XP_MAC)
|
||||
InetSvcRef mServiceRef;
|
||||
|
||||
InetSvcRef mServiceRef;
|
||||
QHdr mCompletionQueue;
|
||||
|
||||
#if TARGET_CARBON
|
||||
OTClientContextPtr mClientContext;
|
||||
OTNotifyUPP nsDnsServiceNotifierRoutineUPP;
|
||||
#endif /* TARGET_CARBON */
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
//XXX - to be defined
|
||||
|
||||
|
|
Двоичные данные
netwerk/macbuild/netwerk.mcp
Двоичные данные
netwerk/macbuild/netwerk.mcp
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче