socket: correctly iterate over lookup entries

This commit is contained in:
Danny Robson 2017-12-26 17:27:36 +11:00
parent 39894b5619
commit a979b253f5
2 changed files with 34 additions and 5 deletions

View File

@ -62,7 +62,7 @@ public:
auto end (void) const { return nullptr; }
private:
std::unique_ptr<addrinfo[],void(*)(addrinfo*)> m_addresses;
std::unique_ptr<addrinfo,void(*)(addrinfo*)> m_addresses;
};
@ -88,6 +88,12 @@ connect_host (const util::view<const char*> host, int port)
///////////////////////////////////////////////////////////////////////////////
socket::socket (int _fd):
fd (_fd)
{ ; }
//-----------------------------------------------------------------------------
socket::socket (int domain, int type):
socket (domain, type, 0)
{ ; }
@ -110,12 +116,28 @@ socket::~socket ()
{ ; }
//-----------------------------------------------------------------------------
socket::socket (socket &&rhs):
fd (std::move (rhs))
{ ; }
//-----------------------------------------------------------------------------
class socket&
socket::operator= (socket &&rhs)
{
fd::operator= (std::move (rhs));
return *this;
}
///////////////////////////////////////////////////////////////////////////////
void
socket::connect (util::view<const char*> host, int port)
{
for (const auto &info: lookup { host, port }) {
if (!::connect (*this, info.ai_addr, info.ai_addrlen))
const lookup l { host, port };
for (auto cursor = l.begin (); cursor != l.end (); cursor = cursor->ai_next) {
if (!::connect (*this, cursor->ai_addr, cursor->ai_addrlen))
return;
}

View File

@ -28,24 +28,31 @@
namespace util::posix {
class socket : public fd {
public:
explicit socket (int _fd);
socket (int domain, int type);
socket (int domain, int type, int protocol);
socket (util::view<const char*> host, int port);
void connect (util::view<const char*> host, int port);
socket (const socket&) = delete;
socket& operator= (const socket&) = delete;
socket (socket &&rhs);
socket& operator= (socket &&);
// the destructor is provided so that we can operate more cleanly on
// win32 where we must call closesocket instead of the normal close.
// because windows...
~socket ();
void connect (util::view<const char*> host, int port);
void shutdown ();
template <typename ValueT>
void setoption (int _level, int _name, const ValueT &_value)
{
error::try_code (
error::try_value (
setsockopt (
native (),
_level,