summaryrefslogtreecommitdiff
path: root/ACE/ace/QoS
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/QoS')
-rw-r--r--ACE/ace/QoS/ACE_QoS.pc.in11
-rw-r--r--ACE/ace/QoS/ACE_QoS_Export.h46
-rw-r--r--ACE/ace/QoS/Makefile.am74
-rw-r--r--ACE/ace/QoS/QoS_Decorator.cpp165
-rw-r--r--ACE/ace/QoS/QoS_Decorator.h179
-rw-r--r--ACE/ace/QoS/QoS_Manager.cpp41
-rw-r--r--ACE/ace/QoS/QoS_Manager.h74
-rw-r--r--ACE/ace/QoS/QoS_Session.h183
-rw-r--r--ACE/ace/QoS/QoS_Session_Factory.cpp105
-rw-r--r--ACE/ace/QoS/QoS_Session_Factory.h96
-rw-r--r--ACE/ace/QoS/QoS_Session_Impl.cpp724
-rw-r--r--ACE/ace/QoS/QoS_Session_Impl.h265
-rw-r--r--ACE/ace/QoS/QoS_Session_Impl.i229
-rw-r--r--ACE/ace/QoS/README55
-rw-r--r--ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.cpp258
-rw-r--r--ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.h142
-rw-r--r--ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.i57
-rw-r--r--ACE/ace/QoS/qos.mpc16
18 files changed, 2720 insertions, 0 deletions
diff --git a/ACE/ace/QoS/ACE_QoS.pc.in b/ACE/ace/QoS/ACE_QoS.pc.in
new file mode 100644
index 00000000000..ba6fda765b9
--- /dev/null
+++ b/ACE/ace/QoS/ACE_QoS.pc.in
@@ -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}
diff --git a/ACE/ace/QoS/ACE_QoS_Export.h b/ACE/ace/QoS/ACE_QoS_Export.h
new file mode 100644
index 00000000000..45790bbd24c
--- /dev/null
+++ b/ACE/ace/QoS/ACE_QoS_Export.h
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+// $Id$
+// 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.
diff --git a/ACE/ace/QoS/Makefile.am b/ACE/ace/QoS/Makefile.am
new file mode 100644
index 00000000000..70065de4481
--- /dev/null
+++ b/ACE/ace/QoS/Makefile.am
@@ -0,0 +1,74 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+includedir = @includedir@/ace/QoS
+pkgconfigdir = @libdir@/pkgconfig
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+
+## Makefile.QoS.am
+
+if BUILD_QOS
+
+lib_LTLIBRARIES = libACE_QoS.la
+
+libACE_QoS_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -DACE_QoS_BUILD_DLL
+
+libACE_QoS_la_SOURCES = \
+ QoS_Decorator.cpp \
+ QoS_Manager.cpp \
+ QoS_Session_Factory.cpp \
+ QoS_Session_Impl.cpp \
+ SOCK_Dgram_Mcast_QoS.cpp
+
+libACE_QoS_la_LDFLAGS = \
+ -release @ACE_VERSION_NAME@
+
+libACE_QoS_la_LIBADD = \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+nobase_include_HEADERS = \
+ ACE_QoS_Export.h \
+ QoS_Decorator.h \
+ QoS_Manager.h \
+ QoS_Session.h \
+ QoS_Session_Factory.h \
+ QoS_Session_Impl.h \
+ QoS_Session_Impl.i \
+ SOCK_Dgram_Mcast_QoS.h \
+ SOCK_Dgram_Mcast_QoS.i
+
+pkgconfig_DATA = \
+ ACE_QoS.pc
+
+CLEANFILES = \
+ ACE_QoS.pc
+
+ACE_QoS.pc: ${top_builddir}/config.status ${srcdir}/ACE_QoS.pc.in
+ ${top_builddir}/config.status --file "$@":${srcdir}/ACE_QoS.pc.in
+
+endif BUILD_QOS
+
+EXTRA_DIST = \
+ ACE_QoS.pc.in
+
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/ace/QoS/QoS_Decorator.cpp b/ACE/ace/QoS/QoS_Decorator.cpp
new file mode 100644
index 00000000000..90cc748e856
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Decorator.cpp
@@ -0,0 +1,165 @@
+// QoS_Decorator.cpp
+// $Id$
+
+#include "QoS_Decorator.h"
+
+ACE_RCSID(ace, QoS_Decorator, "$Id$")
+
+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
diff --git a/ACE/ace/QoS/QoS_Decorator.h b/ACE/ace/QoS/QoS_Decorator.h
new file mode 100644
index 00000000000..512912e7c3b
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Decorator.h
@@ -0,0 +1,179 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file QoS_Decorator.h
+ *
+ * $Id$
+ *
+ * @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 */
diff --git a/ACE/ace/QoS/QoS_Manager.cpp b/ACE/ace/QoS/QoS_Manager.cpp
new file mode 100644
index 00000000000..27fa39ab560
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Manager.cpp
@@ -0,0 +1,41 @@
+// QoS_Manager.cpp
+// $Id$
+
+#include "QoS_Manager.h"
+#include "ace/Log_Msg.h"
+
+ACE_RCSID(ace, QoS_Manager, "$Id$")
+
+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)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("Error in adding a new session to the ")
+ ACE_LIB_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
diff --git a/ACE/ace/QoS/QoS_Manager.h b/ACE/ace/QoS/QoS_Manager.h
new file mode 100644
index 00000000000..8a0b52c9943
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Manager.h
@@ -0,0 +1,74 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file QoS_Manager.h
+ *
+ * $Id$
+ *
+ * @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 */
diff --git a/ACE/ace/QoS/QoS_Session.h b/ACE/ace/QoS/QoS_Session.h
new file mode 100644
index 00000000000..3e08bbc69ce
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Session.h
@@ -0,0 +1,183 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file QoS_Session.h
+ *
+ * $Id$
+ *
+ * @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 */
diff --git a/ACE/ace/QoS/QoS_Session_Factory.cpp b/ACE/ace/QoS/QoS_Session_Factory.cpp
new file mode 100644
index 00000000000..89a8fbcc913
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Session_Factory.cpp
@@ -0,0 +1,105 @@
+// QoS_Session_Factory.cpp
+// $Id$
+
+#include "QoS_Session_Factory.h"
+#include "QoS_Session_Impl.h"
+#include "ace/Log_Msg.h"
+
+ACE_RCSID(ace, QoS_Session_Factory, "$Id$")
+
+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;
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_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))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_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)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("Error in adding a new session")
+ ACE_LIB_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)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("Error in removing a session")
+ ACE_LIB_TEXT ("from the session set\n")),
+ -1);
+
+ return 0;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/QoS/QoS_Session_Factory.h b/ACE/ace/QoS/QoS_Session_Factory.h
new file mode 100644
index 00000000000..0559dce4220
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Session_Factory.h
@@ -0,0 +1,96 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file QoS_Session_Factory.h
+ *
+ * $Id$
+ *
+ * @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 */
diff --git a/ACE/ace/QoS/QoS_Session_Impl.cpp b/ACE/ace/QoS/QoS_Session_Impl.cpp
new file mode 100644
index 00000000000..09014ae50c2
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Session_Impl.cpp
@@ -0,0 +1,724 @@
+// QoS_Session_Impl.cpp
+// $Id$
+
+#include "ace/OS_NS_arpa_inet.h"
+#include "ace/SOCK.h"
+#include "QoS_Manager.h"
+#include "QoS_Session_Impl.h"
+#include "ace/Log_Msg.h"
+
+#if !defined (__ACE_INLINE__)
+#include "QoS_Session_Impl.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(ace, QoS_Session_Impl, "$Id$")
+
+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)
+ ACE_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)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "(%N|%l) Null flow_spec_list\n"));
+ }
+ else
+ {
+ // Extended Legacy format.
+ csxp = &flow_spec_list->specbody_qosx;
+ if(!csxp)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N|%l) Null csxp\n"),
+ -1);
+ }
+ }
+
+ ACE_QoS ace_qos = qos_session->qos ();
+
+ switch(eventype)
+ {
+ case RAPI_PATH_EVENT:
+ {
+ ACE_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);
+
+
+ ACE_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:
+ {
+ ACE_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:
+ ACE_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:
+ {
+ ACE_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:
+ {
+ ACE_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:
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "RESV CONFIRM Event received\n"));
+ qos_session->rsvp_event_type (ACE_QoS_Session::RSVP_RESV_CONFIRM);
+ }
+ break;
+
+ default:
+ ACE_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);
+ ACE_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)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "rapi_session () call fails. Error\n"),
+ -1);
+ else
+ ACE_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)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Can't release RSVP session:\n\t%s\n",
+ rapi_errlist[rsvp_error]),
+ -1);
+ else
+ ACE_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,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ 25) ;
+ if (result != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N|%l) rapi_sender error %d:\n\tPATH Generation can't be started\n",
+ result),
+ -1);
+ else
+ ACE_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)
+ ACE_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));
+ ACE_DEBUG ((LM_DEBUG,
+ "\nSender TSpec : %s\n",
+ buffer));
+
+ // Print out all the fields separately.
+ ACE_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 ());
+
+ ACE_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 (),
+ NULL,
+ t_spec,
+ NULL,
+ NULL,
+ sending_flowspec->ttl ()) ;
+
+ /*
+ int result = rapi_sender(this->session_id_,
+ 0,
+ (sockaddr *) sender_addr.get_addr (),
+ NULL,
+ t_spec,
+ NULL,
+ NULL,
+ sending_flowspec->ttl ()) ;
+ */
+ if(result!= 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N|%l) rapi_sender error %d:\n\tPATH Generation can't be started\n",
+ result),
+ -1);
+ else
+ ACE_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.
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ // The filter spec is NULL. This should work since the RSTYLE is
+ // WILDCARD.
+ 0,
+ 0) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N|%l)rapi_reserve () error:\n\tRESV Generation can't be started\n"),
+ -1);
+ else
+ ACE_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)
+ ACE_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));
+ ACE_DEBUG ((LM_DEBUG,
+ "\nReceiver FlowSpec : %s\n",
+ buffer));
+
+ // Print out all the fields separately.
+ ACE_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.
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ // The filter spec is NULL. This should work since the RSTYLE is
+ // WILDCARD.
+ 1,
+ flow_spec) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "rapi_reserve () error:\n\tRESV Generation can't be started\n"),
+ -1);
+ else
+ ACE_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)
+ ACE_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:
+ ACE_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)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("This QoS session was not subscribed to")
+ ACE_LIB_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)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("Error in Qos set ACE_OS::ioctl() %d\n"),
+ ret_bytes),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_LIB_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
diff --git a/ACE/ace/QoS/QoS_Session_Impl.h b/ACE/ace/QoS/QoS_Session_Impl.h
new file mode 100644
index 00000000000..193c537a74c
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Session_Impl.h
@@ -0,0 +1,265 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file QoS_Session_Impl.h
+ *
+ * $Id$
+ *
+ * @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.i"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_QOS_SESSION_IMPL_H */
diff --git a/ACE/ace/QoS/QoS_Session_Impl.i b/ACE/ace/QoS/QoS_Session_Impl.i
new file mode 100644
index 00000000000..b3971b46d52
--- /dev/null
+++ b/ACE/ace/QoS/QoS_Session_Impl.i
@@ -0,0 +1,229 @@
+// -*- C++ -*-
+//
+// $Id$
+
+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 ();
+ ACE_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
diff --git a/ACE/ace/QoS/README b/ACE/ace/QoS/README
new file mode 100644
index 00000000000..4415bf1862b
--- /dev/null
+++ b/ACE/ace/QoS/README
@@ -0,0 +1,55 @@
+$Id$
+
+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
+
diff --git a/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.cpp b/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.cpp
new file mode 100644
index 00000000000..548c56bef12
--- /dev/null
+++ b/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.cpp
@@ -0,0 +1,258 @@
+// $Id$
+
+#include "SOCK_Dgram_Mcast_QoS.h"
+#include "ace/Log_Msg.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.i"
+#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_RCSID (QoS,
+ SOCK_Dgram_Mcast_QoS,
+ "$Id$")
+
+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;
+
+ ACE_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_LIB_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].get_ip_address() == INADDR_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)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("Unable to join QoS Session\n")),
+ -1);
+ }
+ else
+ {
+ if (this->close () != 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_LIB_TEXT ("Unable to close socket\n")));
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("Dest Addr in the QoS Session does")
+ ACE_LIB_TEXT (" not match the address passed into")
+ ACE_LIB_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
diff --git a/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.h b/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.h
new file mode 100644
index 00000000000..032bbe22f11
--- /dev/null
+++ b/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.h
@@ -0,0 +1,142 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file SOCK_Dgram_Mcast_QoS.h
+ *
+ * $Id$
+ *
+ * @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 <buffers> to <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 <n> byte <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.i"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SOCK_DGRAM_MCAST_QOS_H */
diff --git a/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.i b/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.i
new file mode 100644
index 00000000000..9e2347669c5
--- /dev/null
+++ b/ACE/ace/QoS/SOCK_Dgram_Mcast_QoS.i
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+//
+// $Id$
+
+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
diff --git a/ACE/ace/QoS/qos.mpc b/ACE/ace/QoS/qos.mpc
new file mode 100644
index 00000000000..cf50f96b557
--- /dev/null
+++ b/ACE/ace/QoS/qos.mpc
@@ -0,0 +1,16 @@
+// -*- MPC -*-
+// $Id$
+
+project(QoS) : acelib, core {
+ requires += qos
+ sharedname = ACE_QoS
+ dynamicflags = ACE_QoS_BUILD_DLL
+
+ specific(borland, bmake, nmake, em3, vc6, vc7, vc71, vc8) {
+ macros += ACE_HAS_WINSOCK2_GQOS
+ }
+
+ pkgconfig_files {
+ ACE_QoS.pc.in
+ }
+}