From 21be6a20e2d77b54dad39188935cd8d6fdbdd626 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 18 May 2001 21:52:30 +0000 Subject: [PATCH] Added communication version numbers to PStats --- panda/src/pstatclient/Sources.pp | 1 + panda/src/pstatclient/pStatClient.cxx | 2 + .../pstatclient/pStatClientControlMessage.cxx | 9 +++ .../pstatclient/pStatClientControlMessage.h | 2 + panda/src/pstatclient/pStatFrameData.cxx | 1 + panda/src/pstatclient/pStatProperties.cxx | 38 ++++++++++-- panda/src/pstatclient/pStatProperties.h | 6 +- pandatool/src/gtk-stats/Sources.pp | 4 +- .../gtk-stats/gtkStatsBadVersionWindow.cxx | 60 +++++++++++++++++++ .../src/gtk-stats/gtkStatsBadVersionWindow.h | 32 ++++++++++ pandatool/src/gtk-stats/gtkStatsMonitor.cxx | 20 +++++++ pandatool/src/gtk-stats/gtkStatsMonitor.h | 2 + pandatool/src/pstatserver/pStatMonitor.cxx | 35 +++++++++++ pandatool/src/pstatserver/pStatMonitor.h | 5 ++ pandatool/src/pstatserver/pStatReader.cxx | 17 +++++- 15 files changed, 226 insertions(+), 8 deletions(-) create mode 100644 pandatool/src/gtk-stats/gtkStatsBadVersionWindow.cxx create mode 100644 pandatool/src/gtk-stats/gtkStatsBadVersionWindow.h diff --git a/panda/src/pstatclient/Sources.pp b/panda/src/pstatclient/Sources.pp index 5aa13848e2..10dfa2fbaf 100644 --- a/panda/src/pstatclient/Sources.pp +++ b/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 diff --git a/panda/src/pstatclient/pStatClient.cxx b/panda/src/pstatclient/pStatClient.cxx index f3fe88a6c0..5c15836a15 100644 --- a/panda/src/pstatclient/pStatClient.cxx +++ b/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); diff --git a/panda/src/pstatclient/pStatClientControlMessage.cxx b/panda/src/pstatclient/pStatClientControlMessage.cxx index b377cbc535..ed9bc94d08 100644 --- a/panda/src/pstatclient/pStatClientControlMessage.cxx +++ b/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: diff --git a/panda/src/pstatclient/pStatClientControlMessage.h b/panda/src/pstatclient/pStatClientControlMessage.h index a208910068..0109d4ca49 100644 --- a/panda/src/pstatclient/pStatClientControlMessage.h +++ b/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 _collectors; diff --git a/panda/src/pstatclient/pStatFrameData.cxx b/panda/src/pstatclient/pStatFrameData.cxx index 0ff8bfc380..fd262b50b1 100644 --- a/panda/src/pstatclient/pStatFrameData.cxx +++ b/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); } diff --git a/panda/src/pstatclient/pStatProperties.cxx b/panda/src/pstatclient/pStatProperties.cxx index 37f54a7ba4..a78f83b227 100644 --- a/panda/src/pstatclient/pStatProperties.cxx +++ b/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 diff --git a/panda/src/pstatclient/pStatProperties.h b/panda/src/pstatclient/pStatProperties.h index 617a7c091e..a6724f0dd2 100644 --- a/panda/src/pstatclient/pStatProperties.h +++ b/panda/src/pstatclient/pStatProperties.h @@ -8,13 +8,15 @@ #include -#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 diff --git a/pandatool/src/gtk-stats/Sources.pp b/pandatool/src/gtk-stats/Sources.pp index d36970a555..cd0114a733 100644 --- a/pandatool/src/gtk-stats/Sources.pp +++ b/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 \ diff --git a/pandatool/src/gtk-stats/gtkStatsBadVersionWindow.cxx b/pandatool/src/gtk-stats/gtkStatsBadVersionWindow.cxx new file mode 100644 index 0000000000..f84b5585a1 --- /dev/null +++ b/pandatool/src/gtk-stats/gtkStatsBadVersionWindow.cxx @@ -0,0 +1,60 @@ +// Filename: gtkStatsBadVersionWindow.cxx +// Created by: drose (18May01) +// +//////////////////////////////////////////////////////////////////// + +#include "gtkStatsBadVersionWindow.h" +#include "gtkStatsMonitor.h" + +#include + +//////////////////////////////////////////////////////////////////// +// 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(); +} diff --git a/pandatool/src/gtk-stats/gtkStatsBadVersionWindow.h b/pandatool/src/gtk-stats/gtkStatsBadVersionWindow.h new file mode 100644 index 0000000000..bbca193106 --- /dev/null +++ b/pandatool/src/gtk-stats/gtkStatsBadVersionWindow.h @@ -0,0 +1,32 @@ +// Filename: gtkStatsBadVersionWindow.h +// Created by: drose (18May01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef GTKSTATSBADVERSIONWINDOW_H +#define GTKSTATSBADVERSIONWINDOW_H + +#include + +#include + +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 + diff --git a/pandatool/src/gtk-stats/gtkStatsMonitor.cxx b/pandatool/src/gtk-stats/gtkStatsMonitor.cxx index e5e46c6144..5302a5002a 100644 --- a/pandatool/src/gtk-stats/gtkStatsMonitor.cxx +++ b/pandatool/src/gtk-stats/gtkStatsMonitor.cxx @@ -6,6 +6,7 @@ #include "gtkStatsMonitor.h" #include "gtkStatsWindow.h" #include "gtkStatsStripWindow.h" +#include "gtkStatsBadVersionWindow.h" #include #include @@ -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 diff --git a/pandatool/src/gtk-stats/gtkStatsMonitor.h b/pandatool/src/gtk-stats/gtkStatsMonitor.h index fc937a6a43..d65e70dd30 100644 --- a/pandatool/src/gtk-stats/gtkStatsMonitor.h +++ b/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(); diff --git a/pandatool/src/pstatserver/pStatMonitor.cxx b/pandatool/src/pstatserver/pStatMonitor.cxx index b5e0115a2c..2a81dc60de 100644 --- a/pandatool/src/pstatserver/pStatMonitor.cxx +++ b/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 diff --git a/pandatool/src/pstatserver/pStatMonitor.h b/pandatool/src/pstatserver/pStatMonitor.h index 4e649e3340..9610ce200a 100644 --- a/pandatool/src/pstatserver/pStatMonitor.h +++ b/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); diff --git a/pandatool/src/pstatserver/pStatReader.cxx b/pandatool/src/pstatserver/pStatReader.cxx index 43d6b39346..63492bd1e6 100644 --- a/pandatool/src/pstatserver/pStatReader.cxx +++ b/pandatool/src/pstatserver/pStatReader.cxx @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -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: