In addition to IP broadcast and IP multicast for DTM node discovery, add support
for IP unicast to a list of peer IP addresses. The list of IP addresses is read
when DTM starts, either from a file or using a DNS query.
---
00-README.conf | 24 +-
src/dtm/dtmnd/Multicast.cc | 594 ++++++++++++++++++++++++++++++--------
src/dtm/dtmnd/Multicast.h | 58 +++-
src/dtm/dtmnd/dtm_node.cc | 5 +
src/dtm/dtmnd/dtm_node_sockets.cc | 44 +--
src/dtm/dtmnd/dtmd.conf | 35 ++-
6 files changed, 608 insertions(+), 152 deletions(-)
diff --git a/00-README.conf b/00-README.conf
index b67da8ee7..8a2d6a146 100644
--- a/00-README.conf
+++ b/00-README.conf
@@ -76,12 +76,28 @@ address is presented.
*******************************************************************************
dtmd.conf
-
-This file contains MDS/TCP configuration parameters.
-This file has to be edited only when you chose TCP as the mode of transport.
-
+
+This file contains MDS/TCP configuration parameters. This file has to be edited
+only when you chose TCP as the mode of transport.
+
The variable DTM_NODE_IP should be set to IP address of that local node
+To use IP multicast or unicast instead of broadcast, the variable
DTM_MCAST_ADDR
+should be set to an IPv4/IPv6 multicast group address, or source of peer IP
+addresses for unicast
+
+* To use multicast, specify an IPv4 or IPv6 multicast group address
+* To use unicast, the string should start with "file:" followed by the path
name
+ of a file containing a list of IP addresses (one per line), or start with
+ "dns:" followed by a DNS domain name, respectively.
+
+Examples:
+
+DTM_MCAST_ADDR=224.0.0.1
+DTM_MCAST_ADDR=ff02::1
+DTM_MCAST_ADDR=file:/var/lib/peer_ip_addresses.txt
+DTM_MCAST_ADDR=dns:peers.opensaf.org
+
*******************************************************************************
nid.conf
diff --git a/src/dtm/dtmnd/Multicast.cc b/src/dtm/dtmnd/Multicast.cc
index 922124a9c..1c674b239 100644
--- a/src/dtm/dtmnd/Multicast.cc
+++ b/src/dtm/dtmnd/Multicast.cc
@@ -26,7 +26,9 @@
#include <cerrno>
#include <cstdio>
#include <cstring>
+#include <fstream>
#include "base/logtrace.h"
+#include "base/osaf_utility.h"
Multicast::Multicast(uint16_t cluster_id, uint32_t node_id,
in_port_t stream_port, in_port_t dgram_port,
@@ -45,45 +47,222 @@ Multicast::Multicast(uint16_t cluster_id, uint32_t node_id,
multicast_address_{multicast_address},
ifname_{ifname},
scope_link_{scope_link},
- dest_addr_size_{},
+ protocol_{GetProtocol(multicast_address)},
dgram_sock_sndr{-1},
- dgram_sock_rcvr{-1},
- dest_addr_{} {
- if (!multicast_address.empty()) {
- /*
- 0
- restricted to the same host
- 1
- restricted to the same subnet
- 32
- restricted to the same site
- 64
- restricted to the same region
- 128
- restricted to the same continent
- 255
- unrestricted
- */
- uint32_t rc = dtm_dgram_mcast_sender(64); /*TODO */
- if (rc == NCSCC_RC_SUCCESS) {
- rc = dtm_dgram_mcast_listener();
- if (rc != NCSCC_RC_SUCCESS) {
- LOG_ER("DTM:Set up the initial mcast receiver socket failed");
+ dgram_sock_rcvr{-1} {
+ switch (protocol_) {
+ case kBroadcast: {
+ uint32_t rc = dtm_dgram_bcast_sender();
+ if (rc == NCSCC_RC_SUCCESS) {
+ rc = dtm_dgram_bcast_listener();
+ if (rc != NCSCC_RC_SUCCESS) {
+ LOG_ER("DTM:Set up the initial bcast receiver socket failed");
+ }
+ } else {
+ LOG_ER("DTM:Set up the initial bcast sender socket failed rc: %d",
rc);
+ }
+ break;
+ }
+ case kMulticast: {
+ uint32_t rc = dtm_dgram_mcast_sender(64); /*TODO */
+ if (rc == NCSCC_RC_SUCCESS) {
+ rc = dtm_dgram_mcast_listener();
+ if (rc != NCSCC_RC_SUCCESS) {
+ LOG_ER("DTM:Set up the initial mcast receiver socket failed");
+ }
+ } else {
+ LOG_ER("DTM:Set up the initial mcast sender socket failed rc: %d", rc);
+ }
+ break;
+ }
+ case kFileUnicast: {
+ GetPeersFromFile(multicast_address.substr(5));
+ bool result = InitializeUnicastSender();
+ if (result) {
+ result = InitializeUnicastReceiver();
+ if (!result) {
+ LOG_ER("DTM:Set up the initial ucast receiver socket failed");
+ }
+ } else {
+ LOG_ER("DTM:Set up the initial ucast sender socket failed");
+ }
+ break;
+ }
+ case kDnsUnicast: {
+ GetPeersFromDns(multicast_address.substr(4));
+ bool result = InitializeUnicastSender();
+ if (result) {
+ result = InitializeUnicastReceiver();
+ if (!result) {
+ LOG_ER("DTM:Set up the initial ucast receiver socket failed");
+ }
+ } else {
+ LOG_ER("DTM:Set up the initial ucast sender socket failed");
+ }
+ break;
+ }
+ }
+
+ struct in_addr addr_ipv4;
+ struct in6_addr addr_ipv6;
+ int rc = -1;
+ if (address_family_ == AF_INET) {
+ rc = inet_pton(AF_INET, stream_address_.c_str(), &addr_ipv4);
+ } else if (address_family_ == AF_INET6) {
+ rc = inet_pton(AF_INET6, stream_address_.c_str(), &addr_ipv6);
+ }
+ unsigned ifindex = if_nametoindex(ifname_.c_str());
+ if (rc == 1) {
+ auto start = peers_.begin();
+ auto end = peers_.end();
+ while (start != end) {
+ bool found = false;
+ if (address_family_ == AF_INET &&
+ start->address()->sa_family == AF_INET) {
+ const struct sockaddr_in *peer =
+ reinterpret_cast<const struct sockaddr_in *>(start->address());
+ if (addr_ipv4.s_addr == peer->sin_addr.s_addr) found = true;
+ } else if (address_family_ == AF_INET6 &&
+ start->address()->sa_family == AF_INET6) {
+ const struct sockaddr_in6 *peer =
+ reinterpret_cast<const struct sockaddr_in6 *>(start->address());
+ if (IN6_ARE_ADDR_EQUAL(&addr_ipv6, &peer->sin6_addr) &&
+ (!scope_link_ || ifindex == peer->sin6_scope_id))
+ found = true;
+ }
+ auto iter = start;
+ ++start;
+ if (found) peers_.erase(iter);
+ }
+ }
+ if (protocol_ == kFileUnicast || protocol_ == kDnsUnicast) {
+ LOG_NO("Number of unicast peers: %zu", static_cast<size_t>(peers_.size()));
+ }
+}
+
+Multicast::Protocol Multicast::GetProtocol(
+ const std::string &multicast_address) {
+ TRACE_ENTER();
+ Multicast::Protocol p;
+ if (multicast_address.empty()) {
+ p = kBroadcast;
+ } else if (multicast_address.compare(0, 5, "file:") == 0) {
+ p = kFileUnicast;
+ } else if (multicast_address.compare(0, 4, "dns:") == 0) {
+ p = kDnsUnicast;
+ } else {
+ p = kMulticast;
+ }
+ TRACE_LEAVE2("Protocol = %d", static_cast<int>(p));
+ return p;
+}
+
+bool Multicast::GetPeersFromFile(const std::string &path_name) {
+ std::ifstream str;
+ try {
+ str.open(path_name);
+ while (str.good()) {
+ std::string address;
+ std::getline(str, address);
+ if (!address.empty()) {
+ struct sockaddr_storage addr;
+ socklen_t len =
+ ParseAddress(address_family_, address, dgram_port_, &addr);
+ if (len != 0) {
+ if (peers_.emplace(reinterpret_cast<sockaddr *>(&addr), len).second)
{
+ LOG_IN("Added IP '%s' from '%s'", address.c_str(),
+ path_name.c_str());
+ } else {
+ LOG_WA("Duplicate IP '%s' in '%s'", address.c_str(),
+ path_name.c_str());
+ }
+ }
}
- } else {
- LOG_ER("DTM:Set up the initial mcast sender socket failed rc: %d", rc);
}
+ } catch (std::ifstream::failure) {
+ LOG_ER("Caught std::ifstream::failure when reading file '%s', peers=%zu",
+ path_name.c_str(), static_cast<size_t>(peers_.size()));
+ peers_.clear();
+ }
+ if (peers_.empty()) {
+ LOG_ER("Failed to read peers from file '%s': fail=%d, peers=%zu",
+ path_name.c_str(), str.fail() ? 1 : 0,
+ static_cast<size_t>(peers_.size()));
+ }
+ return !peers_.empty();
+}
+
+socklen_t Multicast::ParseAddress(sa_family_t address_family,
+ const std::string &address, in_port_t port,
+ struct sockaddr_storage *addr) {
+ char local_port_str[8];
+ snprintf(local_port_str, sizeof(local_port_str), "%" PRIu16, port);
+
+ struct addrinfo addr_criteria {};
+ addr_criteria.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+ addr_criteria.ai_family = address_family;
+ addr_criteria.ai_socktype = SOCK_DGRAM;
+ addr_criteria.ai_protocol = IPPROTO_UDP;
+
+ struct addrinfo *res;
+ int rv = getaddrinfo(address.c_str(), local_port_str, &addr_criteria, &res);
+ socklen_t addrlen;
+ if (rv == 0) {
+ addrlen = res->ai_addrlen;
+ memcpy(addr, res->ai_addr, addrlen);
+ freeaddrinfo(res);
} else {
- uint32_t rc = dtm_dgram_bcast_sender();
- if (rc == NCSCC_RC_SUCCESS) {
- rc = dtm_dgram_bcast_listener();
- if (rc != NCSCC_RC_SUCCESS) {
- LOG_ER("DTM:Set up the initial bcast receiver socket failed");
+ LOG_ER("getaddrinfo('%s', %s) failed: %s", address.c_str(), local_port_str,
+ gai_strerror(rv));
+ addrlen = 0;
+ }
+ return addrlen;
+}
+
+bool Multicast::GetPeersFromDns(const std::string &domain_name) {
+ char local_port_str[8];
+ snprintf(local_port_str, sizeof(local_port_str), "%" PRIu16, dgram_port_);
+
+ struct addrinfo addr_criteria {};
+ addr_criteria.ai_flags = AI_IDN | AI_NUMERICSERV;
+ addr_criteria.ai_family = address_family_;
+ addr_criteria.ai_socktype = SOCK_DGRAM;
+ addr_criteria.ai_protocol = IPPROTO_UDP;
+
+ struct addrinfo *res;
+ int rv =
+ getaddrinfo(domain_name.c_str(), local_port_str, &addr_criteria, &res);
+ if (rv == 0) {
+ for (struct addrinfo *p = res; p != nullptr; p = p->ai_next) {
+ char buf[INET6_ADDRSTRLEN];
+ const char *result = nullptr;
+ if (p->ai_family == AF_INET) {
+ struct sockaddr_in *addr =
+ reinterpret_cast<struct sockaddr_in *>(p->ai_addr);
+ result = inet_ntop(p->ai_family, &addr->sin_addr, buf, sizeof(buf));
+ } else if (p->ai_family == AF_INET6) {
+ struct sockaddr_in6 *addr =
+ reinterpret_cast<struct sockaddr_in6 *>(p->ai_addr);
+ result = inet_ntop(p->ai_family, &addr->sin6_addr, buf, sizeof(buf));
}
- } else {
- LOG_ER("DTM:Set up the initial bcast sender socket failed rc: %d", rc);
+ if (peers_.emplace(p->ai_addr, p->ai_addrlen).second) {
+ if (result != nullptr)
+ LOG_IN("Added IP '%s' from '%s'", result, domain_name.c_str());
+ } else {
+ if (result != nullptr)
+ LOG_WA("Duplicate IP '%s' from '%s'", result, domain_name.c_str());
+ }
+ }
+ freeaddrinfo(res);
+ if (peers_.empty()) {
+ LOG_ER("Failed to get any peers from domain name '%s'",
+ domain_name.c_str());
}
+ } else {
+ LOG_ER("getaddrinfo('%s', %s) failed: %s", domain_name.c_str(),
+ local_port_str, gai_strerror(rv));
}
+ return !peers_.empty();
}
Multicast::~Multicast() {
@@ -91,6 +270,162 @@ Multicast::~Multicast() {
if (dgram_sock_rcvr >= 0) close(dgram_sock_rcvr);
}
+bool Multicast::InitializeUnicastSender() {
+ TRACE_ENTER();
+
+ dgram_sock_sndr = socket(
+ address_family_, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_UDP);
+ if (dgram_sock_sndr < 0) {
+ LOG_ER("socket() failed: %s", strerror(errno));
+ TRACE_LEAVE();
+ return false;
+ }
+
+ if (address_family_ == AF_INET6) {
+ int v6only = 1;
+ if (setsockopt(dgram_sock_sndr, IPPROTO_IPV6, IPV6_V6ONLY, &v6only,
+ sizeof(v6only)) < 0)
+ LOG_ER("setsockopt(IPV6_V6ONLY) failed: %s", strerror(errno));
+ }
+ TRACE_LEAVE();
+ return true;
+}
+
+bool Multicast::InitializeUnicastReceiver() {
+ struct addrinfo *addr_list = nullptr, *p; // Criteria for address
+ int rv;
+ char ucast_addr_eth[INET6_ADDRSTRLEN + IFNAMSIZ];
+ TRACE_ENTER();
+
+ TRACE("DTM :dgram_port_rcvr : %" PRIu16, dgram_port_);
+ char local_port_str[8];
+ snprintf(local_port_str, sizeof(local_port_str), "%" PRIu16, dgram_port_);
+
+ dgram_sock_rcvr = -1;
+ struct addrinfo addr_criteria {};
+ addr_criteria.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV;
+ addr_criteria.ai_family = AF_UNSPEC;
+ addr_criteria.ai_socktype = SOCK_DGRAM;
+ addr_criteria.ai_protocol = IPPROTO_UDP;
+
+ TRACE("DTM :ip_addr : %s local_port_str :%s", stream_address_.c_str(),
+ local_port_str);
+ if (address_family_ == AF_INET) {
+ if ((rv = getaddrinfo(stream_address_.c_str(), local_port_str,
+ &addr_criteria, &addr_list)) != 0) {
+ LOG_ER("DTM:Unable to getaddrinfo() for '%s': %s",
+ stream_address_.c_str(), gai_strerror(rv));
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ return NCSCC_RC_FAILURE;
+ }
+ } else if (address_family_ == AF_INET6) {
+ if (scope_link_) {
+ memset(ucast_addr_eth, 0, (INET6_ADDRSTRLEN + IFNAMSIZ));
+ sprintf(ucast_addr_eth, "%s%%%s", stream_address_.c_str(),
+ ifname_.c_str());
+ if ((rv = getaddrinfo(ucast_addr_eth, local_port_str, &addr_criteria,
+ &addr_list)) != 0) {
+ LOG_ER("DTM:Unable to getaddrinfo() for '%s': %s", ucast_addr_eth,
+ gai_strerror(rv));
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ return NCSCC_RC_FAILURE;
+ }
+ } else {
+ if ((rv = getaddrinfo(stream_address_.c_str(), local_port_str,
+ &addr_criteria, &addr_list)) != 0) {
+ LOG_ER("DTM:Unable to getaddrinfo() for '%s': %s",
+ stream_address_.c_str(), gai_strerror(rv));
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ return NCSCC_RC_FAILURE;
+ }
+ }
+ }
+
+ if (addr_list == nullptr) {
+ LOG_ER("DTM:Unable to get addr_list ");
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ return NCSCC_RC_FAILURE;
+ }
+
+ /* results and bind to the first we can */
+ p = addr_list;
+ bool bound = false;
+ for (; p; p = p->ai_next) {
+ TRACE("DTM :family : %d, socktype : %d, protocol :%d", p->ai_family,
+ p->ai_socktype, p->ai_protocol);
+ if (address_family_ != p->ai_family) {
+ continue;
+ }
+
+ if (p->ai_family == AF_INET) {
+ void *addr;
+ char ipstr[INET6_ADDRSTRLEN];
+ struct sockaddr_in *ipv4 =
+ reinterpret_cast<struct sockaddr_in *>(p->ai_addr);
+ addr = &(ipv4->sin_addr);
+ inet_ntop(p->ai_family, addr, ipstr, sizeof(ipstr));
+ if (strcasecmp(ipstr, stream_address_.c_str()) != 0) {
+ continue;
+ } else
+ TRACE("DTM: DGRAM Socket bound to = %s\n", ipstr);
+ } else if (p->ai_family == AF_INET6) {
+ void *addr;
+ char ipstr[INET6_ADDRSTRLEN];
+ struct sockaddr_in6 *ipv6 =
+ reinterpret_cast<struct sockaddr_in6 *>(p->ai_addr);
+ addr = &(ipv6->sin6_addr);
+ inet_ntop(p->ai_family, addr, ipstr, sizeof(ipstr));
+ if (strcasecmp(ipstr, stream_address_.c_str()) != 0) {
+ continue;
+ } else
+ TRACE("DTM: DGRAM Socket bound to = %s\n", ipstr);
+ }
+ if ((dgram_sock_rcvr =
+ socket(p->ai_family, p->ai_socktype | SOCK_NONBLOCK |
SOCK_CLOEXEC,
+ p->ai_protocol)) == -1) {
+ LOG_ER("DTM:Socket creation failed (socket()) err :%s", strerror(errno));
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ continue;
+ }
+
+ int smode = 1;
+ if ((setsockopt(dgram_sock_rcvr, SOL_SOCKET, SO_REUSEADDR, &smode,
+ sizeof(smode)) == -1)) {
+ LOG_ER("DTM : Error setsockpot: err :%s", strerror(errno));
+ freeaddrinfo(addr_list);
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ return NCSCC_RC_FAILURE;
+ }
+ if (p->ai_family == AF_INET6) {
+ int v6only = 1;
+ if (setsockopt(dgram_sock_rcvr, IPPROTO_IPV6, IPV6_V6ONLY, &v6only,
+ sizeof(v6only)) < 0)
+ LOG_ER("setsockopt(IPV6_V6ONLY) failed: %s", strerror(errno));
+ }
+ if (bind(dgram_sock_rcvr, p->ai_addr, p->ai_addrlen) == -1) {
+ LOG_ER("DTM:Socket bind failed err :%s", strerror(errno));
+ close(dgram_sock_rcvr);
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ perror("listener: bind");
+ freeaddrinfo(addr_list);
+ return NCSCC_RC_FAILURE;
+ } else {
+ bound = true;
+ break;
+ }
+ }
+
+ /* Free address structure(s) allocated by getaddrinfo() */
+ freeaddrinfo(addr_list);
+ if (bound != true) {
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ return NCSCC_RC_FAILURE;
+ } else {
+ TRACE_LEAVE2("rc :%d", NCSCC_RC_SUCCESS);
+ return NCSCC_RC_SUCCESS;
+ }
+}
+
/**
* Function for sending the bcast
*
@@ -104,13 +439,14 @@ uint32_t Multicast::dtm_dgram_bcast_sender() {
TRACE_ENTER();
dgram_sock_sndr = -1;
- dest_addr_size_ = 0;
- memset(&dest_addr_, 0, sizeof(dest_addr_));
+ socklen_t dest_addr_size = 0;
+ struct sockaddr_storage dest_addr;
if (address_family_ == AF_INET) {
/* Holder for bcast_dest_address address */
struct sockaddr_in *bcast_sender_addr_in =
- reinterpret_cast<struct sockaddr_in *>(&dest_addr_);
+ reinterpret_cast<struct sockaddr_in *>(&dest_addr);
+ memset(bcast_sender_addr_in, 0, sizeof(struct sockaddr_in));
bcast_sender_addr_in->sin_family = AF_INET;
bcast_sender_addr_in->sin_port = htons(dgram_port_);
TRACE("DTM: IP address : %s Bcast address : %s sa_family : %d ",
@@ -125,11 +461,12 @@ uint32_t Multicast::dtm_dgram_bcast_sender() {
memset(bcast_sender_addr_in->sin_zero, '\0',
sizeof(bcast_sender_addr_in->sin_zero));
- dest_addr_size_ = sizeof(struct sockaddr_in);
+ dest_addr_size = sizeof(struct sockaddr_in);
} else if (address_family_ == AF_INET6) {
/* Holder for bcast_dest_address address */
struct sockaddr_in6 *bcast_sender_addr_in6 =
- reinterpret_cast<struct sockaddr_in6 *>(&dest_addr_);
+ reinterpret_cast<struct sockaddr_in6 *>(&dest_addr);
+ memset(bcast_sender_addr_in6, 0, sizeof(struct sockaddr_in6));
bcast_sender_addr_in6->sin6_family = AF_INET6;
bcast_sender_addr_in6->sin6_port = htons(dgram_port_);
bcast_sender_addr_in6->sin6_flowinfo = 0;
@@ -138,16 +475,22 @@ uint32_t Multicast::dtm_dgram_bcast_sender() {
stream_address_.c_str(), dgram_address_.c_str(), address_family_);
inet_pton(AF_INET6, dgram_address_.c_str(),
&bcast_sender_addr_in6->sin6_addr);
- dest_addr_size_ = sizeof(struct sockaddr_in6);
+ dest_addr_size = sizeof(struct sockaddr_in6);
} else {
LOG_ER("DTM : dgram_enable_bcast failed");
TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
}
+ if (peers_.emplace(reinterpret_cast<sockaddr *>(&dest_addr), dest_addr_size)
+ .second) {
+ LOG_IN("Added broadcast IP '%s'", dgram_address_.c_str());
+ } else {
+ osaf_abort(peers_.size());
+ }
/* Create socket for sending/receiving datagrams */
dgram_sock_sndr =
- socket(dest_addr_.ss_family, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
+ socket(dest_addr.ss_family, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
IPPROTO_UDP);
if (dgram_sock_sndr == -1) {
LOG_ER("DTM :socket create failederr :%s", strerror(errno));
@@ -165,8 +508,12 @@ uint32_t Multicast::dtm_dgram_bcast_sender() {
}
if (address_family_ == AF_INET6) {
+ int v6only = 1;
+ if (setsockopt(dgram_sock_sndr, IPPROTO_IPV6, IPV6_V6ONLY, &v6only,
+ sizeof(v6only)) < 0)
+ LOG_ER("setsockopt(IPV6_V6ONLY) failed: %s", strerror(errno));
struct sockaddr_in6 *bcast_sender_addr_in6 =
- reinterpret_cast<struct sockaddr_in6 *>(&dest_addr_);
+ reinterpret_cast<struct sockaddr_in6 *>(&dest_addr);
int yes = 1;
if (setsockopt(dgram_sock_sndr, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &yes,
sizeof(yes)) < 0) {
@@ -183,8 +530,7 @@ uint32_t Multicast::dtm_dgram_bcast_sender() {
return NCSCC_RC_FAILURE;
}
- unsigned int ifindex;
- ifindex = if_nametoindex(ifname_.c_str());
+ unsigned ifindex = if_nametoindex(ifname_.c_str());
if (setsockopt(dgram_sock_sndr, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex,
sizeof(ifindex)) < 0) {
LOG_ER("DTM :setsockopt(IPV6_MULTICAST_IF) failed err :%s ifname :%d",
@@ -239,6 +585,12 @@ uint32_t Multicast::dgram_enable_bcast(int sock_desc) {
* Function to send the mcast message
*
* @param dtms_cb mcast_ttl
+ * 0 restricted to the same host
+ * 1 restricted to the same subnet
+ * 32 restricted to the same site
+ * 64 restricted to the same region
+ * 128 restricted to the same continent
+ * 255 unrestricted
*
* @return NCSCC_RC_SUCCESS
* @return NCSCC_RC_FAILURE
@@ -246,43 +598,39 @@ uint32_t Multicast::dgram_enable_bcast(int sock_desc) {
*/
uint32_t Multicast::dtm_dgram_mcast_sender(int mcast_ttl) {
/* Construct the serv address structure */
- struct addrinfo addr_criteria; // Criteria for address match
- char local_port_str[INET6_ADDRSTRLEN];
int rv;
TRACE_ENTER();
dgram_sock_sndr = -1;
- TRACE("DTM :dgram_port_rcvr :%d", dgram_port_);
- snprintf(local_port_str, sizeof(local_port_str), "%d", (dgram_port_));
+ TRACE("DTM :dgram_port_rcvr : %" PRIu16, dgram_port_);
+ char local_port_str[8];
+ snprintf(local_port_str, sizeof(local_port_str), "%" PRIu16, dgram_port_);
- memset(&addr_criteria, 0, sizeof(addr_criteria)); /* Zero out structure */
- addr_criteria.ai_family = AF_UNSPEC; /* v4 or v6 is OK */
- addr_criteria.ai_socktype = SOCK_DGRAM; /* Only datagram sockets */
- addr_criteria.ai_protocol = IPPROTO_UDP; /* Only UDP please */
- addr_criteria.ai_flags |= AI_NUMERICHOST; /* Don't try to resolve address */
+ struct addrinfo addr_criteria {};
+ addr_criteria.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+ addr_criteria.ai_family = AF_UNSPEC;
+ addr_criteria.ai_socktype = SOCK_DGRAM;
+ addr_criteria.ai_protocol = IPPROTO_UDP;
struct addrinfo *mcast_sender_addr;
+ char mcast_addr_eth[INET6_ADDRSTRLEN + IFNAMSIZ];
+ memset(mcast_addr_eth, 0, (INET6_ADDRSTRLEN + IFNAMSIZ));
/* For link-local address, need to set sin6_scope_id to match the
device index of the network device on it has to connecct */
if (scope_link_) {
- char mcast_addr_eth[INET6_ADDRSTRLEN + IFNAMSIZ];
- memset(mcast_addr_eth, 0, (INET6_ADDRSTRLEN + IFNAMSIZ));
- sprintf(mcast_addr_eth, "%s%%%s", multicast_address_.c_str(),
- ifname_.c_str());
- rv = getaddrinfo(mcast_addr_eth, local_port_str, &addr_criteria,
- &mcast_sender_addr);
- TRACE("DTM :mcast_addr : %s local_port_str :%s", mcast_addr_eth,
- local_port_str);
+ snprintf(mcast_addr_eth, sizeof(mcast_addr_eth), "%s%%%s",
+ multicast_address_.c_str(), ifname_.c_str());
} else {
- rv = getaddrinfo(multicast_address_.c_str(), local_port_str,
&addr_criteria,
- &mcast_sender_addr);
- TRACE("DTM :mcast_addr : %s local_port_str :%s",
multicast_address_.c_str(),
- local_port_str);
+ snprintf(mcast_addr_eth, sizeof(mcast_addr_eth), "%s",
+ multicast_address_.c_str());
}
+ rv = getaddrinfo(mcast_addr_eth, local_port_str, &addr_criteria,
+ &mcast_sender_addr);
+ TRACE("DTM :mcast_addr : %s local_port_str :%s", mcast_addr_eth,
+ local_port_str);
if (rv != 0) {
- LOG_ER("DTM:Unable to getaddrinfo() rtn_val :%d err :%s", rv,
- strerror(errno));
+ LOG_ER("DTM:Unable to getaddrinfo(): %s", gai_strerror(rv));
TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
}
@@ -319,12 +667,14 @@ uint32_t Multicast::dtm_dgram_mcast_sender(int mcast_ttl)
{
return NCSCC_RC_FAILURE;
}
- size_t addrlen = mcast_sender_addr->ai_addrlen;
- if (addrlen > sizeof(dest_addr_)) {
- LOG_ER("getaddrinfo() returned too large address: %zu", addrlen);
- addrlen = sizeof(dest_addr_);
+ if (peers_
+ .emplace(reinterpret_cast<sockaddr *>(mcast_sender_addr->ai_addr),
+ mcast_sender_addr->ai_addrlen)
+ .second) {
+ LOG_IN("Added broadcast IP '%s'", mcast_addr_eth);
+ } else {
+ osaf_abort(peers_.size());
}
- memcpy(&dest_addr_, mcast_sender_addr->ai_addr, addrlen);
freeaddrinfo(mcast_sender_addr);
@@ -363,6 +713,10 @@ uint32_t Multicast::dgram_set_mcast_ttl(int mcast_ttl, int
family) {
/* Set TTL of mcast packet. Unfortunately this requires */
/* address-family-specific code */
if (family == AF_INET6) { // v6-specific
+ int v6only = 1;
+ if (setsockopt(dgram_sock_sndr, IPPROTO_IPV6, IPV6_V6ONLY, &v6only,
+ sizeof(v6only)) < 0)
+ LOG_ER("setsockopt(IPV6_V6ONLY) failed: %s", strerror(errno));
/* The v6 mcast TTL socket option requires that the value be */
/* passed in as an integer */
if (setsockopt(dgram_sock_sndr, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
@@ -372,8 +726,7 @@ uint32_t Multicast::dgram_set_mcast_ttl(int mcast_ttl, int
family) {
TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
}
- unsigned int ifindex;
- ifindex = if_nametoindex(ifname_.c_str());
+ unsigned ifindex = if_nametoindex(ifname_.c_str());
if (setsockopt(dgram_sock_sndr, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex,
sizeof(ifindex)) < 0) {
LOG_ER("DTM :setsockopt(IPV6_MULTICAST_IF) failed err :%s ifname :%d",
@@ -404,15 +757,19 @@ bool Multicast::Send() {
Message msg{cluster_id_, node_id_, !multicast_address_.empty(),
stream_port_, address_family_, stream_address_};
bool success = true;
- ssize_t num_bytes =
- sendto(dgram_sock_sndr, &msg, sizeof(msg), 0,
- reinterpret_cast<struct sockaddr *>(&dest_addr_),
dest_addr_size_);
- if (num_bytes < 0) {
- LOG_ER("sendto() failed: %s ", strerror(errno));
- success = false;
- } else if (static_cast<size_t>(num_bytes) != sizeof(msg)) {
- LOG_ER("sendto() sent unexpected number of bytes %zd", num_bytes);
- success = false;
+ for (const auto &addr : peers_) {
+ ssize_t num_bytes;
+ do {
+ num_bytes = sendto(dgram_sock_sndr, &msg, sizeof(msg), 0, addr.address(),
+ addr.length());
+ } while (num_bytes < 0 && errno == EINTR);
+ if (num_bytes < 0) {
+ LOG_ER("sendto() failed: %s ", strerror(errno));
+ success = false;
+ } else if (static_cast<size_t>(num_bytes) != sizeof(msg)) {
+ LOG_ER("sendto() sent unexpected number of bytes %zd", num_bytes);
+ success = false;
+ }
}
TRACE_LEAVE2("success: %d", success ? 1 : 0);
@@ -515,22 +872,21 @@ uint32_t Multicast::dgram_join_mcast_group(
*/
uint32_t Multicast::dtm_dgram_mcast_listener() {
/* Construct the serv address structure */
- struct addrinfo addr_criteria; /* Criteria for address match */
- char local_port_str[INET6_ADDRSTRLEN];
int rv;
struct addrinfo *addr_list; /* Holder serv address */
TRACE_ENTER();
- TRACE("DTM :dgram_port_rcvr :%d", dgram_port_);
+ TRACE("DTM :dgram_port_rcvr : %" PRIu16, dgram_port_);
+ char local_port_str[8];
snprintf(local_port_str, sizeof(local_port_str), "%" PRIu16, dgram_port_);
dgram_sock_rcvr = -1;
- memset(&addr_criteria, 0, sizeof(addr_criteria)); /* Zero out structure */
- addr_criteria.ai_family = AF_UNSPEC; /* v4 or v6 is OK */
- addr_criteria.ai_socktype = SOCK_DGRAM; /* Only datagram sockets */
- addr_criteria.ai_protocol = IPPROTO_UDP; /* Only UDP protocol */
- addr_criteria.ai_flags |= AI_NUMERICHOST; /* Don't try to resolve address */
+ struct addrinfo addr_criteria {};
+ addr_criteria.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+ addr_criteria.ai_family = AF_UNSPEC;
+ addr_criteria.ai_socktype = SOCK_DGRAM;
+ addr_criteria.ai_protocol = IPPROTO_UDP;
/* For link-local address, need to set sin6_scope_id to match the
device index of the network device on it has to connecct */
@@ -550,8 +906,7 @@ uint32_t Multicast::dtm_dgram_mcast_listener() {
local_port_str);
}
if (rv != 0) {
- LOG_ER("DTM:Unable to getaddrinfo() rtn_val :%d err :%s", rv,
- strerror(errno));
+ LOG_ER("DTM:Unable to getaddrinfo(): %s", gai_strerror(rv));
TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
}
@@ -583,6 +938,13 @@ uint32_t Multicast::dtm_dgram_mcast_listener() {
return NCSCC_RC_FAILURE;
}
+ if (address_family_ == AF_INET6) {
+ int v6only = 1;
+ if (setsockopt(dgram_sock_rcvr, IPPROTO_IPV6, IPV6_V6ONLY, &v6only,
+ sizeof(v6only)) < 0)
+ LOG_ER("setsockopt(IPV6_V6ONLY) failed: %s", strerror(errno));
+ }
+
if (bind(dgram_sock_rcvr, addr_list->ai_addr, addr_list->ai_addrlen) < 0) {
LOG_ER("DTM : bind() failed err :%s ", strerror(errno));
if (close(dgram_sock_rcvr) != 0 && errno != EINTR)
@@ -617,32 +979,29 @@ uint32_t Multicast::dtm_dgram_mcast_listener() {
*
*/
uint32_t Multicast::dtm_dgram_bcast_listener() {
- struct addrinfo addr_criteria, *addr_list = nullptr,
- *p; // Criteria for address
- char local_port_str[INET6_ADDRSTRLEN];
+ struct addrinfo *addr_list = nullptr, *p; // Criteria for address
int rv;
char bcast_addr_eth[INET6_ADDRSTRLEN + IFNAMSIZ];
TRACE_ENTER();
- TRACE("DTM :dgram_port_rcvr :%d", dgram_port_);
- snprintf(local_port_str, sizeof(local_port_str), "%d", (dgram_port_));
+ TRACE("DTM :dgram_port_rcvr : %" PRIu16, dgram_port_);
+ char local_port_str[8];
+ snprintf(local_port_str, sizeof(local_port_str), "%" PRIu16, dgram_port_);
dgram_sock_rcvr = -1;
- /* Construct the server address structure */
- memset(&addr_criteria, 0, sizeof(addr_criteria)); // Zero out structure
- addr_criteria.ai_family = AF_UNSPEC; // Any address family
- addr_criteria.ai_flags = AI_PASSIVE; // Accept on any address/port
- addr_criteria.ai_socktype = SOCK_DGRAM; // Only datagram socket
- addr_criteria.ai_protocol = IPPROTO_UDP; // Only UDP socket
- addr_criteria.ai_flags |= AI_NUMERICHOST;
+ struct addrinfo addr_criteria {};
+ addr_criteria.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV;
+ addr_criteria.ai_family = AF_UNSPEC;
+ addr_criteria.ai_socktype = SOCK_DGRAM;
+ addr_criteria.ai_protocol = IPPROTO_UDP;
TRACE("DTM :ip_addr : %s local_port_str :%s", stream_address_.c_str(),
local_port_str);
if (address_family_ == AF_INET) {
if ((rv = getaddrinfo(dgram_address_.c_str(), local_port_str,
&addr_criteria, &addr_list)) != 0) {
- LOG_ER("DTM:Unable to getaddrinfo() rtn_val :%d err :%s", rv,
- strerror(errno));
+ LOG_ER("DTM:Unable to getaddrinfo() for '%s': %s",
dgram_address_.c_str(),
+ gai_strerror(rv));
TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
}
@@ -653,16 +1012,16 @@ uint32_t Multicast::dtm_dgram_bcast_listener() {
ifname_.c_str());
if ((rv = getaddrinfo(bcast_addr_eth, local_port_str, &addr_criteria,
&addr_list)) != 0) {
- LOG_ER("DTM:Unable to getaddrinfo() rtn_val :%d err :%s", rv,
- strerror(errno));
+ LOG_ER("DTM:Unable to getaddrinfo() for '%s': %s", bcast_addr_eth,
+ gai_strerror(rv));
TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
}
} else {
if ((rv = getaddrinfo(dgram_address_.c_str(), local_port_str,
&addr_criteria, &addr_list)) != 0) {
- LOG_ER("DTM:Unable to getaddrinfo() rtn_val :%d err :%s", rv,
- strerror(errno));
+ LOG_ER("DTM:Unable to getaddrinfo() for '%s': %s",
+ dgram_address_.c_str(), gai_strerror(rv));
TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
}
@@ -677,8 +1036,7 @@ uint32_t Multicast::dtm_dgram_bcast_listener() {
/* results and bind to the first we can */
p = addr_list;
- bool binded = false;
- unsigned int ifindex;
+ bool bound = false;
for (; p; p = p->ai_next) {
TRACE("DTM :family : %d, socktype : %d, protocol :%d", p->ai_family,
@@ -697,7 +1055,7 @@ uint32_t Multicast::dtm_dgram_bcast_listener() {
if (strcasecmp(ipstr, dgram_address_.c_str()) != 0) {
continue;
} else
- TRACE("DTM: DGRAM Socket binded to = %s\n", ipstr);
+ TRACE("DTM: DGRAM Socket bound to = %s\n", ipstr);
} else if (p->ai_family == AF_INET6) {
void *addr;
char ipstr[INET6_ADDRSTRLEN];
@@ -708,7 +1066,7 @@ uint32_t Multicast::dtm_dgram_bcast_listener() {
if (strcasecmp(ipstr, dgram_address_.c_str()) != 0) {
continue;
} else
- TRACE("DTM: DGRAM Socket binded to = %s\n", ipstr);
+ TRACE("DTM: DGRAM Socket bound to = %s\n", ipstr);
}
if ((dgram_sock_rcvr =
socket(p->ai_family, p->ai_socktype | SOCK_NONBLOCK |
SOCK_CLOEXEC,
@@ -727,9 +1085,13 @@ uint32_t Multicast::dtm_dgram_bcast_listener() {
return NCSCC_RC_FAILURE;
}
if (p->ai_family == AF_INET6) {
+ int v6only = 1;
+ if (setsockopt(dgram_sock_rcvr, IPPROTO_IPV6, IPV6_V6ONLY, &v6only,
+ sizeof(v6only)) < 0)
+ LOG_ER("setsockopt(IPV6_V6ONLY) failed: %s", strerror(errno));
struct sockaddr_in6 *ipv6 =
reinterpret_cast<struct sockaddr_in6 *>(p->ai_addr);
- ifindex = if_nametoindex(ifname_.c_str());
+ unsigned ifindex = if_nametoindex(ifname_.c_str());
ipv6->sin6_scope_id = ifindex;
if (setsockopt(dgram_sock_rcvr, IPPROTO_IPV6, IPV6_MULTICAST_IF,
&ifindex,
sizeof(ifindex)) < 0) {
@@ -763,14 +1125,14 @@ uint32_t Multicast::dtm_dgram_bcast_listener() {
freeaddrinfo(addr_list);
return NCSCC_RC_FAILURE;
} else {
- binded = true;
+ bound = true;
break;
}
}
/* Free address structure(s) allocated by getaddrinfo() */
freeaddrinfo(addr_list);
- if (binded != true) {
+ if (bound != true) {
TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
} else {
diff --git a/src/dtm/dtmnd/Multicast.h b/src/dtm/dtmnd/Multicast.h
index e3b90f1b6..01d818639 100644
--- a/src/dtm/dtmnd/Multicast.h
+++ b/src/dtm/dtmnd/Multicast.h
@@ -21,6 +21,8 @@
#include <sys/socket.h>
#include <cstddef>
#include <cstdint>
+#include <cstring>
+#include <set>
#include <string>
// The Multicast class implements a mechanism to send the DTM node discovery
@@ -42,7 +44,8 @@ class Multicast {
char stream_address[kInet6AddrStrlen];
};
- // Construct an instance of Multicast, using the supplied configuration
parameters.
+ // Construct an instance of Multicast, using the supplied configuration
+ // parameters.
Multicast(uint16_t cluster_id, uint32_t node_id, in_port_t stream_port,
in_port_t dgram_port, sa_family_t address_family,
const std::string& stream_address, const std::string&
dgram_address,
@@ -67,6 +70,48 @@ class Multicast {
int fd() { return dgram_sock_rcvr; }
private:
+ class Peer {
+ public:
+ Peer(const struct sockaddr* addr, socklen_t length)
+ : address_{new uint8_t[length]}, length_{length} {
+ memcpy(address_, addr, length);
+ }
+ Peer(const Peer& peer)
+ : address_{new uint8_t[peer.length_]}, length_{peer.length_} {
+ memcpy(address_, peer.address_, peer.length_);
+ }
+ Peer(Peer&& peer) : address_{peer.address_}, length_{peer.length_} {}
+ ~Peer() { delete[] address_; }
+ Peer& operator=(const Peer& peer) {
+ if (&peer != this) {
+ address_ = new uint8_t[peer.length_];
+ length_ = peer.length_;
+ memcpy(address_, peer.address_, peer.length_);
+ }
+ return *this;
+ }
+ Peer& operator=(Peer&& peer) {
+ address_ = peer.address_;
+ length_ = peer.length_;
+ return *this;
+ }
+ bool operator<(const Peer& peer) const {
+ return length_ == peer.length_
+ ? (memcmp(address_, peer.address_, length_) < 0)
+ : (length_ < peer.length_);
+ }
+ const struct sockaddr* address() const {
+ return reinterpret_cast<sockaddr*>(address_);
+ }
+ socklen_t length() const { return length_; }
+
+ private:
+ uint8_t* address_;
+ socklen_t length_;
+ };
+ enum Protocol { kBroadcast, kMulticast, kFileUnicast, kDnsUnicast };
+ bool InitializeUnicastSender();
+ bool InitializeUnicastReceiver();
uint32_t dtm_dgram_bcast_sender();
uint32_t dgram_enable_bcast(int sock_desc);
uint32_t dtm_dgram_mcast_sender(int mcast_ttl);
@@ -74,6 +119,12 @@ class Multicast {
uint32_t dgram_join_mcast_group(struct addrinfo* mcast_receiver_addr);
uint32_t dtm_dgram_mcast_listener();
uint32_t dtm_dgram_bcast_listener();
+ static Protocol GetProtocol(const std::string& multicast_address);
+ bool GetPeersFromFile(const std::string& path_name);
+ bool GetPeersFromDns(const std::string& domain_name);
+ static socklen_t ParseAddress(sa_family_t address_family,
+ const std::string& address, in_port_t port,
+ struct sockaddr_storage* addr);
uint16_t cluster_id_;
uint32_t node_id_;
@@ -85,12 +136,11 @@ class Multicast {
std::string multicast_address_;
std::string ifname_;
bool scope_link_;
+ Protocol protocol_;
+ std::set<Peer> peers_;
- socklen_t dest_addr_size_; // Holder for bcast_dest_address size ip v4 or v6
- // address
int dgram_sock_sndr;
int dgram_sock_rcvr;
- struct sockaddr_storage dest_addr_;
};
#endif // DTM_DTMND_MULTICAST_H_
diff --git a/src/dtm/dtmnd/dtm_node.cc b/src/dtm/dtmnd/dtm_node.cc
index 66f728c74..92cd60ace 100644
--- a/src/dtm/dtmnd/dtm_node.cc
+++ b/src/dtm/dtmnd/dtm_node.cc
@@ -27,6 +27,7 @@
#include <cstdlib>
#include <cstring>
#include "base/ncsencdec_pub.h"
+#include "base/osaf_utility.h"
#include "dtm/dtmnd/Multicast.h"
#include "dtm/dtmnd/dtm.h"
#include "dtm/dtmnd/dtm_inter.h"
@@ -452,6 +453,10 @@ void node_discovery_process(void *arg) {
/* descriptor. */
/*******************************************************/
if (close_conn) {
+ if (node == &dgram_sock_rcvr || node == &stream_sock ||
+ node == &mbx_fd) {
+ osaf_abort(node->comm_socket);
+ }
close_conn = false;
RemoveNodeFromEpoll(dtms_cb, node);
dtm_comm_socket_close(node);
diff --git a/src/dtm/dtmnd/dtm_node_sockets.cc
b/src/dtm/dtmnd/dtm_node_sockets.cc
index 59cf12a0d..2b49b988d 100644
--- a/src/dtm/dtmnd/dtm_node_sockets.cc
+++ b/src/dtm/dtmnd/dtm_node_sockets.cc
@@ -22,6 +22,7 @@
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <unistd.h>
+#include <cerrno>
#include <cstring>
#include "base/ncsencdec_pub.h"
#include "base/usrbuf.h"
@@ -35,6 +36,8 @@
#define MYPORT "6900"
#define MAXBUFLEN 100
+#define MAXPENDING 20
+
/**
* Close the socketr descriptors
*
@@ -350,30 +353,35 @@ done:
* @return NCSCC_RC_FAILURE
*
*/
-#define MAXPENDING 20
-
static uint32_t stream_sock_bind(DTM_INTERNODE_CB *dtms_cb,
struct addrinfo *stream_addr) {
/* Bind to the local address and set socket to list */
TRACE_ENTER();
- if ((bind(dtms_cb->stream_sock, stream_addr->ai_addr,
- stream_addr->ai_addrlen) == 0) &&
- (listen(dtms_cb->stream_sock, MAXPENDING) == 0)) {
- /* get local address of socket */
- struct sockaddr_storage local_addr;
- socklen_t addr_size = sizeof(local_addr);
- if (getsockname(dtms_cb->stream_sock,
- reinterpret_cast<struct sockaddr *>(&local_addr),
- &addr_size) < 0) {
- LOG_ER("DTM : getsockname() failed err :%s", strerror(errno));
- TRACE_LEAVE2("rc :%d", NCSCC_RC_FAILURE);
+ if (bind(dtms_cb->stream_sock, stream_addr->ai_addr,
+ stream_addr->ai_addrlen) == 0) {
+ if (listen(dtms_cb->stream_sock, MAXPENDING) == 0) {
+ /* get local address of socket */
+ struct sockaddr_storage local_addr;
+ socklen_t addr_size = sizeof(local_addr);
+ if (getsockname(dtms_cb->stream_sock,
+ reinterpret_cast<struct sockaddr *>(&local_addr),
+ &addr_size) < 0) {
+ LOG_ER("DTM : getsockname() failed err :%s", strerror(errno));
+ TRACE_LEAVE2("rc: %d", NCSCC_RC_FAILURE);
+ return NCSCC_RC_FAILURE;
+ }
+ TRACE("DTM : Binding done for : %d", dtms_cb->stream_sock);
+ } else {
+ LOG_ER("listen(%d) failed with errno %d", dtms_cb->stream_sock, errno);
+ TRACE_LEAVE2("rc: %d", NCSCC_RC_FAILURE);
return NCSCC_RC_FAILURE;
}
-
- TRACE("DTM : Binding done for : %d", dtms_cb->stream_sock);
+ } else {
+ LOG_ER("bind(%d) failed with errno %d", dtms_cb->stream_sock, errno);
+ TRACE_LEAVE2("rc: %d", NCSCC_RC_FAILURE);
+ return NCSCC_RC_FAILURE;
}
-
- TRACE_LEAVE2("rc :%d", NCSCC_RC_SUCCESS);
+ TRACE_LEAVE2("rc: %d", NCSCC_RC_SUCCESS);
return NCSCC_RC_SUCCESS;
}
@@ -422,7 +430,7 @@ uint32_t dtm_stream_nonblocking_listener(DTM_INTERNODE_CB
*dtms_cb) {
} else {
rv = getaddrinfo(dtms_cb->ip_addr.c_str(), local_port_str, &addr_criteria,
&addr_list);
- TRACE("DTM :ip_addr : %s local_port_str -%s", dtms_cb->ip_addr.c_str(),
+ TRACE("DTM :ip_addr : %s local_port_str :%s", dtms_cb->ip_addr.c_str(),
local_port_str);
}
if (rv != 0) {
diff --git a/src/dtm/dtmnd/dtmd.conf b/src/dtm/dtmnd/dtmd.conf
index 50661fd52..08530b808 100644
--- a/src/dtm/dtmnd/dtmd.conf
+++ b/src/dtm/dtmnd/dtmd.conf
@@ -8,6 +8,9 @@
# Uncomment the next line to enable trace
#args="--tracemask=0xffffffff"
+# Uncomment the next line to enable info level logging
+#args="--loglevel=info"
+
# Healthcheck keys
export DTM_ENV_HEALTHCHECK_KEY="Default"
@@ -19,9 +22,21 @@ DTM_CLUSTER_ID=1
# Mandatory
DTM_NODE_IP=10.130.100.114
-# Multicast IP of the self node
-# DTMSv
-# Optional
+# IPv4/IPv6 multicast group address, or source of peer IP addresses for unicast
+#
+# Set DTM_MCAST_ADDR to a non-empty string to use multicast or unicast instead
+# of broadcast.
+#
+# * To use multicast, specify an IPv4 or IPv6 multicast group address
+# * To use unicast, the string should start with "file:" followed
+# by the path name of a file containing a list of IP addresses (one per
line),
+# or start with "dns:" followed by a DNS domain name, respectively.
+#
+# Examples:
+#DTM_MCAST_ADDR=224.0.0.1
+#DTM_MCAST_ADDR=ff02::1
+#DTM_MCAST_ADDR=file:/var/lib/peer_ip_addresses.txt
+#DTM_MCAST_ADDR=dns:peers.opensaf.org
DTM_MCAST_ADDR=
# tcp_listening_port: The TCP port that the DTMSv listens on
@@ -40,7 +55,7 @@ DTM_UDP_BCAST_REV_PORT=6900
#
# bcast_freq: frequencey (in milliseconds) between broadcasts during initial
# discovery
-DTM_BCAST_FRE_MSECS=250
+DTM_BCAST_FRE_MSECS=250
# cont_bcast_int: interval (in milliseconds) between broadcasts after initial
# discovery has completed
@@ -59,19 +74,19 @@ DTM_INI_DIS_TIMEOUT_SECS=5
DTM_SKEEPALIVE=1
#
-# tcp_keepalive_time: The time (in seconds) the connection needs to remain
+# tcp_keepalive_time: The time (in seconds) the connection needs to remain
# idle before TCP starts sending keepalive probes
# Optional
DTM_TCP_KEEPIDLE_TIME=2
#
-# tcp_keepalive_intvl: The time (in seconds) between individual keepalive
+# tcp_keepalive_intvl: The time (in seconds) between individual keepalive
# probes.
# Optional
DTM_TCP_KEEPALIVE_INTVL=1
#
-# tcp_keepalive_probes: The maximum number of keepalive probes TCP should
+# tcp_keepalive_probes: The maximum number of keepalive probes TCP should
# send before dropping the connection.
# Optional
DTM_TCP_KEEPALIVE_PROBES=2
@@ -83,7 +98,7 @@ DTM_TCP_KEEPALIVE_PROBES=2
# Decreasing the user timeouts allows applications to "fail fast" if so
desired.
# Otherwise it may take upto 20 minutes with the current system
# defaults in a normal WAN environment.
-# This option, TCP_USER_TIMEOUT will override keepalive
+# This option, TCP_USER_TIMEOUT will override keepalive
# to determine when to close a connection due to keepalive failure.
# kept to 1.5 sec to match other transport protocols supported Opensaf
DTM_TCP_USER_TIMEOUT=1500
@@ -98,10 +113,10 @@ DTM_TCP_USER_TIMEOUT=1500
# IMP NOTE : If DTM_SOCK_SND_RCV_BUF_SIZE is configured according to
application requirements ,
#it is also mandatory to export `MDS_SOCK_SND_RCV_BUF_SIZE=` with the same
value of
#for example if set as DTM_SOCK_SND_RCV_BUF_SIZE=126976 need to do :
-#export MDS_SOCK_SND_RCV_BUF_SIZE=126976
+#export MDS_SOCK_SND_RCV_BUF_SIZE=126976
DTM_SOCK_SND_RCV_BUF_SIZE=65536
#
#The maximum processes allowed per node
-#Used to Set the dtm intra node maximum allowed processes
+#Used to Set the dtm intra node maximum allowed processes
DTM_INTRANODE_MAX_PROCESSES=100
--
2.13.3
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel