|
|
@@ -432,7 +432,7 @@ static __always_inline long cw_inject_header3(void* headers_ptr, char * header_s
|
|
|
|
|
|
if (curr_keyvalue_count == 0) {
|
|
|
// No key-value pairs in the Go map, need to "allocate" memory for the user
|
|
|
- bucket_ptr = write_target_data2(bucket_map_value, sizeof(struct map_bucket),proc_info);
|
|
|
+ bucket_ptr = cw_write_target_data(bucket_map_value, sizeof(struct map_bucket),proc_info);
|
|
|
if (bucket_ptr == NULL) {
|
|
|
cw_bpf_debug("inject_header: Failed to write bucket to user");
|
|
|
return -1;
|
|
|
@@ -446,7 +446,7 @@ static __always_inline long cw_inject_header3(void* headers_ptr, char * header_s
|
|
|
} else {
|
|
|
// There is at least 1 key-value pair, hence the bucket pointer from the user is valid
|
|
|
// Read the bucket pointer
|
|
|
- res = bpf_probe_read_user(&bucket_ptr, sizeof(bucket_ptr), buckets_ptr_ptr);
|
|
|
+ bpf_probe_read_user(&bucket_ptr, sizeof(bucket_ptr), buckets_ptr_ptr);
|
|
|
// Read the user's bucket to the eBPF map entry
|
|
|
bpf_probe_read_user(bucket_map_value, sizeof(struct map_bucket), bucket_ptr);
|
|
|
}
|
|
|
@@ -458,7 +458,7 @@ static __always_inline long cw_inject_header3(void* headers_ptr, char * header_s
|
|
|
|
|
|
// Prepare the key string for the user
|
|
|
char key[CW_HEADER_KEY_LENGTH] = CW_HEADER_KEY_VAL;
|
|
|
- void *ptr = write_target_data2(key, CW_HEADER_KEY_LENGTH,proc_info);
|
|
|
+ void *ptr = cw_write_target_data(key, CW_HEADER_KEY_LENGTH,proc_info);
|
|
|
if (ptr == NULL) {
|
|
|
cw_bpf_debug("inject_header: Failed to write key to user");
|
|
|
return -1;
|
|
|
@@ -469,20 +469,32 @@ static __always_inline long cw_inject_header3(void* headers_ptr, char * header_s
|
|
|
bucket_map_value->tophash[bucket_index] = traceparent_tophash;
|
|
|
bucket_map_value->keys[bucket_index] = (struct go_string_ot) {.len = CW_HEADER_KEY_LENGTH, .str = ptr};
|
|
|
|
|
|
+// u32 k0;
|
|
|
+// struct tail_client_ctx_t *tail_calls_context = bpf_map_lookup_elem(&tail_client_ctx_heap, &k0);
|
|
|
+// if (!tail_calls_context){
|
|
|
+// return -1;
|
|
|
+// }
|
|
|
|
|
|
// Prepare the value string slice
|
|
|
// First the value string which constains the span context
|
|
|
// char val[CW_HEADER_VAL_LENGTH];
|
|
|
// span_context_to_cw_string(propagated_ctx, val);
|
|
|
- ptr = write_target_data2(header_str, CW_HEADER_VAL_LENGTH,proc_info);
|
|
|
+ ptr = cw_write_target_data(header_str, CW_HEADER_VAL_LENGTH,proc_info);
|
|
|
if(ptr == NULL) {
|
|
|
cw_bpf_debug("inject_header: Failed to write value to user");
|
|
|
return -1;
|
|
|
}
|
|
|
+ bucket_map_value->header_value_str_p = ptr;
|
|
|
+
|
|
|
+ bucket_map_value->curr_keyvalue_count = curr_keyvalue_count;
|
|
|
+ bucket_map_value->bucket_index = bucket_index;
|
|
|
+ bucket_map_value->headers_ptr = headers_ptr;
|
|
|
+ bucket_map_value->bucket_ptr = bucket_ptr;
|
|
|
|
|
|
+ return 0;
|
|
|
// The go string pointing to the above val
|
|
|
struct go_string_ot header_value = {.len = CW_HEADER_VAL_LENGTH, .str = ptr};
|
|
|
- ptr = write_target_data2((void*)&header_value, sizeof(header_value),proc_info);
|
|
|
+ ptr = cw_write_target_data((void*)&header_value, sizeof(header_value),proc_info);
|
|
|
if(ptr == NULL) {
|
|
|
cw_bpf_debug("inject_header: Failed to write go_string to user");
|
|
|
return -1;
|
|
|
@@ -584,18 +596,18 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) {
|
|
|
// generate_random_bytes(httpReq->sc.SpanID, SPAN_ID_SIZE);
|
|
|
}
|
|
|
// }
|
|
|
- if (!get_go_string_from_user_ptr((void *)(req_ptr+proc_info->method_ptr_pos), httpReq->method, sizeof(httpReq->method))) {
|
|
|
- cw_bpf_debug("uprobe_Transport_roundTrip: Failed to get method from request");
|
|
|
- return 0;
|
|
|
- }
|
|
|
+// if (!get_go_string_from_user_ptr((void *)(req_ptr+proc_info->method_ptr_pos), httpReq->method, sizeof(httpReq->method))) {
|
|
|
+// cw_bpf_debug("uprobe_Transport_roundTrip: Failed to get method from request");
|
|
|
+// return 0;
|
|
|
+// }
|
|
|
|
|
|
// get path from Request.URL
|
|
|
- void *url_ptr = 0;
|
|
|
- bpf_probe_read(&url_ptr, sizeof(url_ptr), (void *)(req_ptr+proc_info->url_ptr_pos));
|
|
|
- if (!get_go_string_from_user_ptr((void *)(url_ptr+proc_info->path_ptr_pos), httpReq->path, sizeof(httpReq->path))) {
|
|
|
- cw_bpf_debug("uprobe_Transport_roundTrip: Failed to get path from Request.URL");
|
|
|
- return 0;
|
|
|
- }
|
|
|
+// void *url_ptr = 0;
|
|
|
+// bpf_probe_read(&url_ptr, sizeof(url_ptr), (void *)(req_ptr+proc_info->url_ptr_pos));
|
|
|
+// if (!get_go_string_from_user_ptr((void *)(url_ptr+proc_info->path_ptr_pos), httpReq->path, sizeof(httpReq->path))) {
|
|
|
+// cw_bpf_debug("uprobe_Transport_roundTrip: Failed to get path from Request.URL");
|
|
|
+// return 0;
|
|
|
+// }
|
|
|
|
|
|
// get host from Request
|
|
|
if (!get_go_string_from_user_ptr((void *)(req_ptr+proc_info->request_host_pos), httpReq->host, sizeof(httpReq->host))) {
|
|
|
@@ -638,9 +650,9 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) {
|
|
|
set_assumed_app_id_arrays(httpReq->host, httpReq->apm_sc.assumed_app_id, APM_ASSUMED_APP_ID_STRING_SIZE);
|
|
|
cw_save_current_tracking_span(&httpReq->apm_sc);
|
|
|
// get proto from Request
|
|
|
- if (!get_go_string_from_user_ptr((void *)(req_ptr+proc_info->request_proto_pos), httpReq->proto, sizeof(httpReq->proto))) {
|
|
|
- cw_bpf_debug("uprobe_Transport_roundTrip: Failed to get proto from Request");
|
|
|
- }
|
|
|
+// if (!get_go_string_from_user_ptr((void *)(req_ptr+proc_info->request_proto_pos), httpReq->proto, sizeof(httpReq->proto))) {
|
|
|
+// cw_bpf_debug("uprobe_Transport_roundTrip: Failed to get proto from Request");
|
|
|
+// }
|
|
|
|
|
|
// get headers from Request
|
|
|
void *headers_ptr = 0;
|
|
|
@@ -656,14 +668,84 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) {
|
|
|
long res2 = cw_inject_header3(headers_ptr, val,proc_info);
|
|
|
if (res2 < 0) {
|
|
|
cw_bpf_debug("uprobe_Transport_roundTrip: Failed to inject header");
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
+ bpf_tail_call(ctx, &jmp_table2, 0);
|
|
|
+
|
|
|
// Write event
|
|
|
// bpf_map_update_elem(&http_events, &key, httpReq, 0);
|
|
|
// start_tracking_span(context_ptr_val, &httpReq->sc);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
+// return 1;
|
|
|
+
|
|
|
+ __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;
|
|
|
+ }
|
|
|
+// __u32 k0;
|
|
|
+// struct tail_client_ctx_t *tail_calls_context =
|
|
|
+// bpf_map_lookup_elem(&tail_client_ctx_heap, &k0);
|
|
|
+// if (!tail_calls_context){
|
|
|
+// return -1;
|
|
|
+// }
|
|
|
+ u32 map_id = 0;
|
|
|
+
|
|
|
+ struct map_bucket *bucket_map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
|
|
|
+ if (!bucket_map_value) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (!bucket_map_value->header_value_str_p){
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (!bucket_map_value->headers_ptr){
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (!bucket_map_value->bucket_ptr){
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // The go string pointing to the above val
|
|
|
+ struct go_string_ot header_value = {.len = CW_HEADER_VAL_LENGTH, .str = bucket_map_value->header_value_str_p};
|
|
|
+ void * ptr = cw_write_target_data((void*)&header_value, sizeof(header_value),proc_info);
|
|
|
+ if(ptr == NULL) {
|
|
|
+ cw_bpf_debug("inject_header: Failed to write go_string to user");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Last, go_slice pointing to the above go_string
|
|
|
+ if (bucket_map_value->bucket_index >=8) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ bucket_map_value->values[bucket_map_value->bucket_index] = (struct go_slice_ot) {.array = ptr, .cap = 1, .len = 1};
|
|
|
+
|
|
|
+ // Update the map header count field
|
|
|
+ bucket_map_value->curr_keyvalue_count += 1;
|
|
|
+ long res = bpf_probe_write_user(bucket_map_value->headers_ptr, &bucket_map_value->curr_keyvalue_count, sizeof(bucket_map_value->curr_keyvalue_count));
|
|
|
+ if (res < 0) {
|
|
|
+ cw_bpf_debug("Failed to update key-value count in map header");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Update the bucket
|
|
|
+ res = bpf_probe_write_user(bucket_map_value->bucket_ptr, bucket_map_value, sizeof(struct map_bucket));
|
|
|
+ if (res < 0) {
|
|
|
+ cw_bpf_debug("Failed to update bucket content");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ bpf_memset((unsigned char *)bucket_map_value, sizeof(struct map_bucket), 0);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
// This instrumentation attaches uretprobe to the following function:
|
|
|
// func net/http/transport.roundTrip(req *Request) (*Response, error)
|
|
|
SEC("uprobe/Transport_roundTrip")
|