Re: [Nagios-devel] NSCA bottleneck / NSCA Timestamp

Support forum for Nagios Core, Nagios Plugins, NCPA, NRPE, NSCA, NDOUtils and more. Engage with the community of users including those using the open source solutions.
Locked
Guest

Re: [Nagios-devel] NSCA bottleneck / NSCA Timestamp

Post by Guest »

Thomas Guyot-Sionnest wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Thomas Guyot-Sionnest wrote:
>> * Or did you have another idea to do this? Tabs are currently allowed in
>> the last field for service checks so the number of separators isn't an
>> option, even when adding two new fields. Perhaps the position of the
>> return code + two new fields, but then a service named "0" trough "3"
>> would mess the thing up.
>
> Oh, I overlooked a bit too much the protocol (I thought the data was
> sent as-it but I believe I actually got confused reading client code
> thinking it was server-side code).
>
> Solution #1:
> Since the server only read sizeof(receive_packet) bytes, we should
> normally be able to add things to the struct without breaking anything
> (older server will just ignore it).
>
> Solution #2:
> Each packet sent have a version number, so we can create new packet
> formats with different version (older servers will discard non-matching
> version). I'm not an expert in network protocols but I guess we should
> do something like this:
>
> typedef struct data_packet_struct{
> int16_t packet_version;
> u_int32_t crc32_value;
> u_int32_t timestamp;
> int16_t return_code;
> uint16_t count; /* bytes of data */
> char payload[MAX_PACKET_SIZE];
> }data_packet;
>
> typedef struct nsca_message_v3_struct{
> int16_t return_code;
> char host_name[MAX_HOSTNAME_LENGTH];
> char svc_description[MAX_DESCRIPTION_LENGTH];
> char plugin_output[MAX_PLUGINOUTPUT_LENGTH];
> }nsca_message_v3;
>

This is bad. Look up modbus for how to write header + body part
messages which allows for near-unlimited protocol extensions.

With this way of doing things, you're limiting yourself to a
definitive size of each host/service. It makes for (a little)
easier coding, but it's a useless limitation to put on people.

A header should (basically) consist of something like this:
struct proto_header {
u_int32_t proto_version;
u_int32_t pkt_type;
u_int32_t body_len;
char pad[DESIRED_HEADER_SIZE - (sizeof(u_int32_t) * 3);
};

where DESIRED_HEADER_SIZE is usually 32 or 64, for alignment purposes.
It's usually desirable to have protocol_version be 32 bits wide as
well, also for alignment reasons (no modern architecture aligns on
2 byte boundaries).

Then you just invent packets as you go along and can handle them all
in a single switch() statement (to decide which function *really*
should take care of them) or, if performance is really critical,
you do it with a list such as this:

---% MAX_PKT_TYPE)
unsupported_packet();

handle_pkt[hdr.pkt_type](packet_body, len);
---%<---%<---%<---

which will incur exactly one branch and one memory lookup per
packet. Note that this is really a micro-optimization though.
For anything but embedded systems, the switch() statement will
almost certainly be a better choice, providing better readability
at the expense of binary footprint size and memory usage.

--
Andreas Ericsson [email protected]
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231





This post was automatically imported from historical nagios-devel mailing list archives
Original poster: [email protected]
Locked