32 namespace AddressLocalImp
34 constexpr std::size_t minsize()
36 #if GCONFIG_HAVE_UDS_LEN
37 return offsetof( sockaddr_un , sun_family ) +
sizeof( sockaddr_un::sun_family ) ;
39 return sizeof( sockaddr_un::sun_family ) ;
42 void setsize( sockaddr_un & a )
noexcept
44 #if GCONFIG_HAVE_UDS_LEN
45 a.sun_len = SUN_LEN( &a ) ;
47 GDEF_IGNORE_PARAM( a ) ;
50 constexpr std::size_t psize() noexcept
52 return sizeof( sockaddr_un::sun_path ) ;
54 constexpr std::size_t poffset() noexcept
56 return offsetof( sockaddr_un , sun_path ) ;
58 std::size_t strnlen(
const char * p , std::size_t limit )
noexcept
61 for( ; p && *p && n < limit ; ++p )
68unsigned short GNet::AddressLocal::af() noexcept
73int GNet::AddressLocal::domain() noexcept
78GNet::AddressLocal::AddressLocal( std::nullptr_t ) :
80 m_size(AddressLocalImp::minsize())
82 namespace imp = AddressLocalImp ;
83 m_local.sun_family = af() ;
84 std::memset( m_local.sun_path , 0 , AddressLocalImp::psize() ) ;
85 imp::setsize( m_local ) ;
88GNet::AddressLocal::AddressLocal(
unsigned int ) :
93GNet::AddressLocal::AddressLocal(
unsigned int ,
int ) :
98GNet::AddressLocal::AddressLocal(
const sockaddr * addr , socklen_t len ) :
101 namespace imp = AddressLocalImp ;
102 std::size_t size =
static_cast<std::size_t
>( len ) ;
104 if( addr ==
nullptr || size < imp::minsize() || size >
sizeof(sockaddr_type) )
105 throw Address::Error(
"invalid unix domain sockaddr" ) ;
107 if( addr->sa_family != af() )
108 throw Address::BadFamily() ;
110 std::memcpy( &m_local , addr , size ) ;
112 if( size <= imp::poffset() )
115 m_size = imp::minsize() ;
117 else if( G::is_linux() && m_local.sun_path[0] ==
'\0' )
127 if( size ==
sizeof(sockaddr_type) )
129 const char * p = &m_local.sun_path[0] ;
130 const char * end = p + imp::psize() ;
131 if( std::find( p , end , 0 ) == end )
132 throw Address::Error(
"unix domain path too long" ) ;
137 throw Address::BadString(
"invalid unix domain socket path" ) ;
141 m_size = imp::poffset() + std::strlen( &m_local.sun_path[0] ) + 1U ;
142 G_ASSERT( m_size <= size ) ;
144 imp::setsize( m_local ) ;
148GNet::AddressLocal::AddressLocal( std::string_view host_part ) :
149 AddressLocal(nullptr)
151 namespace imp = AddressLocalImp ;
153 if( host_part.empty() || host_part.at(0) !=
'/' )
154 throw Address::BadString() ;
157 throw Address::BadString() ;
159 if( host_part.size() >= imp::psize() )
160 throw Address::BadString(
"unix domain address too long" ) ;
162 std::memcpy( &m_local.sun_path[0] , host_part.data() , host_part.size() ) ;
163 imp::setsize( m_local ) ;
164 m_size = imp::poffset() + host_part.size() + 1U ;
167std::string GNet::AddressLocal::path()
const
169 namespace imp = AddressLocalImp ;
170 if( m_size <= imp::poffset() )
172 return std::string( 1U ,
'/' ) ;
174 else if( G::is_linux() && m_local.sun_path[0] ==
'\0' )
176 return { &m_local.sun_path[0] , m_size-imp::poffset() } ;
180 std::string p = std::string( &m_local.sun_path[0] , imp::strnlen( &m_local.sun_path[0] , std::min(m_size-imp::poffset(),imp::psize()) ) ) ;
181 return p.empty() ? std::string(1U,
'/') : p ;
185void GNet::AddressLocal::setPort(
unsigned int )
189bool GNet::AddressLocal::setZone( std::string_view )
194void GNet::AddressLocal::setScopeId(
unsigned long )
198std::string GNet::AddressLocal::displayString(
bool )
const
203std::string GNet::AddressLocal::hostPartString()
const
208std::string GNet::AddressLocal::queryString()
const
213bool GNet::AddressLocal::validData(
const sockaddr * addr , socklen_t len )
215 return addr !=
nullptr && addr->sa_family == af() && len >= AddressLocalImp::minsize() && len <=
sizeof(sockaddr_type) ;
218bool GNet::AddressLocal::validString( std::string_view path , std::string * reason_p )
220 const char * reason = nullptr ;
221 if( path.size() > AddressLocalImp::psize() )
222 reason =
"local-domain address too long" ;
224 reason =
"empty string" ;
226 reason =
"not an absolute filesystem path" ;
228 reason =
"invalid characters" ;
229 if( reason && reason_p )
230 *reason_p = std::string( reason ) ;
231 return reason == nullptr ;
234bool GNet::AddressLocal::validStrings( std::string_view host_part , std::string_view ,
235 std::string * reason_p )
237 return validString( host_part , reason_p ) ;
241bool GNet::AddressLocal::validPort(
unsigned int )
247bool GNet::AddressLocal::same(
const AddressLocal & other ,
bool )
const
249 G_ASSERT( m_local.sun_family == af() ) ;
251 m_local.sun_family == other.m_local.sun_family &&
252 m_size == other.m_size &&
253 path() == other.path() ;
256bool GNet::AddressLocal::sameHostPart(
const AddressLocal & other )
const
258 return same( other ) ;
261unsigned int GNet::AddressLocal::port()
const
266unsigned long GNet::AddressLocal::scopeId(
unsigned long default_ )
const
272const sockaddr * GNet::AddressLocal::address()
const
274 return reinterpret_cast<const sockaddr*
>(&m_local) ;
278sockaddr * GNet::AddressLocal::address()
280 return reinterpret_cast<sockaddr*
>(&m_local) ;
283socklen_t GNet::AddressLocal::length() const noexcept
290 return { displayString() } ;
294bool GNet::AddressLocal::format(
const std::string & )
300bool GNet::AddressLocal::isLocal( std::string & )
const
305bool GNet::AddressLocal::isLoopback()
const
310bool GNet::AddressLocal::isLinkLocal()
const
315bool GNet::AddressLocal::isUniqueLocal()
const
320bool GNet::AddressLocal::isMulticast()
const
325bool GNet::AddressLocal::isAny()
const
327 return path().empty() ;
330unsigned int GNet::AddressLocal::bits()
const
static bool isPrintable(std::string_view s) noexcept
Returns true if every character is 0x20 or above but not 0x7f.
std::vector< std::string > StringArray
A std::vector of std::strings.