Thread: Undefined Reference/ Poorly defined inheritenance

  1. #1
    Registered User lantzvillian's Avatar
    Join Date
    Sep 2010
    Posts
    44

    Question Undefined Reference/ Poorly defined inheritenance

    Hello all,

    I'm mostly a C embedded developer and definitely catching up with what I've forgotten with C++. I am forward porting an ancient project that is starting to get attention again, but I am getting a multitude of errors that I think are related to inheritance.

    Normally, undefined references would mean that the code is not visible or not being included during the linking phase; however, that library is compiled and included so I suspect something is wrong with the way those classes/objects were written (not be me).

    Any help would be greatly appreciated as this will be all uploaded on sourceForge as I have recently gotten maintainer access to OpenDiameter.

    Below are the errors that are suspect:

    Code:
    src/nasd_pana.o: In function `NASD_EapPassThroughAuthIdentityStateMachine':
    /home/rbrash/concordia-code/opendiameter-1.0.8-mod/applications/nas/./include/nasd_eap_passthrough.h:49: undefined reference to `EapAuthIdentityStateMachine::EapAuthIdentityStateMachine(EapSwitchStateMachine&)'
    src/nasd_pana.o: In function `NASD_EapPassThroughAuthSwitchStateMachine':
    /home/rbrash/concordia-code/opendiameter-1.0.8-mod/applications/nas/./include/nasd_eap_passthrough.h:68: undefined reference to `EapPassThroughAuthSwitchStateMachine::EapPassThroughAuthSwitchStateMachine(ACE_Reactor&, AAA_JobHandle<AAA_GroupedJob>&)'
    /home/rbrash/concordia-code/opendiameter-1.0.8-mod/applications/nas/./include/nasd_eap_passthrough.h:68: undefined reference to `EapPassThroughAuthSwitchStateMachine::~EapPassThroughAuthSwitchStateMachine()'
    src/nasd_pana.o: In function `~NASD_EapPassThroughAuthSwitchStateMachine':
    /home/rbrash/concordia-code/opendiameter-1.0.8-mod/applications/nas/./include/nasd_eap_passthrough.h:58: undefined reference to `EapPassThroughAuthSwitchStateMachine::~EapPassThroughAuthSwitchStateMachine()'
    src/nasd_pana.o:(.rodata._ZTV41NASD_EapPassThroughAuthSwitchStateMachine[vtable for NASD_EapPassThroughAuthSwitchStateMachine]+0x68): undefined reference to `EapAuthSwitchStateMachine::Receive(AAAMessageBlock*)'
    src/nasd_pana.o:(.rodata._ZTI41NASD_EapPassThroughAuthSwitchStateMachine[typeinfo for NASD_EapPassThroughAuthSwitchStateMachine]+0x10): undefined reference to `typeinfo for EapPassThroughAuthSwitchStateMachine'
    Here is one of the headers:

    Code:
    #ifndef __EAP_AUTHFSM_HXX__
    #define __EAP_AUTHFSM_HXX__
    
    #include <ace/Basic_Types.h>
    #include <string>
    #include "eap.hxx"
    #include "eap_fsm.hxx"
    #include "eap_method_registrar.hxx"
    
    #include <iostream>
    
    /// A class for authetnicator state machine.  Class creation can be made
    /// only by EapSession.
    class EapAuthSwitchStateMachine:public EapSwitchStateMachine {
     public:
    	virtual void Success(AAAMessageBlock * b) = 0;
    
    	/// This Success callback is called when EAP authentication succeeds
    	/// without generating an EAP-Success message.
    	virtual void Success() = 0;
    
    	virtual void Failure(AAAMessageBlock * b) = 0;
    
    	inline ACE_UINT16 & MaxRetransmissionCount() {
    		return maxRetransmissionCount;
    	}
    	/// Call this function to get the reference to the retransmission/// interval value.
    	    inline ACE_UINT16 & RetransmissionInterval() {
    		return retransmissionInterval;
    	}
    
    	/// Call this function to get the currentIdentifier.
    	//  inline ACE_Byte CurrentIdentifier() { return currentIdentifier; }
    
    	/// Call this function to set the isEapBackend variable.
    	virtual inline bool IsEapBackend(void) {
    		return false;
    	}
    
    	/// Call this function to check whether retransmission is enabled.
    	inline bool RetransmissionEnabled() {
    		return (retransmissionInterval != 0);
    	}
    
    	/// Call this function to set whether the backend authenticator
    	/// sends the initial Request.
    	inline void NeedInitialRequestToSend(bool b) {
    		needInitialRequestToSend = b;
    	}
    
    	/// Call this function to check whether the backend authenticator
    	/// sends the initial Request.
    	inline bool NeedInitialRequestToSend() {
    		return needInitialRequestToSend;
    	}
    
    	/// Call this function to get the reference to the notificationString.
    	inline std::string & NotificationString() {
    		return notificationString;
    	}
    
    	/// Call this function to get the reference to the retransmissionCount.
    	inline ACE_UINT16 & RetransmissionCount() {
    		return retransmissionCount;
    	}
    
    	enum EapAuthDecision {
    		DecisionSuccess,
    		DecisionFailure,
    		DecisionContinue,
    		DecisionPassthrough
    	};
    
    	/// Call this function to obtain the authenticator decision.
    	virtual EapAuthDecision Decision() {
    	};
    
    	/// External method state visibile to authenticator switch state machine.  
    	/// The state is updated by the authenticator state machine.
    
    	enum EapAuthMethodState {
    		PROPOSED = 0,
    		CONT,
    		END,
    	};
    
    	EapAuthMethodState & MethodState() {
    	};
    
    	/// External events passed from applications and methods.
    	enum event {
    		EvRxMsg = (-1),	// Message reception event passed from
    		// application via
    		// EapSession::Receive().
    		EvSgPortEnabled = (-2),	// Port enabled event passed from
    		// application.
    		EvSgValidResp = (-3),	// Event for integrity check success
    		// with continueing method (passed
    		// from methods).
    		EvSgInvalidResp = (-4),	// Integrity check failure event
    		// passed from methods.
    		EvSgEndMethod = (-5),	// Event for integrity check sucess
    		// with end method (passed from
    		// methods).
    		EvSgRestart = (-6),	// Event generated to start the state
    		// machine as a non-backend server.
    		EvSgAaaContinue = (-7),	// Event generated when AAA continues.
    
    		EvSgAaaSuccess = (-8),	// Event generated when AAA succeeds.
    
    		EvSgAaaFailure = (-9),	// Event generated when AAA fails.
    	};
    
     protected:
    
    	EapAuthSwitchStateMachine(ACE_Reactor & r, EapJobHandle & h)
     :	    
    	EapSwitchStateMachine(r, h),
    	discardCount(0),
    	retransmissionCount(0),
    	maxRetransmissionCount(defaultMaxRetransmissionCount),
    	retransmissionInterval(defaultRetransmissionInterval), needInitialRequestToSend(true) {
    	};
    
    	virtual ~ EapAuthSwitchStateMachine() {
    	};
    
    	static const ACE_UINT16 defaultMaxRetransmissionCount;
    	static const ACE_UINT16 defaultRetransmissionInterval;
    
    	ACE_UINT16 discardCount;
    	ACE_UINT16 retransmissionCount;
    	ACE_UINT16 maxRetransmissionCount;
    	ACE_UINT16 retransmissionInterval;	// Set this value to zero when
    	// retransmission is disabled.
    	std::string notificationString;	// Used for sending notification
    	// to the per.
    	bool needInitialRequestToSend;
    
    	/// This variable stores method state.
    	EapAuthMethodState methodState;
    };
    
    /// A leaf class for standalone authenticator state machine.  Class
    /// creation can be made only by EapSession.
    class EAP_EXPORTS EapStandAloneAuthSwitchStateMachine:
        public EapAuthSwitchStateMachine, public EapStateMachine < EapStandAloneAuthSwitchStateMachine > {
     public:
    
    	void Start() throw(AAA_Error) {
    		//std::cout<<"[EApStandAloneAuthswitchstatemachine]:start\n";
    		// Set the current policy element to point to the initial policy
    		// element.
    		policy.CurrentPolicyElement(policy.InitialPolicyElement());
    
    		// Delete the last executed method if any.
    		DeleteMethodStateMachine();
    
    		// Initialize the state machine.
    		EapStateMachine < EapStandAloneAuthSwitchStateMachine >::Start();
    
    		// Initialize key stuff.
    		keyData.resize(0);
    		keyAvailable = false;
    
    		// Generate the initial event.
    		Notify(EapAuthSwitchStateMachine::EvSgRestart);
    	} inline void Notify(AAA_Event ev) {
    		//std::cout<<"[EapStandAloneAuthSwitchStateMachine]notify evsgrestart\n";
    		try {
    			EapStateMachine < EapStandAloneAuthSwitchStateMachine >::Notify(ev);
    		}
    		catch(int i) {
    			ACE_UNUSED_ARG(i);
    			EAP_LOG(LM_DEBUG, "Nofify() failed.\n");
    			Abort();
    		}
    	}
    
     protected:
    	EapStandAloneAuthSwitchStateMachine(ACE_Reactor & r, EapJobHandle & h);
    
    	virtual ~ EapStandAloneAuthSwitchStateMachine();
    };
    
    /// A leaf class for backend authenticator state machine.  Class
    /// creation can be made only by EapSession.
    class EAP_EXPORTS EapBackendAuthSwitchStateMachine:public EapAuthSwitchStateMachine,
        public EapStateMachine < EapBackendAuthSwitchStateMachine > {
     public:
    
    	void Start() throw(AAA_Error) {
    		// Set the current policy element to point to the initial policy
    		// element.
    		policy.CurrentPolicyElement(policy.InitialPolicyElement());
    
    		// Initialize the state machine.
    		EapStateMachine < EapBackendAuthSwitchStateMachine >::Start();
    
    		// Initialize key stuff.
    		keyData.resize(0);
    		keyAvailable = false;
    
    		// Generate the initial event.
    		Notify(EapAuthSwitchStateMachine::EvSgRestart);
    	} inline void Notify(AAA_Event ev) {
    		try {
    			EapStateMachine < EapBackendAuthSwitchStateMachine >::Notify(ev);
    		}
    		catch(int i) {
    			ACE_UNUSED_ARG(i);
    			EAP_LOG(LM_DEBUG, "Nofify() failed.\n");
    			Abort();
    		}
    	}
    
    	/// Call this function to start the session.
    	void Start(AAAMessageBlock * msg);
    
    	inline bool IsEapBackend(void) {
    		return true;
    	}
    
     protected:
    	EapBackendAuthSwitchStateMachine(ACE_Reactor & r, EapJobHandle & h);
    
    	virtual ~ EapBackendAuthSwitchStateMachine();
    };
    
    /// A leaf class for passthrough authenticator state machine.  Class
    /// creation can be made only by EapSession.
    class EAP_EXPORTS EapPassThroughAuthSwitchStateMachine:public EapAuthSwitchStateMachine,
        public EapStateMachine < EapPassThroughAuthSwitchStateMachine > {
     public:
    
    	void Start() throw(AAA_Error) {
    		// Set the current policy element to point to the initial policy
    		// element.
    		policy.CurrentPolicyElement(policy.InitialPolicyElement());
    
    		// Initialize the state machine.
    		EapStateMachine < EapPassThroughAuthSwitchStateMachine >::Start();
    
    		// Initialize key stuff.
    		keyData.resize(0);
    		keyAvailable = false;
    
    		// Generate the initial event.
    		Notify(EapAuthSwitchStateMachine::EvSgRestart);
    	} inline void Notify(AAA_Event ev) {
    		try {
    			EapStateMachine < EapPassThroughAuthSwitchStateMachine >::Notify(ev);
    		}
    		catch(int i) {
    			ACE_UNUSED_ARG(i);
    			EAP_LOG(LM_DEBUG, "Nofify() failed.\n");
    			Abort();
    		}
    	}
    
    	/// A callback function callled when a Response is forwarded to an
    	/// EAP server.  // virtual void ForwardResponse(AAAMessageBlock
    	/// *msg)=0;
    	virtual void ForwardResponse(AAAMessageBlock * msg) = 0;
    
    	/// Call this function for getting a reference to aaaRxQueue.
    	inline EapMessageQueue & AAARxQueue() throw() {
    		return aaaRxQueue;
    	}
    
    	/// The specified identifier is used as the next identifier.
    	ACE_Byte GetNextIdentifier(ACE_Byte id) {
    		return id;
    	}
    
    	/// Reimplemented from EapAuthSwitchStateMachine::Decision().
    	EapAuthDecision Decision() {
    	};
    
    	/// Called by application when AAA succeeds.  The argument may be null.
    	void AAA_Success(AAAMessageBlock * msg) throw(int) {
    		// Check if this is operating in passthorugh mode.
    		if (Decision() != DecisionPassthrough) {
    			EAP_LOG(LM_ERROR, "Not operating in pass-through mode");
    			throw - 1;
    		}
    
    		if (msg)
    			AAARxQueue().enqueue_tail(AAAMessageBlock::Acquire(msg));
    
    		Notify(EvSgAaaSuccess);
    	}
    
    	/// Called by application when AAA succeeds with passing a AAA-Key.
    	/// The first argument may be null.
    	void AAA_Success(AAAMessageBlock * msg, std::string & aaaKey) throw(int) {
    		// Check if this is operating in passthorugh mode.
    		if (Decision() != DecisionPassthrough) {
    			EAP_LOG(LM_ERROR, "Not operating in pass-through mode");
    			throw - 1;
    		}
    
    		KeyData() = aaaKey;
    
    		if (msg)
    			AAARxQueue().enqueue_tail(AAAMessageBlock::Acquire(msg));
    
    		Notify(EvSgAaaSuccess);
    	}
    
    	/// Called by application when AAA fails.  The argument may be null.
    	void AAA_Failure(AAAMessageBlock * msg) throw(int) {
    		// Check if this is operating in passthorugh mode.
    		if (Decision() != DecisionPassthrough) {
    			EAP_LOG(LM_ERROR, "Not operating in pass-through mode.\n");
    			throw - 1;
    		}
    
    		if (msg)
    			AAARxQueue().enqueue_tail(AAAMessageBlock::Acquire(msg));
    
    		Notify(EvSgAaaFailure);
    	}
    
    	/// Called by application when AAA continues.  The argument must not
    	/// be null.
    	void AAA_Continue(AAAMessageBlock * msg) throw(int) {
    		// Check if this is operating in passthorugh mode.
    		if (Decision() != DecisionPassthrough) {
    			EAP_LOG(LM_ERROR, "Not operating in pass-through mode.\n");
    			throw - 1;
    		}
    
    		if (!msg) {
    			EAP_LOG(LM_ERROR, "AAAContinue must contain non-null msg.\n");
    			throw - 1;
    		}
    		AAARxQueue().enqueue_tail(AAAMessageBlock::Acquire(msg));
    		Notify(EvSgAaaContinue);
    	}
    
     protected:
    	EapPassThroughAuthSwitchStateMachine(ACE_Reactor & r, EapJobHandle & h);
    	virtual ~ EapPassThroughAuthSwitchStateMachine();
    
    	/// this queue is used for receiving EAP message from EAP server.
    	EapMessageQueue aaaRxQueue;
    };
    
    #endif				// __EAP_AUTHFSM_HXX__
    Here is the C that uses and is used for EapPassThroughAuthSwitchStateMachine

    Code:
    #include <ace/Basic_Types.h>
    #include <ace/Singleton.h>
    #include "eap.hxx"
    #include "eap_authfsm.hxx"
    #include "eap_policy.hxx"
    #include "eap_log.hxx"
    #include "eap_parser.hxx"
    
    typedef ACE_Singleton < EapPassThroughAuthSwitchStateTable_S,
        ACE_Recursive_Thread_Mutex > EapPassThroughAuthSwitchStateTable;
    
    /// Action class for EAP. 
    class EapPassThroughAuthSwitchAction:public AAA_Action < EapPassThroughAuthSwitchStateMachine > {
     public:
    	virtual void operator() (EapPassThroughAuthSwitchStateMachine &) {
     } protected:
    	 EapPassThroughAuthSwitchAction() {
    	}
    	virtual ~ EapPassThroughAuthSwitchAction() {
    	}
    };
    
    /// State table used by EapAuthSwitchStateMachine.
    class EapPassThroughAuthSwitchStateTable_S:public AAA_StateTable < EapPassThroughAuthSwitchStateMachine > {
    	friend class ACE_Singleton < EapPassThroughAuthSwitchStateTable_S, ACE_Recursive_Thread_Mutex >;
     private:
    	 class AcDisable:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			sm.Event(EapAuthSwitchStateMachine::EvSgPortEnabled);
    	}};
    
    	class AcInitialize:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			sm.CurrentIdentifier() = 0;	// Initilize the identifier
    			sm.Event(EvUCT);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcInitialize.\n");
    	}};
    
    	class AcSendSuccess:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg = AAAMessageBlock::Acquire(4);
    
    			 EAP_LOG(LM_DEBUG, "Passthrough: Composing Success message.\n");
    
    			// Compose the PDU.
    			EapHeaderParser parser;
    			EapHeader header;
    			 header.code = Success;
    			 header.identifier = sm.CurrentIdentifier();
    			 header.length = 4;
    			 parser.setAppData(&header);
    			 parser.setRawData(msg);
    			 parser.parseAppToRaw();
    
    			// Stop retransmission timer and reset retransmission counter.
    			 sm.CancelTimer();
    			 sm.RetransmissionCount() = 0;
    
    			// Make the key available. (not specified in the state machine document.)
    			if (sm.KeyData().size() > 0)
    				 sm.KeyAvailable() = true;
    
    			// Call Success callback function.
    			 sm.Success(msg);
    			 msg->release();
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcSendSuccess.\n");
    		}
    	};
    
    	class AcSendFailure:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg = AAAMessageBlock::Acquire(4);
    			 EAP_LOG(LM_DEBUG, "Passthrough: Composing Failure message.\n");
    
    			// Compose the PDU.
    			EapHeaderParser parser;
    			EapHeader header;
    			 header.code = Failure;
    			 header.identifier = sm.CurrentIdentifier();
    			 header.length = 4;
    			 parser.setAppData(&header);
    			 parser.setRawData(msg);
    			 parser.parseAppToRaw();
    
    			// Stop retransmission timer and reset retransmission counter.
    			 sm.CancelTimer();
    			 sm.RetransmissionCount() = 0;
    
    			// Call Failure callback function.
    			 sm.Failure(msg);
    			 msg->release();
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcSendFailure.\n");
    	}};
    
    	class AcMethodResponse:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			EapMethodStateMachine & msm = sm.MethodStateMachine();
    			if (msm.IsDone()) {
    				sm.KeyData() = msm.KeyData();
    				sm.MethodState() = EapAuthSwitchStateMachine::END;
    				sm.Event(EapAuthSwitchStateMachine::EvSgEndMethod);
    			} else {
    				sm.MethodState() = EapAuthSwitchStateMachine::CONT;
    				sm.Event(EvElse);
    			}
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcMethodResponse.\n");
    		}
    	};
    
    	class AcBuildRequest:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			// Calculate the next Identifier for the new request.
    			ACE_Byte id = sm.CurrentIdentifier() =
    			    sm.MethodStateMachine().GetNextIdentifier(sm.CurrentIdentifier());
    
    			AAAMessageBlock *msg = sm.GetTxMessage();
    
    			// Compose the PDU.
    			EapHeaderParser headerParser;
    			EapHeader header;
    			 header.code = Request;
    			 header.identifier = id;
    			 header.length = msg->length();
    			 headerParser.setAppData(&header);
    			 headerParser.setRawData(msg);
    			 headerParser.parseAppToRaw();
    
    			// Set the wr_ptr to the tail of the message.
    			 msg->wr_ptr(msg->base() + header.length);
    
    			 sm.Event(EvUCT);
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcBuildRequest.\n");
    	}};
    
    	class AcSendRequest:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			// Stop retransmission timer and reset retransmission counter.
    			sm.CancelTimer();
    			sm.RetransmissionCount() = 0;
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcSendRequest                    1.\n");
    
    			AAAMessageBlock *msg = sm.GetTxMessage();
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcSendRequest                    2.\n");
    
    			// Call Send callback function.
    			// Increment the retransmission count.
    			 sm.RetransmissionCount()++;
    
    			// Schedule retransmssion timer
    			 EAP_LOG(LM_DEBUG, "Passthrough: Request sent and timer started.\n");
    			if (sm.RetransmissionEnabled())
    				 sm.ScheduleTimer(EvTo, sm.RetransmissionInterval());
    
    			 sm.Notify(EvUCT);
    
    			// Send the messsage.
    			 sm.Send(msg);
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcSendRequest.\n");
    		}
    	};
    
    	class AcDoIntegrityCheck:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			EAP_LOG(LM_DEBUG, "Passthrough: Integrity Check.\n");
    			sm.MethodStateMachine().Notify(EapMethodStateMachine::EvSgIntegrityCheck);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcDoIntegrityCheck.\n");
    	}};
    
    	class AcProposeMethod:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			EapType type = sm.Policy().CurrentMethod();
    
    			if (!type.IsVSE())
    				 EAP_LOG(LM_DEBUG, "PassThrough: Trying a legacy method.\n");
    			else
    				 EAP_LOG(LM_DEBUG, "PassThrough: Trying an extended method.\n");
    
    			 sm.DeleteMethodStateMachine();
    			 sm.CurrentMethod() = type;
    			 sm.CreateMethodStateMachine(type, Authenticator);
    			 sm.MethodStateMachine().Start();
    
    			if (type == EapType(1) || type == EapType(2))	// Identity or Notification
    				sm.MethodState() = EapAuthSwitchStateMachine::CONT;
    			else
    				 sm.MethodState() = EapAuthSwitchStateMachine::PROPOSED;
    
    			// Notify method
    			 sm.MethodStateMachine().Notify(EapMethodStateMachine::EvSgIntegrityCheck);
    			 EAP_LOG(LM_DEBUG, "end of acproposemethod.\n");
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcProposeMethod.\n");
    
    		}
    	};
    
    	class AcDoPolicyCheck:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			EapAuthSwitchStateMachine::EapAuthDecision decision = sm.Decision();
    			if (decision == EapAuthSwitchStateMachine::DecisionSuccess) {
    				sm.Event(EvSgPolicySat);
    			} else if (decision == EapAuthSwitchStateMachine::DecisionFailure) {
    				sm.Event(EvSgPolicyNotSat_EndSess);
    			} else if (decision == EapAuthSwitchStateMachine::DecisionPassthrough) {
    				sm.Event(EvSgPassThrough);
    			} else {	// continue
    				sm.Event(EvElse);
    			}
    		}
    	};
    
    	class AcDiscard:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			EAP_LOG(LM_DEBUG, "Passthrough: Message Discarded.\n");
    			sm.DiscardCount()++;
    			sm.Event(EvUCT);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcDiscard.\n");
    	}};
    
    	class AcDiscard2:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			EAP_LOG(LM_DEBUG, "Passthrough: Message discarded without parsing.\n");
    			sm.DiscardCount()++;
    			AAAMessageBlock *msg;
    			 EapMessageQueue & q = sm.RxQueue();
    			// Dequeue a message from receiving queue.
    			 q.dequeue_head((ACE_Message_Block * &)msg);
    
    			// Release it.
    			 msg->release();
    			 sm.Event(EvUCT);
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcDiscard2.\n");
    	}};
    
    	class AcDiscard3:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			EAP_LOG(LM_DEBUG, "Passthrough: Message Discarded.\n");
    			AAAMessageBlock *msg;
    			 EapMessageQueue & q = sm.AAARxQueue();
    
    			// Dequeue a message from receiving queue.
    			 q.dequeue_head((ACE_Message_Block * &)msg);
    			 msg->release();
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcDiscard3.\n");
    	}};
    
    	class AcResetMethod:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg = sm.GetRxMessage();
    
    			 EAP_LOG(LM_DEBUG, "Passthrough: Reset method due to receiving Nak.\n");
    			// Parse the nak
    			EapNakParser parser;
    			EapNak nak;
    			 parser.setDictData(NULL);
    			 parser.setAppData(&nak);
    			 parser.setRawData(msg);
    			 parser.parseRawToApp();
    
    			 sm.DeleteRxMessage();
    
    			// Update policy based on type list.
    			 EAP_LOG(LM_DEBUG, "Passthrough: Update policy on Nak.\n");
    			 sm.Policy().Update(nak.TypeList());
    
    			 sm.Event(EvUCT);
    	}};
    
    	class AcRetransmit:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			if (sm.RetransmissionCount() < sm.MaxRetransmissionCount()) {
    				EAP_LOG(LM_DEBUG, "Passthrough: Retransmitting Request.\n");
    				// Get the message to retransmit.
    				AAAMessageBlock *msg = sm.GetTxMessage();
    
    				// Call Send callback function.
    				// Increment the retransmission count
    				 sm.RetransmissionCount()++;
    
    				 sm.Notify(EvElse);
    
    				// Execute the callback function for sending the messsage
    				//      cb->Send(msg);
    				 sm.Send(msg);
    
    			} else {
    				EAP_LOG(LM_ERROR, "AuthSwitch: Reach max retransmission count.\n");
    				sm.CancelTimer();
    				sm.Event(EvSgMaxRetransmission);
    			}
    		}
    	};
    
    	class AcReceiveMsg:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg;
    			// Dequeue a message from receiving queue.
    			 sm.RxQueue().dequeue_head((ACE_Message_Block * &)msg);
    
    			// Set the read pointer to the message head.
    			 msg->rd_ptr(msg->base());
    
    			// Set msg to rxMessage.
    			 sm.SetRxMessage(msg);
    
    			// Parse the header
    			EapHeaderParser hp;
    			EapHeader header;
    			 hp.setAppData(&header);
    			 hp.setRawData(msg);
    			 hp.parseRawToApp();
    
    			// Check code
    			unsigned code = header.code;
    			unsigned id = header.identifier;
    
    			// Check code & identifier
    			if ((code != Response) || (id != sm.CurrentIdentifier())) {
    				sm.DeleteRxMessage();
    				sm.Notify(EvElse);
    				return;
    			}
    			// Parse the response EapResponseParser parser; EapResponse resp;
    			parser.setAppData(&resp);
    			parser.setRawData(msg);
    			parser.parseRawToApp();
    
    			EapType type = sm.CurrentMethod();
    
    			// Check response type.  If this is a Nak message and the current
    			// method is not a pass-through method, then generate a Nak
    			// reception event.
    			if (resp.GetType() == EapType(3) &&
    			    sm.Decision() != EapAuthSwitchStateMachine::DecisionPassthrough) {
    				if (sm.MethodState() == EapAuthSwitchStateMachine::PROPOSED) {
    					sm.Event(EvRxNak);
    				} else {
    					sm.DeleteRxMessage();
    					sm.Event(EvElse);
    				}
    			} else	// Normal method
    			{
    				if (resp.GetType() != type &&
    				    sm.Decision() != EapAuthSwitchStateMachine::DecisionPassthrough) {
    					sm.DeleteRxMessage();
    					sm.Event(EvElse);
    				} else {
    					sm.Event(EvRxMethodResp);
    				}
    			}
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcReceiveMsg.\n");
    		}
    	};
    
    	class AcReceiveMsg2:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg;
    
    			// Dequeue a message from receiving queue.
    			 sm.RxQueue().dequeue_head((ACE_Message_Block * &)msg);
    
    			// Set the read pointer to the message head.
    			 msg->rd_ptr(msg->base());
    
    			// Set msg to rxMessage.
    			 sm.SetRxMessage(msg);
    
    			// Parse the header
    			EapHeaderParser hp;
    			EapHeader header;
    			 hp.setAppData(&header);
    			 hp.setRawData(msg);
    			 hp.parseRawToApp();
    
    			// Check code
    			unsigned code = header.code;
    			unsigned id = header.identifier;
    
    			// Check code & identifier
    			if ((code != Response) || (id != sm.CurrentIdentifier())) {
    				sm.DeleteRxMessage();
    				sm.Notify(EvElse);
    				return;
    			}
    
    			sm.Event(EvRxMethodResp);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcReceiveMsg2.\n");
    		}
    	};
    
    	class AcPickUpInitCheck:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			if (sm.GetRxMessage() == 0)
    				sm.Event(EvSgNoPickUpInit);
    			else
    				sm.Event(EvSgPickUpInit);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcPickUpInitCheck.\n");
    		}
    	};
    
    	class AcAaaRequest:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			sm.Event(EvUCT);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcAaaRequest.\n");
    	}};
    
    	class AcDoIntegrityCheck2:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg = sm.GetRxMessage();
    
    			// If msg is empty, the system has been just started.  So call
    			// ForwardResponse with null argument and let the application do
    			// an appropriate action (e.g, send AAA message to the EAP
    			// server).  Otherwise, there is another method that has been
    			// completed immediately before entering passthrough mode, with
    			// receiving the first Response from the peer.  In this case, just
    			// pick up the Response and forward to the backend.
    
    			 EAP_LOG(LM_DEBUG, "Passthough: Integrity check.\n");
    
    			// Call the callback to forward the response.
    			 sm.ForwardResponse(msg);
    			 EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcDoIntegrityCheck2.\n");
    			// stay in this state (wait external event).
    	}};
    
    	class AcAaaContinue:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg;
    			 EapMessageQueue & q = sm.AAARxQueue();
    
    			if (q.is_empty()) {
    				sm.DeleteTxMessage();
    				EAP_LOG(LM_ERROR, "Passthrough: AAA message does not contain EAP-Request.\n");
    				sm.Abort();
    				return;
    			}
    
    			q.dequeue_head((ACE_Message_Block * &)msg);
    
    			// Parse the message and determine the event to be passed.
    			msg->rd_ptr(msg->base());
    
    			// Parse the message
    			EapHeaderParser hp;
    			EapHeader header;
    			hp.setAppData(&header);
    			hp.setRawData(msg);
    			hp.parseRawToApp();
    
    			unsigned code = header.code;
    
    			// Check code
    			if (code != Request) {
    				sm.Event(EvSgDiscard);
    				return;
    			}
    			// Set the received identifier as the current identifier.
    			sm.CurrentIdentifier() = header.identifier;
    
    			// Set the pass-through transmission message.
    			sm.SetTxMessage(msg);
    
    			if (code != Request) {
    				EAP_LOG(LM_ERROR, "Passthrough: AAA message does not contain EAP-Request.\n");
    				sm.Abort();
    				return;
    			}
    			// XXX: If we need to modify Identifier field, this is the place
    			// to do it.
    			sm.Event(EvRxAaaEapReq);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcAaaContinue.\n");
    		}
    	};
    
    	class AcAaaSuccess:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg;
    			 EapMessageQueue & q = sm.AAARxQueue();
    
    			if (q.is_empty()) {
    				sm.DeleteTxMessage();
    				sm.Event(EvSgAaaSuccess);
    				return;
    			}
    			q.dequeue_head((ACE_Message_Block * &)msg);
    
    			// Parse the message and determine the event to be passed.
    			msg->rd_ptr(msg->base());
    
    			// Parse the message
    			EapHeaderParser hp;
    			EapHeader header;
    			hp.setAppData(&header);
    			hp.setRawData(msg);
    			hp.parseRawToApp();
    
    			unsigned code = header.code;
    
    			// Check code
    			if (code != Success) {
    				sm.Event(EvSgDiscard);
    				return;
    			}
    			// Set the received identifier as the current identifier.
    			sm.CurrentIdentifier() = header.identifier;
    
    			// Set the pass-through transmission message.
    			sm.SetTxMessage(msg);
    			sm.Event(EvSgAaaSuccess);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcAaaSuccess.\n");
    		}
    	};
    
    	class AcAaaFailure:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg;
    			 EapMessageQueue & q = sm.AAARxQueue();
    
    			if (q.is_empty()) {
    				sm.DeleteTxMessage();
    				sm.Event(EvSgAaaFailure);
    				return;
    			}
    			q.dequeue_head((ACE_Message_Block * &)msg);
    
    			// Parse the message and determine the event to be passed.
    			msg->rd_ptr(msg->base());
    
    			// Parse the message
    			EapHeaderParser hp;
    			EapHeader header;
    			hp.setAppData(&header);
    			hp.setRawData(msg);
    			hp.parseRawToApp();
    
    			unsigned code = header.code;
    
    			// Check code
    			if (code != Failure) {
    				sm.Event(EvSgDiscard);
    				return;
    			}
    			// Set the received identifier as the current identifier.
    			sm.CurrentIdentifier() = header.identifier;
    
    			// Set the pass-through transmission message.
    			sm.SetTxMessage(msg);
    			sm.Event(EvSgAaaFailure);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcAaaFailure.\n");
    		}
    	};
    
    	class AcPrepareRequest:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			sm.Event(EvUCT);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcPrepareRequest.\n");
    	}};
    
    	class AcCompletePassThroughWithFailure:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg = sm.GetTxMessage();
    
    			 EAP_LOG(LM_DEBUG, "Passthrough: EAP authentication failed.\n");
    
    			// Stop retransmission timer and reset retransmission counter.
    			 sm.CancelTimer();
    			 sm.RetransmissionCount() = 0;
    
    			// Call Failure callback function.
    			if (msg) {
    				sm.Failure(msg);
    				// release the outstanding request.
    				sm.DeleteTxMessage();
    			} else
    				 sm.Failure();
    		}
    	};
    
    	class AcCompletePassThroughWithSuccess:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			AAAMessageBlock *msg = sm.GetTxMessage();
    
    			 EAP_LOG(LM_DEBUG, "Passthrough: EAP authentication succeeded.\n");
    
    			// Stop retransmission timer and reset retransmission counter.
    			 sm.CancelTimer();
    			 sm.RetransmissionCount() = 0;
    
    			// Make the key available. (not specified in the state machine document.)
    			if (sm.KeyData().size() > 0)
    				 sm.KeyAvailable() = true;
    
    			// Call Failure callback function.
    			if (msg) {
    				sm.Success(msg);
    				// release the outstanding request.
    				sm.DeleteTxMessage();
    			} else
    				 sm.Success();
    		}
    	};
    
    	class AcReturnToSwitch:public EapPassThroughAuthSwitchAction {
    		void operator() (EapPassThroughAuthSwitchStateMachine & sm) {
    			sm.Event(EapAuthSwitchStateMachine::EvSgValidResp);
    			EAP_LOG(LM_DEBUG, "Passthrough[auth]: AcReturnToSwitch  .\n");
    	}};
    
    	AcDisable acDisable;
    	AcInitialize acInitialize;
    	AcProposeMethod acProposeMethod;
    	AcBuildRequest acBuildRequest;
    	AcMethodResponse acMethodResponse;
    	AcSendSuccess acSendSuccess;
    	AcSendFailure acSendFailure;
    	AcSendRequest acSendRequest;
    	AcDoIntegrityCheck acDoIntegrityCheck;
    	AcDoPolicyCheck acDoPolicyCheck;
    	AcDiscard acDiscard;
    	AcDiscard2 acDiscard2;
    	AcResetMethod acResetMethod;
    	AcRetransmit acRetransmit;
    	AcReceiveMsg acReceiveMsg;
    
    	AcPickUpInitCheck acPickUpInitCheck;
    	AcAaaRequest acAaaRequest;
    	AcDoIntegrityCheck2 acDoIntegrityCheck2;
    	AcCompletePassThroughWithSuccess acCompletePassThroughWithSuccess;
    	AcCompletePassThroughWithFailure acCompletePassThroughWithFailure;
    	AcPrepareRequest acPrepareRequest;
    	AcAaaContinue acAaaContinue;
    	AcAaaSuccess acAaaSuccess;
    	AcAaaFailure acAaaFailure;
    	AcReturnToSwitch acReturnToSwitch;
    	AcDiscard3 acDiscard3;
    	AcReceiveMsg2 acReceiveMsg2;
    
    	enum event {
    		EvUCT,
    		EvSgPolicySat,
    		EvSgPolicyNotSat_EndSess,
    		EvSgPolicyNotSat_ContSess,
    		EvRxMethodResp,
    		EvRxNak,
    		EvTo,
    		EvSgMaxRetransmission,
    		EvElse,
    		EvSgPassThrough,
    		EvSgPickUpInit,
    		EvSgNoPickUpInit,
    		EvRxAaaEapReq,
    		EvSgAaaSuccess,
    		EvSgAaaFailure,
    		EvSgDiscard,
    	};
    
    	enum state {
    		StBegin,
    		StDisabled,
    		StInitialize,
    		StSelectAction,
    		StProposeMethod,
    		StIdle,
    		StIntegrityCheck,
    		StMethodRequest,
    		StMethodResponse,
    
    		StSendRequest,
    		StNak,
    		StRetransmit,
    		StDiscard,
    		StSuccess,
    		StFailure,
    		StTimeoutFailure,
    		StReceived,
    
    		StInitializePassThrough,
    		StAaaRequest,
    		StAaaIdle,
    		StAaaResponse,
    		StIdle2,
    		StReceived2,
    		StSuccess2,
    		StFailure2,
    		StSendRequest2,
    		StDiscard2,
    		StRetransmit2,
    		StTimeoutFailure2,
    	};
    
    	EapPassThroughAuthSwitchStateTable_S() {
    
    		AddStateTableEntry(StBegin, EapAuthSwitchStateMachine::EvSgRestart, StDisabled, acDisable);
    		AddStateTableEntry(StDisabled, EapAuthSwitchStateMachine::EvSgPortEnabled, StInitialize, acInitialize);
    		AddStateTableEntry(StInitialize, EvUCT, StSelectAction, acDoPolicyCheck);
    
    		AddStateTableEntry(StSelectAction, EvSgPolicySat, StSuccess, acSendSuccess);
    		AddStateTableEntry(StSelectAction, EvSgPolicyNotSat_EndSess, StFailure, acSendFailure);
    		AddStateTableEntry(StSelectAction, EvElse, StProposeMethod, acProposeMethod);
    		AddStateTableEntry(StSelectAction, EvSgPassThrough, StInitializePassThrough, acPickUpInitCheck);
    		AddStateTableEntry(StProposeMethod,
    				   EapAuthSwitchStateMachine::EvSgValidResp, StMethodRequest, acBuildRequest);
    
    		AddStateTableEntry(StMethodRequest, EvUCT, StSendRequest, acSendRequest);
    
    		AddStateTableEntry(StIntegrityCheck,
    				   EapAuthSwitchStateMachine::EvSgValidResp, StMethodResponse, acMethodResponse);
    		AddStateTableEntry(StIntegrityCheck, EapAuthSwitchStateMachine::EvSgInvalidResp, StDiscard, acDiscard);
    		// This state table entry is needed for queueing incoming requests.
    		AddStateTableEntry(StIntegrityCheck, EapAuthSwitchStateMachine::EvRxMsg, StIntegrityCheck, acDiscard2);
    
    		AddStateTableEntry(StMethodResponse,
    				   EapAuthSwitchStateMachine::EvSgEndMethod, StSelectAction, acDoPolicyCheck);
    		AddStateTableEntry(StMethodResponse, EvElse, StMethodRequest, acBuildRequest);
    
    		AddStateTableEntry(StSendRequest, EvUCT, StIdle);
    
    		AddStateTableEntry(StIdle, EvTo, StRetransmit, acRetransmit);
    		AddStateTableEntry(StIdle, EapAuthSwitchStateMachine::EvRxMsg, StReceived, acReceiveMsg);
    
    		AddStateTableEntry(StReceived, EvRxMethodResp, StIntegrityCheck, acDoIntegrityCheck);
    		AddStateTableEntry(StReceived, EvRxNak, StNak, acResetMethod);
    		AddStateTableEntry(StReceived, EvElse, StDiscard, acDiscard);
    
    		AddStateTableEntry(StRetransmit, EvSgMaxRetransmission, StTimeoutFailure);
    		AddStateTableEntry(StRetransmit, EvElse, StIdle);
    
    		AddStateTableEntry(StNak, EvUCT, StSelectAction, acDoPolicyCheck);
    
    		AddStateTableEntry(StDiscard, EvUCT, StIdle);
    
    		AddStateTableEntry(StSuccess, EapAuthSwitchStateMachine::EvRxMsg, StSuccess, acDiscard2);
    		AddWildcardStateTableEntry(StSuccess, StSuccess);
    		AddStateTableEntry(StFailure, EapAuthSwitchStateMachine::EvRxMsg, StFailure, acDiscard2);
    		AddWildcardStateTableEntry(StFailure, StFailure);
    
    		// Passthrough diagram
    		AddStateTableEntry(StInitializePassThrough, EvSgPickUpInit, StAaaRequest, acAaaRequest);
    		AddStateTableEntry(StInitializePassThrough, EvSgNoPickUpInit, StAaaIdle, acDoIntegrityCheck2);
    
    		AddStateTableEntry(StAaaRequest, EvUCT, StAaaIdle, acDoIntegrityCheck2);
    
    		AddStateTableEntry(StAaaIdle, EvRxAaaEapReq, StAaaResponse, acPrepareRequest);
    		AddStateTableEntry(StAaaIdle, EvSgAaaSuccess, StSuccess2, acCompletePassThroughWithSuccess);
    		AddStateTableEntry(StAaaIdle, EvSgAaaFailure, StFailure2, acCompletePassThroughWithFailure);
    		AddStateTableEntry(StAaaIdle, EapAuthSwitchStateMachine::EvSgAaaContinue, StAaaIdle, acAaaContinue);
    		AddStateTableEntry(StAaaIdle, EapAuthSwitchStateMachine::EvSgAaaSuccess, StAaaIdle, acAaaSuccess);
    		AddStateTableEntry(StAaaIdle, EapAuthSwitchStateMachine::EvSgAaaFailure, StAaaIdle, acAaaFailure);
    		AddStateTableEntry(StAaaIdle, EvSgDiscard, StDiscard2, acDiscard3);
    		AddWildcardStateTableEntry(StAaaIdle, StAaaIdle);
    
    		AddStateTableEntry(StDiscard2, EvUCT, StIdle2);
    
    		AddStateTableEntry(StReceived2, EvRxMethodResp, StAaaRequest, acAaaRequest);
    		AddStateTableEntry(StReceived2, EvElse, StDiscard2, acDiscard);
    
    		AddStateTableEntry(StIdle2, EapAuthSwitchStateMachine::EvRxMsg, StReceived2, acReceiveMsg2);
    		AddStateTableEntry(StIdle2, EapAuthSwitchStateMachine::EvSgAaaContinue, StIdle2, acDiscard3);
    		AddStateTableEntry(StIdle2, EvTo, StRetransmit2, acRetransmit);
    		AddWildcardStateTableEntry(StIdle2, StIdle2);
    
    		AddStateTableEntry(StAaaResponse, EvUCT, StSendRequest2, acSendRequest);
    		AddStateTableEntry(StSendRequest2, EvUCT, StIdle2);
    
    		AddStateTableEntry(StSuccess2, EapAuthSwitchStateMachine::EvSgAaaContinue, StSuccess2, acDiscard3);
    		AddWildcardStateTableEntry(StSuccess2, StSuccess2);
    		AddStateTableEntry(StFailure2, EapAuthSwitchStateMachine::EvSgAaaContinue, StFailure2, acDiscard3);
    		AddWildcardStateTableEntry(StFailure2, StFailure2);
    
    		AddStateTableEntry(StRetransmit2, EvSgMaxRetransmission, StTimeoutFailure2);
    		AddStateTableEntry(StRetransmit2, EvElse, StIdle2);
    
    		InitialState(StBegin);
    	}
    	~EapPassThroughAuthSwitchStateTable_S() {
    	}
    };
    
     EapPassThroughAuthSwitchStateMachine::EapPassThroughAuthSwitchStateMachine(ACE_Reactor & r, EapJobHandle & h):
    EapAuthSwitchStateMachine(r, h),
        EapStateMachine < EapPassThroughAuthSwitchStateMachine >
        (*this, *EapPassThroughAuthSwitchStateTable::instance(), r, *this, "passthrough")
    {
    }
    
    EapPassThroughAuthSwitchStateMachine::~EapPassThroughAuthSwitchStateMachine()
    {
    }
    
    EapAuthSwitchStateMachine::EapAuthDecision EapPassThroughAuthSwitchStateMachine::Decision()
    {
    	EapType type;
    
    	try {
    		type = policy.CurrentMethod();
    	}
    	catch(EapPolicy::PolicyError e) {	// No method to try.
    		if (e == EapPolicy::NoCurrentMethod)
    			return DecisionPassthrough;
    	}
    	return DecisionContinue;
    }

    And here is the application header that has those errors stated at the top:

    Code:
    #ifndef __NASD_EAP_PASSTHROUGH_H__
    #define __NASD_EAP_PASSTHROUGH_H__
    
    #include "nasd_call_framework.h"
    #include "eap_identity.hxx"
    #include "eap_method_registrar.hxx"
    
    class NASD_EapPassThroughAuthIdentityStateMachine : 
          public EapAuthIdentityStateMachine
    {
         friend class EapMethodStateMachineCreator
                      <NASD_EapPassThroughAuthIdentityStateMachine>;
       public:
         NASD_EapPassThroughAuthIdentityStateMachine(EapSwitchStateMachine &s)
            : EapAuthIdentityStateMachine(s) {
         } 
         ProcessIdentityResult ProcessIdentity(std::string& identity);
         
       private:
         virtual ~NASD_EapPassThroughAuthIdentityStateMachine() {
         } 
    };
    
    class NASD_EapPassThroughAuthSwitchStateMachine :
          public EapPassThroughAuthSwitchStateMachine
    {
       public:
          NASD_EapPassThroughAuthSwitchStateMachine
                 (ACE_Reactor &r, 
                  EapJobHandle& h,
                  NASD_CallRouting &rte) :
              EapPassThroughAuthSwitchStateMachine(r, h),
              m_Node(rte),
              m_IdentityPolicy(EapContinuedPolicyElement(EapType(1))) {
              Policy().InitialPolicyElement(&m_IdentityPolicy);
          }
          void Send(AAAMessageBlock *b) {
              m_Node.SendEgress(*b);
          }
          void ForwardResponse(AAAMessageBlock *b) {
              m_Node.SendIngress(*b);
          }
          void Success(AAAMessageBlock *b) {
              m_Node.PrevNode()->Success(b);
          }
          void Success() {
              m_Node.PrevNode()->Success(0);
          }
          void Failure(AAAMessageBlock *b) {
              m_Node.PrevNode()->Failure(b);
          }
          void Failure() {
              m_Node.PrevNode()->Failure(0);
          }
          void Abort() {
              m_Node.PrevNode()->Failure(0);
          }
          NASD_CallRouting &CallRouting() {
              return dynamic_cast<NASD_CallRouting&>(m_Node);
          }
          
       private:
          /// node reference
          NASD_CallNode &m_Node;
          
          /// policy elements
          EapContinuedPolicyElement m_IdentityPolicy;
    };
    
    class NASD_EapPassThrough : 
       public NASD_CallRouting
    {
       public:
          NASD_EapPassThrough(AAA_Task &t) : 
             m_Task(t),
             m_JobHandle(AAA_GroupedJob::Create
                 (t.Job(), this, (char *)("eap-passthrough"))) {
          }
          virtual ~NASD_EapPassThrough() {
    	 Stop();
             m_JobHandle->Stop();
             m_JobHandle.reset();
          }
          int Start() {
             if (m_Eap.get()) {
                 return (-1);
             }
             
             m_MethodRegistrar.registerMethod
                 (std::string("Identity"), EapType(1),
                   Authenticator, m_NasEapAuthIdentityCreator);
    
             m_Eap = boost::shared_ptr<NASD_EapPassThroughAuthSwitchStateMachine>
                      (new NASD_EapPassThroughAuthSwitchStateMachine
                          (*m_Task.reactor(), m_JobHandle, *this));
    
             m_Eap->NeedInitialRequestToSend(false);
             m_Eap->Start();
             return (0);
          }
          bool IsRunning() {
             return (m_Eap.get()) ? true : false;
          }
          void Stop() {
             if (m_Eap.get()) {         
                 m_Eap->Stop();
                 m_Eap.reset();
             }
          }
          bool CurrentKey(std::string &key) {
            if (m_Eap->KeyAvailable()) {
                 NASD_LOG(LM_INFO, "(%P|%t) Assigning key\n");
                 key.assign(m_Eap->KeyData().data(), 
                            m_Eap->KeyData().size());
                 return true;
             }
             return false;
          }
          bool Identity(std::string &ident) {
    	 if (m_Identity.length() > 0) {
    	     ident = m_Identity;
                 return true;
    	 }
             return false;
          }
          int ReceiveIngress(AAAMessageBlock &msg) {
             m_Eap->Receive(&msg);
             return (0);
          }
          int ReceiveEgress(AAAMessageBlock &msg) {
             m_Eap->AAA_Continue(&msg);
             return (0); // standalone does not have next
          }
          void Success(AAAMessageBlock *msg = 0) {
             if (msg) {
    	     std::string key;
    	     if (NextNode()->CurrentKey(key)) {
                     m_Eap->AAA_Success(msg, key);
    	     }
                 else {
                     m_Eap->AAA_Success(msg);
    	     }
             }
          }
          void Failure(AAAMessageBlock *msg = 0) {
             if (msg) {
                 m_Eap->AAA_Failure(msg);
             }
          }
          void Timeout() {
             Stop();
          }
          void Error() {
             Stop();
          }
       
       private:
          /// framework
          AAA_Task &m_Task;
          AAA_JobHandle<AAA_GroupedJob> m_JobHandle;
          
          /// eap instance
          boost::shared_ptr<NASD_EapPassThroughAuthSwitchStateMachine> m_Eap;
          
          /// method creators
          EapMethodRegistrar m_MethodRegistrar;
          EapMethodStateMachineCreator<NASD_EapPassThroughAuthIdentityStateMachine> 
              m_NasEapAuthIdentityCreator;
    
          /// user information
          std::string m_Identity;
    
          friend class NASD_EapPassThroughAuthIdentityStateMachine;
    };
    
    inline EapAuthIdentityStateMachine::ProcessIdentityResult 
    NASD_EapPassThroughAuthIdentityStateMachine::ProcessIdentity
        (std::string& identity) 
    {
        NASD_EapPassThroughAuthSwitchStateMachine &fsm = 
           (NASD_EapPassThroughAuthSwitchStateMachine&)
                SwitchStateMachine();
     
        NASD_EapPassThrough &pt = (NASD_EapPassThrough&)fsm.CallRouting();
        pt.m_Identity = identity;
    
        pt.IncommingCall(identity);
        return EapAuthIdentityStateMachine::Success;
    }
    
    class NASD_EapPassThroughInitializer : 
        public NASD_CnInitCallback
    {
        public:
            virtual bool Initialize(AAA_Task &t) {
               NASD_LOG(LM_INFO, 
                      "(%P|%t) Initializing Local EAP auth\n");
               return (true);
    	}
            virtual NASD_CallElement *Create(AAA_Task &t) {
               return (new NASD_EapPassThrough(t));
    	}
    };

    Again, I'd greatly appreciate the help!

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    I don't really think you can expect much help when you dump over a thousand lines of code in the forum. The forum guidelines specify that you should post the smallest example that illustrates your problem.

    That being said, I don't see you defining the copy constructor that it says it can't find. I haven't dug any deeper than that.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  3. #3
    Registered User lantzvillian's Avatar
    Join Date
    Sep 2010
    Posts
    44
    Quote Originally Posted by Elkvis View Post
    I don't really think you can expect much help when you dump over a thousand lines of code in the forum. The forum guidelines specify that you should post the smallest example that illustrates your problem.

    That being said, I don't see you defining the copy constructor that it says it can't find. I haven't dug any deeper than that.
    Yes thats true, but unfortunately - the source is HUGE. I am doing this as a favour for the previous researchers and advisors. I suspect that much of this is poorly written which is why it makes little sense to me. I appreciate the comment though.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Actually, I guess it's not a copy constructor, but regardless, I don't see a definition of EapAuthIdentityStateMachine::EapAuthIdentityStateM achine(EapSwitchStateMachine&).
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The reason is probably that you're missing a source file (or the compiled object) from your build.

    Those error messages are from the linker (not the compiler) and basically means your code has tried to call a function (which, in C++, means it has been declared) but there is no definition (aka implementation) of that function provided.

    I could get the same thing with a program
    Code:
    void foo();
    
    int main()
    {
        foo();
        return 0;
    }
    Note that foo() has been declared but not defined, so a linker would complain about foo() being undefined. The code will compile (since the call of foo() matches the declaration) but not link.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User lantzvillian's Avatar
    Join Date
    Sep 2010
    Posts
    44
    Quote Originally Posted by grumpy View Post
    The reason is probably that you're missing a source file (or the compiled object) from your build.

    Those error messages are from the linker (not the compiler) and basically means your code has tried to call a function (which, in C++, means it has been declared) but there is no definition (aka implementation) of that function provided.

    I could get the same thing with a program
    Code:
    void foo();
    
    int main()
    {
        foo();
        return 0;
    }
    Note that foo() has been declared but not defined, so a linker would complain about foo() being undefined. The code will compile (since the call of foo() matches the declaration) but not link.

    I suspect you are right as its common in C libraries.

  7. #7
    Registered User lantzvillian's Avatar
    Join Date
    Sep 2010
    Posts
    44
    I see it being defined in this c file as:

    Code:
    EapAuthIdentityStateMachine::EapAuthIdentityStateMachine
    (EapSwitchStateMachine &s)
      : EapMethodStateMachine(s), 
        EapStateMachine<EapAuthIdentityStateMachine>
      (*this, *EapAuthIdentityStateTable::instance(), s.Reactor(), s, "identity"),
        nTrial(0) 
    {}
    And being used in tandem with this hxx file

    Code:
    #ifndef __EAP_IDENTITY_HXX__
    #define __EAP_IDENTITY_HXX__
    
    #include <ace/Basic_Types.h>
    #include "eap.hxx"
    #include "eap_fsm.hxx"
    #include "eap_authfsm.hxx"
    #include "eap_peerfsm.hxx"
    
    class EapAuthIdentityStateMachine;
    
    /// This class implements Identity method at authenticator side.
    class EAP_EXPORTS EapAuthIdentityStateMachine : 
      public EapMethodStateMachine,
      public EapStateMachine<EapAuthIdentityStateMachine>
    {
      friend class EapMethodStateMachineCreator<EapAuthIdentityStateMachine>;
      friend class EapAuthIdentityStateTable_S;
    public:
    
      /// Reimplemented from EapMethodStateMachine
      void Start() throw(AAA_Error)
      {
        EapStateMachine<EapAuthIdentityStateMachine>::Start();
      }
    
      /// Reimplemented from EapMethodStateMachine
      inline void Notify(AAA_Event ev)
      {
        EapStateMachine<EapAuthIdentityStateMachine>::Notify(ev);
      }
    
      void Receive(AAAMessageBlock *b) {}
      /// Maximum number of retry for sending Request/Identity.
      static const ACE_UINT32 maxTrial;
    
      /// Use this function to obtain the current number of trial for this method.
      ACE_UINT32& NumberOfTrial() { return nTrial; }
    
      /// Used by ProcessIdentity() as return values.
      enum ProcessIdentityResult {
        Success,
        Failure
      };
    
      /// This pure virtual function is a callback used when an
      /// identity of the peer is received.
      virtual ProcessIdentityResult ProcessIdentity(std::string& identity)=0;
    
    protected:
      EapAuthIdentityStateMachine(EapSwitchStateMachine &s);
      ~EapAuthIdentityStateMachine() {} 
    
      ACE_UINT32 nTrial;
    };
    
    #endif // __EAP_IDENTITY_HXX__
    it appears to be compiled into the library so there for I think it should work no?

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Check the link order. Place libraries at the end of the command line.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. undefined reference to defined function
    By quo in forum C++ Programming
    Replies: 20
    Last Post: 05-11-2012, 04:43 PM
  2. Replies: 5
    Last Post: 03-07-2011, 01:01 AM
  3. Undefined reference - however they ARE defined
    By scarecrow in forum C++ Programming
    Replies: 4
    Last Post: 05-04-2008, 05:14 PM
  4. Replies: 4
    Last Post: 03-04-2004, 10:56 PM
  5. Undefined Variables that ARE defined
    By Teema in forum C Programming
    Replies: 3
    Last Post: 12-03-2002, 01:14 AM