|
@@ -25,8 +25,8 @@ struct grpc_client_request_t {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// struct hpack_header_field {
|
|
// struct hpack_header_field {
|
|
|
-// struct go_string name;
|
|
|
|
|
-// struct go_string value;
|
|
|
|
|
|
|
+// struct go_string_ot name;
|
|
|
|
|
+// struct go_string_ot value;
|
|
|
// bool sensitive;
|
|
// bool sensitive;
|
|
|
// };
|
|
// };
|
|
|
|
|
|
|
@@ -52,17 +52,37 @@ struct {
|
|
|
__uint(max_entries, 1);
|
|
__uint(max_entries, 1);
|
|
|
} grpc_client_storage_map SEC(".maps");
|
|
} grpc_client_storage_map SEC(".maps");
|
|
|
|
|
|
|
|
|
|
+// 用于 loopyWriter_headerHandler 的临时存储
|
|
|
|
|
+struct header_handler_storage {
|
|
|
|
|
+ struct span_context sc;
|
|
|
|
|
+ char val[SPAN_CONTEXT_STRING_SIZE];
|
|
|
|
|
+ struct hpack_header_field hf;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+struct {
|
|
|
|
|
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
|
|
|
|
|
+ __uint(key_size, sizeof(u32));
|
|
|
|
|
+ __uint(value_size, sizeof(struct header_handler_storage));
|
|
|
|
|
+ __uint(max_entries, 1);
|
|
|
|
|
+} header_handler_storage_map SEC(".maps");
|
|
|
|
|
+
|
|
|
// Injected in init
|
|
// Injected in init
|
|
|
-volatile const u64 clientconn_target_ptr_pos;
|
|
|
|
|
-volatile const u64 httpclient_nextid_pos;
|
|
|
|
|
|
|
+// volatile const u64 clientconn_target_ptr_pos;
|
|
|
|
|
+u64 clientconn_target_ptr_pos = 24;
|
|
|
|
|
+// volatile const u64 httpclient_nextid_pos;
|
|
|
|
|
+u64 httpclient_nextid_pos = 404;
|
|
|
// volatile const u64 headerFrame_streamid_pos;
|
|
// volatile const u64 headerFrame_streamid_pos;
|
|
|
u64 headerFrame_streamid_pos = 0;
|
|
u64 headerFrame_streamid_pos = 0;
|
|
|
// volatile const u64 headerFrame_hf_pos;
|
|
// volatile const u64 headerFrame_hf_pos;
|
|
|
u64 headerFrame_hf_pos = 8;
|
|
u64 headerFrame_hf_pos = 8;
|
|
|
-volatile const u64 error_status_pos;
|
|
|
|
|
-volatile const u64 status_s_pos;
|
|
|
|
|
-volatile const u64 status_message_pos;
|
|
|
|
|
-volatile const u64 status_code_pos;
|
|
|
|
|
|
|
+// volatile const u64 error_status_pos;
|
|
|
|
|
+u64 error_status_pos = 0;
|
|
|
|
|
+// volatile const u64 status_s_pos;
|
|
|
|
|
+// static u64 status_s_pos = 0;
|
|
|
|
|
+// volatile const u64 status_message_pos;
|
|
|
|
|
+u64 status_message_pos = 48;
|
|
|
|
|
+// volatile const u64 status_code_pos;
|
|
|
|
|
+// static u64 status_code_pos = 40;
|
|
|
|
|
|
|
|
volatile const bool write_status_supported;
|
|
volatile const bool write_status_supported;
|
|
|
|
|
|
|
@@ -186,6 +206,7 @@ int uprobe_ClientConn_Invoke_Returns(struct pt_regs *ctx) {
|
|
|
(void *)(s_ptr + status_message_pos), grpc_span->err_msg, sizeof(grpc_span->err_msg));
|
|
(void *)(s_ptr + status_message_pos), grpc_span->err_msg, sizeof(grpc_span->err_msg));
|
|
|
|
|
|
|
|
done:
|
|
done:
|
|
|
|
|
+ bpf_printk("switch to the done position\n");
|
|
|
grpc_span->end_time = bpf_ktime_get_ns();
|
|
grpc_span->end_time = bpf_ktime_get_ns();
|
|
|
// output_span_event(ctx, grpc_span, sizeof(*grpc_span), &grpc_span->sc);
|
|
// output_span_event(ctx, grpc_span, sizeof(*grpc_span), &grpc_span->sc);
|
|
|
stop_tracking_span(&grpc_span->sc, &grpc_span->psc);
|
|
stop_tracking_span(&grpc_span->sc, &grpc_span->psc);
|
|
@@ -193,112 +214,26 @@ done:
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// func (l *loopyWriter) headerHandler(h *headerFrame) error
|
|
|
|
|
-// SEC("uprobe/loopyWriter_headerHandler")
|
|
|
|
|
-// int uprobe_LoopyWriter_HeaderHandler(struct pt_regs *ctx) {
|
|
|
|
|
-// bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler \n");
|
|
|
|
|
-// void *headerFrame_ptr = get_argument(ctx, 2);
|
|
|
|
|
-// // u32 stream_id = 0;
|
|
|
|
|
-// // bpf_probe_read(
|
|
|
|
|
-// // &stream_id, sizeof(stream_id), (void *)(headerFrame_ptr + (headerFrame_streamid_pos)));
|
|
|
|
|
-// // void *sc_ptr = bpf_map_lookup_elem(&streamid_to_span_contexts, &stream_id);
|
|
|
|
|
-// // if (sc_ptr == NULL) {
|
|
|
|
|
-// // return 0;
|
|
|
|
|
-// // }
|
|
|
|
|
-// bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler1111 \n");
|
|
|
|
|
-// __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;
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
-// bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler2222222\n");
|
|
|
|
|
-// // struct span_context current_span_context = {};
|
|
|
|
|
-// // bpf_probe_read(¤t_span_context, sizeof(current_span_context), sc_ptr);
|
|
|
|
|
-
|
|
|
|
|
-// char tp_key[CW_HEADER_KEY_LENGTH] = CW_HEADER_KEY_VAL;
|
|
|
|
|
-// struct go_string_ot key_str = write_user_go_string(tp_key, sizeof(tp_key));
|
|
|
|
|
-// if (key_str.len == 0) {
|
|
|
|
|
-// bpf_printk("key write failed, aborting ebpf probe");
|
|
|
|
|
-// goto done;
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-// bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler333333\n");
|
|
|
|
|
-// u32 map_id = 0;
|
|
|
|
|
-// struct grpc_client_request_t *grpcClientReq = bpf_map_lookup_elem(&grpc_client_storage_map, &map_id);
|
|
|
|
|
-// if (grpcClientReq == NULL)
|
|
|
|
|
-// {
|
|
|
|
|
-// cw_bpf_debug("uprobe_LoopyWriter_HeaderHandler: grpcClientReq is NULL");
|
|
|
|
|
-// return 0;
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
-// __builtin_memset(grpcClientReq, 0, sizeof(struct grpc_client_request_t));
|
|
|
|
|
-// grpcClientReq->start_time = bpf_ktime_get_ns();
|
|
|
|
|
-
|
|
|
|
|
-// bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler444444\n");
|
|
|
|
|
-// struct apm_span_context *cw_psc = cw_get_parent_tracking_span();
|
|
|
|
|
-// if(cw_psc){
|
|
|
|
|
-// bpf_probe_read(&grpcClientReq->apm_psc, sizeof(grpcClientReq->apm_psc), cw_psc);
|
|
|
|
|
-// copy_byte_arrays(grpcClientReq->apm_psc.trace_id, grpcClientReq->apm_sc.trace_id, APM_TRACE_ID_SIZE);
|
|
|
|
|
-// generate_random_bytes(grpcClientReq->apm_sc.span_id, APM_SPAN_ID_SIZE);
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
-// u32 k0 = 0;
|
|
|
|
|
-// struct trace_conf_t *trace_conf = trace_conf_map__lookup(&k0);
|
|
|
|
|
-// if (trace_conf) {
|
|
|
|
|
-// copy_byte_arrays(trace_conf->host_id, grpcClientReq->apm_sc.host_id, APM_HOST_ID_SIZE);
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
-// copy_byte_arrays(proc_info->instance_id, grpcClientReq->apm_sc.instance_id, APM_APP_ID_SIZE);
|
|
|
|
|
-// copy_byte_arrays(proc_info->app_id, grpcClientReq->apm_sc.app_id, APM_APP_ID_SIZE);
|
|
|
|
|
-
|
|
|
|
|
-// // set assumed_app_id
|
|
|
|
|
-// // set_assumed_app_id_arrays(httpReq->host, httpReq->apm_sc.assumed_app_id, APM_ASSUMED_APP_ID_STRING_SIZE);
|
|
|
|
|
-// cw_save_current_tracking_span(&grpcClientReq->apm_sc);
|
|
|
|
|
-
|
|
|
|
|
-// // Write headers
|
|
|
|
|
-// char val[CW_HEADER_VAL_LENGTH];
|
|
|
|
|
-// span_context_to_cw_string(&grpcClientReq->apm_sc, val);
|
|
|
|
|
-// struct go_string_ot val_str = write_user_go_string(val, sizeof(val));
|
|
|
|
|
-// if (val_str.len == 0) {
|
|
|
|
|
-// bpf_printk("val write failed, aborting ebpf probe");
|
|
|
|
|
-// goto done;
|
|
|
|
|
-// }
|
|
|
|
|
-// bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler6666\n");
|
|
|
|
|
-// struct hpack_header_field hf = {};
|
|
|
|
|
-// hf.name = key_str;
|
|
|
|
|
-// hf.value = val_str;
|
|
|
|
|
-// append_item_to_slice(&hf, sizeof(hf), (void *)(headerFrame_ptr + (headerFrame_hf_pos)));
|
|
|
|
|
-// done:
|
|
|
|
|
-// // bpf_map_delete_elem(&streamid_to_span_contexts, &stream_id);
|
|
|
|
|
-
|
|
|
|
|
-// return 0;
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
static __always_inline void
|
|
static __always_inline void
|
|
|
cw_append_item_to_slice(void *new_item, u32 item_size, void *slice_user_ptr) {
|
|
cw_append_item_to_slice(void *new_item, u32 item_size, void *slice_user_ptr) {
|
|
|
// read the slice descriptor
|
|
// read the slice descriptor
|
|
|
struct go_slice_ot slice = {0};
|
|
struct go_slice_ot slice = {0};
|
|
|
- bpf_probe_read(&slice, sizeof(slice), slice_user_ptr);
|
|
|
|
|
- long res = 0;
|
|
|
|
|
|
|
+ long res = bpf_probe_read_user(&slice, sizeof(slice), slice_user_ptr);
|
|
|
|
|
+ if (res != 0) {
|
|
|
|
|
+ bpf_printk("cw_append_item_to_slice: failed to read slice descriptor, res=%ld\n", res);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
bpf_printk("cw_append_item_to_slice len is %d\n", slice.len);
|
|
bpf_printk("cw_append_item_to_slice len is %d\n", slice.len);
|
|
|
bpf_printk("cw_append_item_to_slice cap is %d\n", slice.cap);
|
|
bpf_printk("cw_append_item_to_slice cap is %d\n", slice.cap);
|
|
|
|
|
+ bpf_printk("cw_append_item_to_slice array is %p\n", slice.array);
|
|
|
|
|
|
|
|
u64 slice_len = slice.len;
|
|
u64 slice_len = slice.len;
|
|
|
u64 slice_cap = slice.cap;
|
|
u64 slice_cap = slice.cap;
|
|
|
if (slice_len < slice_cap && slice.array != NULL) {
|
|
if (slice_len < slice_cap && slice.array != NULL) {
|
|
|
// Room available on current array, append to the underlying array
|
|
// Room available on current array, append to the underlying array
|
|
|
bpf_printk("enter the cw_append_item_to_slice11111\n");
|
|
bpf_printk("enter the cw_append_item_to_slice11111\n");
|
|
|
- // struct hpack_header_field hf = {};
|
|
|
|
|
- // bpf_probe_read(&hf, sizeof(hf), slice.array + (item_size * 6));
|
|
|
|
|
- // bpf_printk("cw_append_item_to_slice hf.name.str is %s\n", hf.name.str);
|
|
|
|
|
- // bpf_printk("cw_append_item_to_slice hf.value.str is %s\n", hf.value.str);
|
|
|
|
|
res = bpf_probe_write_user(slice.array + (item_size * slice_len), new_item, item_size);
|
|
res = bpf_probe_write_user(slice.array + (item_size * slice_len), new_item, item_size);
|
|
|
} else {
|
|
} else {
|
|
|
// No room on current array - try to copy new one of size item_size * (len + 1)
|
|
// No room on current array - try to copy new one of size item_size * (len + 1)
|
|
@@ -359,41 +294,61 @@ cw_append_item_to_slice(void *new_item, u32 item_size, void *slice_user_ptr) {
|
|
|
SEC("uprobe/loopyWriter_headerHandler")
|
|
SEC("uprobe/loopyWriter_headerHandler")
|
|
|
int uprobe_LoopyWriter_HeaderHandler(struct pt_regs *ctx) {
|
|
int uprobe_LoopyWriter_HeaderHandler(struct pt_regs *ctx) {
|
|
|
void *headerFrame_ptr = get_argument(ctx, 2);
|
|
void *headerFrame_ptr = get_argument(ctx, 2);
|
|
|
- u32 stream_id = 0;
|
|
|
|
|
- bpf_probe_read(
|
|
|
|
|
- &stream_id, sizeof(stream_id), (void *)(headerFrame_ptr + (headerFrame_streamid_pos)));
|
|
|
|
|
- // void *sc_ptr = bpf_map_lookup_elem(&streamid_to_span_contexts, &stream_id);
|
|
|
|
|
- // if (sc_ptr == NULL) {
|
|
|
|
|
- // return 0;
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // struct span_context current_span_context = {};
|
|
|
|
|
- // bpf_probe_read(¤t_span_context, sizeof(current_span_context), sc_ptr);
|
|
|
|
|
|
|
+ bpf_printk("enter the get header handler storage\n");
|
|
|
|
|
+
|
|
|
|
|
+ // Get storage from per-cpu map
|
|
|
|
|
+ u32 zero = 0;
|
|
|
|
|
+ struct header_handler_storage *storage = bpf_map_lookup_elem(&header_handler_storage_map, &zero);
|
|
|
|
|
+ if (!storage) {
|
|
|
|
|
+ bpf_printk("Failed to get header handler storage\n");
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Generate span context
|
|
|
|
|
+ generate_random_bytes(storage->sc.TraceID, TRACE_ID_SIZE);
|
|
|
|
|
+ generate_random_bytes(storage->sc.SpanID, SPAN_ID_SIZE);
|
|
|
|
|
|
|
|
|
|
+ // Strategy: Write key and value separately with manual offset
|
|
|
|
|
+ // First write the key
|
|
|
char tp_key[11] = "traceparent";
|
|
char tp_key[11] = "traceparent";
|
|
|
- struct go_string_ot key_str = write_user_go_string(tp_key, sizeof(tp_key));
|
|
|
|
|
- if (key_str.len == 0) {
|
|
|
|
|
- bpf_printk("key write failed, aborting ebpf probe");
|
|
|
|
|
- goto done;
|
|
|
|
|
|
|
+ char *key_data_addr = write_target_data((void *)tp_key, sizeof(tp_key));
|
|
|
|
|
+ if (key_data_addr == NULL) {
|
|
|
|
|
+ bpf_printk("Key data write failed\n");
|
|
|
|
|
+ return 0;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // Write headers
|
|
|
|
|
- char val[SPAN_CONTEXT_STRING_SIZE] = "11111111";
|
|
|
|
|
- // span_context_to_w3c_string(¤t_span_context, val);
|
|
|
|
|
- struct go_string_ot val_str = write_user_go_string(val, sizeof(val));
|
|
|
|
|
- if (val_str.len == 0) {
|
|
|
|
|
- bpf_printk("val write failed, aborting ebpf probe");
|
|
|
|
|
- goto done;
|
|
|
|
|
|
|
+ bpf_printk("key_data_addr=%p\n", key_data_addr);
|
|
|
|
|
+
|
|
|
|
|
+ // Manually advance the pointer for value (workaround for alloc_map bug)
|
|
|
|
|
+ // Allocate enough space: align to 8 bytes
|
|
|
|
|
+ u64 key_size_aligned = ((sizeof(tp_key) + 7) / 8) * 8;
|
|
|
|
|
+
|
|
|
|
|
+ // Write value at offset from key
|
|
|
|
|
+ span_context_to_w3c_string(&storage->sc, storage->val);
|
|
|
|
|
+
|
|
|
|
|
+ // Try to write value with manual offset
|
|
|
|
|
+ char *val_data_addr = key_data_addr + key_size_aligned;
|
|
|
|
|
+ long val_write_result = bpf_probe_write_user(val_data_addr, storage->val, sizeof(storage->val));
|
|
|
|
|
+ bpf_printk("val_data_addr=%p, write_result=%ld\n", val_data_addr, val_write_result);
|
|
|
|
|
+
|
|
|
|
|
+ if (val_write_result != 0) {
|
|
|
|
|
+ bpf_printk("Val direct write failed\n");
|
|
|
|
|
+ return 0;
|
|
|
}
|
|
}
|
|
|
- struct hpack_header_field hf = {};
|
|
|
|
|
- hf.name = key_str;
|
|
|
|
|
- hf.value = val_str;
|
|
|
|
|
- hf.sensitive = false;
|
|
|
|
|
- bpf_printk("uprobe_LoopyWriter_HeaderHandler hf.name.str is %s\n", key_str.str);
|
|
|
|
|
- bpf_printk("uprobe_LoopyWriter_HeaderHandler hf.value.str is %s\n", val_str.str);
|
|
|
|
|
- cw_append_item_to_slice(&hf, sizeof(hf), (void *)(headerFrame_ptr + (headerFrame_hf_pos)));
|
|
|
|
|
-done:
|
|
|
|
|
- bpf_map_delete_elem(&streamid_to_span_contexts, &stream_id);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ struct go_string_ot key_str = {.str = key_data_addr, .len = sizeof(tp_key)};
|
|
|
|
|
+ struct go_string_ot val_str = {.str = val_data_addr, .len = sizeof(storage->val)};
|
|
|
|
|
+
|
|
|
|
|
+ bpf_printk("key_str: len=%d, ptr=%p\n", key_str.len, key_str.str);
|
|
|
|
|
+ bpf_printk("val_str: len=%d, ptr=%p\n", val_str.len, val_str.str);
|
|
|
|
|
+
|
|
|
|
|
+ // Build header field
|
|
|
|
|
+ storage->hf.name = key_str;
|
|
|
|
|
+ storage->hf.value = val_str;
|
|
|
|
|
+ storage->hf.sensitive = false;
|
|
|
|
|
+
|
|
|
|
|
+ // Append to slice
|
|
|
|
|
+ void *slice_ptr = (void *)(headerFrame_ptr + headerFrame_hf_pos);
|
|
|
|
|
+ cw_append_item_to_slice(&storage->hf, sizeof(storage->hf), slice_ptr);
|
|
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
@@ -411,6 +366,7 @@ int uprobe_http2Client_NewStream(struct pt_regs *ctx) {
|
|
|
// // the context here is derived from the Invoke context.
|
|
// // the context here is derived from the Invoke context.
|
|
|
// struct span_context *current_span_context = get_parent_span_context(&go_context);
|
|
// struct span_context *current_span_context = get_parent_span_context(&go_context);
|
|
|
// if (current_span_context != NULL) {
|
|
// if (current_span_context != NULL) {
|
|
|
|
|
+ // bpf_printk("uprobe_http2Client_NewStream streamid is %d\n", nextid);
|
|
|
// bpf_map_update_elem(&streamid_to_span_contexts, &nextid, current_span_context, 0);
|
|
// bpf_map_update_elem(&streamid_to_span_contexts, &nextid, current_span_context, 0);
|
|
|
// }
|
|
// }
|
|
|
|
|
|