haiku/headers/os/net/NetworkAddressResolver.h
Adrien Destugues b140a1c340 NetworkAddressResolver: cache needs to be locked
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.
2017-11-21 22:15:32 +01:00

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