aboutsummaryrefslogtreecommitdiff
path: root/lib/stream.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-05-05 10:31:44 -0700
committerBen Pfaff <blp@nicira.com>2010-05-11 11:50:45 -0700
commit1e3c004749e1e0498dac6240b6edda472718dde2 (patch)
tree1e23164258304afce1f61f167436b3b4333ce11c /lib/stream.c
parentc088c3be069e991e2d8a3acfdcbb9af278c6d5e5 (diff)
Diagnose attempts to connect the wrong protocol to a network port.
Sometimes, when a user asks me to help debug a problem, it turns out that an SSL connection was being made on a TCP port, or vice versa, or that an OpenFlow connection was being made on a JSON-RPC port, or vice versa, and so on. This commit adds log messages that diagnose this kind of problem, e.g. "tcp:127.0.0.1:6633: received JSON-RPC data on OpenFlow channel".
Diffstat (limited to 'lib/stream.c')
-rw-r--r--lib/stream.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/stream.c b/lib/stream.c
index 43b73af0..667a23ff 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -718,5 +718,66 @@ pstream_open_with_default_ports(const char *name_,
return error;
}
+
+/* Attempts to guess the content type of a stream whose first few bytes were
+ * the 'size' bytes of 'data'. */
+static enum stream_content_type
+stream_guess_content(const uint8_t *data, size_t size)
+{
+ if (size >= 2) {
+#define PAIR(A, B) (((A) << 8) | (B))
+ switch (PAIR(data[0], data[1])) {
+ case PAIR(0x16, 0x03): /* Handshake, version 3. */
+ return STREAM_SSL;
+ case PAIR('{', '"'):
+ return STREAM_JSONRPC;
+ case PAIR(OFP_VERSION, OFPT_HELLO):
+ return STREAM_OPENFLOW;
+ }
+ }
+
+ return STREAM_UNKNOWN;
+}
+
+/* Returns a string represenation of 'type'. */
+static const char *
+stream_content_type_to_string(enum stream_content_type type)
+{
+ switch (type) {
+ case STREAM_UNKNOWN:
+ default:
+ return "unknown";
+ case STREAM_JSONRPC:
+ return "JSON-RPC";
+ case STREAM_OPENFLOW:
+ return "OpenFlow";
+
+ case STREAM_SSL:
+ return "SSL";
+ }
+}
+
+/* Attempts to guess the content type of a stream whose first few bytes were
+ * the 'size' bytes of 'data'. If this is done successfully, and the guessed
+ * content type is other than 'expected_type', then log a message in vlog
+ * module 'module', naming 'stream_name' as the source, explaining what
+ * content was expected and what was actually received. */
+void
+stream_report_content(const void *data, size_t size,
+ enum stream_content_type expected_type,
+ enum vlog_module module, const char *stream_name)
+{
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
+ enum stream_content_type actual_type;
+
+ actual_type = stream_guess_content(data, size);
+ if (actual_type != expected_type && actual_type != STREAM_UNKNOWN) {
+ vlog_rate_limit(module, VLL_WARN, &rl,
+ "%s: received %s data on %s channel",
+ stream_name,
+ stream_content_type_to_string(expected_type),
+ stream_content_type_to_string(actual_type));
+ }
+}