diff options
author | Ben Pfaff <blp@nicira.com> | 2010-05-05 10:31:44 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2010-05-11 11:50:45 -0700 |
commit | 1e3c004749e1e0498dac6240b6edda472718dde2 (patch) | |
tree | 1e23164258304afce1f61f167436b3b4333ce11c /lib/stream.c | |
parent | c088c3be069e991e2d8a3acfdcbb9af278c6d5e5 (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.c | 61 |
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)); + } +} |