void Communicator::initiate_handshake()
{
if(handshake_status!=0)
- throw InvalidState("Handshaking is already underway or done");
+ throw sequence_error("handshaking already done");
send_handshake();
handshake_status = 1;
namespace Msp {
namespace Net {
+class sequence_error: public std::logic_error
+{
+public:
+ sequence_error(const std::string &w): std::logic_error(w) { }
+ virtual ~sequence_error() throw() { }
+};
+
+
class Communicator
{
public:
void send(const P &pkt)
{
if(handshake_status!=2)
- throw InvalidState("Handshaking is not done");
+ throw sequence_error("handshaking not done");
unsigned size = protocol.assemble(pkt, out_buf, buf_size);
socket.write(out_buf, size);
}
#include <cerrno>
+#include <msp/core/systemerror.h>
#include <msp/strings/format.h>
#include "datagramsocket.h"
int err = ::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
if(err==-1)
- throw SystemError("Unable to connect", errno);
+ {
+#ifdef WIN32
+ throw system_error("connect", WSAGetLastError());
+#else
+ throw system_error("connect");
+#endif
+ }
delete peer_addr;
peer_addr = addr.copy();
if(errno==EAGAIN)
return 0;
else
- throw SystemError("Sendto failed", errno);
+ {
+#ifdef WIN32
+ throw system_error("sendto", WSAGetLastError());
+#else
+ throw system_error("sendto");
+#endif
+ }
}
return ret;
if(errno==EAGAIN)
return 0;
else
- throw SystemError("Recvfrom failed", errno);
+ {
+#ifdef WIN32
+ throw system_error("recvfrom", WSAGetLastError());
+#else
+ throw system_error("recvfrom");
+#endif
+ }
}
addr_ = SockAddr::create(addr);
-#include <msp/core/except.h>
#include <msp/strings/format.h>
#include "inet6.h"
unsigned Inet6Addr::fill_sockaddr(sockaddr &) const
{
- throw Exception("Inet6Addr doesn't fit in struct sockaddr");
+ throw logic_error("sizeof(sockaddr_in6)>sizeof(sockaddr)");
}
unsigned Inet6Addr::fill_sockaddr(sockaddr_storage &sa) const
namespace {
+using Msp::Net::buffer_error;
+
template<typename T>
class Assembler
{
for(unsigned i=0; i<sizeof(T); ++i)
{
if(data==end)
- throw Msp::Exception("Out of buffer space");
+ throw buffer_error("overflow");
*data++ = *--ptr;
}
return data;
{
data = Assembler<unsigned short>::assemble(v.size(), data, end);
if(end-data<static_cast<int>(v.size()))
- throw Msp::Exception("Out of buffer space");
+ throw buffer_error("overflow");
memcpy(data, v.data(), v.size());
return data+v.size();
}
for(unsigned i=0; i<sizeof(T); ++i)
{
if(data==end)
- throw Msp::Exception("Premature end of data");
+ throw buffer_error("underflow");
*--ptr = *data++;
}
return data;
unsigned short size;
data = Assembler<unsigned short>::disassemble(size, data, end);
if(end-data<size)
- throw Msp::Exception("Premature end of data");
+ throw buffer_error("underflow");
v.assign(data, data+size);
return data+size;
}
unsigned id = (udata[0]<<8)+udata[1];
unsigned psz = (udata[2]<<8)+udata[3];
if(psz>size)
- throw InvalidParameterValue("Not enough data for packet");
+ throw bad_packet("truncated");
const PacketDefBase &pdef = get_packet_by_id(id);
const char *ptr = pdef.disassemble(rcv, data+4, data+psz);
return ptr-data;
#define MSP_NET_PROTOCOL_H_
#include <map>
+#include <stdexcept>
#include <vector>
-#include <msp/core/except.h>
#include "receiver.h"
namespace Msp {
namespace Net {
+class bad_packet: public std::runtime_error
+{
+public:
+ bad_packet(const std::string &w): std::runtime_error(w) { }
+ virtual ~bad_packet() throw() { }
+};
+
+
+class buffer_error: public std::runtime_error
+{
+public:
+ buffer_error(const std::string &w): std::runtime_error(w) { }
+ virtual ~buffer_error() throw() { }
+};
+
+
class Protocol
{
private:
{
PacketReceiver<P> *prcv = dynamic_cast<PacketReceiver<P> *>(&r);
if(!prcv)
- throw Exception("Packet type not supported by receiver");
+ throw bad_packet("unsupported");
P pkt;
for(typename std::vector<FieldBase<P> *>::const_iterator i=fields.begin(); i!=fields.end(); ++i)
d = (*i)->disassemble(pkt, d, e);
#else
#include <netdb.h>
#endif
+#include <msp/core/systemerror.h>
#include <msp/strings/format.h>
#include "socket.h"
#include "resolve.h"
}
else
#ifdef WIN32
- throw Exception(format("Can't resolve '%s': %d", host, err));
+ throw system_error("getaddrinfo", WSAGetLastError());
#else
- throw Exception(format("Can't resolve '%s': %s", host, gai_strerror(err)));
+ throw system_error("getaddrinfo", gai_strerror(err));
#endif
}
-#include <msp/core/except.h>
+#include <stdexcept>
#include "inet.h"
#include "inet6.h"
+using namespace std;
+
namespace Msp {
namespace Net {
case AF_INET6:
return new Inet6Addr(reinterpret_cast<const sockaddr_in6 &>(sa));
default:
- throw InvalidParameterValue("Unknown address family");
+ throw invalid_argument("SockAddr::create");
}
}
#include <sys/socket.h>
#endif
#include <iostream>
+#include <msp/core/systemerror.h>
#include <msp/io/handle_private.h>
#include <msp/strings/format.h>
#include <msp/time/rawtime_private.h>
int err = ::bind(handle, reinterpret_cast<sockaddr *>(&sa), size);
if(err==-1)
- throw SystemError("Unable to bind", errno);
+ throw system_error("bind");
delete local_addr;
local_addr = addr.copy();
const SockAddr &Socket::get_local_address() const
{
if(local_addr==0)
- throw InvalidState("Local address not set");
+ throw bad_socket_state("not bound");
return *local_addr;
}
const SockAddr &Socket::get_peer_address() const
{
if(peer_addr==0)
- throw InvalidState("Peer address not set");
+ throw bad_socket_state("not connected");
return *peer_addr;
}
void Socket::check_state(bool conn) const
{
if(handle==MSP_NET_INVALID_SOCKET_HANDLE)
- throw Exception("Socket is closed");
+ throw bad_socket_state("socket is closed");
if(conn && !connected)
- throw Exception("Socket is not connected");
+ throw bad_socket_state("not connected");
}
int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen)
if(errno==EAGAIN)
return 0;
else
- throw SystemError("Writing to socket failed", errno);
+ throw system_error("send");
}
return ret;
if(errno==EAGAIN)
return 0;
else
- throw SystemError("Reading from socket failed", errno);
+ throw system_error("recv");
}
else if(ret==0 && !eof_flag)
{
namespace Msp {
namespace Net {
+class bad_socket_state: public std::logic_error
+{
+public:
+ bad_socket_state(const std::string &w): std::logic_error(w) { }
+ virtual ~bad_socket_state() throw() { }
+};
+
+
class Socket: public IO::EventObject
{
protected:
#include <cerrno>
#include <msp/core/refptr.h>
+#include <msp/core/systemerror.h>
#include <msp/strings/format.h>
#include "streamlistensocket.h"
#include "streamsocket.h"
+using namespace std;
+
namespace Msp {
namespace Net {
int StreamListenSocket::connect(const SockAddr &)
{
- throw Exception("Can't connect a listen socket");
+ // XXX This function needs to go away
+ throw logic_error("Can't connect a listen socket");
}
void StreamListenSocket::listen(const SockAddr &addr, unsigned backlog)
int err = ::listen(handle, backlog);
if(err==-1)
- throw SystemError("Unable to listen", errno);
+ throw system_error("listen");
#ifdef WIN32
WSAEventSelect(handle, event, FD_ACCEPT);
StreamSocket *StreamListenSocket::accept()
{
if(!listening)
- throw InvalidState("Socket is not listening");
+ throw bad_socket_state("not listening");
sockaddr_storage sa;
socklen_t size = sizeof(sockaddr_storage);
#include <sys/socket.h>
#endif
#include <cerrno>
+#include <msp/core/systemerror.h>
#include <msp/io/poll.h>
#include <msp/strings/format.h>
#include "streamsocket.h"
{
check_state(false);
if(!connecting)
- throw InvalidState("No connection attempt going on");
+ throw bad_socket_state("not connecting");
int res = poll(*this, IO::P_OUTPUT, timeout);
if(res==-1)
#ifdef WIN32
- throw Exception(format("Connection polling failed: %d", WSAGetLastError()));
+ throw system_error("poll", WSAGetLastError());
#else
- throw SystemError("Connection polling failed", errno);
+ throw system_error("poll");
#endif
else if(res>0)
{
{
set_events(IO::P_NONE);
#ifdef WIN32
- throw Exception(format("Connection failed: %d", err));
+ throw system_error("connect", WSAGetLastError());
#else
- throw SystemError("Connection failed", err);
+ throw system_error("connect");
#endif
}
check_state(false);
if(connected)
- throw InvalidState("Socket is already connected");
+ throw bad_socket_state("already connected");
sockaddr_storage sa;
socklen_t size = addr.fill_sockaddr(sa);
set_events(IO::P_OUTPUT);
}
else
- throw Exception(format("Unable to connect: %d", err_code));
+ throw system_error("connect", err_code);
}
#else
int err = ::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
set_events(IO::P_OUTPUT);
}
else
- throw SystemError("Unable to connect", errno);
+ throw system_error("connect");
}
#endif