Skip to content
Snippets Groups Projects
Commit cf6ffc4c authored by sbund's avatar sbund
Browse files

implemented further protocol methods

parent 585b287a
No related branches found
No related tags found
No related merge requests found
// $Id$
//
// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// Definition of non-inline non-template functions
#include "BSDSocketProtocol.hh"
//#include "BSDSocketProtocol.ih"
// Custom includes
#include <sys/types.h>
#include <sys/socket.h>
#include "SocketHandle.hh"
//#include "BSDSocketProtocol.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ bool satcom::lib::BSDSocketProtocol::reuseaddr()
const
{
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0)
throw SystemException(errno);
return value;
}
prefix_ void satcom::lib::BSDSocketProtocol::reuseaddr(bool value)
const
{
// FIXME: This is only relevant for addressable sockets (not for e.g. socketpair)
int ivalue (value);
if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0)
throw SystemException(errno);
}
prefix_ std::pair<bool,unsigned> satcom::lib::BSDSocketProtocol::linger()
{
// FIXME: This is really only relevant for stream sockets ...
// TODO: Can the linger timeout be 0 or -1 and what does that mean?
struct linger ling;
socklen_t len = sizeof(ling);
if (::getsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,&len) < 0)
throw SystemException(errno);
return std::make_pair(ling.l_onoff,ling.l_linger);
}
prefix_ void satcom::lib::BSDSocketProtocol::linger(bool enable, unsigned timeout)
{
struct linger ling;
ling.l_onoff = enable;
ling.l_linger = timeout;
if (::setsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling)) < 0)
throw SystemException(errno);
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "BSDSocketProtocol.mpp"
// Local Variables:
// mode: c++
// c-file-style: "satcom"
// End:
// $Id$
//
// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HH_BSDSocketProtocol_
#define HH_BSDSocketProtocol_ 1
// Custom includes
#include "SocketProtocol.hh"
//#include "BSDSocketProtocol.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace satcom {
namespace lib {
class BSDSocketProtocol
: public virtual SocketProtocolHelper
{
public:
bool reuseaddr() const;
void reuseaddr(bool value) const;
std::pair<bool,unsigned> linger();
void linger(bool enable, unsigned timeout);
};
}}
///////////////////////////////hh.e////////////////////////////////////////
//#include "BSDSocketProtocol.cci"
//#include "BSDSocketProtocol.ct"
//#include "BSDSocketProtocol.cti"
//#include "BSDSocketProtocol.mpp"
#endif
// Local Variables:
// mode: c++
// c-file-style: "satcom"
// End:
...@@ -27,12 +27,17 @@ ...@@ -27,12 +27,17 @@
// Custom includes // Custom includes
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h> // for if_nametoindex
#include "Utils/Exception.hh" #include "Utils/Exception.hh"
//#include "INetProtocol.mpp" //#include "INetProtocol.mpp"
#define prefix_ #define prefix_
///////////////////////////////cc.p//////////////////////////////////////// ///////////////////////////////cc.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// satcom::lib::INet4AddressingPolicy
prefix_ void satcom::lib::INet4AddressingPolicy::local(FileHandle handle, Address & addr) prefix_ void satcom::lib::INet4AddressingPolicy::local(FileHandle handle, Address & addr)
{ {
addr.clear(); addr.clear();
...@@ -58,10 +63,117 @@ prefix_ void satcom::lib::INet4AddressingPolicy::do_peer(FileHandle handle, Addr ...@@ -58,10 +63,117 @@ prefix_ void satcom::lib::INet4AddressingPolicy::do_peer(FileHandle handle, Addr
prefix_ void satcom::lib::INet4AddressingPolicy::do_connect(FileHandle handle, prefix_ void satcom::lib::INet4AddressingPolicy::do_connect(FileHandle handle,
Address const & addr) Address const & addr)
{ {
// FIXME: a non-blocking socket will return with EINPROGRESS
// This necessitates reading the SO_ERROR value and poll-ing for
// completion !! (see man connect)
if (::connect(handle.fd(),addr.sockaddr_p(),addr.sockaddr_len()) < 0) if (::connect(handle.fd(),addr.sockaddr_p(),addr.sockaddr_len()) < 0)
throw SystemException(errno); throw SystemException(errno);
} }
///////////////////////////////////////////////////////////////////////////
// satcom::lib::INet4Protocol
prefix_ void satcom::lib::IPv4Protocol::connect(INet4Address const & address)
const
{
if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
throw SystemException(errno);
}
prefix_ void satcom::lib::IPv4Protocol::bind(INet4Address const & address)
const
{
if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
throw SystemException(errno);
}
prefix_ bool satcom::lib::IPv4Protocol::mcLoop()
{
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0)
throw SystemException(errno);
return value;
}
prefix_ void satcom::lib::IPv4Protocol::mcLoop(bool value)
{
int ivalue (value);
if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0)
throw SystemException(errno);
}
prefix_ void satcom::lib::IPv4Protocol::mcAddMembership(INet4Address const & mcAddr)
{
struct ip_mreqn mreqn;
mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
mreqn.imr_address.s_addr = htons(INADDR_ANY);
mreqn.imr_ifindex = 0;
if (::setsockopt(body().fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
throw SystemException(errno);
}
prefix_ void satcom::lib::IPv4Protocol::mcAddMembership(INet4Address const & mcAddr,
INet4Address const & localAddr)
{
struct ip_mreqn mreqn;
mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
mreqn.imr_address = reinterpret_cast<struct sockaddr_in const *>(localAddr.sockaddr_p())->sin_addr;
mreqn.imr_ifindex = 0;
if (::setsockopt(body().fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
throw SystemException(errno);
}
prefix_ void satcom::lib::IPv4Protocol::mcDropMembership(INet4Address const & mcAddr)
{
struct ip_mreqn mreqn;
mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
mreqn.imr_address.s_addr = htons(INADDR_ANY);
mreqn.imr_ifindex = 0;
if (::setsockopt(body().fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
throw SystemException(errno);
}
prefix_ void satcom::lib::IPv4Protocol::mcDropMembership(INet4Address const & mcAddr,
INet4Address const & localAddr)
{
struct ip_mreqn mreqn;
mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
mreqn.imr_address = reinterpret_cast<struct sockaddr_in const *>(localAddr.sockaddr_p())->sin_addr;
mreqn.imr_ifindex = 0;
if (::setsockopt(body().fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
throw SystemException(errno);
}
prefix_ void satcom::lib::IPv4Protocol::mcIface(std::string iface)
{
struct ip_mreqn mreqn;
::memset(&mreqn,sizeof(mreqn),0);
if (!iface.empty()) {
mreqn.imr_ifindex = if_nametoindex(iface.c_str());
if (mreqn.imr_ifindex == 0)
throw SystemException(EINVAL);
}
if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0)
throw SystemException(errno);
}
prefix_ unsigned satcom::lib::IPv4Protocol::mcTTL()
{
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0)
throw SystemException(errno);
return value;
}
prefix_ void satcom::lib::IPv4Protocol::mcTTL(unsigned value)
{
if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0)
throw SystemException(errno);
}
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_ #undef prefix_
//#include "INetProtocol.mpp" //#include "INetProtocol.mpp"
......
...@@ -20,10 +20,13 @@ ...@@ -20,10 +20,13 @@
// Free Software Foundation, Inc., // Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// TODO: what about OOB data? das OOB Data block receipt of normal data ?
#ifndef HH_INetProtocol_ #ifndef HH_INetProtocol_
#define HH_INetProtocol_ 1 #define HH_INetProtocol_ 1
// Custom includes // Custom includes
#include "SocketProtocol.hh"
#include "SocketPolicy.hh" #include "SocketPolicy.hh"
#include "INetAddress.hh" #include "INetAddress.hh"
#include "ClientSocketHandle.hh" #include "ClientSocketHandle.hh"
...@@ -62,9 +65,35 @@ namespace lib { ...@@ -62,9 +65,35 @@ namespace lib {
}; };
class IPv4Protocol class IPv4Protocol
{}; : public virtual SocketProtocolHelper
{
public:
void connect(INet4Address const & address) const;
void bind(INet4Address const & address) const;
unsigned mcTTL();
void mcTTL(unsigned value);
bool mcLoop();
void mcLoop(bool value);
// TODO: Implement real INet4Address datatype and
// rename this one to INet4SockAddress ...
// TODO: Is it safe, not to allow setting the interface
// index on add/drop? what does it do (especially if
// the local addres is given ?)
void mcAddMembership(INet4Address const & mcAddr);
void mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr);
void mcDropMembership(INet4Address const & mcAddr);
void mcDropMembership(INet4Address const & mcAddr, INet4Address const & localAddr);
void mcIface(std::string iface = std::string());
};
class IPv6Protocol class IPv6Protocol
: public virtual SocketProtocolHelper
{}; {};
}} }}
......
...@@ -30,14 +30,14 @@ ...@@ -30,14 +30,14 @@
#define prefix_ inline #define prefix_ inline
///////////////////////////////cci.p/////////////////////////////////////// ///////////////////////////////cci.p///////////////////////////////////////
prefix_ satcom::lib::SocketProtocol::SocketProtocol() prefix_ satcom::lib::SocketProtocolHelper::SocketProtocolHelper()
: body_() : body_()
{} {}
prefix_ satcom::lib::SocketProtocol::~SocketProtocol() prefix_ satcom::lib::SocketProtocolHelper::~SocketProtocolHelper()
{} {}
prefix_ satcom::lib::SocketBody & satcom::lib::SocketProtocol::body() prefix_ satcom::lib::SocketBody & satcom::lib::SocketProtocolHelper::body()
const const
{ {
BOOST_ASSERT( body_ ); BOOST_ASSERT( body_ );
......
...@@ -36,11 +36,24 @@ namespace lib { ...@@ -36,11 +36,24 @@ namespace lib {
class FileHandle; class FileHandle;
class SocketPolicyBase; class SocketPolicyBase;
/** \brief class SocketProtocolHelper
*/
class SocketProtocol
: boost::noncopyable : boost::noncopyable
{ {
public:
SocketProtocolHelper();
virtual ~SocketProtocolHelper() = 0;
SocketBody & body() const;
private:
SocketBody * body_;
friend class SocketBody;
};
class SocketProtocol
: public virtual SocketProtocolHelper
{
public: public:
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Types // Types
...@@ -49,17 +62,13 @@ namespace lib { ...@@ -49,17 +62,13 @@ namespace lib {
///\name Structors and default members ///\name Structors and default members
///@{ ///@{
SocketProtocol(); // default default constructor
virtual ~SocketProtocol() = 0;
// no default constructor
// no copy // no copy
// no conversion constructors // no conversion constructors
///@} ///@}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
SocketBody & body() const;
virtual SocketPolicyBase const & policy() const = 0; virtual SocketPolicyBase const & policy() const = 0;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
...@@ -74,9 +83,6 @@ namespace lib { ...@@ -74,9 +83,6 @@ namespace lib {
private: private:
// That SocketBody instance owns us and controls our lifetime // That SocketBody instance owns us and controls our lifetime
// Do we need this ?? // Do we need this ??
SocketBody * body_;
friend class SocketBody;
}; };
/** \brief /** \brief
......
// $Id$
//
// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// Definition of non-inline non-template functions
#include "TCPProtocol.hh"
//#include "TCPProtocol.ih"
// Custom includes
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <linux/sockios.h> // for SIOCINQ / SIOCOUTQ
#include "SocketHandle.hh"
//#include "TCPProtocol.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ bool satcom::lib::TCPProtocol::nodelay()
const
{
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&value,&len) < 0)
throw SystemException(errno);
return value;
}
prefix_ void satcom::lib::TCPProtocol::nodelay(bool value)
const
{
int ivalue (value);
if (::setsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&ivalue,sizeof(ivalue)) < 0)
throw SystemException(errno);
}
prefix_ unsigned satcom::lib::TCPProtocol::siocinq()
const
{
int n;
if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
throw SystemException(errno);
return n;
}
prefix_ unsigned satcom::lib::TCPProtocol::siocoutq()
const
{
int n;
if (::ioctl(body().fd(),SIOCOUTQ,&n) < 0)
throw SystemException(errno);
return n;
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "TCPProtocol.mpp"
// Local Variables:
// mode: c++
// c-file-style: "satcom"
// End:
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define HH_TCPProtocol_ 1 #define HH_TCPProtocol_ 1
// Custom includes // Custom includes
#include "SocketProtocol.hh"
//#include "TCPProtocol.mpp" //#include "TCPProtocol.mpp"
///////////////////////////////hh.p//////////////////////////////////////// ///////////////////////////////hh.p////////////////////////////////////////
...@@ -32,7 +33,15 @@ namespace satcom { ...@@ -32,7 +33,15 @@ namespace satcom {
namespace lib { namespace lib {
class TCPProtocol class TCPProtocol
{}; : public virtual SocketProtocolHelper
{
public:
bool nodelay() const;
void nodelay(bool value) const;
unsigned siocinq() const;
unsigned siocoutq() const;
};
}} }}
......
...@@ -36,24 +36,6 @@ ...@@ -36,24 +36,6 @@
#define prefix_ #define prefix_
///////////////////////////////cc.p//////////////////////////////////////// ///////////////////////////////cc.p////////////////////////////////////////
prefix_ bool satcom::lib::TCPv4SocketProtocol::reuseraddr()
const
{
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0)
throw SystemException(errno);
return value;
}
prefix_ void satcom::lib::TCPv4SocketProtocol::reuseaddr(bool value)
const
{
int ivalue (value);
if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0)
throw SystemException(errno);
}
prefix_ void satcom::lib::TCPv4SocketProtocol::init_client() prefix_ void satcom::lib::TCPv4SocketProtocol::init_client()
const const
{ {
...@@ -91,20 +73,6 @@ satcom::lib::TCPv4SocketProtocol::init_server(INet4Address const & address) ...@@ -91,20 +73,6 @@ satcom::lib::TCPv4SocketProtocol::init_server(INet4Address const & address)
throw SystemException(errno); throw SystemException(errno);
} }
prefix_ void satcom::lib::TCPv4SocketProtocol::connect(INet4Address const & address)
const
{
if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
throw SystemException(errno);
}
prefix_ void satcom::lib::TCPv4SocketProtocol::bind(INet4Address const & address)
const
{
if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
throw SystemException(errno);
}
prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::TCPv4SocketProtocol::clone() prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::TCPv4SocketProtocol::clone()
const const
{ {
...@@ -114,10 +82,7 @@ prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::TCPv4SocketProto ...@@ -114,10 +82,7 @@ prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::TCPv4SocketProto
prefix_ unsigned satcom::lib::TCPv4SocketProtocol::available() prefix_ unsigned satcom::lib::TCPv4SocketProtocol::available()
const const
{ {
int n; return siocinq();
if (::ioctl(body().fd(),FIONREAD,&n) < 0)
throw SystemException(errno);
return n;
} }
prefix_ bool satcom::lib::TCPv4SocketProtocol::eof() prefix_ bool satcom::lib::TCPv4SocketProtocol::eof()
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
// Custom includes // Custom includes
#include "INetProtocol.hh" #include "INetProtocol.hh"
#include "TCPProtocol.hh" #include "TCPProtocol.hh"
#include "BSDSocketProtocol.hh"
#include "StreamFramingPolicy.hh" #include "StreamFramingPolicy.hh"
#include "CommunicationPolicy.hh" #include "CommunicationPolicy.hh"
#include "ReadWritePolicy.hh" #include "ReadWritePolicy.hh"
...@@ -51,12 +52,10 @@ namespace lib { ...@@ -51,12 +52,10 @@ namespace lib {
class TCPv4SocketProtocol class TCPv4SocketProtocol
: public ConcreteSocketProtocol<TCPv4Socket_Policy>, : public ConcreteSocketProtocol<TCPv4Socket_Policy>,
public IPv4Protocol, public IPv4Protocol,
public TCPProtocol public TCPProtocol,
public BSDSocketProtocol
{ {
public: public:
bool reuseraddr() const;
void reuseaddr(bool value) const;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// internal interface // internal interface
...@@ -65,9 +64,6 @@ namespace lib { ...@@ -65,9 +64,6 @@ namespace lib {
void init_server() const; void init_server() const;
void init_server(INet4Address const & address) const; void init_server(INet4Address const & address) const;
void connect(INet4Address const & address) const;
void bind(INet4Address const & address) const;
std::auto_ptr<SocketProtocol> clone() const; std::auto_ptr<SocketProtocol> clone() const;
unsigned available() const; unsigned available() const;
bool eof() const; bool eof() const;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment