summaryrefslogtreecommitdiff
path: root/libcult/cult/os/net
diff options
context:
space:
mode:
Diffstat (limited to 'libcult/cult/os/net')
-rw-r--r--libcult/cult/os/net/address.cxx37
-rw-r--r--libcult/cult/os/net/address.hxx60
-rw-r--r--libcult/cult/os/net/datagram-socket.cxx26
-rw-r--r--libcult/cult/os/net/datagram-socket.hxx57
-rw-r--r--libcult/cult/os/net/ipv4/address.cxx37
-rw-r--r--libcult/cult/os/net/ipv4/address.hxx143
-rw-r--r--libcult/cult/os/net/ipv4/datagram-socket.cxx20
-rw-r--r--libcult/cult/os/net/ipv4/datagram-socket.hxx282
-rw-r--r--libcult/cult/os/net/ipv4/multicast-socket.cxx19
-rw-r--r--libcult/cult/os/net/ipv4/multicast-socket.hxx133
-rw-r--r--libcult/cult/os/net/multicast-socket.cxx26
-rw-r--r--libcult/cult/os/net/multicast-socket.hxx40
-rw-r--r--libcult/cult/os/net/socket.cxx26
-rw-r--r--libcult/cult/os/net/socket.hxx54
14 files changed, 960 insertions, 0 deletions
diff --git a/libcult/cult/os/net/address.cxx b/libcult/cult/os/net/address.cxx
new file mode 100644
index 0000000..7860b29
--- /dev/null
+++ b/libcult/cult/os/net/address.cxx
@@ -0,0 +1,37 @@
+// file : cult/os/net/address.cxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/os/net/address.hxx>
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ Address::
+ Address ()
+ {
+ }
+
+ Address::
+ ~Address ()
+ {
+ }
+
+ Address::
+ Address (Address const&)
+ {
+ }
+
+ Address& Address::
+ operator= (Address const&)
+ {
+ return *this;
+ }
+ }
+ }
+}
+
diff --git a/libcult/cult/os/net/address.hxx b/libcult/cult/os/net/address.hxx
new file mode 100644
index 0000000..2923ec6
--- /dev/null
+++ b/libcult/cult/os/net/address.hxx
@@ -0,0 +1,60 @@
+// file : cult/os/net/address.hxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CULT_OS_NET_ADDRESS_HXX
+#define CULT_OS_NET_ADDRESS_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/os/exception.hxx>
+
+#include <sys/socket.h> // sa_family_t, sockaddr
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ class Address
+ {
+ public:
+ struct Exception: virtual OS::Exception {};
+
+ struct Invalid : virtual Exception {};
+
+ public:
+ Address ();
+
+ virtual
+ ~Address ();
+
+ public:
+ //@@ need to wrap family
+ //
+ virtual sa_family_t
+ familiy () const = 0;
+
+ virtual sockaddr const*
+ raw_addr () const = 0;
+
+ virtual Size
+ raw_size () const = 0;
+
+
+ //@@ Should it be Clonable rather?
+ //
+ protected:
+ Address (Address const&);
+
+ Address&
+ operator= (Address const&);
+ };
+ }
+ }
+}
+
+
+#endif // CULT_OS_NET_ADDRESS_HXX
diff --git a/libcult/cult/os/net/datagram-socket.cxx b/libcult/cult/os/net/datagram-socket.cxx
new file mode 100644
index 0000000..b023b46
--- /dev/null
+++ b/libcult/cult/os/net/datagram-socket.cxx
@@ -0,0 +1,26 @@
+// file : cult/os/net/datagram-socket.cxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/os/net/datagram-socket.hxx>
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ DatagramSocket::
+ DatagramSocket ()
+ {
+ }
+
+ DatagramSocket::
+ ~DatagramSocket ()
+ {
+ }
+ }
+ }
+}
+
diff --git a/libcult/cult/os/net/datagram-socket.hxx b/libcult/cult/os/net/datagram-socket.hxx
new file mode 100644
index 0000000..62d1a07
--- /dev/null
+++ b/libcult/cult/os/net/datagram-socket.hxx
@@ -0,0 +1,57 @@
+// file : cult/os/net/datagram-socket.hxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CULT_OS_NET_DATAGRAM_SOCKET_HXX
+#define CULT_OS_NET_DATAGRAM_SOCKET_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/os/net/address.hxx>
+#include <cult/os/net/socket.hxx>
+
+#include <sys/socket.h> // SOCK_DGRAM
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ class DatagramSocket: public virtual Socket
+ {
+ protected:
+ DatagramSocket ();
+
+ virtual
+ ~DatagramSocket ();
+
+ public:
+ virtual Int
+ type () const
+ {
+ return SOCK_DGRAM;
+ }
+
+ public:
+ virtual Size
+ send (Void const* buf, Size size, Address const& addr) = 0;
+
+ virtual Size
+ recv (Void* buf, Size size) = 0;
+
+ /*
+ virtual Boolean
+ recv (Void* buf,
+ Size size,
+ Size& received,
+ OS::Time const& timeout) = 0;
+ */
+ };
+ }
+ }
+}
+
+
+#endif // CULT_OS_NET_DATAGRAM_SOCKET_HXX
diff --git a/libcult/cult/os/net/ipv4/address.cxx b/libcult/cult/os/net/ipv4/address.cxx
new file mode 100644
index 0000000..2507ed6
--- /dev/null
+++ b/libcult/cult/os/net/ipv4/address.cxx
@@ -0,0 +1,37 @@
+// file : cult/os/net/ipv4/address.cxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/os/net/ipv4/address.hxx>
+
+#include <ostream>
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ namespace IPv4
+ {
+ std::ostream&
+ operator<< (std::ostream& os, Address const& addr)
+ {
+ char str[INET_ADDRSTRLEN];
+
+ if (inet_ntop (AF_INET,
+ &addr.addr_.sin_addr,
+ str,
+ INET_ADDRSTRLEN) == 0)
+ {
+ throw Address::Invalid ();
+ }
+
+ return os << str << ":" << addr.port ();
+ }
+ }
+ }
+ }
+}
+
diff --git a/libcult/cult/os/net/ipv4/address.hxx b/libcult/cult/os/net/ipv4/address.hxx
new file mode 100644
index 0000000..9168507
--- /dev/null
+++ b/libcult/cult/os/net/ipv4/address.hxx
@@ -0,0 +1,143 @@
+// file : cult/os/net/ipv4/address.hxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CULT_OS_NET_IPV4_ADDRESS_HXX
+#define CULT_OS_NET_IPV4_ADDRESS_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/os/net/address.hxx>
+
+#include <netinet/in.h> // IPv4 types (sockaddr_in, etc)
+#include <arpa/inet.h> // hto{n,h}{s,l}, iNet_pton
+
+#include <iosfwd>
+#include <cstring> // memset
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ namespace IPv4
+ {
+ class Address: public Net::Address
+ {
+ public:
+ Address ()
+ {
+ std::memset (&addr_, 0, sizeof (addr_));
+ }
+
+ Address (sockaddr_in const& addr)
+ {
+ if (addr.sin_family != AF_INET)
+ throw Invalid ();
+
+ std::memset (&addr_, 0, sizeof (addr_));
+
+ addr_.sin_family = AF_INET;
+ addr_.sin_addr.s_addr = addr.sin_addr.s_addr;
+ addr_.sin_port = addr.sin_port;
+ }
+
+ Address (in_addr_t host_addr, in_port_t host_port)
+ {
+ std::memset (&addr_, 0, sizeof (addr_));
+
+ addr_.sin_family = AF_INET;
+ addr_.sin_addr.s_addr = htonl (host_addr);
+ addr_.sin_port = htons (host_port);
+ }
+
+ Address (String const& host_addr, in_port_t host_port)
+ {
+ std::memset (&addr_, 0, sizeof (addr_));
+
+ addr_.sin_family = AF_INET;
+ addr_.sin_port = htons (host_port);
+
+ if (inet_pton (AF_INET, host_addr.c_str (), &addr_.sin_addr) <= 0)
+ throw Invalid ();
+ }
+
+ public:
+ virtual sa_family_t
+ familiy () const
+ {
+ return AF_INET;
+ }
+
+ virtual sockaddr const*
+ raw_addr () const
+ {
+ return reinterpret_cast<sockaddr const*> (&addr_);
+ }
+
+ virtual Size
+ raw_size () const
+ {
+ return sizeof (addr_);
+ }
+
+ public:
+ sockaddr_in const&
+ addr () const
+ {
+ return addr_;
+ }
+
+ in_addr_t
+ ip () const
+ {
+ return ntohl (addr_.sin_addr.s_addr);
+ }
+
+ in_port_t
+ port () const
+ {
+ return ntohs (addr_.sin_port);
+ }
+
+ public:
+ friend
+ Boolean
+ operator< (Address const& x, Address const& y)
+ {
+ return (x.addr_.sin_addr.s_addr < y.addr_.sin_addr.s_addr) ||
+ ((x.addr_.sin_addr.s_addr == y.addr_.sin_addr.s_addr) &&
+ (x.addr_.sin_port < y.addr_.sin_port));
+ }
+
+ friend
+ Boolean
+ operator== (Address const& x, Address const& y)
+ {
+ return (x.addr_.sin_addr.s_addr == y.addr_.sin_addr.s_addr) &&
+ (x.addr_.sin_port == y.addr_.sin_port);
+ }
+
+ friend
+ Boolean
+ operator!= (Address const& x, Address const& y)
+ {
+ return !(x == y);
+ }
+
+ friend
+ std::ostream&
+ operator<< (std::ostream&, Address const&);
+
+ private:
+ sockaddr_in addr_;
+ };
+ }
+ }
+ }
+}
+
+
+#endif // CULT_OS_NET_IPV4_ADDRESS_HXX
diff --git a/libcult/cult/os/net/ipv4/datagram-socket.cxx b/libcult/cult/os/net/ipv4/datagram-socket.cxx
new file mode 100644
index 0000000..ce470cc
--- /dev/null
+++ b/libcult/cult/os/net/ipv4/datagram-socket.cxx
@@ -0,0 +1,20 @@
+// file : cult/os/net/ipv4/datagram-socket.cxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/os/net/ipv4/datagram-socket.hxx>
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ namespace IPv4
+ {
+ }
+ }
+ }
+}
+
diff --git a/libcult/cult/os/net/ipv4/datagram-socket.hxx b/libcult/cult/os/net/ipv4/datagram-socket.hxx
new file mode 100644
index 0000000..2aad43f
--- /dev/null
+++ b/libcult/cult/os/net/ipv4/datagram-socket.hxx
@@ -0,0 +1,282 @@
+// file : cult/os/net/ipv4/datagram-socket.hxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CULT_OS_NET_IPV4_DATAGRAM_SOCKET_HXX
+#define CULT_OS_NET_IPV4_DATAGRAM_SOCKET_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/os/net/address.hxx>
+#include <cult/os/net/datagram-socket.hxx>
+#include <cult/os/net/ipv4/address.hxx>
+
+#include <unistd.h> // close
+#include <sys/socket.h> // socket, bind, sendto, revcfrom
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ namespace IPv4
+ {
+ class DatagramSocket: public virtual Net::DatagramSocket
+ {
+ public:
+ virtual
+ ~DatagramSocket ()
+ {
+ ::close (sock_);
+ }
+
+ DatagramSocket ()
+ {
+ sock_ = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ if (sock_ == -1)
+ throw Exception (); //@@
+ }
+
+ DatagramSocket (Address const& addr)
+ {
+ sock_ = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ if (sock_ == -1)
+ throw Exception (); //@@
+
+ if (::bind (sock_, addr.raw_addr (), addr.raw_size ()) == -1)
+ throw Exception (); //@@
+ }
+
+ public:
+ virtual sa_family_t
+ familiy () const
+ {
+ return AF_INET;
+ }
+
+ virtual Int
+ protocol () const
+ {
+ return IPPROTO_UDP;
+ }
+
+ // Options.
+ //
+ public:
+ Size
+ recv_buffer_size () const
+ {
+ Int r;
+ socklen_t s (sizeof (r));
+
+ if (::getsockopt (sock_,
+ SOL_SOCKET,
+ SO_RCVBUF,
+ &r,
+ &s) == -1)
+ {
+ throw Exception (); //@@
+ }
+
+ return static_cast<Size> (r);
+ }
+
+ Void
+ recv_buffer_size (Size size)
+ {
+ Int r (static_cast<Int> (size));
+
+ if (::setsockopt (sock_,
+ SOL_SOCKET,
+ SO_RCVBUF,
+ &r,
+ sizeof (r)) == -1)
+ {
+ throw Exception ();
+ }
+ }
+
+ Size
+ send_buffer_size () const
+ {
+ Int r;
+ socklen_t s (sizeof (r));
+
+ if (::getsockopt (sock_,
+ SOL_SOCKET,
+ SO_SNDBUF,
+ &r,
+ &s) == -1)
+ {
+ throw Exception ();
+ }
+
+ return static_cast<Size> (r);
+ }
+
+ void
+ send_buffer_size (Size size)
+ {
+ Int r (static_cast<Int> (size));
+
+ if (::setsockopt (sock_,
+ SOL_SOCKET,
+ SO_SNDBUF,
+ &r,
+ sizeof (r)) == -1)
+ {
+ throw Exception ();
+ }
+ }
+
+ public:
+ Void
+ connect (Address const& addr)
+ {
+ if (::connect (sock_, addr.raw_addr (), addr.raw_size ()) == -1)
+ throw Exception ();
+ }
+
+ Address
+ address () const
+ {
+ sockaddr_in raw_addr;
+ socklen_t raw_size (sizeof (raw_addr));
+
+ if (::getsockname (sock_,
+ reinterpret_cast<sockaddr*> (&raw_addr),
+ &raw_size) == -1)
+ {
+ throw Exception ();
+ }
+
+ return Address (raw_addr);
+ }
+
+
+ public:
+ virtual Size
+ send (Void const* buf, Size size, Net::Address const& addr)
+ {
+ if (addr.familiy () != familiy ())
+ throw InvalidAddress ();
+
+ return send (buf, size, dynamic_cast<Address const&> (addr));
+ }
+
+ virtual Size
+ send (Void const* buf, Size size, Address const& addr)
+ {
+ ssize_t n (::sendto (sock_,
+ buf,
+ size,
+ 0,
+ addr.raw_addr (),
+ addr.raw_size ()));
+
+ if (n == -1)
+ throw Exception ();
+
+ return static_cast<Size> (n);
+ }
+
+ virtual Size
+ recv (Void* buf, Size size)
+ {
+ ssize_t n (::recvfrom (sock_, buf, size, 0, 0, 0));
+
+ if (n == -1)
+ throw Exception ();
+
+ return static_cast<Size> (n);
+ }
+
+ virtual Size
+ recv (Void* buf, Size size, Address& addr)
+ {
+ sockaddr_in raw_addr;
+ socklen_t raw_size (sizeof (raw_addr));
+
+ ssize_t n (::recvfrom (sock_,
+ buf,
+ size,
+ 0,
+ reinterpret_cast<sockaddr*> (&raw_addr),
+ &raw_size));
+
+ if (n == -1)
+ throw Exception ();
+
+ addr = Address (raw_addr);
+
+ return static_cast<Size> (n);
+ }
+
+ virtual Size
+ peek (Void* buf, Size size, Address& addr)
+ {
+ sockaddr_in raw_addr;
+ socklen_t raw_size (sizeof (raw_addr));
+
+ ssize_t n (::recvfrom (sock_,
+ buf,
+ size,
+ MSG_PEEK,
+ reinterpret_cast<sockaddr*> (&raw_addr),
+ &raw_size));
+
+ if (n == -1)
+ throw Exception ();
+
+ addr = Address (raw_addr);
+
+ return static_cast<Size> (n);
+ }
+
+ /*
+ virtual Boolean
+ recv (Void* buf,
+ Size size,
+ Size& received,
+ OS::Time const& timeout)
+ {
+ fd_set r,e;
+
+ FD_ZERO (&r);
+ FD_ZERO (&e);
+
+ FD_SET (sock_, &r);
+ FD_SET (sock_, &e);
+
+ int n = ::pselect (sock_ + 1, &r, 0, &e, &timeout.timespec (), 0);
+
+ if (n > 0)
+ {
+ recv_size = recv (buf, buf_size);
+ return true;
+ }
+ else if (n == 0) // timeout
+ {
+ return false;
+ }
+ else
+ {
+ throw Failure ("pselect");
+ }
+ }
+ */
+
+ protected:
+ Int sock_;
+ };
+ }
+ }
+ }
+}
+
+
+#endif // CULT_OS_NET_IPV4_DATAGRAM_SOCKET_HXX
diff --git a/libcult/cult/os/net/ipv4/multicast-socket.cxx b/libcult/cult/os/net/ipv4/multicast-socket.cxx
new file mode 100644
index 0000000..1431adc
--- /dev/null
+++ b/libcult/cult/os/net/ipv4/multicast-socket.cxx
@@ -0,0 +1,19 @@
+// file : cult/os/net/ipv4/multicast-socket.cxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/os/net/ipv4/multicast-socket.hxx>
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ namespace IPv4
+ {
+ }
+ }
+ }
+}
diff --git a/libcult/cult/os/net/ipv4/multicast-socket.hxx b/libcult/cult/os/net/ipv4/multicast-socket.hxx
new file mode 100644
index 0000000..70207a3
--- /dev/null
+++ b/libcult/cult/os/net/ipv4/multicast-socket.hxx
@@ -0,0 +1,133 @@
+// file : cult/os/net/ipv4/multicast-socket.hxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CULT_OS_NET_IPV4_MULTICAST_SOCKET_HXX
+#define CULT_OS_NET_IPV4_MULTICAST_SOCKET_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/os/net/address.hxx>
+#include <cult/os/net/multicast-socket.hxx>
+#include <cult/os/net/ipv4/address.hxx>
+#include <cult/os/net/ipv4/datagram-socket.hxx>
+
+#include <cstring> // memcpy
+#include <sys/socket.h> // bind, setsockopt
+#include <arpa/inet.h> // htonl
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ namespace IPv4
+ {
+ //@@ Add MulticastAddress (with proper checks)?
+ //
+
+ class MulticastSocket : public virtual Net::MulticastSocket,
+ public virtual DatagramSocket
+ {
+ public:
+ virtual
+ ~MulticastSocket ()
+ {
+ }
+
+ public:
+ MulticastSocket (Boolean loop = true, UnsignedShort ttl = 1)
+ {
+ unsigned char ttl_ (static_cast<unsigned char> (ttl));
+
+ {
+ Int flag (1);
+
+ if (::setsockopt (sock_,
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ &flag,
+ sizeof (flag)) == -1)
+ {
+ throw Exception ();
+ }
+ }
+
+ if (ttl != 1)
+ {
+ if (::setsockopt (sock_,
+ IPPROTO_IP,
+ IP_MULTICAST_TTL,
+ &ttl_,
+ sizeof (ttl_)) == -1)
+ {
+ throw Exception ();
+ }
+ }
+
+ if (!loop)
+ {
+ unsigned char flag (0);
+
+ if (::setsockopt (sock_,
+ IPPROTO_IP,
+ IP_MULTICAST_LOOP,
+ &flag,
+ sizeof (flag)) == -1)
+ {
+ throw Exception ();
+ }
+ }
+
+ }
+
+ public:
+ virtual Void
+ join (Net::Address const& addr)
+ {
+ if (addr.familiy () != familiy ())
+ throw InvalidAddress ();
+
+ join (dynamic_cast<Address const&> (addr));
+ }
+
+ virtual Void
+ join (Address const& addr)
+ {
+ ip_mreq mreq;
+
+ std::memcpy (&mreq.imr_multiaddr,
+ &addr.addr ().sin_addr,
+ sizeof (in_addr));
+
+ mreq.imr_interface.s_addr = htonl (INADDR_ANY);
+
+ if (::setsockopt (sock_,
+ IPPROTO_IP,
+ IP_ADD_MEMBERSHIP,
+ &mreq,
+ sizeof (mreq)) == -1)
+ {
+ throw Exception ();
+ }
+
+ if (::bind (sock_, addr.raw_addr (), addr.raw_size ()) == -1)
+ throw Exception ();
+ }
+
+ virtual Void
+ leave ()
+ {
+ //@@ TODO
+ abort ();
+ }
+ };
+ }
+ }
+ }
+}
+
+
+#endif // CULT_OS_NET_IPV4_MULTICAST_SOCKET_HXX
diff --git a/libcult/cult/os/net/multicast-socket.cxx b/libcult/cult/os/net/multicast-socket.cxx
new file mode 100644
index 0000000..64710cf
--- /dev/null
+++ b/libcult/cult/os/net/multicast-socket.cxx
@@ -0,0 +1,26 @@
+// file : cult/os/net/multicast-socket.cxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/os/net/multicast-socket.hxx>
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ MulticastSocket::
+ MulticastSocket ()
+ {
+ }
+
+ MulticastSocket::
+ ~MulticastSocket ()
+ {
+ }
+ }
+ }
+}
+
diff --git a/libcult/cult/os/net/multicast-socket.hxx b/libcult/cult/os/net/multicast-socket.hxx
new file mode 100644
index 0000000..7aeff74
--- /dev/null
+++ b/libcult/cult/os/net/multicast-socket.hxx
@@ -0,0 +1,40 @@
+// file : cult/os/net/multicast-socket.hxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CULT_OS_NET_MULTICAST_SOCKET_HXX
+#define CULT_OS_NET_MULTICAST_SOCKET_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/os/net/address.hxx>
+#include <cult/os/net/datagram-socket.hxx>
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ class MulticastSocket : public virtual DatagramSocket
+ {
+ protected:
+ MulticastSocket ();
+
+ virtual
+ ~MulticastSocket ();
+
+ public:
+ virtual Void
+ join (Address const& addr) = 0;
+
+ virtual Void
+ leave () = 0;
+ };
+ }
+ }
+}
+
+
+#endif // CULT_OS_NET_MULTICAST_SOCKET_HXX
diff --git a/libcult/cult/os/net/socket.cxx b/libcult/cult/os/net/socket.cxx
new file mode 100644
index 0000000..bd9969c
--- /dev/null
+++ b/libcult/cult/os/net/socket.cxx
@@ -0,0 +1,26 @@
+// file : cult/os/net/socket.cxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/os/net/socket.hxx>
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ Socket::
+ Socket ()
+ {
+ }
+
+ Socket::
+ ~Socket ()
+ {
+ }
+ }
+ }
+}
+
diff --git a/libcult/cult/os/net/socket.hxx b/libcult/cult/os/net/socket.hxx
new file mode 100644
index 0000000..a471186
--- /dev/null
+++ b/libcult/cult/os/net/socket.hxx
@@ -0,0 +1,54 @@
+// file : cult/os/net/socket.hxx
+// author : Boris Kolpackov <boris@kolpackov.Net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CULT_OS_NET_SOCKET_HXX
+#define CULT_OS_NET_SOCKET_HXX
+
+#include <cult/types.hxx>
+#include <cult/os/exception.hxx>
+
+#include <sys/socket.h> // sa_family_t
+
+namespace Cult
+{
+ namespace OS
+ {
+ namespace Net
+ {
+ class Socket: public NonCopyable
+ {
+ public:
+ struct Exception : virtual OS::Exception {};
+
+ struct InvalidAddress : virtual Exception {};
+
+ protected:
+ Socket ();
+
+ virtual
+ ~Socket ();
+
+ public:
+ // AF_INET, AF_INET6, etc.
+ //
+ virtual sa_family_t
+ familiy () const = 0;
+
+ // SOCK_DGRAM, SOCK_STREAM, etc.
+ //
+ virtual Int
+ type () const = 0;
+
+ // IPPROTO_UDP, IPPROTO_TCP, IPPROTO_SCTP, etc.
+ //
+ virtual Int
+ protocol () const = 0;
+ };
+ }
+ }
+}
+
+
+#endif // CULT_OS_NET_SOCKET_HXX