ported double tracking from TC

This commit is contained in:
mikx
2020-10-30 23:45:46 -04:00
commit 44b1f31c23
4914 changed files with 4961129 additions and 0 deletions

11
deps/acelite/ace/QoS/ACE_QoS.pc.in vendored Normal file
View File

@@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: ACE_QOS
Description: ACE Quality of Service Library
Requires: ACE
Version: @VERSION@
Libs: -L${libdir} -lACE_QoS
Cflags: -I${includedir}

45
deps/acelite/ace/QoS/ACE_QoS_Export.h vendored Normal file
View File

@@ -0,0 +1,45 @@
// -*- C++ -*-
// Definition for Win32 Export directives.
// This file is generated automatically by
// generate_export_file.pl
// ------------------------------
#if !defined (ACE_QOS_EXPORT_H)
#define ACE_QOS_EXPORT_H
#include /**/ "ace/config-all.h"
#if defined (ACE_AS_STATIC_LIBS)
# if !defined (ACE_QoS_HAS_DLL)
# define ACE_QoS_HAS_DLL 0
# endif /* ! ACE_QoS_HAS_DLL */
#else
# if !defined (ACE_QoS_HAS_DLL)
# define ACE_QoS_HAS_DLL 1
# endif /* ! ACE_QoS_HAS_DLL */
#endif /* ACE_AS_STATIC_LIB */
#if defined (ACE_QoS_HAS_DLL)
# if (ACE_QoS_HAS_DLL == 1)
# if defined (ACE_QoS_BUILD_DLL)
# define ACE_QoS_Export ACE_Proper_Export_Flag
# define ACE_QoS_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
# define ACE_QoS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
# else
# define ACE_QoS_Export ACE_Proper_Import_Flag
# define ACE_QoS_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
# define ACE_QoS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
# endif /* ACE_QoS_BUILD_DLL */
# else
# define ACE_QoS_Export
# define ACE_QoS_SINGLETON_DECLARATION(T)
# define ACE_QoS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
# endif /* ! ACE_QoS_HAS_DLL == 1 */
#else
# define ACE_QoS_Export
# define ACE_QoS_SINGLETON_DECLARATION(T)
# define ACE_QoS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
#endif /* ACE_QoS_HAS_DLL */
#endif /* ACE_QOS_EXPORT_H */
// End of auto generated file.

161
deps/acelite/ace/QoS/QoS_Decorator.cpp vendored Normal file
View File

@@ -0,0 +1,161 @@
// QoS_Decorator.cpp
#include "QoS_Decorator.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_QOS_DECORATOR)
// Constructor.
ACE_QoS_Decorator_Base::ACE_QoS_Decorator_Base (void)
{}
// Constructor.
ACE_QoS_Decorator_Base::ACE_QoS_Decorator_Base (ACE_Event_Handler
*event_handler)
: event_handler_ (event_handler)
{
}
// Destructor.
ACE_QoS_Decorator_Base::~ACE_QoS_Decorator_Base (void)
{
}
// Forward the call to ACE_Event_Handler component.
ACE_HANDLE
ACE_QoS_Decorator_Base::get_handle (void) const
{
return this->event_handler_->get_handle ();
}
// Forward the call to ACE_Event_Handler component.
int
ACE_QoS_Decorator_Base::handle_input (ACE_HANDLE fd)
{
return this->event_handler_->handle_input (fd);
}
// Forward the call to ACE_Event_Handler component.
int
ACE_QoS_Decorator_Base::handle_qos (ACE_HANDLE fd)
{
return this->event_handler_->handle_qos (fd);
}
// Constructor.
ACE_QoS_Decorator::ACE_QoS_Decorator (void)
{}
// Constructor.
ACE_QoS_Decorator::ACE_QoS_Decorator (ACE_Event_Handler *event_handler,
ACE_QoS_Session *qos_session,
ACE_Reactor *reactor)
: qos_session_ (qos_session),
reactor_ (reactor)
{
ACE_NEW (this->decorator_base_,
ACE_QoS_Decorator_Base (event_handler));
ACE_NEW (this->qos_event_handler_,
ACE_QoS_Event_Handler (this->decorator_base_));
}
// Destructor.
ACE_QoS_Decorator::~ACE_QoS_Decorator (void)
{
delete this->decorator_base_;
delete this->qos_event_handler_;
}
// Implements the undecorated functionality. This is sufficient for
// GQoS. RAPI needs additional QoS decoration. This is done by the
// ACE_QoS_Event_Handler class.
ACE_HANDLE
ACE_QoS_Decorator::get_handle (void) const
{
return this->decorator_base_->get_handle ();
}
// Implements the undecorated functionality. This is sufficient for
// GQoS. RAPI needs additional QoS decoration. This is done by the
// ACE_QoS_Event_Handler class.
int
ACE_QoS_Decorator::handle_input (ACE_HANDLE fd)
{
return this->decorator_base_->handle_input (fd);
}
// Implements the undecorated functionality. This is sufficient for
// GQoS. RAPI needs additional QoS decoration. This is done by the
// ACE_QoS_Event_Handler class.
int
ACE_QoS_Decorator::handle_qos (ACE_HANDLE fd)
{
return this->decorator_base_->handle_qos (fd);
}
// This method registers the RAPI QoS event handler with the reactor
// if the application is using RAPI. Note that it is a no-op for GQoS
// because an extra socket for handling QoS events is not required.
int
ACE_QoS_Decorator::init (void)
{
#if defined (ACE_HAS_RAPI)
// Pass the QoS session to QoS Event Handler.
this->qos_event_handler_->qos_session (this->qos_session_);
// Register the QoS Event Handler with the Reactor.
return this->reactor_->register_handler (this->qos_event_handler_,
ACE_Event_Handler::READ_MASK);
#endif
return 0;
}
// Constructor.
ACE_QoS_Event_Handler::ACE_QoS_Event_Handler (void)
{
}
// Constructor.
ACE_QoS_Event_Handler::ACE_QoS_Event_Handler (ACE_QoS_Decorator_Base
*decorator_base)
: decorator_base_ (decorator_base)
{
}
// Destructor.
ACE_QoS_Event_Handler::~ACE_QoS_Event_Handler (void)
{
}
// Set the QoS session.
void
ACE_QoS_Event_Handler::qos_session (ACE_QoS_Session *qos_session)
{
this->qos_session_ = qos_session;
}
// Returns the RAPI file descriptor for listening to RAPI evnets.
ACE_HANDLE
ACE_QoS_Event_Handler::get_handle (void) const
{
return this->qos_session_->rsvp_events_handle ();
}
// Note, here the handle_input () calls the handle_qos () of the
// Decorator Base which then calls handle_qos () of the
// ACE_Event_Handler component within it. This helps to translate the
// normal read events into qos events in case of RAPI so the
// application using the API is oblivious to the fact that in RAPI,
// QoS events are received on a different socket. This helps to
// maintain a uniform design for the application irrespective of
// whether it is using RAPI or GQoS.
int
ACE_QoS_Event_Handler::handle_input (ACE_HANDLE fd)
{
return this->decorator_base_->handle_qos (fd);
}
ACE_END_VERSIONED_NAMESPACE_DECL

177
deps/acelite/ace/QoS/QoS_Decorator.h vendored Normal file
View File

@@ -0,0 +1,177 @@
// -*- C++ -*-
//=============================================================================
/**
* @file QoS_Decorator.h
*
* @author Vishal Kachroo <vishal@cs.wustl.edu>
*/
//=============================================================================
#ifndef QOS_DECORATOR_H
#define QOS_DECORATOR_H
#include /**/ "ace/pre.h"
#include "ace/Reactor.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/INET_Addr.h"
#include "ace/Event_Handler.h"
#include "SOCK_Dgram_Mcast_QoS.h"
#include "ACE_QoS_Export.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_QoS_Decorator_Base
*
* @brief This class is the Decorator Pattern Base class for decorating
* ACE_Event_Handler.
*
* It simply forwards the requests for get_handle (),
* handle_input () and handle_qos () to its event_handler_
* component. Concrete decorators for ACE_Event_Handler will use
* this class to access the basic event handler functionality and
* decorate that by their own implementation.
*/
class ACE_QoS_Export ACE_QoS_Decorator_Base : public ACE_Event_Handler
{
public:
// Initialization and termination methods.
/// Constructor.
ACE_QoS_Decorator_Base (void);
/// Constructor.
ACE_QoS_Decorator_Base (ACE_Event_Handler *event_handler);
/// Destructor.
~ACE_QoS_Decorator_Base (void);
/// Forwards the request to its event_handler_ component.
virtual ACE_HANDLE get_handle (void) const;
/// Forwards the request to its event_handler_ component.
virtual int handle_input (ACE_HANDLE fd);
/// Forwards the request to its event_handler_ component.
virtual int handle_qos (ACE_HANDLE fd);
private:
/// The event handler that is decorated by this class.
ACE_Event_Handler *event_handler_;
};
/**
* @class ACE_QoS_Event_Handler
*
* @brief This Handler is registered with the Reactor for QoS events.
*
* Concrete QoS decorator uses this class to receive QoS events
* for RAPI. It hides the application from knowing that it is
* receiving QoS events on a different socket so the application
* doesnt have to be designed differently for RAPI and GQoS.
*/
class ACE_QoS_Export ACE_QoS_Event_Handler : public ACE_Event_Handler
{
/// Destructor.
~ACE_QoS_Event_Handler (void);
/// Returns the RAPI file descriptor for receiving QoS events.
virtual ACE_HANDLE get_handle (void) const;
/// Calls the base class handle_input ().
virtual int handle_input (ACE_HANDLE fd);
/// Sets the QoS session.
void qos_session (ACE_QoS_Session *qos_session);
friend class ACE_QoS_Decorator;
private:
/// Constructor is private because only ACE_QoS_Decorator should
/// create this object.
ACE_QoS_Event_Handler (void);
/// The QoS Decorator passes in its base for this handler to use.
ACE_QoS_Event_Handler (ACE_QoS_Decorator_Base *decorator_base);
/// Used to get to the RAPI file descriptor for QoS Events.
ACE_QoS_Session *qos_session_;
/// Requests on the class are forwarded to this base class;
ACE_QoS_Decorator_Base *decorator_base_;
};
/**
* @class ACE_QoS_Decorator
*
* @brief Concrete QoS Decorator.
*
* Decorates the ACE_Event_Handler to additionally handle QoS
* events uniformly for different QoS mechanisms like RAPI and
* GQoS.
*/
class ACE_QoS_Export ACE_QoS_Decorator : public ACE_QoS_Decorator_Base
{
public:
// Initialization and termination methods.
/// Constructor.
ACE_QoS_Decorator (void);
/// Constructor.
ACE_QoS_Decorator (ACE_Event_Handler *event_handler,
ACE_QoS_Session *qos_session,
ACE_Reactor *reactor = ACE_Reactor::instance ());
/// Destructor.
~ACE_QoS_Decorator (void);
/// Calls the base class get_handle ().
virtual ACE_HANDLE get_handle (void) const;
/// Calls the base class handle_input ().
virtual int handle_input (ACE_HANDLE fd);
/// Calls the base class handle_qos ().
virtual int handle_qos (ACE_HANDLE fd);
/// This method registers the QoS Event Handler with the Reactor
/// to receive RAPI events.
int init (void);
private:
/// Requests on the class are forwarded to this base class;
ACE_QoS_Decorator_Base *decorator_base_;
/// Handles the QoS events and in that sense decorates the usual
/// ACE_Event_Handler.
ACE_QoS_Event_Handler *qos_event_handler_;
/// Passed to the ACE_QoS_Event_Handler for retrieving the RAPI
/// session specific information like rapi_fd.
ACE_QoS_Session *qos_session_;
/// If the application wants to use an instance of Reactor other
/// than the Singleton one.
ACE_Reactor *reactor_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#include /**/ "ace/post.h"
#endif /* QOS_DECORATOR_H */

37
deps/acelite/ace/QoS/QoS_Manager.cpp vendored Normal file
View File

@@ -0,0 +1,37 @@
// QoS_Manager.cpp
#include "QoS_Manager.h"
#include "ace/Log_Category.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_QOS_MANAGER)
ACE_QoS_Manager::ACE_QoS_Manager (void)
{}
ACE_QoS_Manager::~ACE_QoS_Manager (void)
{}
// Adds the given session to the list of session objects joined by
// this socket.
int
ACE_QoS_Manager::join_qos_session (ACE_QoS_Session *qos_session)
{
if (this->qos_session_set ().insert (qos_session) != 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in adding a new session to the ")
ACE_TEXT ("socket session set\n")),
-1);
return 0;
}
// Returns the QoS session set for this socket.
ACE_Unbounded_Set <ACE_QoS_Session *>
ACE_QoS_Manager::qos_session_set (void)
{
return this->qos_session_set_;
}
ACE_END_VERSIONED_NAMESPACE_DECL

72
deps/acelite/ace/QoS/QoS_Manager.h vendored Normal file
View File

@@ -0,0 +1,72 @@
// -*- C++ -*-
//=============================================================================
/**
* @file QoS_Manager.h
*
* @author Vishal Kachroo
*/
//=============================================================================
#ifndef ACE_QOS_MANAGER_H
#define ACE_QOS_MANAGER_H
#include /**/ "ace/pre.h"
#include "ace/Addr.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/IPC_SAP.h"
#include "ace/Containers_T.h"
#include "ACE_QoS_Export.h"
#include "QoS_Session.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_QoS_Manager
*
* @brief This class manages the QoS sessions associated with ACE_SOCK.
*
* This class provides functions to manage the QoS
* associated with a socket. The idea is to keep the management of
* QoS for a socket separate from the socket itself. Currently, the
* manager is used to manage the QoS session set. It will handle more
* responsibilities in the future.
*/
class ACE_QoS_Export ACE_QoS_Manager
{
public:
/// Default constructor.
ACE_QoS_Manager (void);
/// Default destructor.
~ACE_QoS_Manager (void);
/**
* Join the given QoS session. A socket can join multiple QoS
* sessions. This call adds the given QoS session to the list of
* QoS sessions that the socket has already joined.
*/
int join_qos_session (ACE_QoS_Session *qos_session);
typedef ACE_Unbounded_Set <ACE_QoS_Session *> ACE_QOS_SESSION_SET;
/// Get the QoS session set.
ACE_QOS_SESSION_SET qos_session_set (void);
private:
/// Set of QoS sessions that this socket has joined.
ACE_QOS_SESSION_SET qos_session_set_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#include /**/ "ace/post.h"
#endif /* ACE_QOS_MANAGER_H */

181
deps/acelite/ace/QoS/QoS_Session.h vendored Normal file
View File

@@ -0,0 +1,181 @@
/* -*- C++ -*- */
//=============================================================================
/**
* @file QoS_Session.h
*
* @author Vishal Kachroo <vishal@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_QOS_SESSION_H
#define ACE_QOS_SESSION_H
#include /**/ "ace/pre.h"
#include "ACE_QoS_Export.h"
#include "ace/INET_Addr.h"
#include "ace/OS_QoS.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_SOCK;
class ACE_QoS_Manager;
typedef int ACE_Protocol_ID;
// IPPROTO_UDP or IPPROTO_TCP.
/**
* @class ACE_QoS_Session
*
* @brief A QoS Session object.
*
* This class defines the interface for a QoS Session. It abstracts the
* notion of QoS on different platforms and presents a simple, easy-to-use
* API. Current [RAPI,GQoS] and future implementations will conform to this
* interface.
*/
class ACE_QoS_Export ACE_QoS_Session
{
public:
enum RSVP_Event_Type
{
RSVP_PATH_EVENT,
RSVP_RESV_EVENT,
RSVP_RESV_CONFIRM,
RSVP_RESV_ERROR,
RSVP_PATH_ERROR
};
/// A flag to indicate if this endpoint is a sender or a receiver or
/// both.
enum ACE_End_Point_Type
{
ACE_QOS_SENDER,
ACE_QOS_RECEIVER,
ACE_QOS_BOTH
};
/// to shutup g++.
virtual ~ACE_QoS_Session (void) {};
/// Open a QoS session [dest IP, dest port, Protocol ID].
virtual int open (ACE_INET_Addr dest_addr,
ACE_Protocol_ID protocol_id) = 0;
/// Close the QoS Session.
virtual int close (void) = 0;
/// Returns the QoS in the current session.
virtual ACE_QoS qos (void) const = 0;
/// Set QoS for the current session. The qos manager is used to
/// confirm if this QoS session was subscribed to by the socket.
virtual int qos (ACE_SOCK *socket,
ACE_QoS_Manager *qos_manager,
const ACE_QoS &ace_qos) = 0;
/**
* Sets the QoS for this session object to ace_qos. Does not
* interfere with the QoS in the underlying socket. This call is
* useful to update the QoS object when the underlying socket QoS is
* being set through a mechanism other than the previous qos ()
* method e.g. inside the dgram_mcast.subscribe () where the QoS for
* the socket is set through ACE_OS::join_leaf ().
*/
virtual void qos (const ACE_QoS &ace_qos) = 0;
/**
* This is called from handle_qos () method of the the QoS Event
* Handler. Invoking this method is an indication of a QoS event
* occurring, that may have resulted in a change of QoS for the
* underlying session. This method updates the QoS object associated
* with this session.
*/
virtual int update_qos (void) = 0;
/// Get/Set methods for the flags_.
virtual ACE_End_Point_Type flags (void) const = 0;
virtual void flags (const ACE_End_Point_Type flags) = 0;
/// Get the session id.
virtual int session_id (void) const = 0;
/// Set the session id.
virtual void session_id (const int session_id) = 0;
/// Get the file descriptor on which RSVP events will occur.
virtual ACE_HANDLE rsvp_events_handle (void) = 0;
virtual void rsvp_event_type (RSVP_Event_Type event_type) = 0;
///Set the RAPI event that last occured
virtual RSVP_Event_Type rsvp_event_type (void) = 0;
///Get the RAPI event that last occured
/// Get the destination address for this session.
virtual ACE_INET_Addr dest_addr (void) const = 0;
/// Set the destination address for this session.
virtual void dest_addr (const ACE_INET_Addr &dest_addr) = 0;
/// Get the source port for this session.
virtual u_short source_port (void) const = 0;
/// Set the source port for this session.
virtual void source_port (const u_short &source_port) = 0;
//Set the source host
virtual ACE_INET_Addr* source_addr (void) const = 0;
/// Set the source port for this session.
virtual void source_addr (ACE_INET_Addr* source_addr) = 0;
/**
* Returns the version of the underlying RSVP implementation. Is
* meaningful only when the underlying implementation has
* versioning.
*/
virtual int version (void) = 0;
protected:
/// Source port if this is a Sender session. Used for rapi_sender ().
u_short source_port_;
/// session id for the session.
int session_id_;
/// Destination address for this session.
ACE_INET_Addr dest_addr_;
/// Source address for this session.
ACE_INET_Addr* src_addr_;
/// Is this a TCP or a UDP session.
ACE_Protocol_ID protocol_id_;
/// QoS for this session.
ACE_QoS qos_;
/// Specifies if this is a sending/receiving/both session.
ACE_End_Point_Type flags_;
RSVP_Event_Type rsvp_event_type_;
//Has the last rsvp event that occured
};
ACE_END_VERSIONED_NAMESPACE_DECL
#include /**/ "ace/post.h"
#endif /* ACE_QOS_SESSION_H */

View File

@@ -0,0 +1,101 @@
// QoS_Session_Factory.cpp
#include "QoS_Session_Factory.h"
#include "QoS_Session_Impl.h"
#include "ace/Log_Category.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_QoS_Session_Factory)
#if defined(ACE_HAS_RAPI)
const enum ACE_QoS_Session_Factory::ACE_QoS_Session_Type
ACE_QoS_Session_Factory::ACE_DEFAULT_QOS_SESSION = ACE_QoS_Session_Factory::ACE_RAPI_SESSION;
#elif defined(ACE_HAS_WINSOCK2_GQOS)
const enum ACE_QoS_Session_Factory::ACE_QoS_Session_Type
ACE_QoS_Session_Factory::ACE_DEFAULT_QOS_SESSION = ACE_QoS_Session_Factory::ACE_GQOS_SESSION;
#else
# error "QoS type not supported. Cannot build."
#endif /* ACE_HAS_RAPI */
ACE_QoS_Session_Factory::ACE_QoS_Session_Factory (void)
{
ACE_TRACE ("ACE_QoS_Session_Factory::ACE_QoS_Session_Factory");
}
ACE_QoS_Session_Factory::~ACE_QoS_Session_Factory (void)
{
ACE_TRACE ("ACE_QoS_Session_Factory::~ACE_QoS_Session_Factory");
}
// Create a QoS session of the given type (RAPI or GQoS).
ACE_QoS_Session *
ACE_QoS_Session_Factory::create_session (ACE_QoS_Session_Type qos_session_type)
{
ACE_QoS_Session * qos_session = 0;
#if defined (ACE_HAS_RAPI)
if (qos_session_type == ACE_RAPI_SESSION)
ACE_NEW_RETURN (qos_session,
ACE_RAPI_Session,
0);
#endif /* ACE_HAS_RAPI */
if (qos_session_type == ACE_GQOS_SESSION)
ACE_NEW_RETURN (qos_session,
ACE_GQoS_Session,
0);
if (this->add_session (qos_session) == -1)
{
delete qos_session;
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in adding session\n")),
0);
}
return qos_session;
}
// Destroy the QoS Session.
int
ACE_QoS_Session_Factory::destroy_session (ACE_QoS_Session *qos_session)
{
if ((qos_session != 0) && (this->remove_session (qos_session) == -1))
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in destroying session\n")),
-1);
return 0;
}
// Add a session to the set of sessions created by this factory. This is a
// private method called by the create_session ().
int
ACE_QoS_Session_Factory::add_session (ACE_QoS_Session *qos_session)
{
if (this->qos_session_set_.insert (qos_session) != 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in adding a new session")
ACE_TEXT ("to the session set\n")),
-1);
return 0;
}
// Remove a session from the set of sessions created by this factory. This is
// a private method called by the destroy_session ().
int
ACE_QoS_Session_Factory::remove_session (ACE_QoS_Session *qos_session)
{
if (this->qos_session_set_.remove (qos_session) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in removing a session")
ACE_TEXT ("from the session set\n")),
-1);
return 0;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,94 @@
// -*- C++ -*-
//=============================================================================
/**
* @file QoS_Session_Factory.h
*
* @author Vishal Kachroo <vishal@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_QOS_SESSION_FACTORY_H
#define ACE_QOS_SESSION_FACTORY_H
#include /**/ "ace/pre.h"
#include "ace/QoS/QoS_Session.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Containers_T.h"
#include "ACE_QoS_Export.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declare this, so the factory uses only references to this.
class ACE_QoS_Session;
/**
* @class ACE_QoS_Session_Factory
*
* @brief Concrete factory for the QoS Session objects.
*
* This class manages the life cycle of QoS Session objects. These
* objects are currently either RAPI session objects or GQoS session
* objects. It stores the sessions in an unbounded set.
*/
class ACE_QoS_Export ACE_QoS_Session_Factory
{
public :
// = Initialization and termination methods.
/// Default constructor.
ACE_QoS_Session_Factory (void);
/// Default destructor.
~ACE_QoS_Session_Factory (void);
/// Types of sessions for this factory to manage.
enum ACE_QoS_Session_Type
{
/// ACE_RAPI_SESSION on Unix platforms with RAPI support
ACE_RAPI_SESSION,
/// ACE_GQOS_SESSION on Windows platforms with GQOS support
ACE_GQOS_SESSION
};
/** The default QoS type supported on this platform.
*
* ACE_DEFAULT_QOS_SESSION = ACE_RAPI_SESSION on Unix platforms with RAPI support
* = ACE_GQOS_SESSION on Windows platforms with GQOS support
*/
static const enum ACE_QoS_Session_Type ACE_DEFAULT_QOS_SESSION;
/// Create a QoS session of the given type (RAPI or GQoS).
ACE_QoS_Session * create_session (ACE_QoS_Session_Type qos_session_type = ACE_DEFAULT_QOS_SESSION );
/// Destroy the QoS Session.
int destroy_session (ACE_QoS_Session *qos_session);
private:
/// Used by the create_session () to add new sessions to the
/// set of sessions created by this factory.
int add_session (ACE_QoS_Session *qos_session);
/// Used by the destroy_session () to remove a session from the set
/// of sessions created by this factory.
int remove_session (ACE_QoS_Session *qos_session);
/// Unordered set of QoS Sessions.
typedef ACE_Unbounded_Set <ACE_QoS_Session *> QOS_SESSION_SET;
QOS_SESSION_SET qos_session_set_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#include /**/ "ace/post.h"
#endif /* ACE_QOS_SESSION_FACTORY_H */

View File

@@ -0,0 +1,714 @@
// QoS_Session_Impl.cpp
#include "ace/OS_NS_arpa_inet.h"
#include "ace/SOCK.h"
#include "QoS_Manager.h"
#include "QoS_Session_Impl.h"
#include "ace/Log_Category.h"
#if !defined (__ACE_INLINE__)
#include "QoS_Session_Impl.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_QoS_Session_Impl)
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (ACE_HAS_RAPI)
#include "rapi_err.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
int ACE_RAPI_Session::rsvp_error = 0;
// Call back function used by RAPI to report RSVP events. This
// function translates the RAPI QoS parameters into the more generic
// ACE_QoS parameters for the underlying RAPI session.
int
rsvp_callback (rapi_sid_t /* sid */,
rapi_eventinfo_t eventype,
int /* style_id */,
int errcode,
int errvalue,
sockaddr * errnode,
u_char /* errflags */,
int /* filter_spec_no */,
rapi_filter_t * /* filter_spec_list */,
int flow_spec_no,
rapi_flowspec_t *flow_spec_list,
int /* ad_spec_no */,
rapi_adspec_t * /* ad_spec_list */,
void *args
)
{
if (args == 0)
ACELIB_DEBUG ((LM_DEBUG,
"Argument in the call back function is null\n\n"));
ACE_QoS_Session *qos_session = (ACE_QoS_Session *) args;
qos_flowspecx_t *csxp = 0;
if (!flow_spec_list)
{
ACELIB_DEBUG ((LM_DEBUG,
"(%N|%l) Null flow_spec_list\n"));
}
else
{
// Extended Legacy format.
csxp = &flow_spec_list->specbody_qosx;
if(!csxp)
{
ACELIB_ERROR_RETURN ((LM_ERROR,
"(%N|%l) Null csxp\n"),
-1);
}
}
ACE_QoS ace_qos = qos_session->qos ();
switch(eventype)
{
case RAPI_PATH_EVENT:
{
ACELIB_DEBUG ((LM_DEBUG,
"RSVP PATH Event received\n"
"No. of TSpecs received : %d %d\n",
flow_spec_no, &flow_spec_list->len));
ACE_Flow_Spec *receiving_fs = 0;
if (flow_spec_no != 0)
{
ACE_NEW_RETURN (receiving_fs,
ACE_Flow_Spec,
-1);
ACE_NEW_RETURN (receiving_fs,
ACE_Flow_Spec ((u_long)csxp->xspec_r,
(u_long)csxp->xspec_b,
(u_long)csxp->xspec_p,
0,
csxp->xspec_S,
1,
csxp->xspec_M,
csxp->xspec_m,
25,
0),
-1);
ACELIB_DEBUG ((LM_DEBUG,
"\nTSpec :\n"
"\t Spec Type = %d\n"
"\t Rate = %f\n"
"\t Bucket = %f\n"
"\t Peak = %f\n"
"\t MPU = %d\n"
"\t MDU = %d\n"
"\t TTL = %d\n",
csxp->spec_type,
csxp->xspec_r,
csxp->xspec_b,
csxp->xspec_p,
csxp->xspec_m,
csxp->xspec_M,
25));
}
// Set the sending flowspec QoS of the given session.
ace_qos.receiving_flowspec (receiving_fs);
qos_session->rsvp_event_type (ACE_QoS_Session::RSVP_PATH_EVENT);
}
break;
case RAPI_RESV_EVENT:
{
ACELIB_DEBUG ((LM_DEBUG,
"RSVP RESV Event received\n"
"No. of FlowSpecs received : %d\n",
flow_spec_no));
ACE_Flow_Spec *sending_flow = 0;
if (flow_spec_no != 0)
{
ACE_NEW_RETURN (sending_flow,
ACE_Flow_Spec,
-1);
// Choose based on the service type : [QOS_GUARANTEEDX/QOS_CNTR_LOAD].
switch (csxp->spec_type)
{
case QOS_GUARANTEEDX:
// Slack term in MICROSECONDS
sending_flow->delay_variation (csxp->xspec_S);
// @@How does the guaranteed rate parameter map to the ACE_Flow_Spec.
// Note there is no break !!
case QOS_CNTR_LOAD:
// qos_service_type.
sending_flow->service_type (csxp->spec_type);
// Token Bucket Average Rate (B/s)
sending_flow->token_rate ((u_long)csxp->xspec_r);
// Token Bucket Rate (B)
sending_flow->token_bucket_size ((u_long)csxp->xspec_b);
// Peak Data Rate (B/s)
sending_flow->peak_bandwidth ((u_long)csxp->xspec_p);
// Minimum Policed Unit (B)
sending_flow->minimum_policed_size (csxp->xspec_m);
// Max Packet Size (B)
sending_flow->max_sdu_size (csxp->xspec_M);
break;
default:
ACELIB_ERROR_RETURN ((LM_ERROR,
"(%N|%l) Unknown flowspec type: %u.\n", csxp->spec_type),
-1);
}
}
ace_qos.sending_flowspec (sending_flow);
qos_session->rsvp_event_type (ACE_QoS_Session::RSVP_RESV_EVENT);
}
break;
case RAPI_PATH_ERROR:
{
ACELIB_DEBUG ((LM_DEBUG,
"PATH ERROR Event received\n"
"Code=%d Val=%d Node= %s\n",
errcode,
errvalue,
ACE_OS::inet_ntoa(((sockaddr_in *)errnode)->sin_addr)));
qos_session->rsvp_event_type (ACE_QoS_Session::RSVP_PATH_ERROR);
}
break;
case RAPI_RESV_ERROR:
{
ACELIB_DEBUG ((LM_DEBUG,
"RESV ERROR Event received\n"
"Code=%d Val=%d Node= %s\n",
errcode,
errvalue,
ACE_OS::inet_ntoa(((sockaddr_in *)errnode)->sin_addr)));
qos_session->rsvp_event_type (ACE_QoS_Session::RSVP_RESV_ERROR);
}
break;
case RAPI_RESV_CONFIRM:
{
ACELIB_DEBUG ((LM_DEBUG,
"RESV CONFIRM Event received\n"));
qos_session->rsvp_event_type (ACE_QoS_Session::RSVP_RESV_CONFIRM);
}
break;
default:
ACELIB_DEBUG ((LM_DEBUG,
"Unknown RSVP Event Received\n"));
break;
}
// Set the updated ACE_QoS for the RSVP callback argument(QoS session).
qos_session->qos (ace_qos);
// @@ what is the meaning of the return value. RAPI docs don't say anything!
return 0;
}
// Constructor.
ACE_RAPI_Session::ACE_RAPI_Session (void)
{
ACE_TRACE ("ACE_RAPI_Session::ACE_RAPI_Session");
//this->source_port (DEFAULT_SOURCE_SENDER_PORT);
ACE_NEW (this->src_addr_,
ACE_INET_Addr ("0"));
}
// Open a RAPI QoS session [dest IP, dest port, Protocol ID].
int
ACE_RAPI_Session::open (ACE_INET_Addr dest_addr,
ACE_Protocol_ID protocol_id)
{
char buf [BUFSIZ];
dest_addr.addr_to_string (buf,
BUFSIZ);
ACELIB_DEBUG ((LM_DEBUG,
"In RAPI SESSION OPEN %s\n",
buf));
this->dest_addr_ = dest_addr;
this->protocol_id_ = protocol_id;
// Open a RAPI session. Note "this" is being passed as an argument to
// the callback function. The callback function uses this argument to
// update the QoS of this session based on the RSVP event it receives.
if ((this->session_id_ = rapi_session((struct sockaddr *) dest_addr.get_addr (),
protocol_id,
0,
rsvp_callback,
(void *) this,
&rsvp_error)) == NULL_SID)
ACELIB_ERROR_RETURN ((LM_ERROR,
"rapi_session () call fails. Error\n"),
-1);
else
ACELIB_DEBUG ((LM_DEBUG,
"rapi_session () call succeeds. "
"Session ID = %d\n",
this->session_id_));
return 0;
}
// Close the RAPI QoS Session.
int
ACE_RAPI_Session::close (void)
{
this->rsvp_error = rapi_release(this->session_id_);
if (rsvp_error == 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
"Can't release RSVP session:\n\t%s\n",
rapi_errlist[rsvp_error]),
-1);
else
ACELIB_DEBUG ((LM_DEBUG,
"rapi session with id %d released successfully.\n",
this->session_id_));
return 0;
}
//Get the most recent RSVP event that occured
ACE_QoS_Session::RSVP_Event_Type
ACE_RAPI_Session::rsvp_event_type (void)
{
return this->rsvp_event_type_;
}
//Set the most recent RSVP event that occured
void
ACE_RAPI_Session::rsvp_event_type (ACE_QoS_Session::RSVP_Event_Type event_type)
{
this->rsvp_event_type_ = event_type;
}
int
ACE_RAPI_Session::qos (ACE_SOCK * /* socket */,
ACE_QoS_Manager * /* qos_manager */,
const ACE_QoS &ace_qos)
{
// If sender : call sending_qos ()
// If receiver : call receiving_qos ()
// If both : call sending_qos () and receiving_qos ()
if (this->flags_ != ACE_QOS_RECEIVER)
return this->sending_qos (ace_qos);
if (this->flags_ != ACE_QOS_SENDER)
return this->receiving_qos (ace_qos);
return 0;
}
// Set sending QoS for this RAPI session.
int
ACE_RAPI_Session::sending_qos (const ACE_QoS &ace_qos)
{
ACE_Flow_Spec *sending_flowspec = ace_qos.sending_flowspec ();
if (sending_flowspec == 0)
{
int result = rapi_sender (this->session_id_,
0,
0,
0,
0,
0,
0,
25);
if (result != 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
"(%N|%l) rapi_sender error %d:\n\tPATH Generation can't be started\n",
result),
-1);
else
ACELIB_DEBUG ((LM_DEBUG,
"rapi_sender () call succeeds with PATH Tear!\n"));
return 0;
}
rapi_tspec_t *t_spec = this->init_tspec_simplified (*sending_flowspec);
if (t_spec == 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
"(%N|%l) Error in translating from ACE Flow Spec to"
" RAPI TSpec\n"),
-1);
char buffer[BUFSIZ];
// This formats the t_spec in a visually intuitive char * that can
// be printed.
(void) rapi_fmt_tspec(t_spec, buffer, sizeof(buffer));
ACELIB_DEBUG ((LM_DEBUG,
"\nSender TSpec : %s\n",
buffer));
// Print out all the fields separately.
ACELIB_DEBUG ((LM_DEBUG,
"\nTSpec :\n"
"\t Spec Type = %d\n"
"\t Rate = %f\n"
"\t Bucket = %f\n"
"\t Peak = %f\n"
"\t MPU = %d\n"
"\t MDU = %d\n"
"\t TTL = %d\n",
t_spec->tspecbody_qosx.spec_type,
t_spec->tspecbody_qosx.xtspec_r,
t_spec->tspecbody_qosx.xtspec_b,
t_spec->tspecbody_qosx.xtspec_p,
t_spec->tspecbody_qosx.xtspec_m,
t_spec->tspecbody_qosx.xtspec_M,
sending_flowspec->ttl ()));
// This the source sender port.
// ACE_INET_Addr sender_addr (this->source_port ());
ACELIB_DEBUG ((LM_DEBUG,
"Making the rapi_sender () call\n"));
// Set the Sender TSpec for this QoS session.
int result = rapi_sender(this->session_id_,
0,
(sockaddr *) this->src_addr_->get_addr (),
0,
t_spec,
0,
0,
sending_flowspec->ttl ()) ;
/*
int result = rapi_sender(this->session_id_,
0,
(sockaddr *) sender_addr.get_addr (),
0,
t_spec,
0,
0,
sending_flowspec->ttl ()) ;
*/
if(result!= 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
"(%N|%l) rapi_sender error %d:\n\tPATH Generation can't be started\n",
result),
-1);
else
ACELIB_DEBUG ((LM_DEBUG,
"rapi_sender () call succeeds !\n"));
return 0;
}
// Set receiving QoS for this RAPI session.
int
ACE_RAPI_Session::receiving_qos (const ACE_QoS &ace_qos)
{
ACE_Flow_Spec *receiving_flowspec = ace_qos.receiving_flowspec ();
if (receiving_flowspec == 0)
{
if (rapi_reserve(this->session_id_,
0,
// Setting the RAPI_REQ_CONFIRM flag requests confirmation
// of the resevation, by means of a confirmation upcall of
// type RAPI_RESV_CONFIRM.
// (sockaddr *)receiver_addr.get_addr (),
0,
RAPI_RSTYLE_WILDCARD,
// This applies the flowspec to all the senders. Given this,
// @@I am passing the filter_spec to be null, hoping this will work.
0,
0,
0,
0,
// The filter spec is NULL. This should work since the RSTYLE is
// WILDCARD.
0,
0) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
"(%N|%l)rapi_reserve () error:\n\tRESV Generation can't be started\n"),
-1);
else
ACELIB_DEBUG ((LM_DEBUG,
"rapi_reserve () for RESV Tear call succeeds\n"));
return 0;
}
rapi_flowspec_t *flow_spec = init_flowspec_simplified (*receiving_flowspec);
if (flow_spec == 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
"(%N|%l) Error in translating from ACE Flow Spec to"
" RAPI FlowSpec\n"),
-1);
char buffer[BUFSIZ];
// This formats the flow_spec in a visually intuitive char * that can
// be printed.
(void)rapi_fmt_flowspec(flow_spec, buffer, sizeof(buffer));
ACELIB_DEBUG ((LM_DEBUG,
"\nReceiver FlowSpec : %s\n",
buffer));
// Print out all the fields separately.
ACELIB_DEBUG ((LM_DEBUG,
"\nFlowSpec :\n"
"\t Spec Type = %d\n"
"\t Rate = %f\n"
"\t Bucket = %f\n"
"\t Peak = %f\n"
"\t MPU = %d\n"
"\t MDU = %d\n",
flow_spec->specbody_qosx.spec_type,
flow_spec->specbody_qosx.xspec_r,
flow_spec->specbody_qosx.xspec_b,
flow_spec->specbody_qosx.xspec_p,
flow_spec->specbody_qosx.xspec_m,
flow_spec->specbody_qosx.xspec_M));
sockaddr_in Receiver_host;
Receiver_host.sin_addr.s_addr = INADDR_ANY;
// Set the Receiver FlowSpec for this QoS session.
// @@The filter style is hardcoded to WildCard. This can be changed later.
if (rapi_reserve(this->session_id_,
RAPI_REQ_CONFIRM,
// Setting the RAPI_REQ_CONFIRM flag requests confirmation
// of the resevation, by means of a confirmation upcall of
// type RAPI_RESV_CONFIRM.
// (sockaddr *)receiver_addr.get_addr (),
(sockaddr *)&Receiver_host,
RAPI_RSTYLE_WILDCARD,
// This applies the flowspec to all the senders. Given this,
// @@I am passing the filter_spec to be null, hoping this will work.
0,
0,
0,
0,
// The filter spec is NULL. This should work since the RSTYLE is
// WILDCARD.
1,
flow_spec) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
"rapi_reserve () error:\n\tRESV Generation can't be started\n"),
-1);
else
ACELIB_DEBUG ((LM_DEBUG,
"rapi_reserve () call succeeds\n"));
return 0;
}
int
ACE_RAPI_Session::update_qos (void)
{
// Update the session QoS Parameters based on the RSVP Event Received.
if ((rsvp_error = rapi_dispatch ()) != 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
"Error in rapi_dispatch () : %s\n",
rapi_errlist[rsvp_error]),
-1);
return 0;
}
// Construct a simplified RAPI Sender TSpec object
// from an ACE_Flow_Spec. Note the form of the TSpec is
// simplified as against the full bodied IntServ version.
rapi_tspec_t *
ACE_RAPI_Session::init_tspec_simplified (const ACE_Flow_Spec &flow_spec)
{
rapi_tspec_t *t_spec;
ACE_NEW_RETURN (t_spec,
rapi_tspec_t,
0);
qos_tspecx_t *ctxp = &(t_spec->tspecbody_qosx);
// There may be some type incompatibility here.
// Note the types of the LHS are float32_t, uint32_t etc.
ctxp->spec_type = flow_spec.service_type ();//QOS_TSPEC;
ctxp->xtspec_r = flow_spec.token_rate (); // Token Rate (B/s)
ctxp->xtspec_b = flow_spec.token_bucket_size (); // Token Bucket Depth (B)
ctxp->xtspec_p = flow_spec.peak_bandwidth (); // Peak Data Rate (B/s)
ctxp->xtspec_m = flow_spec.minimum_policed_size (); // Minimum policed unit.
ctxp->xtspec_M = flow_spec.max_sdu_size(); // Maximum SDU size.
t_spec->len = sizeof(rapi_hdr_t) + sizeof(qos_tspecx_t);
t_spec->form = RAPI_TSPECTYPE_Simplified;
return (t_spec);
}
// Construct a simplified RAPI flowspec object from ACE_Flow_Spec.
// Note the form of the FlowSpec is simplified as against the
// full bodied IntServ version.
rapi_flowspec_t *
ACE_RAPI_Session::init_flowspec_simplified(const ACE_Flow_Spec &flow_spec)
{
rapi_flowspec_t *flowsp;
ACE_NEW_RETURN (flowsp,
rapi_flowspec_t,
0);
// Extended Legacy format.
qos_flowspecx_t *csxp = &flowsp->specbody_qosx;
// Choose based on the service type : [QOS_GUARANTEEDX/QOS_CNTR_LOAD].
switch (flow_spec.service_type ())
{
case QOS_GUARANTEEDX:
csxp->xspec_R = 0 ; // Guaranteed Rate B/s. @@How does this map to the
// ACE Flow Spec Parameters.
csxp->xspec_S = flow_spec.delay_variation () ; // Slack term in MICROSECONDS
// Note there is no break !!
case QOS_CNTR_LOAD:
csxp->spec_type = flow_spec.service_type (); // qos_service_type
csxp->xspec_r = flow_spec.token_rate (); // Token Bucket Average Rate (B/s)
csxp->xspec_b = flow_spec.token_bucket_size (); // Token Bucket Rate (B)
csxp->xspec_p = flow_spec.peak_bandwidth (); // Peak Data Rate (B/s)
csxp->xspec_m = flow_spec.minimum_policed_size (); // Minimum Policed Unit (B)
csxp->xspec_M = flow_spec.max_sdu_size(); // Max Packet Size (B)
flowsp->form = RAPI_FLOWSTYPE_Simplified;
break;
default:
ACELIB_ERROR_RETURN ((LM_ERROR,
"(%N|%l) Unknown flowspec type: %u\n",flow_spec.service_type () ),
0);
}
flowsp->len = sizeof(rapi_flowspec_t);
return flowsp;
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_RAPI */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// This is a GQoS session ID generator.
int ACE_GQoS_Session::GQoS_session_id = 0;
// Constructor.
ACE_GQoS_Session::ACE_GQoS_Session (void)
{
ACE_TRACE ("ACE_GQoS_Session::ACE_GQoS_Session");
}
// Open a GQoS session [dest IP, dest port, Protocol ID].
int
ACE_GQoS_Session::open (ACE_INET_Addr dest_addr,
ACE_Protocol_ID protocol_id)
{
this->dest_addr_ = dest_addr;
this->protocol_id_ = protocol_id;
this->session_id_ = GQoS_session_id++;
return 0;
}
// Close the GQoS Session.
int
ACE_GQoS_Session::close (void)
{
// TBD.
return 0;
}
// Set the QoS for this GQoS session.
int
ACE_GQoS_Session::qos (ACE_SOCK *socket,
ACE_QoS_Manager *qos_manager,
const ACE_QoS &ace_qos)
{
// Confirm if the current session is one of the QoS sessions
// subscribed to by the given socket.
if (qos_manager->qos_session_set ().find (this) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("This QoS session was not subscribed to")
ACE_TEXT (" by the socket\n")),
-1);
// Set the QOS according to the supplied ACE_QoS. The I/O control
// code used under the hood is SIO_SET_QOS.
u_long ret_bytes = 0;
ACE_QoS qos = ace_qos;
if (ACE_OS::ioctl (socket->get_handle (),
ACE_SIO_SET_QOS,
qos,
&ret_bytes) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in Qos set ACE_OS::ioctl() %d\n"),
ret_bytes),
-1);
else
ACELIB_DEBUG ((LM_DEBUG,
ACE_TEXT ("Setting QoS with ACE_OS::ioctl () succeeds\n")));
return 0;
}
int
ACE_GQoS_Session::update_qos (void)
{
// WSAIoctl (GET_QOS) call goes here...
return 0;
}
//Get the most recent RSVP event that occured
ACE_QoS_Session::RSVP_Event_Type
ACE_GQoS_Session::rsvp_event_type (void)
{
return this->rsvp_event_type_;
}
//Set the most recent RSVP event that occured
void
ACE_GQoS_Session::rsvp_event_type (ACE_QoS_Session::RSVP_Event_Type event_type)
{
this->rsvp_event_type_ = event_type;
}
ACE_END_VERSIONED_NAMESPACE_DECL

263
deps/acelite/ace/QoS/QoS_Session_Impl.h vendored Normal file
View File

@@ -0,0 +1,263 @@
// -*- C++ -*-
//=============================================================================
/**
* @file QoS_Session_Impl.h
*
* @author Vishal Kachroo <vishal@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_QOS_SESSION_IMPL_H
#define ACE_QOS_SESSION_IMPL_H
#include /**/ "ace/pre.h"
#include "ace/QoS/QoS_Session.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_RAPI)
#include "rapi_lib.h"
#define DEFAULT_SOURCE_SENDER_PORT 10001
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_RAPI_Session
*
* @brief A RAPI QoS session object.
*
* This class is a RAPI (RSVP API, an implementation of RSVP on UNIX)
* implementation of the ACE_QoS_Session interface.
*/
class ACE_QoS_Export ACE_RAPI_Session : public ACE_QoS_Session
{
public:
/// Default destructor.
~ACE_RAPI_Session (void);
/// Error handling for RSVP callback
static int rsvp_error;
/// Open a RAPI QoS session [dest IP, dest port, Protocol ID].
virtual int open (ACE_INET_Addr dest_addr,
ACE_Protocol_ID protocol_id);
/// Close the RAPI QoS Session.
virtual int close (void);
/// Returns the QoS for this RAPI session.
virtual ACE_QoS qos (void) const;
/// Set QoS for this RAPI session. The socket parameter is used to confirm if
/// this QoS session was subscribed to by the socket.
virtual int qos (ACE_SOCK *socket,
ACE_QoS_Manager *qos_manager,
const ACE_QoS &ace_qos);
/**
* Sets the QoS for this session object to ace_qos. Does not interfere with the
* QoS in the underlying socket. This call is useful to update the QoS object
* when the underlying socket QoS is being set through a mechanism other than
* the previous qos () method e.g. inside the dgram_mcast.subscribe () where the
* QoS for the socket is set through ACE_OS::join_leaf ().
*/
virtual void qos (const ACE_QoS &ace_qos);
/**
* Calls rapi_dispatch () that further triggers the call back function.
* It is a mechanism of updating the QoS for this session asynchronously, as
* RSVP events occur.
*/
virtual int update_qos (void);
/// Get methods for the flags_.
virtual ACE_End_Point_Type flags (void) const;
/// Set methods for the flags_.
virtual void flags (const ACE_End_Point_Type flags);
/// Get the RAPI session id.
virtual int session_id (void) const;
/// Set the RAPI session id.
virtual void session_id (const int session_id);
/// Get the RAPI file descriptor for RSVP events.
virtual ACE_HANDLE rsvp_events_handle (void);
///Set the RAPI event that last occured
virtual void rsvp_event_type (RSVP_Event_Type event_type);
///Get the RAPI event that last occured
virtual RSVP_Event_Type rsvp_event_type (void);
/// Get the destination address for this RAPI session.
virtual ACE_INET_Addr dest_addr (void) const;
/// Set the destination address for this RAPI session.
virtual void dest_addr (const ACE_INET_Addr &dest_addr);
/// Get the source port for this session.
virtual u_short source_port (void) const;
/// Set the source port for this session.
virtual void source_port (const u_short &source_port);
//Set the source host
virtual ACE_INET_Addr* source_addr (void) const;
/// Set the source port for this session.
virtual void source_addr (ACE_INET_Addr* source_addr);
/// RAPI version. Returned value = 100 * major-version + minor-version.
virtual int version ();
/// The factory is a friend so it can create this object through
/// the only private constructor.
friend class ACE_QoS_Session_Factory;
private:
/// Default constuctor. Constructor is defined private so that only
/// the friend factory can instantiate this class.
ACE_RAPI_Session (void);
/// Construct a simplified RAPI Sender TSpec object
/// from an ACE_Flow_Spec object. Used internally by this class.
rapi_tspec_t *init_tspec_simplified (const ACE_Flow_Spec &flow_spec);
/// Construct a simplified RAPI Receiver FlowSpec object
/// from an ACE_Flow_Spec object. Used internally by the class.
rapi_flowspec_t *init_flowspec_simplified(const ACE_Flow_Spec &flow_spec);
/// Set sending QoS for this RAPI session.
int sending_qos (const ACE_QoS &ace_qos);
/// Set receiving QoS for this RAPI session.
int receiving_qos (const ACE_QoS &ace_qos);
};
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_RAPI */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_GQoS_Session
*
* @brief A GQoS session object.
*
* This class is a GQoS (Generic QoS, an implementation of RSVP on
* Win2K) implementation of the ACE_QoS_Session interface.
*/
class ACE_QoS_Export ACE_GQoS_Session : public ACE_QoS_Session
{
public:
/// Default destructor.
~ACE_GQoS_Session (void);
/// This is a session ID generator. It does a lot more than expected
/// from an int!.
static int GQoS_session_id;
/// Open a GQoS session [dest IP, dest port, Protocol ID].
virtual int open (ACE_INET_Addr dest_addr,
ACE_Protocol_ID protocol_id);
/// Close the GQoS Session.
virtual int close (void);
/// Returns the QoS for this GQoS session.
virtual ACE_QoS qos (void) const;
/// Set QoS for this GQoS session. The socket parameter is used to confirm if
/// this QoS session was subscribed to by the socket.
virtual int qos (ACE_SOCK *socket,
ACE_QoS_Manager *qos_manager,
const ACE_QoS &ace_qos);
/**
* Sets the QoS for this session object to ace_qos. Does not interfere with the
* QoS in the underlying socket. This call is useful to update the QoS object
* when the underlying socket QoS is being set through a mechanism other than
* the previous qos () method e.g. inside the dgram_mcast.subscribe () where the
* QoS for the socket is set through ACE_OS::join_leaf ().
*/
virtual void qos (const ACE_QoS &ace_qos);
/// Calls the ioctl (ACE_SIO_GET_QOS). It is a mechanism of updating the
/// QoS for this session asynchronously, as RSVP events occur.
virtual int update_qos (void);
/// Get/Set methods for the flags_.
virtual ACE_End_Point_Type flags (void) const;
virtual void flags (const ACE_End_Point_Type flags);
/// Get the destination address for this GQoS session.
virtual ACE_INET_Addr dest_addr (void) const;
/// Set the destination address for this GQoS session.
virtual void dest_addr (const ACE_INET_Addr &dest_addr);
/// Get the source port for this session.
virtual u_short source_port (void) const;
/// Set the source port for this session.
virtual void source_port (const u_short &source_port);
//Set the source host
virtual ACE_INET_Addr* source_addr (void) const;
/// Set the source port for this session.
virtual void source_addr (ACE_INET_Addr* source_addr);
/// Get the GQoS session id.
virtual int session_id (void) const;
/// Set the GQoS session id.
virtual void session_id (const int session_id);
/// Get the file descriptor of the underlying socket.
virtual ACE_HANDLE rsvp_events_handle (void);
virtual void rsvp_event_type (RSVP_Event_Type event_type);
///Set the RAPI event that last occured
virtual RSVP_Event_Type rsvp_event_type (void);
///Get the RAPI event that last occured
/// GQoS version.
virtual int version ();
/// The factory is a friend so it can create this object through
/// the only private constructor.
friend class ACE_QoS_Session_Factory;
private:
/// Default constructor. Constructor is defined private so that only
/// the friend factory can instantiate this class.
ACE_GQoS_Session (void);
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "QoS_Session_Impl.inl"
#endif /* __ACE_INLINE__ */
#include /**/ "ace/post.h"
#endif /* ACE_QOS_SESSION_IMPL_H */

View File

@@ -0,0 +1,226 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
#if defined (ACE_HAS_RAPI)
ACE_INLINE
ACE_RAPI_Session::~ACE_RAPI_Session (void)
{
ACE_TRACE ("ACE_RAPI_Session::~ACE_RAPI_Session");
}
// Returns the QoS for this RAPI session.
ACE_INLINE ACE_QoS
ACE_RAPI_Session::qos (void) const
{
return this->qos_;
}
// Overloaded method to set the QoS for this session object. Does not
// interfere with the underlying socket QoS.
ACE_INLINE void
ACE_RAPI_Session::qos (const ACE_QoS &ace_qos)
{
this->qos_ = ace_qos;
}
// Get the RAPI session id.
ACE_INLINE int
ACE_RAPI_Session::session_id (void) const
{
return this->session_id_;
}
// Set the RAPI session id.
ACE_INLINE void
ACE_RAPI_Session::session_id (const int session_id)
{
this->session_id_ = session_id;
}
// Get the RAPI file desciptor for RSVP events.
ACE_INLINE ACE_HANDLE
ACE_RAPI_Session::rsvp_events_handle (void)
{
int rapi_fd = rapi_getfd (this->session_id ());
if (rapi_fd == -1)
{
this->close ();
ACELIB_ERROR_RETURN ((LM_ERROR,
"Error in rapi_getfd ()\n"),
-1);
}
return rapi_fd;
}
// Get the End Point Type (Sender/Receiver/Both).
ACE_INLINE ACE_QoS_Session::ACE_End_Point_Type
ACE_RAPI_Session::flags (void) const
{
return this->flags_;
}
// Set the End Point Type (Sender/Receiver/Both).
ACE_INLINE void
ACE_RAPI_Session::flags (const ACE_End_Point_Type flags)
{
this->flags_ = flags;
}
// Get the destination address for this RAPI session.
ACE_INLINE ACE_INET_Addr
ACE_RAPI_Session::dest_addr (void) const
{
return this->dest_addr_;
}
// Set the destination address for this RAPI session.
ACE_INLINE void
ACE_RAPI_Session::dest_addr (const ACE_INET_Addr &dest_addr)
{
this->dest_addr_ = dest_addr;
}
// Get the source port for this RAPI session.
ACE_INLINE u_short
ACE_RAPI_Session::source_port (void) const
{
return this->source_port_;
}
// Set the source port for this RAPI session.
ACE_INLINE void
ACE_RAPI_Session::source_port (const u_short &source_port)
{
this->source_port_ = source_port;
}
ACE_INLINE ACE_INET_Addr*
ACE_RAPI_Session::source_addr (void) const
{
return this->src_addr_;
}
ACE_INLINE void
ACE_RAPI_Session::source_addr (ACE_INET_Addr* source_addr)
{
this->src_addr_ = source_addr;
}
// RAPI version. Returned value = 100 * major-version + minor-version.
ACE_INLINE int
ACE_RAPI_Session::version (void)
{
return 0;
}
#endif /* ACE_HAS_RAPI */
ACE_INLINE
ACE_GQoS_Session::~ACE_GQoS_Session (void)
{
ACE_TRACE ("ACE_GQoS_Session::~ACE_GQoS_Session");
}
// Returns the QoS for this GQoS session.
ACE_INLINE ACE_QoS
ACE_GQoS_Session::qos (void) const
{
return this->qos_;
}
// Overloaded method to set the QoS for this session object. Does not
// interfere with the underlying socket QoS.
ACE_INLINE void
ACE_GQoS_Session::qos (const ACE_QoS &ace_qos)
{
this->qos_ = ace_qos;
}
// Get the GQoS session id.
ACE_INLINE int
ACE_GQoS_Session::session_id (void) const
{
return this->session_id_;
}
// Set the GQoS session id.
ACE_INLINE void
ACE_GQoS_Session::session_id (const int session_id)
{
this->session_id_ = session_id;
}
// Get the underlying file desciptor for RSVP events.
// Currently returns 0 because GQoS does not have a special
// descriptor for QoS events.
ACE_INLINE ACE_HANDLE
ACE_GQoS_Session::rsvp_events_handle (void)
{
return 0;
}
// Get the End Point Type (Sender/Receiver/Both).
ACE_INLINE ACE_QoS_Session::ACE_End_Point_Type
ACE_GQoS_Session::flags (void) const
{
return this->flags_;
}
// Set the End Point Type (Sender/Receiver/Both).
ACE_INLINE void
ACE_GQoS_Session::flags (const ACE_End_Point_Type flags)
{
this->flags_ = flags;
}
// Get the destination address for this GQoS session.
ACE_INLINE ACE_INET_Addr
ACE_GQoS_Session::dest_addr (void) const
{
return this->dest_addr_;
}
// Set the destination address for this GQoS session.
ACE_INLINE void
ACE_GQoS_Session::dest_addr (const ACE_INET_Addr &dest_addr)
{
this->dest_addr_ = dest_addr;
}
// Get the source port for this RAPI session.
ACE_INLINE u_short
ACE_GQoS_Session::source_port (void) const
{
return this->source_port_;
}
// Set the source port for this RAPI session.
ACE_INLINE void
ACE_GQoS_Session::source_port (const u_short &source_port)
{
this->source_port_ = source_port;
}
ACE_INLINE ACE_INET_Addr*
ACE_GQoS_Session::source_addr (void) const
{
return this->src_addr_;
}
ACE_INLINE void
ACE_GQoS_Session::source_addr (ACE_INET_Addr* source_addr)
{
this->src_addr_ = source_addr;
}
// GQoS version.
ACE_INLINE int
ACE_GQoS_Session::version (void)
{
return 0;
}
ACE_END_VERSIONED_NAMESPACE_DECL

55
deps/acelite/ace/QoS/README vendored Normal file
View File

@@ -0,0 +1,55 @@
ACE QoS API (AQoSA)
===================
This directory contains the implementation for the ACE QoS API (AQoSA).
BUILD REQUIREMENTS
==================
WIN2K :
AQoSA makes use of the GQOS API under Windows 2000. The minimum
requirements are:
1. June98 Platform SDK or later.
2. Link with ws2_32.lib
More information about GQOS is available from the MSDN website:
http://msdn.microsoft.com/msdn-files/026/002/258/Search.asp
-------------------------------------------------------------------------------
UNIX :
AQoSA makes use of the RSVP API (RAPI) under UNIX.
RAPI can be obtained from: ftp://ftp.isi.edu/rsvp/release/.
rsvpd.rel4.2a4-1 may require patches in order to compile
under current versions of Linux. Contact Craig Rodrigues <crodrigu@bbn.com>
to obtain these patches.
The following lines should be added to your platform_macros.GNU file
before building AQoSA:
PLATFORM_RAPI_CPPFLAGS += -I[path to RAPI header files]
PLATFORM_RAPI_LIBS += -lrsvp
PLATFORM_RAPI_LDFLAGS += -L[path to RAPI library files]
1. Compile AQoSA with
make rapi=1
More information about RAPI can be found at:
http://www.opengroup.org/onlinepubs/9619099/toc.htm
http://www.cs.wustl.edu/~vishal/qos.html
http://www.sun.com/software/bandwidth/rsvp/docs/
http://www.tru64unix.compaq.com/faqs/publications/base_doc/DOCUMENTATION/V51_HTML/ARH9UCTE/TOC.HTM#RSVPCHXX
-------------------------------------------------------------------------------
TEST
====
The test for AQoSA is located in $ACE_ROOT/examples/QOS

View File

@@ -0,0 +1,252 @@
#include "SOCK_Dgram_Mcast_QoS.h"
#include "ace/Log_Category.h"
#include "ace/OS_NS_sys_socket.h"
#if defined (ACE_WIN32)
#include "ace/Sock_Connect.h" // needed for subscribe_ifs()
#endif /* ACE_WIN32 */
#if !defined (__ACE_INLINE__)
#include "SOCK_Dgram_Mcast_QoS.inl"
#endif /* __ACE_INLINE__ */
// This is a workaround for platforms with non-standard
// definitions of the ip_mreq structure
#if ! defined (IMR_MULTIADDR)
#define IMR_MULTIADDR imr_multiaddr
#endif /* ! defined (IMR_MULTIADDR) */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Mcast_QoS)
// Dummy default constructor...
ACE_SOCK_Dgram_Mcast_QoS::ACE_SOCK_Dgram_Mcast_QoS (options opts)
: ACE_SOCK_Dgram_Mcast (opts)
{
ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::ACE_SOCK_Dgram_Mcast_QoS");
}
int
ACE_SOCK_Dgram_Mcast_QoS::open (const ACE_INET_Addr &addr,
const ACE_QoS_Params &qos_params,
int protocol_family,
int protocol,
ACE_Protocol_Info *protocolinfo,
ACE_SOCK_GROUP g,
u_long flags,
int reuse_addr)
{
ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::open");
ACE_UNUSED_ARG (qos_params);
// Only perform the <open> initialization if we haven't been opened
// earlier.
if (this->get_handle () != ACE_INVALID_HANDLE)
return 0;
ACELIB_DEBUG ((LM_DEBUG,
"Get Handle Returns Invalid Handle\n"));
if (ACE_SOCK::open (SOCK_DGRAM,
protocol_family,
protocol,
protocolinfo,
g,
flags,
reuse_addr) == -1)
return -1;
return this->open_i (addr, 0, reuse_addr);
}
int
ACE_SOCK_Dgram_Mcast_QoS::subscribe_ifs (const ACE_INET_Addr &mcast_addr,
const ACE_QoS_Params &qos_params,
const ACE_TCHAR *net_if,
int protocol_family,
int protocol,
int reuse_addr,
ACE_Protocol_Info *protocolinfo)
{
ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::subscribe_ifs");
#if defined (ACE_WIN32)
// Windows NT's winsock has trouble with multicast subscribes in the
// presence of multiple network interfaces when the IP address is
// given as INADDR_ANY. It will pick the first interface and only
// accept mcast there. So, to work around this, cycle through all
// of the interfaces known and subscribe to all the non-loopback
// ones.
//
// Note that this only needs to be done on NT, but there's no way to
// tell at this point if the code will be running on NT - only if it
// is compiled for NT-only or for NT/95, and that doesn't really
// help us. It doesn't hurt to do this on Win95, it's just a little
// slower than it normally would be.
//
// NOTE - <ACE_Sock_Connect::get_ip_interfaces> doesn't always get all
// of the interfaces. In particular, it may not get a PPP interface. This
// is a limitation of the way <ACE_Sock_Connect::get_ip_interfaces> works
// with MSVC. The reliable way of getting the interface list is
// available only with MSVC 5.
if (net_if == 0)
{
ACE_INET_Addr *if_addrs = 0;
size_t if_cnt;
if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
return -1;
size_t nr_subscribed = 0;
if (if_cnt < 2)
{
if (this->subscribe (mcast_addr,
qos_params,
reuse_addr,
ACE_TEXT ("0.0.0.0"),
protocol_family,
protocol,
protocolinfo) == 0)
++nr_subscribed;
}
else
// Iterate through all the interfaces, figure out which ones
// offer multicast service, and subscribe to them.
while (if_cnt > 0)
{
--if_cnt;
// Convert to 0-based for indexing, next loop check.
if (if_addrs[if_cnt].is_loopback())
continue;
if (this->subscribe (mcast_addr,
qos_params,
reuse_addr,
ACE_TEXT_CHAR_TO_TCHAR
(if_addrs[if_cnt].get_host_addr()),
protocol_family,
protocol,
protocolinfo) == 0)
++nr_subscribed;
}
delete [] if_addrs;
if (nr_subscribed == 0)
{
errno = ENODEV;
return -1;
}
else
// 1 indicates a "short-circuit" return. This handles the
// rather bizarre semantics of checking all the interfaces on
// NT.
return 1;
}
#else
ACE_UNUSED_ARG (mcast_addr);
ACE_UNUSED_ARG (qos_params);
ACE_UNUSED_ARG (protocol_family);
ACE_UNUSED_ARG (protocol);
ACE_UNUSED_ARG (reuse_addr);
ACE_UNUSED_ARG (protocolinfo);
#endif /* ACE_WIN32 */
// Otherwise, do it like everyone else...
// Create multicast request.
if (this->make_multicast_ifaddr (0,
mcast_addr,
net_if) == -1)
return -1;
else
return 0;
}
int
ACE_SOCK_Dgram_Mcast_QoS::subscribe (const ACE_INET_Addr &mcast_addr,
const ACE_QoS_Params &qos_params,
int reuse_addr,
const ACE_TCHAR *net_if,
int protocol_family,
int protocol,
ACE_Protocol_Info *protocolinfo,
ACE_SOCK_GROUP g,
u_long flags,
ACE_QoS_Session *qos_session)
{
ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::subscribe");
if (this->open (mcast_addr,
qos_params,
protocol_family,
protocol,
protocolinfo,
g,
flags,
reuse_addr) == -1)
return -1;
// The following method call only applies to Win32 currently.
int result = this->subscribe_ifs (mcast_addr,
qos_params,
net_if,
protocol_family,
protocol,
reuse_addr,
protocolinfo);
// Check for the "short-circuit" return value of 1 (for NT).
if (result != 0)
return result;
// Tell network device driver to read datagrams with a
// <mcast_request_if_> IP interface.
else
{
// Check if the mcast_addr passed into this method is the
// same as the QoS session address.
if (qos_session != 0 && mcast_addr == qos_session->dest_addr ())
{
// Subscribe to the QoS session.
if (this->qos_manager_.join_qos_session (qos_session) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Unable to join QoS Session\n")),
-1);
}
else
{
if (this->close () != 0)
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("Unable to close socket\n")));
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Dest Addr in the QoS Session does")
ACE_TEXT (" not match the address passed into")
ACE_TEXT (" subscribe\n")),
-1);
}
ip_mreq ret_mreq;
this->make_multicast_ifaddr (&ret_mreq, mcast_addr, net_if);
// XX This is windows stuff only. fredk
if (ACE_OS::join_leaf (this->get_handle (),
reinterpret_cast<const sockaddr *> (&ret_mreq.IMR_MULTIADDR.s_addr),
sizeof ret_mreq.IMR_MULTIADDR.s_addr,
qos_params) == ACE_INVALID_HANDLE
&& errno != ENOTSUP)
return -1;
else
if (qos_params.socket_qos () != 0 && qos_session != 0)
qos_session->qos (*(qos_params.socket_qos ()));
return 0;
}
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,140 @@
// -*- C++ -*-
//=============================================================================
/**
* @file SOCK_Dgram_Mcast_QoS.h
*
* @author Vishal Kachroo <vishal@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_SOCK_DGRAM_MCAST_QOS_H
#define ACE_SOCK_DGRAM_MCAST_QOS_H
#include /**/ "ace/pre.h"
#include "ace/SOCK_Dgram_Mcast.h"
#include "QoS_Manager.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_SOCK_Dgram_Mcast_QoS
*
* @brief Defines the member functions for the ACE QoS enabled socket
* wrapper for UDP/IP multicast.
*/
class ACE_QoS_Export ACE_SOCK_Dgram_Mcast_QoS : public ACE_SOCK_Dgram_Mcast
{
public:
// = Initialization routines.
/// Ctor, has same defaults as ACE_SOCK_Dgram_Mcast
ACE_SOCK_Dgram_Mcast_QoS (options opts = DEFOPTS);
// Note that there is no public <open> method. Therefore, this
// class cannot be used unless you <subscribe> to a multicast group.
// If you just want to send (and not listen) to a multicast group,
// use <ACE_SOCK_Dgram> or <ACE_SOCK_CODgram> instead.
/// Default dtor.
~ACE_SOCK_Dgram_Mcast_QoS (void);
// = Multicast group management routines.
/**
* This is a QoS-enabled method for joining a multicast group, which
* passes <qos_params> via <ACE_OS::join_leaf>. The network
* interface device driver is instructed to accept datagrams with
* <mcast_addr> multicast addresses. If the socket has already been
* opened, <subscribe> closes the socket and opens a new socket
* bound to the <mcast_addr>. The session object specifies the QoS
* session that the socket wants to subscribe to. A socket may
* subscribe to multiple QoS sessions by calling this method multiple
* times with different session objects.
*
* The <net_if> interface is hardware specific, e.g., use "netstat
* -i" to find whether your interface is, such as "le0" or something
* else. If net_if == 0, <subscribe> uses the default mcast
* interface. Returns: -1 if the call fails.
*
* Note that some platforms, such as pSoS, support only number, not
* names, for network interfaces. For these platforms, just give
* these numbers in alphanumeric form and <subscribe> will convert
* them into numbers via <ACE_OS::atoi>.
*/
int subscribe (const ACE_INET_Addr &mcast_addr,
const ACE_QoS_Params &qos_params,
int reuse_addr = 1,
const ACE_TCHAR *net_if = 0,
int protocol_family = PF_INET,
int protocol = 0,
ACE_Protocol_Info *protocolinfo = 0,
ACE_SOCK_GROUP g = 0,
u_long flags = 0,
ACE_QoS_Session *qos_session = 0);
// = Data transfer routines.
/// Send <buffer_count> worth of @a buffers to @a addr using overlapped
/// I/O (uses <WSASentTo>). Returns 0 on success.
ssize_t send (const iovec buffers[],
int buffer_count,
size_t &number_of_bytes_sent,
int flags,
const ACE_Addr &addr,
ACE_OVERLAPPED *overlapped,
ACE_OVERLAPPED_COMPLETION_FUNC func) const;
/// Send an @a n byte @a buf to the datagram socket (uses <WSASentTo>).
ssize_t send (const void *buf,
size_t n,
const ACE_Addr &addr,
int flags,
ACE_OVERLAPPED *overlapped,
ACE_OVERLAPPED_COMPLETION_FUNC func) const;
/// Returns the QoS manager for this socket.
ACE_QoS_Manager qos_manager (void);
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
int open (const ACE_INET_Addr &addr,
const ACE_QoS_Params &qos_params,
int protocol_family = PF_INET,
int protocol = 0,
ACE_Protocol_Info *protocolinfo = 0,
ACE_SOCK_GROUP g = 0,
u_long flags = 0,
int reuse_addr = 0);
private:
// = Disable public <open> method to ensure class used properly.
/// Subscribe to the multicast interface using QoS-enabled semantics.
int subscribe_ifs (const ACE_INET_Addr &mcast_addr,
const ACE_QoS_Params &qos_params,
const ACE_TCHAR *net_if,
int protocol_family,
int protocol,
int reuse_addr,
ACE_Protocol_Info *protocolinfo);
/// Manages the QoS sessions that this socket subscribes to.
ACE_QoS_Manager qos_manager_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "SOCK_Dgram_Mcast_QoS.inl"
#endif /* __ACE_INLINE__ */
#include /**/ "ace/post.h"
#endif /* ACE_SOCK_DGRAM_MCAST_QOS_H */

View File

@@ -0,0 +1,54 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE
ACE_SOCK_Dgram_Mcast_QoS::~ACE_SOCK_Dgram_Mcast_QoS (void)
{
}
ACE_INLINE ssize_t
ACE_SOCK_Dgram_Mcast_QoS::send (const iovec buffers[],
int buffer_count,
size_t &number_of_bytes_sent,
int flags,
const ACE_Addr &addr,
ACE_OVERLAPPED *overlapped,
ACE_OVERLAPPED_COMPLETION_FUNC func) const
{
ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::send");
return ACE_SOCK_Dgram::send (buffers,
buffer_count,
number_of_bytes_sent,
flags,
addr,
overlapped,
func);
}
ACE_INLINE ssize_t
ACE_SOCK_Dgram_Mcast_QoS::send (const void *buf,
size_t n,
const ACE_Addr &addr,
int flags,
ACE_OVERLAPPED *overlapped,
ACE_OVERLAPPED_COMPLETION_FUNC func) const
{
ACE_TRACE ("ACE_SOCK_Dgram_Mcast_QoS::send");
return ACE_SOCK_Dgram::send (buf,
n,
addr,
flags,
overlapped,
func);
}
ACE_INLINE ACE_QoS_Manager
ACE_SOCK_Dgram_Mcast_QoS::qos_manager (void)
{
return this->qos_manager_;
}
ACE_END_VERSIONED_NAMESPACE_DECL

19
deps/acelite/ace/QoS/qos.mpc vendored Normal file
View File

@@ -0,0 +1,19 @@
// -*- MPC -*-
project(QoS) : acelib, ace_output, install {
requires += qos
sharedname = ACE_QoS
dynamicflags += ACE_QoS_BUILD_DLL
macros += ACE_HAS_QOS
specific(prop:windows) {
macros += ACE_HAS_WINSOCK2_GQOS
}
specific {
install_dir = ace/qos
}
pkgconfig_files {
ACE_QoS.pc.in
}
}