⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xrl_mld6igmp_node.cc

📁 MLDv2 support igmpv3 lite
💻 CC
📖 第 1 页 / 共 5 页
字号:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// Copyright (c) 2001-2008 XORP, Inc.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the "Software")// to deal in the Software without restriction, subject to the conditions// listed in the XORP LICENSE file. These conditions include: you must// preserve this copyright notice, and you cannot mention the copyright// holders in advertising related to the Software without their permission.// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This// notice is a summary of the XORP LICENSE file; the license in that file is// legally binding.#ident "$XORP: xorp/contrib/mld6igmp_lite/xrl_mld6igmp_node.cc,v 1.2 2008/07/23 05:09:50 pavlin Exp $"#include "mld6igmp_module.h"#include "libxorp/xorp.h"#include "libxorp/xlog.h"#include "libxorp/debug.h"#include "libxorp/ipvx.hh"#include "libxorp/status_codes.h"#include "libxorp/utils.hh"#include "mld6igmp_node.hh"#include "mld6igmp_node_cli.hh"#include "mld6igmp_vif.hh"#include "xrl_mld6igmp_node.hh"const TimeVal XrlMld6igmpNode::RETRY_TIMEVAL = TimeVal(1, 0);//// XrlMld6igmpNode front-end interface//XrlMld6igmpNode::XrlMld6igmpNode(int		family,				 xorp_module_id	module_id, 				 EventLoop&	eventloop,				 const string&	class_name,				 const string&	finder_hostname,				 uint16_t	finder_port,				 const string&	finder_target,				 const string&	fea_target,				 const string&	mfea_target)    : Mld6igmpNode(family, module_id, eventloop),      XrlStdRouter(eventloop, class_name.c_str(), finder_hostname.c_str(),		   finder_port),      XrlMld6igmpTargetBase(&xrl_router()),      Mld6igmpNodeCli(*static_cast<Mld6igmpNode *>(this)),      _eventloop(eventloop),      _finder_target(finder_target),      _fea_target(fea_target),      _mfea_target(mfea_target),      _ifmgr(eventloop, mfea_target.c_str(), xrl_router().finder_address(),	     xrl_router().finder_port()),      _xrl_fea_client4(&xrl_router()),      _xrl_fea_client6(&xrl_router()),      _xrl_mld6igmp_client_client(&xrl_router()),      _xrl_cli_manager_client(&xrl_router()),      _xrl_finder_client(&xrl_router()),      _is_finder_alive(false),      _is_fea_alive(false),      _is_fea_registered(false),      _is_mfea_alive(false),      _is_mfea_registered(false){    _ifmgr.set_observer(dynamic_cast<Mld6igmpNode*>(this));    _ifmgr.attach_hint_observer(dynamic_cast<Mld6igmpNode*>(this));}XrlMld6igmpNode::~XrlMld6igmpNode(){    shutdown();    _ifmgr.detach_hint_observer(dynamic_cast<Mld6igmpNode*>(this));    _ifmgr.unset_observer(dynamic_cast<Mld6igmpNode*>(this));    delete_pointers_list(_xrl_tasks_queue);}intXrlMld6igmpNode::startup(){    if (start_mld6igmp() != XORP_OK)	return (XORP_ERROR);    return (XORP_OK);}intXrlMld6igmpNode::shutdown(){   int ret_value = XORP_OK;    if (stop_cli() != XORP_OK)	ret_value = XORP_ERROR;    if (stop_mld6igmp() != XORP_OK)	ret_value = XORP_ERROR;    return (ret_value);}intXrlMld6igmpNode::enable_cli(){    Mld6igmpNodeCli::enable();        return (XORP_OK);}intXrlMld6igmpNode::disable_cli(){    Mld6igmpNodeCli::disable();        return (XORP_OK);}intXrlMld6igmpNode::start_cli(){    if (Mld6igmpNodeCli::start() != XORP_OK)	return (XORP_ERROR);        return (XORP_OK);}intXrlMld6igmpNode::stop_cli(){    if (Mld6igmpNodeCli::stop() != XORP_OK)	return (XORP_ERROR);        return (XORP_OK);}intXrlMld6igmpNode::enable_mld6igmp(){    Mld6igmpNode::enable();        return (XORP_OK);}intXrlMld6igmpNode::disable_mld6igmp(){    Mld6igmpNode::disable();        return (XORP_OK);}intXrlMld6igmpNode::start_mld6igmp(){    if (Mld6igmpNode::start() != XORP_OK)	return (XORP_ERROR);        return (XORP_OK);}intXrlMld6igmpNode::stop_mld6igmp(){    if (Mld6igmpNode::stop() != XORP_OK)	return (XORP_ERROR);        return (XORP_OK);}//// Finder-related events///** * Called when Finder connection is established. * * Note that this method overwrites an XrlRouter virtual method. */voidXrlMld6igmpNode::finder_connect_event(){    _is_finder_alive = true;}/** * Called when Finder disconnect occurs. * * Note that this method overwrites an XrlRouter virtual method. */voidXrlMld6igmpNode::finder_disconnect_event(){    XLOG_ERROR("Finder disconnect event. Exiting immediately...");    _is_finder_alive = false;    stop_mld6igmp();}//// Task-related methods//voidXrlMld6igmpNode::add_task(XrlTaskBase* xrl_task){    _xrl_tasks_queue.push_back(xrl_task);    // If the queue was empty before, start sending the changes    if (_xrl_tasks_queue.size() == 1)	send_xrl_task();}voidXrlMld6igmpNode::send_xrl_task(){    if (_xrl_tasks_queue.empty())	return;    XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front();    XLOG_ASSERT(xrl_task_base != NULL);    xrl_task_base->dispatch();}voidXrlMld6igmpNode::pop_xrl_task(){    XLOG_ASSERT(! _xrl_tasks_queue.empty());    XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front();    XLOG_ASSERT(xrl_task_base != NULL);    delete xrl_task_base;    _xrl_tasks_queue.pop_front();}voidXrlMld6igmpNode::retry_xrl_task(){    if (_xrl_tasks_queue_timer.scheduled())	return;		// XXX: already scheduled    _xrl_tasks_queue_timer = _eventloop.new_oneoff_after(	RETRY_TIMEVAL,	callback(this, &XrlMld6igmpNode::send_xrl_task));}//// Register with the FEA//voidXrlMld6igmpNode::fea_register_startup(){    if (! _is_finder_alive)	return;		// The Finder is dead    if (_is_fea_registered)	return;		// Already registered    Mld6igmpNode::incr_startup_requests_n();	// XXX: for FEA registration    Mld6igmpNode::incr_startup_requests_n();	// XXX: for FEA birth    //    // Register interest in the FEA with the Finder    //    add_task(new RegisterUnregisterInterest(*this, _fea_target, true));}//// Register with the MFEA//voidXrlMld6igmpNode::mfea_register_startup(){    if (! _is_finder_alive)	return;		// The Finder is dead    if (_is_mfea_registered)	return;		// Already registered    Mld6igmpNode::incr_startup_requests_n();	// XXX: for MFEA registration    Mld6igmpNode::incr_startup_requests_n();	// XXX: for MFEA birth    Mld6igmpNode::incr_startup_requests_n();	// XXX: for the ifmgr    //    // Register interest in the FEA with the Finder    //    add_task(new RegisterUnregisterInterest(*this, _mfea_target, true));}//// De-register with the FEA//voidXrlMld6igmpNode::fea_register_shutdown(){    if (! _is_finder_alive)	return;		// The Finder is dead    if (! _is_fea_alive)	return;		// The FEA is not there anymore    if (! _is_fea_registered)	return;		// Not registered    Mld6igmpNode::incr_shutdown_requests_n();	// XXX: for FEA deregistration    //    // De-register interest in the FEA with the Finder    //    add_task(new RegisterUnregisterInterest(*this, _fea_target, false));}//// De-register with the MFEA//voidXrlMld6igmpNode::mfea_register_shutdown(){    if (! _is_finder_alive)	return;		// The Finder is dead    if (! _is_mfea_alive)	return;		// The MFEA is not there anymore    if (! _is_mfea_registered)	return;		// Not registered    Mld6igmpNode::incr_shutdown_requests_n();	// XXX: for MFEA deregistration    Mld6igmpNode::incr_shutdown_requests_n();	// XXX: for the ifmgr    //    // De-register interest in the MFEA with the Finder    //    add_task(new RegisterUnregisterInterest(*this, _mfea_target, false));    //    // XXX: when the shutdown is completed, Mld6igmpNode::status_change()    // will be called.    //    _ifmgr.shutdown();}voidXrlMld6igmpNode::send_register_unregister_interest(){    bool success = true;    if (! _is_finder_alive)	return;		// The Finder is dead    XLOG_ASSERT(! _xrl_tasks_queue.empty());    XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front();    RegisterUnregisterInterest* entry;    entry = dynamic_cast<RegisterUnregisterInterest*>(xrl_task_base);    XLOG_ASSERT(entry != NULL);    if (entry->is_register()) {	// Register interest	success = _xrl_finder_client.send_register_class_event_interest(	    _finder_target.c_str(), xrl_router().instance_name(),	    entry->target_name(),	    callback(this, &XrlMld6igmpNode::finder_send_register_unregister_interest_cb));    } else {	// Unregister interest	success = _xrl_finder_client.send_deregister_class_event_interest(	    _finder_target.c_str(), xrl_router().instance_name(),	    entry->target_name(),	    callback(this, &XrlMld6igmpNode::finder_send_register_unregister_interest_cb));    }    if (! success) {	//	// If an error, then try again	//	XLOG_ERROR("Failed to %s register interest in %s with the Finder. "		   "Will try again.",		   entry->operation_name(),		   entry->target_name().c_str());	retry_xrl_task();	return;    }}voidXrlMld6igmpNode::finder_send_register_unregister_interest_cb(const XrlError& xrl_error){    XLOG_ASSERT(! _xrl_tasks_queue.empty());    XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front();    RegisterUnregisterInterest* entry;    entry = dynamic_cast<RegisterUnregisterInterest*>(xrl_task_base);    XLOG_ASSERT(entry != NULL);    switch (xrl_error.error_code()) {    case OKAY:	//	// If success, then schedule the next task	//	if (entry->is_register()) {	    //	    // Register interest	    //	    if (entry->target_name() == _fea_target) {		//		// If success, then the FEA birth event will startup the FEA		// registration.		//		_is_fea_registered = true;		Mld6igmpNode::decr_startup_requests_n(); // XXX: for FEA registration	    }	    if (entry->target_name() == _mfea_target) {		//		// If success, then the MFEA birth event will startup the MFEA		// registration and the ifmgr.		//		_is_mfea_registered = true;		Mld6igmpNode::decr_startup_requests_n(); // XXX: for MFEA registration	    }	} else {	    //	    // Unregister interest	    //	    if (entry->target_name() == _fea_target) {		_is_fea_registered = false;		Mld6igmpNode::decr_shutdown_requests_n(); // XXX: for the FEA	    }	    if (entry->target_name() == _mfea_target) {		_is_mfea_registered = false;		Mld6igmpNode::decr_shutdown_requests_n(); // XXX: for the MFEA	    }	}	pop_xrl_task();	send_xrl_task();	break;    case COMMAND_FAILED:	//	// If a command failed because the other side rejected it, this is	// fatal.	//	XLOG_FATAL("Cannot %s interest in Finder events: %s",		   entry->operation_name(), xrl_error.str().c_str());	break;    case NO_FINDER:    case RESOLVE_FAILED:    case SEND_FAILED:	//	// A communication error that should have been caught elsewhere	// (e.g., by tracking the status of the Finder and the other targets).	// Probably we caught it here because of event reordering.	// In some cases we print an error. In other cases our job is done.	//	if (entry->is_register()) {	    XLOG_ERROR("XRL communication error: %s", xrl_error.str().c_str());	} else {	    if (entry->target_name() == _fea_target) {		_is_fea_registered = false;	    }	    if (entry->target_name() == _mfea_target) {		_is_mfea_registered = false;	    }	    pop_xrl_task();	    send_xrl_task();	}	break;    case BAD_ARGS:    case NO_SUCH_METHOD:    case INTERNAL_ERROR:	//	// An error that should happen only if there is something unusual:	// e.g., there is XRL mismatch, no enough internal resources, etc.	// We don't try to recover from such errors, hence this is fatal.	//	XLOG_FATAL("Fatal XRL error: %s", xrl_error.str().c_str());	break;    case REPLY_TIMED_OUT:    case SEND_FAILED_TRANSIENT:	//	// If a transient error, then try again	//	XLOG_ERROR("Failed to %s interest in Finder envents: %s. "		   "Will try again.",		   entry->operation_name(), xrl_error.str().c_str());	retry_xrl_task();	break;    }}intXrlMld6igmpNode::register_receiver(const string& if_name,				   const string& vif_name,				   uint8_t ip_protocol,				   bool enable_multicast_loopback){    Mld6igmpNode::incr_startup_requests_n();	// XXX: for FEA-receiver    add_task(new RegisterUnregisterReceiver(*this, if_name, vif_name,					    ip_protocol,					    enable_multicast_loopback,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -