Skip to content

Commit 076c301

Browse files
committed
fixed SF# 1985180: Poco::Net::DNS multithreading issue
1 parent b3d124f commit 076c301

4 files changed

Lines changed: 131 additions & 40 deletions

File tree

Net/include/Poco/Net/DNS.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DNS.h
33
//
4-
// $Id: //poco/svn/Net/include/Poco/Net/DNS.h#2 $
4+
// $Id: //poco/Main/Net/include/Poco/Net/DNS.h#3 $
55
//
66
// Library: Net
77
// Package: NetCore
@@ -59,7 +59,7 @@ class Net_API DNS
5959
/// An internal DNS cache is used to speed up name lookups.
6060
{
6161
public:
62-
static const HostEntry& hostByName(const std::string& hostname);
62+
static HostEntry hostByName(const std::string& hostname);
6363
/// Returns a HostEntry object containing the DNS information
6464
/// for the host with the given name.
6565
///
@@ -73,7 +73,7 @@ class Net_API DNS
7373
///
7474
/// Throws an IOException in case of any other error.
7575

76-
static const HostEntry& hostByAddress(const IPAddress& address);
76+
static HostEntry hostByAddress(const IPAddress& address);
7777
/// Returns a HostEntry object containing the DNS information
7878
/// for the host with the given IP address.
7979
///
@@ -84,7 +84,7 @@ class Net_API DNS
8484
///
8585
/// Throws an IOException in case of any other error.
8686

87-
static const HostEntry& resolve(const std::string& address);
87+
static HostEntry resolve(const std::string& address);
8888
/// Returns a HostEntry object containing the DNS information
8989
/// for the host with the given IP address or host name.
9090
///
@@ -102,7 +102,7 @@ class Net_API DNS
102102
/// Convenience method that calls resolve(address) and returns
103103
/// the first address from the HostInfo.
104104

105-
static const HostEntry& thisHost();
105+
static HostEntry thisHost();
106106
/// Returns a HostEntry object containing the DNS information
107107
/// for this host.
108108
///

Net/include/Poco/Net/HostEntry.h

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// HostEntry.h
33
//
4-
// $Id: //poco/svn/Net/include/Poco/Net/HostEntry.h#2 $
4+
// $Id: //poco/Main/Net/include/Poco/Net/HostEntry.h#3 $
55
//
66
// Library: Net
77
// Package: NetCore
@@ -43,22 +43,70 @@
4343
#include "Poco/Net/Net.h"
4444
#include "Poco/Net/SocketDefs.h"
4545
#include "Poco/Net/IPAddress.h"
46+
#include "Poco/RefCountedObject.h"
47+
#include "Poco/AutoPtr.h"
4648
#include <vector>
4749

4850

4951
namespace Poco {
5052
namespace Net {
5153

5254

53-
class Net_API HostEntry
55+
class Net_API HostEntryImpl: public Poco::RefCountedObject
5456
/// This class stores information about a host
5557
/// such as host name, alias names and a list
5658
/// of IP addresses.
59+
///
60+
/// This class is used internally by HostEntry and is not
61+
/// intended for public use.
5762
{
58-
public:
63+
protected:
5964
typedef std::vector<std::string> AliasList;
6065
typedef std::vector<IPAddress> AddressList;
6166

67+
HostEntryImpl();
68+
/// Creates an empty HostEntry.
69+
70+
HostEntryImpl(struct hostent* entry);
71+
/// Creates the HostEntry from the data in a hostent structure.
72+
73+
#if defined(_WIN32) && defined(POCO_HAVE_IPv6)
74+
HostEntryImpl(struct addrinfo* info);
75+
/// Creates the HostEntry from the data in a Windows addrinfo structure.
76+
#endif
77+
78+
~HostEntryImpl();
79+
/// Destroys the HostEntryImpl.
80+
81+
const std::string& name() const;
82+
/// Returns the canonical host name.
83+
84+
const AliasList& aliases() const;
85+
/// Returns a vector containing alias names for
86+
/// the host name.
87+
88+
const AddressList& addresses() const;
89+
/// Returns a vector containing the IPAddresses
90+
/// for the host.
91+
92+
private:
93+
std::string _name;
94+
AliasList _aliases;
95+
AddressList _addresses;
96+
97+
friend class HostEntry;
98+
};
99+
100+
101+
class Net_API HostEntry
102+
/// This class stores information about a host
103+
/// such as host name, alias names and a list
104+
/// of IP addresses.
105+
{
106+
public:
107+
typedef HostEntryImpl::AliasList AliasList;
108+
typedef HostEntryImpl::AddressList AddressList;
109+
62110
HostEntry();
63111
/// Creates an empty HostEntry.
64112

@@ -94,33 +142,55 @@ class Net_API HostEntry
94142
/// for the host.
95143

96144
private:
97-
std::string _name;
98-
AliasList _aliases;
99-
AddressList _addresses;
145+
Poco::AutoPtr<HostEntryImpl> _pImpl;
100146
};
101147

102148

103149
//
104150
// inlines
105151
//
106-
inline const std::string& HostEntry::name() const
152+
inline const std::string& HostEntryImpl::name() const
107153
{
108154
return _name;
109155
}
110156

111157

112-
inline const HostEntry::AliasList& HostEntry::aliases() const
158+
inline const HostEntryImpl::AliasList& HostEntryImpl::aliases() const
113159
{
114160
return _aliases;
115161
}
116162

117163

118-
inline const HostEntry::AddressList& HostEntry::addresses() const
164+
inline const HostEntryImpl::AddressList& HostEntryImpl::addresses() const
119165
{
120166
return _addresses;
121167
}
122168

123169

170+
inline const std::string& HostEntry::name() const
171+
{
172+
return _pImpl->name();
173+
}
174+
175+
176+
inline const HostEntry::AliasList& HostEntry::aliases() const
177+
{
178+
return _pImpl->aliases();
179+
}
180+
181+
182+
inline const HostEntry::AddressList& HostEntry::addresses() const
183+
{
184+
return _pImpl->addresses();
185+
}
186+
187+
188+
inline void HostEntry::swap(HostEntry& other)
189+
{
190+
_pImpl.swap(other._pImpl);
191+
}
192+
193+
124194
inline void swap(HostEntry& h1, HostEntry& h2)
125195
{
126196
h1.swap(h2);

Net/src/DNS.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DNS.cpp
33
//
4-
// $Id: //poco/svn/Net/src/DNS.cpp#2 $
4+
// $Id: //poco/Main/Net/src/DNS.cpp#9 $
55
//
66
// Library: Net
77
// Package: NetCore
@@ -82,7 +82,7 @@ DNS::DNSCache DNS::_cache;
8282
Poco::FastMutex DNS::_mutex;
8383

8484

85-
const HostEntry& DNS::hostByName(const std::string& hostname)
85+
HostEntry DNS::hostByName(const std::string& hostname)
8686
{
8787
FastMutex::ScopedLock lock(_mutex);
8888

@@ -118,7 +118,7 @@ const HostEntry& DNS::hostByName(const std::string& hostname)
118118
}
119119

120120

121-
const HostEntry& DNS::hostByAddress(const IPAddress& address)
121+
HostEntry DNS::hostByAddress(const IPAddress& address)
122122
{
123123
FastMutex::ScopedLock lock(_mutex);
124124

@@ -158,7 +158,7 @@ const HostEntry& DNS::hostByAddress(const IPAddress& address)
158158
}
159159

160160

161-
const HostEntry& DNS::resolve(const std::string& address)
161+
HostEntry DNS::resolve(const std::string& address)
162162
{
163163
IPAddress ip;
164164
if (IPAddress::tryParse(address, ip))
@@ -170,15 +170,15 @@ const HostEntry& DNS::resolve(const std::string& address)
170170

171171
IPAddress DNS::resolveOne(const std::string& address)
172172
{
173-
const HostEntry& entry = resolve(address);
173+
HostEntry entry = resolve(address);
174174
if (!entry.addresses().empty())
175175
return entry.addresses()[0];
176176
else
177177
throw NoAddressFoundException(address);
178178
}
179179

180180

181-
const HostEntry& DNS::thisHost()
181+
HostEntry DNS::thisHost()
182182
{
183183
return hostByName(Environment::nodeName());
184184
}

Net/src/HostEntry.cpp

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// HostEntry.cpp
33
//
4-
// $Id: //poco/svn/Net/src/HostEntry.cpp#2 $
4+
// $Id: //poco/Main/Net/src/HostEntry.cpp#8 $
55
//
66
// Library: Net
77
// Package: NetCore
@@ -43,12 +43,17 @@ namespace Poco {
4343
namespace Net {
4444

4545

46-
HostEntry::HostEntry()
46+
//
47+
// HostEntryImpl
48+
//
49+
50+
51+
HostEntryImpl::HostEntryImpl()
4752
{
4853
}
4954

5055

51-
HostEntry::HostEntry(struct hostent* entry)
56+
HostEntryImpl::HostEntryImpl(struct hostent* entry)
5257
{
5358
poco_check_ptr (entry);
5459

@@ -77,7 +82,7 @@ HostEntry::HostEntry(struct hostent* entry)
7782
#if defined(_WIN32) && defined(POCO_HAVE_IPv6)
7883

7984

80-
HostEntry::HostEntry(struct addrinfo* ainfo)
85+
HostEntryImpl::HostEntryImpl(struct addrinfo* ainfo)
8186
{
8287
poco_check_ptr (ainfo);
8388

@@ -94,37 +99,53 @@ HostEntry::HostEntry(struct addrinfo* ainfo)
9499
#endif
95100

96101

97-
HostEntry::HostEntry(const HostEntry& entry):
98-
_name(entry._name),
99-
_aliases(entry._aliases),
100-
_addresses(entry._addresses)
102+
HostEntryImpl::~HostEntryImpl()
101103
{
102104
}
103105

104106

105-
HostEntry& HostEntry::operator = (const HostEntry& entry)
107+
//
108+
// HostEntry
109+
//
110+
111+
112+
HostEntry::HostEntry():
113+
_pImpl(new HostEntryImpl)
114+
{
115+
}
116+
117+
118+
HostEntry::HostEntry(struct hostent* entry):
119+
_pImpl(new HostEntryImpl(entry))
106120
{
107-
if (&entry != this)
108-
{
109-
_name = entry._name;
110-
_aliases = entry._aliases;
111-
_addresses = entry._addresses;
112-
}
113-
return *this;
114121
}
115122

116123

117-
void HostEntry::swap(HostEntry& hostEntry)
124+
#if defined(_WIN32) && defined(POCO_HAVE_IPv6)
125+
HostEntry::HostEntry(struct addrinfo* info):
126+
_pImpl(new HostEntryImpl(info))
118127
{
119-
std::swap(_name, hostEntry._name);
120-
std::swap(_aliases, hostEntry._aliases);
121-
std::swap(_addresses, hostEntry._addresses);
122128
}
129+
#endif
123130

124131

125132
HostEntry::~HostEntry()
126133
{
127134
}
128135

129136

137+
HostEntry::HostEntry(const HostEntry& entry):
138+
_pImpl(entry._pImpl)
139+
{
140+
}
141+
142+
143+
HostEntry& HostEntry::operator = (const HostEntry& entry)
144+
{
145+
HostEntry tmp(entry);
146+
tmp.swap(*this);
147+
return *this;
148+
}
149+
150+
130151
} } // namespace Poco::Net

0 commit comments

Comments
 (0)