17
17
18
18
#include "api.h"
19
19
#include "socket_opts.h"
20
+ #include "socket_data.h"
20
21
#include "socket_reader.h"
21
22
#include "protocol_analyzer.h"
22
23
#include "../common/connection.h"
23
24
#include "../common/data_args.h"
24
25
25
- #define SOCKET_UPLOAD_CHUNK_LIMIT 12
26
+
26
27
27
28
// openssl read or write
28
29
struct {
@@ -77,58 +78,6 @@ struct {
77
78
__uint (type , BPF_MAP_TYPE_PERF_EVENT_ARRAY );
78
79
} socket_detail_data_queue SEC (".maps" );
79
80
80
- struct socket_data_upload_event {
81
- __u8 protocol ;
82
- __u8 have_reduce_after_chunk ;
83
- __u8 direction ;
84
- __u8 finished ;
85
- __u16 sequence ;
86
- __u16 data_len ;
87
- __u64 start_time ;
88
- __u64 end_time ;
89
- __u64 conid ;
90
- __u64 randomid ;
91
- __u64 data_id ;
92
- __u64 total_size ;
93
- char buffer [MAX_TRANSMIT_SOCKET_READ_LENGTH + 1 ];
94
- };
95
- struct {
96
- __uint (type , BPF_MAP_TYPE_PERCPU_ARRAY );
97
- __type (key , __u32 );
98
- __type (value , struct socket_data_upload_event );
99
- __uint (max_entries , 1 );
100
- } socket_data_upload_event_per_cpu_map SEC (".maps" );
101
- struct {
102
- __uint (type , BPF_MAP_TYPE_PERF_EVENT_ARRAY );
103
- } socket_data_upload_event_queue SEC (".maps" );
104
-
105
- struct socket_data_sequence_t {
106
- __u64 data_id ;
107
- __u16 sequence ;
108
- };
109
- struct {
110
- __uint (type , BPF_MAP_TYPE_LRU_HASH );
111
- __uint (max_entries , 1000 );
112
- __type (key , __u64 );
113
- __type (value , struct socket_data_sequence_t );
114
- } socket_data_sequence_generator SEC (".maps" );
115
- static __inline __u16 generate_socket_sequence (__u64 conid , __u64 data_id ) {
116
- struct socket_data_sequence_t * seq = bpf_map_lookup_elem (& socket_data_sequence_generator , & conid );
117
- if (seq == NULL ) {
118
- struct socket_data_sequence_t data = {};
119
- data .data_id = data_id ;
120
- data .sequence = 0 ;
121
- bpf_map_update_elem (& socket_data_sequence_generator , & conid , & data , BPF_NOEXIST );
122
- return 0 ;
123
- }
124
- if (seq -> data_id != data_id ) {
125
- seq -> data_id = data_id ;
126
- seq -> sequence = 0 ;
127
- } else {
128
- seq -> sequence ++ ;
129
- }
130
- return seq -> sequence ;
131
- }
132
81
133
82
static __inline void upload_socket_detail (void * ctx , __u64 conid , struct active_connection_t * connection , __u8 func_name , struct sock_data_args_t * data_args , bool ssl , __u64 end_nacs ) {
134
83
// only send the original socket syscall(not ssl)
@@ -176,120 +125,6 @@ static __inline void upload_socket_detail(void *ctx, __u64 conid, struct active_
176
125
bpf_perf_event_output (ctx , & socket_detail_data_queue , BPF_F_CURRENT_CPU , detail , sizeof (* detail ));
177
126
}
178
127
179
- static __always_inline void __upload_socket_data_with_buffer (void * ctx , __u8 index , char * buf , size_t size , __u32 is_finished , __u8 have_reduce_after_chunk , struct socket_data_upload_event * event ) {
180
- event -> sequence = index ;
181
- event -> data_len = size ;
182
- event -> finished = is_finished ;
183
- event -> have_reduce_after_chunk = have_reduce_after_chunk ;
184
- if (size <= 0 ) {
185
- return ;
186
- }
187
- asm volatile ("%[size] &= 0x7ff;\n" ::[size ] "+r" (size ) :);
188
- bpf_probe_read (& event -> buffer , size & 0x7ff , buf );
189
-
190
- bpf_perf_event_output (ctx , & socket_data_upload_event_queue , BPF_F_CURRENT_CPU , event , sizeof (* event ));
191
- }
192
-
193
- static __always_inline void upload_socket_data_buf (void * ctx , char * buf , ssize_t size , struct socket_data_upload_event * event , __u8 force_unfinished ) {
194
- ssize_t already_send = 0 ;
195
- #pragma unroll
196
- for (__u8 index = 0 ; index < SOCKET_UPLOAD_CHUNK_LIMIT ; index ++ ) {
197
- // calculate bytes need to send
198
- ssize_t remaining = size - already_send ;
199
- size_t need_send_in_chunk = 0 ;
200
- __u8 have_reduce_after_chunk = 0 ;
201
- if (remaining > MAX_TRANSMIT_SOCKET_READ_LENGTH ) {
202
- need_send_in_chunk = MAX_TRANSMIT_SOCKET_READ_LENGTH ;
203
- have_reduce_after_chunk = 1 ;
204
- } else {
205
- need_send_in_chunk = remaining ;
206
- }
207
-
208
- __u32 is_finished = (need_send_in_chunk + already_send ) >= size || index == (SOCKET_UPLOAD_CHUNK_LIMIT - 1 ) ? true : false;
209
- __u8 sequence = index ;
210
- if (force_unfinished == 1 && need_send_in_chunk > 0 ) {
211
- is_finished = 0 ;
212
- sequence = generate_socket_sequence (event -> conid , event -> data_id );
213
- }
214
- __upload_socket_data_with_buffer (ctx , sequence , buf + already_send , need_send_in_chunk , is_finished , have_reduce_after_chunk , event );
215
- already_send += need_send_in_chunk ;
216
-
217
- }
218
- }
219
-
220
- #define UPLOAD_PER_SOCKET_DATA_IOV () \
221
- if (iov_index < iovlen) { \
222
- struct iovec cur_iov; \
223
- bpf_probe_read(&cur_iov, sizeof(cur_iov), &iov[iov_index]); \
224
- ssize_t remaining = size - already_send; \
225
- size_t need_send_in_chunk = remaining - cur_iov_sended; \
226
- __u8 have_reduce_after_chunk = 0; \
227
- if (cur_iov_sended + need_send_in_chunk > cur_iov.iov_len) { \
228
- need_send_in_chunk = cur_iov.iov_len - cur_iov_sended; \
229
- if (need_send_in_chunk > MAX_TRANSMIT_SOCKET_READ_LENGTH) { \
230
- need_send_in_chunk = MAX_TRANSMIT_SOCKET_READ_LENGTH; \
231
- have_reduce_after_chunk = 1; \
232
- } else { \
233
- iov_index++; \
234
- cur_iov_sended = 0; \
235
- } \
236
- } else if (need_send_in_chunk > MAX_TRANSMIT_SOCKET_READ_LENGTH) { \
237
- need_send_in_chunk = MAX_TRANSMIT_SOCKET_READ_LENGTH; \
238
- have_reduce_after_chunk = 1; \
239
- } \
240
- __u32 is_finished = (need_send_in_chunk + already_send) >= size || loop_count == (SOCKET_UPLOAD_CHUNK_LIMIT - 1) ? true : false; \
241
- __upload_socket_data_with_buffer(ctx, loop_count, cur_iov.iov_base + cur_iov_sended, need_send_in_chunk, is_finished, have_reduce_after_chunk, event); \
242
- already_send += need_send_in_chunk; \
243
- loop_count++; \
244
- }
245
-
246
- static __always_inline void upload_socket_data_iov (void * ctx , struct iovec * iov , const size_t iovlen , ssize_t size , struct socket_data_upload_event * event ) {
247
- ssize_t already_send = 0 ;
248
- ssize_t cur_iov_sended = 0 ;
249
- __u8 iov_index = 0 ;
250
- __u8 loop_count = 0 ;
251
-
252
- // each count is same with SOCKET_UPLOAD_CHUNK_LIMIT
253
- UPLOAD_PER_SOCKET_DATA_IOV ();
254
- UPLOAD_PER_SOCKET_DATA_IOV ();
255
- UPLOAD_PER_SOCKET_DATA_IOV ();
256
- UPLOAD_PER_SOCKET_DATA_IOV ();
257
- UPLOAD_PER_SOCKET_DATA_IOV ();
258
- UPLOAD_PER_SOCKET_DATA_IOV ();
259
- UPLOAD_PER_SOCKET_DATA_IOV ();
260
- UPLOAD_PER_SOCKET_DATA_IOV ();
261
- }
262
-
263
- static __inline void upload_socket_data (void * ctx , __u64 start_time , __u64 end_time , __u64 conid , struct active_connection_t * connection , struct sock_data_args_t * args , ssize_t bytes_count , __u32 existing_msg_type , __u32 data_direction , bool ssl ) {
264
- // must have protocol and ssl must same(plain)
265
- // if the connection data is needs to skip upload, then skip
266
- if (connection -> protocol == CONNECTION_PROTOCOL_UNKNOWN || connection -> ssl != ssl || connection -> skip_data_upload == 1 ) {
267
- return ;
268
- }
269
- // generate event
270
- __u32 kZero = 0 ;
271
- struct socket_data_upload_event * event = bpf_map_lookup_elem (& socket_data_upload_event_per_cpu_map , & kZero );
272
- if (event == NULL ) {
273
- return ;
274
- }
275
-
276
- // basic data
277
- event -> start_time = start_time ;
278
- event -> end_time = end_time ;
279
- event -> protocol = connection -> protocol ;
280
- event -> direction = data_direction ;
281
- event -> conid = conid ;
282
- event -> randomid = connection -> random_id ;
283
- event -> total_size = bytes_count ;
284
- event -> data_id = args -> data_id ;
285
-
286
- if (args -> buf != NULL ) {
287
- upload_socket_data_buf (ctx , args -> buf , bytes_count , event , args -> ssl_buffer_force_unfinished );
288
- } else if (args -> iovec != NULL ) {
289
- upload_socket_data_iov (ctx , args -> iovec , args -> iovlen , bytes_count , event );
290
- }
291
- }
292
-
293
128
static __always_inline void process_write_data (void * ctx , __u64 id , struct sock_data_args_t * args , ssize_t bytes_count ,
294
129
__u32 data_direction , const bool vecs , __u8 func_name , bool ssl ) {
295
130
__u64 curr_nacs = bpf_ktime_get_ns ();
@@ -356,5 +191,23 @@ static __always_inline void process_write_data(void *ctx, __u64 id, struct sock_
356
191
upload_socket_detail (ctx , conid , conn , func_name , args , ssl , curr_nacs );
357
192
358
193
// upload the socket data if need
359
- upload_socket_data (ctx , args -> start_nacs , curr_nacs , conid , conn , args , bytes_count , msg_type , data_direction , ssl );
194
+ struct upload_data_args * upload_data_args = generate_socket_upload_args ();
195
+ if (upload_data_args != NULL ) {
196
+ upload_data_args -> start_time = args -> start_nacs ;
197
+ upload_data_args -> end_time = curr_nacs ;
198
+ upload_data_args -> con_id = conid ;
199
+ upload_data_args -> random_id = conn -> random_id ;
200
+ upload_data_args -> socket_data_id = args -> data_id ;
201
+ upload_data_args -> socket_data_iovec = args -> iovec ;
202
+ upload_data_args -> socket_data_iovlen = args -> iovlen ;
203
+ upload_data_args -> bytes_count = bytes_count ;
204
+ upload_data_args -> socket_data_buf = args -> buf ;
205
+ upload_data_args -> data_direction = data_direction ;
206
+ upload_data_args -> connection_protocol = conn -> protocol ;
207
+ upload_data_args -> connection_ssl = conn -> ssl ;
208
+ upload_data_args -> socket_ssl_buffer_force_unfinished = args -> ssl_buffer_force_unfinished ;
209
+ upload_data_args -> connection_skip_data_upload = conn -> skip_data_upload ;
210
+ upload_data_args -> socket_data_ssl = ssl ;
211
+ upload_socket_data (ctx , upload_data_args );
212
+ };
360
213
}
0 commit comments