Saya memutuskan untuk menulis tentang kesalahan umum dalam aplikasi jaringan dan perangkat jaringan. Saya akan mencoba menjelaskan masalah menggunakan tumpukan Linux sebagai contoh. Dan saya akan berdebat lebih abstrak, mencoba menjelaskan prinsip. Toh, semua aplikasi itu berbeda, meski intinya sama. (Mereka mentransfer bit bolak-balik.) Dan setiap aplikasi jaringan, atau perangkat jaringan, membutuhkan pendekatannya sendiri untuk memperbaiki kesalahan yang dibuat di dalamnya.
Masalahnya terletak pada potongan kecil data yang dipertukarkan oleh sistem. Lebih tepatnya, bukan dalam porsi ini sendiri, tetapi bagaimana mereka dikumpulkan dan diproses lebih lanjut.
Misalnya, satu sistem mengirimkan frasa “ Hello World! "
Bagaimana saya bisa melakukan itu? Ya terserah. Semua protokol transfer data dipilih : TCP , MPTCP , UDP . Data tersebut dibagi menjadi beberapa bagian, yang akan kami sebut paket. Dan mereka dikirim ke sistem terakhir. (Bagaimana tepatnya? Tidak masalah sama sekali.)
Yang penting adalah apa (dan bagaimana) sistem akhir akan melakukan dengan data yang diterima. Jika string “ Hello World! "Dibagi menjadi dua paket:
" Halo " - Ini adalah isi dari paket pertama.
“ Dunia! "- Dan ini paket kedua.
, ( ) , (). ( . )
, . , , . , .. . — .
, . ,
«World !» - .
«Hello » - .
, , : «World !Hello ». ( , , « » «seq»).
: seq. , « ». , , . seq? , , «Hello World !»
Linux TCP ( Linux-5.10.7 ) net/ipv4/tcp_ipv4.c tcp_v4_fill_cb, . ,
TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
skb->len - th->doff * 4);
end_seq — . ( , ( , )
: «Hello » - . 6 .
, seq = 0x1 end_seq = 0x7
«World !» - . 7 .
, seq = 0x7 end_seq = 0xe
«Hello World !»
, seq = 0x4 end_seq = 0xb
«Hello ld !»
«Wor» . ( , ) . tcp_rcv_nxt_update net/ipv4/tcp_input.c rcv_nxt struct tcp_sock. , end_seq ( ). ( rcv_nxt tcp )
: end_seq. , copied_seq struct tcp_sock. , ( ) , rcv_nxt end_seq. .
. : seq = 0xfffffff0 0x64 (100)
TCP_SKB_CB(skb)->end_seq = (0xfffffff0 + 0x1 + 0 + 0x140 - 0x40);
( doff = 5 tcp )
TCP_SKB_CB(skb)->end_seq = 0xfffffff0 + 0x65 = 0x100000055
. . , end_seq = 0x55 (85 ) rcv_nxt = 0xfffffff0 , . . .
, end_seq < seq ( 0x55 < 0xfffffff0 )
, , . ( , skb_len )
. seq = 0xfffffc6e 1000 (end_seq = 0x56 ) , URG . : 16- . , (urgent) .
, . , urg . . . ( TCP Offload Engine )
seq ( ), ( ), urg 0 - 0xffff,
rcv_nxt. . ( ) . .
, : after before. , "" , "" "".
, .
inline bool before(__u32 seq1, __u32 seq2)
{
return (__s32)(seq1-seq2) < 0;
}
#define after(seq2, seq1) before(seq1, seq2)
after( 0x80000000, 0x7fffffff ) = 1
after( 0x7fffffff, 0x80000000 ) = 0
after( 0x80000000, 0x80000000 ) = 0
before( 0x80000000, 0x7fffffff ) = 0
before( 0x7fffffff, 0x80000000 ) = 1
before( 0x80000000, 0x80000000 ) = 0
, , .
, , . , end_seq , .
end_seq < seq ( 0x55 < 0xfffffff0 )
, , __,
if(TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq >= __) {
__ } else { _ }
if(0x55 - 0xfffffff0 >= __)
if(0xffffff9 >= __)
drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c .
handle_urg_ptr .
if (skb && tp->copied_seq - ULP_SKB_CB(skb)->seq >= skb->len)
chtls_free_skb(sk, skb);
: copied_seq, seq, skb->len .
(- , ULP_SKB_CB(skb)->seq ). (skb)->seq, seq, copied skb->len , , . ( , )
, : chtls_cm.c
chtls_recv_data
if (unlikely(hdr->urg))
handle_urg_ptr(sk, tp->rcv_nxt + ntohs(hdr->urg));
if (unlikely(tp->urg_data == TCP_URG_NOTYET &&
tp->urg_seq - tp->rcv_nxt < skb->len))
tp->urg_data = TCP_URG_VALID |
skb->data[tp->urg_seq - tp->rcv_nxt];
handle_urg_ptr(sk, tp->rcv_nxt + ntohs(hdr->urg)); : tp->rcv_nxt + ntohs(hdr->urg) .
rcv_nxt , hdr->urg . , __ handle_urg_ptr . , .
if (unlikely(tp->urg_data == TCP_URG_NOTYET &&
tp->urg_seq - tp->rcv_nxt < skb->len))
tp->urg_data = TCP_URG_VALID |
skb->data[tp->urg_seq - tp->rcv_nxt];
tp->urg_seq - tp->rcv_nxt < skb->len , , , ( ). skb->data[tp->urg_seq - tp->rcv_nxt];
, tp->urg_seq - tp->rcv_nxt. , - ???
tp->urg_seq - tp->rcv_nxt < skb->len
, skb->data
urg_seq - tp->rcv_nxt , .
skb->len,
tp->urg_seq - tp->rcv_nxt < skb->len
skb->data[0xffffffff];
skb->data[0xfffffff0];
skb->data[0xffffff00]; .
, . .
.
(, ). , , ( ). , .
, " " , .
tcp , / , . . , ( , .). , "" ( - ), , - . , ( ), . , . . , . , . . , , , .
, . .
, ( ) . . , . ( ) ( . , )
chtls_recv , .
void chtls_recv(struct chtls_dev *cdev,
struct sk_buff **skbs, const __be64 *rsp)
{
struct sk_buff *skb = *skbs;
unsigned int opcode;
int ret;
opcode = *(u8 *)rsp; //
__skb_push(skb, sizeof(struct rss_header));
skb_copy_to_linear_data(skb, rsp, sizeof(struct rss_header));
ret = chtls_handlers[opcode](cdev, skb); // ,
if (ret & CPL_RET_BUF_DONE)
kfree_skb(skb);
}
, .
opcode = *(u8 *)rsp; , .
, , seq urg, , .
ret = chtls_handlers[opcode](cdev, skb);
NULL. .
.
, TCP urg. , UDP (. , , ). , . , .
( ). , . . ( + , ) , , ) .
.