一覧NW-15-3 · Wi-Fiと無線通信

Wi-Fiの接続とローミング

BSSIDの切替と鍵の準備、IP通信再開までの時間を照合します。

説明

同じSSID内で接続先を変えるときも、無線の切替と認証・鍵の準備、IP通信の再開は別の出来事です。信号が強いAPを見つけた瞬間に通信が再開するとは限りません。

WPA2-Personalを使う固定記録で接続段階を確認し、BSSIDを切り替えたときの停止時間を計算します。BSSIDが変わってもIPを維持する場合と、通信再開が別の段階で遅れる場合を比較します。

1接続の段階を順番に確認する

この例はWPA2-Personalで、802.11のOpen System Authenticationの後に鍵を準備する構成です。

events=接続段階と経過ms[(0,"scan"),(20,"802.11 authentication success"),(30,"association success"),(50,"EAPOL M1"),(60,"EAPOL M2"),(70,"EAPOL M3"),(80,"EAPOL M4"),(90,"data allowed")]; events接続開始から利用可能まで

802.11の認証成功と、暗号化通信に必要な鍵が使用可能になることは別の段階です。WPA3-SAEやEnterpriseでは手順が異なるため、この並びをすべての無線接続へそのまま当てはめません。

2鍵交換の前後に何が残るか

association完了30msからM4の80ms、データ許可90msまでを計算します。

associated=関連付けの完了30; keys_complete=この記録の鍵交換完了80; allowed=データ許可90; (keys_complete残っていた時間-associated,allowed-associated)

鍵交換完了まで50ms、データ許可まで60msです。association成功の記録だけでIP通信が可能になったと判断せず、後続の鍵交換や認可を確認します。

3同じSSIDでBSSIDが変わる

ローミング前後の接続情報を比較します。

before=移動前の接続dict(ssid="Study",bssid="02:00:00:00:00:0a",ip="192.0.2.10"); after=移動後の接続dict(ssid="Study",bssid="02:00:00:00:00:0b",ip="192.0.2.10"); {k:変化した項目(before[k],after[k]) for k in before if before[k]!=after[k]}

変わったのはBSSIDです。この例は同じIPネットワーク内の移動なのでIPを維持しています。BSSIDの変更だけで新しいDHCP割当てが必須になるとは限りません。

4無線の切替とデータ再開の時刻

最後のデータ受信1000ms、走査終了1030ms、再関連付け1050ms、鍵完了1080ms、データ再開1090msの記録です。

roam=移動中の時刻[("last data",1000),("scan done",1030),("reassociated",1050),("keys ready",1080),("data resumed",1090)]; [(roam[i][0]段階ごとの所要時間,roam[i][1]-roam[i-1][1]) for i in range(1,len(roam))]

各段階の差は30・20・30・10msです。最後のデータから再開までは90ms空いています。無線のフレームだけでなく、実際にデータが届いた時刻まで照合すると、利用者が体験した停止を確認できます。

5予定していたデータの何件分が途切れたか

20ms間隔のデータが1020・1040・1060・1080・1100msに到着予定だったとします。再開1090msより前の予定を数えます。

scheduled=20ms間隔の予定list(range(1020,1101,20)); interrupted=再開前の予定時刻[t for t in scheduled if t<1090]; (interrupted該当する予定と件数,len(interrupted))

4件分の予定が停止区間に入ります。これは再送やバッファを含めない予定時刻との比較で、実際に4パケットがネットワークで破棄された証明ではありません。アプリケーションの期限と受信記録も確認します。

6無線は切り替わったのに通信が遅い場合

別の記録では鍵準備1080ms、近隣解決完了1200ms、アプリ応答1240msでした。

keys=鍵の準備時刻1080; neighbor=近隣解決の完了1200; response=アプリ応答1240; (neighbor無線準備後の遅れ-keys,response-neighbor,response-keys)

鍵の準備後に近隣解決へ120ms、その後応答へ40msかかっています。停止全体をローミング認証だけの問題と扱わず、VLAN、IP経路、近隣表、アプリケーションのどこで時間を使ったかを確認します。

まとめ

無線の関連付け、鍵の準備、IP通信、アプリ応答の時刻を分けて照合します。

同じSSID内の移動でも停止があり、BSSIDの変化とIPの変化は別です。

操作履歴と解説を振り返れます。

Python 3

1
events=[(0,"scan"),(20,"802.11 authentication success"),(30,"association success"),(50,"EAPOL M1"),(60,"EAPOL M2"),(70,"EAPOL M3"),(80,"EAPOL M4"),(90,"data allowed")]; events
[(0, 'scan'), (20, '802.11 authentication success'), (30, 'association success'), (50, 'EAPOL M1'), (60, 'EAPOL M2'), (70, 'EAPOL M3'), (80, 'EAPOL M4'), (90, 'data allowed')]
2
associated=30; keys_complete=80; allowed=90; (keys_complete-associated,allowed-associated)
(50, 60)
3
before=dict(ssid="Study",bssid="02:00:00:00:00:0a",ip="192.0.2.10"); after=dict(ssid="Study",bssid="02:00:00:00:00:0b",ip="192.0.2.10"); {k:(before[k],after[k]) for k in before if before[k]!=after[k]}
{'bssid': ('02:00:00:00:00:0a', '02:00:00:00:00:0b')}
4
roam=[("last data",1000),("scan done",1030),("reassociated",1050),("keys ready",1080),("data resumed",1090)]; [(roam[i][0],roam[i][1]-roam[i-1][1]) for i in range(1,len(roam))]
[('scan done', 30), ('reassociated', 20), ('keys ready', 30), ('data resumed', 10)]
5
scheduled=list(range(1020,1101,20)); interrupted=[t for t in scheduled if t<1090]; (interrupted,len(interrupted))
([1020, 1040, 1060, 1080], 4)
6
keys=1080; neighbor=1200; response=1240; (neighbor-keys,response-neighbor,response-keys)
(120, 40, 160)

演習完了