195 lines
6.7 KiB
C++
195 lines
6.7 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) Intel Corporation, 2006 - 2007.
|
|
//
|
|
// File: TunnelHandler.h
|
|
//
|
|
// Contents: Handles tunnel connection
|
|
//
|
|
// Notes:
|
|
//----------------------------------------------------------------------------
|
|
|
|
#ifndef AMT_TUNNEL_HANDLER
|
|
#define AMT_TUNNEL_HANDLER
|
|
|
|
#include <ace/ACE.h>
|
|
#include "APF.h"
|
|
|
|
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
|
# pragma once
|
|
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
|
|
|
#include <ace/Svc_Handler.h>
|
|
#include <ace/SOCK_Stream.h>
|
|
#include <ace/Recursive_Thread_Mutex.h>
|
|
#include <ace/Reactor_Notification_Strategy.h>
|
|
|
|
#include <vector>
|
|
|
|
#include "ChannelManager.h"
|
|
|
|
using namespace std;
|
|
class Port_Address;
|
|
// ============================================================================
|
|
// = TITLE
|
|
// Handles reception of APF packet from Intel(R) AMT.
|
|
//
|
|
// = DESCRIPTION
|
|
// Performs parsing on APF messages and acts accordingly. Intended to
|
|
// run reactively, i.e., in one thread of control using a
|
|
// Reactor for demuxing and dispatching.
|
|
// ============================================================================
|
|
class AMT_Tunnel_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
|
|
{
|
|
friend class AMT_Tunnel_Supplier;
|
|
friend class AMT_Tunnel_Consumer;
|
|
|
|
public:
|
|
// = Initialization method.
|
|
AMT_Tunnel_Handler (void);
|
|
|
|
// = Destruction
|
|
virtual ~AMT_Tunnel_Handler(void);
|
|
|
|
enum Tunnel_State
|
|
{
|
|
// -- NOTE -- for new APF support
|
|
SESSION_INIT = 1, //
|
|
SESSION_OPENED, //
|
|
AUTH_PENDING, //
|
|
SESSION_AUTHENTICATED, //
|
|
PFWD_OPEN, //
|
|
DISCONNECTED // Handler is disconnected, but pending all notifications
|
|
// in reactor to be dispatched.
|
|
};
|
|
|
|
struct disconnectData
|
|
{
|
|
ACE_UINT32 _disconnect_reason; // APF Reason for disconnecting this tunnel
|
|
bool _is_APF_send; //holds true iff we should send APF_DISCONNECT
|
|
bool _is_consumer_hold_disconnect; //holds true iff consumer already holds a disconnect message
|
|
PRIORITY _hangup_prio; //if PRIO_HIGH the hangup message will be enqueued to the head of the queue.
|
|
|
|
disconnectData(): _disconnect_reason(APF_DISCONNECT_PROTOCOL_ERROR),
|
|
_is_APF_send(false),
|
|
_is_consumer_hold_disconnect(false),
|
|
_hangup_prio(PRIO_LOW){} // default priority is low, so if no fatel error accured, (if so, we will change the priority to HIGH)
|
|
// we want to send the messages in queue first, and only then handle the disconnect
|
|
// (supporting half close connection)
|
|
|
|
void setParams(ACE_UINT32 reason, bool is_APF_send, PRIORITY prio)
|
|
{
|
|
_disconnect_reason = reason;
|
|
_is_APF_send = is_APF_send;
|
|
_hangup_prio = prio;
|
|
}
|
|
|
|
void setParams(bool is_APF_send, PRIORITY prio)
|
|
{
|
|
_is_APF_send = is_APF_send;
|
|
_hangup_prio = prio;
|
|
}
|
|
};
|
|
|
|
|
|
// = Set/get the current tunnel state.
|
|
void tunnelState (int state) { tunnel_state_ = state;}
|
|
int tunnelState (void) const { return tunnel_state_;}
|
|
|
|
// Returns the underlying AMT_Tunnel_Supplier.
|
|
AMT_Tunnel_Supplier *supplier (void) const { return supplier_;}
|
|
|
|
// Returns the underlying AMT_Tunnel_Consumer.
|
|
AMT_Tunnel_Consumer *consumer (void) const { return consumer_;}
|
|
|
|
// Returns the underlying Channel_Mgr.
|
|
Channel_Manager& channel_mgr (void) { return channel_mgr_;}
|
|
|
|
// Handle reactor calls.
|
|
virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE);
|
|
virtual int handle_output (ACE_HANDLE = ACE_INVALID_HANDLE);
|
|
virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
|
|
ACE_Reactor_Mask close_mask =
|
|
ACE_Event_Handler::ALL_EVENTS_MASK);
|
|
virtual int handle_timeout(const ACE_Time_Value ¤t_time,
|
|
const void * arg = NULL);
|
|
|
|
// Close functions
|
|
void shutdown_tunnel();
|
|
|
|
// virtual from ACE_Svc_Handler<>
|
|
virtual int open (void * pVoid);
|
|
|
|
// int AMT_ID() {return AMT_ID_;}
|
|
// void AMT_ID(int id) {AMT_ID_ = id;}
|
|
//ACE_RW_Thread_Mutex& guard() {return tunnel_mutex_;}
|
|
|
|
virtual const char* identifier() {return _identifier.c_str();}
|
|
void set_identifier(const ACE_CString &str) { _identifier = str;}
|
|
protected:
|
|
ACE_CString _identifier;
|
|
STATUS initiate_io (ACE_Reactor_Mask mask);
|
|
STATUS cancel_io (ACE_Reactor_Mask mask);
|
|
STATUS terminate_io (ACE_Reactor_Mask mask);
|
|
|
|
int processReturnVal (int result);
|
|
//-------------------------------------------------------
|
|
// return true on the following cases:
|
|
// (1) some other thread is currently handling this object message's
|
|
// (so it will handle all messages currently in the queue)
|
|
// (2) the object is in DISCONNECT state, but we are NOT the last dispacher
|
|
// (it can happend whan some earlier thread handled several of messages,
|
|
// so we dont have anything to do)
|
|
//-------------------------------------------------------
|
|
bool needReturnWithoutWorking(int* reply);
|
|
|
|
//-------------------------------------------------------
|
|
// NOTE:
|
|
// you must take TunnelMgr mutex BEFORE calling this function
|
|
//-------------------------------------------------------
|
|
void removeTcpForwardConnection(Port_Address& addr);
|
|
|
|
//-------------------------------------------------------
|
|
// NOTE:
|
|
// you must take TunnelMgr mutex BEFORE calling this function
|
|
//-------------------------------------------------------
|
|
void removeFromTunnelMgr();
|
|
//-----------------------------------------------------------
|
|
// Disconnect this tunnel due to some error/or socket closed.
|
|
//
|
|
// NOTES:
|
|
// (1) _mutex_disconnect MUST be taken before invoking this method!
|
|
// This function should be called only ONCE on each tunnel
|
|
// to make sure the consumer is still running.
|
|
// (2) the disconnect uses the params in _disconnect_data.
|
|
//-----------------------------------------------------------
|
|
STATUS disconnect();
|
|
|
|
private:
|
|
AMT_Tunnel_Supplier* supplier_; // Reference to this tunnel supplier
|
|
AMT_Tunnel_Consumer* consumer_; // Reference to this tunnel consumer
|
|
Channel_Manager channel_mgr_; // The channel manager
|
|
int tunnel_state_; // This tunnel state
|
|
int flg_mask_; // Mask that registers with the reactor
|
|
ACE_CString full_addr_;
|
|
ACE_Recursive_Thread_Mutex output_mutex_;
|
|
ACE_UINT32 AMT_ID_;
|
|
|
|
vector<Port_Address> _tcp_forward_connections;
|
|
|
|
//bool _is_consumer_hold_disconnect;
|
|
// notification on queue
|
|
ACE_Reactor_Notification_Strategy _notification_strategy;
|
|
ACE_Recursive_Thread_Mutex _dispatch_output_counter_mutex;
|
|
ACE_UINT32 _dispatch_output_counter;
|
|
ACE_RW_Thread_Mutex _state_mutex;
|
|
|
|
ACE_Recursive_Thread_Mutex _active_mutex;
|
|
ACE_INT32 _active_counter;
|
|
//bool _send_APF_disconnect;
|
|
ACE_Recursive_Thread_Mutex _mutex_disconnect;
|
|
ACE_Recursive_Thread_Mutex _close_mutex; //will be used only in handle_close
|
|
disconnectData _disconnect_data;
|
|
};
|
|
|
|
#endif // AMT_TUNNEL_HANDLER
|