lsquic_qlog.c revision 7d09751d
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <stdlib.h> 3#include <stdio.h> 4#include <errno.h> 5#include <inttypes.h> 6#include <string.h> 7#include <sys/queue.h> 8#ifdef WIN32 9#include <Ws2tcpip.h> 10#else 11#include <sys/types.h> 12#include <sys/socket.h> 13#include <netinet/in.h> 14#include <arpa/inet.h> 15#endif 16 17#include "lsquic.h" 18#include "lsquic_types.h" 19#include "lsquic_int_types.h" 20#include "lsquic_packet_common.h" 21#include "lsquic_packet_in.h" 22#include "lsquic_packet_out.h" 23#include "lsquic_util.h" 24#include "lsquic_qlog.h" 25 26#define LSQUIC_LOGGER_MODULE LSQLM_QLOG 27#include "lsquic_logger.h" 28 29#define LSQUIC_LOG_CONN_ID cid 30#define LCID(...) LSQ_LOG2(LSQ_LOG_DEBUG, __VA_ARGS__) 31 32#define MAX_IP_LEN INET6_ADDRSTRLEN 33#define QLOG_PACKET_RAW_SZ 64 34 35 36void 37lsquic_qlog_create_connection (const lsquic_cid_t* cid, 38 const struct sockaddr *local_sa, 39 const struct sockaddr *peer_sa) 40{ 41 uint32_t ip_version, srcport, dstport; 42 struct sockaddr_in *local4, *peer4; 43 struct sockaddr_in6 *local6, *peer6; 44 char srcip[MAX_IP_LEN], dstip[MAX_IP_LEN]; 45 46 if (!local_sa || !peer_sa) 47 return; 48 49 if (local_sa->sa_family == AF_INET) 50 { 51 ip_version = 4; 52 local4 = (struct sockaddr_in *)local_sa; 53 peer4 = (struct sockaddr_in *)peer_sa; 54 srcport = ntohs(local4->sin_port); 55 dstport = ntohs(peer4->sin_port); 56 inet_ntop(local4->sin_family, &local4->sin_addr, srcip, MAX_IP_LEN); 57 inet_ntop(peer4->sin_family, &peer4->sin_addr, dstip, MAX_IP_LEN); 58 } 59 else if (local_sa->sa_family == AF_INET6) 60 { 61 ip_version = 6; 62 local6 = (struct sockaddr_in6 *)local_sa; 63 peer6 = (struct sockaddr_in6 *)peer_sa; 64 srcport = ntohs(local6->sin6_port); 65 dstport = ntohs(peer6->sin6_port); 66 inet_ntop(local6->sin6_family, &local6->sin6_addr, srcip, MAX_IP_LEN); 67 inet_ntop(peer6->sin6_family, &peer6->sin6_addr, dstip, MAX_IP_LEN); 68 } 69 else 70 return; 71 72 LCID("[%" PRIu64 ",\"CONNECTIVITY\",\"NEW_CONNECTION\",\"LINE\"," 73 "{" 74 "\"ip_version\":\"%u\"," 75 "\"srcip\":\"%s\"," 76 "\"dstip\":\"%s\"," 77 "\"srcport\":\"%u\"," 78 "\"dstport\":\"%u\"" 79 "}]", 80 lsquic_time_now(), ip_version, srcip, dstip, srcport, dstport); 81} 82 83#define QLOG_FRAME_DICT_PREFIX_COMMA ",{\"frame_type\":\"" 84#define QLOG_FRAME_DICT_PREFIX "{\"frame_type\":\"" 85#define QLOG_FRAME_DICT_SUFFIX "\"}" 86#define QLOG_FRAME_LIST_PREFIX ",\"frames\":[" 87#define QLOG_FRAME_LIST_SUFFIX "]" 88#define QLOG_FRAME_LIST_MAX \ 89 sizeof(QLOG_FRAME_LIST_PREFIX) + \ 90 sizeof(QLOG_FRAME_LIST_SUFFIX) + \ 91 lsquic_frame_types_str_sz + \ 92 (N_QUIC_FRAMES * \ 93 (sizeof(QLOG_FRAME_DICT_PREFIX_COMMA) + \ 94 sizeof(QLOG_FRAME_DICT_SUFFIX))) 95 96void 97lsquic_qlog_packet_rx (const lsquic_cid_t* cid, 98 const struct lsquic_packet_in *packet_in, 99 const unsigned char *packet_in_data, 100 size_t packet_in_size) 101{ 102 int i, first, ret; 103 unsigned cur; 104 size_t raw_bytes_written; 105 char data[QLOG_PACKET_RAW_SZ]; 106 char frame_list[QLOG_FRAME_LIST_MAX + 1]; 107 108 if (!packet_in || !packet_in_data) 109 return; 110 111 if (packet_in->pi_frame_types) 112 { 113 memcpy(frame_list, QLOG_FRAME_LIST_PREFIX, 114 sizeof(QLOG_FRAME_LIST_PREFIX)); 115 cur = sizeof(QLOG_FRAME_LIST_PREFIX) - 1; 116 for (i = 0, first = 0; i < N_QUIC_FRAMES; i++) 117 if (packet_in->pi_frame_types & (1 << i)) 118 { 119 ret = snprintf(frame_list + cur, 120 QLOG_FRAME_LIST_MAX - cur, 121 /* prefix + FRAME_NAME + suffix */ 122 "%s%s%s", 123 /* skip comma in prefix if first frame */ 124 (first++ ? 125 QLOG_FRAME_DICT_PREFIX_COMMA : 126 QLOG_FRAME_DICT_PREFIX), 127 QUIC_FRAME_NAME(i), 128 QLOG_FRAME_DICT_SUFFIX); 129 if (ret < 0 || (unsigned)ret > QLOG_FRAME_LIST_MAX - cur) 130 break; 131 cur += ret; 132 } 133 if (cur + sizeof(QLOG_FRAME_LIST_SUFFIX) <= QLOG_FRAME_LIST_MAX) 134 memcpy(frame_list + cur, QLOG_FRAME_LIST_SUFFIX, 135 sizeof(QLOG_FRAME_LIST_SUFFIX)); 136 } 137 else 138 frame_list[0] = '\0'; 139 140 raw_bytes_written = lsquic_hex_encode(packet_in_data, packet_in_size, 141 data, QLOG_PACKET_RAW_SZ); 142 143 LCID("[%" PRIu64 ",\"TRANSPORT\",\"PACKET_RX\",\"LINE\"," 144 "{" 145 "\"raw\":\"%s%s\"," 146 "\"header\":{" 147 "\"type\":\"%s\"," 148 "\"payload_length\":\"%d\"," 149 "\"packet_number\":\"%" PRIu64 "\"" 150 "}%s" 151 "}]", 152 packet_in->pi_received, 153 data, (raw_bytes_written < packet_in_size) ? "..." : "", 154 lsquic_hety2str[packet_in->pi_header_type], 155 packet_in->pi_data_sz, 156 packet_in->pi_packno, 157 frame_list); 158} 159 160 161void 162lsquic_qlog_hsk_completed (const lsquic_cid_t* cid) 163{ 164 LCID("[%" PRIu64 ",\"CONNECTIVITY\",\"HANDSHAKE\",\"PACKET_RX\"," 165 "{\"status\":\"complete\"}]", lsquic_time_now()); 166} 167 168 169void 170lsquic_qlog_zero_rtt (const lsquic_cid_t* cid) 171{ 172 LCID("[%" PRIu64 ",\"RECOVERY\",\"RTT_UPDATE\",\"PACKET_RX\"," 173 "{\"zero_rtt\":\"successful\"}]", lsquic_time_now()); 174} 175 176 177void 178lsquic_qlog_check_certs (const lsquic_cid_t* cid, const lsquic_str_t **certs, 179 size_t count) 180{ 181 size_t i; 182 size_t buf_sz = 0; 183 char *buf = NULL; 184 char *new_buf; 185 186 for (i = 0; i < count; i++) 187 { 188 if (buf_sz < (lsquic_str_len(certs[i]) * 2) + 1) 189 { 190 buf_sz = (lsquic_str_len(certs[i]) * 2) + 1; 191 new_buf = realloc(buf, buf_sz); 192 if (!new_buf) 193 break; 194 buf = new_buf; 195 } 196 lsquic_hex_encode(lsquic_str_cstr(certs[i]), lsquic_str_len(certs[i]), 197 buf, buf_sz); 198 LCID("[%" PRIu64 ",\"SECURITY\",\"CHECK_CERT\",\"CERTLOG\"," 199 "{\"certificate\":\"%s\"}]", lsquic_time_now(), buf); 200 } 201 if (buf) 202 free(buf); 203} 204 205 206void 207lsquic_qlog_version_negotiation (const lsquic_cid_t* cid, 208 const char *action, const char *ver) 209{ 210 char *trig; 211 212 if (!action || !ver) 213 return; 214 if (strcmp(action, "proposed") == 0) 215 trig = "LINE"; 216 else if (strcmp(action, "supports") == 0 || strcmp(action, "agreed") == 0) 217 trig = "PACKET_RX"; 218 else 219 return; 220 LCID("[%" PRIu64 ",\"CONNECTIVITY\",\"VERNEG\",\"%s\"," 221 "{\"%s_version\":\"%s\"}]", lsquic_time_now(), trig, action, ver); 222} 223