(toppers-users 2925) Re: TINET による PPP 接続時の切断について

Manabu Tanabe m_tanabe @ na.rim.or.jp
2009年 4月 9日 (木) 17:42:59 JST


 田辺@名古屋です。

 いつもお世話になっております。

 下記の再接続時の不具合の件、解決しました。

 原因は、IPCP でセッション開始時、若しくはセッション終了時に
ダイアルアップ PPP サーバから通知を受けたローカルの IP アドレスを
クリアしていなかったため、2回目の接続時に、既にサーバから
通知済みの IP アドレスがあるかのように振舞ってしまい、
2回目の接続で送信したパケットをサーバ側で無視していたようです。

 小生が使用している ISP が特殊なのかは分かりませんが、
ダイアルアップ PPP サーバはセッション確立毎に異なる IP アドレスを
通知してくるので、その IP アドレスを使用するように変更しました。

 通信が出来なかった仕組みを書きますと・・・

[1回目の接続]
・TCP の SYN パケットを送信しようとする(送信元は IPV4_ADDRANY)
・PPP サーバにダイアルアップ
・PPP のリンク確立で IP アドレスが通知される(例えば、192.168.1.1)
・TCP/IP で通信をする
・TCP/IP を切断する
・PPP を切断する
・ダイアルアップ終了
[2回目の接続]
・TCP の SYN パケットを送信しようとする(送信元は IPV4_ADDRANY)
・TCP_CON_CEP() の IN_IFAWITHIFP(IF_GET_IFNET(), &p_dstaddr->ipaddr)) の
 IF_GET_IFNET() => ppp_get_ifnet() で "192.168.1.1" が返される
・PPP のリンク確立で IP アドレスが通知される(例えば、192.168.1.2)
・サーバへは送信元 "192.168.1.1" でパケットが送られる
・サーバは割り振ったアドレス "192.168.1.2" からので無いので無視(?)する
・サーバからの応答が無く、通信が出来ない

のようになっていました。

 この状態を回避するため、ipcp_local_ack_cfg を PPP のセッション終了時に
初期化すべく、ipcp_down() を下記のように変更しました。

static void
ipcp_down (T_PPP_FSM *fsm)
{
//	sig_sem(SEM_IPCP_READY);					←先にコメントアウト済み
	syslog(LOG_NOTICE, "[PPP/IPCP] down.");
	ipcp_resetci( fsm );						←追加
	}

 以上です。お騒がせしました。

>  阿部 様
> 
>  田辺@名古屋です。
> 
>  いつもお世話になっております。
> 
>  すこしソースを追いかけてみました。
> TCP 通信端点の状態が1回目の接続と、2回目の
> 接続シーケンスが異なることが気になりまして。。。
> 
>  PPP で接続時、ppp.c の関数 ppp_output() を呼び出した際、
> IPCP の接続が確立していない時は wait_ipcp() の呼び出しで
> 処理がブロックされます。実際に処理をブロックしているのは、
> ppp_ipcp.c の関数 wait_ipcp() 内で呼び出している
> wai_sem(SEM_IPCP_READY); の部分です。
> 
>  1回目の接続時はこの部分で IPCP 接続まで待機しているのですが、
> 2回目の接続を行おうとすると、この部分をすり抜けてしまいます。
> よって、SEM_IPCP_READY で grep をかけてみたところ、
> ppp_ipcp.c の関数 ipcp_down() で sig_sem(SEM_IPCP_READY); を
> していたので、この部分をコメントアウトしてみました。
> 
>  早速、試してみたところ・・・2回目の接続も1回目の接続と同様、
> wai_sem(SEM_IPCP_READY); で処理がブロックされていい感じか・・・
> と思いきや、やはり、上手く再接続してくれませんでした。
> 
>  とりあえず、初回の接続と2回目以降の接続シーケンスの違いは、
> ipcp_down() で sig_sem(SEM_IPCP_READY); が影響していると思われます。
> 
>  以上、途中報告です。
> 
> > tinet/netinet/tcp_var.h の 460行目ぐらいに TCP 通信端点の状態フラグが
> > 定義されています。
> > 
> > 0x00000001 は、直ちに相手に ACK を送る。
> > 0x00002000 は、生成済みで有効な通信端点。
> > 
> > という意味ですので、今回には関係ないと思います。
> > 
> > 二回目接続時の状態から見ると、こちらからサーバに、
> > コネクション確立要求を送っていますが、サーバから応答がないと推測されます。
> > なお、送信した PPP フレームがエラーで破棄され、サーバに届いていないか、
> > サーバからの PPP フレームがエラーで破棄されている可能性もありますので、
> > プロトコルアナライザー等でフレームを見て判断するしか方法は無いようですね。
> 
>  以上、よろしくお願いいたします。
> 
> -<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-
>  E-mail  : m_tanabe @ na.rim.or.jp
> -<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-

 以上、よろしくお願いいたします。

-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-
 E-mail  : m_tanabe @ na.rim.or.jp
-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-<->-