WPA_SUPPLICANT源码分析(1):EVENT LOOP的实现

本文详细解读了WPA_SUPPLICANT中EVENTLOOP的工作原理,包括数据结构设计、多事件处理机制及核心函数select的实现。重点讨论了Socket事件、Timeout事件、Signal事件的处理流程,并解答了Socket和Signal事件使用动态数组而非链表的原因。

转:http://blog.chinaunix.net/uid-20273473-id-3128151.html

WPA_SUPPLICANT的程序的生命就是在运行一个EVENT LOOP, 等待各种Event的到来,然后做相应的处理。因此分析EVENT LOOP的实现能起到提纲挈领的作用。


1. 数据结构: 见下图



struct eloop_data结构体是一个统领全局的数据结构,只有一个实例,即Line 75:

点击(此处)折叠或打开

  1. static struct eloop_data eloop;
要处理的Event有三大种类型:Socket事件,Timeout事件,Signal事件.  其中Socket事件又分为三种类型:

  1.  * @EVENT_TYPE_READ: Socket has data available for reading
  2.  * @EVENT_TYPE_WRITE: Socket has room for new data to be written
  3.  * @EVENT_TYPE_EXCEPTION: An exception has been reported
Socket 事件:有readers, writers, exceptions三个eloop_sock_table结构体, 每个里面都有动态数组,数组的每一项都是一个具体的eloop_sock.  可以向各个Table里面添加、删除eloop_sock.  事件分发就是遍历sock_table, 依次运行里面的每个Handler.

Timeout事件: 每个struct eloop_timeout都被放在一个双向链表中, 链表头就是eloop_data中的”timeout”项。这些struct eloop_timeout按超时先后排序。

Signal事件:每个struct eloop_signal放在动态数组中

疑问: 为什么Socket和signal事件不使用链表,而是动态的扩大和缩小数组?

2. 基于Select的多Event处理

void eloop_run(void) 是个总函数,我们看它是怎么用select系统调用实现多路复用监听多个事件的。

  1. while (!eloop.terminate &&
  2.      (!dl_list_empty(&eloop.timeout) || eloop.readers.count > 0 ||
  3.         eloop.writers.count > 0 || eloop.exceptions.count > 0)) {

如果eloop.terminate变为非零值,就会退出循环。这是为了提供一种从外部结束循环的方法。

如果eloop.terminate为零,只要timeout链表或者任一个Socket不为空,都会继续循环。

Select系统调用的原型是:

  1. int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
在循环体里面:

(1)找到timeout链表的第一项(因为是按超时先后排序的,所以第一项肯定是最先超时的),计算超时时间距现在还有多久, 并据此设置select的timeout参数。

(2)设置readfd, writefds和exceptfds三个fd_set:  方法是遍历各个eloop_sock_table,把每个sock描述符加入相应的fd_set里面。

(3)调用select。   可能阻塞在此处。

(4)eloop_process_pending_signals();  处理Signal事件。后面会分析。

(5)判断是否有超时发生,如果是则调用其Handler, 并从timeout链表移除。然后继续下次循环。

(6)如果不是超时事件,则应该是readfds, writefds或者exceptfds事件, fd_set里面会被改变,存放发生事件的描述符。因此分别遍历三个sock_table,  如果其描述符在fd_set里面则调用其Handler.

(7)继续下次循环.

值得一提的是,这里对Signal的处理有点特别。在eloop_register_signal() 函数注册的signal的Handler并不是当Signal发生时就会自动执行的。当Signal发生时只会对该struct eloop_signal的 signaled变量加1,以表明Signal已收到并处于Pendning状态。在select()超时或者有Socket事件方式时才会顺便调用eloop_process_pending_signals(), 对每个处于Pending状态的struct eloop_signal调用其Handler.

疑问:这样做有什么好处?如果select阻塞很久,岂不是Signal也要Pending很久才得到处理?

nl80211: Connect request send successfully 行 64558: 09-27 10:51:47.823 3399 3400 W C05200/wpa_supplicant: nl80211: Connect request send successfully 行 64560: 09-27 10:51:47.823 3399 3400 D C05200/wpa_supplicant: wlan0: Setting authentication timeout: 10 sec 0 usec 行 64561: 09-27 10:51:47.823 3399 3400 D C05200/wpa_supplicant: EAPOL: External notification - EAP success=0 行 64562: 09-27 10:51:47.823 3399 3400 D C05200/wpa_supplicant: EAPOL: External notification - EAP fail=0 行 64563: 09-27 10:51:47.823 3399 3400 D C05200/wpa_supplicant: EAPOL: External notification - portControl=Auto 行 67765: 09-27 10:51:47.973 3399 3400 D C05200/wpa_supplicant: RTM_NEWLINK: ifi_index=32 ifname=wlan0 operstate=5 linkmode=1 ifi_family=0 ifi_flags=0x11003 ([UP][LOWER_UP]) 行 67776: 09-27 10:51:47.974 3399 3400 D C05200/wpa_supplicant: nl80211: Event message available 行 67780: 09-27 10:51:47.975 3399 3400 I C05200/wpa_supplicant: nl80211: Drv Event 46 (NL80211_CMD_CONNECT) received for wlan0 行 67781: 09-27 10:51:47.975 3399 3400 D C05200/wpa_supplicant: nl80211: Connect event (status=0 ignore_next_local_disconnect=0) 行 67789: 09-27 10:51:47.977 3399 3400 D C05200/wpa_supplicant: nl80211: Associated on 2412 MHz 行 67790: 09-27 10:51:47.977 3399 3400 D C05200/wpa_supplicant: nl80211: Associated with 02:6c:26:35:2e:d9 行 67791: 09-27 10:51:47.977 3399 3400 D C05200/wpa_supplicant: nl80211: Operating frequency for the associated BSS from scan results: 2412 MHz 行 67893: 09-27 10:51:47.978 3399 3400 D C05200/wpa_supplicant: nl80211: Associated on 2412 MHz 行 67897: 09-27 10:51:47.979 3399 3400 D C05200/wpa_supplicant: nl80211: Associated with 02:6c:26:35:2e:d9 行 67904: 09-27 10:51:47.980 3399 3400 D C05200/wpa_supplicant: nl80211: Set drv->ssid based on scan res info to 'yangshilun' 行 67904: 09-27 10:51:47.980 3399 3400 D C05200/wpa_supplicant: nl80211: Set drv->ssid based on scan res info to 'yangshilun' 行 67909: 09-27 10:51:47.980 3399 3400 D C05200/wpa_supplicant: CTRL-DEBUG: ctrl_sock-sendmsg: sock=9 sndbuf=229376 outq=0 send_len=24 行 67912: 09-27 10:51:47.980 3399 3400 D C05200/wpa_supplicant: CTRL_IFACE monitor sent successfully to /data/service/el1/public/wifi/wpa_ctrl_872-108\x00 行 67921: 09-27 10:51:47.980 3399 3400 D C05200/wpa_supplicant: wlan0: Association info event 行 67923: 09-27 10:51:47.980 3399 3400 D C05200/wpa_supplicant: req_ies - hexdump(len=178): 00 0a 79 61 6e 67 73 68 69 6c 75 6e 01 08 82 84 8b 96 0c 12 18 24 21 02 0a 14 32 04 30 48 60 行 67926: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: resp_ies - hexdump(len=166): 01 08 82 84 8b 96 0c 12 18 24 32 04 30 48 60 6c 2d 1a ad 09 17 ff ff 00 00 00 00 00 00 00 00 行 67928: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: unknown vendor specific information element ignored (vendor OUI 8c:fd:f0 len=11) 行 67929: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: unknown vendor specific information element ignored (vendor OUI 8c:fd:f0 len=11) 行 67931: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: wlan0: freq=2412 MHz 行 67932: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: unknown vendor specific information element ignored (vendor OUI 40:45:da len=6) 行 67935: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: unknown vendor specific information element ignored (vendor OUI 8c:fd:f0 len=11) 行 67937: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: VHT operation CBW: 11 行 67938: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: overall operation CBW: 1 行 67939: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: WPA: set own WPA/RSN IE - hexdump(len=22): 30 14 01 00 00 0f ac 04 01 00 00 0f ac 04 01 00 00 0f ac 02 8c 00 行 67940: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: wlan0: RSN: clearing own RSNXE 行 67941: 09-27 10:51:47.981 3399 3400 I C05200/wpa_supplicant: wlan0: State: ASSOCIATING -> ASSOCIATED 行 67942: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: CTRL-DEBUG: ctrl_sock-sendmsg: sock=9 sndbuf=229376 outq=0 send_len=32 行 67943: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: CTRL_IFACE monitor sent successfully to /data/service/el1/public/wifi/wpa_ctrl_872-108\x00 行 67944: 09-27 10:51:47.981 3399 3400 D C05200/wpa_supplicant: nl80211: Set wlan0 operstate 0->0 (DORMANT) 行 67946: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: netlink: Operstate: ifindex=32 linkmode=-1 (no change), operstate=5 (IF_OPER_DORMANT) 行 67947: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: CTRL-DEBUG: ctrl_sock-sendmsg: sock=9 sndbuf=229376 outq=0 send_len=76 行 67948: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: CTRL_IFACE monitor sent successfully to /data/service/el1/public/wifi/wpa_ctrl_872-108\x00 行 67949: 09-27 10:51:47.982 872 3401 D C01560/WifiWpaHal: wpa recv buf: IFNAME=wlan0 <3>CTRL-EVENT-STATE-CHANGE id=0 state=6 BSSID=00:00:00:00:00:00 SSID=yangshilun! 行 67950: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: prepare call onEventStateChanged 行 67952: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: wlan0: Shared frequencies (len=1): completed iteration 行 67953: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: wlan0: freq[0]: 2412, flags=0x1 行 67954: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Add operating class 81 行 67956: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=13): 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 行 67957: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Add operating class 115 行 67958: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=4): 24 28 2c 30 行 67959: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Add operating class 116 行 67960: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=2): 24 2c 行 67962: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=2): 28 30 行 67963: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Add operating class 124 行 67966: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=5): 95 99 9d a1 a5 行 67967: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Add operating class 126 行 67968: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=2): 95 9d 行 67969: 09-27 10:51:47.982 3399 3400 D C05200/wpa_supplicant: P2P: Add operating class 127 行 67970: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=2): 99 a1 行 67972: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: P2P: Add operating class 128 行 67974: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=8): 24 28 2c 30 95 99 9d a1 行 67976: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: P2P: Add operating class 130 行 67977: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: P2P: Channels - hexdump(len=8): 24 28 2c 30 95 99 9d a1 行 67978: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: P2P: Update channel list 行 67979: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: P2P: channels: 81:1,2,3,4,5,6,7,8,9,10,11,12,13 115:36,40,44,48 116:36,44 117:40,48 124:149,153,157,161 125:149,153,157,1 行 67981: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: P2P: cli_channels: 行 67982: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: Associated to a new BSS: BSSID=02:6c:26:35:2e:d9 行 67989: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: CTRL_IFACE monitor sent successfully to /data/service/el1/public/wifi/wpa_ctrl_872-108\x00 行 67990: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: WPA: Update cipher suite selection based on IEs in driver-generated WPA/RSNE in AssocReq - hexdump(len=49): 30 14 01 00 0 行 67992: 09-27 10:51:47.983 3399 3400 I C05200/wpa_supplicant: wlan0: WPA: AP key_mgmt 0x2 network key_mgmt 0x2; available key_mgmt 0x2 行 67994: 09-27 10:51:47.983 3399 3400 D C05200/wpa_supplicant: CTRL-DEBUG: ctrl_sock-sendmsg: sock=9 sndbuf=229376 outq=768 send_len=65 行 67998: 09-27 10:51:47.984 3399 3400 I C05200/wpa_supplicant: wlan0: WPA: using KEY_MGMT WPA2-PSK and proto 2 行 67999: 09-27 10:51:47.984 3399 3400 D C05200/wpa_supplicant: CTRL-DEBUG: ctrl_sock-sendmsg: sock=9 sndbuf=229376 outq=1536 send_len=40 行 68000: 09-27 10:51:47.984 3399 3400 D C05200/wpa_supplicant: CTRL_IFACE monitor sent successfully to /data/service/el1/public/wifi/wpa_ctrl_872-108\x00 行 68001: 09-27 10:51:47.984 3399 3400 I C05200/wpa_supplicant: wlan0: WPA: AP pairwise cipher 0x10 network pairwise cipher 0x18; available pairwise cipher 0x10 行 68003: 09-27 10:51:47.984 3399 3400 D C05200/wpa_supplicant: CTRL-DEBUG: ctrl_sock-sendmsg: sock=9 sndbuf=229376 outq=2304 send_len=89 行 68004: 09-27 10:51:47.984 3399 3400 D C05200/wpa_supplicant: CTRL_IFACE monitor sent successfully to /data/service/el1/public/wifi/wpa_ctrl_872-108\x00 行 68006: 09-27 10:51:47.984 3399 3400 D C05200/wpa_supplicant: wlan0: WPA: using PTK CCMP 行 68010: 09-27 10:51:47.984 3399 3400 D C05200/wpa_supplicant: wlan0: WPA: using GTK CCMP 行 68011: 09-27 10:51:47.984 3399 3400 D C05200/wpa_supplicant: wlan0: WPA: AP mgmt_group_cipher 0x20 network mgmt_group_cipher 0x0; available mgmt_group_cipher 0x20 行 68022: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: wlan0: WPA: clearing AP RSNXE 行 68023: 09-27 10:51:47.985 3399 3400 I C05200/wpa_supplicant: wlan0: Associated with 02:6c:26:35:2e:d9 行 68025: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: CTRL-DEBUG: ctrl_sock-sendmsg: sock=9 sndbuf=229376 outq=3072 send_len=33 行 68027: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: CTRL_IFACE monitor sent successfully to /data/service/el1/public/wifi/wpa_ctrl_872-108\x00 行 68029: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: wlan0: WPA: Association event - clear replay counter 行 68031: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: wlan0: WPA: Clear old PTK 行 68034: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: EAPOL: External notification - portValid=0 行 68035: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: EAPOL: External notification - EAP success=0 行 68036: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: EAPOL: External notification - portEnabled=1 行 68037: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: EAPOL: SUPP_PAE entering state CONNECTING 行 68038: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: EAPOL: enable timer tick 行 68039: 09-27 10:51:47.985 3399 3400 D C05200/wpa_supplicant: EAPOL: SUPP_BE entering state IDLE 行 68049: 09-27 10:51:47.986 3399 3400 I C05200/wpa_supplicant: wlan0: Cancelling scan request 上面是正常连接wpa2的日志,和错误日志对比有什么差异,问题点出现在那
最新发布
09-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值