(toppers-users 5) TINET 1.7 - TCPハンドシェイク時のマルチキャストアドレス判定について

駒込 豊 komagome @ meikyo.co.jp
2019年 11月 12日 (火) 11:41:05 JST


TINETご担当様

明京電機株式会社の駒込と申します。

TINET 1.7(JSP版) を使用し、
IPv4/6 デュアルスタックを搭載した装置ソフトの開発を行っております。
IPv4射影アドレスは無効です。
装置は、PCとLAN接続し、PCからWEB画面を介しての操作も行えるものです。

さて、IPv4の環境にて、
WEB画面を自動更新し、繰り返し表示させていたところ
時々「このページを表示できません」となってしまうケースが発生しています。
ハングアップには至っておらず、更新等をすると元に戻ります。

その現象が起きた時には、
ハンドシェイクのSYNパケットに対してACKを返していませんでした。

処理を確認したところ、SYNパケット(IPv4フォーマット) に対して、
一部 IPv6 フォーマット(IPv4射影アドレスも含みます)にて
参照していると思われる箇所がありました。
この影響で、誤って(IPv6の)マルチキャストパケットと判断して、
TCPのハンドシェイクをやめてしまっているようです。


以下、詳細な流れです;

tcp_input.c
 ハンドシェイクでSYNパケットを受け取ったときに
 listening() 関数が実行されます。
 ここで、パケットが受信可能なIPアドレスとポート番号であることを
 確認する処理(tcp_is_addr_accept)を呼びます。

tcp_subr.c
 tcp_is_addr_accept() では
 受信可能かどうかの条件の一つに
 マルチキャストアドレスかどうかの確認が含まれています。
 IN_IS_NET_ADDR_MULTICAST マクロです。

in_var.h、in_sub.c
 IPv4/6 デュアルのときは、
 IN_IS_NET_ADDR_MULTICAST マクロは、
 IN_IS_ADDR_MULTICAST(&GET_IP6_HDR(nbuf)->dst) を呼びます。
 IN_IS_ADDR_MULTICASTマクロは、inn_is_addr_multicast() を呼ぶマクロです。

 inn_is_addr_multicast() の引数は、IP6ヘッダでのdstアドレスへのポインタです。
 ここから IPv4 (Mapped) アドレスか IPv6 アドレスを判断し、
 それぞれマルチキャストアドレスかを選択します。

 しかし、実際に IPv4 のパケットを参照していますのでチェック箇所が誤ります。
 結果として、偶然そこにある値によってマルチキャストかどうかを 判断します。


この箇所を、
 まず IPv4, 6パケットかを判別し、
 それぞれのマルチキャストパケット判断マクロを実行すると
 安定するように見受けられます。

 IN_IS_NET_ADDR_MULTICAST の箇所を以下に変更;

 if (GET_IP_VER(input)==IPV6_VERSION ? IN_IS_ADDR_MULTICAST(&GET_IP6_HDR(input)->dst) :
IN4_IS_ADDR_MULTICAST(ntohl(GET_IP4_HDR(input)->dst)))


ただし、我々のアプリにTINETを移植した際に漏れがないか、
例えばどこかでIPv4射影アドレスに展開する必要があったのか?
なども気にかかっております。

それで、大変お忙しいところ恐縮ですが、
お気づきの点ありましたらご教示いただきたくお願いいたします。



---
明京電機株式会社
駒込 豊 [Komagome Yutaka]



More information about the USERS mailing list