diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2020-06-18 21:56:45 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2020-06-18 21:56:45 +0200 |
commit | 9f743e36909ba5509edaacd3f0e0edee625a72f5 (patch) | |
tree | 73e598b8d7d9642ef2503110ad39a8eca122f6c9 | |
parent | 44b764cff8f8bcfd10751760d4e304f0a19398a2 (diff) |
* capture, prettify and print recv/sent bytes
* error and disconnect if server or client have different WINDOW_SIZE's
* removed additional WINDOW_SIZE pre-processor checks which are not required anymore
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | client.c | 8 | ||||
-rw-r--r-- | common-event2.c | 4 | ||||
-rw-r--r-- | protocol.c | 26 | ||||
-rw-r--r-- | protocol.h | 6 | ||||
-rw-r--r-- | server.c | 7 | ||||
-rw-r--r-- | utils.h | 19 |
6 files changed, 56 insertions, 14 deletions
@@ -212,7 +212,15 @@ __attribute__((noreturn)) static void cleanup_and_exit(struct event_base ** cons struct connection ** const state, int exit_code) { + char pretty_bytes_rx[16]; + char pretty_bytes_tx[16]; + LOG(LP_DEBUG, "Cleanup and exit with exit code: %d", exit_code); + if (*state != NULL) { + LOG(NOTICE, "Closed connection; received %s; sent %s", + prettify_bytes_with_units(pretty_bytes_rx, sizeof(pretty_bytes_rx), (*state)->total_bytes_recv), + prettify_bytes_with_units(pretty_bytes_tx, sizeof(pretty_bytes_tx), (*state)->total_bytes_sent)); + } *state = NULL; cleanup(ev_base, ev_sig, my_keypair); exit(exit_code); diff --git a/common-event2.c b/common-event2.c index b0bfe95..bc631e7 100644 --- a/common-event2.c +++ b/common-event2.c @@ -279,6 +279,10 @@ void ev_read_cb(struct bufferevent * bev, void * connection_state) LOG(ERROR, "Crypto error"); ev_disconnect(c); return; + case RECV_FATAL_REMOTE_WINDOW_SIZE: + LOG(ERROR, "Remote has a larger WINDOW_SIZE size than us."); + ev_disconnect(c); + return; case RECV_CORRUPT_PACKET: LOG(ERROR, "Packet Corrupt"); ev_disconnect(c); @@ -214,14 +214,9 @@ static enum recv_return validate_header(struct protocol_header const * const hdr } size = hdr->body_size; - /* following check does not make sense if sizeof(header.body_size) == 2 and WINDOW_SIZE >= (65535*2) */ -#if WINDOW_SIZE < (65535*2) if (size > WINDOW_SIZE) { - return RECV_CORRUPT_PACKET; + return RECV_FATAL_REMOTE_WINDOW_SIZE; } -#elif WINDOW_SIZE > (65535*2) -#error "Remember to change that code part if you've changed the type of header.body_size e.g. to uint32_t" -#endif if (size > buffer_size) { return RECV_BUFFER_NEED_MORE_DATA; } @@ -407,6 +402,7 @@ enum recv_return process_received(struct connection * const state, } } + state->total_bytes_recv += *buffer_size; state->partial_packet_received = 0; *buffer_size = 0; return run_protocol_callback(state, &encrypted, &decrypted, buffer_size); @@ -416,13 +412,17 @@ enum recv_return process_received(struct connection * const state, * PDU send functionality * **************************/ -static void protocol_response(void * const buffer, uint32_t body_and_payload_size, enum header_types type) +static void protocol_response(struct connection * const state, + void * const buffer, uint32_t body_and_payload_size, + enum header_types type) { struct protocol_header * const header = (struct protocol_header *)buffer; header->magic = htonl(PROTOCOL_MAGIC); header->pdu_type = htons((uint16_t)type); header->body_size = htonl(body_and_payload_size - sizeof(*header)); + + state->total_bytes_sent += (sizeof(*header) + body_and_payload_size); } void protocol_response_client_auth(unsigned char out[CRYPT_PACKET_SIZE_CLIENT_AUTH], @@ -432,7 +432,7 @@ void protocol_response_client_auth(unsigned char out[CRYPT_PACKET_SIZE_CLIENT_AU { struct protocol_client_auth auth_pkt; - protocol_response(&auth_pkt, sizeof(auth_pkt), TYPE_CLIENT_AUTH); + protocol_response(state, &auth_pkt, sizeof(auth_pkt), TYPE_CLIENT_AUTH); /* version */ state->used_protocol_version = PROTOCOL_VERSION; auth_pkt.protocol_version = htonl(state->used_protocol_version); @@ -460,7 +460,7 @@ void protocol_response_server_helo(unsigned char out[CRYPT_PACKET_SIZE_SERVER_HE { struct protocol_server_helo helo_pkt; - protocol_response(&helo_pkt, sizeof(helo_pkt), TYPE_SERVER_HELO); + protocol_response(state, &helo_pkt, sizeof(helo_pkt), TYPE_SERVER_HELO); /* nonce */ sodium_increment(state->last_nonce, crypto_box_NONCEBYTES); memcpy(helo_pkt.nonce_increment, state->last_nonce, crypto_box_NONCEBYTES); @@ -485,7 +485,7 @@ void protocol_response_data(uint8_t * out, if (out_size != CRYPT_PACKET_SIZE_DATA + payload_size) { return; } - protocol_response(&data_hdr, sizeof(data_hdr) + payload_size, TYPE_DATA); + protocol_response(state, &data_hdr, sizeof(data_hdr) + payload_size, TYPE_DATA); crypto_secretstream_xchacha20poly1305_push( &state->crypto_tx_state, out, NULL, (uint8_t *)&data_hdr, sizeof(data_hdr), NULL, 0, 0); @@ -512,7 +512,7 @@ void protocol_response_ping(unsigned char out[CRYPT_PACKET_SIZE_PING], struct co struct protocol_ping ping_pkt; state->awaiting_pong++; - protocol_response(&ping_pkt, sizeof(ping_pkt), TYPE_PING); + protocol_response(state, &ping_pkt, sizeof(ping_pkt), TYPE_PING); create_timestamp(&state->last_ping_send, ping_pkt.timestamp, &state->last_ping_send_usec); ping_pkt.timestamp_usec = htobe64(state->last_ping_send_usec); @@ -532,7 +532,7 @@ void protocol_response_pong(unsigned char out[CRYPT_PACKET_SIZE_PONG], struct co { struct protocol_pong pong_pkt; - protocol_response(&pong_pkt, sizeof(pong_pkt), TYPE_PONG); + protocol_response(state, &pong_pkt, sizeof(pong_pkt), TYPE_PONG); create_timestamp(&state->last_pong_send, pong_pkt.timestamp, &state->last_pong_send_usec); pong_pkt.timestamp_usec = htobe64(state->last_pong_send_usec); @@ -569,6 +569,8 @@ static struct connection * new_connection(struct longterm_keypair const * const create_timestamp(&c->last_pong_recv, NULL, &c->last_pong_recv_usec); create_timestamp(&c->last_pong_send, NULL, &c->last_pong_send_usec); c->latency_usec = 0.0; + c->total_bytes_recv = 0; + c->total_bytes_sent = 0; sodium_mlock(c, sizeof(*c)); return c; @@ -12,7 +12,7 @@ #define PROTOCOL_VERSION 0xDEADCAFE #define PROTOCOL_TIME_STRLEN 32 #define WINDOW_SIZE (65535*2) -#if WINDOW_SIZE > (65535*2) +#if WINDOW_SIZE > (UINT_MAX) #error "Window size is limited by sizeof(header.body_size)" #endif @@ -142,6 +142,9 @@ struct connection { double latency_usec; + uint64_t total_bytes_recv; + uint64_t total_bytes_sent; + /* generated symmetric session keys used by server and client */ struct session_keys * session_keys; @@ -158,6 +161,7 @@ enum recv_return { RECV_FATAL, RECV_FATAL_UNAUTH, RECV_FATAL_CRYPTO_ERROR, + RECV_FATAL_REMOTE_WINDOW_SIZE, RECV_CORRUPT_PACKET, RECV_BUFFER_NEED_MORE_DATA, RECV_CALLBACK_NOT_IMPLEMENTED @@ -155,6 +155,12 @@ enum recv_return protocol_request_pong(struct connection * const state, void on_disconnect(struct connection * const state) { + char pretty_bytes_rx[16]; + char pretty_bytes_tx[16]; + + LOG(NOTICE, "Client closed connection; received %s; sent %s", + prettify_bytes_with_units(pretty_bytes_rx, sizeof(pretty_bytes_rx), state->total_bytes_recv), + prettify_bytes_with_units(pretty_bytes_tx, sizeof(pretty_bytes_tx), state->total_bytes_sent)); (void)state; } @@ -172,7 +178,6 @@ static void event_cb(struct bufferevent * bev, short events, void * con) return; } if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) { - LOG(NOTICE, "Client closed connection"); ev_disconnect(c); return; } @@ -67,4 +67,23 @@ static inline void parse_cmdline(struct cmd_options * const opts, int argc, char } } +static inline char * prettify_bytes_with_units(char * const out, size_t out_size, + unsigned long long bytes) +{ + static char const * const unit_prefixes[] = {"","Kilo","Mega","Giga","Tera"}; + size_t const unit_prefixes_length = sizeof(unit_prefixes)/sizeof(unit_prefixes[0]); + unsigned char unit_prefixes_index = 0; + size_t const convert_bytes_every = 1024; + + while (bytes / convert_bytes_every > 0 && unit_prefixes_index < unit_prefixes_length) + { + bytes /= convert_bytes_every; + unit_prefixes_index++; + } + + snprintf(out, out_size, "%llu %sBytes", bytes, unit_prefixes[unit_prefixes_index]); + + return out; +} + #endif |