b140a1c340
It is not a good idea to have a thread get an address from the request cache, while another thread is deleting said address as the cache has grown too large. Add a lock around the cache access to make it safe.
113 lines
3.1 KiB
C++
113 lines
3.1 KiB
C++
/*
|
|
* Copyright 2010-2017, Haiku, Inc. All Rights Reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
#ifndef _NETWORK_ADDRESS_RESOLVER_H
|
|
#define _NETWORK_ADDRESS_RESOLVER_H
|
|
|
|
|
|
#include <Locker.h>
|
|
#include <ObjectList.h>
|
|
#include <Referenceable.h>
|
|
#include <String.h>
|
|
#include <SupportDefs.h>
|
|
|
|
|
|
class BNetworkAddress;
|
|
struct addrinfo;
|
|
|
|
|
|
// flags for name resolution
|
|
enum {
|
|
B_NO_ADDRESS_RESOLUTION = 0x0001,
|
|
B_UNCONFIGURED_ADDRESS_FAMILIES = 0x0002,
|
|
};
|
|
|
|
|
|
class BNetworkAddressResolver: public BReferenceable {
|
|
public:
|
|
BNetworkAddressResolver();
|
|
BNetworkAddressResolver(const char* address,
|
|
uint16 port = 0, uint32 flags = 0);
|
|
BNetworkAddressResolver(const char* address,
|
|
const char* service, uint32 flags = 0);
|
|
BNetworkAddressResolver(int family,
|
|
const char* address, uint16 port = 0,
|
|
uint32 flags = 0);
|
|
BNetworkAddressResolver(int family,
|
|
const char* address, const char* service,
|
|
uint32 flags = 0);
|
|
~BNetworkAddressResolver();
|
|
|
|
status_t InitCheck() const;
|
|
|
|
void Unset();
|
|
|
|
status_t SetTo(const char* address, uint16 port = 0,
|
|
uint32 flags = 0);
|
|
status_t SetTo(const char* address, const char* service,
|
|
uint32 flags = 0);
|
|
status_t SetTo(int family, const char* address,
|
|
uint16 port = 0, uint32 flags = 0);
|
|
status_t SetTo(int family, const char* address,
|
|
const char* service, uint32 flags = 0);
|
|
|
|
status_t GetNextAddress(uint32* cookie,
|
|
BNetworkAddress& address) const;
|
|
status_t GetNextAddress(int family, uint32* cookie,
|
|
BNetworkAddress& address) const;
|
|
|
|
// TODO all the ::Resolve variants are needed. Maybe the SetTo and
|
|
// constructors could be removed as ::Resolve is the right way to get a
|
|
// resolver (using the cache).
|
|
static BReference<const BNetworkAddressResolver> Resolve(
|
|
const char* address, const char* service,
|
|
uint32 flags = 0);
|
|
static BReference<const BNetworkAddressResolver> Resolve(
|
|
const char* address, uint16 port = 0,
|
|
uint32 flags = 0);
|
|
static BReference<const BNetworkAddressResolver> Resolve(int family,
|
|
const char* address, const char* service,
|
|
uint32 flags = 0);
|
|
static BReference<const BNetworkAddressResolver> Resolve(int family,
|
|
const char* address, uint16 port = 0,
|
|
uint32 flags = 0);
|
|
|
|
private:
|
|
addrinfo* fInfo;
|
|
status_t fStatus;
|
|
|
|
|
|
struct CacheEntry {
|
|
CacheEntry(int family, const char* address, const char* service,
|
|
uint32 flags, BNetworkAddressResolver* resolver)
|
|
:
|
|
fFamily(family),
|
|
fAddress(address),
|
|
fService(service),
|
|
fFlags(flags),
|
|
fResolver(resolver, false)
|
|
{
|
|
}
|
|
|
|
bool Matches(int family, BString address, BString service, uint32 flags)
|
|
{
|
|
return family == fFamily && flags == fFlags && address == fAddress
|
|
&& service == fService;
|
|
}
|
|
|
|
int fFamily;
|
|
BString fAddress;
|
|
BString fService;
|
|
uint32 fFlags;
|
|
|
|
BReference<const BNetworkAddressResolver> fResolver;
|
|
};
|
|
|
|
static BLocker sCacheLock;
|
|
static BObjectList<CacheEntry> sCacheMap;
|
|
};
|
|
|
|
|
|
#endif // _NETWORK_ADDRESS_RESOLVER_H
|