Commit c52eaf30 authored by Pavel Vainerman's avatar Pavel Vainerman Committed by Pavel Vainerman

[unet-multicast]: config params refactoring

parent ff8b871a
......@@ -45,6 +45,7 @@ xmlNode* MulticastReceiveTransport::getReceiveListNode( UniXML::iterator root )
}
// -------------------------------------------------------------------------
/*
* <nodes unet_multicast_ip=".." unet_multicast_iface=".." >
* <item id="3000"
* unet_multicast_port="2048"
* unet_multicast_ip="224.0.0.1"
......@@ -52,10 +53,11 @@ xmlNode* MulticastReceiveTransport::getReceiveListNode( UniXML::iterator root )
* unet_multicast_port2="2049"
* unet_multicast_ip2="225.0.0.1"
* unet_multicast_iface2="192.169.1.1"
* >
* </item>
* />
* ...
* </nodes>
*/
std::unique_ptr<MulticastReceiveTransport> MulticastReceiveTransport::createFromXml( UniXML::iterator it, int numChan )
std::unique_ptr<MulticastReceiveTransport> MulticastReceiveTransport::createFromXml( UniXML::iterator root, UniXML::iterator it, int numChan )
{
ostringstream fieldIp;
fieldIp << "unet_multicast_ip";
......@@ -63,7 +65,7 @@ std::unique_ptr<MulticastReceiveTransport> MulticastReceiveTransport::createFrom
if( numChan > 0 )
fieldIp << numChan;
const string h = it.getProp(fieldIp.str());
const string h = it.getProp2(fieldIp.str(), root.getProp(fieldIp.str()));
if( h.empty() )
{
......@@ -72,6 +74,15 @@ std::unique_ptr<MulticastReceiveTransport> MulticastReceiveTransport::createFrom
throw uniset::SystemError(err.str());
}
Poco::Net::IPAddress a(h);
if( !a.isMulticast() && !a.isWildcard() )
{
ostringstream err;
err << "(MulticastReceiveTransport): " << h << " is not multicast address or 0.0.0.0";
throw SystemError(err.str());
}
ostringstream fieldPort;
fieldPort << "unet_multicast_port";
......@@ -86,16 +97,7 @@ std::unique_ptr<MulticastReceiveTransport> MulticastReceiveTransport::createFrom
if( numChan > 0 )
ifaceField << numChan;
const string iface = it.getProp(ifaceField.str());
Poco::Net::IPAddress a(h);
if( !a.isMulticast() && !a.isWildcard() )
{
ostringstream err;
err << "(MulticastReceiveTransport): " << h << " is not multicast address or 0.0.0.0";
throw SystemError(err.str());
}
const string iface = it.getProp2(ifaceField.str(), root.getProp(ifaceField.str()) );
std::vector<Poco::Net::IPAddress> groups{a};
return unisetstd::make_unique<MulticastReceiveTransport>(h, p, std::move(groups), iface);
......@@ -303,14 +305,19 @@ std::string MulticastReceiveTransport::iface() const
}
// -------------------------------------------------------------------------
/*
* <nodes unet_multicast_ip=".." unet_multicast_iface=".." >
* <item id="3000"
* unet_multicast_port="2048"
* unet_multicast_ip="224.0.0.1"
* unet_multicast_iface="192.168.1.1"
* unet_multicast_port2="2049"
* unet_multicast_ip2="225.0.0.1"
* unet_multicast_iface="eth2"
* unet_multicast_ttl="3"/>
* ...
* </nodes>
*/
std::unique_ptr<MulticastSendTransport> MulticastSendTransport::createFromXml( UniXML::iterator it, int numChan )
std::unique_ptr<MulticastSendTransport> MulticastSendTransport::createFromXml( UniXML::iterator root, UniXML::iterator it, int numChan )
{
ostringstream fieldIp;
fieldIp << "unet_multicast_ip";
......@@ -318,7 +325,7 @@ std::unique_ptr<MulticastSendTransport> MulticastSendTransport::createFromXml( U
if( numChan > 0 )
fieldIp << numChan;
const string h = it.getProp(fieldIp.str());
const string h = it.getProp2(fieldIp.str(), root.getProp(fieldIp.str()));
if( h.empty() )
{
......@@ -351,18 +358,27 @@ std::unique_ptr<MulticastSendTransport> MulticastSendTransport::createFromXml( U
throw SystemError(err.str());
}
ostringstream ipIface;
ipIface << "unet_multicast_iface";
ostringstream ipField;
ipField << "unet_multicast_sender_ip";
if( numChan > 0 )
{
ipField << numChan;
ipIface << numChan;
}
string ip = it.getProp2(ipField.str(), it.getProp(ipIface.str()));
string ip = it.getProp(ipField.str());
if( ip.empty() )
ip = root.getProp2(ipField.str(), root.getProp(ipIface.str()));
if( ip.empty() )
{
ostringstream err;
err << "(MulticastSendTransport): Undefined " << ipField.str() << " for " << it.getProp("name");
err << "(MulticastSendTransport): Undefined sender ip " << ipField.str() << " for " << it.getProp("name");
throw SystemError(err.str());
}
......@@ -390,7 +406,7 @@ std::unique_ptr<MulticastSendTransport> MulticastSendTransport::createFromXml( U
ip = al[0].get<0>().toString();
}
int ttl = it.getPIntProp("unet_multicast_ttl", 1);
int ttl = it.getPIntProp("unet_multicast_ttl", root.getPIntProp("unet_multicast_ttl", 1));
return unisetstd::make_unique<MulticastSendTransport>(ip, p, h, p, ttl);
}
// -------------------------------------------------------------------------
......
......@@ -31,7 +31,7 @@ namespace uniset
{
public:
static std::unique_ptr<MulticastReceiveTransport> createFromXml(UniXML::iterator it, int numChan);
static std::unique_ptr<MulticastReceiveTransport> createFromXml( UniXML::iterator root, UniXML::iterator it, int numChan);
static xmlNode* getReceiveListNode( UniXML::iterator root );
MulticastReceiveTransport( const std::string& bind, int port, const std::vector<Poco::Net::IPAddress>& joinGroups, const std::string& iface = "" );
......@@ -64,7 +64,7 @@ namespace uniset
{
public:
static std::unique_ptr<MulticastSendTransport> createFromXml( UniXML::iterator it, int numChan );
static std::unique_ptr<MulticastSendTransport> createFromXml( UniXML::iterator root, UniXML::iterator it, int numChan );
MulticastSendTransport(const std::string& sockHost, int sockPort, const std::string& groupHost, int groupPort, int ttl = 1 );
virtual ~MulticastSendTransport();
......
......@@ -1096,9 +1096,13 @@ void UNetExchange::initMulticastTransport( UniXML::iterator n_it,
{
auto conf = uniset_conf();
auto root = n_it;
if( !n_it.goChildren() )
throw uniset::SystemError("(UNetExchange): Items not found for <nodes>");
const string defaultIP2 = root.getProp("unet_multicast_ip2");
// init senders
for( ; n_it.getCurrent(); n_it.goNext() )
{
......@@ -1116,7 +1120,7 @@ void UNetExchange::initMulticastTransport( UniXML::iterator n_it,
if( n != conf->getLocalNodeName() )
{
initMulticastReceiverForNode(n_it, prefix);
initMulticastReceiverForNode(root, n_it, prefix);
continue;
}
......@@ -1129,7 +1133,7 @@ void UNetExchange::initMulticastTransport( UniXML::iterator n_it,
// INIT SENDER
unetinfo << myname << "(init): " << n_it.getProp("name") << " init sender.." << endl;
auto s1 = MulticastSendTransport::createFromXml(n_it, 0);
auto s1 = MulticastSendTransport::createFromXml(root, n_it, 0);
unetinfo << myname << "(init): " << n_it.getProp("name") << " send (channel1) to multicast group: " << s1->getGroupAddress().toString() << endl;
sender = make_shared<UNetSender>(std::move(s1), shm, false, s_field, s_fvalue, "unet", prefix);
......@@ -1139,9 +1143,9 @@ void UNetExchange::initMulticastTransport( UniXML::iterator n_it,
{
sender2 = nullptr;
if( !n_it.getProp("unet_multicast_ip2").empty() )
if( !n_it.getProp2("unet_multicast_ip2", defaultIP2).empty() )
{
auto s2 = MulticastSendTransport::createFromXml(n_it, 2);
auto s2 = MulticastSendTransport::createFromXml(root, n_it, 2);
if( s2 )
unetinfo << myname << "(init): " << n_it.getProp("name") << " send (channel2) to multicast group: " << s2->getGroupAddress().toString() << endl;
......@@ -1164,12 +1168,12 @@ void UNetExchange::initMulticastTransport( UniXML::iterator n_it,
}
}
// ----------------------------------------------------------------------------
void UNetExchange::initMulticastReceiverForNode( UniXML::iterator n_it, const std::string& prefix )
void UNetExchange::initMulticastReceiverForNode( UniXML::iterator root, UniXML::iterator n_it, const std::string& prefix )
{
auto conf = uniset_conf();
unetinfo << myname << "(init): " << n_it.getProp("name") << " init receivers:" << endl;
auto transport1 = MulticastReceiveTransport::createFromXml(n_it, 0);
auto transport1 = MulticastReceiveTransport::createFromXml(root, n_it, 0);
if( checkExistTransport(transport1->ID()) )
{
......@@ -1181,6 +1185,7 @@ void UNetExchange::initMulticastReceiverForNode( UniXML::iterator n_it, const st
string s_resp_id(n_it.getProp("unet_respond1_id"));
uniset::ObjectId resp_id = uniset::DefaultObjectId;
const string defaultIP2 = root.getProp("unet_multicast_ip2");
if( !s_resp_id.empty() )
{
......@@ -1330,8 +1335,8 @@ void UNetExchange::initMulticastReceiverForNode( UniXML::iterator n_it, const st
{
std::unique_ptr<MulticastReceiveTransport> transport2 = nullptr;
if (!n_it.getProp("unet_multicast_ip2").empty() )
transport2 = MulticastReceiveTransport::createFromXml(n_it, 2);
if (!n_it.getProp2("unet_multicast_ip2", defaultIP2).empty() )
transport2 = MulticastReceiveTransport::createFromXml(root, n_it, 2);
if( transport2 ) // создаём читателя по второму каналу
{
......
......@@ -114,9 +114,12 @@ namespace uniset
unet_multicast_iface="192.168.1.1" можно задать интерфейс через который ожидаются multicast-пакеты.
Поддерживается текстовое задание интерфейса в виде unet_multicast_iface="eth0"
Для указания ip для sender используется параметр unet_multicast_sender_ip="..", если он не задан,
будет использован unet_multicast_iface="..".
Для посылающего процесса можно определить параметр \b unet_multicast_ttl задающий время жизни multicast пакетов.
По умолчанию ttl=1. А так же определить ip для сокета параметром \b unet_multicast_sender_ip. По умолчанию "0.0.0.0".
Можно задавать текстовое название интерфейса unet_multicast_sender_ip="eth0", при этом
По умолчанию ttl=1. А так же определить ip для сокета параметром \b unet_multicast_iface.
Можно задавать текстовое название интерфейса unet_multicast_iface="eth0", при этом
в качестве ip будет взят \b первый ip-адрес из привязанных к указанному интерфейсу.
В данной реализации поддерживается работа в два канала. Соответствующие настройки для второго канала имеют индекс "2":
......@@ -125,8 +128,11 @@ namespace uniset
Чтобы отключить запуск "sender", можно указать \b nosender="1" в \b <item> конкретного узла
или непосредственно в настройках \b <UNetExchange nosender="1"...>
В корневой секции \b <nodes..> можно задавать значения по умолчанию используемые для всех улов
\b unet_multicast_ip, \b unet_multicast_iface, \b unet_multicast_sender_ip.
\code
<nodes port="2809" unet_broadcast_ip="192.168.56.255">
<nodes port="2809" unet_broadcast_ip="192.168.56.255" unet_multicast_ip="224.0.0.1 unet_multicast_iface="net1">
<item ip="127.0.0.1" name="LocalhostNode" textname="Локальный узел" unet_ignore="1">
<iocards>
...
......@@ -134,18 +140,18 @@ namespace uniset
</item>
<item id="3001" ip="192.168.56.10" name="Node1" textname="Node1" unet_update_strategy="evloop"
unet_multicast_ip="224.0.0.1"
unet_multicast_sender_ip="192.168.1.1"
unet_multicast_iface="192.168.1.1"
unet_multicast_port2="3031"
unet_multicast_ip2="225.0.0.1"
unet_multicast_sender_ip2="192.168.2.1">
unet_multicast_iface2="192.168.2.1">
...
</item>
<item id="3002" ip="192.168.56.11" name="Node2" textname="Node2">
unet_multicast_ip="224.0.0.2"
unet_multicast_sender_ip="192.168.1.2"
unet_multicast_iface="192.168.1.2"
unet_multicast_port2="3032"
unet_multicast_ip2="225.0.0.2"
unet_multicast_sender_ip2="eth0">
unet_multicast_iface2="eth0">
...
</item>
</nodes>
......@@ -257,7 +263,7 @@ namespace uniset
void termReceivers();
void initMulticastTransport( UniXML::iterator nodes, const std::string& n_field, const std::string& n_fvalue, const std::string& prefix );
void initMulticastReceiverForNode( UniXML::iterator n_it, const std::string& prefix );
void initMulticastReceiverForNode( UniXML::iterator root, UniXML::iterator n_it, const std::string& prefix );
void initUDPTransport(UniXML::iterator nodes, const std::string& n_field, const std::string& n_fvalue, const std::string& prefix);
void initIterators() noexcept;
......
......@@ -17,6 +17,8 @@ TEST_CASE("[UNetUDP]: multicast setup", "[unetudp][multicast][config]")
{
UniXML xml("unetudp-test-configure.xml");
UniXML::iterator it = xml.findNode(xml.getFirstNode(), "nodes");
UniXML::iterator root = it;
REQUIRE( it.getCurrent() );
REQUIRE( it.goChildren() );
REQUIRE( it.findName("item", "localhost", false) );
......@@ -24,52 +26,50 @@ TEST_CASE("[UNetUDP]: multicast setup", "[unetudp][multicast][config]")
REQUIRE( it.getName() == "item" );
REQUIRE( it.getProp("name") == "localhost" );
REQUIRE_NOTHROW( MulticastReceiveTransport::createFromXml(it, 0 ) );
REQUIRE_NOTHROW( MulticastReceiveTransport::createFromXml(it, 2 ) );
REQUIRE_NOTHROW( MulticastSendTransport::createFromXml(it, 0 ) );
REQUIRE_NOTHROW( MulticastSendTransport::createFromXml(it, 2 ) );
REQUIRE_NOTHROW( MulticastReceiveTransport::createFromXml(root, it, 0 ) );
REQUIRE_NOTHROW( MulticastReceiveTransport::createFromXml(root, it, 2 ) );
REQUIRE_NOTHROW( MulticastSendTransport::createFromXml(root, it, 0 ) );
REQUIRE_NOTHROW( MulticastSendTransport::createFromXml(root, it, 2 ) );
auto t1 = MulticastReceiveTransport::createFromXml(it, 2);
auto t1 = MulticastReceiveTransport::createFromXml(root, it, 2);
REQUIRE( t1->toString() == "225.0.0.1:3030" );
auto t2 = MulticastSendTransport::createFromXml(it, 2);
REQUIRE( t2->toString() == "0.0.0.0:3030" );
auto t2 = MulticastSendTransport::createFromXml(root, it, 2);
REQUIRE( t2->toString() == "127.0.0.1:3030" );
}
// -----------------------------------------------------------------------------
TEST_CASE("[UNetUDP]: multicast transport", "[unetudp][multicast][transport]")
TEST_CASE("[UNetUDP]: unet2", "[unetudp][multicast][unet2]")
{
UniXML xml("unetudp-test-configure.xml");
UniXML::iterator it = xml.findNode(xml.getFirstNode(), "nodes");
UniXML::iterator eit = xml.findNode(xml.getFirstNode(), "UNetExchange", "UNetExchange2");
REQUIRE( eit.getCurrent() );
REQUIRE( eit.goChildren() );
UniXML::iterator it = eit;
REQUIRE( it.find("unet2") );
REQUIRE( it.getCurrent() );
UniXML::iterator root = it;
REQUIRE( it.goChildren() );
REQUIRE( it.findName("item", "localhost", false) );
REQUIRE( it.getName() == "item" );
REQUIRE( it.getProp("name") == "localhost" );
auto t1 = MulticastReceiveTransport::createFromXml(it, 0 );
auto t1 = MulticastReceiveTransport::createFromXml(root, it, 0 );
REQUIRE( t1->toString() == "224.0.0.1:3000" );
REQUIRE( t1->createConnection(false, 5000, true) );
auto t2 = MulticastSendTransport::createFromXml(it, 0 );
REQUIRE( t2->toString() == "0.0.0.0:3000" );
auto t2 = MulticastSendTransport::createFromXml(root, it, 0 );
REQUIRE( t2->toString() == "127.0.0.1:3000" );
REQUIRE( t2->getGroupAddress() == Poco::Net::SocketAddress("224.0.0.1", 3000) );
REQUIRE( t2->createConnection(false, 5000) );
string msg = "hello world";
REQUIRE( t2->send(msg.data(), msg.size()) == msg.size() );
unsigned char buf[64];
REQUIRE( t1->receive(&buf, sizeof(buf)) == msg.size() );
REQUIRE( string((const char*)buf) == msg );
auto t3 = MulticastReceiveTransport::createFromXml(root, it, 2 );
REQUIRE( t3->toString() == "225.0.0.1:3000" );
REQUIRE( t3->createConnection(false, 5000, true) );
REQUIRE( t1->receive(&buf, sizeof(buf)) == -1 );
msg = "hello world, again";
REQUIRE( t2->send(msg.data(), msg.size()) == msg.size() );
memset(buf, 0, sizeof(buf));
REQUIRE( t1->receive(&buf, sizeof(buf)) == msg.size() );
REQUIRE( string((const char*)buf) == msg );
auto t4 = MulticastSendTransport::createFromXml(root, it, 2 );
REQUIRE( t4->toString() == "127.0.0.1:3000" );
REQUIRE( t4->getGroupAddress().toString() == Poco::Net::SocketAddress("225.0.0.1", 3000).toString() );
}
// -----------------------------------------------------------------------------
......@@ -58,8 +58,8 @@ static void initHelpers()
if( !udp_s )
{
udp_s = make_unique<MulticastSendTransport>("0.0.0.0", 3002, "224.0.0.2", 3002);
REQUIRE( udp_s->toString() == "0.0.0.0:3002" );
udp_s = make_unique<MulticastSendTransport>("127.0.0.1", 3002, "224.0.0.2", 3002);
REQUIRE( udp_s->toString() == "127.0.0.1:3002" );
REQUIRE( udp_s->createConnection(false, 5000) );
// pause for igmp message
msleep(3000);
......
......@@ -10,6 +10,6 @@ cd -
./uniset2-start.sh -f ./tests-multicast-with-sm $* -- --unet-transport multicast --confile unetudp-test-configure.xml --e-startup-pause 10 \
--unet-name UNetExchange --unet-filter-field unet --unet-filter-value 1 --unet-maxdifferense 5 \
--unet-recv-timeout 1000 --unet-sendpause 500 --unet-update-strategy evloop
--unet-recv-timeout 1000 --unet-sendpause 500 --unet-update-strategy evloop
#--unet-log-add-levels any
......@@ -29,29 +29,36 @@
<settings>
<SharedMemory name="SharedMemory" shmID="SharedMemory"/>
<UNetExchange name="UNetExchange"/>
<UNetExchange name="UNetExchange2">
<unet2 port="2809" unet_multicast_ip="224.0.0.1" unet_multicast_iface="127.0.0.1" unet_multicast_ip2="225.0.0.1" unet_multicast_iface2="127.0.0.1">
<item id="3000" ip="127.0.0.1" name="localhost" textname="Локальный узел" unet_ignore="0"/>
<item id="3002" ip="192.168.56.10" name="Node1" textname="Node1" unet_ignore="0"/>
<item id="3003" ip="192.168.56.11" name="Node2" textname="Node2" unet_ignore="0"/>
</unet2>
</UNetExchange>
</settings>
<ObjectsMap idfromfile="1">
<nodes port="2809" unet_broadcast_ip="127.255.255.255" unet_broadcast_ip2="badip">
<item id="3000" ip="127.0.0.1" name="localhost" textname="Локальный узел" unet_ignore="0" unet_port="3000"
unet_multicast_ip="224.0.0.1"
unet_multicast_sender_ip="0.0.0.0"
unet_multicast_iface="127.0.0.1"
unet_multicast_ip2="225.0.0.1"
unet_multicast_port2="3030"
unet_multicast_sender_ip2="0.0.0.0"/>
unet_multicast_iface2="127.0.0.1"/>
<item id="3001" ip="127.0.0.1" name="localhost1" textname="Локальный узел" unet_ignore="1" unet_port="3001"/>
<item id="3002" ip="192.168.56.10" name="Node1" textname="Node1" unet_ignore="0" unet_respond_id="Node1_Not_Respond_S" unet_respond_invert="1" unet_channelswitchcount_id="Node1_ChannelSwitchCount_AS"
unet_multicast_ip="224.0.0.2"
unet_multicast_sender_ip="0.0.0.0"
unet_multicast_iface="127.0.0.1"
unet_multicast_ip2="225.0.0.2"
unet_multicast_port2="3032"
unet_multicast_sender_ip2="0.0.0.0"/>
unet_multicast_iface2="127.0.0.1"/>
<item id="3003" ip="192.168.56.11" name="Node2" textname="Node2" unet_ignore="0" unet_respond_id="Node2_Respond_S" unet_lostpackets_id="Node2_LostPackets_AS" unet_numchannel_id="Node2_NumChannel_AS"
unet_multicast_ip="224.0.0.3"
unet_multicast_sender_ip="0.0.0.0"
unet_multicast_iface="127.0.0.1"
unet_multicast_ip2="225.0.0.3"
unet_multicast_port2="3033"
unet_multicast_sender_ip2="0.0.0.0"/>
unet_multicast_iface2="127.0.0.1"/>
</nodes>
<!-- ************************ Датчики ********************** -->
<sensors name="Sensors">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment