summaryrefslogtreecommitdiff
path: root/netconf-service/netconf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'netconf-service/netconf.cpp')
-rw-r--r--netconf-service/netconf.cpp131
1 files changed, 85 insertions, 46 deletions
diff --git a/netconf-service/netconf.cpp b/netconf-service/netconf.cpp
index a5efc331..2596a6f9 100644
--- a/netconf-service/netconf.cpp
+++ b/netconf-service/netconf.cpp
@@ -161,19 +161,23 @@ int main(int argc,char **argv)
try {
const std::string &reqType = request.get("type");
if (reqType == "netconf-request") { // NETWORK_CONFIG_REQUEST packet
+ // Deserialize querying peer identity and network ID
Identity peerIdentity(request.get("peerId"));
uint64_t nwid = strtoull(request.get("nwid").c_str(),(char **)0,16);
+ std::string fromAddr(request.get("from"));
+
+ // Meta-information from node, such as (future) geo-location stuff
Dictionary meta;
if (request.contains("meta"))
meta.fromString(request.get("meta"));
- // Do quick signature check / sanity check
+ // Check validity of node's identity, ignore request on failure
if (!peerIdentity.locallyValidate()) {
fprintf(stderr,"identity failed validity check: %s\n",peerIdentity.toString(false).c_str());
continue;
}
- // Save identity if unknown
+ // Save node's identity if unknown
{
Query q = dbCon->query();
q << "SELECT identity FROM Node WHERE id = " << peerIdentity.address().toInt();
@@ -196,17 +200,21 @@ int main(int argc,char **argv)
}
}
- // Update lastSeen
+ // Update lastSeen for Node, which is always updated on a netconf request
{
Query q = dbCon->query();
q << "UPDATE Node SET lastSeen = " << Utils::now() << " WHERE id = " << peerIdentity.address().toInt();
q.exec();
}
+ // Look up core network information
bool isOpen = false;
- unsigned int mpb = 0;
- unsigned int md = 0;
- std::string name,desc;
+ unsigned int multicastPrefixBits = 0;
+ unsigned int multicastDepth = 0;
+ bool emulateArp = false;
+ bool emulateNdp = false;
+ std::string name;
+ std::string desc;
{
Query q = dbCon->query();
q << "SELECT name,`desc`,isOpen,multicastPrefixBits,multicastDepth FROM Network WHERE id = " << nwid;
@@ -215,8 +223,10 @@ int main(int argc,char **argv)
name = rs[0]["name"].c_str();
desc = rs[0]["desc"].c_str();
isOpen = ((int)rs[0]["isOpen"] > 0);
- mpb = (unsigned int)rs[0]["multicastPrefixBits"];
- md = (unsigned int)rs[0]["multicastDepth"];
+ emulateArp = ((int)rs[0]["emulateArp"] > 0);
+ emulateNdp = ((int)rs[0]["emulateNdp"] > 0);
+ multicastPrefixBits = (unsigned int)rs[0]["multicastPrefixBits"];
+ multicastDepth = (unsigned int)rs[0]["multicastDepth"];
} else {
Dictionary response;
response["peer"] = peerIdentity.address().toString();
@@ -231,10 +241,34 @@ int main(int argc,char **argv)
write(STDOUT_FILENO,&respml,4);
write(STDOUT_FILENO,respm.data(),respm.length());
stdoutWriteLock.unlock();
- continue;
+ continue; // ABORT, wait for next request
}
}
+ // Check membership if this is a closed network
+ if (!isOpen) {
+ Query q = dbCon->query();
+ q << "SELECT Node_id FROM NetworkNodes WHERE Network_id = " << nwid << " AND Node_id = " << peerIdentity.address().toInt();
+ StoreQueryResult rs = q.store();
+ if (!rs.num_rows()) {
+ Dictionary response;
+ response["peer"] = peerIdentity.address().toString();
+ response["nwid"] = request.get("nwid");
+ response["type"] = "netconf-response";
+ response["requestId"] = request.get("requestId");
+ response["error"] = "ACCESS_DENIED";
+ std::string respm = response.toString();
+ uint32_t respml = (uint32_t)htonl((uint32_t)respm.length());
+
+ stdoutWriteLock.lock();
+ write(STDOUT_FILENO,&respml,4);
+ write(STDOUT_FILENO,respm.data(),respm.length());
+ stdoutWriteLock.unlock();
+ continue; // ABORT, wait for next request
+ }
+ }
+
+ // Get list of etherTypes in comma-delimited hex format
std::string etherTypeWhitelist;
{
Query q = dbCon->query();
@@ -247,6 +281,7 @@ int main(int argc,char **argv)
}
}
+ // Get multicast group rates in dictionary format
Dictionary multicastRates;
{
Query q = dbCon->query();
@@ -267,40 +302,16 @@ int main(int argc,char **argv)
if (mac) {
sprintf(buf,"%.12llx/%lx",(mac & 0xffffffffffffULL),(unsigned long)rs[i]["multicastGroupAdi"]);
multicastRates[buf] = buf2;
- } else multicastRates["*"] = buf2;
+ } else { // zero MAC indicates default for unmatching multicast groups
+ multicastRates["*"] = buf2;
+ }
}
}
- Dictionary netconf;
-
- sprintf(buf,"%.16llx",(unsigned long long)nwid);
- netconf["nwid"] = buf;
- netconf["o"] = (isOpen ? "1" : "0");
- netconf["name"] = name;
- netconf["desc"] = desc;
- netconf["et"] = etherTypeWhitelist;
- netconf["mr"] = multicastRates.toString();
- sprintf(buf,"%llx",(unsigned long long)Utils::now());
- netconf["ts"] = buf;
- netconf["peer"] = peerIdentity.address().toString();
- if (mpb) {
- sprintf(buf,"%x",mpb);
- netconf["mpb"] = buf;
- }
- if (md) {
- sprintf(buf,"%x",md);
- netconf["md"] = buf;
- }
-
- if (!isOpen) {
- // TODO: handle closed networks, look up private membership,
- // generate signed cert.
- }
-
- std::string ipv4Static,ipv6Static;
-
+ // Check for (or assign?) static IP address assignments
+ std::string ipv4Static;
+ std::string ipv6Static;
{
- // Check for IPv4 static assignments
Query q = dbCon->query();
q << "SELECT INET_NTOA(ip) AS ip,netmaskBits FROM IPv4Static WHERE Node_id = " << peerIdentity.address().toInt() << " AND Network_id = " << nwid;
StoreQueryResult rs = q.store();
@@ -363,16 +374,42 @@ int main(int argc,char **argv)
}
}
- // Add static assignments to netconf, if any
- if (ipv4Static.length()) {
- netconf["ipv4Static"] = ipv4Static; // TODO: remove, old name
- netconf["v4s"] = ipv4Static;
+ // Update activity table for this network to indicate peer's participation
+ {
+ Query q = dbCon->query();
+ q << "INSERT INTO NetworkActivity (Network_id,Node_id,lastActivityTime,lastActivityFrom) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << Utils::now() << "," << fromAddr << ") ON DUPLICATE KEY UPDATE lastActivityTime = VALUES(lastActivityTime),lastActivityFrom = VALUES(lastActivityFrom)";
+ q.exec();
}
- if (ipv6Static.length()) {
- netconf["v6s"] = ipv6Static;
+
+ // Assemble response dictionary to send to peer
+ Dictionary netconf;
+ sprintf(buf,"%.16llx",(unsigned long long)nwid);
+ netconf["nwid"] = buf;
+ netconf["peer"] = peerIdentity.address().toString();
+ netconf["name"] = name;
+ netconf["desc"] = desc;
+ netconf["o"] = (isOpen ? "1" : "0");
+ netconf["et"] = etherTypeWhitelist;
+ netconf["mr"] = multicastRates.toString();
+ sprintf(buf,"%llx",(unsigned long long)Utils::now());
+ netconf["ts"] = buf;
+ netconf["eARP"] = (emulateArp ? "1" : "0");
+ netconf["eNDP"] = (emulateNdp ? "1" : "0");
+ if (multicastPrefixBits) {
+ sprintf(buf,"%x",multicastPrefixBits);
+ netconf["mpb"] = buf;
+ }
+ if (multicastDepth) {
+ sprintf(buf,"%x",multicastDepth);
+ netconf["md"] = buf;
}
+ if (ipv4Static.length())
+ netconf["v4s"] = ipv4Static;
+ if (ipv6Static.length())
+ netconf["v6s"] = ipv6Static;
- { // Create and send service bus response with payload attached as 'netconf'
+ // Send netconf as service bus response
+ {
Dictionary response;
response["peer"] = peerIdentity.address().toString();
response["nwid"] = request.get("nwid");
@@ -386,6 +423,8 @@ int main(int argc,char **argv)
write(STDOUT_FILENO,&respml,4);
write(STDOUT_FILENO,respm.data(),respm.length());
stdoutWriteLock.unlock();
+
+ // LOOP, wait for next request
}
}
} catch (std::exception &exc) {