예제 #1
0
		void IPNDAgent::join(const ibrcommon::vinterface &iface, const ibrcommon::vaddress &addr) throw ()
		{
			IBRCOMMON_LOGGER_DEBUG_TAG(TAG, 10) << "Join on " << iface.toString() << " (" << addr.toString() << ", family: " << addr.family() << ")" << IBRCOMMON_LOGGER_ENDL;

			// only join IPv6 and IPv4 addresses
			if ((addr.family() != AF_INET) && (addr.family() != AF_INET6)) return;

			// do not join on loopback interfaces
			if (addr.isLocal()) return;

			// create a multicast socket and bind to given addr
			ibrcommon::multicastsocket *msock = new ibrcommon::multicastsocket(addr);

			// if we are in UP state
			if (_state) {
				try {
					// bring up
					msock->up();

					// listen to multicast addresses
					for (std::set<ibrcommon::vaddress>::const_iterator it_addr = _destinations.begin(); it_addr != _destinations.end(); ++it_addr)
					{
                        if (msock->get_family() != it_addr->family())
                            continue;
                        
						try {
							msock->join(*it_addr, iface);
						} catch (const ibrcommon::socket_raw_error &e) {
							if (e.error() == EADDRINUSE) {
								// silent error
							} else if (e.error() == 92) {
								// silent error - protocol not available
							} else {
								IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, warning) << "Join to " << (*it_addr).toString() << " failed on " << iface.toString() << "; " << e.what() << IBRCOMMON_LOGGER_ENDL;
							}
						} catch (const ibrcommon::socket_exception &e) {
							IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 10) << "Join to " << (*it_addr).toString() << " failed on " << iface.toString() << "; " << e.what() << IBRCOMMON_LOGGER_ENDL;
						}
					}
				} catch (const ibrcommon::socket_exception &ex) {
					IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, error) << "Join failed on " << iface.toString() << " (" << addr.toString() << ", family: " << addr.family() << ")" << "; " << ex.what() << IBRCOMMON_LOGGER_ENDL;
					delete msock;
					return;
				}
			}

			// add multicast socket to _socket
			_socket.add(msock, iface);
		}
예제 #2
0
		void IPNDAgent::leave(const ibrcommon::vinterface &iface, const ibrcommon::vaddress &addr) throw ()
		{
			IBRCOMMON_LOGGER_DEBUG_TAG(TAG, 10) << "Leave " << iface.toString() << " (" << addr.toString() << ", family: " << addr.family() << ")" << IBRCOMMON_LOGGER_ENDL;

			// get all sockets bound to the given interface
			ibrcommon::socketset ifsocks = _socket.get(iface);

			for (ibrcommon::socketset::iterator it = ifsocks.begin(); it != ifsocks.end(); ++it)
			{
				ibrcommon::multicastsocket *msock = dynamic_cast<ibrcommon::multicastsocket*>(*it);
				if (msock == NULL) continue;

				if (msock->get_address() == addr) {
					// remove the socket
					_socket.remove(msock);

					// shutdown the socket
					try {
						msock->down();
					} catch (const ibrcommon::socket_exception &ex) {
						IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 10) << "leave failed: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
					}

					// delete the socket
					delete msock;

					return;
				}
			}
		}
예제 #3
0
		void IPNDAgent::join_interface(const ibrcommon::vinterface &iface) throw ()
		{
			ibrcommon::multicastsocket &msock = dynamic_cast<ibrcommon::multicastsocket&>(**_recv_socket.getAll().begin());

			for (std::set<ibrcommon::vaddress>::const_iterator it_addr = _destinations.begin(); it_addr != _destinations.end(); ++it_addr)
			{
				try {
					msock.join(*it_addr, iface);
				} catch (const ibrcommon::socket_raw_error &e) {
					if (e.error() != EADDRINUSE) {
						IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, error) << "join failed on " << iface.toString() << "; " << e.what() << IBRCOMMON_LOGGER_ENDL;
					}
				} catch (const ibrcommon::socket_exception &e) {
					IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 10) << "can not join " << (*it_addr).toString() << " on " << iface.toString() << "; " << e.what() << IBRCOMMON_LOGGER_ENDL;
				}
			}
		}
예제 #4
0
		void IPNDAgent::join(const ibrcommon::vinterface &iface, const ibrcommon::vaddress &addr) throw ()
		{
			// only join IPv6 and IPv4 addresses
			if ((addr.family() != AF_INET) && (addr.family() != AF_INET6)) return;

			// do not join on loopback interfaces
			if (addr.isLocal()) return;

			// create a multicast socket and bind to given addr
			ibrcommon::multicastsocket *msock = new ibrcommon::multicastsocket(addr);

			try {
				// bring up
				msock->up();

				// add multicast socket to _socket
				_socket.add(msock, iface);
			} catch (const ibrcommon::socket_exception &ex) {
				IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, error) << "Can not send on " << iface.toString() << " (" << addr.toString() << ", family: " << addr.family() << ")" << "; " << ex.what() << IBRCOMMON_LOGGER_ENDL;
				delete msock;
			}
		}
예제 #5
0
		void IPNDAgent::onAdvertiseBeacon(const ibrcommon::vinterface &iface, const DiscoveryBeacon &beacon) throw ()
		{
			// serialize announcement
			stringstream ss; ss << beacon;
			const std::string data = ss.str();

			// get all sockets for the given interface
			ibrcommon::socketset fds = _socket.get(iface);

			// send out discovery announcements on all bound sockets
			// (hopefully only one per interface)
			for (ibrcommon::socketset::const_iterator iter = fds.begin(); iter != fds.end(); ++iter)
			{
				try {
					ibrcommon::udpsocket &sock = dynamic_cast<ibrcommon::udpsocket&>(**iter);

					// send beacon to all addresses
					for (std::set<ibrcommon::vaddress>::const_iterator addr_it = _destinations.begin(); addr_it != _destinations.end(); ++addr_it)
					{
						const ibrcommon::vaddress &addr = (*addr_it);

						try {
							// prevent broadcasting in the wrong address family
							if (addr.family() != sock.get_family()) continue;

							sock.sendto(data.c_str(), data.length(), 0, addr);
						} catch (const ibrcommon::socket_exception &e) {
							IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 5) << "can not send message to " << addr.toString() << " via " << sock.get_address().toString() << "/" << iface.toString() << "; socket exception: " << e.what() << IBRCOMMON_LOGGER_ENDL;
						} catch (const ibrcommon::vaddress::address_exception &ex) {
							IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, warning) << ex.what() << IBRCOMMON_LOGGER_ENDL;
						}
					}
				} catch (const std::bad_cast&) {
					IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, error) << "Socket for sending isn't a udpsocket." << IBRCOMMON_LOGGER_ENDL;
				}
			}
		}
예제 #6
0
		void IPNDAgent::send(const DiscoveryAnnouncement &a, const ibrcommon::vinterface &iface, const ibrcommon::vaddress &addr)
		{
			// serialize announcement
			stringstream ss; ss << a;
			const std::string data = ss.str();

			ibrcommon::socketset fds = _send_socket.get(iface);

			// send out discovery announcements on all bound sockets
			// (hopefully only one per interface)
			for (ibrcommon::socketset::const_iterator iter = fds.begin(); iter != fds.end(); ++iter)
			{
				ibrcommon::udpsocket &sock = dynamic_cast<ibrcommon::udpsocket&>(**iter);

				try {
					// prevent broadcasting in the wrong address family
					if (addr.family() != sock.get_family()) continue;

					sock.sendto(data.c_str(), data.length(), 0, addr);
				} catch (const ibrcommon::socket_exception &e) {
					IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 5) << "can not send message to " << addr.toString() << " via " << sock.get_address().toString() << "/" << iface.toString() << "; socket exception: " << e.what() << IBRCOMMON_LOGGER_ENDL;
				} catch (const ibrcommon::vaddress::address_exception &ex) {
					IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, warning) << ex.what() << IBRCOMMON_LOGGER_ENDL;
				}
			}
		}
예제 #7
0
		void IPNDAgent::join(const ibrcommon::vinterface &iface) throw ()
		{
			// register as discovery handler for this interface
			dtn::core::BundleCore::getInstance().getDiscoveryAgent().registerService(iface, this);

			// do not create sockets for any interface
			if (!iface.isAny()) {
				// subscribe to NetLink events on our interfaces
				ibrcommon::LinkManager::getInstance().addEventListener(iface, this);

				/**
				 * create sockets for each address on the interface
				 */
				const std::list<ibrcommon::vaddress> addrs = iface.getAddresses();

				for (std::list<ibrcommon::vaddress>::const_iterator it = addrs.begin(); it != addrs.end(); ++it)
				{
					const ibrcommon::vaddress addr = (*it);

					// join to all multicast addresses on this interface
					join(iface, addr);
				}
			}

			/**
			 * subscribe to multicast address on this interface using the sockets bound to any address
			 */
			const ibrcommon::vinterface any_iface(ibrcommon::vinterface::ANY);
			ibrcommon::socketset anysocks = _socket.get(any_iface);

			for (ibrcommon::socketset::iterator it = anysocks.begin(); it != anysocks.end(); ++it)
			{
				ibrcommon::multicastsocket *msock = dynamic_cast<ibrcommon::multicastsocket*>(*it);
				if (msock == NULL) continue;

				for (std::set<ibrcommon::vaddress>::const_iterator addr_it = _destinations.begin(); addr_it != _destinations.end(); ++addr_it)
				{
					const ibrcommon::vaddress &addr = (*addr_it);

					// join only if family matches
					if (addr.family() != msock->get_family()) continue;

					try {
						msock->join(addr, iface);

						IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 10) << "Joined " << addr.toString() << " on " << iface.toString() << IBRCOMMON_LOGGER_ENDL;
					} catch (const ibrcommon::socket_raw_error &e) {
						if (e.error() == EADDRINUSE) {
							// silent error
						} else if (e.error() == 92) {
							// silent error - protocol not available
						} else {
							IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, warning) << "Join to " << addr.toString() << " failed on " << iface.toString() << "; " << e.what() << IBRCOMMON_LOGGER_ENDL;
						}
					} catch (const ibrcommon::socket_exception &e) {
						IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 10) << "Join to " << addr.toString() << " failed on " << iface.toString() << "; " << e.what() << IBRCOMMON_LOGGER_ENDL;
					}
				}
			}
		}
예제 #8
0
		void IPNDAgent::leave(const ibrcommon::vinterface &iface) throw ()
		{
			// subscribe to NetLink events on our interfaces
			ibrcommon::LinkManager::getInstance().removeEventListener(iface, this);

			// un-register as discovery handler for this interface
			dtn::core::BundleCore::getInstance().getDiscoveryAgent().unregisterService(iface, this);

			// get all sockets bound to any interface
			ibrcommon::socketset anysocks = _socket.get(ibrcommon::vinterface(ibrcommon::vinterface::ANY));

			for (ibrcommon::socketset::iterator it = anysocks.begin(); it != anysocks.end(); ++it)
			{
				ibrcommon::multicastsocket *msock = dynamic_cast<ibrcommon::multicastsocket*>(*it);
				if (msock == NULL) continue;

				for (std::set<ibrcommon::vaddress>::const_iterator addr_it = _destinations.begin(); addr_it != _destinations.end(); ++addr_it)
				{
					const ibrcommon::vaddress &addr = (*addr_it);

					// leave only if family matches
					if (addr.family() != msock->get_family()) continue;

					try {
						msock->leave(addr, iface);
					} catch (const ibrcommon::socket_exception &e) {
						IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 10) << "Leave of " << addr.toString() << " failed on " << iface.toString() << "; " << e.what() << IBRCOMMON_LOGGER_ENDL;
					}
				}
			}

			// get all sockets bound to the given interface
			ibrcommon::socketset ifsocks = _socket.get(iface);

			for (ibrcommon::socketset::iterator it = ifsocks.begin(); it != ifsocks.end(); ++it)
			{
				ibrcommon::multicastsocket *msock = dynamic_cast<ibrcommon::multicastsocket*>(*it);
				if (msock == NULL) continue;

				// remove the socket
				_socket.remove(msock);

				// shutdown the socket
				try {
					msock->down();
				} catch (const ibrcommon::socket_exception &ex) {
					IBRCOMMON_LOGGER_DEBUG_TAG(IPNDAgent::TAG, 10) << "Socket down failed: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
				}

				// delete the socket
				delete msock;
			}
		}