Browse Source

Added communication version numbers to PStats

David Rose 24 years ago
parent
commit
21be6a20e2

+ 1 - 0
panda/src/pstatclient/Sources.pp

@@ -24,6 +24,7 @@
     config_pstats.h pStatClient.I pStatClient.h \
     pStatClientControlMessage.h pStatCollector.I pStatCollector.h \
     pStatCollectorDef.h pStatFrameData.I pStatFrameData.h \
+    pStatProperties.h \
     pStatServerControlMessage.h pStatThread.I pStatThread.h \
     pStatTimer.I pStatTimer.h
 

+ 2 - 0
panda/src/pstatclient/pStatClient.cxx

@@ -709,6 +709,8 @@ send_hello() {
   message._type = PStatClientControlMessage::T_hello;
   message._client_hostname = get_hostname();
   message._client_progname = _client_name;
+  message._major_version = get_current_pstat_major_version();
+  message._minor_version = get_current_pstat_minor_version();
 
   Datagram datagram;
   message.encode(datagram);

+ 9 - 0
panda/src/pstatclient/pStatClientControlMessage.cxx

@@ -32,6 +32,8 @@ encode(Datagram &datagram) const {
   case T_hello:
     datagram.add_string(_client_hostname);
     datagram.add_string(_client_progname);
+    datagram.add_uint16(_major_version);
+    datagram.add_uint16(_minor_version);
     break;
 
   case T_define_collectors:
@@ -74,6 +76,13 @@ decode(const Datagram &datagram) {
   case T_hello:
     _client_hostname = source.get_string();
     _client_progname = source.get_string();
+    if (source.get_remaining_size() == 0) {
+      _major_version = 1;
+      _minor_version = 0;
+    } else {
+      _major_version = source.get_uint16();
+      _minor_version = source.get_uint16();
+    }
     break;
 
   case T_define_collectors:

+ 2 - 0
panda/src/pstatclient/pStatClientControlMessage.h

@@ -39,6 +39,8 @@ public:
   // Used for T_hello
   string _client_hostname;
   string _client_progname;
+  int _major_version;
+  int _minor_version;
 
   // Used for T_define_collectors
   vector<PStatCollectorDef *> _collectors;

+ 1 - 0
panda/src/pstatclient/pStatFrameData.cxx

@@ -55,5 +55,6 @@ read_datagram(DatagramIterator &source) {
     dp._value = source.get_float32();
     _level_data.push_back(dp);
   }
+  nassertv(source.get_remaining_size() == 0);
 }
 

+ 34 - 4
panda/src/pstatclient/pStatProperties.cxx

@@ -7,13 +7,44 @@
 #include "pStatCollectorDef.h"
 #include "pStatClient.h"
 
+////////////////////////////////////////////////////////////////////
+//     Function: get_current_pstat_major_version
+//  Description: Returns the current major version number of the
+//               PStats protocol.  This is the version number that
+//               will be reported by clients running this code, and
+//               that will be expected by servers running this code.
+//
+//               The major version numbers must match exactly in order
+//               for a communication to be successful.
+////////////////////////////////////////////////////////////////////
+int
+get_current_pstat_major_version() {
+  return 2;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: get_current_pstat_minor_version
+//  Description: Returns the current minor version number of the
+//               PStats protocol.  This is the version number that
+//               will be reported by clients running this code, and
+//               that will be expected by servers running this code.
+//
+//               The minor version numbers need not match exactly, but
+//               the server must be >= the client.
+////////////////////////////////////////////////////////////////////
+int
+get_current_pstat_minor_version() {
+  return 0;
+}
+
+
 #ifdef DO_PSTATS
 
 ////////////////////////////////////////////////////////////////////
 //
-// This file defines the predefined properties (color, sort, etc.) for
-// the various PStatCollectors that may be defined within Panda or
-// even elsewhere.
+// The rest of this file defines the predefined properties (color,
+// sort, etc.) for the various PStatCollectors that may be defined
+// within Panda or even elsewhere.
 //
 // It is a little strange to defined these properties here instead of
 // where the collectors are actually declared, but it's handy to have
@@ -137,5 +168,4 @@ initialize_collector_def(PStatClient *client, PStatCollectorDef *def) {
   }
 }
 
-
 #endif // DO_PSTATS

+ 4 - 2
panda/src/pstatclient/pStatProperties.h

@@ -8,13 +8,15 @@
 
 #include <pandabase.h>
 
-#ifdef DO_PSTATS
 
 class PStatClient;
 class PStatCollectorDef;
 
-void initialize_collector_def(PStatClient *client, PStatCollectorDef *def);
+EXPCL_PANDA int get_current_pstat_major_version();
+EXPCL_PANDA int get_current_pstat_minor_version();
 
+#ifdef DO_PSTATS
+void initialize_collector_def(PStatClient *client, PStatCollectorDef *def);
 #endif  // DO_PSTATS
 
 #endif

+ 3 - 1
pandatool/src/gtk-stats/Sources.pp

@@ -14,7 +14,9 @@
     m
 
   #define SOURCES \
-    gtkStats.cxx gtkStats.h gtkStatsGuide.cxx gtkStatsGuide.h \
+    gtkStats.cxx gtkStats.h \
+    gtkStatsBadVersionWindow.cxx gtkStatsBadVersionWindow.h \
+    gtkStatsGuide.cxx gtkStatsGuide.h \
     gtkStatsLabel.cxx gtkStatsLabel.h gtkStatsMainWindow.cxx \
     gtkStatsMainWindow.h gtkStatsMonitor.cxx gtkStatsMonitor.h \
     gtkStatsPianoRoll.I gtkStatsPianoRoll.cxx gtkStatsPianoRoll.h \

+ 60 - 0
pandatool/src/gtk-stats/gtkStatsBadVersionWindow.cxx

@@ -0,0 +1,60 @@
+// Filename: gtkStatsBadVersionWindow.cxx
+// Created by:  drose (18May01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "gtkStatsBadVersionWindow.h"
+#include "gtkStatsMonitor.h"
+
+#include <string_utils.h>
+
+////////////////////////////////////////////////////////////////////
+//     Function: GtkStatsBadVersionWindow::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+GtkStatsBadVersionWindow::
+GtkStatsBadVersionWindow(GtkStatsMonitor *monitor,
+                         int client_major, int client_minor,
+                         int server_major, int server_minor) {
+  set_title("Bad client");
+
+  Gtk::VBox *box1 = new Gtk::VBox;
+  box1->show();
+  box1->set_border_width(8);
+  add(*manage(box1));
+
+  string message = 
+    "Rejected connection by " +
+    monitor->get_client_progname() + " from " + 
+    monitor->get_client_hostname() + ".\nClient uses PStats version " +
+    format_string(client_major) + "." + format_string(client_minor) +
+    ",\nwhile server expects PStats version " +
+    format_string(server_major) + "." + format_string(server_minor) + ".";
+      
+  Gtk::Label *label = new Gtk::Label(message);
+  label->show();
+  box1->pack_start(*manage(label), true, false, 8);
+
+  Gtk::HBox *box2 = new Gtk::HBox;
+  box2->show();
+  box1->pack_start(*manage(box2), false, false, 0);
+
+  Gtk::Button *close = new Gtk::Button("Close");
+  close->set_usize(80, 30);
+  close->show();
+  box2->pack_start(*manage(close), true, false, 0);
+  close->clicked.connect(slot(this, &GtkStatsBadVersionWindow::close_clicked));
+
+  setup();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GtkStatsBadVersionWindow::close_clicked
+//       Access: Private
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void GtkStatsBadVersionWindow::
+close_clicked() {
+  destruct();
+}

+ 32 - 0
pandatool/src/gtk-stats/gtkStatsBadVersionWindow.h

@@ -0,0 +1,32 @@
+// Filename: gtkStatsBadVersionWindow.h
+// Created by:  drose (18May01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#ifndef GTKSTATSBADVERSIONWINDOW_H
+#define GTKSTATSBADVERSIONWINDOW_H
+
+#include <pandatoolbase.h>
+
+#include <basicGtkWindow.h>
+
+class GtkStatsMonitor;
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : GtkStatsBadVersionWindow
+// Description : This window is popped up to indicated an attempted
+//               connection from an invalid client.
+////////////////////////////////////////////////////////////////////
+class GtkStatsBadVersionWindow : public BasicGtkWindow {
+public:
+  GtkStatsBadVersionWindow(GtkStatsMonitor *monitor,
+                           int client_major, int client_minor,
+                           int server_major, int server_minor);
+
+private:
+  void close_clicked();
+};
+
+
+#endif
+

+ 20 - 0
pandatool/src/gtk-stats/gtkStatsMonitor.cxx

@@ -6,6 +6,7 @@
 #include "gtkStatsMonitor.h"
 #include "gtkStatsWindow.h"
 #include "gtkStatsStripWindow.h"
+#include "gtkStatsBadVersionWindow.h"
 
 #include <luse.h>
 #include <pStatCollectorDef.h>
@@ -100,6 +101,25 @@ got_hello() {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GtkStatsMonitor::got_bad_version
+//       Access: Public, Virtual
+//  Description: Like got_hello(), this is called when the "hello"
+//               message has been received from the client.  At this
+//               time, the client's hostname and program name will be
+//               known.  However, the client appears to be an
+//               incompatible version and the connection will be
+//               terminated; the monitor should issue a message to
+//               that effect.
+////////////////////////////////////////////////////////////////////
+void GtkStatsMonitor::
+got_bad_version(int client_major, int client_minor,
+                int server_major, int server_minor) {
+  new GtkStatsBadVersionWindow(this, client_major, client_minor,
+                               server_major, server_minor);
+  close_all_windows();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GtkStatsMonitor::new_collector
 //       Access: Public, Virtual

+ 2 - 0
pandatool/src/gtk-stats/gtkStatsMonitor.h

@@ -32,6 +32,8 @@ public:
 
   virtual void initialized();
   virtual void got_hello();
+  virtual void got_bad_version(int client_major, int client_minor,
+                               int server_major, int server_minor);
   virtual void new_collector(int collector_index);
   virtual void new_data(int thread_index, int frame_number);
   virtual void lost_connection();

+ 35 - 0
pandatool/src/pstatserver/pStatMonitor.cxx

@@ -42,6 +42,26 @@ hello_from(const string &hostname, const string &progname) {
   got_hello();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PStatMonitor::bad_version
+//       Access: Public
+//  Description: Called shortly after startup time with the greeting
+//               from the client.  In this case, the client seems to
+//               have an incompatible version and will be
+//               automatically disconnected; the server should issue a
+//               message to that effect.
+////////////////////////////////////////////////////////////////////
+void PStatMonitor::
+bad_version(const string &hostname, const string &progname,
+            int client_major, int client_minor,
+            int server_major, int server_minor) {
+  _client_known = true;
+  _client_hostname = hostname;
+  _client_progname = progname;
+  got_bad_version(client_major, client_minor,
+                  server_major, server_minor);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PStatMonitor::set_client_data
 //       Access: Public
@@ -192,6 +212,21 @@ void PStatMonitor::
 got_hello() {
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PStatMonitor::got_bad_version
+//       Access: Public, Virtual
+//  Description: Like got_hello(), this is called when the "hello"
+//               message has been received from the client.  At this
+//               time, the client's hostname and program name will be
+//               known.  However, the client appears to be an
+//               incompatible version and the connection will be
+//               terminated; the monitor should issue a message to
+//               that effect.
+////////////////////////////////////////////////////////////////////
+void PStatMonitor::
+got_bad_version(int, int, int, int) {
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PStatMonitor::new_collector
 //       Access: Public, Virtual

+ 5 - 0
pandatool/src/pstatserver/pStatMonitor.h

@@ -38,6 +38,9 @@ public:
   virtual ~PStatMonitor();
 
   void hello_from(const string &hostname, const string &progname);
+  void bad_version(const string &hostname, const string &progname,
+                   int client_major, int client_minor,
+                   int server_major, int server_minor);
   void set_client_data(PStatClientData *client_data);
 
 
@@ -65,6 +68,8 @@ public:
 
   virtual void initialized();
   virtual void got_hello();
+  virtual void got_bad_version(int client_major, int client_minor,
+                               int server_major, int server_minor);
   virtual void new_collector(int collector_index);
   virtual void new_thread(int thread_index);
   virtual void new_data(int thread_index, int frame_number);

+ 16 - 1
pandatool/src/pstatserver/pStatReader.cxx

@@ -10,6 +10,7 @@
 #include <pStatClientControlMessage.h>
 #include <pStatServerControlMessage.h>
 #include <pStatFrameData.h>
+#include <pStatProperties.h>
 #include <datagram.h>
 #include <datagramIterator.h>
 #include <connectionManager.h>
@@ -181,7 +182,21 @@ void PStatReader::
 handle_client_control_message(const PStatClientControlMessage &message) {
   switch (message._type) {
   case PStatClientControlMessage::T_hello:
-    _monitor->hello_from(message._client_hostname, message._client_progname);
+    {
+      int current_major_version = get_current_pstat_major_version();
+      int current_minor_version = get_current_pstat_minor_version();
+
+      if (message._major_version != current_major_version ||
+          (message._major_version == current_major_version &&
+           message._minor_version > current_minor_version)) {
+        _monitor->bad_version(message._client_hostname, message._client_progname,
+                              message._major_version, message._minor_version,
+                              current_major_version, current_minor_version);
+        _monitor->close();
+      } else {
+        _monitor->hello_from(message._client_hostname, message._client_progname);
+      }
+    }
     break;
 
   case PStatClientControlMessage::T_define_collectors: