This is an automated email from the ASF dual-hosted git repository.

liuhan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-rover.git


The following commit(s) were added to refs/heads/main by this push:
     new 8252217  Support monitoring TLS-based network data in continuous 
profiling (#79)
8252217 is described below

commit 8252217ce94bf2f8cdc00fd7f708f04ae344449e
Author: mrproliu <[email protected]>
AuthorDate: Fri Feb 24 09:58:53 2023 +0800

    Support monitoring TLS-based network data in continuous profiling (#79)
---
 bpf/include/goid.c                                 |  70 +++
 .../network/go_tls.h => include/symbol_offsets.h}  | 146 +++--
 bpf/profiling/{network => continuous}/go_tls.c     | 106 ++--
 .../{network/openssl.h => continuous/go_tls.h}     |  25 +-
 bpf/profiling/continuous/network.c                 |  32 +-
 bpf/profiling/continuous/network.h                 |   2 +-
 bpf/profiling/continuous/openssl.c                 | 106 ++++
 bpf/profiling/{network => continuous}/openssl.h    |  20 +-
 bpf/profiling/network/go_tls.c                     |  46 +-
 bpf/profiling/network/go_tls.h                     | 104 +---
 bpf/profiling/network/netmonitor.c                 |   4 -
 bpf/profiling/network/openssl.c                    |   3 +-
 bpf/profiling/network/openssl.h                    |  18 -
 pkg/process/finders/base/tool.go                   |   4 +-
 .../continuous/checker/bpf/network/http1.go        |   2 +-
 .../continuous/checker/bpf/network/network.go      |  55 +-
 .../continuous/checker/bpf/network/process.go      |  82 +++
 .../continuous/checker/bpf/network/reader.go       |   2 +-
 .../continuous/checker/bpf/network/ssl.go          |  37 +-
 pkg/profiling/task/network/analyze/base/enums.go   |   7 -
 pkg/profiling/task/network/ssl.go                  | 595 +--------------------
 pkg/profiling/task/offcpu/runner.go                |  10 +-
 pkg/profiling/task/oncpu/runner.go                 |  10 +-
 pkg/tools/btf/linker.go                            |   4 +-
 pkg/tools/{ => process}/process.go                 |  10 +-
 pkg/tools/ssl/envoy.go                             |  75 +++
 pkg/tools/ssl/gotls.go                             | 258 +++++++++
 pkg/tools/ssl/node.go                              | 211 ++++++++
 pkg/tools/ssl/openssl.go                           | 141 +++++
 .../ssl_test.go => tools/ssl/openssl_test.go}      |  19 +-
 pkg/tools/ssl/ssl.go                               | 146 +++++
 31 files changed, 1335 insertions(+), 1015 deletions(-)

diff --git a/bpf/include/goid.c b/bpf/include/goid.c
new file mode 100644
index 0000000..80c0813
--- /dev/null
+++ b/bpf/include/goid.c
@@ -0,0 +1,70 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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 "symbol_offsets.h"
+
+struct {
+       __uint(type, BPF_MAP_TYPE_HASH);
+       __uint(max_entries, 1024);
+       __type(key, __u64);
+       __type(value, __u64);
+} go_tgid_goid_map SEC(".maps");
+static __inline __u64 get_goid(__u64 id) {
+    __u64 *val;
+    val = bpf_map_lookup_elem(&go_tgid_goid_map, &id);
+    return !val ? 0 : *val;
+}
+static __inline void set_goid(__u64 id, __u64 goid) {
+    bpf_map_update_elem(&go_tgid_goid_map, &id, &goid, 0);
+}
+
+SEC("uprobe/casgstatus")
+int go_casgstatus(struct pt_regs* ctx) {
+    const void* sp = (const void*)PT_REGS_SP(ctx);
+    __u64* regs = go_regabi_regs(ctx);
+    if (regs == NULL) {
+       return 0;
+    }
+
+    __u64 id = bpf_get_current_pid_tgid();
+    __u32 tgid = id >> 32;
+    struct go_tls_args_symaddr_t* symaddrs = get_go_tls_args_symaddr(tgid);
+    if (symaddrs == NULL) {
+       return 0;
+    }
+
+    // get runtime.g
+    void* gptr = NULL;
+    assign_go_tls_arg(&gptr, sizeof(gptr), symaddrs->casg_status_gp_loc, sp, 
regs);
+    if (gptr == NULL) {
+        return 0;
+    }
+
+    // get goid in runtime.g
+    int64_t goid;
+    bpf_probe_read(&goid, sizeof(goid), gptr + symaddrs->gid_offset);
+
+    // newval in runtime.g
+    __u32 status;
+    assign_go_tls_arg(&status, sizeof(status), 
symaddrs->casg_status_new_val_loc, sp, regs);
+
+    // check the status is running
+    if (status == 2) {
+        set_goid(id, goid);
+    }
+    return 0;
+}
\ No newline at end of file
diff --git a/bpf/profiling/network/go_tls.h b/bpf/include/symbol_offsets.h
similarity index 66%
copy from bpf/profiling/network/go_tls.h
copy to bpf/include/symbol_offsets.h
index 1428a4e..33b19ef 100644
--- a/bpf/profiling/network/go_tls.h
+++ b/bpf/include/symbol_offsets.h
@@ -15,61 +15,36 @@
 // specific language governing permissions and limitations
 // under the License.
 
-struct go_tls_arg_location_t {
-    __u32 type;
-    __u32 offset;
-};
-
-struct go_tls_args_symaddr_t {
-    __u64 fd_sys_offset;
-    __u64 tls_conn_offset;
-    __u64 gid_offset;
-    __u64 tcp_conn_offset;
-
-    // casg
-    struct go_tls_arg_location_t casg_status_gp_loc;
-    struct go_tls_arg_location_t casg_status_new_val_loc;
-
-    // read
-    struct go_tls_arg_location_t read_connection_loc;
-    struct go_tls_arg_location_t read_buffer_loc;
-    struct go_tls_arg_location_t read_ret0_loc;
-    struct go_tls_arg_location_t read_ret1_loc;
-
-    // write
-    struct go_tls_arg_location_t write_connection_loc;
-    struct go_tls_arg_location_t write_buffer_loc;
-    struct go_tls_arg_location_t write_ret0_loc;
-    struct go_tls_arg_location_t write_ret1_loc;
+#pragma once
+
+// ------------------------------------------ openssl start 
-------------------------------------------------------
+struct openssl_symaddr {
+    // read the BIO offset from ssl
+    __u32 bio_read_offset;
+    __u32 bio_write_offset;
+    // read the fd offset from BIO
+    __u32 fd_offset;
+    // read the SSL is server side or not
+    __u32 server_offset;
 };
 
 struct {
        __uint(type, BPF_MAP_TYPE_HASH);
        __uint(max_entries, 10000);
        __type(key, __u32);
-       __type(value, struct go_tls_args_symaddr_t);
-} go_tls_args_symaddr_map SEC(".maps");
-static __always_inline struct go_tls_args_symaddr_t* 
get_go_tls_args_symaddr(__u32 tgid) {
-    struct go_tls_args_symaddr_t *addr = 
bpf_map_lookup_elem(&go_tls_args_symaddr_map, &tgid);
+       __type(value, struct openssl_symaddr);
+} openssl_symaddr_map SEC(".maps");
+static __inline struct openssl_symaddr* get_openssl_symaddr(__u32 tgid) {
+    struct openssl_symaddr *addr = bpf_map_lookup_elem(&openssl_symaddr_map, 
&tgid);
     return addr;
 }
+// ------------------------------------------ openssl end 
-------------------------------------------------------
 
-struct go_tls_tgid_goid_t {
-    __u64 tgid;
-    __u64 goid;
-};
-struct go_tls_connection_args_t {
-    void* connection_ptr;
-    char* buffer_ptr;
-    __u64 start_nacs;
+// ------------------------------------------ go tls start 
-------------------------------------------------------
+struct go_tls_arg_location_t {
+    __u32 type;
+    __u32 offset;
 };
-struct {
-       __uint(type, BPF_MAP_TYPE_HASH);
-       __uint(max_entries, 10000);
-       __type(key, struct go_tls_tgid_goid_t);
-       __type(value, struct go_tls_connection_args_t);
-} go_tls_active_connection_args SEC(".maps");
-
 
 struct go_regabi_regs_t {
     __u64 regs[9];
@@ -82,7 +57,7 @@ struct {
 } go_regabi_regs_map SEC(".maps");
 // Copies the registers of the golang ABI, so that they can be
 // easily accessed using an offset.
-static __always_inline uint64_t* go_regabi_regs(const struct pt_regs* ctx) {
+static __always_inline __u64* go_regabi_regs(const struct pt_regs* ctx) {
     __u32 zero = 0;
     struct go_regabi_regs_t* regs_heap_var = 
bpf_map_lookup_elem(&go_regabi_regs_map, &zero);
     if (regs_heap_var == NULL) {
@@ -102,13 +77,43 @@ static __always_inline uint64_t* go_regabi_regs(const 
struct pt_regs* ctx) {
     return regs_heap_var->regs;
 }
 
-struct go_interface {
-    int64_t type;
-    void* ptr;
+struct go_tls_args_symaddr_t {
+    __u64 fd_sys_offset;
+    __u64 tls_conn_offset;
+    __u64 gid_offset;
+    __u64 tcp_conn_offset;
+    __u64 is_client_offset;
+
+    // casg
+    struct go_tls_arg_location_t casg_status_gp_loc;
+    struct go_tls_arg_location_t casg_status_new_val_loc;
+
+    // read
+    struct go_tls_arg_location_t read_connection_loc;
+    struct go_tls_arg_location_t read_buffer_loc;
+    struct go_tls_arg_location_t read_ret0_loc;
+    struct go_tls_arg_location_t read_ret1_loc;
+
+    // write
+    struct go_tls_arg_location_t write_connection_loc;
+    struct go_tls_arg_location_t write_buffer_loc;
+    struct go_tls_arg_location_t write_ret0_loc;
+    struct go_tls_arg_location_t write_ret1_loc;
 };
 
+struct {
+       __uint(type, BPF_MAP_TYPE_HASH);
+       __uint(max_entries, 10000);
+       __type(key, __u32);
+       __type(value, struct go_tls_args_symaddr_t);
+} go_tls_args_symaddr_map SEC(".maps");
+static __always_inline struct go_tls_args_symaddr_t* 
get_go_tls_args_symaddr(__u32 tgid) {
+    struct go_tls_args_symaddr_t *addr = 
bpf_map_lookup_elem(&go_tls_args_symaddr_map, &tgid);
+    return addr;
+}
+
 static __always_inline void assign_go_tls_arg(void* arg, size_t arg_size, 
struct go_tls_arg_location_t loc, const void* sp,
-                                uint64_t* regs) {
+                                __u64* regs) {
     // stack type
     if (loc.type == 1) {
         bpf_probe_read(arg, arg_size, sp + loc.offset);
@@ -120,32 +125,25 @@ static __always_inline void assign_go_tls_arg(void* arg, 
size_t arg_size, struct
     }
 }
 
-static __always_inline int get_fd_from_go_tls_conn(struct go_interface conn, 
struct go_tls_args_symaddr_t* symaddr) {
-    // read connection
-    bpf_probe_read(&conn, sizeof(conn), conn.ptr + symaddr->tls_conn_offset);
-
-    if (conn.type != symaddr->tcp_conn_offset) {
-        return 0;
-    }
+struct go_interface {
+    int64_t type;
+    void* ptr;
+};
+// ------------------------------------------ go tls end 
-------------------------------------------------------
 
-    void* fd_ptr;
-    bpf_probe_read(&fd_ptr, sizeof(fd_ptr), conn.ptr);
-    __u64 sysfd;
-    bpf_probe_read(&sysfd, sizeof(sysfd), fd_ptr + symaddr->fd_sys_offset);
-    return sysfd;
-}
+// ------------------------------------------ envoy tls start 
-------------------------------------------------------
+struct envoy_tls_args_symaddr_t {
+    __u64 is_server_offset;
+};
 
 struct {
        __uint(type, BPF_MAP_TYPE_HASH);
-       __uint(max_entries, 1024);
-       __type(key, __u64);
-       __type(value, __u64);
-} go_tgid_goid_map SEC(".maps");
-static __inline __u64 get_goid(__u64 tgid) {
-    __u64 *val;
-    val = bpf_map_lookup_elem(&go_tgid_goid_map, &tgid);
-    return !val ? 0 : *val;
+       __uint(max_entries, 10000);
+       __type(key, __u32);
+       __type(value, struct envoy_tls_args_symaddr_t);
+} envoy_tls_args_symaddr_map SEC(".maps");
+static __always_inline struct envoy_tls_args_symaddr_t* 
get_envoy_tls_args_symaddr(__u32 tgid) {
+    struct envoy_tls_args_symaddr_t *addr = 
bpf_map_lookup_elem(&envoy_tls_args_symaddr_map, &tgid);
+    return addr;
 }
-static __inline void set_goid(__u64 tgid, __u64 goid) {
-    bpf_map_update_elem(&go_tgid_goid_map, &tgid, &goid, 0);
-}
\ No newline at end of file
+// ------------------------------------------ envoy tls end 
-------------------------------------------------------
\ No newline at end of file
diff --git a/bpf/profiling/network/go_tls.c b/bpf/profiling/continuous/go_tls.c
similarity index 67%
copy from bpf/profiling/network/go_tls.c
copy to bpf/profiling/continuous/go_tls.c
index d7af96b..60ed538 100644
--- a/bpf/profiling/network/go_tls.c
+++ b/bpf/profiling/continuous/go_tls.c
@@ -16,49 +16,17 @@
 // under the License.
 
 #include "go_tls.h"
+#include "goid.c"
 
-SEC("uprobe/casgstatus")
-int go_casgstatus(struct pt_regs* ctx) {
-    const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
-    if (regs == NULL) {
-       return 0;
-    }
-
+SEC("uprobe/go_tls_write")
+int go_tls_write(struct pt_regs* ctx) {
     __u64 id = bpf_get_current_pid_tgid();
     __u32 tgid = id >> 32;
-    struct go_tls_args_symaddr_t* symaddrs = get_go_tls_args_symaddr(tgid);
-    if (symaddrs == NULL) {
-       return 0;
-    }
 
-    // get runtime.g
-    void* gptr = NULL;
-    assign_go_tls_arg(&gptr, sizeof(gptr), symaddrs->casg_status_gp_loc, sp, 
regs);
-    if (gptr == NULL) {
+    if (tgid_should_trace(tgid) == false) {
         return 0;
     }
 
-    // get goid in runtime.g
-    int64_t goid;
-    bpf_probe_read(&goid, sizeof(goid), gptr + symaddrs->gid_offset);
-
-    // newval in runtime.g
-    __u32 status;
-    assign_go_tls_arg(&status, sizeof(status), 
symaddrs->casg_status_new_val_loc, sp, regs);
-
-    // check the status is running
-    if (status == 2) {
-        set_goid(id, goid);
-    }
-    return 0;
-}
-
-SEC("uprobe/go_tls_write")
-int go_tls_write(struct pt_regs* ctx) {
-    __u64 id = bpf_get_current_pid_tgid();
-    __u32 tgid = id >> 32;
-
     __u64 goid = get_goid(id);
     if (goid == 0) {
         return 0;
@@ -70,17 +38,24 @@ int go_tls_write(struct pt_regs* ctx) {
     }
 
     const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
+    __u64* regs = go_regabi_regs(ctx);
     if (regs == NULL) {
         return 0;
     }
 
+    // ignore if the connection is client side
+    struct go_tls_connection_args_t data_args = {};
+    assign_go_tls_arg(&data_args.connection_ptr, 
sizeof(data_args.connection_ptr), symaddrs->write_connection_loc, sp, regs);
+    __u8 is_client;
+    bpf_probe_read(&is_client, sizeof(is_client), data_args.connection_ptr + 
symaddrs->is_client_offset);
+    if (is_client == 1) {
+        return 0;
+    }
+
     struct go_tls_tgid_goid_t tgid_goid = {};
     tgid_goid.tgid = tgid;
     tgid_goid.goid = goid;
 
-    struct go_tls_connection_args_t data_args = {};
-    assign_go_tls_arg(&data_args.connection_ptr, 
sizeof(data_args.connection_ptr), symaddrs->write_connection_loc, sp, regs);
     assign_go_tls_arg(&data_args.buffer_ptr, sizeof(data_args.buffer_ptr), 
symaddrs->write_buffer_loc, sp, regs);
     data_args.start_nacs = bpf_ktime_get_ns();
     bpf_map_update_elem(&go_tls_active_connection_args, &tgid_goid, 
&data_args, 0);
@@ -103,7 +78,7 @@ int go_tls_write_ret(struct pt_regs* ctx) {
     }
 
     const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
+    __u64* regs = go_regabi_regs(ctx);
     if (regs == NULL) {
         return 0;
     }
@@ -122,22 +97,10 @@ int go_tls_write_ret(struct pt_regs* ctx) {
 
     struct go_tls_connection_args_t *args = 
bpf_map_lookup_elem(&go_tls_active_connection_args, &tgid_goid);
     if (args) {
-        struct go_interface conn_intf = {};
-        conn_intf.type = 1;
-        conn_intf.ptr = args->connection_ptr;
-        int fd = get_fd_from_go_tls_conn(conn_intf, symaddrs);
-
-        set_conn_as_ssl(ctx, tgid, fd, SOCKET_OPTS_TYPE_GOTLS_WRITE);
-
-        struct sock_data_args_t data_args = {};
-        data_args.fd = fd;
-        data_args.buf = args->buffer_ptr;
-        data_args.start_nacs = args->start_nacs;
-        data_args.data_id = ssl_get_data_id(6, id, fd);
-
-        process_write_data(ctx, id, &data_args, retval0, 
SOCK_DATA_DIRECTION_EGRESS, false, SOCKET_OPTS_TYPE_GOTLS_WRITE, true);
+        process_data(ctx, id, args->connection_ptr, args->buffer_ptr, retval0, 
args->start_nacs);
     }
     bpf_map_delete_elem(&go_tls_active_connection_args, &tgid_goid);
+
     return 0;
 }
 
@@ -146,6 +109,10 @@ int go_tls_read(struct pt_regs* ctx) {
     __u64 id = bpf_get_current_pid_tgid();
     __u32 tgid = id >> 32;
 
+    if (tgid_should_trace(tgid) == false) {
+        return 0;
+    }
+
     __u64 goid = get_goid(id);
     if (goid == 0) {
         return 0;
@@ -157,19 +124,25 @@ int go_tls_read(struct pt_regs* ctx) {
     }
 
     const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
+    __u64* regs = go_regabi_regs(ctx);
     if (regs == NULL) {
         return 0;
     }
 
+    // ignore if the connection is client side
+    struct go_tls_connection_args_t data_args = {};
+    assign_go_tls_arg(&data_args.connection_ptr, 
sizeof(data_args.connection_ptr), symaddrs->write_connection_loc, sp, regs);
+    __u8 is_client;
+    bpf_probe_read(&is_client, sizeof(is_client), data_args.connection_ptr + 
symaddrs->is_client_offset);
+    if (is_client == 1) {
+        return 0;
+    }
+
     struct go_tls_tgid_goid_t tgid_goid = {};
     tgid_goid.tgid = tgid;
     tgid_goid.goid = goid;
 
-    struct go_tls_connection_args_t data_args = {};
-    assign_go_tls_arg(&data_args.connection_ptr, 
sizeof(data_args.connection_ptr), symaddrs->read_connection_loc, sp, regs);
     assign_go_tls_arg(&data_args.buffer_ptr, sizeof(data_args.buffer_ptr), 
symaddrs->read_buffer_loc, sp, regs);
-    data_args.start_nacs = bpf_ktime_get_ns();
     bpf_map_update_elem(&go_tls_active_connection_args, &tgid_goid, 
&data_args, 0);
     return 0;
 }
@@ -190,7 +163,7 @@ int go_tls_read_ret(struct pt_regs* ctx) {
     }
 
     const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
+    __u64* regs = go_regabi_regs(ctx);
     if (regs == NULL) {
         return 0;
     }
@@ -209,20 +182,7 @@ int go_tls_read_ret(struct pt_regs* ctx) {
 
     struct go_tls_connection_args_t *args = 
bpf_map_lookup_elem(&go_tls_active_connection_args, &tgid_goid);
     if (args) {
-        struct go_interface conn_intf = {};
-        conn_intf.type = 1;
-        conn_intf.ptr = args->connection_ptr;
-        int fd = get_fd_from_go_tls_conn(conn_intf, symaddrs);
-
-        set_conn_as_ssl(ctx, tgid, fd, SOCKET_OPTS_TYPE_GOTLS_READ);
-
-        struct sock_data_args_t data_args = {};
-        data_args.fd = fd;
-        data_args.buf = args->buffer_ptr;
-        data_args.start_nacs = args->start_nacs;
-        data_args.data_id = ssl_get_data_id(8, id, fd);
-
-        process_write_data(ctx, id, &data_args, retval0, 
SOCK_DATA_DIRECTION_INGRESS, false, SOCKET_OPTS_TYPE_GOTLS_WRITE, true);
+        process_data(ctx, id, args->connection_ptr, args->buffer_ptr, retval0, 
bpf_ktime_get_ns());
     }
     bpf_map_delete_elem(&go_tls_active_connection_args, &tgid_goid);
     return 0;
diff --git a/bpf/profiling/network/openssl.h b/bpf/profiling/continuous/go_tls.h
similarity index 65%
copy from bpf/profiling/network/openssl.h
copy to bpf/profiling/continuous/go_tls.h
index 61e8425..43d3bff 100644
--- a/bpf/profiling/network/openssl.h
+++ b/bpf/profiling/continuous/go_tls.h
@@ -15,21 +15,18 @@
 // specific language governing permissions and limitations
 // under the License.
 
-struct openssl_fd_symaddr {
-    // read the BIO offset from ssl
-    __u32 bio_read_offset;
-    __u32 bio_write_offset;
-    // read the fd offset from BIO
-    __u32 fd_offset;
+struct go_tls_tgid_goid_t {
+    __u64 tgid;
+    __u64 goid;
+};
+struct go_tls_connection_args_t {
+    void* connection_ptr;
+    char* buffer_ptr;
+    __u64 start_nacs;
 };
-
 struct {
        __uint(type, BPF_MAP_TYPE_HASH);
        __uint(max_entries, 10000);
-       __type(key, __u32);
-       __type(value, struct openssl_fd_symaddr);
-} openssl_fd_symaddr_finder SEC(".maps");
-static __inline struct openssl_fd_symaddr* get_openssl_fd_symaddr(__u32 tgid) {
-    struct openssl_fd_symaddr *addr = 
bpf_map_lookup_elem(&openssl_fd_symaddr_finder, &tgid);
-    return addr;
-}
+       __type(key, struct go_tls_tgid_goid_t);
+       __type(value, struct go_tls_connection_args_t);
+} go_tls_active_connection_args SEC(".maps");
\ No newline at end of file
diff --git a/bpf/profiling/continuous/network.c 
b/bpf/profiling/continuous/network.c
index cd0a603..c37bdfc 100644
--- a/bpf/profiling/continuous/network.c
+++ b/bpf/profiling/continuous/network.c
@@ -53,13 +53,7 @@ static __always_inline bool socket_should_trace(__u64 id, 
struct sock *sock) {
     return true;
 }
 
-static __always_inline void process_data(struct pt_regs *ctx, __u64 id, void 
*channel_ref, struct msghdr *msg) {
-    const struct iovec *iovec;
-    iovec = _KERNEL(msg->msg_iter.iov);
-    struct iovec iov;
-    bpf_probe_read(&iov, sizeof(iov), iovec);
-    char* buf = (char *)iov.iov_base;
-    __u64 size = iov.iov_len;
+static __always_inline void process_data(struct pt_regs *ctx, __u64 id, void 
*channel_ref, char *buf, __u64 size, __u64 timestamp) {
     if (size <= 0) {
         return;
     }
@@ -72,12 +66,12 @@ static __always_inline void process_data(struct pt_regs 
*ctx, __u64 id, void *ch
     if (reader == NULL) {
         return;
     }
-    asm volatile("%[size] &= 0x9f;\n" ::[size] "+r"(size) :);
+    asm volatile("%[size] &= 0xff;\n" ::[size] "+r"(size) :);
     bpf_probe_read(&reader->buffer, size & MAX_PROTOCOL_SOCKET_READ_LENGTH, 
buf);
     __u8 protocol;
     __u32 direction = analyze_protocol(reader->buffer, size & 
MAX_PROTOCOL_SOCKET_READ_LENGTH, &protocol);
     if (protocol != CONNECTION_PROTOCOL_UNKNOWN) {
-        reader->timestamp = bpf_ktime_get_ns();
+        reader->timestamp = timestamp;
         reader->channel_ref = channel_ref;
         reader->pid = (__u32)(id >> 32);
         reader->protocol = protocol;
@@ -87,6 +81,17 @@ static __always_inline void process_data(struct pt_regs 
*ctx, __u64 id, void *ch
     }
 }
 
+static __always_inline void process_msghdr_data(struct pt_regs *ctx, __u64 id, 
void *channel_ref, struct msghdr *msg) {
+    const struct iovec *iovec;
+    iovec = _KERNEL(msg->msg_iter.iov);
+    struct iovec iov;
+    bpf_probe_read(&iov, sizeof(iov), iovec);
+    char* buf = (char *)iov.iov_base;
+    __u64 size = iov.iov_len;
+
+    return process_data(ctx, id, channel_ref, buf, size, bpf_ktime_get_ns());
+}
+
 SEC("kprobe/tcp_sendmsg")
 int tcp_sendmsg(struct pt_regs *ctx) {
     __u64 id = bpf_get_current_pid_tgid();
@@ -96,7 +101,7 @@ int tcp_sendmsg(struct pt_regs *ctx) {
     }
 
     struct msghdr *msg = (void *)PT_REGS_PARM2(ctx);
-    process_data(ctx, id, s, msg);
+    process_msghdr_data(ctx, id, s, msg);
     return 0;
 }
 
@@ -122,8 +127,11 @@ int ret_tcp_recvmsg(struct pt_regs *ctx) {
     struct recv_msg_args *args = bpf_map_lookup_elem(&receiving_args, &id);
     int bytes_count = PT_REGS_RC(ctx);
     if (args != NULL && bytes_count > 0) {
-        process_data(ctx, id, args->sock, args->msg);
+        process_msghdr_data(ctx, id, args->sock, args->msg);
     }
     bpf_map_delete_elem(&receiving_args, &id);
     return 0;
-}
\ No newline at end of file
+}
+
+#include "openssl.c"
+#include "go_tls.c"
diff --git a/bpf/profiling/continuous/network.h 
b/bpf/profiling/continuous/network.h
index b8c4dd3..461b037 100644
--- a/bpf/profiling/continuous/network.h
+++ b/bpf/profiling/continuous/network.h
@@ -18,7 +18,7 @@
 #include "api.h"
 #include "skb.h"
 
-#define MAX_PROTOCOL_SOCKET_READ_LENGTH 158
+#define MAX_PROTOCOL_SOCKET_READ_LENGTH 255
 
 struct {
        __uint(type, BPF_MAP_TYPE_HASH);
diff --git a/bpf/profiling/continuous/openssl.c 
b/bpf/profiling/continuous/openssl.c
new file mode 100644
index 0000000..fe24eef
--- /dev/null
+++ b/bpf/profiling/continuous/openssl.c
@@ -0,0 +1,106 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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 "symbol_offsets.h"
+#include "openssl.h"
+
+static __always_inline bool openssl_should_trace(__u64 id, void *ssl) {
+    // check the pid is monitoring
+    __u32 tgid = (__u32)(id >> 32);
+    if (tgid_should_trace(tgid) == false) {
+        return false;
+    }
+
+    // check the socket if server side
+    struct openssl_symaddr* addr = get_openssl_symaddr(tgid);
+    if (addr != NULL) {
+        int is_server;
+        bpf_probe_read(&is_server, sizeof(is_server), ssl + 
addr->server_offset);
+        if (is_server == 1) {
+            return true;
+        }
+        return false;
+    }
+    struct envoy_tls_args_symaddr_t *envoy_addr = 
get_envoy_tls_args_symaddr(tgid);
+    if (envoy_addr != NULL) {
+        __u8 is_server_from_nginx;
+        bpf_probe_read(&is_server_from_nginx, sizeof(is_server_from_nginx), 
ssl + envoy_addr->is_server_offset);
+        if (is_server_from_nginx == 1) {
+            return true;
+        }
+        return false;
+    }
+
+    // could not check is server or client, just ignore it
+    return false;
+}
+
+SEC("uprobe/ssl_write")
+int openssl_write(struct pt_regs* ctx) {
+    __u64 id = bpf_get_current_pid_tgid();
+    void* ssl = (void*)PT_REGS_PARM1(ctx);
+    if (openssl_should_trace(id, ssl) == false) {
+        return 0;
+    }
+    char* buf = (char*)PT_REGS_PARM2(ctx);
+
+    struct openssl_args args = {};
+    args.ssl = ssl;
+    args.buf = buf;
+    args.timestamp = bpf_ktime_get_ns();
+    bpf_map_update_elem(&openssl_args_map, &id, &args, 0);
+    return 0;
+}
+
+SEC("uretprobe/ssl_write")
+int openssl_write_ret(struct pt_regs* ctx) {
+    __u64 id = bpf_get_current_pid_tgid();
+    struct openssl_args *args = bpf_map_lookup_elem(&openssl_args_map, &id);
+    int bytes_count = PT_REGS_RC(ctx);
+    if (args && bytes_count > 0) {
+        process_data(ctx, id, args->ssl, args->buf, bytes_count, 
args->timestamp);
+    }
+    bpf_map_delete_elem(&openssl_args_map, &id);
+    return 0;
+}
+
+SEC("uprobe/ssl_read")
+int openssl_read(struct pt_regs* ctx) {
+    __u64 id = bpf_get_current_pid_tgid();
+    void* ssl = (void*)PT_REGS_PARM1(ctx);
+    if (openssl_should_trace(id, ssl) == false) {
+        return 0;
+    }
+    char* buf = (char*)PT_REGS_PARM2(ctx);
+    struct openssl_args args = {};
+    args.ssl = ssl;
+    args.buf = buf;
+    bpf_map_update_elem(&openssl_args_map, &id, &args, 0);
+    return 0;
+}
+
+SEC("uretprobe/ssl_read")
+int openssl_read_ret(struct pt_regs* ctx) {
+    __u64 id = bpf_get_current_pid_tgid();
+    struct openssl_args *args = bpf_map_lookup_elem(&openssl_args_map, &id);
+    int bytes_count = PT_REGS_RC(ctx);
+    if (args && bytes_count > 0) {
+        process_data(ctx, id, args->ssl, args->buf, bytes_count, 
bpf_ktime_get_ns());
+    }
+    bpf_map_delete_elem(&openssl_args_map, &id);
+    return 0;
+}
\ No newline at end of file
diff --git a/bpf/profiling/network/openssl.h 
b/bpf/profiling/continuous/openssl.h
similarity index 65%
copy from bpf/profiling/network/openssl.h
copy to bpf/profiling/continuous/openssl.h
index 61e8425..ee0ef84 100644
--- a/bpf/profiling/network/openssl.h
+++ b/bpf/profiling/continuous/openssl.h
@@ -15,21 +15,15 @@
 // specific language governing permissions and limitations
 // under the License.
 
-struct openssl_fd_symaddr {
-    // read the BIO offset from ssl
-    __u32 bio_read_offset;
-    __u32 bio_write_offset;
-    // read the fd offset from BIO
-    __u32 fd_offset;
+struct openssl_args {
+    void* ssl;
+    char* buf;
+    __u64 timestamp;
 };
 
 struct {
        __uint(type, BPF_MAP_TYPE_HASH);
        __uint(max_entries, 10000);
-       __type(key, __u32);
-       __type(value, struct openssl_fd_symaddr);
-} openssl_fd_symaddr_finder SEC(".maps");
-static __inline struct openssl_fd_symaddr* get_openssl_fd_symaddr(__u32 tgid) {
-    struct openssl_fd_symaddr *addr = 
bpf_map_lookup_elem(&openssl_fd_symaddr_finder, &tgid);
-    return addr;
-}
+       __type(key, __u64);
+       __type(value, struct openssl_args);
+} openssl_args_map SEC(".maps");
diff --git a/bpf/profiling/network/go_tls.c b/bpf/profiling/network/go_tls.c
index d7af96b..3fde4a5 100644
--- a/bpf/profiling/network/go_tls.c
+++ b/bpf/profiling/network/go_tls.c
@@ -16,43 +16,7 @@
 // under the License.
 
 #include "go_tls.h"
-
-SEC("uprobe/casgstatus")
-int go_casgstatus(struct pt_regs* ctx) {
-    const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
-    if (regs == NULL) {
-       return 0;
-    }
-
-    __u64 id = bpf_get_current_pid_tgid();
-    __u32 tgid = id >> 32;
-    struct go_tls_args_symaddr_t* symaddrs = get_go_tls_args_symaddr(tgid);
-    if (symaddrs == NULL) {
-       return 0;
-    }
-
-    // get runtime.g
-    void* gptr = NULL;
-    assign_go_tls_arg(&gptr, sizeof(gptr), symaddrs->casg_status_gp_loc, sp, 
regs);
-    if (gptr == NULL) {
-        return 0;
-    }
-
-    // get goid in runtime.g
-    int64_t goid;
-    bpf_probe_read(&goid, sizeof(goid), gptr + symaddrs->gid_offset);
-
-    // newval in runtime.g
-    __u32 status;
-    assign_go_tls_arg(&status, sizeof(status), 
symaddrs->casg_status_new_val_loc, sp, regs);
-
-    // check the status is running
-    if (status == 2) {
-        set_goid(id, goid);
-    }
-    return 0;
-}
+#include "goid.c"
 
 SEC("uprobe/go_tls_write")
 int go_tls_write(struct pt_regs* ctx) {
@@ -70,7 +34,7 @@ int go_tls_write(struct pt_regs* ctx) {
     }
 
     const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
+    __u64* regs = go_regabi_regs(ctx);
     if (regs == NULL) {
         return 0;
     }
@@ -103,7 +67,7 @@ int go_tls_write_ret(struct pt_regs* ctx) {
     }
 
     const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
+    __u64* regs = go_regabi_regs(ctx);
     if (regs == NULL) {
         return 0;
     }
@@ -157,7 +121,7 @@ int go_tls_read(struct pt_regs* ctx) {
     }
 
     const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
+    __u64* regs = go_regabi_regs(ctx);
     if (regs == NULL) {
         return 0;
     }
@@ -190,7 +154,7 @@ int go_tls_read_ret(struct pt_regs* ctx) {
     }
 
     const void* sp = (const void*)PT_REGS_SP(ctx);
-    uint64_t* regs = go_regabi_regs(ctx);
+    __u64* regs = go_regabi_regs(ctx);
     if (regs == NULL) {
         return 0;
     }
diff --git a/bpf/profiling/network/go_tls.h b/bpf/profiling/network/go_tls.h
index 1428a4e..1057ef9 100644
--- a/bpf/profiling/network/go_tls.h
+++ b/bpf/profiling/network/go_tls.h
@@ -15,44 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-struct go_tls_arg_location_t {
-    __u32 type;
-    __u32 offset;
-};
-
-struct go_tls_args_symaddr_t {
-    __u64 fd_sys_offset;
-    __u64 tls_conn_offset;
-    __u64 gid_offset;
-    __u64 tcp_conn_offset;
-
-    // casg
-    struct go_tls_arg_location_t casg_status_gp_loc;
-    struct go_tls_arg_location_t casg_status_new_val_loc;
-
-    // read
-    struct go_tls_arg_location_t read_connection_loc;
-    struct go_tls_arg_location_t read_buffer_loc;
-    struct go_tls_arg_location_t read_ret0_loc;
-    struct go_tls_arg_location_t read_ret1_loc;
-
-    // write
-    struct go_tls_arg_location_t write_connection_loc;
-    struct go_tls_arg_location_t write_buffer_loc;
-    struct go_tls_arg_location_t write_ret0_loc;
-    struct go_tls_arg_location_t write_ret1_loc;
-};
-
-struct {
-       __uint(type, BPF_MAP_TYPE_HASH);
-       __uint(max_entries, 10000);
-       __type(key, __u32);
-       __type(value, struct go_tls_args_symaddr_t);
-} go_tls_args_symaddr_map SEC(".maps");
-static __always_inline struct go_tls_args_symaddr_t* 
get_go_tls_args_symaddr(__u32 tgid) {
-    struct go_tls_args_symaddr_t *addr = 
bpf_map_lookup_elem(&go_tls_args_symaddr_map, &tgid);
-    return addr;
-}
+#include "symbol_offsets.h"
 
 struct go_tls_tgid_goid_t {
     __u64 tgid;
@@ -70,56 +33,6 @@ struct {
        __type(value, struct go_tls_connection_args_t);
 } go_tls_active_connection_args SEC(".maps");
 
-
-struct go_regabi_regs_t {
-    __u64 regs[9];
-};
-struct {
-    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
-    __type(key, __u32);
-    __type(value, struct go_regabi_regs_t);
-    __uint(max_entries, 1);
-} go_regabi_regs_map SEC(".maps");
-// Copies the registers of the golang ABI, so that they can be
-// easily accessed using an offset.
-static __always_inline uint64_t* go_regabi_regs(const struct pt_regs* ctx) {
-    __u32 zero = 0;
-    struct go_regabi_regs_t* regs_heap_var = 
bpf_map_lookup_elem(&go_regabi_regs_map, &zero);
-    if (regs_heap_var == NULL) {
-        return NULL;
-    }
-
-    regs_heap_var->regs[0] = ctx->rax;
-    regs_heap_var->regs[1] = ctx->rbx;
-    regs_heap_var->regs[2] = ctx->rcx;
-    regs_heap_var->regs[3] = ctx->rdi;
-    regs_heap_var->regs[4] = ctx->rsi;
-    regs_heap_var->regs[5] = ctx->r8;
-    regs_heap_var->regs[6] = ctx->r9;
-    regs_heap_var->regs[7] = ctx->r10;
-    regs_heap_var->regs[8] = ctx->r11;
-
-    return regs_heap_var->regs;
-}
-
-struct go_interface {
-    int64_t type;
-    void* ptr;
-};
-
-static __always_inline void assign_go_tls_arg(void* arg, size_t arg_size, 
struct go_tls_arg_location_t loc, const void* sp,
-                                uint64_t* regs) {
-    // stack type
-    if (loc.type == 1) {
-        bpf_probe_read(arg, arg_size, sp + loc.offset);
-    } else if (loc.type == 2) {
-        // register type
-        if (loc.offset >= 0 && loc.offset <= 30) {
-            bpf_probe_read(arg, arg_size, (char*)regs + loc.offset);
-        }
-    }
-}
-
 static __always_inline int get_fd_from_go_tls_conn(struct go_interface conn, 
struct go_tls_args_symaddr_t* symaddr) {
     // read connection
     bpf_probe_read(&conn, sizeof(conn), conn.ptr + symaddr->tls_conn_offset);
@@ -133,19 +46,4 @@ static __always_inline int get_fd_from_go_tls_conn(struct 
go_interface conn, str
     __u64 sysfd;
     bpf_probe_read(&sysfd, sizeof(sysfd), fd_ptr + symaddr->fd_sys_offset);
     return sysfd;
-}
-
-struct {
-       __uint(type, BPF_MAP_TYPE_HASH);
-       __uint(max_entries, 1024);
-       __type(key, __u64);
-       __type(value, __u64);
-} go_tgid_goid_map SEC(".maps");
-static __inline __u64 get_goid(__u64 tgid) {
-    __u64 *val;
-    val = bpf_map_lookup_elem(&go_tgid_goid_map, &tgid);
-    return !val ? 0 : *val;
-}
-static __inline void set_goid(__u64 tgid, __u64 goid) {
-    bpf_map_update_elem(&go_tgid_goid_map, &tgid, &goid, 0);
 }
\ No newline at end of file
diff --git a/bpf/profiling/network/netmonitor.c 
b/bpf/profiling/network/netmonitor.c
index 13abc00..1636cea 100644
--- a/bpf/profiling/network/netmonitor.c
+++ b/bpf/profiling/network/netmonitor.c
@@ -108,10 +108,6 @@ static __always_inline void submit_new_connection(struct 
pt_regs* ctx, __u32 fun
         con.socket_family = AF_UNKNOWN;
     }
 
-    if (con.remote_port == 53) {
-        bpf_printk("found the remote port is 53");
-    }
-
     // save to the active connection map
     __u64 conid = gen_tgid_fd(tgid, fd);
     struct socket_connect_event_t *event = create_socket_connect_event();
diff --git a/bpf/profiling/network/openssl.c b/bpf/profiling/network/openssl.c
index 0db64e0..ef09f73 100644
--- a/bpf/profiling/network/openssl.c
+++ b/bpf/profiling/network/openssl.c
@@ -16,6 +16,7 @@
 // under the License.
 
 #include "args.h"
+#include "symbol_offsets.h"
 #include "openssl.h"
 #include "node_tls.h"
 
@@ -36,7 +37,7 @@ static __inline void process_openssl_data(struct pt_regs* 
ctx, __u64 id, __u32 d
 }
 
 static int get_fd_symaddr(__u32 tgid, bool read, void* ssl) {
-    struct openssl_fd_symaddr* addr = get_openssl_fd_symaddr(tgid);
+    struct openssl_symaddr* addr = get_openssl_symaddr(tgid);
     if (addr == NULL) {
         return -1;
     }
diff --git a/bpf/profiling/network/openssl.h b/bpf/profiling/network/openssl.h
index 61e8425..3fa197d 100644
--- a/bpf/profiling/network/openssl.h
+++ b/bpf/profiling/network/openssl.h
@@ -15,21 +15,3 @@
 // specific language governing permissions and limitations
 // under the License.
 
-struct openssl_fd_symaddr {
-    // read the BIO offset from ssl
-    __u32 bio_read_offset;
-    __u32 bio_write_offset;
-    // read the fd offset from BIO
-    __u32 fd_offset;
-};
-
-struct {
-       __uint(type, BPF_MAP_TYPE_HASH);
-       __uint(max_entries, 10000);
-       __type(key, __u32);
-       __type(value, struct openssl_fd_symaddr);
-} openssl_fd_symaddr_finder SEC(".maps");
-static __inline struct openssl_fd_symaddr* get_openssl_fd_symaddr(__u32 tgid) {
-    struct openssl_fd_symaddr *addr = 
bpf_map_lookup_elem(&openssl_fd_symaddr_finder, &tgid);
-    return addr;
-}
diff --git a/pkg/process/finders/base/tool.go b/pkg/process/finders/base/tool.go
index 408693c..749d4f6 100644
--- a/pkg/process/finders/base/tool.go
+++ b/pkg/process/finders/base/tool.go
@@ -25,9 +25,9 @@ import (
        v3 "skywalking.apache.org/repo/goapi/collect/ebpf/profiling/process/v3"
 
        "github.com/apache/skywalking-rover/pkg/process/api"
-       "github.com/apache/skywalking-rover/pkg/tools"
        "github.com/apache/skywalking-rover/pkg/tools/host"
        "github.com/apache/skywalking-rover/pkg/tools/path"
+       process_tool "github.com/apache/skywalking-rover/pkg/tools/process"
        "github.com/apache/skywalking-rover/pkg/tools/profiling"
 
        "github.com/shirou/gopsutil/process"
@@ -41,7 +41,7 @@ func BuildProfilingStat(ps *process.Process) 
(*profiling.Info, error) {
        }
 
        // check support profiling
-       return tools.ProcessProfilingStat(ps.Pid, exePath)
+       return process_tool.ProfilingStat(ps.Pid, exePath)
 }
 
 func tryToFindFileExecutePath(ps *process.Process) string {
diff --git a/pkg/profiling/continuous/checker/bpf/network/http1.go 
b/pkg/profiling/continuous/checker/bpf/network/http1.go
index 77ba21e..2a91647 100644
--- a/pkg/profiling/continuous/checker/bpf/network/http1.go
+++ b/pkg/profiling/continuous/checker/bpf/network/http1.go
@@ -66,7 +66,7 @@ func (h *HTTP1Analyzer) HandleBufferEvent(buffer 
*networkBufferInBPF) BufferEven
                return nil
        }
        // clean the request buffer
-       h.channelEvents[buffer.ChannelRef] = nil
+       delete(h.channelEvents, buffer.ChannelRef)
 
        code, err := h.analyzeResponseStatus(buffer)
        if err != nil {
diff --git a/pkg/profiling/continuous/checker/bpf/network/network.go 
b/pkg/profiling/continuous/checker/bpf/network/network.go
index 4bcda76..26bdded 100644
--- a/pkg/profiling/continuous/checker/bpf/network/network.go
+++ b/pkg/profiling/continuous/checker/bpf/network/network.go
@@ -18,6 +18,7 @@
 package network
 
 import (
+       "os"
        "sync"
        "time"
 
@@ -39,11 +40,11 @@ var log = logger.GetLogger("profiling", "continuous", 
"checker", "network", "bpf
 var locker sync.Mutex
 var bpf *bpfObjects
 var bpfLinker *btf.Linker
-var monitoringProcesses map[int32]map[string]bool
+var monitoringProcesses map[int32]*monitoringProcessInfo
 var notifiers []EventNotify
 
 func init() {
-       monitoringProcesses = make(map[int32]map[string]bool)
+       monitoringProcesses = make(map[int32]*monitoringProcessInfo)
 }
 
 type BufferEvent interface {
@@ -69,21 +70,21 @@ func AddWatchProcess(pid int32, from string) error {
                return e
        }
 
-       // first, update to the monitor control
-       if e := bpf.ProcessMonitorControl.Update(uint32(pid), uint32(1), 
ebpf.UpdateAny); e != nil {
-               // if add failure, then check the BPF should be shutdown or not
-               _ = shutdownBPFIfNoProcesses()
-               return e
-       }
-
-       // then, add to the monitoring cache
+       // adding to the cache
        monitoring := monitoringProcesses[pid]
        if monitoring == nil {
-               monitoring = make(map[string]bool)
+               monitoring = newMonitoringProcessInfo(pid)
                monitoringProcesses[pid] = monitoring
        }
 
-       monitoring[from] = true
+       // start monitoring process
+       if e := monitoring.AddSource(from); e != nil {
+               // remove the source if add failure
+               if deleteProcess, _ := monitoring.RemoveSource(from); 
deleteProcess {
+                       delete(monitoringProcesses, pid)
+               }
+               return e
+       }
        return nil
 }
 
@@ -100,23 +101,27 @@ func RemoveWatchProcess(pid int32, from string) error {
                return nil
        }
 
-       delete(monitoring, from)
-       shouldRemoveMonitor := false
-       if len(monitoringProcesses[pid]) == 0 {
+       deleteProcess, err := monitoring.RemoveSource(from)
+       if deleteProcess {
                delete(monitoringProcesses, pid)
-               shouldRemoveMonitor = true
-       }
-
-       if shouldRemoveMonitor {
-               if err := bpf.ProcessMonitorControl.Delete(uint32(pid)); err != 
nil {
-                       return err
-               }
        }
-       return nil
+       return err
 }
 
 func ForceShutdownBPF() error {
-       return shutdownBPF()
+       // shutdown all processes
+       var err error
+       for _, p := range monitoringProcesses {
+               if e := p.Shutdown(); e != nil {
+                       err = multierror.Append(err, e)
+               }
+       }
+       // shutdown the main BPF
+       monitoringProcesses = make(map[int32]*monitoringProcessInfo)
+       if e := shutdownBPF(); e != nil {
+               err = multierror.Append(err, e)
+       }
+       return err
 }
 
 // start the BPF program if contains process that needs monitor
@@ -142,7 +147,7 @@ func startBPFIfNeed() error {
                        n.ReceiveBufferEvent(event)
                }
        })
-       bpfLinker.ReadEventAsync(bpf.SocketBufferSendQueue, reader.Read, 
reader.BufferDataBPFSupplier)
+       bpfLinker.ReadEventAsyncWithBufferSize(bpf.SocketBufferSendQueue, 
reader.Read, os.Getpagesize()*100, reader.BufferDataBPFSupplier)
 
        if err := bpfLinker.HasError(); err != nil {
                _ = bpfLinker.Close()
diff --git a/pkg/profiling/continuous/checker/bpf/network/process.go 
b/pkg/profiling/continuous/checker/bpf/network/process.go
new file mode 100644
index 0000000..f2447bc
--- /dev/null
+++ b/pkg/profiling/continuous/checker/bpf/network/process.go
@@ -0,0 +1,82 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+package network
+
+import (
+       "github.com/cilium/ebpf"
+
+       "github.com/apache/skywalking-rover/pkg/tools/btf"
+
+       "github.com/hashicorp/go-multierror"
+)
+
+type monitoringProcessInfo struct {
+       pid    int32
+       linker *btf.Linker
+       source map[string]bool
+}
+
+func newMonitoringProcessInfo(pid int32) *monitoringProcessInfo {
+       return &monitoringProcessInfo{
+               pid:    pid,
+               linker: btf.NewLinker(),
+               source: make(map[string]bool),
+       }
+}
+
+func (m *monitoringProcessInfo) AddSource(from string) error {
+       // if already have source, then just added
+       if len(m.source) != 0 {
+               m.source[from] = true
+       }
+
+       // start the TLS first
+       if err := addSSLProcess(int(m.pid), m.linker, bpf); err != nil {
+               return err
+       }
+
+       // add to the process control
+       if e := bpf.ProcessMonitorControl.Update(uint32(m.pid), uint32(1), 
ebpf.UpdateAny); e != nil {
+               return e
+       }
+       m.source[from] = true
+       return nil
+}
+
+func (m *monitoringProcessInfo) RemoveSource(from string) (bool, error) {
+       delete(m.source, from)
+
+       // if still have source monitoring, then just ignore to shut down 
process monitoring
+       if len(m.source) > 0 {
+               return false, nil
+       }
+
+       var err error
+       if e := m.linker.Close(); e != nil {
+               err = multierror.Append(err, e)
+       }
+       if e := bpf.ProcessMonitorControl.Delete(uint32(m.pid)); e != nil {
+               err = multierror.Append(err, e)
+       }
+
+       return true, err
+}
+
+func (m *monitoringProcessInfo) Shutdown() error {
+       return m.linker.Close()
+}
diff --git a/pkg/profiling/continuous/checker/bpf/network/reader.go 
b/pkg/profiling/continuous/checker/bpf/network/reader.go
index 7530e5c..c5893f0 100644
--- a/pkg/profiling/continuous/checker/bpf/network/reader.go
+++ b/pkg/profiling/continuous/checker/bpf/network/reader.go
@@ -42,7 +42,7 @@ type networkBufferInBPF struct {
        Direction  BufferDirection
        Size       uint16
        Pid        uint32
-       Buffer     [159]byte
+       Buffer     [256]byte
 }
 
 type networkBufferReader struct {
diff --git a/bpf/profiling/network/openssl.h 
b/pkg/profiling/continuous/checker/bpf/network/ssl.go
similarity index 51%
copy from bpf/profiling/network/openssl.h
copy to pkg/profiling/continuous/checker/bpf/network/ssl.go
index 61e8425..50261f4 100644
--- a/bpf/profiling/network/openssl.h
+++ b/pkg/profiling/continuous/checker/bpf/network/ssl.go
@@ -15,21 +15,24 @@
 // specific language governing permissions and limitations
 // under the License.
 
-struct openssl_fd_symaddr {
-    // read the BIO offset from ssl
-    __u32 bio_read_offset;
-    __u32 bio_write_offset;
-    // read the fd offset from BIO
-    __u32 fd_offset;
-};
-
-struct {
-       __uint(type, BPF_MAP_TYPE_HASH);
-       __uint(max_entries, 10000);
-       __type(key, __u32);
-       __type(value, struct openssl_fd_symaddr);
-} openssl_fd_symaddr_finder SEC(".maps");
-static __inline struct openssl_fd_symaddr* get_openssl_fd_symaddr(__u32 tgid) {
-    struct openssl_fd_symaddr *addr = 
bpf_map_lookup_elem(&openssl_fd_symaddr_finder, &tgid);
-    return addr;
+package network
+
+import (
+       "github.com/apache/skywalking-rover/pkg/tools/btf"
+       "github.com/apache/skywalking-rover/pkg/tools/ssl"
+)
+
+func addSSLProcess(pid int, linker *btf.Linker, bpf *bpfObjects) error {
+       register := ssl.NewSSLRegister(pid, linker)
+
+       register.OpenSSL(bpf.OpensslSymaddrMap, bpf.OpensslWrite, 
bpf.OpensslWriteRet, bpf.OpensslRead, bpf.OpensslReadRet)
+
+       register.Envoy(bpf.EnvoyTlsArgsSymaddrMap, bpf.OpensslWrite, 
bpf.OpensslWriteRet, bpf.OpensslRead, bpf.OpensslReadRet)
+
+       register.GoTLS(bpf.GoTlsArgsSymaddrMap, bpf.GoCasgstatus, 
bpf.GoTlsWrite, bpf.GoTlsWriteRet, bpf.GoTlsRead, bpf.GoTlsReadRet)
+
+       register.Node(bpf.OpensslSymaddrMap, nil, bpf.OpensslWrite, 
bpf.OpensslWriteRet, bpf.OpensslRead, bpf.OpensslReadRet,
+               nil, nil, nil)
+
+       return register.Execute()
 }
diff --git a/pkg/profiling/task/network/analyze/base/enums.go 
b/pkg/profiling/task/network/analyze/base/enums.go
index ad4aa60..04173dc 100644
--- a/pkg/profiling/task/network/analyze/base/enums.go
+++ b/pkg/profiling/task/network/analyze/base/enums.go
@@ -111,13 +111,6 @@ func (c ConnectionProtocol) String() string {
        }
 }
 
-type GoTLSArgsLocationType uint32
-
-const (
-       GoTLSArgsLocationTypeStack    GoTLSArgsLocationType = 1
-       GoTLSArgsLocationTypeRegister GoTLSArgsLocationType = 2
-)
-
 type SocketMessageType uint8
 
 const (
diff --git a/pkg/profiling/task/network/ssl.go 
b/pkg/profiling/task/network/ssl.go
index 5591d53..d3fd33e 100644
--- a/pkg/profiling/task/network/ssl.go
+++ b/pkg/profiling/task/network/ssl.go
@@ -18,600 +18,21 @@
 package network
 
 import (
-       "bytes"
-       "encoding/binary"
-       "fmt"
-       "os/exec"
-       "regexp"
-       "strconv"
-       "strings"
-
-       
"github.com/apache/skywalking-rover/pkg/profiling/task/network/analyze/base"
        "github.com/apache/skywalking-rover/pkg/profiling/task/network/bpf"
-       "github.com/apache/skywalking-rover/pkg/tools"
-       "github.com/apache/skywalking-rover/pkg/tools/btf"
-       "github.com/apache/skywalking-rover/pkg/tools/elf"
-       "github.com/apache/skywalking-rover/pkg/tools/host"
-       "github.com/apache/skywalking-rover/pkg/tools/path"
-       "github.com/apache/skywalking-rover/pkg/tools/profiling"
-       "github.com/apache/skywalking-rover/pkg/tools/version"
-)
-
-var (
-       openSSLVersionRegex  = 
regexp.MustCompile(`^OpenSSL\s+(?P<Major>\d)\.(?P<Minor>\d)\.(?P<Fix>\d+)\w?\s+`)
-       goVersionRegex       = 
regexp.MustCompile(`^go(?P<Major>\d)\.(?P<Minor>\d+)`)
-       goTLSWriteSymbol     = "crypto/tls.(*Conn).Write"
-       goTLSReadSymbol      = "crypto/tls.(*Conn).Read"
-       goTLSGIDStatusSymbol = "runtime.casgstatus"
-       goTLSPollFDSymbol    = "internal/poll.FD"
-       goTLSConnSymbol      = "crypto/tls.Conn"
-       goTLSRuntimeG        = "runtime.g"
-       nodeVersionRegex     = 
regexp.MustCompile(`^node\.js/v(?P<Major>\d+)\.(?P<Minor>\d+)\.(?P<Patch>\d+)$`)
+       "github.com/apache/skywalking-rover/pkg/tools/ssl"
 )
 
-type OpenSSLFdSymAddrConfigInBPF struct {
-       BIOReadOffset  uint32
-       BIOWriteOffset uint32
-       FDOffset       uint32
-}
-
 func addSSLProcess(pid int, loader *bpf.Loader) error {
-       modules, err := tools.ProcessModules(int32(pid))
-       if err != nil {
-               return fmt.Errorf("read process modules error: %d, error: %v", 
pid, err)
-       }
-
-       // openssl process
-       if err1 := processOpenSSLProcess(pid, loader, modules); err1 != nil {
-               return err1
-       }
-
-       // envoy with boring ssl
-       if err1 := processEnvoyProcess(pid, loader, modules); err1 != nil {
-               return err1
-       }
-
-       // GoTLS
-       if err1 := processGoProcess(pid, loader, modules); err1 != nil {
-               return err1
-       }
-
-       // Nodejs
-       if err1 := processNodeProcess(pid, loader, modules); err1 != nil {
-               return err1
-       }
-
-       return nil
-}
-
-func processOpenSSLProcess(pid int, loader *bpf.Loader, modules 
[]*profiling.Module) error {
-       var libcryptoName, libsslName = "libcrypto.so", "libssl.so"
-       var libcryptoPath, libsslPath string
-       processModules, err := findProcessModules(modules, libcryptoName, 
libsslName)
-       if err != nil {
-               return err
-       }
-       // the openssl not exists, so ignore
-       if len(processModules) == 0 {
-               return nil
-       }
-       if libcrypto := processModules[libcryptoName]; libcrypto != nil {
-               libcryptoPath = libcrypto.Path
-       }
-       if libssl := processModules[libsslName]; libssl != nil {
-               libsslPath = libssl.Path
-       }
-       if libcryptoPath == "" || libsslPath == "" {
-               return fmt.Errorf("the OpenSSL library not complete, libcrypto: 
%s, libssl: %s", libcryptoPath, libsslPath)
-       }
-
-       // build the symbol address config and write to the bpf
-       conf, err := buildSSLSymAddrConfig(libcryptoPath)
-       if err != nil {
-               return err
-       }
-       if err := loader.OpensslFdSymaddrFinder.Put(uint32(pid), conf); err != 
nil {
-               return err
-       }
-
-       // attach the linker
-       return processOpenSSLModule(loader, processModules[libsslName])
-}
-
-func processOpenSSLModule(loader *bpf.Loader, libSSLModule *profiling.Module) 
error {
-       libSSLLinker := loader.OpenUProbeExeFile(libSSLModule.Path)
-       libSSLLinker.AddLink("SSL_write", loader.OpensslWrite, 
loader.OpensslWriteRet)
-       libSSLLinker.AddLink("SSL_read", loader.OpensslRead, 
loader.OpensslReadRet)
-       return loader.HasError()
-}
-
-func processEnvoyProcess(_ int, loader *bpf.Loader, modules 
[]*profiling.Module) error {
-       moduleName := "/envoy"
-       processModules, err := findProcessModules(modules, moduleName)
-       if err != nil {
-               return err
-       }
-       envoyModule := processModules[moduleName]
-       if envoyModule == nil {
-               return nil
-       }
-       var readSymbol, writeSymbol bool
-       for _, sym := range envoyModule.Symbols {
-               if sym.Name == "SSL_read" {
-                       readSymbol = true
-               } else if sym.Name == "SSL_write" {
-                       writeSymbol = true
-               }
-       }
-       if !readSymbol || !writeSymbol {
-               log.Debugf("found the envoy process, but the ssl read or write 
symbol not exists, so ignore. read: %t, write: %t",
-                       readSymbol, writeSymbol)
-               return nil
-       }
-
-       log.Debugf("found current module is envoy, so attach to the SSL read 
and write")
-
-       // attach the linker
-       libSSLLinker := loader.OpenUProbeExeFile(envoyModule.Path)
-       libSSLLinker.AddLink("SSL_write", loader.OpensslWrite, 
loader.OpensslWriteRet)
-       libSSLLinker.AddLink("SSL_read", loader.OpensslRead, 
loader.OpensslReadRet)
-       return loader.HasError()
-}
-
-type SymbolLocation struct {
-       Type   base.GoTLSArgsLocationType
-       Offset uint32
-}
-
-type GoTLSSymbolAddresses struct {
-       // net.Conn addresses
-       FDSysFDOffset uint64
-       TLSConnOffset uint64
-       GIDOffset     uint64
-       TCPConnOffset uint64
-
-       // casgstatus(goroutine status change) function relate locations
-       CasgStatusGPLoc     SymbolLocation
-       CasgStatusNEWValLoc SymbolLocation
-
-       // write function relate locations
-       WriteConnectionLoc SymbolLocation
-       WriteBufferLoc     SymbolLocation
-       WriteRet0Loc       SymbolLocation
-       WriteRet1Loc       SymbolLocation
-
-       // write function relate locations
-       ReadConnectionLoc SymbolLocation
-       ReadBufferLoc     SymbolLocation
-       ReadRet0Loc       SymbolLocation
-       ReadRet1Loc       SymbolLocation
-}
-
-type GoStringInC struct {
-       Ptr  uint64
-       Size uint64
-}
+       register := ssl.NewSSLRegister(pid, loader.Linker)
 
-func processGoProcess(pid int, loader *bpf.Loader, modules 
[]*profiling.Module) error {
-       // check current process is go program
-       buildVersionSymbol := searchSymbol(modules, func(a, b string) bool {
-               return a == b
-       }, "runtime.buildVersion")
-       if buildVersionSymbol == nil {
-               log.Debugf("current process is not Go program, so won't add the 
GoTLS protos. pid: %d", pid)
-               return nil
-       }
-       pidExeFile := host.GetFileInHost(fmt.Sprintf("/proc/%d/exe", pid))
-       elfFile, err := elf.NewFile(pidExeFile)
-       if err != nil {
-               return fmt.Errorf("read executable file error: %v", err)
-       }
-       defer elfFile.Close()
+       register.OpenSSL(loader.OpensslSymaddrMap, loader.OpensslWrite, 
loader.OpensslWriteRet, loader.OpensslRead, loader.OpensslReadRet)
 
-       v, err := getGoVersion(elfFile, buildVersionSymbol)
-       if err != nil {
-               return err
-       }
+       register.Envoy(nil, loader.OpensslWrite, loader.OpensslWriteRet, 
loader.OpensslRead, loader.OpensslReadRet)
 
-       // generate symbol offsets
-       symbolConfig, elfFile, err := generateGOTLSSymbolOffsets(modules, pid, 
elfFile, v)
-       if err != nil {
-               return err
-       }
-       if symbolConfig == nil || elfFile == nil {
-               return nil
-       }
-
-       // setting the locations
-       if err := loader.GoTlsArgsSymaddrMap.Put(uint32(pid), symbolConfig); 
err != nil {
-               return fmt.Errorf("setting the Go TLS argument location 
failure, pid: %d, error: %v", pid, err)
-       }
-
-       // uprobes
-       exeFile := loader.OpenUProbeExeFile(pidExeFile)
-       exeFile.AddLinkWithType("runtime.casgstatus", true, loader.GoCasgstatus)
-       exeFile.AddGoLink(goTLSWriteSymbol, loader.GoTlsWrite, 
loader.GoTlsWriteRet, elfFile)
-       exeFile.AddGoLink(goTLSReadSymbol, loader.GoTlsRead, 
loader.GoTlsReadRet, elfFile)
-
-       return loader.HasError()
-}
-
-func processNodeProcess(pid int, loader *bpf.Loader, modules 
[]*profiling.Module) error {
-       moduleName1, moduleName2, libsslName := "/nodejs", "/node", "libssl.so"
-       processModules, err := findProcessModules(modules, moduleName1, 
moduleName2, libsslName)
-       if err != nil {
-               return err
-       }
-       nodeModule := processModules[moduleName1]
-       libsslModule := processModules[libsslName]
-       needsReAttachSSL := false
-       if nodeModule == nil {
-               nodeModule = processModules[moduleName2]
-       }
-       if nodeModule == nil {
-               log.Debugf("current process is not nodejs program, so won't add 
the nodejs protos. pid: %d", pid)
-               return nil
-       }
-       if libsslModule == nil {
-               if searchSymbol([]*profiling.Module{nodeModule}, func(a, b 
string) bool {
-                       return a == b
-               }, "SSL_read") == nil || 
searchSymbol([]*profiling.Module{nodeModule}, func(a, b string) bool {
-                       return a == b
-               }, "SSL_write") == nil {
-                       log.Warnf("could not found the SSL_read/SSL_write under 
the nodejs program, so ignore. pid: %d", pid)
-                       return nil
-               }
-               libsslModule = nodeModule
-               needsReAttachSSL = true
-       }
-       v, err := getNodeVersion(nodeModule.Path)
-       if err != nil {
-               return fmt.Errorf("read nodejs version failure, pid: %d, error: 
%v", pid, err)
-       }
-       log.Debugf("read the nodejs version, pid: %d, version: %s", pid, v)
-       config, err := findNodeTLSAddrConfig(v)
-       if err != nil {
-               return err
-       }
-       // setting the locations
-       if err := loader.NodeTlsSymaddrMap.Put(uint32(pid), config); err != nil 
{
-               return fmt.Errorf("setting the node TLS location failure, pid: 
%d, error: %v", pid, err)
-       }
-       // register node tls
-       if err := registerNodeTLSProbes(v, loader, nodeModule, libsslModule); 
err != nil {
-               return fmt.Errorf("register node TLS probes failure, pid: %d, 
error: %v", pid, err)
-       }
-       // attach the OpenSSL Probe if needs
-       if needsReAttachSSL {
-               return processOpenSSLModule(loader, libsslModule)
-       }
-       return nil
-}
-
-var nodeTLSAddrWithVersions = []struct {
-       v    *version.Version
-       conf *NodeTLSAddrInBPF
-}{
-       {version.Build(10, 19, 0), &NodeTLSAddrInBPF{0x0130, 0x08, 0x00, 0x50, 
0x90, 0x88, 0x30}},
-       {version.Build(12, 3, 1), &NodeTLSAddrInBPF{0x0130, 0x08, 0x00, 0x50, 
0x90, 0x88, 0x30}},
-       {version.Build(12, 16, 2), &NodeTLSAddrInBPF{0x0138, 0x08, 0x00, 0x58, 
0x98, 0x88, 0x30}},
-       {version.Build(13, 0, 0), &NodeTLSAddrInBPF{0x0130, 0x08, 0x00, 0x50, 
0x90, 0x88, 0x30}},
-       {version.Build(13, 2, 0), &NodeTLSAddrInBPF{0x0130, 0x08, 0x00, 0x58, 
0x98, 0x88, 0x30}},
-       {version.Build(13, 10, 1), &NodeTLSAddrInBPF{0x0140, 0x08, 0x00, 0x60, 
0xa0, 0x88, 0x30}},
-       {version.Build(14, 5, 0), &NodeTLSAddrInBPF{0x138, 0x08, 0x00, 0x58, 
0x98, 0x88, 0x30}},
-       {version.Build(15, 0, 0), &NodeTLSAddrInBPF{0x78, 0x08, 0x00, 0x58, 
0x98, 0x88, 0x30}},
-}
-
-var nodeTLSProbeWithVersions = []struct {
-       v *version.Version
-       f func(uprobe *btf.UProbeExeFile, bpf *bpf.Loader, nodeModule 
*profiling.Module)
-}{
-       {version.Build(10, 19, 0), func(uprobe *btf.UProbeExeFile, bpf 
*bpf.Loader, nodeModule *profiling.Module) {
-               
uprobe.AddLinkWithSymbols(searchSymbolNames([]*profiling.Module{nodeModule}, 
strings.HasPrefix, "_ZN4node7TLSWrapC2E"),
-                       bpf.NodeTlsWrap, bpf.NodeTlsWrapRet)
-               
uprobe.AddLinkWithSymbols(searchSymbolNames([]*profiling.Module{nodeModule}, 
strings.HasPrefix, "_ZN4node7TLSWrap7ClearInE"),
-                       bpf.NodeTlsWrap, bpf.NodeTlsWrapRet)
-               
uprobe.AddLinkWithSymbols(searchSymbolNames([]*profiling.Module{nodeModule}, 
strings.HasPrefix, "_ZN4node7TLSWrap8ClearOutE"),
-                       bpf.NodeTlsWrap, bpf.NodeTlsWrapRet)
-       }},
-       {version.Build(15, 0, 0), func(uprobe *btf.UProbeExeFile, bpf 
*bpf.Loader, nodeModule *profiling.Module) {
-               
uprobe.AddLinkWithSymbols(searchSymbolNames([]*profiling.Module{nodeModule}, 
strings.HasPrefix, "_ZN4node6crypto7TLSWrapC2E"),
-                       bpf.NodeTlsWrap, bpf.NodeTlsWrapRet)
-               
uprobe.AddLinkWithSymbols(searchSymbolNames([]*profiling.Module{nodeModule}, 
strings.HasPrefix, "_ZN4node6crypto7TLSWrap7ClearInE"),
-                       bpf.NodeTlsWrap, bpf.NodeTlsWrapRet)
-               
uprobe.AddLinkWithSymbols(searchSymbolNames([]*profiling.Module{nodeModule}, 
strings.HasPrefix, "_ZN4node6crypto7TLSWrap8ClearOutE"),
-                       bpf.NodeTlsWrap, bpf.NodeTlsWrapRet)
-       }},
-}
+       register.GoTLS(loader.GoTlsArgsSymaddrMap, loader.GoCasgstatus, 
loader.GoTlsWrite, loader.GoTlsWriteRet, loader.GoTlsRead, loader.GoTlsReadRet)
 
-type NodeTLSAddrInBPF struct {
-       TLSWrapStreamListenerOffset     uint32
-       StreamListenerStreamOffset      uint32
-       StreamBaseStreamResourceOffset  uint32
-       LibuvStreamWrapStreamBaseOffset uint32
-       LibuvStreamWrapStreamOffset     uint32
-       UVStreamSIOWatcherOffset        uint32
-       UVIOSFDOffset                   uint32
-}
-
-func findNodeTLSAddrConfig(v *version.Version) (*NodeTLSAddrInBPF, error) {
-       var lastest *NodeTLSAddrInBPF
-       for _, c := range nodeTLSAddrWithVersions {
-               if v.GreaterOrEquals(c.v) {
-                       lastest = c.conf
-               }
-       }
-       if lastest != nil {
-               return lastest, nil
-       }
-       return nil, fmt.Errorf("could not support version: %s", v)
-}
-
-func registerNodeTLSProbes(v *version.Version, loader *bpf.Loader, nodeModule, 
libSSLModule *profiling.Module) error {
-       var probeFunc func(uprobe *btf.UProbeExeFile, bpf *bpf.Loader, 
nodeModule *profiling.Module)
-       for _, c := range nodeTLSProbeWithVersions {
-               if v.GreaterOrEquals(c.v) {
-                       probeFunc = c.f
-               }
-       }
-       if probeFunc == nil {
-               return fmt.Errorf("the version is not support: %v", v)
-       }
-       file := loader.OpenUProbeExeFile(nodeModule.Path)
-       probeFunc(file, loader, nodeModule)
-
-       // find the SSL_new, and register
-       file = loader.OpenUProbeExeFile(libSSLModule.Path)
-       file.AddLinkWithType("SSL_new", false, loader.NodeTlsRetSsl)
-       return loader.HasError()
-}
-
-func getNodeVersion(p string) (*version.Version, error) {
-       result, err := exec.Command("strings", p).Output()
-       if err != nil {
-               return nil, err
-       }
-       for _, d := range strings.Split(string(result), "\n") {
-               versionInfo := 
nodeVersionRegex.FindStringSubmatch(strings.TrimSpace(d))
-               if len(versionInfo) != 4 {
-                       continue
-               }
-               return version.Read(versionInfo[1], versionInfo[2], 
versionInfo[3])
-       }
-
-       return nil, fmt.Errorf("nodejs version is not found")
-}
-
-func getGoVersion(elfFile *elf.File, versionSymbol *profiling.Symbol) 
(*version.Version, error) {
-       buffer, err := elfFile.ReadSymbolData(".data", versionSymbol.Location, 
versionSymbol.Size)
-       if err != nil {
-               return nil, fmt.Errorf("reading go version struct info failure: 
%v", err)
-       }
-       var t = GoStringInC{}
-       buf := bytes.NewReader(buffer)
-       err = binary.Read(buf, binary.LittleEndian, &t)
-       if err != nil {
-               return nil, fmt.Errorf("read the go structure failure: %v", err)
-       }
-       buffer, err = elfFile.ReadSymbolData(".data", t.Ptr, t.Size)
-       if err != nil {
-               return nil, fmt.Errorf("read the go version failure: %v", err)
-       }
-
-       // parse versions
-       submatch := goVersionRegex.FindStringSubmatch(string(buffer))
-       if len(submatch) != 3 {
-               return nil, fmt.Errorf("the go version is failure to identify, 
version: %s", string(buffer))
-       }
-       return version.Read(submatch[1], submatch[2], "")
-}
-
-func generateGOTLSSymbolOffsets(modules []*profiling.Module, _ int, elfFile 
*elf.File, v *version.Version) (*GoTLSSymbolAddresses, *elf.File, error) {
-       reader, err := elfFile.NewDwarfReader(
-               goTLSReadSymbol, goTLSWriteSymbol, goTLSGIDStatusSymbol,
-               goTLSPollFDSymbol, goTLSConnSymbol, goTLSRuntimeG)
-       if err != nil {
-               return nil, nil, err
-       }
-
-       symbolAddresses := &GoTLSSymbolAddresses{}
-
-       sym := searchSymbol(modules, func(a, b string) bool {
-               return a == b
-       }, "go.itab.*net.TCPConn,net.Conn")
-       if sym == nil {
-               log.Warnf("could not found the tcp connection symbol: 
go.itab.*net.TCPConn,net.Conn")
-               return nil, nil, nil
-       }
-       symbolAddresses.TCPConnOffset = sym.Location
-
-       readFunction := reader.GetFunction(goTLSReadSymbol)
-       if readFunction == nil {
-               log.Warnf("could not found the go tls read symbol: %s", 
goTLSReadSymbol)
-               return nil, nil, nil
-       }
-       writeFunction := reader.GetFunction(goTLSWriteSymbol)
-       if writeFunction == nil {
-               log.Warnf("could not found the go tls write symbol: %s", 
goTLSWriteSymbol)
-               return nil, nil, nil
-       }
-       gidStatusFunction := reader.GetFunction(goTLSGIDStatusSymbol)
-       if gidStatusFunction == nil {
-               log.Warnf("could not found the goid status change symbol: %s", 
goTLSGIDStatusSymbol)
-               return nil, nil, nil
-       }
-
-       var retValArg0, retValArg1 = "~r1", "~r2"
-       if v.Minor >= 18 {
-               retValArg0, retValArg1 = "~r0", "~r1"
-       }
-
-       // build the symbols
-       var assignError error
-       // offset
-       assignError = assignGoTLSStructureOffset(assignError, reader, 
goTLSPollFDSymbol, "Sysfd", &symbolAddresses.FDSysFDOffset)
-       assignError = assignGoTLSStructureOffset(assignError, reader, 
goTLSConnSymbol, "conn", &symbolAddresses.TLSConnOffset)
-       assignError = assignGoTLSStructureOffset(assignError, reader, 
goTLSRuntimeG, "goid", &symbolAddresses.GIDOffset)
-
-       // gid status change
-       assignError = assignGoTLSArgsLocation(assignError, gidStatusFunction, 
"gp", &symbolAddresses.CasgStatusGPLoc)
-       assignError = assignGoTLSArgsLocation(assignError, gidStatusFunction, 
"newval", &symbolAddresses.CasgStatusNEWValLoc)
-
-       // write
-       assignError = assignGoTLSArgsLocation(assignError, writeFunction, "c", 
&symbolAddresses.WriteConnectionLoc)
-       assignError = assignGoTLSArgsLocation(assignError, writeFunction, "b", 
&symbolAddresses.WriteBufferLoc)
-       assignError = assignGoTLSArgsLocation(assignError, writeFunction, 
retValArg0, &symbolAddresses.WriteRet0Loc)
-       assignError = assignGoTLSArgsLocation(assignError, writeFunction, 
retValArg1, &symbolAddresses.WriteRet1Loc)
-       // read
-       assignError = assignGoTLSArgsLocation(assignError, readFunction, "c", 
&symbolAddresses.ReadConnectionLoc)
-       assignError = assignGoTLSArgsLocation(assignError, readFunction, "b", 
&symbolAddresses.ReadBufferLoc)
-       assignError = assignGoTLSArgsLocation(assignError, readFunction, 
retValArg0, &symbolAddresses.ReadRet0Loc)
-       assignError = assignGoTLSArgsLocation(assignError, readFunction, 
retValArg1, &symbolAddresses.ReadRet1Loc)
-
-       return symbolAddresses, elfFile, assignError
-}
-
-func assignGoTLSStructureOffset(err error, reader *elf.DwarfReader, 
structName, fieldName string, dest *uint64) error {
-       if err != nil {
-               return err
-       }
-       structure := reader.GetStructure(structName)
-       if structure == nil {
-               return fmt.Errorf("the structure is not found, name: %s", 
structName)
-       }
-       field := structure.GetField(fieldName)
-       if field == nil {
-               return fmt.Errorf("the field is not found in structure, 
structure name: %s, field name: %s", structName, fieldName)
-       }
-       *dest = uint64(field.Offset)
-       return nil
-}
-
-func assignGoTLSArgsLocation(err error, function *elf.FunctionInfo, argName 
string, dest *SymbolLocation) error {
-       if err != nil {
-               return err
-       }
-       var kSPOffset uint32 = 8
-       args := function.Args(argName)
-       if args == nil {
-               return fmt.Errorf("the args is not found, function: %s, args 
name: %s", function.Name(), argName)
-       }
-       if args.Location.Type == elf.ArgLocationTypeStack {
-               dest.Type = base.GoTLSArgsLocationTypeStack
-               dest.Offset = uint32(args.Location.Offset) + kSPOffset
-       } else if args.Location.Type == elf.ArgLocationTypeRegister {
-               dest.Type = base.GoTLSArgsLocationTypeRegister
-               dest.Offset = uint32(args.Location.Offset)
-       } else {
-               return fmt.Errorf("the location type is not support, function: 
%s, args name: %s, type: %d",
-                       function.Name(), argName, args.Location.Type)
-       }
-       return nil
-}
-
-func findProcessModules(modules []*profiling.Module, moduleNames ...string) 
(map[string]*profiling.Module, error) {
-       result := make(map[string]*profiling.Module)
-       for _, mod := range modules {
-               for _, modName := range moduleNames {
-                       if strings.Contains(mod.Name, modName) {
-                               if !path.Exists(mod.Path) {
-                                       return nil, fmt.Errorf("the module path 
not exists, path: %s", mod.Path)
-                               }
-                               result[modName] = mod
-                       }
-               }
-       }
-       return result, nil
-}
-
-func buildSSLSymAddrConfig(libcryptoPath string) 
(*OpenSSLFdSymAddrConfigInBPF, error) {
-       // using "strings" command to query the symbol in the libcrypto library
-       result, err := exec.Command("strings", libcryptoPath).Output()
-       if err != nil {
-               return nil, err
-       }
-       for _, p := range strings.Split(string(result), "\n") {
-               submatch := openSSLVersionRegex.FindStringSubmatch(p)
-               if len(submatch) != 4 {
-                       continue
-               }
-               major := submatch[1]
-               minor := submatch[2]
-               fix := submatch[3]
-
-               log.Debugf("found the libcrypto.so version: %s.%s.%s", major, 
minor, fix)
-               conf := &OpenSSLFdSymAddrConfigInBPF{}
-
-               // must be number, already validate in the regex
-               majorVal, _ := strconv.Atoi(major)
-               minorVal, _ := strconv.Atoi(minor)
-               fixVal, _ := strconv.Atoi(fix)
-
-               // max support version is 3.0.x
-               if majorVal > 3 || (majorVal == 3 && minorVal > 0) {
-                       return nil, fmt.Errorf("the version of the libcrypto is 
not support: %s.%s.%s", major, minor, fix)
-               }
-
-               // bio offset
-               // 
https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/ssl/ssl.h#L1093-L1111
-               // 
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/ssl/ssl_local.h#L1068-L1083
-               // 
https://github.com/openssl/openssl/blob/openssl-3.0.7/ssl/ssl_local.h#L1212-L1227
-               conf.BIOReadOffset = 16
-               conf.BIOWriteOffset = 24
-               // fd offset
-               if majorVal == 3 && minorVal == 0 {
-                       // 3.0.x
-                       // 
https://github.com/openssl/openssl/blob/openssl-3.0.7/crypto/bio/bio_local.h#L115-L128
-                       // OPENSSL_NO_DEPRECATED_3_0 is not defined by default 
unless the user pass the specific build option
-                       conf.FDOffset = 56
-               } else if (minorVal == 0) || (minorVal == 1 && fixVal == 0) {
-                       // 1.0.x || 1.1.0
-                       // 
https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/crypto/bio/bio.h#L297-L306
-                       conf.FDOffset = 40
-               } else {
-                       // 1.1.1
-                       // 
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/crypto/bio/bio_local.h#L115-L125
-                       conf.FDOffset = 48
-               }
-               log.Debugf("the lobcrypto.so library symbol verson config, 
version: %s.%s.%s, bio offset: %d",
-                       major, minor, fix, conf.FDOffset)
-               return conf, nil
-       }
-       return nil, fmt.Errorf("could not fount the version of the 
libcrypto.so")
-}
-
-type stringVerify func(a, b string) bool
-
-func searchSymbolNames(modules []*profiling.Module, verify stringVerify, 
values ...string) []string {
-       list := searchSymbolList(modules, verify, values...)
-       if len(list) > 0 {
-               result := make([]string, 0)
-               for _, i := range list {
-                       result = append(result, i.Name)
-               }
-               return result
-       }
-       return nil
-}
-
-func searchSymbol(modules []*profiling.Module, verify stringVerify, values 
...string) *profiling.Symbol {
-       list := searchSymbolList(modules, verify, values...)
-       if len(list) > 0 {
-               return list[0]
-       }
-       return nil
-}
+       register.Node(nil, loader.NodeTlsSymaddrMap, loader.OpensslWrite, 
loader.OpensslWriteRet, loader.OpensslRead, loader.OpensslReadRet,
+               loader.NodeTlsRetSsl, loader.NodeTlsWrap, loader.NodeTlsWrapRet)
 
-func searchSymbolList(modules []*profiling.Module, verify stringVerify, values 
...string) []*profiling.Symbol {
-       var result []*profiling.Symbol
-       for _, mod := range modules {
-               for _, s := range mod.Symbols {
-                       for _, validator := range values {
-                               if verify(s.Name, validator) {
-                                       result = append(result, s)
-                               }
-                       }
-               }
-       }
-       return result
+       return register.Execute()
 }
diff --git a/pkg/profiling/task/offcpu/runner.go 
b/pkg/profiling/task/offcpu/runner.go
index 149747e..9c8c7e9 100644
--- a/pkg/profiling/task/offcpu/runner.go
+++ b/pkg/profiling/task/offcpu/runner.go
@@ -32,8 +32,8 @@ import (
        "github.com/apache/skywalking-rover/pkg/module"
        "github.com/apache/skywalking-rover/pkg/process/api"
        "github.com/apache/skywalking-rover/pkg/profiling/task/base"
-       "github.com/apache/skywalking-rover/pkg/tools"
        "github.com/apache/skywalking-rover/pkg/tools/btf"
+       "github.com/apache/skywalking-rover/pkg/tools/process"
        "github.com/apache/skywalking-rover/pkg/tools/profiling"
 
        v3 "skywalking.apache.org/repo/goapi/collect/ebpf/profiling/v3"
@@ -80,10 +80,10 @@ func (r *Runner) Init(task *base.ProfilingTask, processes 
[]api.ProcessInterface
        if len(processes) != 1 {
                return fmt.Errorf("the processes count must be 1, current is: 
%d", len(processes))
        }
-       process := processes[0]
-       r.pid = process.Pid()
-       r.processProfiling = process.ProfilingStat()
-       kernelProfiling, err := tools.KernelFileProfilingStat()
+       curProcess := processes[0]
+       r.pid = curProcess.Pid()
+       r.processProfiling = curProcess.ProfilingStat()
+       kernelProfiling, err := process.KernelFileProfilingStat()
        if err != nil {
                log.Warnf("could not analyze kernel profiling stats: %v", err)
        }
diff --git a/pkg/profiling/task/oncpu/runner.go 
b/pkg/profiling/task/oncpu/runner.go
index b346372..01287f6 100644
--- a/pkg/profiling/task/oncpu/runner.go
+++ b/pkg/profiling/task/oncpu/runner.go
@@ -31,7 +31,7 @@ import (
        "github.com/apache/skywalking-rover/pkg/module"
        "github.com/apache/skywalking-rover/pkg/process/api"
        "github.com/apache/skywalking-rover/pkg/profiling/task/base"
-       "github.com/apache/skywalking-rover/pkg/tools"
+       "github.com/apache/skywalking-rover/pkg/tools/process"
        "github.com/apache/skywalking-rover/pkg/tools/profiling"
 
        "golang.org/x/sys/unix"
@@ -86,14 +86,14 @@ func (r *Runner) Init(task *base.ProfilingTask, processes 
[]api.ProcessInterface
        if len(processes) != 1 {
                return fmt.Errorf("the processes count must be 1, current is: 
%d", len(processes))
        }
-       process := processes[0]
-       r.pid = process.Pid()
+       curProcess := processes[0]
+       r.pid = curProcess.Pid()
        // process profiling stat
-       if r.processProfiling = process.ProfilingStat(); r.processProfiling == 
nil {
+       if r.processProfiling = curProcess.ProfilingStat(); r.processProfiling 
== nil {
                return fmt.Errorf("this process could not be profiling")
        }
        // kernel profiling stat
-       kernelProfiling, err := tools.KernelFileProfilingStat()
+       kernelProfiling, err := process.KernelFileProfilingStat()
        if err != nil {
                log.Warnf("could not analyze kernel profiling stats: %v", err)
        }
diff --git a/pkg/tools/btf/linker.go b/pkg/tools/btf/linker.go
index 8c80726..d08242a 100644
--- a/pkg/tools/btf/linker.go
+++ b/pkg/tools/btf/linker.go
@@ -28,8 +28,8 @@ import (
 
        "golang.org/x/arch/x86/x86asm"
 
-       "github.com/apache/skywalking-rover/pkg/tools"
        "github.com/apache/skywalking-rover/pkg/tools/elf"
+       "github.com/apache/skywalking-rover/pkg/tools/process"
 
        "github.com/cilium/ebpf"
        "github.com/cilium/ebpf/link"
@@ -46,7 +46,7 @@ type RingBufferReader func(data interface{})
 var syscallPrefix string
 
 func init() {
-       stat, err := tools.KernelFileProfilingStat()
+       stat, err := process.KernelFileProfilingStat()
        if err != nil {
                syscallPrefix = defaultSymbolPrefix
                return
diff --git a/pkg/tools/process.go b/pkg/tools/process/process.go
similarity index 94%
rename from pkg/tools/process.go
rename to pkg/tools/process/process.go
index 9539093..1186b8e 100644
--- a/pkg/tools/process.go
+++ b/pkg/tools/process/process.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package tools
+package process
 
 import (
        "bufio"
@@ -61,8 +61,8 @@ func KernelFileProfilingStat() (*profiling.Info, error) {
        return kernelFinder.Analyze(profiling.KernelSymbolFilePath)
 }
 
-// ProcessProfilingStat is validating the exe file could be profiling and get 
info
-func ProcessProfilingStat(pid int32, exePath string) (*profiling.Info, error) {
+// ProfilingStat is validating the exe file could be profiling and get info
+func ProfilingStat(pid int32, exePath string) (*profiling.Info, error) {
        stat, err := os.Stat(exePath)
        if err != nil {
                return nil, fmt.Errorf("check file error: %v", err)
@@ -83,8 +83,8 @@ func ProcessProfilingStat(pid int32, exePath string) 
(*profiling.Info, error) {
        return analyzeProfilingInfo(context, pid)
 }
 
-// ProcessModules Read the profiling info of the process, without the symbol 
check
-func ProcessModules(pid int32) ([]*profiling.Module, error) {
+// Modules Read the profiling info of the process, without the symbol check
+func Modules(pid int32) ([]*profiling.Module, error) {
        context := newAnalyzeContext()
        info, err := analyzeProfilingInfo(context, pid)
        if err != nil {
diff --git a/pkg/tools/ssl/envoy.go b/pkg/tools/ssl/envoy.go
new file mode 100644
index 0000000..7ccc298
--- /dev/null
+++ b/pkg/tools/ssl/envoy.go
@@ -0,0 +1,75 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+package ssl
+
+import (
+       "fmt"
+
+       "github.com/cilium/ebpf"
+)
+
+type EnvoySymbolAddress struct {
+       IsServerOffset uint64
+}
+
+func (r *Register) Envoy(envoySymbolAddrMap *ebpf.Map, sslWrite, sslWriteRet, 
sslRead, sslReadRet *ebpf.Program) {
+       r.addHandler("Envoy", func() (bool, error) {
+               moduleName := "/envoy"
+               processModules, err := r.findModules(moduleName)
+               if err != nil {
+                       return false, err
+               }
+               envoyModule := processModules[moduleName]
+               if envoyModule == nil {
+                       return false, nil
+               }
+               var readSymbol, writeSymbol bool
+               for _, sym := range envoyModule.Symbols {
+                       if sym.Name == "SSL_read" {
+                               readSymbol = true
+                       } else if sym.Name == "SSL_write" {
+                               writeSymbol = true
+                       }
+               }
+               if !readSymbol || !writeSymbol {
+                       log.Debugf("found the envoy process, but the ssl read 
or write symbol not exists, so ignore. read: %t, write: %t",
+                               readSymbol, writeSymbol)
+                       return false, nil
+               }
+
+               if envoySymbolAddrMap != nil {
+                       addr := &EnvoySymbolAddress{
+                               // for now the server field have fixed position
+                               // 
https://github.com/google/boringssl/blob/master/ssl/internal.h#L3734-L3812
+                               IsServerOffset: 164,
+                       }
+
+                       if err := envoySymbolAddrMap.Put(uint32(r.pid), addr); 
err != nil {
+                               return false, fmt.Errorf("setting the envoy 
symbol offsets failure, pid: %d, error: %v", r.pid, err)
+                       }
+               }
+
+               envoy := r.linker.OpenUProbeExeFile(envoyModule.Path)
+               envoy.AddLink("SSL_write", sslWrite, sslWriteRet)
+               envoy.AddLink("SSL_read", sslRead, sslReadRet)
+               if e := r.linker.HasError(); e != nil {
+                       return false, e
+               }
+               return true, nil
+       })
+}
diff --git a/pkg/tools/ssl/gotls.go b/pkg/tools/ssl/gotls.go
new file mode 100644
index 0000000..2a88498
--- /dev/null
+++ b/pkg/tools/ssl/gotls.go
@@ -0,0 +1,258 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+package ssl
+
+import (
+       "bytes"
+       "encoding/binary"
+       "fmt"
+       "regexp"
+
+       "github.com/apache/skywalking-rover/pkg/tools/elf"
+       "github.com/apache/skywalking-rover/pkg/tools/host"
+       "github.com/apache/skywalking-rover/pkg/tools/profiling"
+       "github.com/apache/skywalking-rover/pkg/tools/version"
+
+       "github.com/cilium/ebpf"
+)
+
+var (
+       goVersionRegex = regexp.MustCompile(`^go(?P<Major>\d)\.(?P<Minor>\d+)`)
+
+       goTLSWriteSymbol     = "crypto/tls.(*Conn).Write"
+       goTLSReadSymbol      = "crypto/tls.(*Conn).Read"
+       goTLSGIDStatusSymbol = "runtime.casgstatus"
+       goTLSPollFDSymbol    = "internal/poll.FD"
+       goTLSConnSymbol      = "crypto/tls.Conn"
+       goTLSRuntimeG        = "runtime.g"
+)
+
+type GoTLSArgsLocationType uint32
+
+const (
+       GoTLSArgsLocationTypeStack    GoTLSArgsLocationType = 1
+       GoTLSArgsLocationTypeRegister GoTLSArgsLocationType = 2
+)
+
+type GoSymbolLocation struct {
+       Type   GoTLSArgsLocationType
+       Offset uint32
+}
+
+type GoTLSSymbolAddress struct {
+       // net.Conn addresses
+       FDSysFDOffset  uint64
+       TLSConnOffset  uint64
+       GIDOffset      uint64
+       TCPConnOffset  uint64
+       IsClientOffset uint64
+
+       // casgstatus(goroutine status change) function relate locations
+       CasgStatusGPLoc     GoSymbolLocation
+       CasgStatusNEWValLoc GoSymbolLocation
+
+       // write function relate locations
+       WriteConnectionLoc GoSymbolLocation
+       WriteBufferLoc     GoSymbolLocation
+       WriteRet0Loc       GoSymbolLocation
+       WriteRet1Loc       GoSymbolLocation
+
+       // write function relate locations
+       ReadConnectionLoc GoSymbolLocation
+       ReadBufferLoc     GoSymbolLocation
+       ReadRet0Loc       GoSymbolLocation
+       ReadRet1Loc       GoSymbolLocation
+}
+
+func (r *Register) GoTLS(symbolAddrMap *ebpf.Map, goIDChange, write, writeRet, 
read, readRet *ebpf.Program) {
+       r.addHandler("goTLS", func() (bool, error) {
+               buildVersionSymbol := r.searchSymbolInModules(r.modules, 
func(a, b string) bool {
+                       return a == b
+               }, "runtime.buildVersion")
+               if buildVersionSymbol == nil {
+                       return false, nil
+               }
+               pidExeFile := host.GetFileInHost(fmt.Sprintf("/proc/%d/exe", 
r.pid))
+               elfFile, err := elf.NewFile(pidExeFile)
+               if err != nil {
+                       return false, fmt.Errorf("read executable file error: 
%v", err)
+               }
+               defer elfFile.Close()
+
+               v, err := r.getGoVersion(elfFile, buildVersionSymbol)
+               if err != nil {
+                       return false, err
+               }
+
+               offsets, err := r.generateGOTLSSymbolOffsets(r, elfFile, v)
+               if err != nil {
+                       return false, err
+               }
+               if offsets == nil {
+                       return false, nil
+               }
+
+               // setting the locations
+               if err := symbolAddrMap.Put(uint32(r.pid), offsets); err != nil 
{
+                       return false, fmt.Errorf("setting the Go TLS argument 
location failure, pid: %d, error: %v", r.pid, err)
+               }
+
+               exeFile := r.linker.OpenUProbeExeFile(pidExeFile)
+               exeFile.AddLinkWithType("runtime.casgstatus", true, goIDChange)
+               exeFile.AddGoLink(goTLSWriteSymbol, write, writeRet, elfFile)
+               exeFile.AddGoLink(goTLSReadSymbol, read, readRet, elfFile)
+               if e := r.linker.HasError(); e != nil {
+                       return false, e
+               }
+
+               return true, nil
+       })
+}
+
+func (r *Register) getGoVersion(elfFile *elf.File, versionSymbol 
*profiling.Symbol) (*version.Version, error) {
+       buffer, err := elfFile.ReadSymbolData(".data", versionSymbol.Location, 
versionSymbol.Size)
+       if err != nil {
+               return nil, fmt.Errorf("reading go version struct info failure: 
%v", err)
+       }
+       var t = goStringInC{}
+       buf := bytes.NewReader(buffer)
+       err = binary.Read(buf, binary.LittleEndian, &t)
+       if err != nil {
+               return nil, fmt.Errorf("read the go structure failure: %v", err)
+       }
+       buffer, err = elfFile.ReadSymbolData(".data", t.Ptr, t.Size)
+       if err != nil {
+               return nil, fmt.Errorf("read the go version failure: %v", err)
+       }
+
+       // parse versions
+       submatch := goVersionRegex.FindStringSubmatch(string(buffer))
+       if len(submatch) != 3 {
+               return nil, fmt.Errorf("the go version is failure to identify, 
version: %s", string(buffer))
+       }
+       return version.Read(submatch[1], submatch[2], "")
+}
+
+type goStringInC struct {
+       Ptr  uint64
+       Size uint64
+}
+
+func (r *Register) generateGOTLSSymbolOffsets(register *Register, elfFile 
*elf.File, v *version.Version) (*GoTLSSymbolAddress, error) {
+       reader, err := elfFile.NewDwarfReader(
+               goTLSReadSymbol, goTLSWriteSymbol, goTLSGIDStatusSymbol,
+               goTLSPollFDSymbol, goTLSConnSymbol, goTLSRuntimeG)
+       if err != nil {
+               return nil, err
+       }
+
+       symbolAddresses := &GoTLSSymbolAddress{}
+
+       sym := register.SearchSymbol(func(a, b string) bool {
+               return a == b
+       }, "go.itab.*net.TCPConn,net.Conn")
+       if sym == nil {
+               log.Warnf("could not found the tcp connection symbol: 
go.itab.*net.TCPConn,net.Conn")
+               return nil, nil
+       }
+       symbolAddresses.TCPConnOffset = sym.Location
+
+       readFunction := reader.GetFunction(goTLSReadSymbol)
+       if readFunction == nil {
+               log.Warnf("could not found the go tls read symbol: %s", 
goTLSReadSymbol)
+               return nil, nil
+       }
+       writeFunction := reader.GetFunction(goTLSWriteSymbol)
+       if writeFunction == nil {
+               log.Warnf("could not found the go tls write symbol: %s", 
goTLSWriteSymbol)
+               return nil, nil
+       }
+       gidStatusFunction := reader.GetFunction(goTLSGIDStatusSymbol)
+       if gidStatusFunction == nil {
+               log.Warnf("could not found the goid status change symbol: %s", 
goTLSGIDStatusSymbol)
+               return nil, nil
+       }
+
+       var retValArg0, retValArg1 = "~r1", "~r2"
+       if v.Minor >= 18 {
+               retValArg0, retValArg1 = "~r0", "~r1"
+       }
+
+       // build the symbols
+       var assignError error
+       // offset
+       assignError = r.assignGoTLSStructureOffset(assignError, reader, 
goTLSPollFDSymbol, "Sysfd", &symbolAddresses.FDSysFDOffset)
+       assignError = r.assignGoTLSStructureOffset(assignError, reader, 
goTLSConnSymbol, "conn", &symbolAddresses.TLSConnOffset)
+       assignError = r.assignGoTLSStructureOffset(assignError, reader, 
goTLSRuntimeG, "goid", &symbolAddresses.GIDOffset)
+       assignError = r.assignGoTLSStructureOffset(assignError, reader, 
goTLSConnSymbol, "isClient", &symbolAddresses.IsClientOffset)
+
+       // gid status change
+       assignError = r.assignGoTLSArgsLocation(assignError, gidStatusFunction, 
"gp", &symbolAddresses.CasgStatusGPLoc)
+       assignError = r.assignGoTLSArgsLocation(assignError, gidStatusFunction, 
"newval", &symbolAddresses.CasgStatusNEWValLoc)
+
+       // write
+       assignError = r.assignGoTLSArgsLocation(assignError, writeFunction, 
"c", &symbolAddresses.WriteConnectionLoc)
+       assignError = r.assignGoTLSArgsLocation(assignError, writeFunction, 
"b", &symbolAddresses.WriteBufferLoc)
+       assignError = r.assignGoTLSArgsLocation(assignError, writeFunction, 
retValArg0, &symbolAddresses.WriteRet0Loc)
+       assignError = r.assignGoTLSArgsLocation(assignError, writeFunction, 
retValArg1, &symbolAddresses.WriteRet1Loc)
+       // read
+       assignError = r.assignGoTLSArgsLocation(assignError, readFunction, "c", 
&symbolAddresses.ReadConnectionLoc)
+       assignError = r.assignGoTLSArgsLocation(assignError, readFunction, "b", 
&symbolAddresses.ReadBufferLoc)
+       assignError = r.assignGoTLSArgsLocation(assignError, readFunction, 
retValArg0, &symbolAddresses.ReadRet0Loc)
+       assignError = r.assignGoTLSArgsLocation(assignError, readFunction, 
retValArg1, &symbolAddresses.ReadRet1Loc)
+
+       return symbolAddresses, assignError
+}
+
+func (r *Register) assignGoTLSStructureOffset(err error, reader 
*elf.DwarfReader, structName, fieldName string, dest *uint64) error {
+       if err != nil {
+               return err
+       }
+       structure := reader.GetStructure(structName)
+       if structure == nil {
+               return fmt.Errorf("the structure is not found, name: %s", 
structName)
+       }
+       field := structure.GetField(fieldName)
+       if field == nil {
+               return fmt.Errorf("the field is not found in structure, 
structure name: %s, field name: %s", structName, fieldName)
+       }
+       *dest = uint64(field.Offset)
+       return nil
+}
+
+func (r *Register) assignGoTLSArgsLocation(err error, function 
*elf.FunctionInfo, argName string, dest *GoSymbolLocation) error {
+       if err != nil {
+               return err
+       }
+       var kSPOffset uint32 = 8
+       args := function.Args(argName)
+       if args == nil {
+               return fmt.Errorf("the args is not found, function: %s, args 
name: %s", function.Name(), argName)
+       }
+       if args.Location.Type == elf.ArgLocationTypeStack {
+               dest.Type = GoTLSArgsLocationTypeStack
+               dest.Offset = uint32(args.Location.Offset) + kSPOffset
+       } else if args.Location.Type == elf.ArgLocationTypeRegister {
+               dest.Type = GoTLSArgsLocationTypeRegister
+               dest.Offset = uint32(args.Location.Offset)
+       } else {
+               return fmt.Errorf("the location type is not support, function: 
%s, args name: %s, type: %d",
+                       function.Name(), argName, args.Location.Type)
+       }
+       return nil
+}
diff --git a/pkg/tools/ssl/node.go b/pkg/tools/ssl/node.go
new file mode 100644
index 0000000..e0f2f99
--- /dev/null
+++ b/pkg/tools/ssl/node.go
@@ -0,0 +1,211 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+package ssl
+
+import (
+       "fmt"
+       "os/exec"
+       "regexp"
+       "strings"
+
+       "github.com/apache/skywalking-rover/pkg/tools/btf"
+       "github.com/apache/skywalking-rover/pkg/tools/profiling"
+       "github.com/apache/skywalking-rover/pkg/tools/version"
+
+       "github.com/cilium/ebpf"
+)
+
+var (
+       nodeVersionRegex = 
regexp.MustCompile(`^node\.js/v(?P<Major>\d+)\.(?P<Minor>\d+)\.(?P<Patch>\d+)$`)
+)
+
+type NodeTLSSymbolAddress struct {
+       TLSWrapStreamListenerOffset     uint32
+       StreamListenerStreamOffset      uint32
+       StreamBaseStreamResourceOffset  uint32
+       LibuvStreamWrapStreamBaseOffset uint32
+       LibuvStreamWrapStreamOffset     uint32
+       UVStreamSIOWatcherOffset        uint32
+       UVIOSFDOffset                   uint32
+}
+
+func (r *Register) Node(sslSymbolOffsetsMap, nodeTLSSymbolOffsetsMap *ebpf.Map,
+       sslWrite, sslWriteRet, sslRead, sslReadRet,
+       sslNew, tlsWrap, tlsWrapRet *ebpf.Program) {
+       r.addHandler("Node", func() (bool, error) {
+               libSSLModule, nodeModule, openSSLAttach, err := 
r.findNodeTLSModules()
+               if err != nil {
+                       return false, err
+               }
+               if libSSLModule == nil || nodeModule == nil {
+                       return false, nil
+               }
+               v, err := r.getNodeVersion(nodeModule.Path)
+               if err != nil {
+                       return false, err
+               }
+               log.Debugf("read the nodejs version, pid: %d, version: %s", 
r.pid, v)
+               // openSSL symbol offsets
+               if sslSymbolOffsetsMap != nil {
+                       config, err := 
r.buildOpenSSLSymAddrConfig(libSSLModule.Path)
+                       if err != nil {
+                               return false, err
+                       }
+                       if err := sslSymbolOffsetsMap.Put(uint32(r.pid), 
config); err != nil {
+                               return false, err
+                       }
+               }
+               if nodeTLSSymbolOffsetsMap != nil {
+                       config, err := r.findNodeTLSAddrConfig(v)
+                       if err != nil {
+                               return false, err
+                       }
+                       // setting the locations
+                       if err := nodeTLSSymbolOffsetsMap.Put(uint32(r.pid), 
config); err != nil {
+                               return false, fmt.Errorf("setting the node TLS 
location failure, pid: %d, error: %v", r.pid, err)
+                       }
+               }
+               libSSLLinker := r.linker.OpenUProbeExeFile(libSSLModule.Path)
+               if openSSLAttach {
+                       libSSLLinker.AddLink("SSL_write", sslWrite, sslWriteRet)
+                       libSSLLinker.AddLink("SSL_read", sslRead, sslReadRet)
+               }
+               if e := r.nodeTLSRegisterProbes(v, libSSLLinker, nodeModule, 
sslNew, tlsWrap, tlsWrapRet); e != nil {
+                       return false, e
+               }
+               if e := r.linker.HasError(); e != nil {
+                       return false, e
+               }
+               return true, nil
+       })
+}
+
+func (r *Register) getNodeVersion(p string) (*version.Version, error) {
+       result, err := exec.Command("strings", p).Output()
+       if err != nil {
+               return nil, err
+       }
+       for _, d := range strings.Split(string(result), "\n") {
+               versionInfo := 
nodeVersionRegex.FindStringSubmatch(strings.TrimSpace(d))
+               if len(versionInfo) != 4 {
+                       continue
+               }
+               return version.Read(versionInfo[1], versionInfo[2], 
versionInfo[3])
+       }
+
+       return nil, fmt.Errorf("nodejs version is not found")
+}
+
+var nodeTLSAddrWithVersions = []struct {
+       v    *version.Version
+       conf *NodeTLSSymbolAddress
+}{
+       {version.Build(10, 19, 0), &NodeTLSSymbolAddress{0x0130, 0x08, 0x00, 
0x50, 0x90, 0x88, 0x30}},
+       {version.Build(12, 3, 1), &NodeTLSSymbolAddress{0x0130, 0x08, 0x00, 
0x50, 0x90, 0x88, 0x30}},
+       {version.Build(12, 16, 2), &NodeTLSSymbolAddress{0x0138, 0x08, 0x00, 
0x58, 0x98, 0x88, 0x30}},
+       {version.Build(13, 0, 0), &NodeTLSSymbolAddress{0x0130, 0x08, 0x00, 
0x50, 0x90, 0x88, 0x30}},
+       {version.Build(13, 2, 0), &NodeTLSSymbolAddress{0x0130, 0x08, 0x00, 
0x58, 0x98, 0x88, 0x30}},
+       {version.Build(13, 10, 1), &NodeTLSSymbolAddress{0x0140, 0x08, 0x00, 
0x60, 0xa0, 0x88, 0x30}},
+       {version.Build(14, 5, 0), &NodeTLSSymbolAddress{0x138, 0x08, 0x00, 
0x58, 0x98, 0x88, 0x30}},
+       {version.Build(15, 0, 0), &NodeTLSSymbolAddress{0x78, 0x08, 0x00, 0x58, 
0x98, 0x88, 0x30}},
+}
+
+var nodeTLSProbeWithVersions = []struct {
+       v *version.Version
+       f func(uprobe *btf.UProbeExeFile, register *Register, nodeModule 
*profiling.Module, tlsWrap, tlsWrapRet *ebpf.Program)
+}{
+       {version.Build(10, 19, 0), func(uprobe *btf.UProbeExeFile, register 
*Register, nodeModule *profiling.Module, tlsWrap, tlsWrapRet *ebpf.Program) {
+               
uprobe.AddLinkWithSymbols(register.searchSymbolNames([]*profiling.Module{nodeModule},
 strings.HasPrefix, "_ZN4node7TLSWrapC2E"),
+                       tlsWrap, tlsWrapRet)
+               
uprobe.AddLinkWithSymbols(register.searchSymbolNames([]*profiling.Module{nodeModule},
 strings.HasPrefix, "_ZN4node7TLSWrap7ClearInE"),
+                       tlsWrap, tlsWrapRet)
+               
uprobe.AddLinkWithSymbols(register.searchSymbolNames([]*profiling.Module{nodeModule},
 strings.HasPrefix, "_ZN4node7TLSWrap8ClearOutE"),
+                       tlsWrap, tlsWrapRet)
+       }},
+       {version.Build(15, 0, 0), func(uprobe *btf.UProbeExeFile, register 
*Register, nodeModule *profiling.Module, tlsWrap, tlsWrapRet *ebpf.Program) {
+               
uprobe.AddLinkWithSymbols(register.searchSymbolNames([]*profiling.Module{nodeModule},
 strings.HasPrefix, "_ZN4node6crypto7TLSWrapC2E"),
+                       tlsWrap, tlsWrapRet)
+               
uprobe.AddLinkWithSymbols(register.searchSymbolNames([]*profiling.Module{nodeModule},
 strings.HasPrefix, "_ZN4node6crypto7TLSWrap7ClearInE"),
+                       tlsWrap, tlsWrapRet)
+               
uprobe.AddLinkWithSymbols(register.searchSymbolNames([]*profiling.Module{nodeModule},
 strings.HasPrefix, "_ZN4node6crypto7TLSWrap8ClearOutE"),
+                       tlsWrap, tlsWrapRet)
+       }},
+}
+
+func (r *Register) findNodeTLSAddrConfig(v *version.Version) 
(*NodeTLSSymbolAddress, error) {
+       var lastest *NodeTLSSymbolAddress
+       for _, c := range nodeTLSAddrWithVersions {
+               if v.GreaterOrEquals(c.v) {
+                       lastest = c.conf
+               }
+       }
+       if lastest != nil {
+               return lastest, nil
+       }
+       return nil, fmt.Errorf("could not support version: %s", v)
+}
+
+func (r *Register) findNodeTLSModules() (libSSLModule, nodeModule 
*profiling.Module, openSSLAttach bool, err error) {
+       moduleName1, moduleName2, libsslName := "/nodejs", "/node", "libssl.so"
+       processModules, err := r.findModules(moduleName1, moduleName2, 
libsslName)
+       if err != nil {
+               return nil, nil, false, err
+       }
+       nodeModule = processModules[moduleName1]
+       libSSLModule = processModules[libsslName]
+       if nodeModule == nil {
+               nodeModule = processModules[moduleName2]
+       }
+       if nodeModule == nil {
+               return nil, nil, false, nil
+       }
+       if libSSLModule == nil {
+               if r.searchSymbolInModules([]*profiling.Module{nodeModule}, 
func(a, b string) bool {
+                       return a == b
+               }, "SSL_read") == nil || 
r.searchSymbolInModules([]*profiling.Module{nodeModule}, func(a, b string) bool 
{
+                       return a == b
+               }, "SSL_write") == nil {
+                       return nil, nil, false, nil
+               }
+               libSSLModule = nodeModule
+               openSSLAttach = true
+       }
+       return
+}
+
+func (r *Register) nodeTLSRegisterProbes(v *version.Version, libSSLLinker 
*btf.UProbeExeFile, nodeModule *profiling.Module,
+       sslNew, tlsWrap, tlsWrapRet *ebpf.Program) error {
+       if sslNew != nil {
+               libSSLLinker.AddLinkWithType("SSL_new", false, sslNew)
+       }
+       if tlsWrap != nil && tlsWrapRet != nil {
+               var probeFunc func(uprobe *btf.UProbeExeFile, register 
*Register, nodeModule *profiling.Module, tlsWrap, tlsWrapRet *ebpf.Program)
+               for _, c := range nodeTLSProbeWithVersions {
+                       if v.GreaterOrEquals(c.v) {
+                               probeFunc = c.f
+                       }
+               }
+               if probeFunc == nil {
+                       return fmt.Errorf("the version is not support to attach 
TLSWrap relate probes: %v, pid: %d", v, r.pid)
+               }
+               file := r.linker.OpenUProbeExeFile(nodeModule.Path)
+               probeFunc(file, r, nodeModule, tlsWrap, tlsWrapRet)
+       }
+
+       return nil
+}
diff --git a/pkg/tools/ssl/openssl.go b/pkg/tools/ssl/openssl.go
new file mode 100644
index 0000000..87f1931
--- /dev/null
+++ b/pkg/tools/ssl/openssl.go
@@ -0,0 +1,141 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+package ssl
+
+import (
+       "fmt"
+       "os/exec"
+       "regexp"
+       "strconv"
+       "strings"
+
+       "github.com/cilium/ebpf"
+)
+
+var (
+       openSSLVersionRegex = 
regexp.MustCompile(`^OpenSSL\s+(?P<Major>\d)\.(?P<Minor>\d)\.(?P<Fix>\d+)\w?`)
+)
+
+type OpenSSLSymbolAddresses struct {
+       BIOReadOffset  uint32
+       BIOWriteOffset uint32
+       FDOffset       uint32
+       RoleOffset     uint32
+}
+
+func (r *Register) OpenSSL(symbolAddrMap *ebpf.Map, sslWrite, sslWriteRet, 
sslRead, sslReadRet *ebpf.Program) {
+       r.addHandler("OpenSSL", func() (bool, error) {
+               var libcryptoName, libsslName = "libcrypto.so", "libssl.so"
+               var libcryptoPath, libsslPath string
+               modules, err := r.findModules(libcryptoName, libsslName)
+               if err != nil {
+                       return false, err
+               }
+               if len(modules) == 0 {
+                       return false, nil
+               }
+               if libcrypto := modules[libcryptoName]; libcrypto != nil {
+                       libcryptoPath = libcrypto.Path
+               }
+               if libssl := modules[libsslName]; libssl != nil {
+                       libsslPath = libssl.Path
+               }
+               if libcryptoPath == "" || libsslPath == "" {
+                       return false, fmt.Errorf("the OpenSSL library not 
complete, libcrypto: %s, libssl: %s", libcryptoPath, libsslPath)
+               }
+
+               addresses, err := r.buildOpenSSLSymAddrConfig(libcryptoPath)
+               if err != nil {
+                       return false, err
+               }
+
+               if err := symbolAddrMap.Put(uint32(r.pid), addresses); err != 
nil {
+                       return false, err
+               }
+
+               libSSLLinker := r.linker.OpenUProbeExeFile(libsslPath)
+               libSSLLinker.AddLink("SSL_write", sslWrite, sslWriteRet)
+               libSSLLinker.AddLink("SSL_read", sslRead, sslReadRet)
+               if err := r.linker.HasError(); err != nil {
+                       return false, err
+               }
+               return true, nil
+       })
+}
+
+func (r *Register) buildOpenSSLSymAddrConfig(libcryptoPath string) 
(*OpenSSLSymbolAddresses, error) {
+       // using "strings" command to query the symbol in the libcrypto library
+       result, err := exec.Command("strings", libcryptoPath).Output()
+       if err != nil {
+               return nil, err
+       }
+       for _, p := range strings.Split(string(result), "\n") {
+               submatch := openSSLVersionRegex.FindStringSubmatch(p)
+               if len(submatch) != 4 {
+                       continue
+               }
+               major := submatch[1]
+               minor := submatch[2]
+               fix := submatch[3]
+
+               log.Debugf("found the libcrypto.so version: %s.%s.%s", major, 
minor, fix)
+               conf := &OpenSSLSymbolAddresses{}
+
+               // must be number, already validate in the regex
+               majorVal, _ := strconv.Atoi(major)
+               minorVal, _ := strconv.Atoi(minor)
+               fixVal, _ := strconv.Atoi(fix)
+
+               // max support version is 3.0.x
+               if majorVal > 3 || (majorVal == 3 && minorVal > 0) {
+                       return nil, fmt.Errorf("the version of the libcrypto is 
not support: %s.%s.%s", major, minor, fix)
+               }
+
+               // bio offset
+               // 
https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/ssl/ssl.h#L1093-L1111
+               // 
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/ssl/ssl_local.h#L1068-L1083
+               // 
https://github.com/openssl/openssl/blob/openssl-3.0.7/ssl/ssl_local.h#L1212-L1227
+               conf.BIOReadOffset = 16
+               conf.BIOWriteOffset = 24
+               // fd offset
+               if majorVal == 3 && minorVal == 0 {
+                       // 3.0.x
+                       // 
https://github.com/openssl/openssl/blob/openssl-3.0.7/crypto/bio/bio_local.h#L115-L128
+                       // OPENSSL_NO_DEPRECATED_3_0 is not defined by default 
unless the user pass the specific build option
+                       conf.FDOffset = 56
+                       // 
https://github.com/openssl/openssl/blob/openssl-3.0.7/ssl/ssl_local.h#L1212-L1245
+                       conf.RoleOffset = 56
+               } else if (minorVal == 0) || (minorVal == 1 && fixVal == 0) {
+                       // 1.0.x || 1.1.0
+                       // 
https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/crypto/bio/bio.h#L297-L306
+                       conf.FDOffset = 40
+                       // 
https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/ssl/ssl.h#L1093-L1138
+                       conf.RoleOffset = 72
+               } else {
+                       // 1.1.1
+                       // 
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/crypto/bio/bio_local.h#L115-L125
+                       conf.FDOffset = 48
+                       // 
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/ssl/ssl_local.h#L1068-L1101
+                       conf.RoleOffset = 56
+               }
+               log.Debugf("the lobcrypto.so library symbol verson config, 
version: %s.%s.%s, bio offset: %d",
+                       major, minor, fix, conf.FDOffset)
+               return conf, nil
+       }
+       return nil, fmt.Errorf("could not fount the version of the 
libcrypto.so")
+}
diff --git a/pkg/profiling/task/network/ssl_test.go 
b/pkg/tools/ssl/openssl_test.go
similarity index 76%
rename from pkg/profiling/task/network/ssl_test.go
rename to pkg/tools/ssl/openssl_test.go
index 1ed387d..cb0bb7c 100644
--- a/pkg/profiling/task/network/ssl_test.go
+++ b/pkg/tools/ssl/openssl_test.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package network
+package ssl
 
 import (
        "os/exec"
@@ -29,6 +29,7 @@ func TestBuildSSLSymAddrConfig(t *testing.T) {
        mockOutput := func(out string) *exec.Cmd {
                return exec.Command("echo", out)
        }
+       register := NewSSLRegister(0, nil)
 
        result := `%s:%d: OpenSSL internal error: %s
 OpenSSL 1.0.2o  31 Mar 2020
@@ -38,7 +39,7 @@ OpenSSL X9.42 DH method`
                patches.Reset()
        })
 
-       conf, err := buildSSLSymAddrConfig("/test")
+       conf, err := register.buildOpenSSLSymAddrConfig("/test")
        assert.Nil(t, err)
        assert.Equal(t, uint32(16), conf.BIOReadOffset)
        assert.Equal(t, uint32(24), conf.BIOWriteOffset)
@@ -49,7 +50,17 @@ OpenSSL X9.42 DH method`
 OpenSSL 1.1.1f  31 Mar 2020
 OpenSSL X9.42 DH method`
        patches = gomonkey.ApplyFuncReturn(exec.Command, mockOutput(result))
-       conf, err = buildSSLSymAddrConfig("/test")
+       conf, err = register.buildOpenSSLSymAddrConfig("/test")
+       assert.Nil(t, err)
+       assert.Equal(t, uint32(16), conf.BIOReadOffset)
+       assert.Equal(t, uint32(24), conf.BIOWriteOffset)
+       assert.Equal(t, uint32(48), conf.FDOffset)
+
+       // should same with 1.1.1, which from the NodeJS build-in version of 
OpenSSL
+       patches.Reset()
+       result = `OpenSSL 1.1.1q+quic  5 Jul 2022`
+       patches = gomonkey.ApplyFuncReturn(exec.Command, mockOutput(result))
+       conf, err = register.buildOpenSSLSymAddrConfig("/test")
        assert.Nil(t, err)
        assert.Equal(t, uint32(16), conf.BIOReadOffset)
        assert.Equal(t, uint32(24), conf.BIOWriteOffset)
@@ -60,7 +71,7 @@ OpenSSL X9.42 DH method`
 OpenSSL 3.0.3 3 May 2022
 OpenSSL RSA method`
        patches = gomonkey.ApplyFuncReturn(exec.Command, mockOutput(result))
-       conf, err = buildSSLSymAddrConfig("/test")
+       conf, err = register.buildOpenSSLSymAddrConfig("/test")
        assert.Nil(t, err)
        assert.Equal(t, uint32(16), conf.BIOReadOffset)
        assert.Equal(t, uint32(24), conf.BIOWriteOffset)
diff --git a/pkg/tools/ssl/ssl.go b/pkg/tools/ssl/ssl.go
new file mode 100644
index 0000000..4830821
--- /dev/null
+++ b/pkg/tools/ssl/ssl.go
@@ -0,0 +1,146 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+package ssl
+
+import (
+       "fmt"
+       "strings"
+
+       "github.com/apache/skywalking-rover/pkg/logger"
+       "github.com/apache/skywalking-rover/pkg/tools/btf"
+       "github.com/apache/skywalking-rover/pkg/tools/path"
+       "github.com/apache/skywalking-rover/pkg/tools/process"
+       "github.com/apache/skywalking-rover/pkg/tools/profiling"
+)
+
+type handler func() (bool, error)
+
+var log = logger.GetLogger("tools", "ssl")
+
+type Register struct {
+       pid    int
+       linker *btf.Linker
+
+       handlers map[string]handler
+       modules  []*profiling.Module
+}
+
+func NewSSLRegister(pid int, linker *btf.Linker) *Register {
+       return &Register{
+               pid:      pid,
+               linker:   linker,
+               handlers: make(map[string]handler),
+       }
+}
+
+func (r *Register) Execute() error {
+       modules, err := process.Modules(int32(r.pid))
+       if err != nil {
+               return fmt.Errorf("read process modules error: %v, error: %v", 
r.pid, err)
+       }
+       r.modules = modules
+
+       count := 0
+       for name, h := range r.handlers {
+               b, err := h()
+               if err != nil {
+                       return err
+               }
+               if b {
+                       count++
+                       log.Debugf("success add register to process, pid: %d, 
name: %s", r.pid, name)
+               }
+       }
+       if count == 0 {
+               log.Debugf("cannot find any SSL register for process: %d", 
r.pid)
+       }
+       return nil
+}
+
+func (r *Register) addHandler(name string, h handler) {
+       r.handlers[name] = h
+}
+
+func (r *Register) findModules(names ...string) (map[string]*profiling.Module, 
error) {
+       result := make(map[string]*profiling.Module)
+       for _, mod := range r.modules {
+               for _, modName := range names {
+                       if strings.Contains(mod.Name, modName) {
+                               if !path.Exists(mod.Path) {
+                                       return nil, fmt.Errorf("the module path 
not exists, path: %s", mod.Path)
+                               }
+                               result[modName] = mod
+                       }
+               }
+       }
+       return result, nil
+}
+
+func (r *Register) SearchSymbol(verify stringVerify, values ...string) 
*profiling.Symbol {
+       return r.searchSymbolInModules(r.modules, verify, values...)
+}
+
+func (r *Register) searchSymbolInModules(modules []*profiling.Module, verify 
stringVerify, values ...string) *profiling.Symbol {
+       list := r.searchSymbolListInModules(modules, verify, values...)
+       if len(list) > 0 {
+               return list[0]
+       }
+       return nil
+}
+
+func (r *Register) searchSymbolListInModules(modules []*profiling.Module, 
verify stringVerify, values ...string) []*profiling.Symbol {
+       var result []*profiling.Symbol
+       for _, mod := range modules {
+               for _, s := range mod.Symbols {
+                       for _, validator := range values {
+                               if verify(s.Name, validator) {
+                                       result = append(result, s)
+                               }
+                       }
+               }
+       }
+       return result
+}
+
+func (r *Register) searchSymbolNames(modules []*profiling.Module, verify 
stringVerify, values ...string) []string {
+       list := r.searchSymbolList(modules, verify, values...)
+       if len(list) > 0 {
+               result := make([]string, 0)
+               for _, i := range list {
+                       result = append(result, i.Name)
+               }
+               return result
+       }
+       return nil
+}
+
+func (r *Register) searchSymbolList(modules []*profiling.Module, verify 
stringVerify, values ...string) []*profiling.Symbol {
+       var result []*profiling.Symbol
+       for _, mod := range modules {
+               for _, s := range mod.Symbols {
+                       for _, validator := range values {
+                               if verify(s.Name, validator) {
+                                       result = append(result, s)
+                               }
+                       }
+               }
+       }
+       return result
+}
+
+type stringVerify func(a, b string) bool

Reply via email to