From 7597281b440366355c812ede250ea2d1d0761d14 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Mon, 6 May 2013 03:20:34 +0000 Subject: [PATCH] https://issues.shibboleth.net/jira/browse/SSPCPP-552 --- shibsp/remoting/impl/TCPListener.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/shibsp/remoting/impl/TCPListener.cpp b/shibsp/remoting/impl/TCPListener.cpp index 5f07611..02df8e4 100644 --- a/shibsp/remoting/impl/TCPListener.cpp +++ b/shibsp/remoting/impl/TCPListener.cpp @@ -88,6 +88,7 @@ namespace shibsp { string m_address; unsigned short m_port; vector m_acl; + size_t m_sockaddrlen; #ifdef HAVE_STRUCT_SOCKADDR_STORAGE struct sockaddr_storage m_sockaddr; #else @@ -157,15 +158,16 @@ bool TCPListener::setup_tcp_sockaddr() return false; } + m_sockaddrlen = ret->ai_addrlen; if (ret->ai_family == AF_INET) { - memcpy(&m_sockaddr, ret->ai_addr, ret->ai_addrlen); + memcpy(&m_sockaddr, ret->ai_addr, m_sockaddrlen); freeaddrinfo(ret); ((struct sockaddr_in*)&m_sockaddr)->sin_port=htons(m_port); return true; } #if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_STORAGE) else if (ret->ai_family == AF_INET6) { - memcpy(&m_sockaddr, ret->ai_addr, ret->ai_addrlen); + memcpy(&m_sockaddr, ret->ai_addr, m_sockaddrlen); freeaddrinfo(ret); ((struct sockaddr_in6*)&m_sockaddr)->sin6_port=htons(m_port); return true; @@ -200,14 +202,14 @@ bool TCPListener::bind(ShibSocket& s, bool force) const ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt)); #ifdef WIN32 - if (SOCKET_ERROR==::bind(s, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) || SOCKET_ERROR==::listen(s, 3)) { + if (SOCKET_ERROR==::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddrlen) || SOCKET_ERROR==::listen(s, 3)) { log_error("bind"); close(s); return false; } #else - // Newer BSDs require the struct length be passed based on the socket address. - // Others have no field for that and take the whole struct size like Windows does. + // Newer BSDs, and Solaris, require the struct length be passed based on the socket address. + // All but Solaris seem to have an ss_len field in the sockaddr_storage struct. # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN # ifdef HAVE_STRUCT_SOCKADDR_STORAGE if (::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.ss_len) < 0) { @@ -215,7 +217,7 @@ bool TCPListener::bind(ShibSocket& s, bool force) const if (::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.sin_len) < 0) { # endif # else - if (::bind(s, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) < 0) { + if (::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddrlen) < 0) { # endif log_error("bind"); close(s); @@ -229,7 +231,7 @@ bool TCPListener::bind(ShibSocket& s, bool force) const bool TCPListener::connect(ShibSocket& s) const { #ifdef WIN32 - if(SOCKET_ERROR==::connect(s, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr))) + if(SOCKET_ERROR==::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddrlen)) return log_error("connect"); #else // Newer BSDs require the struct length be passed based on the socket address. @@ -241,7 +243,7 @@ bool TCPListener::connect(ShibSocket& s) const if (::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.sin_len) < 0) # endif # else - if (::connect(s, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) < 0) + if (::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddrlen) < 0) # endif return log_error("connect"); #endif -- 2.1.4