| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677 |
- // Copyright The OpenTelemetry Authors
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "arguments.h"
- #include "span_context.h"
- #include "go_context.h"
- #include "go_types.h"
- #include "uprobe.h"
- //char __license[] SEC("license") = "Dual MIT/GPL";
- #define PATH_MAX_LEN 128
- #define MAX_BUCKETS 8
- #define METHOD_MAX_LEN 8
- #define MAX_CONCURRENT 50
- #define REMOTE_ADDR_MAX_LEN 256
- #define HOST_MAX_LEN 256
- #define PROTO_MAX_LEN 8
- struct http_server_span_t {
- BASE_SPAN_PROPERTIES
- u64 status_code;
- char method[METHOD_MAX_LEN];
- char path[PATH_MAX_LEN];
- char remote_addr[REMOTE_ADDR_MAX_LEN];
- char host[HOST_MAX_LEN];
- char proto[PROTO_MAX_LEN];
- };
- struct uprobe_data_t {
- struct http_server_span_t span;
- // bpf2go doesn't support pointers fields
- // saving the response pointer in the entry probe
- // and using it in the return probe
- u64 resp_ptr;
- };
- struct {
- __uint(type, BPF_MAP_TYPE_HASH);
- __type(key, void *);
- __type(value, struct uprobe_data_t);
- __uint(max_entries, MAX_CONCURRENT);
- } http_server_uprobes SEC(".maps");
- struct {
- __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
- __uint(key_size, sizeof(u32));
- __uint(value_size, sizeof(struct map_bucket));
- __uint(max_entries, MAX_CONCURRENT);
- } golang_mapbucket_storage_map SEC(".maps");
- struct {
- __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
- __uint(key_size, sizeof(u32));
- __uint(value_size, sizeof(struct cw_header_token));
- __uint(max_entries, MAX_CONCURRENT);
- } header_range SEC(".maps");
- struct {
- __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
- __uint(key_size, sizeof(u32));
- __uint(value_size, sizeof(struct span_context));
- __uint(max_entries, 1);
- } parent_span_context_storage_map SEC(".maps");
- struct {
- __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
- __uint(key_size, sizeof(u32));
- __uint(value_size, sizeof(struct apm_span_context));
- __uint(max_entries, 1);
- } cw_parent_span_context_storage_map SEC(".maps");
- struct {
- __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
- __uint(key_size, sizeof(u32));
- __uint(value_size, sizeof(struct uprobe_data_t));
- __uint(max_entries, 1);
- } http_server_uprobe_storage_map SEC(".maps");
- struct {
- __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
- } events SEC(".maps");
- struct header_key {
- char str[CW_HEADER_KEY_LENGTH];
- };
- struct {
- __uint(type, BPF_MAP_TYPE_HASH);
- __uint(key_size, sizeof(u32));
- __uint(value_size, sizeof(struct header_key));
- __uint(max_entries, 8);
- } header_keys_map SEC(".maps");
- struct {
- __uint(type, BPF_MAP_TYPE_LRU_HASH);
- __uint(key_size, sizeof(u64));
- __uint(value_size, sizeof(char [CW_HEADER_VAL_LENGTH]));
- __uint(max_entries, MAX_CONCURRENT);
- } http_server_context_headers SEC(".maps");
- // Injected in init
- // volatile const u64 ctx_ptr_pos;
- // volatile const u64 headers_ptr_pos;
- // volatile const u64 buckets_ptr_pos;
- //for (int i = 0; i < W3C_KEY_LENGTH; i++)
- //{
- //if (current_header_key[i] != "traceparent"[i]){
- //goto outer_loop;
- //}
- //if (current_header_key[i] != "Traceparent"[i]){
- //goto outer_loop;
- //}
- //}
- static __always_inline struct span_context *extract_context_from_req_headers_del(void *headers_ptr_ptr) {
- void *headers_ptr;
- long res;
- res = bpf_probe_read(&headers_ptr, sizeof(headers_ptr), headers_ptr_ptr);
- if (res < 0) {
- return NULL;
- }
- u64 headers_count = 0;
- res = bpf_probe_read(&headers_count, sizeof(headers_count), headers_ptr);
- if (res < 0) {
- return NULL;
- }
- if (headers_count == 0) {
- return NULL;
- }
- unsigned char log_2_bucket_count;
- res = bpf_probe_read(&log_2_bucket_count, sizeof(log_2_bucket_count), headers_ptr + 9);
- if (res < 0) {
- return NULL;
- }
- u64 bucket_count = 1 << log_2_bucket_count;
- __u64 pid_tgid = bpf_get_current_pid_tgid();
- __u32 tgid = pid_tgid >> 32;
- struct ebpf_proc_info *proc_info =
- bpf_map_lookup_elem(&proc_info_map, &tgid);
- if(!proc_info)
- {
- return 0;
- }
-
- // Check if Go version >= 1.24 (Swiss Tables)
- if (proc_info->version >= GO_VERSION(1, 24, 0)) {
- // Swiss Tables uses dirPtr instead of buckets, structure is incompatible
- // Skip header reading for Go 1.24+
- return NULL;
- }
-
- void *header_buckets;
- res = bpf_probe_read(&header_buckets, sizeof(header_buckets), (void *) (headers_ptr + proc_info->buckets_ptr_pos));
- if (res < 0) {
- return NULL;
- }
- u32 map_id = 0;
- struct map_bucket *map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
- if (!map_value) {
- return NULL;
- }
- for (u32 j = 0; j < MAX_BUCKETS; j++) {
- if (j >= bucket_count) {
- break;
- }
- res = bpf_probe_read(map_value, sizeof(struct map_bucket), header_buckets + (j * sizeof(struct map_bucket)));
- if (res < 0) {
- continue;
- }
- // for (u32 i = 0; i < 8; i++) {
- u32 i = 0;
- if (map_value->tophash[i] != 0 && map_value->keys[i].len == CW_HEADER_KEY_LENGTH) {
- // char current_header_key[CW_HEADER_KEY_LENGTH];
- // bpf_probe_read(current_header_key, sizeof(current_header_key), map_value->keys[i].str);
- for (int ii = 0; ii < CW_HEADER_KEY_LENGTH; ii++) {
- if (map_value->keys[i].str[ii] != CW_HEADER_KEY_VAL[i] && map_value->keys[i].str[ii] != CW_HEADER_KEY_UFIRST_VAL[ii]) {
- // goto outer_loop;
- }
- }
- // continue;
- }
- // if (map_value->keys[i].len != CW_HEADER_KEY_LENGTH) {
- // continue;
- // }
- // char current_header_key[CW_HEADER_KEY_LENGTH];
- // bpf_probe_read(current_header_key, sizeof(current_header_key), map_value->keys[i].str);
- //
- // struct header_key * current_header_key = bpf_map_lookup_elem(&header_keys_map, &map_id);
- // if (current_header_key) {
- // bpf_probe_read(current_header_key->str, sizeof(current_header_key->str), map_value->keys[i].str);
- // }
- //
- // for (int i = 0; i < CW_HEADER_KEY_LENGTH; i++) {
- // if (current_header_key[i] != CW_HEADER_KEY_VAL[i] && current_header_key[i] != CW_HEADER_KEY_UFIRST_VAL[i]) {
- // goto outer_loop;
- // }
- // }
- //
- // void *traceparent_header_value_ptr = map_value->values[i].array;
- // struct go_string_ot traceparent_header_value_go_str;
- // res = bpf_probe_read(&traceparent_header_value_go_str, sizeof(traceparent_header_value_go_str),
- // traceparent_header_value_ptr);
- // // 00-95b5ec2b81e2374a4a27ce36ab71d349-18f65a5a3ab22213-02
- // cw_bpf_debug("traceparent_header_value_go_str.str:%s", traceparent_header_value_go_str.str);
- //
- // if (res < 0) {
- // return NULL;
- // }
- //
- // // char traceparent_header_value[130];
- // int key = 0;
- // char *traceparent_header_value;
- // traceparent_header_value = bpf_map_lookup_elem(&go_large_array_map, &key);
- //
- // res = bpf_probe_read(&traceparent_header_value, sizeof(traceparent_header_value),
- // traceparent_header_value_go_str.str);
- //
- //
- // if (res < 0) {
- // return NULL;
- // }
- // struct span_context *parent_span_context = bpf_map_lookup_elem(&parent_span_context_storage_map, &map_id);
- // if (!parent_span_context) {
- // cw_bpf_debug("no parent_span_context");
- // return NULL;
- // }
- // struct apm_span_context *cw_parent_span_context = bpf_map_lookup_elem(&cw_parent_span_context_storage_map, &map_id);
- // if (!cw_parent_span_context) {
- // cw_bpf_debug("no cw_parent_span_context");
- // return NULL;
- // }
- //
- // w3c_string_to_span_context(traceparent_header_value, parent_span_context);
- //
- // cw_string_to_span_context(traceparent_header_value, cw_parent_span_context);
- //
- // // 保存sc
- // cw_save_parent_tracking_span(cw_parent_span_context);
- //
- // return parent_span_context;
- // outer_loop:
- // continue;
- // }
- }
- return NULL;
- }
- // 获取 get_map_bucket
- static __always_inline struct map_bucket *get_map_bucket(void *headers_ptr_ptr) {
- void *headers_ptr;
- long res;
- res = bpf_probe_read(&headers_ptr, sizeof(headers_ptr), headers_ptr_ptr);
- if (res < 0) {
- return NULL;
- }
- u64 headers_count = 0;
- res = bpf_probe_read(&headers_count, sizeof(headers_count), headers_ptr);
- if (res < 0) {
- return NULL;
- }
- if (headers_count == 0) {
- return NULL;
- }
- unsigned char log_2_bucket_count;
- res = bpf_probe_read(&log_2_bucket_count, sizeof(log_2_bucket_count), headers_ptr + 9);
- if (res < 0) {
- return NULL;
- }
- u64 bucket_count = 1 << log_2_bucket_count;
- __u64 pid_tgid = bpf_get_current_pid_tgid();
- __u32 tgid = pid_tgid >> 32;
- struct ebpf_proc_info *proc_info =
- bpf_map_lookup_elem(&proc_info_map, &tgid);
- if(!proc_info)
- {
- return NULL;
- }
- void *header_buckets;
- res = bpf_probe_read(&header_buckets, sizeof(header_buckets), (void *) (headers_ptr + proc_info->buckets_ptr_pos));
- if (res < 0) {
- return NULL;
- }
- u32 map_id = 0;
- struct map_bucket *map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
- if (!map_value) {
- return NULL;
- }
- __builtin_memset(map_value, 0, sizeof(struct map_bucket));
- for (u32 j = 0; j < 8; j++) {
- if (j >= bucket_count) {
- break;
- }
- res = bpf_probe_read(map_value, sizeof(struct map_bucket), header_buckets + (j * sizeof(struct map_bucket)));
- if (res == 0) {
- return map_value;
- }
- }
- return NULL;
- }
- MAP_BUCKET_DEFINITION(go_string_ot, go_slice_ot)
- static __always_inline char *
- extract_context_from_req_headers_pre_parsed(void *key) {
- char *header_val =
- bpf_map_lookup_elem(&http_server_context_headers, &key);
- if (!header_val) {
- return NULL;
- }
- return header_val;
- }
- static __always_inline char *extract_context_from_req_headers_go_map(void *headers_ptr_ptr)
- {
- void *headers_ptr;
- long res;
- res = bpf_probe_read(&headers_ptr, sizeof(headers_ptr), headers_ptr_ptr);
- if (res < 0)
- {
- return NULL;
- }
- u64 headers_count = 0;
- res = bpf_probe_read(&headers_count, sizeof(headers_count), headers_ptr);
- if (res < 0)
- {
- return NULL;
- }
- if (headers_count == 0)
- {
- return NULL;
- }
- unsigned char log_2_bucket_count;
- res = bpf_probe_read(&log_2_bucket_count, sizeof(log_2_bucket_count), headers_ptr + 9);
- if (res < 0)
- {
- return NULL;
- }
- u64 bucket_count = 1 << log_2_bucket_count;
- void *header_buckets;
- /**/
- __u64 pid_tgid = bpf_get_current_pid_tgid();
- __u32 tgid = pid_tgid >> 32;
- struct ebpf_proc_info *proc_info =
- bpf_map_lookup_elem(&proc_info_map, &tgid);
- if(!proc_info)
- {
- return NULL;
- }
- /**/
- res = bpf_probe_read(&header_buckets, sizeof(header_buckets), (void*)(headers_ptr + proc_info->buckets_ptr_pos));
- if (res < 0)
- {
- return NULL;
- }
- u32 map_id = 0;
- MAP_BUCKET_TYPE(go_string_ot, go_slice_ot) *map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
- if (!map_value)
- {
- return NULL;
- }
- for (u64 j = 0; j < MAX_BUCKETS; j++)
- {
- if (j >= bucket_count)
- {
- break;
- }
- res = bpf_probe_read(map_value, sizeof(MAP_BUCKET_TYPE(go_string_ot, go_slice_ot)), header_buckets + (j * sizeof(MAP_BUCKET_TYPE(go_string_ot, go_slice_ot))));
- if (res < 0)
- {
- continue;
- }
- for (u64 i = 0; i < 8; i++)
- {
- if (map_value->tophash[i] == 0)
- {
- continue;
- }
- if (map_value->keys[i].len != CW_HEADER_KEY_LENGTH)
- {
- continue;
- }
- char current_header_key[CW_HEADER_KEY_LENGTH];
- bpf_probe_read(current_header_key, sizeof(current_header_key), map_value->keys[i].str);
- if (!bpf_memcmp(current_header_key, CW_HEADER_KEY_VAL, CW_HEADER_KEY_LENGTH) && !bpf_memcmp(current_header_key, CW_HEADER_KEY_UFIRST_VAL, CW_HEADER_KEY_LENGTH))
- {
- continue;
- }
- void *traceparent_header_value_ptr = map_value->values[i].array;
- struct go_string_ot traceparent_header_value_go_str;
- res = bpf_probe_read(&traceparent_header_value_go_str, sizeof(traceparent_header_value_go_str), traceparent_header_value_ptr);
- if (res < 0)
- {
- return NULL;
- }
- if (traceparent_header_value_go_str.len != CW_HEADER_VAL_LENGTH)
- {
- continue;
- }
- char traceparent_header_value2[CW_HEADER_VAL_LENGTH];
- res = bpf_probe_read(&traceparent_header_value2, sizeof(traceparent_header_value2), traceparent_header_value_go_str.str);
- if (res < 0)
- {
- return NULL;
- }
- // bpf_printk("has cw header111 j=%d i=%d %s", j, i,traceparent_header_value_go_str.str);
- return traceparent_header_value_go_str.str;
- // w3c_string_to_span_context(traceparent_header_value, parent_span_context);
- // return 0;
- }
- }
- return NULL;
- }
- static __always_inline char *
- extract_context_from_req_headers(void *key, void *headers_ptr_ptr, __u64 use_swiss) {
- if (use_swiss == 1) {
- return extract_context_from_req_headers_pre_parsed(key);
- }
- return extract_context_from_req_headers_go_map(headers_ptr_ptr);
- }
- // 获取 header_val
- static __always_inline char *get_header_val(struct map_bucket *map_value,u32 off,u32 count) {
- for (u32 i = off; i < count; i++) {
- if (map_value->tophash[i] != 0 && map_value->keys[i].len == CW_HEADER_KEY_LENGTH) {
- char current_header_key[CW_HEADER_KEY_LENGTH];
- bpf_probe_read(current_header_key, sizeof(current_header_key), map_value->keys[i].str);
- if ((current_header_key[0] == CW_HEADER_KEY_VAL[0]
- || current_header_key[0] == CW_HEADER_KEY_UFIRST_VAL[0])
- && current_header_key[1] == CW_HEADER_KEY_UFIRST_VAL[1]
- && current_header_key[2] == CW_HEADER_KEY_UFIRST_VAL[2]
- && current_header_key[3] == CW_HEADER_KEY_UFIRST_VAL[3]
- && current_header_key[4] == CW_HEADER_KEY_UFIRST_VAL[4]
- && current_header_key[5] == CW_HEADER_KEY_UFIRST_VAL[5]
- && current_header_key[6] == CW_HEADER_KEY_UFIRST_VAL[6]) {
- void *traceparent_header_value_ptr = map_value->values[i].array;
- struct go_string_ot traceparent_header_value_go_str;
- long res = bpf_probe_read(&traceparent_header_value_go_str, sizeof(traceparent_header_value_go_str),
- traceparent_header_value_ptr);
- if (res == 0) {
- cw_bpf_debug("get_header_val %d-%d %s",off,count,traceparent_header_value_go_str.str);
- return traceparent_header_value_go_str.str;
- }
- }
- }
- }
- return NULL;
- }
- // 分段获取 header_val
- static __always_inline char *get_header_val_off(struct map_bucket *map_value) {
- char *val = get_header_val(map_value, 0, 2);
- if (val == NULL) {
- val = get_header_val(map_value, 2, 4);
- }
- if (val == NULL) {
- val = get_header_val(map_value, 4, 6);
- }
- if (val == NULL) {
- val = get_header_val(map_value, 6, 8);
- }
- return val;
- }
- // This instrumentation attaches uprobe to the following function:
- // func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)
- SEC("uprobe/HandlerFunc_ServeHTTP")
- int uprobe_HandlerFunc_ServeHTTP(struct pt_regs *ctx) {
- cw_bpf_debug("[uprobe_HandlerFunc_ServeHTTP]");
- __u64 pid_tgid = bpf_get_current_pid_tgid();
- __u32 tgid = pid_tgid >> 32;
- struct ebpf_proc_info *proc_info =
- bpf_map_lookup_elem(&proc_info_map, &tgid);
- if(!proc_info)
- {
- cw_bpf_debug("[uprobe_HandlerFunc_ServeHTTP] no proc info");
- return 0;
- }
- void *req_ctx_ptr = get_Go_context(ctx, 4, proc_info->ctx_ptr_pos, false);
- void *key = get_consistent_key(ctx, req_ctx_ptr);
- void *httpReq_ptr = bpf_map_lookup_elem(&http_server_uprobes, &key);
- if (httpReq_ptr != NULL) {
- cw_bpf_debug("uprobe/HandlerFunc_ServeHTTP already tracked with the current request");
- return 0;
- }
-
- u32 map_id = 0;
- struct uprobe_data_t *uprobe_data = bpf_map_lookup_elem(&http_server_uprobe_storage_map, &map_id);
- if (uprobe_data == NULL) {
- cw_bpf_debug("uprobe/HandlerFunc_ServeHTTP: http_server_span is NULL");
- return 0;
- }
- __builtin_memset(uprobe_data, 0, sizeof(struct uprobe_data_t));
- // Save response writer
- void *resp_impl = get_argument(ctx, 3);
- uprobe_data->resp_ptr = (u64) resp_impl;
- struct http_server_span_t *http_server_span = &uprobe_data->span;
- http_server_span->start_time = bpf_ktime_get_ns();
- // return 1;
- // Propagate context
- void *req_ptr = get_argument(ctx, 4);
- // struct map_bucket * map_bucket_p = get_map_bucket((void *) (req_ptr + proc_info->headers_ptr_pos));
- char *traceparent_header_value = extract_context_from_req_headers(key,
- (void *) (req_ptr + proc_info->headers_ptr_pos),
- proc_info->use_swiss_map);
- // bpf_printk("111 %s",traceparent_header_value);
- // char * traceparent_header_value = get_header_val_off(map_bucket_p);
- struct apm_span_context *cw_parent_span_context = bpf_map_lookup_elem(&cw_parent_span_context_storage_map, &map_id);
- if (!cw_parent_span_context) {
- return 0;
- }
- __builtin_memset(cw_parent_span_context, 0, sizeof(struct apm_span_context));
- if (traceparent_header_value != NULL) {
- cw_bpf_debug("traceparent_header_value != NULL");
- cw_string_to_span_context(traceparent_header_value, cw_parent_span_context);
- // found parent context in http headers
- // http_server_span->psc = *parent_ctx;
- // copy traceID
- copy_byte_arrays(http_server_span->psc.TraceID, http_server_span->sc.TraceID, TRACE_ID_SIZE);
- // 生成随机SpanID
- generate_random_bytes(http_server_span->sc.SpanID, SPAN_ID_SIZE);
- cw_save_parent_tracking_span(cw_parent_span_context);
- } else {
- cw_bpf_debug("traceparent_header_value == NULL");
- http_server_span->sc = generate_span_context();
- struct apm_span_context *cw_parent_span_context = bpf_map_lookup_elem(&cw_parent_span_context_storage_map, &map_id);
- if (!cw_parent_span_context) {
- return 0;
- }
- // struct apm_span_context context = {};
- generate_random_bytes(cw_parent_span_context->trace_id, TRACE_ID_SIZE);
- // generate_random_bytes(context.span_id, SPAN_ID_SIZE);
- // 保存 trace_id 到psc
- cw_save_parent_tracking_span(cw_parent_span_context);
- }
- if (req_ctx_ptr == NULL) {
- // cw_bpf_debug("uprobe/HandlerFunc_ServeHTTP: req_ctx_ptr is NULL");
- return 0;
- }
- // cw_bpf_debug("found parent context in http headers");
- // cw_bpf_debug("parent_span_context-TraceID---");
- // for (int i = 0; i < TRACE_ID_SIZE; i++) {
- // cw_bpf_debug("%02x", uprobe_data->span.sc.TraceID[i]);
- // }
- // cw_bpf_debug("parent_span_context-SpanID---");
- // for (int i = 0; i < SPAN_ID_SIZE; i++) {
- // cw_bpf_debug("%02x", uprobe_data->span.sc.SpanID[i]);
- // }
- // bpf_map_update_elem(&http_server_uprobes, &key, uprobe_data, 0);
- // start_tracking_span(req_ctx_ptr, &http_server_span->sc);
- // void save_tracking_span(struct apm_span_context *sc)
- return 0;
- }
- // This instrumentation attaches uprobe to the following function:
- // func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)
- SEC("uprobe/HandlerFunc_ServeHTTP")
- int uprobe_HandlerFunc_ServeHTTP_Returns(struct pt_regs *ctx) {
- // return 1;
- cw_bpf_debug("[uprobe_HandlerFunc_ServeHTTP_Returns]");
- // u64 end_time = bpf_ktime_get_ns();
- __u64 pid_tgid = bpf_get_current_pid_tgid();
- __u32 tgid = pid_tgid >> 32;
- struct ebpf_proc_info *proc_info =
- bpf_map_lookup_elem(&proc_info_map, &tgid);
- if(!proc_info)
- {
- return 0;
- }
- void *req_ctx_ptr = get_Go_context(ctx, 4, proc_info->ctx_ptr_pos, false);
- void *key = get_consistent_key(ctx, req_ctx_ptr);
- struct uprobe_data_t *uprobe_data = bpf_map_lookup_elem(&http_server_uprobes, &key);
- if (uprobe_data == NULL) {
- cw_bpf_debug("uprobe/HandlerFunc_ServeHTTP_Returns: entry_state is NULL");
- bpf_map_delete_elem(&http_server_context_headers, &key);
- return 0;
- }
- bpf_map_delete_elem(&http_server_uprobes, &key);
- bpf_map_delete_elem(&http_server_context_headers, &key);
- struct http_server_span_t *http_server_span = &uprobe_data->span;
- // void *resp_ptr = (void *) uprobe_data->resp_ptr;
- // void *req_ptr = NULL;
- // bpf_probe_read(&req_ptr, sizeof(req_ptr), (void *) (resp_ptr + req_ptr_pos));
- // http_server_span->end_time = end_time;
- //
- // void *url_ptr = 0;
- // bpf_probe_read(&url_ptr, sizeof(url_ptr), (void *) (req_ptr + url_ptr_pos));
- // // Collect fields from response
- // read_go_string(req_ptr, method_ptr_pos, http_server_span->method, sizeof(http_server_span->method),
- // "method from request");
- // read_go_string(url_ptr, path_ptr_pos, http_server_span->path, sizeof(http_server_span->path),
- // "path from Request.URL");
- // read_go_string(req_ptr, remote_addr_pos, http_server_span->remote_addr, sizeof(http_server_span->remote_addr),
- // "remote addr from Request.RemoteAddr");
- // read_go_string(req_ptr, host_pos, http_server_span->host, sizeof(http_server_span->host), "host from Request.Host");
- // read_go_string(req_ptr, proto_pos, http_server_span->proto, sizeof(http_server_span->proto),
- // "proto from Request.Proto");
- //
- // // status code
- // bpf_probe_read(&http_server_span->status_code, sizeof(http_server_span->status_code),
- // (void *) (resp_ptr + status_code_pos));
- //
- // bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, http_server_span, sizeof(*http_server_span));
- stop_tracking_span(&http_server_span->sc, &http_server_span->psc);
- clear_parent_span_context();
- cw_bpf_debug("HTTP_END");
- return 0;
- }
- // This instrumentation attaches uprobe to the following function:
- // func (r *Reader) readContinuedLineSlice(lim int64, validateFirstLine func([]byte) error) ([]byte, error) {
- SEC("uprobe/textproto_Reader_readContinuedLineSlice")
- int uprobe_textproto_Reader_readContinuedLineSlice_Returns(struct pt_regs *ctx) {
- void *key = (void *) GOROUTINE(ctx);
- u64 len = (u64) GO_PARAM2(ctx);
- u8 *buf = (u8 *) GO_PARAM1(ctx);
- if (len == (CW_HEADER_KEY_LENGTH + CW_HEADER_VAL_LENGTH + 2)) {
- long cw_header_native = 0x3A65636172747763LL; // 小端序下的 "cwtrace:"
- __u64 key64 = 0;
- bpf_probe_read_user(&key64, sizeof(key64), buf);
- if (key64 == cw_header_native) {
- char header_val[CW_HEADER_VAL_LENGTH] = {};
- bpf_probe_read_user(header_val, sizeof(header_val), buf + CW_HEADER_KEY_LENGTH + 2);
- cw_bpf_debug("Swiss Map:%s", header_val);
- bpf_map_update_elem(&http_server_context_headers, &key, &header_val, BPF_ANY);
- }
- }
- return 0;
- }
|