Skip to content

Commit

Permalink
support IP address-based tracing, by retaining address inside ptls_lo…
Browse files Browse the repository at this point in the history
…g_conn_state_t
  • Loading branch information
kazuho committed Dec 2, 2024
1 parent d59b3ea commit 7822056
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 7 deletions.
26 changes: 22 additions & 4 deletions include/picotls.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ extern "C" {
#include <inttypes.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#if __GNUC__ >= 3
#define PTLS_LIKELY(x) __builtin_expect(!!(x), 1)
Expand Down Expand Up @@ -1554,6 +1556,10 @@ typedef struct st_ptls_log_conn_state_t {
* `ptls_add_fd'`. To disable logging entirely, use `ptls_log.dummy_conn_state`, or set the value exactly to 1.
*/
float random_;
/**
* represents peer address; ipv4 addresses are stored using the mapped form (::ffff:192.0.2.1)
*/
struct in6_addr address;
struct st_ptls_log_state_t state;
} ptls_log_conn_state_t;

Expand Down Expand Up @@ -1606,11 +1612,12 @@ size_t ptls_log_num_lost(void);
/**
* Registers an fd to the logger. A registered fd is automatically closed and removed when it is closed by the peer.
* @param sample_ratio sampling ratio between 0 and 1
* @param points list of points being logged, in the form of p1\0p2\0\0 (i.e., concatenated list of C strings with an empty string
* marking the end). An empty list means attach to all.
* @param snis list of SNIs being logged, using the same form as points
* @param points list of points to log, in the form of p1\0p2\0\0 (i.e., concatenated list of C strings with an empty string marking
* the end). An empty list means attach to all.
* @param snis list of SNIs to log, using the same form as points
* @param snis list of IPv4/v6 addresses to log, using the same form as points
*/
int ptls_log_add_fd(int fd, float sample_ratio, const char *points, const char *snis);
int ptls_log_add_fd(int fd, float sample_ratio, const char *points, const char *snis, const char *addresses);
#endif

void ptls_log__recalc_point(int caller_locked, struct st_ptls_log_point_t *point);
Expand Down Expand Up @@ -1970,6 +1977,11 @@ char *ptls_hexdump(char *dst, const void *src, size_t len);
* Builds a JSON-safe string without double quotes. Supplied buffer MUST be at least 6x + 1 bytes larger than the input.
*/
char *ptls_jsonescape(char *buf, const char *s, size_t len);
/**
* builds a v4-mapped address (i.e., ::ffff:192.0.2.1)
*/
static void ptls_build_mapped_v4_address(struct in6_addr *v6, const struct in_addr *v4);

/**
* the default get_time callback
*/
Expand Down Expand Up @@ -2145,6 +2157,12 @@ inline size_t ptls_aead_decrypt(ptls_aead_context_t *ctx, void *output, const vo
return ctx->do_decrypt(ctx, output, input, inlen, seq, aad, aadlen);
}

inline void ptls_build_mapped_v4_address(struct in6_addr *v6, const struct in_addr *v4)
{
*v6 = (struct in6_addr){.s6_addr[10] = 0xff, .s6_addr[11] = 0xff};
memcpy(&v6->s6_addr[12], &v4->s_addr, 4);
}

inline void ptls_hash_clone_memcpy(void *dst, const void *src, size_t size)
{
memcpy(dst, src, size);
Expand Down
59 changes: 56 additions & 3 deletions lib/picotls.c
Original file line number Diff line number Diff line change
Expand Up @@ -6841,6 +6841,10 @@ static struct {
*
*/
char *snis;
/**
* list of addresses terminated by ip6addr_any
*/
struct in6_addr *addresses;
/**
*
*/
Expand All @@ -6866,7 +6870,8 @@ void ptls_log_init_conn_state(ptls_log_conn_state_t *state, void (*random_bytes)
random_bytes(&r, sizeof(r));

*state = (ptls_log_conn_state_t){
.random_ = (float)r / ((uint64_t)UINT32_MAX + 1) /* [0..1), so that any(r) < sample_ratio where sample_ratio is [0..1] */
.random_ = (float)r / ((uint64_t)UINT32_MAX + 1), /* [0..1), so that any(r) < sample_ratio where sample_ratio is [0..1] */
.address = in6addr_any,
};
}

Expand Down Expand Up @@ -6903,6 +6908,24 @@ static int is_in_stringlist(const char *list, const char *search_for)
return 0;
}

static int is_in_addresslist(const struct in6_addr *list, const struct in6_addr *search_for)
{
#define IS_EQUAL(x, y) (memcmp((x), (y), sizeof(struct in6_addr)) == 0)

if (IS_EQUAL(&list[0], &in6addr_any))
return 1;

if (IS_EQUAL(search_for, &in6addr_any))
return 0;

for (const struct in6_addr *element = list; !IS_EQUAL(element, &in6addr_any); ++element)
if (IS_EQUAL(element, search_for))
return 1;
return 0;

#undef IS_EQUAL
}

void ptls_log__recalc_point(int caller_locked, struct st_ptls_log_point_t *point)
{
if (!caller_locked)
Expand Down Expand Up @@ -6934,7 +6957,8 @@ void ptls_log__recalc_conn(int caller_locked, struct st_ptls_log_conn_state_t *c
const char *sni = get_sni != NULL ? get_sni(get_sni_arg) : NULL;
for (size_t slot = 0; slot < PTLS_ELEMENTSOF(logctx.conns); ++slot) {
if (logctx.conns[slot].points != NULL && conn->random_ < logctx.conns[slot].sample_ratio &&
is_in_stringlist(logctx.conns[slot].snis, sni)) {
is_in_stringlist(logctx.conns[slot].snis, sni) &&
is_in_addresslist(logctx.conns[slot].addresses, &conn->address)) {
new_active = (uint32_t)1 << slot;
}
}
Expand All @@ -6961,12 +6985,15 @@ static void close_log_fd(size_t slot)
logctx.conns[slot].points = NULL;
free(logctx.conns[slot].snis);
logctx.conns[slot].snis = NULL;
free(logctx.conns[slot].addresses);
logctx.conns[slot].addresses = NULL;
++ptls_log._generation;
}

int ptls_log_add_fd(int fd, float sample_ratio, const char *_points, const char *_snis)
int ptls_log_add_fd(int fd, float sample_ratio, const char *_points, const char *_snis, const char *_addresses)
{
char *points = NULL, *snis = NULL;
struct in6_addr *addresses = NULL;
int ret;

pthread_mutex_lock(&logctx.mutex);
Expand All @@ -6979,6 +7006,30 @@ int ptls_log_add_fd(int fd, float sample_ratio, const char *_points, const char
ret = PTLS_ERROR_NO_MEMORY;
goto Exit;
}
{
size_t num_addresses = 0;
for (const char *input = _addresses; *input != '\0'; input += strlen(input) + 1)
++num_addresses;
if ((addresses = malloc(sizeof(*addresses) * (num_addresses + 1))) == NULL) {
ret = PTLS_ERROR_NO_MEMORY;
goto Exit;
}
size_t index = 0;
for (const char *input = _addresses; *input != '\0'; input += strlen(input) + 1) {
/* note: for consistency to the handling of points, erroneous input is ignored. V4 addresses will use the mapped form
* (::ffff:192.0.2.1) */
if (!inet_pton(AF_INET6, input, &addresses[index])) {
struct in_addr v4;
if (!inet_pton(AF_INET, input, &v4))
continue;
ptls_build_mapped_v4_address(&addresses[index], &v4);
}
if (memcmp(&addresses[index], &in6addr_any, sizeof(struct in6_addr)) == 0)
continue;
++index;
}
addresses[index] = in6addr_any;
}

/* find slot, or return if not available */
size_t slot_index;
Expand All @@ -6994,6 +7045,7 @@ int ptls_log_add_fd(int fd, float sample_ratio, const char *_points, const char
logctx.conns[slot_index].fd = fd;
logctx.conns[slot_index].points = points;
logctx.conns[slot_index].snis = snis;
logctx.conns[slot_index].addresses = addresses;
logctx.conns[slot_index].sample_ratio = sample_ratio;
++ptls_log._generation;

Expand All @@ -7004,6 +7056,7 @@ int ptls_log_add_fd(int fd, float sample_ratio, const char *_points, const char
if (ret != 0) {
free(points);
free(snis);
free(addresses);
}
return ret;
}
Expand Down

0 comments on commit 7822056

Please sign in to comment.