Ejemplo n.º 1
0
void pim_interface::handle_join_source(group *grp, const inet6_addr &src, uint32_t holdtime, bool rpt) {
	if (!grp)
		return;

	pim_group_node *node = (pim_group_node *)grp->node_owned_by(pim);

	if (!node)
		return;

	pim_source_state_base *state = node->get_state(src, rpt);

	if (!state) {
		/// 3.2.2.2

		/* If we don't have a state for G, as it is a join, downstream
		 * wanted to revert Prune to Join, which doesnt make sense here. */
		if (rpt)
			return;

		node->create_state(src, rpt, owner(), false, holdtime);

//		if (pimrouter->mrib().rpf_check(node, src, owner()))
//			node->create_state(src, owner(), false, holdtime);
//		else
//			g_mrd->log().debug() << "Downstream Join failed: RPF check failed." << endl;
	}

	handle_join(node, src, holdtime, rpt);
}
Ejemplo n.º 2
0
void pim_interface::handle_join(const inet6_addr &grpaddr, const inet6_addr &src, uint32_t holdtime, bool rpt) {
	group *grp = g_mrd->get_group_by_addr(grpaddr);
	if (!grp)
		return;

	pim_group_node *node = (pim_group_node *)grp->node_owned_by(pim);

	if (node)
		handle_join(node, src, holdtime, rpt);
}
Ejemplo n.º 3
0
static bool
dispatch_handler(int fd, struct ircmsg *msg)
{
    switch (msg->type) {
      case IRCMSG_UNKNOWN:  return true;
      case IRCMSG_PING:     return handle_ping(fd, &msg->u.ping);
      case IRCMSG_PART:     return handle_part(fd, &msg->u.part);
      case IRCMSG_JOIN:     return handle_join(fd, &msg->u.join);
      case IRCMSG_PRIVMSG:  return handle_privmsg(fd, &msg->u.privmsg);
      case IRCMSG_KICK:     return handle_kick(fd, &msg->u.kick);
      default:              return false;
    }
}
Ejemplo n.º 4
0
void pim_interface::handle_join_wc_rpt(group *grp, const inet6_addr &src,
		const address_set &pruneaddrs, uint32_t holdtime, bool rpt) {
	if (!grp)
		return;

	pim_group_node *node = (pim_group_node *)grp->node_owned_by(pim);

	/// 3.2.2.1.2
	if (!node) {
		/* Either PIM is disabled for this group or we didn't have
		 * enough memory in the past */
		return;
	}

	if (node->has_rp() && !(node->rpaddr() == src)) {
		/*
		 * We already have a group instance for G, and the currently
		 * used RP address differs from the requested one, ignore Join.
		 */
		return;
	}

	bool had = node->has_wildcard();

	if (!had) {
		if (!node->create_wildcard()) {
			return;
		}
	}

	node->wildcard()->set_oif(owner(), holdtime);

	if (!had) {
		rp_source rpsrc;
		inet6_addr possiblerp = node->rp_for_group(rpsrc);
		if (!(possiblerp == src)) {
			if (should_log(DEBUG)) {
				log().writeline("RP in J/P message is not the"
						"configured one, ignoring Join/Prune.");
				return;
			}
		}

		node->set_rp(src, rps_join);

		/// 3.2.2.1.5
		node->wildcard()->check_upstream_path();
	}

	handle_join(node, src, holdtime, rpt);
}
Ejemplo n.º 5
0
void pim_interface::handle_joinprune(const sockaddr_in6 *_from, pim_joinprune_message *msg, uint16_t len) {
	m_stats.counter(JoinPruneCount, RX)++;

	/* Just to be sure */
	if (g_mrd->has_address(_from->sin6_addr))
		return;

	if (should_log(MESSAGE_CONTENT)) {
		base_stream &os = log();
		os.inc_level();
		_debug_pim_dump(os, *msg);
		os.dec_level();
	}

	inet6_addr upneigh(msg->upstream_neigh.addr);

	if (!g_mrd->has_address(upneigh)) {
		/* Lets monitor the Join/Prunes in the link
		 * to react properly */

		handle_external_joinprune(_from, msg, len);

		return;
	}

	pim_neighbour *neigh = pim->get_neighbour(_from->sin6_addr);
	if (!neigh) {
		if (should_log(DEBUG)) {
			log().xprintf("Dropping Join/Prune from %{addr}, not "
				      "a known neighbor.\n", _from->sin6_addr);
		}

		m_stats.counter(JoinPruneCount, Bad)++;

		return;
	}

	pim_group_node *node;

	pim_joinprune_group *grp = msg->groups();

	for (uint8_t i = 0; i < msg->ngroups; i++, grp = grp->next()) {
		inet6_addr groupaddr(grp->maddr.addr, grp->maddr.masklen);

		groupconf *entry = g_mrd->match_group_configuration(groupaddr);
		pim_groupconf_node *info = entry ? (pim_groupconf_node *)entry->get_child("pim") : 0;

		for (pim_jp_g_iterator i = grp->join_begin();
					i != grp->join_end(); ++i) {
			if (i->wc() && i->rpt()) {
				bool accept_rp = true;

				if (info)
					accept_rp = info->get_property_address
							("accept_rp").matches(i->address());

				if (accept_rp) {
					address_set prunes;
					grp->pruned_addrs(prunes);

					handle_join_wc_rpt(groupaddr, i->address(),
							   prunes, msg->holdtime(),
							   i->rpt());
				} else {
					/// 3.2.2.1.1
				}
			} else if (!i->wc() && !i->rpt()) {
				handle_join_source(groupaddr, i->address(),
						   msg->holdtime(), i->rpt());
			} else {
				handle_join(groupaddr, i->address(),
					    msg->holdtime(), i->rpt());
			}
		}

		for (pim_jp_g_iterator i = grp->prune_begin();
					i != grp->prune_end(); ++i) {
			/* we update the node reference on each cycle as
			 * it may have been deleted due to a prune */
			node = pim->get_group(groupaddr);
			if (node == NULL)
				continue;

			pim_source_state_base *target = NULL;
			uint32_t holdtime = 0;

			if (!i->wc()) {
				target = node->get_state(i->address(), i->rpt());
				holdtime = msg->holdtime();
			} else if (i->wc() && i->rpt()) {
				if (node->rpaddr() == i->address())
					target = node->wildcard();
			}

			if (target)
				target->set_oif(owner(), holdtime, false);
		}
	}
}
Ejemplo n.º 6
0
void ircInterface::onMessage(std::string msg){
/*	while(pkge.find("\r\n") != std::string::npos){
		std::string msg = pkge.substr(0, pkge.find("\r\n"));
		pkge = pkge.substr(pkge.find("\r\n") + 2);
*/
		//std::cout << "ircInterface: raw message is : "<<msg<<std::endl;
		ircLog::instance()->logf(FILENAME, "raw message is: %s", msg.c_str());
		
		//alot of the control strings will start with  the type sperated from the 
		//contents of the message with a space
		std::string type = msg.substr(0, msg.find_first_of(' '));


		//first check for messages that start with message names
		//check for ping
		if(!type.compare(PING))
		{
			_connStatus->pingRcvd();	
			sendPong();
			return;
		}

		else if(!type.compare(ERROR))
		{	
			//TODO need to figure out hwat to do here
			//for now lets just try and not spam the other levels
			return;
		}

		else if(!type.compare("IRCERROR"))
		{
			//handle connection errors in conn status
			_connStatus->connectionIoError();

		}

		//now check for messages that start with nicks or server titles
		else 
		{	
			_connStatus->pingRcvd();	
			//type is actually a prefix containing the host mask etc
			std::string prefix = type;
			// the actual message past the prefix
			msg = msg.substr(msg.find_first_of(' ')+1);
			//the first part of that message should be the type
			type = msg.substr(0, msg.find_first_of(' '));

			//check first to see if it is a private message
			//most irc messaages are private messages
			if(!type.compare(PRIVMSG))
			{
				handle_privmsg(msg, prefix);
			}
			else if(!type.compare(NOTICE))
			{	
				if(_connStatus->state() == CS_IDLE)
				{
				 	_connStatus->connected();
				}
				handle_notice(msg, prefix);
			}
			else if(!type.compare(QUIT))

			{
				ircEvent e = handle_quit(msg, prefix);
				notifyEvent(e);
			}
			else if(!type.compare(JOIN))
			{
				ircEvent e = handle_join(msg, prefix);
				notifyEvent(e);
			}
			else if(!type.compare(PART))
			{
				ircEvent e = handle_part(msg, prefix);
				notifyEvent(e);
			}

			else if(!type.compare(NICK))
			{
				ircEvent e = handle_nick(msg, prefix);
				notifyEvent(e);
			}

			else if(!type.compare(INSPIRCDVARS))
			{
				handle_vars(msg);
			}

			else if(!type.compare(NICKLIST))
			{
				//add function to parse the nicklist
				std::vector<ircEvent> e = handle_nicklist(msg);
				for(unsigned int i = 0; i < e.size(); ++i)
				{
					notifyEvent(e[i]);
				}
			}
			else if(!type.compare("001"))
			{
				_connStatus->registered();
			}
		}
//	}
}