Source: ../../fea/xrl_socket_cmds.hh
|
|
|
|
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// Copyright (c) 2001-2005 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.
// $XORP: xorp/fea/xrl_socket_cmds.hh,v 1.6 2005/03/25 02:53:17 pavlin Exp $
#ifndef __FEA_XRL_SOCKET_CMDS_HH__
#define __FEA_XRL_SOCKET_CMDS_HH__
#include <vector>
#include <list>
#include "libxorp/ipv4.hh"
#include "libxorp/ipv6.hh"
class XrlSocketServer;
class XrlSender;
class XrlSocketCommandBase {
public:
typedef XorpCallback1<void, const XrlError&>::RefPtr CommandCallback;
public:
XrlSocketCommandBase(const string& tgt);
virtual ~XrlSocketCommandBase() = 0;
virtual bool execute(XrlSender& xs, const CommandCallback&) = 0;
virtual string str() const = 0;
inline const char* target() const { return _t.c_str(); }
protected:
string _t;
};
template <typename A>
class SocketUserSendRecvEvent : public XrlSocketCommandBase {
public:
inline SocketUserSendRecvEvent(const string& tgt, const string& sockid)
: XrlSocketCommandBase(tgt), _sockid(sockid), _src_port(0xffffffff)
{}
inline void set_source_host(const A& host) { _src_host = host; }
inline void set_source_port(uint16_t port) { _src_port = port; }
inline void set_source(const typename A::SockAddrType& sa,
socklen_t salen);
inline vector<uint8_t>& data() { return _data; }
inline const vector<uint8_t>& data() const { return _data; }
bool execute(XrlSender& xs, const CommandCallback& cb);
string str() const;
private:
string _sockid;
A _src_host;
uint32_t _src_port;
vector<uint8_t> _data;
};
template <>
inline void
SocketUserSendRecvEvent<IPv4>::set_source(const IPv4::SockAddrType& sin,
socklen_t sin_len)
{
XLOG_ASSERT(sin_len == sizeof(sockaddr_in));
_src_host = IPv4(sin);
_src_port = ntohs(sin.sin_port);
}
template <>
inline void
SocketUserSendRecvEvent<IPv6>::set_source(const IPv6::SockAddrType& sin6,
socklen_t sin6_len)
{
XLOG_ASSERT(sin6_len == sizeof(sockaddr_in6));
_src_host = IPv6(sin6);
_src_port = ntohs(sin6.sin6_port);
}
template <typename A>
class SocketUserSendConnectEvent : public XrlSocketCommandBase {
public:
inline SocketUserSendConnectEvent(XrlSocketServer* ss,
const string& tgt,
const string& sockid,
const A& host,
uint16_t port,
const string& new_sockid)
: XrlSocketCommandBase(tgt), _ss(ss), _sockid(sockid),
_src_host(host), _src_port(port), _new_sockid(new_sockid)
{}
bool execute(XrlSender& xs, const CommandCallback& cb);
void accept_or_reject_cb(const XrlError& e, const bool* accept);
string str() const;
private:
XrlSocketServer* _ss;
string _sockid;
A _src_host;
uint32_t _src_port;
string _new_sockid;
};
template <typename A>
class SocketUserSendErrorEvent : public XrlSocketCommandBase {
public:
inline SocketUserSendErrorEvent(const string& tgt,
const string& sockid,
const string& error,
bool fatal)
: XrlSocketCommandBase(tgt), _sockid(sockid),
_error(error), _fatal(fatal)
{}
bool execute(XrlSender& xs, const CommandCallback& cb);
string str() const;
private:
string _sockid;
string _error;
bool _fatal;
};
template <typename A>
class SocketUserSendCloseEvent : public XrlSocketCommandBase {
public:
inline SocketUserSendCloseEvent(const string& tgt,
const string& sockid,
const string& reason)
: XrlSocketCommandBase(tgt), _sockid(sockid), _reason(reason)
{}
bool execute(XrlSender& xs, const CommandCallback& cb);
string str() const;
private:
string _sockid;
string _reason;
};
class XrlSocketCommandDispatcher {
public:
typedef ref_ptr<XrlSocketCommandBase> Command;
public:
XrlSocketCommandDispatcher(XrlSender& xs);
virtual ~XrlSocketCommandDispatcher() = 0;
/**
* Enqueue an Xrl command for dispatch. If queue is empty,
* command is sent immediately for dispatch. When dispatch
* completes xrl_cb() is called with the response.
*/
void enqueue(const Command& cmd);
inline bool queue_empty() const { return _cmds.empty(); }
protected:
/**
* Send next Xrl enqueued (if any).
*
* @return true if next xrl sent, false if queue is empty or send failed.
*/
bool send_next();
/**
* Method invoked when an Xrl dispatch is completed.
* Implementations should call send_next() to trigger next queued
* XrlSocketCommandBase object to be dispatched.
*
* @param xe Xrl error object.
*/
virtual void xrl_cb(const XrlError& xe) = 0;
private:
inline bool dispatch_head();
private:
XrlSender& _xs;
list<Command> _cmds;
};
#endif // __FEA_XRL_SOCKET_CMDS_HH__
Generated by: pavlin on possum.icir.org on Thu Mar 9 04:43:06 2006, using kdoc $.