バックナンバーはこちら。
https://www.simulationroom999.com/blog/In-vehicle-network-backnumber/
はじめに
IPフラグメントの受信フレーム順違いに対応するための設計手法。
登場人物
博識フクロウのフクさん

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
IPフラグメントの順番入れ替えの判定をどこでやっているのか?

じゃー、IPフラグメントの順番違いをどう対応してるのか説明よろしくー。

はいよー。

まずは、全部のフレームが揃ったかどうかチェックしているのは
ip_reass_chain_frag_into_datagram_and_validate
って関数になる。
core/ipv4/ip4_frag.c
で定義されてる関数になるね。

ip4_frag.c?
そのまんまな名前のソースコードがあったとは・・・。
ip_reass_chain_frag_into_datagram_and_validateの中の完了判定部分

さらに、ip_reass_chain_frag_into_datagram_and_validateの中で完了判定をしている箇所がある。
そこだけのコードを切り抜いてきた。
/* At this point, the validation part begins: */
/* If we already received the last fragment */
if (is_last || ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0)) {
/* and had no holes so far */
if (valid) {
/* then check if the rest of the fragments is here */
/* Check if the queue starts with the first datagram */
if ((ipr->p == NULL) || (((struct ip_reass_helper *)ipr->p->payload)->start != 0)) {
valid = 0;
} else {
/* and check that there are no holes after this datagram */
iprh_prev = iprh;
q = iprh->next_pbuf;
while (q != NULL) {
iprh = (struct ip_reass_helper *)q->payload;
if (iprh_prev->end != iprh->start) {
valid = 0;
break;
}
iprh_prev = iprh;
q = iprh->next_pbuf;
}
/* if still valid, all fragments are received
* (because to the MF==0 already arrived */
if (valid) {
LWIP_ASSERT("sanity check", ipr->p != NULL);
LWIP_ASSERT("sanity check",
((struct ip_reass_helper *)ipr->p->payload) != iprh);
LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
iprh->next_pbuf == NULL);
}
}
}
/* If valid is 0 here, there are some fragments missing in the middle
* (since MF == 0 has already arrived). Such datagrams simply time out if
* no more fragments are received... */
return valid ? IP_REASS_VALIDATE_TELEGRAM_FINISHED : IP_REASS_VALIDATE_PBUF_QUEUED;
}
完了判定部分解説

うーん・・・。
何やってるかわからん!!

簡単に説明すると、以下の仕組みになってる。
- 各EthernetFrameは連結リストで連結されている。
- 各EthernetFrameはIPパケット上の開始位置と終了位置を保持している。
- 各EthernetFrameは開始位置順にソートされている。
- 各EthernetFrameの終了位置は次のEthernetFrameの開始位置のはずである。

んー?
うーん?

(わからんか・・・。)

図解するとこうだな。


おー!
そういう関係性かー!

そういえば、連結リストって前にも出てきたね。

あれ?
Ethnertフレーム自体が連結リストだったと思うのだけど、
今回のEthnertフレームがさらに連結されてる???

そうそう。
そこが話がややこしくなってるところで、
構造上は連結リストを連結リストで連結している。

また、ややこしいことに・・・。

まぁEthernet層の話はIP層には直接関係ないんで、
一旦気にしないって方が良いかもねー。

とりあえず、いろいろ工夫されてるという事実はわかった。
まとめ

まとめだよ。
- IPフラグメントの順番入れ替えの判定のソースコードと該当関数説明。
- Ethnertフレームを連結リストで管理。
- 連結は常にソートされた状態。
- 開始位置と完了位置を持ってパケットの完全性を評価している。
使用したコードはこちら。
バックナンバーはこちら。
コメント