バックナンバーはこちら。
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フレームを連結リストで管理。
- 連結は常にソートされた状態。
- 開始位置と完了位置を持ってパケットの完全性を評価している。
使用したコードはこちら。
バックナンバーはこちら。
コメント