Browse Source

Add try/catch in LFDB and add introspection into multicast subscriptions in client network status API

Adam Ierymenko 6 years ago
parent
commit
3db0197865
4 changed files with 87 additions and 28 deletions
  1. 54 28
      controller/LFDB.cpp
  2. 18 0
      include/ZeroTierOne.h
  3. 6 0
      node/Network.cpp
  4. 9 0
      service/OneService.cpp

+ 54 - 28
controller/LFDB.cpp

@@ -79,16 +79,22 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
 							newrec["OwnerPrivate"] = _lfOwnerPrivate;
 							newrec["OwnerPrivate"] = _lfOwnerPrivate;
 							newrec["MaskingKey"] = maskingKey;
 							newrec["MaskingKey"] = maskingKey;
 							newrec["PulseIfUnchanged"] = true;
 							newrec["PulseIfUnchanged"] = true;
-							auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json");
-							if (resp) {
-								if (resp->status == 200) {
-									ns->second.dirty = false;
-									//printf("SET network %.16llx %s\n",ns->first,resp->body.c_str());
+							try {
+								auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json");
+								if (resp) {
+									if (resp->status == 200) {
+										ns->second.dirty = false;
+										//printf("SET network %.16llx %s\n",ns->first,resp->body.c_str());
+									} else {
+										fprintf(stderr,"ERROR: LFDB: %d from node (create/update network): %s" ZT_EOL_S,resp->status,resp->body.c_str());
+									}
 								} else {
 								} else {
-									fprintf(stderr,"ERROR: LFDB: %d from node (create/update network): %s" ZT_EOL_S,resp->status,resp->body.c_str());
+									fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
 								}
 								}
-							} else {
-								fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
+							} catch (std::exception &e) {
+								fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update network): %s" ZT_EOL_S,e.what());
+							} catch ( ... ) {
+								fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update network): unknown exception" ZT_EOL_S);
 							}
 							}
 						}
 						}
 					}
 					}
@@ -125,16 +131,22 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
 							newrec["MaskingKey"] = maskingKey;
 							newrec["MaskingKey"] = maskingKey;
 							newrec["Timestamp"] = ms->second.lastOnlineTime;
 							newrec["Timestamp"] = ms->second.lastOnlineTime;
 							newrec["PulseIfUnchanged"] = true;
 							newrec["PulseIfUnchanged"] = true;
-							auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json");
-							if (resp) {
-								if (resp->status == 200) {
-									ms->second.lastOnlineDirty = false;
-									//printf("SET member online %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str());
+							try {
+								auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json");
+								if (resp) {
+									if (resp->status == 200) {
+										ms->second.lastOnlineDirty = false;
+										//printf("SET member online %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str());
+									} else {
+										fprintf(stderr,"ERROR: LFDB: %d from node (create/update member online status): %s" ZT_EOL_S,resp->status,resp->body.c_str());
+									}
 								} else {
 								} else {
-									fprintf(stderr,"ERROR: LFDB: %d from node (create/update member online status): %s" ZT_EOL_S,resp->status,resp->body.c_str());
+									fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
 								}
 								}
-							} else {
-								fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
+							} catch (std::exception &e) {
+								fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member online status): %s" ZT_EOL_S,e.what());
+							} catch ( ... ) {
+								fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member online status): unknown exception" ZT_EOL_S);
 							}
 							}
 						}
 						}
 
 
@@ -153,16 +165,22 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
 								newrec["OwnerPrivate"] = _lfOwnerPrivate;
 								newrec["OwnerPrivate"] = _lfOwnerPrivate;
 								newrec["MaskingKey"] = maskingKey;
 								newrec["MaskingKey"] = maskingKey;
 								newrec["PulseIfUnchanged"] = true;
 								newrec["PulseIfUnchanged"] = true;
-								auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json");
-								if (resp) {
-									if (resp->status == 200) {
-										ms->second.dirty = false;
-										//printf("SET member %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str());
+								try {
+									auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json");
+									if (resp) {
+										if (resp->status == 200) {
+											ms->second.dirty = false;
+											//printf("SET member %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str());
+										} else {
+											fprintf(stderr,"ERROR: LFDB: %d from node (create/update member): %s" ZT_EOL_S,resp->status,resp->body.c_str());
+										}
 									} else {
 									} else {
-										fprintf(stderr,"ERROR: LFDB: %d from node (create/update member): %s" ZT_EOL_S,resp->status,resp->body.c_str());
+										fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
 									}
 									}
-								} else {
-									fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
+								} catch (std::exception &e) {
+									fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member): %s" ZT_EOL_S,e.what());
+								} catch ( ... ) {
+									fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member): unknown exception" ZT_EOL_S);
 								}
 								}
 							}
 							}
 						}
 						}
@@ -170,7 +188,7 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
 				}
 				}
 			}
 			}
 
 
-			{
+			try {
 				std::ostringstream query;
 				std::ostringstream query;
 				query
 				query
 					<< '{'
 					<< '{'
@@ -228,14 +246,18 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
 							}
 							}
 						}
 						}
 					} else {
 					} else {
-						fprintf(stderr,"ERROR: LFDB: %d from node: %s" ZT_EOL_S,resp->status,resp->body.c_str());
+						fprintf(stderr,"ERROR: LFDB: %d from node (check for network updates): %s" ZT_EOL_S,resp->status,resp->body.c_str());
 					}
 					}
 				} else {
 				} else {
 					fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
 					fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
 				}
 				}
+			} catch (std::exception &e) {
+				fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for network updates): %s" ZT_EOL_S,e.what());
+			} catch ( ... ) {
+				fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for network updates): unknown exception" ZT_EOL_S);
 			}
 			}
 
 
-			{
+			try {
 				std::ostringstream query;
 				std::ostringstream query;
 				query
 				query
 					<< '{'
 					<< '{'
@@ -297,11 +319,15 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
 							}
 							}
 						}
 						}
 					} else {
 					} else {
-						fprintf(stderr,"ERROR: LFDB: %d from node: %s" ZT_EOL_S,resp->status,resp->body.c_str());
+						fprintf(stderr,"ERROR: LFDB: %d from node (check for member updates): %s" ZT_EOL_S,resp->status,resp->body.c_str());
 					}
 					}
 				} else {
 				} else {
 					fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
 					fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S);
 				}
 				}
+			} catch (std::exception &e) {
+				fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for member updates): %s" ZT_EOL_S,e.what());
+			} catch ( ... ) {
+				fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for member updates): unknown exception" ZT_EOL_S);
 			}
 			}
 
 
 			timeRangeStart = time(nullptr) - 120; // start next query 2m before now to avoid losing updates
 			timeRangeStart = time(nullptr) - 120; // start next query 2m before now to avoid losing updates

+ 18 - 0
include/ZeroTierOne.h

@@ -198,6 +198,11 @@ extern "C" {
  */
  */
 #define ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH 7
 #define ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH 7
 
 
+/**
+ * Maximum number of multicast groups a device / network interface can be subscribed to at once
+ */
+#define ZT_MAX_MULTICAST_SUBSCRIPTIONS 1024
+
 /**
 /**
  * Maximum value for link quality (min is 0)
  * Maximum value for link quality (min is 0)
  */
  */
@@ -1193,6 +1198,19 @@ typedef struct
 	 * Routes (excluding those implied by assigned addresses and their masks)
 	 * Routes (excluding those implied by assigned addresses and their masks)
 	 */
 	 */
 	ZT_VirtualNetworkRoute routes[ZT_MAX_NETWORK_ROUTES];
 	ZT_VirtualNetworkRoute routes[ZT_MAX_NETWORK_ROUTES];
+
+	/**
+	 * Number of multicast groups subscribed
+	 */
+	unsigned int multicastSubscriptionCount;
+
+	/**
+	 * Multicast groups to which this network's device is subscribed
+	 */
+	struct {
+		uint64_t mac; /* MAC in lower 48 bits */
+		uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */
+	} multicastSubscriptions[ZT_MAX_MULTICAST_SUBSCRIPTIONS];
 } ZT_VirtualNetworkConfig;
 } ZT_VirtualNetworkConfig;
 
 
 /**
 /**

+ 6 - 0
node/Network.cpp

@@ -1433,6 +1433,12 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
 			memset(&(ec->routes[i]),0,sizeof(ZT_VirtualNetworkRoute));
 			memset(&(ec->routes[i]),0,sizeof(ZT_VirtualNetworkRoute));
 		}
 		}
 	}
 	}
+
+	ec->multicastSubscriptionCount = (unsigned int)_myMulticastGroups.size();
+	for(unsigned long i=0;i<(unsigned long)_myMulticastGroups.size();++i) {
+		ec->multicastSubscriptions[i].mac = _myMulticastGroups[i].mac().toInt();
+		ec->multicastSubscriptions[i].adi = _myMulticastGroups[i].adi();
+	}
 }
 }
 
 
 void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMulticastGroup)
 void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMulticastGroup)

+ 9 - 0
service/OneService.cpp

@@ -273,6 +273,15 @@ static void _networkToJson(nlohmann::json &nj,const ZT_VirtualNetworkConfig *nc,
 		ra.push_back(rj);
 		ra.push_back(rj);
 	}
 	}
 	nj["routes"] = ra;
 	nj["routes"] = ra;
+
+	nlohmann::json mca = nlohmann::json::array();
+	for(unsigned int i=0;i<nc->multicastSubscriptionCount;++i) {
+		nlohmann::json m;
+		m["mac"] = MAC(nc->multicastSubscriptions[i].mac).toString(tmp);
+		m["adi"] = nc->multicastSubscriptions[i].adi;
+		mca.push_back(m);
+	}
+	nj["multicastSubscriptions"] = mca;
 }
 }
 
 
 static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)
 static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)