The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
clientlib/nanoprobe.c
Go to the documentation of this file.
1 
25 #include <projectcommon.h>
26 #include <string.h>
27 #include <frameset.h>
28 #include <framesettypes.h>
29 #include <frametypes.h>
30 #include <compressframe.h>
31 #include <cryptframe.h>
32 #include <intframe.h>
33 #include <cstringframe.h>
34 #include <addrframe.h>
35 #include <ipportframe.h>
36 #include <seqnoframe.h>
37 #include <packetdecoder.h>
38 #include <netgsource.h>
39 #include <reliableudp.h>
40 #include <authlistener.h>
41 #include <nvpairframe.h>
42 #include <hblistener.h>
43 #include <hbsender.h>
44 #include <configcontext.h>
45 #include <pcap_min.h>
46 #include <jsondiscovery.h>
47 #include <switchdiscovery.h>
48 #include <arpdiscovery.h>
49 #include <fsprotocol.h>
50 #include <resourcecmd.h>
51 #include <resourcequeue.h>
52 #include <misc.h>
53 #include <nanoprobe.h>
54 
55 
61 void (*nanoprobe_warntime_agent)(HbListener*, guint64 howlate) = NULL;
62 void (*nanoprobe_comealive_agent)(HbListener*, guint64 howlate) = NULL;
63 WINEXPORT NanoHbStats nano_hbstats = {0U, 0U, 0U, 0U, 0U};
64 gboolean nano_connected = FALSE;
66 WINEXPORT GMainLoop* mainloop = NULL;
67 
75 FSTATIC void nanoobey_change_debug(gint plusminus, AuthListener*, FrameSet*, NetAddr*);
81 FSTATIC void _nano_send_rscexitstatus(ConfigContext* request, gpointer user_data
82 , enum HowDied reason, int rc, int signal, gboolean core_dumped
83 , const char * stringresult);
85 FSTATIC void nano_schedule_discovery(const char *name, guint32 interval,const char* json
86  , ConfigContext*, NetGSource* transport, NetAddr* fromaddr);
87 FSTATIC void nano_stop_discovery(const char * discoveryname, NetGSource*, NetAddr*);
88 FSTATIC gboolean nano_startupidle(gpointer gcruft);
89 FSTATIC gboolean nano_reqconfig(gpointer gcruft);
92 FSTATIC void _real_warntime_agent(HbListener* who, guint64 howlate);
93 FSTATIC void _real_comealive_agent(HbListener* who, guint64 howlate);
96 FSTATIC gboolean _nano_final_shutdown(gpointer unused);
97 FSTATIC gboolean shutdown_when_outdone(gpointer unused);
98 
99 HbListener* (*nanoprobe_hblistener_new)(NetAddr*, ConfigContext*) = _real_hblistener_new;
100 
101 gboolean nano_shutting_down = FALSE;
102 const char * procname = "nanoprobe";
103 static AuthListener* obeycollective = NULL;
104 
105 static NetAddr* nanofailreportaddr = NULL;
106 static NetGSource* nanotransport = NULL;
107 static guint idle_shutdown_gsource = 0;
108 static ResourceQueue* RscQ = NULL;
109 
111 
116 {
117  return hblistener_new(addr, context, 0);
118 }
119 
121 void
122 nanoprobe_report_upstream(guint16 reporttype
123 , NetAddr* who
124 , const char * systemnm
125 , guint64 howlate)
126 {
128  FrameSet* fs;
129 
130  if (nano_shutting_down || NULL == nanofailreportaddr) {
131  DEBUGMSG("%s.%d: Ignoring request to send fstype=%d message upstream [%s]."
132  , __FUNCTION__, __LINE__, reporttype
133  , (nano_shutting_down ? "shutting down" : "not connected to CMA"));
134  return;
135  }
136 
137  fs = frameset_new(reporttype);
138  // Construct and send a frameset reporting this event...
139  if (howlate > 0) {
141  lateframe->setint(lateframe, howlate);
142  frameset_append_frame(fs, &lateframe->baseclass);
143  UNREF2(lateframe);
144  }
145  // Add the address - if any...
146  if (who != NULL) {
148  frameset_append_frame(fs, &peeraddr->baseclass);
149  UNREF2(peeraddr);
150  }
151  // Add the system name - if any...
152  if (systemnm != NULL) {
154  usf->baseclass.setvalue(&usf->baseclass, g_strdup(systemnm), strlen(systemnm)+1
156  frameset_append_frame(fs, &usf->baseclass);
157  UNREF2(usf);
158  }
159  DEBUGMSG3("%s - sending frameset of type %d", __FUNCTION__, reporttype);
160  DUMP3("nanoprobe_report_upstream", &nanofailreportaddr->baseclass, NULL);
161  nanotransport->_netio->sendareliablefs(nanotransport->_netio, nanofailreportaddr, DEFAULT_FSP_QID, fs);
162  UNREF(fs);
163 }
164 
165 
167 FSTATIC void
169 {
170  static guint64 last_martian_time = 0; // microseconds
171  static guint recent_martian_count = 0;
172  guint64 now = g_get_monotonic_time(); // microseconds
173  const guint64 uS = 1000000;
174 
176 
177  // If it's been more than MARTIAN_TIMEOUT seconds since the last
178  // martian, then reset the count of recent martians
179  if (now > (last_martian_time + (MARTIAN_TIMEOUT*uS))) {
180  recent_martian_count = 0;
181  }
182 
183  last_martian_time = now;
184  ++recent_martian_count;
185 
186  // This means if we only get one martian then none, we say nothing
187  // This can happen as a result of timing - and it's OK.
188  // But if we get more than one, we complain then and once every 10 afterwards
189  if ((recent_martian_count % 10) == 2) {
190  char * addrstring;
191 
193  addrstring = who->baseclass.toString(who);
194  g_warning("System at address %s is sending unexpected heartbeats.", addrstring);
195  g_free(addrstring);
196 
198  }
199 }
202 FSTATIC void
204 {
208  }else{
209  char * addrstring;
210 
211  addrstring = who->listenaddr->baseclass.toString(who->listenaddr);
212  g_warning("Peer at address %s is dead (has timed out).", addrstring);
213  g_free(addrstring);
214 
216  }
217 }
218 
221 FSTATIC void
223 {
227  }
228 }
229 
230 
233 FSTATIC void
234 _real_warntime_agent(HbListener* who, guint64 howlate)
235 {
238  nanoprobe_warntime_agent(who, howlate);
239  }else{
240  char * addrstring;
241  guint64 mslate = howlate / 1000;
242  addrstring = who->listenaddr->baseclass.toString(who->listenaddr);
243  g_warning("Heartbeat from peer at address %s was "FMT_64BIT"d ms late.", addrstring, mslate);
244  g_free(addrstring);
246  }
247 }
250 FSTATIC void
251 _real_comealive_agent(HbListener* who, guint64 howlate)
252 {
255  nanoprobe_comealive_agent(who, howlate);
256  }else{
257  char * addrstring;
258  double secsdead = ((double)((howlate+50000) / 100000))/10.0; // Round to nearest tenth of a second
259  addrstring = who->listenaddr->baseclass.toString(who->listenaddr);
260  g_warning("Peer at address %s came alive after being dead for %g seconds.", addrstring, secsdead);
261  g_free(addrstring);
263  }
264 }
265 
277 void
279  , FrameSet* fs
280  , NetAddr* fromaddr)
281 {
282 
283  GSList* slframe;
284  guint addrcount = 0;
286  guint16 sendinterval;
287  gint64 intvalue;
288 
289  if (nano_shutting_down) {
290  return;
291  }
292 
293  g_return_if_fail(fs != NULL);
294  (void)fromaddr;
295 
296  intvalue = config->getint(config, CONFIGNAME_INTERVAL);
297  sendinterval = (intvalue > 0 ? intvalue : CONFIG_DEFAULT_HBTIME);
298 
299  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
300  Frame* frame = CASTTOCLASS(Frame, slframe->data);
301  int frametype = frame->type;
302  switch(frametype) {
303  IntFrame* iframe;
304  IpPortFrame* aframe;
305  HbSender* hb;
306 
308  iframe = CASTTOCLASS(IntFrame, frame);
309  sendinterval = (guint16) iframe->getint(iframe);
310  break;
311  case FRAMETYPE_RSCJSON:{
312  CstringFrame* csf = CASTTOCLASS(CstringFrame, frame);
313  ConfigContext* cfg;
314  const char * json;
315  json = csf->baseclass.value;
316  DEBUGMSG3("%s.%d: Got RSCJSON frame: %s", __FUNCTION__
317  , __LINE__, json);
318  cfg = configcontext_new_JSON_string(json);
319  g_return_if_fail(cfg != NULL);
320  intvalue = cfg->getint(cfg, CONFIGNAME_INTERVAL);
321  sendinterval = (intvalue > 0 ? intvalue : sendinterval);
322  UNREF(cfg);
323  break;
324  }
325  case FRAMETYPE_IPPORT:
326  if (0 == sendinterval) {
327  g_warning("Send interval is zero in %s", __FUNCTION__);
328  continue;
329  }
330  aframe = CASTTOCLASS(IpPortFrame, frame);
331  addrcount++;
332  hb = hbsender_new(aframe->getnetaddr(aframe)
333  , parent->baseclass.transport, sendinterval, 0);
334  (void)hb;
335  break;
336  }
337  }
338 }
350 void
352  , FrameSet* fs
353  , NetAddr* fromaddr)
354 {
355 
356  GSList* slframe;
358  guint addrcount = 0;
359 
360  guint64 deadtime;
361  guint64 warntime;
362  gint64 intvalue;
363 
364  (void)fromaddr;
365 
366  if (nano_shutting_down) {
367  return;
368  }
369 
370  g_return_if_fail(fs != NULL);
371  intvalue = config->getint(config, CONFIGNAME_TIMEOUT);
372  deadtime = (intvalue > 0 ? intvalue : CONFIG_DEFAULT_DEADTIME);
373  intvalue = config->getint(config, CONFIGNAME_WARNTIME);
374  warntime = (intvalue > 0 ? intvalue : CONFIG_DEFAULT_WARNTIME);
375 
376  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
377  Frame* frame = CASTTOCLASS(Frame, slframe->data);
378  int frametype = frame->type;
379  switch(frametype) {
380  IntFrame* iframe;
381 
383  iframe = CASTTOCLASS(IntFrame, frame);
384  deadtime = iframe->getint(iframe);
385  break;
386 
388  iframe = CASTTOCLASS(IntFrame, frame);
389  intvalue = iframe->getint(iframe);
390  warntime = (intvalue > 0 ? (guint64)intvalue : warntime);
391  break;
392 
393  case FRAMETYPE_RSCJSON: {
394  CstringFrame* csf = CASTTOCLASS(CstringFrame, frame);
395  ConfigContext* cfg;
396  const char * json;
397  json = csf->baseclass.value;
398  DEBUGMSG3("%s.%d: Got RSCJSON frame: %s", __FUNCTION__
399  , __LINE__, json);
400  cfg = configcontext_new_JSON_string(json);
401  g_return_if_fail(cfg != NULL);
402  intvalue = cfg->getint(cfg, CONFIGNAME_TIMEOUT);
403  deadtime = (intvalue > 0 ? (guint64)intvalue : deadtime);
404  intvalue = cfg->getint(cfg, CONFIGNAME_WARNTIME);
405  warntime = (intvalue > 0 ? (guint64)intvalue : warntime);
406  UNREF(cfg);
407  }
408  break;
409 
410  case FRAMETYPE_IPPORT: {
411  HbListener* hblisten;
412  IpPortFrame* aframe;
414  aframe = CASTTOCLASS(IpPortFrame, frame);
415  addrcount++;
416  hblisten = hblistener_new(aframe->getnetaddr(aframe), config, 0);
417  hblisten->baseclass.associate(&hblisten->baseclass, transport);
418  if (deadtime > 0) {
419  // Otherwise we get the default deadtime
420  hblisten->set_deadtime(hblisten, deadtime);
421  }
422  if (warntime > 0) {
423  // Otherwise we get the default warntime
424  hblisten->set_warntime(hblisten, warntime);
425  }
426  hblisten->set_deadtime_callback(hblisten, _real_deadtime_agent);
427  hblisten->set_heartbeat_callback(hblisten, _real_heartbeat_agent);
428  hblisten->set_warntime_callback(hblisten, _real_warntime_agent);
429  hblisten->set_comealive_callback(hblisten, _real_comealive_agent);
430  // Intercept incoming heartbeat packets
431  transport->addListener(transport, FRAMESETTYPE_HEARTBEAT
432  , &hblisten->baseclass);
433  // Unref this heartbeat listener, and forget our reference.
434  UNREF2(hblisten);
435  /*
436  * That still leaves two references to 'hblisten':
437  * - in the transport dispatch table
438  * - in the global heartbeat listener table
439  * And one reference to the previous 'hblisten' object:
440  * - in the global heartbeat listener table
441  * Also note that we become the 'proxy' for all incoming heartbeats
442  * but we dispatch them to the right HbListener object.
443  * Since we've become the proxy for all incoming heartbeats, if
444  * we displace and free the old proxy, this all still works nicely,
445  * because the transport object gets rid of its old reference to the
446  * old 'proxy' object.
447  */
448  }
449  break;
450  }
451  }
452 }
453 
463 void
465  , FrameSet* fs
466  , NetAddr* fromaddr)
467 {
468  g_return_if_fail(fs != NULL && fs->fstype == FRAMESETTYPE_SENDEXPECTHB);
469 
470  if (nano_shutting_down) {
471  return;
472  }
473  // This will cause us to ACK the packet twice -- not a problem...
474  nanoobey_sendhb (parent, fs, fromaddr);
475  nanoobey_expecthb(parent, fs, fromaddr);
476 }
484 void
486  , FrameSet* fs
487  , NetAddr* fromaddr)
488 {
489  GSList* slframe;
490  (void)parent;
491  (void)fromaddr;
492 
493  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
494  Frame* frame = CASTTOCLASS(Frame, slframe->data);
495  switch(frame->type) {
496  case FRAMETYPE_IPPORT: {
497  // This is _so_ much simpler than the code to send them ;-)
498  IpPortFrame* aframe = CASTTOCLASS(IpPortFrame, frame);
499  hbsender_stopsend(aframe->getnetaddr(aframe));
500  break;
501  }
502  }//endswitch
503  }//endfor
504 }
505 
513 void
515  , FrameSet* fs
516  , NetAddr* fromaddr)
517 {
518  GSList* slframe;
519  (void)parent;
520  (void)fromaddr;
521 
522  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
523  Frame* frame = CASTTOCLASS(Frame, slframe->data);
524  switch(frame->type) {
525  case FRAMETYPE_IPPORT: {
526  // This is _so_ much simpler than the code to listen for heartbeats...
527  IpPortFrame* aframe = CASTTOCLASS(IpPortFrame, frame);
528  NetAddr* destaddr = aframe->getnetaddr(aframe);
530  hblistener_unlisten(destaddr);
531  transport->closeconn(transport, DEFAULT_FSP_QID, destaddr);
532  break;
533  }
534  }//endswitch
535  }//endfor
536 }
537 
543 void
545  , FrameSet* fs
546  , NetAddr* fromaddr)
547 {
548  nanoobey_stopexpecthb(parent, fs, fromaddr);
549  nanoobey_stopsendhb (parent, fs, fromaddr);
550 }
551 
552 /*
553  * Act on (obey) a <b>FRAMESETTYPE_SETCONFIG</b> @ref FrameSet.
554  * This frameset is sent during the initial configuration phase.
555  * It contains name value pairs to save into our configuration (ConfigContext).
556  * These might be {string,string} pairs or {string,ipaddr} pairs, or
557  * {string, integer} pairs. We process them all.
558  * The frame types that we receive for these are:
559  * <b>FRAMETYPE_PARAMNAME</b> - parameter name to set
560  * <b>FRAMETYPE_CSTRINGVAL</b> - string value to associate with name
561  * <b>FRAMETYPE_CINTVAL</b> - integer value to associate with naem
562  * <b>FRAMETYPE_IPPORT</b> - IP address to associate with name
563  */
564 void
566  , FrameSet* fs
567  , NetAddr* fromaddr)
568 {
569  GSList* slframe;
570  ConfigContext* newconfig = NULL;
572 
573  (void)fromaddr;
574 
575 
576  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
577  Frame* frame = CASTTOCLASS(Frame, slframe->data);
578  switch (frame->type) {
579  case FRAMETYPE_CONFIGJSON: { // Configuration JSON string (parameters)
580  CstringFrame* strf = CASTTOCLASS(CstringFrame, frame);
581  const char * jsonstring;
582  int cprs_thresh;
583  g_return_if_fail(strf != NULL);
584  jsonstring = strf->baseclass.value;
585  DEBUGMSG3("%s.%d: Got CONFIGJSON frame: %s", __FUNCTION__, __LINE__
586  , jsonstring);
587  newconfig = configcontext_new_JSON_string(jsonstring);
588  // This is a good place to check for a compression threshold
589  // And possibly other parameters
590  if (newconfig) {
591  cprs_thresh =
592  newconfig->getint(newconfig, CONFIGNAME_CPRS_THRESH);
593  if (cprs_thresh > 0) {
594  Frame* f;
595  f = config->getframe(config, CONFIGNAME_COMPRESS);
596  if (f) {
597  CompressFrame* cf
599  cf->compression_threshold = cprs_thresh;
600  }
601  }
602  }
603  goto endloop;
604  }
605  }
606  }
607 endloop:
608  if (NULL == newconfig) {
609  g_warning("%s.%d: SETCONFIG message without valid JSON configuration"
610  , __FUNCTION__, __LINE__);
611  return;
612  }
613 
614  if (config) {
615  GSList* keylist = newconfig->keys(newconfig);
616  GSList* thiskey;
617  GSList* nextkey;
618 
619  // Merge the new configuration into the old configuration data...
620  for (thiskey = keylist; thiskey; thiskey=nextkey) {
621  const char * key = thiskey->data;
622  enum ConfigValType valtype = newconfig->gettype(newconfig, key);
623 
624  nextkey=thiskey->next;
625 
626  switch(valtype) {
627  case CFG_NETADDR:
628  config->setaddr(config, key, newconfig->getaddr(newconfig, key));
629  break;
630 
631  case CFG_CFGCTX:
632  config->setconfig(config, key, newconfig->getconfig(newconfig, key));
633  break;
634 
635  case CFG_STRING:
636  config->setstring(config, key, newconfig->getstring(newconfig, key));
637  break;
638 
639  case CFG_BOOL:
640  config->setbool(config, key, newconfig->getbool(newconfig, key));
641  break;
642 
643  case CFG_INT64:
644  config->setint(config, key, newconfig->getint(newconfig, key));
645  break;
646 
647  case CFG_FLOAT:
648  config->setdouble(config, key, newconfig->getdouble(newconfig, key));
649  break;
650  default:
651  break;
652  }
653  g_slist_free1(thiskey);
654  }
655  }
656  UNREF(newconfig);
657 
658  DUMP3("nanoobey_setconfig: cfg is", &config->baseclass, NULL);
659 
660  if (config && config->getaddr(config, CONFIGNAME_CMAFAIL) != NULL) {
661  if (nanofailreportaddr == NULL) {
662  nanofailreportaddr = config->getaddr(config, CONFIGNAME_CMAFAIL);
663  }else if (config->getaddr(config, CONFIGNAME_CMAFAIL) != nanofailreportaddr) {
664  UNREF(nanofailreportaddr);
665  nanofailreportaddr = config->getaddr(config, CONFIGNAME_CMAFAIL);
666  }
667  DUMP3("nanoobey_setconfig: nanofailreportaddr", &nanofailreportaddr->baseclass, NULL);
668  {
669  // Alias localhost to the CMA nanofailreportaddr (at least for now...)
672 
673  NetAddr* localhost = netaddr_string_new("127.0.0.1");
674  NetIO* io = parent->baseclass.transport->_netio;
675  io->addalias(io, localhost, nanofailreportaddr);
676  UNREF(localhost);
677  }
678  REF(nanofailreportaddr);
679  }
680  g_message("Connected to CMA. Happiness :-D");
681  nano_connected = TRUE;
682 }//nanoobey_setconfig
683 
688 FSTATIC void
689 nanoobey_change_debug(gint plusminus
690  , AuthListener* parent
691  , FrameSet* fs
692  , NetAddr* fromaddr)
693 {
694 
695  GSList* slframe;
696  guint changecount = 0;
697 
698  (void)parent;
699  (void)fromaddr;
700 
701  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
702  Frame* frame = CASTTOCLASS(Frame, slframe->data);
703  int frametype = frame->type;
704  switch (frametype) {
705  case FRAMETYPE_CSTRINGVAL: { // String value to set 'paramname' to
706  ++changecount;
707  if (plusminus < 0) {
708  proj_class_decr_debug((char*)frame->value);
709  }else{
710  proj_class_incr_debug((char*)frame->value);
711  }
712  }
713  break;
714  }
715  }
716  if (changecount == 0) {
717  if (plusminus < 0) {
718  proj_class_decr_debug(NULL);
719  }else{
720  proj_class_incr_debug(NULL);
721  }
722  }
723 }
728 FSTATIC void
730  , FrameSet* fs
731  , NetAddr* fromaddr)
732 {
733  nanoobey_change_debug(+1, parent, fs, fromaddr);
734 }
739 FSTATIC void
741  , FrameSet* fs
742  , NetAddr* fromaddr)
743 {
744  nanoobey_change_debug(-1, parent, fs, fromaddr);
745 }
746 
754 FSTATIC void
756  , FrameSet* fs
757  , NetAddr* fromaddr)
758 {
759 
760  GSList* slframe;
761  guint interval = 0;
762  const char * discoveryname = NULL;
763 
764  (void)parent;
765  (void)fromaddr;
766 
767  if (nano_shutting_down) {
768  return;
769  }
770 
771  DEBUGMSG3("%s - got frameset", __FUNCTION__);
772  // Loop over the frames, looking for those we know what to do with ;-)
773  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
774  Frame* frame = CASTTOCLASS(Frame, slframe->data);
775  int frametype = frame->type;
776 
777  switch (frametype) {
778  case FRAMETYPE_DISCNAME: { // Discovery instance name
779  CstringFrame* strf = CASTTOCLASS(CstringFrame, frame);
780  g_return_if_fail(strf != NULL);
781  g_return_if_fail(discoveryname == NULL);
782  discoveryname = strf->baseclass.value;
783  DEBUGMSG3("%s - got DISCOVERYNAME %s", __FUNCTION__, discoveryname);
784  }
785  break;
786 
787  case FRAMETYPE_DISCINTERVAL: { // Discovery interval
788  IntFrame* intf = CASTTOCLASS(IntFrame, frame);
789  interval = (guint)intf->getint(intf);
790  DEBUGMSG3("%s - got DISCOVERYINTERVAL %d", __FUNCTION__, interval);
791  }
792  break;
793 
794  case FRAMETYPE_DISCJSON: { // Discovery JSON string (parameters)
795  CstringFrame* strf = CASTTOCLASS(CstringFrame, frame);
796  const char * jsonstring;
797  g_return_if_fail(strf != NULL);
798  jsonstring = strf->baseclass.value;
799  g_return_if_fail(discoveryname != NULL);
800  DEBUGMSG3("Got DISCJSON frame: %s %d %s" , discoveryname, interval, jsonstring);
801  nano_schedule_discovery(discoveryname, interval, jsonstring
802  , parent->baseclass.config
803  , parent->baseclass.transport
804  , fromaddr);
805  }
806  interval = 0;
807  discoveryname = NULL;
808  break;
809 
810  }
811  }
812 }
813 
815 FSTATIC void
816 _nano_send_rscexitstatus(ConfigContext* request, gpointer user_data
817 , enum HowDied reason, int rc, int signal, gboolean core_dumped
818 , const char * stringresult)
819 {
821  ConfigContext* response = configcontext_new(0);
824  char* rsp_json;
825 
826  struct {
827  const char* framename;
828  int framevalue;
829  } pktframes[] = {
830  {REQREASONENUMNAMEFIELD, reason},
831  {REQRCNAMEFIELD, rc},
832  {REQSIGNALNAMEFIELD, signal},
833  };
834  unsigned j;
835 
836  for (j=0; j < DIMOF(pktframes); ++j) {
837  response->setint(response, pktframes[j].framename, pktframes[j].framevalue);
838  }
839  response->setbool(response, REQCOREDUMPNAMEFIELD, core_dumped);
840  if (stringresult) {
841  response->setstring(response, REQSTRINGRETNAMEFIELD, stringresult);
842  }
843  // Copy the request ID over from the original request
844  response->setint(response, REQIDENTIFIERNAMEFIELD
845  , request->getint(request, REQIDENTIFIERNAMEFIELD));
846  // Copy the resource name (instance) over from the original request
847  response->setstring(response, CONFIGNAME_INSTANCE
848  , request->getstring(request, CONFIGNAME_INSTANCE));
849  // Package it up as a JSON string to send to the CMA
850  rsp_json = response->baseclass.toString(&response->baseclass);
851  UNREF(response);
852  DEBUGMSG1("Reporting resource state change: %s", rsp_json);
853  sf->baseclass.setvalue(&sf->baseclass, rsp_json, strlen(rsp_json)+1, g_free);
855  UNREF2(sf);
856  transport->_netio->sendareliablefs(transport->_netio, nanofailreportaddr, DEFAULT_FSP_QID, fs);
857  UNREF(fs);
858 }
859 FSTATIC void
861 {
862  GSList* slframe;
863 
864  (void)parent;
865  (void)fromaddr;
866  if (nano_shutting_down) {
867  return;
868  }
869  if (NULL == RscQ) {
870  RscQ = resourcequeue_new(0);
871  }
872  // Loop over the frames, looking for those we know what to do with ;-)
873  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
874  Frame* frame = CASTTOCLASS(Frame, slframe->data);
875  CstringFrame* csframe;
876  ConfigContext* cfg;
877  if (frame->type != FRAMETYPE_RSCJSON) {
878  continue;
879  }
880  csframe = CASTTOCLASS(CstringFrame, frame);
882  if (NULL == cfg) {
883  g_warning("%s.%d: Received malformed JSON string [%*s]"
884  , __FUNCTION__, __LINE__
885  , csframe->baseclass.length-1
886  , (char*)csframe->baseclass.value);
887  continue;
888  }
889  RscQ->Qcmd(RscQ, cfg, _nano_send_rscexitstatus, nanotransport);
890  UNREF(cfg);
891  }
892 }
893 
894 FSTATIC void
896 {
897  GSList* slframe;
898 
899  (void)parent;
900  (void)fromaddr;
901  if (NULL == RscQ) {
902  RscQ = resourcequeue_new(0);
903  }
904 
905  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
906  Frame* frame = CASTTOCLASS(Frame, slframe->data);
907  CstringFrame* csframe;
908  ConfigContext* cfg;
909  if (frame->type != FRAMETYPE_RSCJSON) {
910  continue;
911  }
912  csframe = CASTTOCLASS(CstringFrame, frame);
914  if (NULL == cfg) {
915  g_warning("%s.%d: Received malformed JSON string [%*s]"
916  , __FUNCTION__, __LINE__
917  , csframe->baseclass.length-1
918  , (char*)csframe->baseclass.value);
919  continue;
920  }
921  RscQ->cancel(RscQ, cfg);
922  UNREF(cfg);
923  }
924 }
925 
930 FSTATIC void
932  , FrameSet* fs
933  , NetAddr* fromaddr)
934 {
935 
936  GSList* slframe;
937 
938  (void)parent;
939  (void)fromaddr;
940 
941 
942  // Loop over the frames, looking for the one we know what to do with ;-)
943  for (slframe = fs->framelist; slframe != NULL; slframe = g_slist_next(slframe)) {
944  Frame* frame = CASTTOCLASS(Frame, slframe->data);
945  int frametype = frame->type;
946 
947  switch (frametype) {
948  case FRAMETYPE_DISCNAME: { // Discovery instance name
949  CstringFrame* strf = CASTTOCLASS(CstringFrame, frame);
950  const char * discoveryname;
951  g_return_if_fail(strf != NULL);
952  discoveryname = strf->baseclass.value;
953  g_return_if_fail(discoveryname == NULL);
954  discovery_unregister(discoveryname);
955  }
956  break;
957 
958  }
959  }
960 }
961 
962 
966 FSTATIC void
967 nano_schedule_discovery(const char *instance,
968  guint32 interval,
969  const char* json,
972  NetAddr* fromaddr)
973 {
974  ConfigContext* jsonroot;
975  JsonDiscovery* discovery;
976  const char* disctype;
977 
978  (void)fromaddr;
979 
980  DEBUGMSG3("%s(%s,%d,%s)", __FUNCTION__, instance, interval, json);
981  jsonroot = configcontext_new_JSON_string(json);
982  g_return_if_fail(jsonroot != NULL);
983  disctype = jsonroot->getstring(jsonroot, "type");
984  g_return_if_fail(disctype != NULL);
985  discovery = jsondiscovery_new(disctype, instance, interval, jsonroot
986  , transport, config, 0);
987  UNREF(jsonroot);
988  if (discovery) {
989  UNREF2(discovery);
990  }
991 }
992 
995  const char * initdiscover;
998 };
999 
1006 gboolean
1007 nano_startupidle(gpointer gcruft)
1008 {
1009  static enum istate {INIT=3, WAIT=5, DONE=7} state = INIT;
1010  struct startup_cruft* cruft = gcruft;
1011  const char * cfgname = cruft->initdiscover;
1012 
1013  if (state == DONE || nano_shutting_down) {
1014  return FALSE;
1015  }
1016  if (state == INIT) {
1017  const char * jsontext = "{\"parameters\":{}}";
1018  ConfigContext* jsondata = configcontext_new_JSON_string(jsontext);
1020  ( cruft->initdiscover
1021  , cruft->initdiscover
1022  , cruft->discover_interval
1023  , jsondata
1024  , cruft->iosource, obeycollective->baseclass.config, 0);
1025  UNREF(jsondata);
1026  UNREF2(jd);
1027  state = WAIT;
1028  return TRUE;
1029  }
1030  if (obeycollective->baseclass.config->getstring(obeycollective->baseclass.config, cfgname)) {
1031  state = DONE;
1032  // Call it once, and arrange for it to repeat until we hear back.
1033  g_timeout_add_seconds(5, nano_reqconfig, gcruft);
1034  nano_reqconfig(gcruft);
1035  return FALSE;
1036  }
1037  return TRUE;
1038 }
1039 
1042 gboolean
1043 nano_reqconfig(gpointer gcruft)
1044 {
1045  struct startup_cruft* cruft = gcruft;
1046  FrameSet* fs;
1047  CstringFrame* csf;
1048  CstringFrame* usf;
1049  const char * cfgname = cruft->initdiscover;
1050  ConfigContext* context = obeycollective->baseclass.config;
1051  NetAddr* cmainit = context->getaddr(context, CONFIGNAME_CMAINIT);
1052  const char * jsontext;
1053  char * sysname = NULL;
1054 
1055  if (nano_shutting_down) {
1056  return FALSE;
1057  }
1058 
1059  // We <i>have</i> to know our initial request address - or all is lost.
1060  // NOTE THAT THIS ADDRESS MIGHT BE MULTICAST AND MIGHT BE USED ONLY ONCE
1061  g_return_val_if_fail(cmainit != NULL, FALSE);
1062 
1063  // Our initial configuration message must contain these parameters.
1064  if (context->getaddr(context, CONFIGNAME_CMAADDR) != NULL
1065  && context->getaddr(context, CONFIGNAME_CMAFAIL) != NULL
1066  && context->getaddr(context, CONFIGNAME_CMADISCOVER) != NULL
1067  && context->getint(context, CONFIGNAME_CMAPORT) > 0) {
1068  return FALSE;
1069  }
1071 
1072  // Put in the system name
1074  sysname = proj_get_sysname();
1075  usf->baseclass.setvalue(&usf->baseclass, g_strdup(sysname), strlen(sysname)+1
1077  frameset_append_frame(fs, &usf->baseclass);
1078  UNREF2(usf);
1079 
1080  // Put in the JSON configuration text
1081  jsontext = context->getstring(context, cfgname);
1083  csf->baseclass.setvalue(&csf->baseclass, g_strdup(jsontext), strlen(jsontext)+1
1085 
1086  frameset_append_frame(fs, &csf->baseclass);
1087  UNREF2(csf);
1088 
1089  // We've constructed the frameset - now send it - unreliably...
1090  // That's because the reply is typically from a different address
1091  // which would confuse the blazes out of the reliable comm code.
1092  cruft->iosource->sendaframeset(cruft->iosource, cmainit, fs);
1093  DEBUGMSG("%s.%d: Sent initial STARTUP frameset for %s."
1094  , __FUNCTION__, __LINE__, sysname);
1095  g_free(sysname); sysname = NULL;
1096  UNREF(fs);
1097  return TRUE;
1098 }
1099 
1100 static PacketDecoder* decoder = NULL;
1101 static SwitchDiscovery* swdisc = NULL;
1102 static ArpDiscovery* arpdisc = NULL;
1103 
1104 
1109  // This is the complete set of commands that nanoprobes know how to obey - so far...
1123  {0, NULL},
1124 };
1125 
1130 {
1131  static FrameTypeToFrame decodeframes[] = FRAMETYPEMAP;
1132  // Set up our packet decoder
1133  decoder = packetdecoder_new(0, decodeframes, DIMOF(decodeframes));
1134  return decoder;
1135 }
1136 
1137 
1164 WINEXPORT void
1165 nano_start_full(const char *initdiscoverpath
1166  , guint discover_interval
1167  , NetGSource* io
1168  , ConfigContext* config)
1169 {
1170  static struct startup_cruft cruftiness;
1171  struct startup_cruft initcrufty = {
1172  initdiscoverpath,
1174  io,
1175  };
1176  ConfigContext* arpconfig
1178  "{\""CONFIGNAME_INSTANCE"\":\"ARP_eth0\",\""CONFIGNAME_DEVNAME"\":\"eth0\"}");
1179  ConfigContext* swconfig
1181  "{\""CONFIGNAME_INSTANCE"\":\"SWITCH_eth0\",\""CONFIGNAME_DEVNAME"\":\"eth0\",\""CONFIGNAME_SWPROTOS"\":[\"lldp\", \"cdp\"]}");
1182 
1183  nano_shutting_down = FALSE;
1184  BINDDEBUG(nanoprobe_main);
1185 
1187  cruftiness = initcrufty;
1188  g_source_ref(CASTTOCLASS(GSource, io));
1189  nanotransport = io;
1190 
1191  // Get our local switch discovery information.
1192  // To be really right, we probably ought to wait until we know our local network
1193  // configuration - and start it up on all interfaces assigned addresses of global scope.
1195  swdisc = switchdiscovery_new(swconfig, G_PRIORITY_LOW, g_main_context_default()
1196  , io, config, 0);
1197  UNREF(swconfig);
1198  arpdisc = arpdiscovery_new(arpconfig, G_PRIORITY_LOW, g_main_context_default()
1199  , io, config, 0);
1200  UNREF(arpconfig);
1201  obeycollective = authlistener_new(0, collective_obeylist, config, TRUE);
1202  obeycollective->baseclass.associate(&obeycollective->baseclass, io);
1203  // Initiate the startup process
1204  g_idle_add(nano_startupidle, &cruftiness);
1205 }
1206 
1208 WINEXPORT void
1209 nano_shutdown(gboolean report)
1210 {
1211  if (report) {
1212  NetIOstats* ts = &nanotransport->_netio->stats;
1213  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of heartbeats:", nano_hbstats.heartbeat_count);
1214  g_info("%-35s %8d", "Count of deadtimes:", nano_hbstats.dead_count);
1215  g_info("%-35s %8d", "Count of warntimes:", nano_hbstats.warntime_count);
1216  g_info("%-35s %8d", "Count of comealives:", nano_hbstats.comealive_count);
1217  g_info("%-35s %8d", "Count of martians:", nano_hbstats.martian_count);
1218  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of LLDP/CDP pkts sent:", swdisc->baseclass.reportcount);
1219  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of LLDP/CDP pkts received:", swdisc->baseclass.discovercount);
1220  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of recvfrom calls:", ts->recvcalls);
1221  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of pkts read:", ts->pktsread);
1222  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of framesets read:", ts->fsreads);
1223  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of sendto calls:", ts->sendcalls);
1224  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of pkts written:", ts->pktswritten);
1225  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of framesets written:", ts->fswritten);
1226  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of reliable framesets sent:", ts->reliablesends);
1227  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of reliable framesets recvd:", ts->reliablereads);
1228  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of ACKs sent:", ts->ackssent);
1229  g_info("%-35s %8"G_GINT64_MODIFIER"d", "Count of ACKs recvd:", ts->acksrecvd);
1230  }
1233  UNREF2(swdisc);
1234  UNREF2(arpdisc);
1235  if (nanofailreportaddr) {
1236  UNREF(nanofailreportaddr);
1237  }
1238  if (nanotransport) {
1239  g_source_destroy(CASTTOCLASS(GSource, nanotransport));
1240  g_source_unref(CASTTOCLASS(GSource, nanotransport));
1241  nanotransport = NULL;
1242  }
1243  // Free packet decoder
1244  if (decoder) {
1245  UNREF(decoder);
1246  }
1247  obeycollective->baseclass.dissociate(&obeycollective->baseclass);
1248  UNREF2(obeycollective);
1249 }
1250 
1252 WINEXPORT gboolean
1254 {
1255 
1256  if (nano_connected) {
1257  FsProtocol* proto = CASTTOCLASS(ReliableUDP, nanotransport->_netio)->_protocol;
1258  char * sysname;
1259  DEBUGMSG("Sending HBSHUTDOWN to CMA");
1260  sysname = proj_get_sysname();
1262  g_free(sysname); sysname = NULL;
1263  // Initiate connection shutdown.
1264  // This process will wait for all our output to be ACKed.
1265  // It also has an ACK timer, so it won't wait forever...
1266  proto->closeall(proto);
1267  idle_shutdown_gsource = g_idle_add(shutdown_when_outdone, NULL);
1268  nano_shutting_down = TRUE;
1269  // Unregister all discovery modules. Keep us from starting any new ones...
1271  // Let's not start any more resource operations either...
1272  if (RscQ) {
1273  RscQ->cancelall(RscQ);
1274  UNREF(RscQ);
1275  }
1276  // @TODO We need to ignore additional requests during shutdown as well...
1277  }else{
1278  nano_shutting_down = TRUE;
1279  g_warning("%s: Never connected to CMA - cannot send shutdown message.", procname);
1280  ++errcount; // Trigger non-zero exit code...
1281  _nano_final_shutdown(NULL);
1282  return TRUE;
1283  }
1284  return FALSE;
1285 }
1286 
1288 FSTATIC gboolean
1289 shutdown_when_outdone(gpointer unused)
1290 {
1291  ReliableUDP* t = CASTTOCLASS(ReliableUDP, nanotransport->_netio);
1293  (void)unused;
1294  // Wait for all our connections to be shut down
1295  if (proto->activeconncount(proto) == 0){
1296  DEBUGMSG("%s.%d: Shutting down - all connections closed."
1297  , __FUNCTION__, __LINE__);
1298  g_main_quit(mainloop);
1299  return FALSE;
1300  }
1301  return TRUE;
1302 }
1303 // Final Shutdown -- a contingency timer to make sure we eventually shut down
1304 FSTATIC gboolean
1305 _nano_final_shutdown(gpointer unused)
1306 {
1307  (void)unused;
1308  DEBUGMSG("Initiating final shutdown");
1309  if (nano_connected && nanotransport->_netio->outputpending(nanotransport->_netio)){
1310  g_warning("Shutting down with unACKed output.");
1311  DUMP("Transport info", &nanotransport->_netio->baseclass, NULL);
1312  }
1313  if (idle_shutdown_gsource) {
1314  g_source_remove(idle_shutdown_gsource);
1315  idle_shutdown_gsource = 0;
1316  }
1317  g_main_quit(mainloop);
1318  return FALSE;
1319 }
FSTATIC void _nano_send_rscexitstatus(ConfigContext *request, gpointer user_data, enum HowDied reason, int rc, int signal, gboolean core_dumped, const char *stringresult)
Callback that gets called when a resource operation sends back status.
guint64 recvcalls
How many recvfrom calls have we done?
Definition: netio.h:42
ConfigContext * configcontext_new_JSON_string(const char *jsontext)
Construct a ConfigContext object from the given JSON string.
Listener baseclass
Definition: authlistener.h:42
#define FRAMESETTYPE_HBDEAD
System named in packet appears to be dead.
Definition: framesettypes.h:39
#define CONFIGNAME_CMADISCOVER
Address of where to send discovery reports.
#define CONFIGNAME_INTERVAL
How long to wait between events.
Frame baseclass
Definition: ipportframe.h:41
#define FRAMESETTYPE_STOPRSCOP
Stop a (possibly-repeating) JSON resource action.
Definition: framesettypes.h:59
#define CONFIG_DEFAULT_WARNTIME
Default warning time.
This is the base HbSender class. object - which sends heartbeats to particular listeners.
Definition: hbsender.h:39
guint32 length
Frame Length.
Definition: frame.h:46
FSTATIC void nanoobey_dorscoperation(AuthListener *, FrameSet *, NetAddr *)
guint64 discovercount
How many times have we discovered something.
Definition: discovery.h:57
#define CONFIGNAME_SWPROTOS
List of switch protocols as an array of strings.
const char *(* getstring)(const ConfigContext *, const char *name)
Get String value.
Definition: configcontext.h:86
FSTATIC void _real_warntime_agent(HbListener *who, guint64 howlate)
Standard nanoprobe 'warntime elapsed' agent - called when a heartbeat arrives after 'warntime' but be...
FSTATIC gboolean nano_startupidle(gpointer gcruft)
Nanoprobe bootstrap routine.
#define DEBUGMSG1(...)
Definition: proj_classes.h:89
FSTATIC void nanoobey_startdiscover(AuthListener *, FrameSet *, NetAddr *)
Act on (obey) a FrameSet class telling us to perform a possibly repeating discovery action...
#define FRAMESETTYPE_HBMARTIAN
System named in packet appears gave unexpected heartbeat.
Definition: framesettypes.h:43
#define FRAMESETTYPE_HBSHUTDOWN
System originating packet has shut down.
Definition: framesettypes.h:40
Defines miscellaneous interfaces.
Stuff we need only for passing parameters through our glib infrastructures - to start up nanoprobes...
#define FRAMETYPE_ELAPSEDTIME
FRAMETYPE_ELAPSEDTIME Frame (frametype 23) Frame subclass - IntFrame class.
Definition: frametypes.h:350
guint64 ackssent
How many ACKs have we sent?
Definition: netio.h:50
void discovery_unregister_all(void)
Unregister all discovery methods in preparation for shutting down - to make valgrind happy :-D...
Definition: discovery.c:200
double(* getdouble)(const ConfigContext *, const char *name)
Get double value.
Definition: configcontext.h:80
char * proj_get_sysname(void)
Return a malloced string of the system name.
This is an IntFrame class TLV (type, length, value) frame - representing an integer of some specified...
Definition: intframe.h:39
gboolean outputpending(NetIO *self)
< return TRUE if this object has output pending
Structure associating FrameSet class types with actions to perform when they're received.
Definition: authlistener.h:50
NetIO * _netio
netio this object is based on
Definition: netgsource.h:50
#define FRAMESETTYPE_STOPSENDHB
Stop sending Heartbeats to these addresses.
Definition: framesettypes.h:50
NetAddr * destaddr
PacketDecoder * nano_packet_decoder(void)
Return our nanoprobe packet decoder map.
int(* activeconncount)(FsProtocol *)
How many active connections do we have?
Definition: fsprotocol.h:122
#define CONFIGNAME_CMAPORT
Default Port for contacting the CMA.
void(* addalias)(NetIO *, NetAddr *, NetAddr *)
Add an alias to our received address alias table.
Definition: netio.h:88
#define FRAMESETTYPE_HEARTBEAT
A heartbeat packet.
Definition: framesettypes.h:32
NetIOudp is a NetIOudp class subclass specialized to provide reliable UDP connections.
Definition: reliableudp.h:43
FSTATIC void nanoobey_cancelrscoperation(AuthListener *, FrameSet *, NetAddr *)
#define DEBUGMSG(...)
Definition: proj_classes.h:87
WINEXPORT GMainLoop * mainloop
#define FRAMETYPE_JSDISCOVER
FRAMETYPE_JSDISCOVER Frame (frametype 19) Frame subclass - CstringFrame class.
Definition: frametypes.h:302
HbSender * hbsender_new(NetAddr *sendaddr, NetGSource *outmethod, guint interval, gsize objsize)
Construct a new HbSender - setting up timeout data structures for it.
Definition: hbsender.c:127
Implements minimal client-oriented Frame and Frameset capabilities.
#define FRAMETYPE_HBWARNTIME
FRAMETYPE_HBWARNTIME Frame (frametype 16) Frame subclass - IntFrame class.
Definition: frametypes.h:277
ObeyFrameSetTypeMap collective_obeylist[]
The set of Collective Management Authority FrameTypes we know about, and what to do when we get them...
WINEXPORT IpPortFrame * ipportframe_netaddr_new(guint16 frame_type, NetAddr *addr)
Construct and initialize an IpPortFrame class from a IP NetAddr class.
Definition: ipportframe.c:234
const char * procname
process name
This is the base Frame class object (in-memory TLV (type, length, value)) for every general component...
Definition: frame.h:43
FSTATIC gboolean _nano_final_shutdown(gpointer unused)
IntFrame * intframe_new(guint16 frametype, int intbytes)
Construct new IntFrame object.
Definition: intframe.c:181
FSTATIC void nano_stop_discovery(const char *discoveryname, NetGSource *, NetAddr *)
void(* nanoprobe_deadtime_agent)(HbListener *)
#define FRAMESETTYPE_STOPEXPECTHB
Stop expecting (listening for) Heartbeats from these addresses.
Definition: framesettypes.h:51
NetAddr * listenaddr
What address are we listening for?
Definition: hblistener.h:62
guint64 reliablesends
How many reliable FrameSets have we sent?
Definition: netio.h:48
Describes interfaces to C-String Frame (Cstringframe) C-Class It holds conventional zero-terminated b...
AssimObj baseclass
Definition: netaddr.h:44
WINEXPORT void nano_start_full(const char *initdiscoverpath, guint discover_interval, NetGSource *io, ConfigContext *config)
Here is how the startup process works:
FrameSet * frameset_new(guint16 frameset_type)
Construct a new frameset of the given type.
Definition: frameset.c:110
FSTATIC void hblistener_set_martian_callback(void(*callback)(NetAddr *who))
Call to set a callback to be called when an unrecognized node sends us a heartbeat.
Definition: hblistener.c:362
void(* nanoprobe_warntime_agent)(HbListener *, guint64 howlate)
void(* setbool)(ConfigContext *, const char *name, gboolean)
Set bool value.
Definition: configcontext.h:78
#define FRAMESETTYPE_STOPSENDEXPECTHB
Stop sending Heartbeats to these addresses, and stop expecting them as well.
Definition: framesettypes.h:52
class defining object discovered by invoking commands that return JSON as their output.
void(* cancelall)(ResourceQueue *self)
Definition: resourcequeue.h:61
Simple libpcap interface definitions.
void(* setconfig)(ConfigContext *, const char *, ConfigContext *)
Set ConfigContext value.
Definition: configcontext.h:96
ArpDiscovery * arpdiscovery_new(ConfigContext *arpconfig, gint priority, GMainContext *mcontext, NetGSource *iosrc, ConfigContext *config, gsize objsize)
ArpDiscovery constructor - good for listening to ARP packets via pcap.
Definition: arpdiscovery.c:267
FSTATIC void hblistener_shutdown(void)
Shuts down all our hblisteners...
Definition: hblistener.c:200
#define WINEXPORT
Definition: projectcommon.h:45
#define FSTATIC
Definition: projectcommon.h:31
#define DEBUGMSG3(...)
Definition: proj_classes.h:91
#define FRAMETYPE_HOSTNAME
FRAMETYPE_HOSTNAME Frame (frametype 9) Frame subclass - CstringFrame class.
Definition: frametypes.h:186
gpointer value
Frame Value (pointer)
Definition: frame.h:47
FSTATIC void nanoobey_stopdiscover(AuthListener *, FrameSet *, NetAddr *)
Act on (obey) a FrameSet class telling us to stop a repeating discovery action.
enum ConfigValType(* gettype)(const ConfigContext *, const char *)
Return type.
Definition: configcontext.h:99
SwitchDiscovery C-class - for discovering switch and port configuration via LLDP, CDP and similar pro...
guint32 compression_threshold
Definition: compressframe.h:43
#define FRAMETYPE_HBINTERVAL
FRAMETYPE_HBINTERVAL Frame (frametype 14) Frame subclass - IntFrame class.
Definition: frametypes.h:251
#define CONFIG_DEFAULT_HBTIME
Default heartbeat interval.
#define FRAMETYPE_CONFIGJSON
FRAMETYPE_CONFIGJSON Frame (frametype 20) Frame subclass - CstringFrame class.
Definition: frametypes.h:313
gint64(* getint)(const ConfigContext *, const char *name)
Get integer value.
Definition: configcontext.h:74
int signal
Definition: childprocess.c:238
#define FRAMETYPEMAP
Definition: frametypes.h:415
guint64 heartbeat_count
Definition: nanoprobe.h:33
guint16 fstype
Type of frameset.
Definition: frameset.h:51
PacketDecoder * packetdecoder_new(guint objsize, const FrameTypeToFrame *framemap, gint mapsize)
Initialize our frame type map.
Definition: packetdecoder.c:76
FSTATIC gboolean nano_reqconfig(gpointer gcruft)
Function to request our initial configuration data This is typically called from a g_main_loop timeou...
void(* nanoprobe_heartbeat_agent)(HbListener *)
FSTATIC void nanoobey_decrdebug(AuthListener *, FrameSet *, NetAddr *)
Act on (obey) a FrameSet class telling us to decrement debug levels either on a specific set of class...
void proj_class_decr_debug(const char *Cclass)
Decrement debug level for this class and all its subclasses by one.
Definition: proj_classes.c:148
gboolean nano_shutting_down
void hbsender_stopallsenders(void)
Definition: hbsender.c:182
void(* setaddr)(ConfigContext *, const char *, NetAddr *)
Set NetAddr value.
Definition: configcontext.h:93
#define BINDDEBUG(Cclass)
BINDDEBUG is for telling the class system where the debug variable for this class is - put it in the ...
Definition: proj_classes.h:82
NetAddr *(* getaddr)(const ConfigContext *, const char *name)
Get NetAddr value.
Definition: configcontext.h:92
FSTATIC void nano_schedule_discovery(const char *name, guint32 interval, const char *json, ConfigContext *, NetGSource *transport, NetAddr *fromaddr)
Schedule a discovery instance, potentially repetitively.
void(* set_deadtime_callback)(HbListener *, void(*)(HbListener *who))
Definition: hblistener.h:51
Implements the IntFrame class - integers in a frame.
void(* set_deadtime)(HbListener *, guint64)
Set deadtime.
Definition: hblistener.h:47
Class for discovering Link-Level (switch) information (using CDP or LLDP or some future analogous pro...
AssimObj baseclass
Definition: configcontext.h:72
void frameset_append_frame(FrameSet *fs, Frame *f)
Append frame to the front of the end of the frame list.
Definition: frameset.c:143
#define __FUNCTION__
void closeconn(NetIO *self, guint16 qid, const NetAddr *destaddr)
< Flush packets in queues to this address
#define CONFIGNAME_WARNTIME
How long w/o heartbeats before whining?
AssimObj baseclass
Definition: netio.h:59
#define FRAMESETTYPE_EXPECTHB
Expect (listen for) Heartbeats from these addresses.
Definition: framesettypes.h:48
Defines Heartbeat Sender interfaces.
#define REQCOREDUMPNAMEFIELD
Definition: resourcecmd.h:79
This is our CompressFrame class object - used for representing a compression method.
Definition: compressframe.h:41
#define FRAMESETTYPE_SENDHB
Send Heartbeats to these addresses.
Definition: framesettypes.h:47
SwitchDiscovery * switchdiscovery_new(ConfigContext *swconfig, gint priority, GMainContext *mcontext, NetGSource *iosrc, ConfigContext *config, gsize objsize)
SwitchDiscovery constructor.
#define FRAMETYPE_DISCJSON
FRAMETYPE_DISCJSON Frame (frametype 26) Frame subclass - CstringFrame class.
Definition: frametypes.h:388
Describes interfaces to C-String Frame (Cstringframe) C-Class It holds conventional zero-terminated b...
#define CONFIGNAME_TIMEOUT
How before declaring a serious problem...
Implements the Reliable UDP network I/O transport (ReliableUDP) class.
#define DUMP3(prefix, obj, suffix)
Definition: proj_classes.h:97
#define REQSIGNALNAMEFIELD
Definition: resourcecmd.h:78
WINEXPORT int errcount
error count
FSTATIC gboolean shutdown_when_outdone(gpointer unused)
Shut down everything when output is all ACKed - this is idle loop code.
#define FRAMETYPE_IPPORT
FRAMETYPE_IPPORT Frame (frametype 13) Frame subclass - IpPortFrame class.
Definition: frametypes.h:238
Header file defining all known FrameSet types THIS FILE MECHANICALLY GENERATED by "/home/alanr/assim/...
void(* set_comealive_callback)(HbListener *, void(*)(HbListener *who, guint64 howlate))
Definition: hblistener.h:53
#define FRAMESETTYPE_DODISCOVER
Perform (repeating) JSON discovery action.
Definition: framesettypes.h:56
This is the AuthListener class. object - which (authorizes and) obeys packets from the Authority...
Definition: authlistener.h:41
JsonDiscovery * jsondiscovery_new(const char *discoverytype, const char *instancename, gint intervalsecs, ConfigContext *jsoninst, NetGSource *iosource, ConfigContext *context, gsize objsize)
JsonDiscovery constructor.
#define FRAMETYPE_RSCJSON
FRAMETYPE_RSCJSON Frame (frametype 27) Frame subclass - CstringFrame class.
Definition: frametypes.h:400
Describes interfaces to C-String Frame (Compressframe) C-Class It holds conventional zero-terminated ...
#define CONFIGNAME_DEVNAME
Name of NIC for discovery.
FSTATIC void nanoobey_sendexpecthb(AuthListener *, FrameSet *fs, NetAddr *)
Act on (obey) a FRAMESETTYPE_SENDEXPECTHB FrameSet class.
#define FMT_64BIT
Format designator for a 64 bit integer.
Definition: projectcommon.h:32
FSTATIC void nanoobey_change_debug(gint plusminus, AuthListener *, FrameSet *, NetAddr *)
Act on (obey) a FrameSet class telling us to increment or decrement debug levels either on a specific...
#define REF(obj)
Definition: assimobj.h:39
const char * initdiscover
#define REQREASONENUMNAMEFIELD
Definition: resourcecmd.h:76
FsProtocol * _protocol
Queuing, ordering, retransmission and ACKing discipline.
Definition: reliableudp.h:45
Data structure defining the mapping between frametype integers and corresponding demarshalling module...
Definition: packetdecoder.h:37
FSTATIC void nanoobey_stopsendexpecthb(AuthListener *, FrameSet *fs, NetAddr *)
Act on (obey) a FrameSet class telling us to stop sending and expecting heartbeats.
#define FRAMESETTYPE_INCRDEBUG
Increment debug for some or all classes.
Definition: framesettypes.h:54
NetIOstats stats
Net I/O stats.
Definition: netio.h:60
WINEXPORT gint64 g_get_monotonic_time(void)
Local replacement for g_get_monotonic_time() - for old releases of glib.
guint64 reliablereads
How many reliable FrameSets have we read?
Definition: netio.h:49
include file defining functions to be called by a main to instantiate a nanoprobe.
#define CONFIG_DEFAULT_DEADTIME
Default "deadtime".
#define FRAMETYPE_CSTRINGVAL
FRAMETYPE_CSTRINGVAL Frame (frametype 21) Frame subclass - CstringFrame class.
Definition: frametypes.h:324
FSTATIC void nanoobey_stopexpecthb(AuthListener *, FrameSet *fs, NetAddr *)
Act on (obey) a FrameSet class telling us to stop expecting heartbeats.
void(* nanoprobe_comealive_agent)(HbListener *, guint64 howlate)
FSTATIC void _real_comealive_agent(HbListener *who, guint64 howlate)
Standard nanoprobe 'returned-from-the-dead' agent - called when a heartbeats arrive after 'deadtime'...
gboolean(* getbool)(const ConfigContext *, const char *name)
Get boolean value.
Definition: configcontext.h:77
This is the base HbListener class. object - which listens for heartbeats from a particular sender...
Definition: hblistener.h:44
GSList *(* keys)(const ConfigContext *)
Return list of keys.
This is our CstringFrame class object - used for holding C-style NULL terminated strings.
Definition: cstringframe.h:36
Listener baseclass
Definition: hblistener.h:45
gboolean(* cancel)(ResourceQueue *self, ConfigContext *request)
Definition: resourcequeue.h:59
Project common header file.
#define DIMOF(a)
Definition: lldp_min.c:30
Header file defining the data layouts for our Frames.
JsonDiscovery abstract C-class - it supports discovering "things" through running commands outputting...
Definition: jsondiscovery.h:37
NetGSource * transport
Definition: listener.h:44
#define FRAMESETTYPE_HBBACKALIVE
System named in packet sent heartbeat after being marked dead.
Definition: framesettypes.h:42
FSTATIC void nanoobey_stopsendhb(AuthListener *, FrameSet *fs, NetAddr *)
Act on (obey) a FrameSet class telling us to stop sending heartbeats.
void(* setdouble)(ConfigContext *, const char *name, double value)
Definition: configcontext.h:81
#define FRAMETYPE_DISCNAME
FRAMETYPE_DISCNAME Frame (frametype 24) Frame subclass - CstringFrame class.
Definition: frametypes.h:362
WINEXPORT gboolean nano_initiate_shutdown(void)
Initiate shutdown - return TRUE if we have shut down immediately...
Implements Configuration Context class.
WINEXPORT NanoHbStats nano_hbstats
guint64 acksrecvd
How many ACKs have we received?
Definition: netio.h:51
NetGSource * iosource
void(* setint)(ConfigContext *, const char *name, gint value)
Set integer value.
Definition: configcontext.h:75
#define CONFIGNAME_COMPRESS
Frame to use for compressing/decompressing.
HbListener * hblistener_new(NetAddr *listenaddr, ConfigContext *cfg, gsize objsize)
Construct a new HbListener - setting up GSource and timeout data structures for it.
Definition: hblistener.c:237
void(* setstring)(ConfigContext *, const char *name, const char *value)
Definition: configcontext.h:87
void(* set_heartbeat_callback)(HbListener *, void(*)(HbListener *who))
Definition: hblistener.h:50
FSTATIC void discovery_unregister(const char *instance)
Definition: discovery.c:190
#define FRAMETYPE_DISCINTERVAL
FRAMETYPE_DISCINTERVAL Frame (frametype 25) Frame subclass - IntFrame class.
Definition: frametypes.h:375
void proj_class_incr_debug(const char *Cclass)
Increment debug level for this class and all its subclasses by one.
Definition: proj_classes.c:140
ConfigContext * config
Definition: listener.h:43
Class for discovering address resolution (IP to MAC address information) using the ARP protocol...
ConfigValType
Definition: configcontext.h:44
gboolean sendareliablefs(NetIO *self, NetAddr *dest, guint16 queueid, FrameSet *frameset)
[out] source address of return result
guint64 sendcalls
How many sendto calls have we done?
Definition: netio.h:45
void(* addListener)(NetGSource *, guint16, Listener *)
Register a new listener.
Definition: netgsource.h:55
void hbsender_stopsend(NetAddr *sendaddr)
Stop sending heartbeats to a particular address.
Definition: hbsender.c:162
#define FRAMESETTYPE_SETCONFIG
Initial configuration packet.
Definition: framesettypes.h:53
FSTATIC HbListener * _real_hblistener_new(NetAddr *, ConfigContext *)
Default HbListener constructor.
FSTATIC void frame_default_valuefinalize(gpointer value)
Finalize a Frame.
Definition: frame.c:56
FSTATIC void nanoobey_incrdebug(AuthListener *, FrameSet *, NetAddr *)
Act on (obey) a FrameSet class telling us to increment debug levels either on a specific set of class...
#define FRAMESETTYPE_DECRDEBUG
Increment debug for some or all classes.
Definition: framesettypes.h:55
FSTATIC void nanoobey_expecthb(AuthListener *, FrameSet *fs, NetAddr *)
Act on (obey) a FrameSet class telling us to expect heartbeats.
guint16 type
Frame Type (see Individual TLV 'Frame' data types and layouts (by TLV type) - frameformats.h )
Definition: frame.h:45
guint64 reportcount
How many times have we reported anything new upstream.
Definition: discovery.h:55
#define FRAMESETTYPE_HBLATE
System named in packet sent a late heartbeat.
Definition: framesettypes.h:41
guint64 fswritten
How many FrameSet class were successfully written?
Definition: netio.h:47
gboolean nano_connected
GSList * framelist
List of frames in this FrameSet.
Definition: frameset.h:47
The NetAddr class class represents a general network address - whether IP, MAC, or any other type of ...
Definition: netaddr.h:43
#define CONFIGNAME_CMAADDR
Address of the Collective Management authority.
#define FRAMETYPE_HBDEADTIME
FRAMETYPE_HBDEADTIME Frame (frametype 15) Frame subclass - IntFrame class.
Definition: frametypes.h:264
void nanoprobe_report_upstream(guint16 reporttype, NetAddr *who, const char *systemnm, guint64 howlate)
Construct a frameset reporting something - and send it upstream.
AuthListener * authlistener_new(gsize objsize, ObeyFrameSetTypeMap *map, ConfigContext *config, gboolean autoack)
Construct a new Listener - setting up GSource and timeout data structures for it. ...
Definition: authlistener.c:123
Describes interfaces to Address Frame (AddrFrame) C-Class.
Frame baseclass
base Frame class object
Definition: intframe.h:40
Describes interfaces to Address Frame (IpPortFrame) C-Class.
ResourceQueue * resourcequeue_new(guint structsize)
Construct a new ResourceQueue system (you probably only need one)
Definition: resourcequeue.c:80
HowDied
Definition: childprocess.h:35
#define REQIDENTIFIERNAMEFIELD
Definition: resourcecmd.h:75
#define DUMP(prefix, obj, suffix)
Definition: proj_classes.h:94
void(* setint)(IntFrame *self, guint64 value)
set the integer to the given value
Definition: intframe.h:43
#define FRAMESETTYPE_STOPDISCOVER
Stop a repeating JSON discovery action.
Definition: framesettypes.h:57
FSTATIC void _real_deadtime_agent(HbListener *who)
Standard nanoprobe 'deadtime elapsed' agent.
#define g_info(...)
Definition: projectcommon.h:66
void(* sendaframeset)(NetGSource *, const NetAddr *, FrameSet *)
Send a single frameset.
Definition: netgsource.h:53
#define DEFAULT_FSP_QID
Default Queue ID.
Definition: fsprotocol.h:125
#define CONFIGNAME_INSTANCE
Instance name for discovery.
Frame *(* getframe)(const ConfigContext *, const char *)
Get Frame value.
Definition: configcontext.h:90
guint dead_count
Definition: nanoprobe.h:34
ConfigContext *(* getconfig)(const ConfigContext *, const char *name)
Get ConfigContext value.
Definition: configcontext.h:95
guint64 pktsread
How many packets have been successfully read?
Definition: netio.h:43
#define CONFIGNAME_CPRS_THRESH
Threshold for compressing (integer)
FrameSet class - used for collecting Frames when not on the wire, and for marshalling/demarshalling t...
Definition: frameset.h:45
gchar *(* toString)(gconstpointer)
Produce malloc-ed string representation.
Definition: assimobj.h:58
void(* closeall)(FsProtocol *)
Close all our connections.
Definition: fsprotocol.h:121
guint comealive_count
Definition: nanoprobe.h:36
Implements the resource queue class.
#define FRAMESETTYPE_SENDEXPECTHB
Send Heartbeats to these addresses, and expect them as well.
Definition: framesettypes.h:49
WINEXPORT void nano_shutdown(gboolean report)
Shut down the things started up by nano_start_full() - mainly free storage to make valgrind happy...
#define FRAMETYPE_RSCJSONREPLY
FRAMETYPE_RSCJSONREPLY Frame (frametype 28) Frame subclass - CstringFrame class.
Definition: frametypes.h:412
Implements NetIO GSource object.
#define FRAMESETTYPE_STARTUP
System originating packet looking for heartbeat configuration.
Definition: framesettypes.h:38
void(* dissociate)(Listener *self)
Dissociate us from our source.
Definition: listener.h:51
#define DEBUGDECLARATIONS
Definition: proj_classes.h:79
NetAddr *(* getnetaddr)(IpPortFrame *f)
Definition: ipportframe.h:45
FSTATIC void hblistener_unlisten(NetAddr *unlistenaddr)
Stop expecting (listening for) heartbeats from a particular address.
Definition: hblistener.c:322
#define CONFIGNAME_CMAFAIL
Address of where to send failure reports.
#define CONFIGNAME_CMAINIT
Initial startup contact address for the CMA.
void(* set_warntime)(HbListener *, guint64)
Set warntime.
Definition: hblistener.h:49
Implements the resource command abstract class.
Implements the SeqnoFrame class.
void(* associate)(Listener *self, NetGSource *source)
NetGSource class to associate with
Definition: listener.h:49
ArpDiscovery C-class - for discovering IP/MAC address resolution via the ARP protocol captured using ...
Definition: arpdiscovery.h:36
Defines Listener interfaces for packets coming from the Collective Authority.
ConfigContext * configcontext_new(gsize objsize)
Construct a new ConfigContext object - with no values defaulted.
guint martian_count
Definition: nanoprobe.h:37
#define MARTIAN_TIMEOUT
Definition: nanoprobe.h:64
void(* setvalue)(Frame *self, gpointer value, guint32 length, GDestroyNotify valfinal)
member function for setting value
Definition: frame.h:52
guint64(* getint)(IntFrame *self)
get value of integer in this IntFrame
Definition: intframe.h:42
NetAddr * netaddr_string_new(const char *addrstr)
Create a NetAddr from an ipv4, ipv6 or MAC address string.
Definition: netaddr.c:915
gboolean(* Qcmd)(ResourceQueue *self, ConfigContext *request, ResourceCmdCallback callback, gpointer user_data)
Definition: resourcequeue.h:55
FSTATIC void nanoobey_setconfig(AuthListener *, FrameSet *fs, NetAddr *)
This file defines a few functions and interfaces for unmarshalling packet data into FrameSets...
Describes interfaces to name/value pair Frame (NVpairFrame) C-Class It holds conventional zero-termin...
#define UNREF2(obj)
Definition: assimobj.h:36
void(* set_warntime_callback)(HbListener *, void(*)(HbListener *who, guint64 howlate))
Definition: hblistener.h:52
#define CASTTOCLASS(Cclass, obj)
Safely cast 'obj' to C-class 'class' - verifying that it was registerd as being of type class ...
Definition: proj_classes.h:66
#define UNREF(obj)
Definition: assimobj.h:35
guint64 fsreads
How many FrameSet class were successfully read?
Definition: netio.h:44
This is a basic NetIO class abstract class for doing network I/O.
Definition: netio.h:58
#define FRAMESETTYPE_RSCOPREPLY
Packet contains return result from a resource operation.
Definition: framesettypes.h:46
#define REQSTRINGRETNAMEFIELD
Definition: resourcecmd.h:80
Implements the FsProtocol object.
#define REQRCNAMEFIELD
Definition: resourcecmd.h:77
#define FRAMESETTYPE_DORSCOP
Do a (possibly-repeating) JSON resource action.
Definition: framesettypes.h:58
The NetGSource class objects integrate NetIO class objects into the g_main_loop paradigm.
Definition: netgsource.h:43
guint warntime_count
Definition: nanoprobe.h:35
FSTATIC void _real_martian_agent(NetAddr *who)
Standard nanoprobe 'martian heartbeat received' agent.
ReliableUDP * transport
Definition: pinger.c:67
FSTATIC void _real_heartbeat_agent(HbListener *who)
Standard nanoprobe 'hearbeat received' agent.
WINEXPORT CstringFrame * cstringframe_new(guint16 frame_type, gsize framesize)
Construct a new CstringFrame - allowing for "derived" frame types...
Definition: cstringframe.c:101
This is an FsProtocol class object - implementing a reliable user-level FrameSet class delivery syste...
Definition: fsprotocol.h:99
FSTATIC void nanoobey_sendhb(AuthListener *, FrameSet *fs, NetAddr *)
Act on (obey) a FrameSet class telling us to send heartbeats.
Defines Heartbeat Listener interfaces.
guint64 pktswritten
How many packets have been successfully written?
Definition: netio.h:46