try {
for (int i=0; i<=1000; i++) {
senf::TCPv4ClientSocketHandle sock;
- sock.connect(senf::INet4SocketAddress("127.0.0.1", 4243));
+ sock.connect(senf::INet4SocketAddress("127.0.0.1:4243"));
sock.protocol().linger(true);
std::stringstream s;
senf::TCPv4ServerSocketHandle serverSock;
public:
- Server(std::string const & host, unsigned int port)
+ Server(senf::INet4Address const & host, unsigned int port)
: serverSock(senf::INet4SocketAddress(host, port)) {}
void run()
int main(int argc, char const * argv[])
{
try {
- Server myServer ("127.0.0.1", 4243);
+ Server myServer (senf::INet4Address::Loopback, 4243);
myServer.run();
}
catch (std::exception const & ex) {
{
senf::INet4Address addr (senf::INet4Address::from_string("127.0.0.1"));
BOOST_CHECK_EQUAL( addr, senf::INet4Address::Loopback );
+ BOOST_CHECK( addr != senf::INet4Address::Broadcast );
addr = senf::INet4Address::from_string("localhost");
BOOST_CHECK_EQUAL( addr, senf::INet4Address::Loopback );
///////////////////////////////////////////////////////////////////////////
// senf::INet4Address
-prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & host, unsigned port)
+prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & addr)
{
clear();
- /** \todo gethostbyname support */
- if (::inet_aton(host.c_str(), &addr_.sin_addr) == 0)
- throw InvalidINetAddressException();
- addr_.sin_port = htons(port);
+ unsigned i = addr.find(':');
+ if (i == std::string::npos)
+ throw SyntaxException();
+ address(INet4Address::from_string(std::string(addr,0,i)));
+ try {
+ port(boost::lexical_cast< ::u_int16_t >(std::string(addr,i+1)));
+ }
+ catch (boost::bad_lexical_cast const &) {
+ throw SyntaxException();
+ }
}
-prefix_ std::string senf::INet4SocketAddress::str()
- const
+prefix_ senf::INet4SocketAddress::INet4SocketAddress(INet4Address const & addr, unsigned p)
{
- std::stringstream s;
- s << host() << ':' << port();
- return s.str();
+ clear();
+ address(addr);
+ port(p);
}
prefix_ void senf::INet4SocketAddress::clear()
addr_.sin_family = AF_INET;
}
-prefix_ void senf::INet4SocketAddress::assignString(std::string const & address)
-{
- clear();
- unsigned i = address.find(':');
- if (i == std::string::npos)
- throw InvalidINetAddressException();
- // The temporary string in the next expr is guaranteed to live
- // until end-of-statement
- if (::inet_aton(std::string(address,0,i).c_str(), &addr_.sin_addr) == 0)
- throw InvalidINetAddressException();
- try {
- // Replace lexical_cast with strtoul ?
- addr_.sin_port = htons(boost::lexical_cast< ::u_int16_t >(std::string(address,i+1)));
- }
- catch (boost::bad_lexical_cast const &) {
- throw InvalidINetAddressException();
- }
-}
-
///////////////////////////////////////////////////////////////////////////
// senf::INet6Address
prefix_ senf::INet6Address::INet6Address(std::string const & addr)
{
if (inet_pton(AF_INET6,addr.c_str(),&addr_) <= 0)
- throw InvalidINetAddressException();
+ throw SyntaxException();
}
prefix_ senf::INet6Address::INet6Address(char const * addr)
{
if (inet_pton(AF_INET6,addr,&addr_) <= 0)
- throw InvalidINetAddressException();
+ throw SyntaxException();
}
prefix_ void senf::INet6Address::clear()
|| inet_pton(AF_INET6, std::string(boost::begin(*token),boost::end(*token)).c_str(),
&sockaddr_.sin6_addr) <= 0
|| ++token == tokens.end())
- throw InvalidINetAddressException();
+ throw SyntaxException();
if (*token == "@") {
if (++token == tokens.end())
- throw InvalidINetAddressException();
+ throw SyntaxException();
assignIface(std::string(boost::begin(*token),boost::end(*token)));
if (++token == tokens.end()
|| *token != "]")
- throw InvalidINetAddressException();
+ throw SyntaxException();
} else if (*token != "]")
- throw InvalidINetAddressException();
+ throw SyntaxException();
if (++token == tokens.end()
|| *boost::begin(*token) != ':')
- throw InvalidINetAddressException();
+ throw SyntaxException();
try {
sockaddr_.sin6_port = htons(
boost::lexical_cast<unsigned>(std::string(boost::next(boost::begin(*token)),
boost::end(*token))));
} catch(boost::bad_lexical_cast const &) {
- throw InvalidINetAddressException();
+ throw SyntaxException();
}
if (++token != tokens.end())
- throw InvalidINetAddressException();
+ throw SyntaxException();
}
prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface)
else {
sockaddr_.sin6_scope_id = if_nametoindex(iface.c_str());
if (sockaddr_.sin6_scope_id == 0)
- throw InvalidINetAddressException();
+ throw SyntaxException();
}
}
clear();
}
-prefix_ senf::INet4SocketAddress::INet4SocketAddress(char const * address)
-{
- assignString(address);
-}
-
-prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & address)
-{
- assignString(address);
-}
-
prefix_ bool senf::INet4SocketAddress::operator==(INet4SocketAddress const & other)
const
{
addr_.sin_addr.s_addr == other.addr_.sin_addr.s_addr;
}
-prefix_ std::string senf::INet4SocketAddress::host()
+prefix_ senf::INet4Address senf::INet4SocketAddress::address()
const
{
- char buffer[128];
- return std::string(::inet_ntop(AF_INET,&addr_.sin_addr,buffer,128));
+ return INet4Address::from_inaddr(addr_.sin_addr.s_addr);
}
prefix_ unsigned senf::INet4SocketAddress::port()
return ntohs(addr_.sin_port);
}
+prefix_ bool senf::INet4SocketAddress::boolean_test()
+ const
+{
+ return port() || address();
+}
+
+prefix_ void senf::INet4SocketAddress::address(INet4Address const & addr)
+{
+ addr_.sin_addr.s_addr = addr.inaddr();
+}
+
+prefix_ void senf::INet4SocketAddress::port(unsigned p)
+{
+ addr_.sin_port = htons(p);
+}
+
prefix_ struct sockaddr * senf::INet4SocketAddress::sockaddr_p()
{
return reinterpret_cast<struct sockaddr *>(&addr_);
prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr)
{
- os << addr.str();
+ os << addr.address() << ":" << addr.port();
return os;
}
for (; p!=p_end && i!=i_end; ++p, ++i)
*p = *i;
if (p!=p_end || i!=i_end)
- throw InvalidINetAddressException();
+ throw SyntaxException();
}
///////////////////////////////ct.e////////////////////////////////////////
#include <string>
#include <exception>
#include <netinet/in.h>
+#include <boost/operators.hpp>
#include "Socket/SocketPolicy.hh"
#include "Socket/ClientSocketHandle.hh"
#include "Socket/CommunicationPolicy.hh"
#include "Socket/Protocols/GenericAddressingPolicy.hh"
+#include "INet4Address.hh"
//#include "INetAddressing.mpp"
///////////////////////////////hh.p////////////////////////////////////////
INet4Address wraps the standard sockaddr_in datatype. It provides simple accessor methods
to access the host and port. It does \e not integrate \c gethostbyname or DNS lookup.
-
- \todo Implement real INet4Address datatype and rename this one to INet4SockAddress ...
- \todo Implement more complete interface
- \todo gethostbyname support ?
+
+ \implementation This implementation is based on sockaddr_in, which is needed since it needs
+ to provide a non-const struct sockaddr * for legacy compatibility.
*/
class INet4SocketAddress
+ : public boost::equality_comparable<INet4SocketAddress>,
+ public senf::ComparableSafeBool<INet4SocketAddress>
{
public:
INet4SocketAddress();
- INet4SocketAddress(char const * address); ///< Set address and port
- /**< See INet4SocketAddress(std::string)
- \throws InvalidINetAddressException */
- INet4SocketAddress(std::string const & address); ///< Set address and port
+ explicit INet4SocketAddress(std::string const & address); ///< Set address and port
/**< This constructor expects a string of the form
- 'xxx.xxx.xxx.xxx:pppp'. The constructor will use this
- value to initialize the host and port members. This
- constructor does \e only support numeric ip addresses
- not hostnames
- \param[in] address Address and port
- \throws InvalidINetAddressException */
- INet4SocketAddress(std::string const & host, unsigned port);
+ 'host:port'. The constructor will use this value to
+ initialize the host and port members. Since it uses the
+ INet4Address::from_string constructor, this call may
+ block while waiting for the resolver.
+ \throws SyntaxException if the 'host:port' syntax is
+ not obeyed.
+ \throws INet4Address::SyntaxException if the host part
+ cannot be converted to an IP address. */
+
+ INet4SocketAddress(INet4Address const & addr, unsigned port);
///< Set address and port explicitly
- /**< \param[in] host ip address in dotted-quad notation
- \param[in] port port number
- \throws InvalidINetAddressException */
-
+ /**< \param[in] addr IP address
+ \param[in] port port number */
bool operator==(INet4SocketAddress const & other) const;
///< Check INet4SocketAddress for equality
- std::string str() const; ///< Return "address:port" string
- std::string host() const; ///< Return address in doted quad notation
- unsigned port() const; ///< Return portnumber
+ INet4Address address() const; ///< Return address
+ unsigned port() const; ///< Return port number
+
+ bool boolean_test() const; ///< \c true, if address is empty (i.e. 0.0.0.0:0)
void clear(); ///< Clear address/port to 0.0.0.0:0
+ void address(INet4Address const & addr); ///< Set address
+ void port(unsigned p); ///< Set port number
+
/// \name Generic Address Interface
/// @{
/// @}
- private:
- void assignString(std::string const & addr);
+ struct SyntaxException : public std::exception
+ { virtual char const * what() const throw()
+ { return "Invalid IpV4 socket address syntax"; } };
+ private:
struct ::sockaddr_in addr_;
};
/** \brief Write address and port to os
- \related INet4Address
+ \related INet4SocketAddress
*/
std::ostream & operator<<(std::ostream & os, INet4SocketAddress const & addr);
///< Get const pointer to internal address repr
unsigned addr_len() const; ///< Size of an IPv6 address (16 bytes)
+ struct SyntaxException : public std::exception
+ { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } };
+
protected:
private:
///@}
+ struct SyntaxException : public std::exception
+ { virtual char const * what() const throw()
+ { return "Invalid IpV6 socket address syntax"; } };
+
protected:
private:
*/
std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr);
- /** \brief Signal invalid INet address syntax
-
- \related INet4Address
- \relatesalso INet6Address
- */
- struct InvalidINetAddressException : public std::exception
- { char const * what() const throw() { return "invalid inet address"; } };
-
/// @}
/// \addtogroup policy_impl_group
BOOST_AUTO_UNIT_TEST(inet4Address)
{
using senf::INet4SocketAddress;
- using senf::InvalidINetAddressException;
+ using senf::INet4Address;
{
INet4SocketAddress addr;
+
+ BOOST_CHECK( ! addr );
- addr = "127.0.0.1:12345";
+ addr = INet4SocketAddress("127.0.0.1:12345");
+ BOOST_CHECK ( addr != INet4SocketAddress() );
}
{
INet4SocketAddress addr1("127.0.0.1:12345");
- INet4SocketAddress addr2(std::string("127.0.0.1:12345"));
- INet4SocketAddress addr3("127.0.0.1",12345);
+ INet4SocketAddress addr3(INet4Address::Loopback,12345);
}
- BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345"), INet4SocketAddress("127.0.0.1",12345) );
+ BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345"),
+ INet4SocketAddress(INet4Address::Loopback,12345) );
- BOOST_CHECK_THROW( INet4SocketAddress("127.0.0.1"), InvalidINetAddressException );
- BOOST_CHECK_THROW( INet4SocketAddress("foo@bar:12345"), InvalidINetAddressException );
- BOOST_CHECK_THROW( INet4SocketAddress("127.0.0.1:1234a"), InvalidINetAddressException );
- BOOST_CHECK_THROW( INet4SocketAddress("foo@bar",12345), InvalidINetAddressException );
+ BOOST_CHECK_THROW( INet4SocketAddress("127.0.0.1"), INet4SocketAddress::SyntaxException );
+ BOOST_CHECK_THROW( INet4SocketAddress("foo@bar:12345"), INet4Address::SyntaxException );
+ BOOST_CHECK_THROW( INet4SocketAddress("127.0.0.1:1234a"), INet4SocketAddress::SyntaxException );
- BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345").host(), "127.0.0.1" );
+ BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345").address(), INet4Address::Loopback );
BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345").port(), 12345u );
- BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345").str(), "127.0.0.1:12345" );
+ BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(INet4SocketAddress("127.0.0.1:12345")),
+ "127.0.0.1:12345" );
{
INet4SocketAddress addr("127.0.0.1:12345");
{
using senf::INet6Address;
using senf::INet6SocketAddress;
- using senf::InvalidINetAddressException;
{
INet6Address addr1 ("0102:0304:0506:0708:090A:0B0C:0D0E:0F00");
addr1.clear();
addr2 = "::";
BOOST_CHECK_EQUAL( addr1, addr2 );
- BOOST_CHECK_THROW( addr1 = "", InvalidINetAddressException );
+ BOOST_CHECK_THROW( addr1 = "", INet6Address::SyntaxException );
BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr1), "::" );
unsigned char data[] = { 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x21, 0 };
INet6Address addr3 (std::make_pair(&data[0],&data[0]+sizeof(data)-1));
BOOST_CHECK_EQUAL( addr3, "1200::21" );
BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data))),
- InvalidINetAddressException );
+ INet6Address::SyntaxException );
BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data)-2)),
- InvalidINetAddressException );
+ INet6Address::SyntaxException );
}
{
BOOST_CHECK_EQUAL( addr.port(), 100u );
addr.host("::2");
BOOST_CHECK_EQUAL( addr.host(), "::2" );
- BOOST_CHECK_THROW( addr = "", InvalidINetAddressException );
- BOOST_CHECK_THROW( addr = "[::1]", InvalidINetAddressException );
- BOOST_CHECK_THROW( addr = "[::1]1234", InvalidINetAddressException );
+ BOOST_CHECK_THROW( addr = "", INet6SocketAddress::SyntaxException );
+ BOOST_CHECK_THROW( addr = "[::1]", INet6SocketAddress::SyntaxException );
+ BOOST_CHECK_THROW( addr = "[::1]1234", INet6SocketAddress::SyntaxException );
addr = "[12::21@lo]:12345";
BOOST_CHECK_EQUAL( addr.address(), "[12::21@lo]:12345" );
BOOST_CHECK_EQUAL( addr.host(), "12::21" );
{
senf::TCPv4ClientSocketHandle sock;
- BOOST_CHECK_THROW( sock.connect(senf::INet4SocketAddress("127.0.0.1:12345")), senf::SystemException );
- BOOST_CHECK_THROW( sock.protocol().connect("127.0.0.1:12345"), senf::SystemException );
+ BOOST_CHECK_THROW( sock.connect(senf::INet4SocketAddress("127.0.0.1:12345")),
+ senf::SystemException );
+ BOOST_CHECK_THROW( sock.protocol().connect(senf::INet4SocketAddress("127.0.0.1:12345")),
+ senf::SystemException );
}
try {
alarm(10);
start(server_v4);
senf::TCPv4ClientSocketHandle sock;
- BOOST_CHECK_NO_THROW( sock.bind("127.0.0.1:23456") );
- BOOST_CHECK_NO_THROW( sock.connect("127.0.0.1:12345") );
- BOOST_CHECK( sock.peer() == "127.0.0.1:12345" );
- BOOST_CHECK( sock.local() == "127.0.0.1:23456" );
+ BOOST_CHECK_NO_THROW( sock.bind(senf::INet4SocketAddress("127.0.0.1:23456")) );
+ BOOST_CHECK_NO_THROW( sock.connect(senf::INet4SocketAddress("127.0.0.1:12345")) );
+ BOOST_CHECK( sock.peer() == senf::INet4SocketAddress("127.0.0.1:12345") );
+ BOOST_CHECK( sock.local() == senf::INet4SocketAddress("127.0.0.1:23456") );
BOOST_CHECK( sock.blocking() );
BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
try {
alarm(10);
BOOST_CHECKPOINT("Opening server socket");
- senf::TCPv4ServerSocketHandle server ("127.0.0.1:12346");
+ senf::TCPv4ServerSocketHandle server (senf::INet4SocketAddress("127.0.0.1:12346"));
BOOST_CHECKPOINT("Starting client");
start(client_v4);
alarm(10);
start(server_v4);
senf::UDPv4ClientSocketHandle sock;
- BOOST_CHECK_NO_THROW( sock.bind("127.0.0.1:23456") );
- BOOST_CHECK( sock.local() == "127.0.0.1:23456" );
+ BOOST_CHECK_NO_THROW( sock.bind(senf::INet4SocketAddress("127.0.0.1:23456")) );
+ BOOST_CHECK( sock.local() == senf::INet4SocketAddress("127.0.0.1:23456") );
BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
BOOST_CHECK_NO_THROW( sock.sndbuf(2048) );
BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
- BOOST_CHECK_NO_THROW( sock.writeto("127.0.0.1:12345", std::string("TEST-WRITE")) );
+ BOOST_CHECK_NO_THROW( sock.writeto(senf::INet4SocketAddress("127.0.0.1:12345"),
+ std::string("TEST-WRITE")) );
BOOST_CHECK_EQUAL( sock.read(), "TEST-WRITE" );
BOOST_CHECK_NO_THROW( sock.protocol().timestamp() );
- sock.writeto("127.0.0.1:12345","QUIT");
+ sock.writeto(senf::INet4SocketAddress("127.0.0.1:12345"),"QUIT");
sleep(1);
stop();
sleep(1);
s/fontsize=10/fontsize=8/g;
# Wrap long labels (templates)
-if (/label=\"([^"]*)\"/) { #"])){ # To make emacs happy ...
+if (/label=\"([^"]*)\"/) { #"])){ # To make emacs happy ...
$pre=$`;
- $post=$'; #' # To make emacs happy ...
+ $post=$'; #'; # To make emacs happy ...
$label=$1;
# Break at each komma
# If more than one '<' is in the label, break after each '<'
if (($label=~tr/</</)>1) {
- $label=~s/</<\\r\\ \\ \\ \\ \\ \\ \\ \\ /g;
+ $label=~s/</<\\r\\ \\ \\ \\ \\ \\ \\ \\ /g;
}
# If at least one break is in there ...
if ($label=~/\\r/) {
- # Make last line flush right
- $label.="\\r";
- # and first line flush left
- $label=~s/\\r/\\l/;
+ # Make last line flush right
+ $label.="\\r";
+ # and first line flush left
+ $label=~s/\\r/\\ \\ \\ \\ \\ \\ \\ \\ \\l/;
}
print "${pre}label=\"${label}\"${post}";
} else {