在连接wifi的时候,认证或者关联失败,有时会加入黑名单中。记录wpa_supplicant中blacklist的原理。

分析可以看到,如果是机器自己断开,是不会把AP加入黑名单的,只有AP侧出了问题,才有可能加入黑名单。

  1. 首先看一下blacklist的结构体。
  2. external\wpa_supplicant_8\wpa_supplicant\blacklist.h
  3. struct wpa_blacklist {
  4. struct wpa_blacklist *next;
  5. u8 bssid[ETH_ALEN];
  6. int count;
  7. };
  8. external\wpa_supplicant_8\wpa_supplicant\blacklist.c
  9. /**
  10. * wpa_blacklist_get - Get the blacklist entry for a BSSID
  11. * @wpa_s: Pointer to wpa_supplicant data
  12. * @bssid: BSSID
  13. * Returns: Matching blacklist entry for the BSSID or %NULL if not found
  14. */
  15. struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
  16. const u8 *bssid)
  17. {
  18. struct wpa_blacklist *e;
  19. if (wpa_s == NULL || bssid == NULL)
  20. return NULL;
  21. e = wpa_s->blacklist;
  22. while (e) {
  23. if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0)
  24. return e;
  25. e = e->next;
  26. }
  27. return NULL;
  28. }
  29. /**
  30. * wpa_blacklist_add - Add an BSSID to the blacklist
  31. * @wpa_s: Pointer to wpa_supplicant data
  32. * @bssid: BSSID to be added to the blacklist
  33. * Returns: Current blacklist count on success, -1 on failure
  34. *
  35. * This function adds the specified BSSID to the blacklist or increases the
  36. * blacklist count if the BSSID was already listed. It should be called when
  37. * an association attempt fails either due to the selected BSS rejecting
  38. * association or due to timeout.
  39. *
  40. * This blacklist is used to force %wpa_supplicant to go through all available
  41. * BSSes before retrying to associate with an BSS that rejected or timed out
  42. * association. It does not prevent the listed BSS from being used; it only
  43. * changes the order in which they are tried.
  44. */
  45. int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
  46. {
  47. struct wpa_blacklist *e;
  48. if (wpa_s == NULL || bssid == NULL)
  49. return -1;
  50. e = wpa_blacklist_get(wpa_s, bssid);
  51. if (e) { // 如果blacklist中已经存在这个ssid,,count++
  52. e->count++;
  53. wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count "
  54. "incremented to %d",
  55. MAC2STR(bssid), e->count);
  56. return e->count;
  57. }
  58. // 不存在就添加到blacklist链表中
  59. e = os_zalloc(sizeof(*e));
  60. if (e == NULL)
  61. return -1;
  62. // 这个插入方式应该是从链表头插入
  63. os_memcpy(e->bssid, bssid, ETH_ALEN);
  64. e->count = 1;
  65. e->next = wpa_s->blacklist;
  66. wpa_s->blacklist = e;
  67. wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist",
  68. MAC2STR(bssid));
  69. return e->count;
  70. }
  71. /**
  72. * wpa_blacklist_del - Remove an BSSID from the blacklist
  73. * @wpa_s: Pointer to wpa_supplicant data
  74. * @bssid: BSSID to be removed from the blacklist
  75. * Returns: 0 on success, -1 on failure
  76. */
  77. int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
  78. {
  79. struct wpa_blacklist *e, *prev = NULL;
  80. if (wpa_s == NULL || bssid == NULL)
  81. return -1;
  82. e = wpa_s->blacklist;
  83. while (e) {
  84. if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) {
  85. if (prev == NULL) {
  86. wpa_s->blacklist = e->next;
  87. } else {
  88. prev->next = e->next;
  89. }
  90. wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
  91. "blacklist", MAC2STR(bssid));
  92. os_free(e);
  93. return 0;
  94. }
  95. prev = e;
  96. e = e->next;
  97. }
  98. return -1;
  99. }
  100. /**
  101. * wpa_blacklist_clear - Clear the blacklist of all entries
  102. * @wpa_s: Pointer to wpa_supplicant data
  103. */
  104. void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
  105. {
  106. struct wpa_blacklist *e, *prev;
  107. int max_count = 0;
  108. e = wpa_s->blacklist;
  109. wpa_s->blacklist = NULL;
  110. while (e) {
  111. // 获取count的最大值
  112. if (e->count > max_count)
  113. max_count = e->count;
  114. prev = e;
  115. e = e->next;
  116. wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
  117. "blacklist (clear)", MAC2STR(prev->bssid));
  118. os_free(prev);
  119. }
  120. // 临时的计数,判断删除最后一条blacklist是否有失败。
  121. wpa_s->extra_blacklist_count += max_count;
  122. }
  123. wpa_supplicant.c
  124. void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
  125. {
  126. int timeout;
  127. int count;
  128. int *freqs = NULL;
  129. wpas_connect_work_done(wpa_s);
  130. /*
  131. * Remove possible authentication timeout since the connection failed.
  132. */
  133. eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
  134. // 如果断开连接是机器自己产生的,就不会把AP加入到blacklist中,直接返回。
  135. /*
  136. * There is no point in blacklisting the AP if this event is
  137. * generated based on local request to disconnect.
  138. */
  139. if (wpa_s->own_disconnect_req) {
  140. wpa_s->own_disconnect_req = 0;
  141. wpa_dbg(wpa_s, MSG_DEBUG,
  142. "Ignore connection failure due to local request to disconnect");
  143. return;
  144. }
  145. if (wpa_s->disconnected) {
  146. wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
  147. "indication since interface has been put into "
  148. "disconnected state");
  149. return;
  150. }
  151. // 将BSSID加入blacklist中,加速扫描其他可以连接并且关联过的AP。
  152. // 并且对这个BSSID的扫描间隔增加延时,避免连续多次扫描。
  153. /*
  154. * Add the failed BSSID into the blacklist and speed up next scan
  155. * attempt if there could be other APs that could accept association.
  156. * The current blacklist count indicates how many times we have tried
  157. * connecting to this AP and multiple attempts mean that other APs are
  158. * either not available or has already been tried, so that we can start
  159. * increasing the delay here to avoid constant scanning.
  160. */
  161. // 加入黑名单,并获取在黑名单的计数
  162. count = wpa_blacklist_add(wpa_s, bssid);
  163. if (count == 1 && wpa_s->current_bss) {
  164. //这个BSS以前没有在blacklist中,如果在同一个ESS中有另外的BSS,
  165. // 那么另外一个BSS我们也要进行尝试
  166. // 并且在这之前,对这个BSS进行在进行一个尝试,不过还不行,count再加一。
  167. /*
  168. * This BSS was not in the blacklist before. If there is
  169. * another BSS available for the same ESS, we should try that
  170. * next. Otherwise, we may as well try this one once more
  171. * before allowing other, likely worse, ESSes to be considered.
  172. */
  173. freqs = get_bss_freqs_in_ess(wpa_s);
  174. if (freqs) {
  175. wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
  176. "has been seen; try it next");
  177. wpa_blacklist_add(wpa_s, bssid);
  178. /*
  179. * On the next scan, go through only the known channels
  180. * used in this ESS based on previous scans to speed up
  181. * common load balancing use case.
  182. */
  183. os_free(wpa_s->next_scan_freqs);
  184. wpa_s->next_scan_freqs = freqs;
  185. }
  186. }
  187. /*
  188. * Add previous failure count in case the temporary blacklist was
  189. * cleared due to no other BSSes being available.
  190. */
  191. count += wpa_s->extra_blacklist_count;
  192. // count大于3,直接设置认证失败。
  193. if (count > 3 && wpa_s->current_ssid) {
  194. wpa_printf(MSG_DEBUG, "Continuous association failures - "
  195. "consider temporary network disabling");
  196. wpas_auth_failed(wpa_s, "CONN_FAILED");
  197. }
  198. switch (count) {
  199. case 1:
  200. timeout = 100;
  201. break;
  202. case 2:
  203. timeout = 500;
  204. break;
  205. case 3:
  206. timeout = 1000;
  207. break;
  208. case 4:
  209. timeout = 5000;
  210. break;
  211. default:
  212. timeout = 10000;
  213. break;
  214. }
  215. wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
  216. "ms", count, timeout);
  217. // 进行下一次扫描,后面两个参数是扫描的时间
  218. /*
  219. * TODO: if more than one possible AP is available in scan results,
  220. * could try the other ones before requesting a new scan.
  221. */
  222. // 例如timeout=10000, 那么再次扫描的时间10000/1000+1000*(10000%1000) = 10s
  223. wpa_supplicant_req_scan(wpa_s, timeout / 1000,
  224. 1000 * (timeout % 1000));
  225. }

Android 8 wifi blakclist的更多相关文章

  1. 【Android】wifi开发

    WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为“热点 ...

  2. android.net.wifi的简单使用方法

    获取Wifi的控制类WifiManager.  WifiManager  wm=(WifiManager)getSystemService(Context.WIFI_SERVICE); 接下来可以对w ...

  3. android开发 wifi开发工具类

    import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Iterator; import j ...

  4. Android打开WIFI或者移动网络的代码实现

    MainActivity如下: package wy.testnetwork; import java.lang.reflect.Field; import java.lang.reflect.Inv ...

  5. 【移动开发】Android中WIFI开发总结(二)

    搞了好几天终于有点眉目了,这里接着总结一下Android中WiFi的使用,在前面(http://smallwoniu.blog.51cto.com/3911954/1334951)我们已经简单了解了W ...

  6. 【移动开发】Android中WIFI开发总结(一)

     WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为“热 ...

  7. Android 连接Wifi和创建Wifi热点 demo

    android的热点功能不可见,用了反射的技术搞定之外. Eclipse设置语言为utf-8才能查看中文注释 上代码: MainActivity.java package com.widget.hot ...

  8. Android的WiFi开启与关闭

    注意:要首先注册开启和关闭WiFi的权限, <?xml version="1.0" encoding="utf-8"?> <manifest ...

  9. android之wifi开发

    WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为“热点 ...

随机推荐

  1. prometheus-dashboard-to-grafana

    https://prometheus.io/docs/visualization/grafana/ https://www.digitalocean.com/community/tutorials/h ...

  2. [Windows Azure] Building worker role A (email scheduler) for the Windows Azure Email Service application - 4 of 5.

    Building worker role A (email scheduler) for the Windows Azure Email Service application - 4 of 5. T ...

  3. FFmpeg Basics学习笔记(1)ffmpeg基础

    1 FFmpeg的由来 FFmpeg缩写中,FF指的是Fast Forward,mpeg是 Moving Pictures Experts Group的缩写.官网:ffmpeg.org 编译好的可执行 ...

  4. CentOS 6.5 yum安装mysql5.6或其他版本【默认yum只能安装mysql 5.1】 by jason

    by jason [备份配置文件] CentOS 6.5 默认yum只能安装mysql 5.1 安装前要检查机器原来是否安装过mysql,如有安装需要先进行数据备份.清理. [root@snails ...

  5. LeetCode: Pascal's Triangle II 解题报告

    Pascal's Triangle II Total Accepted: 19384 Total Submissions: 63446 My Submissions Question Solution ...

  6. LeetCode: Palindrome Partitioning 解题报告

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

  7. 练习1 Just Java

    任务:做这样一个界面,选择数量,自动计算价格.超级简单.. <?xml version="1.0" encoding="utf-8"?> <a ...

  8. MySQL5.7 利用keepalived来实现mysql双主高可用方案的详细过程

    Reference:  http://blog.csdn.net/mchdba/article/details/51377989 服务器准备 Keepalived:192.168.13.15 Keep ...

  9. C#正则表达式提取HTML中IMG标签的SRC地址

    一般来说一个 HTML 文档有很多标签,比如“<html>”.“<body>”.“<table>”等,想把文档中的 img 标签提取出来并不是一件容易的事.由于 i ...

  10. JAVA-数据库之JDBC连接MySQL数据库

    相关资料:<21天学通Java Web开发> JDBC连接MySQL数据库1.如果需要通过JDBC来连接MySQL数据库,还必须先在MySQL数据库服务器中创建数据库和表. Connect ...