wifi: add watchdog to drop bss if stuck in ap association or get deauthenticated by the ap
This commit is contained in:
parent
196b39126c
commit
5165864dbb
|
@ -285,7 +285,6 @@ recvassoc(Wifi *wifi, Wnode *wn, uchar *d, int len)
|
||||||
default:
|
default:
|
||||||
wn->aid = 0;
|
wn->aid = 0;
|
||||||
setstatus(wifi, Sunassoc);
|
setstatus(wifi, Sunassoc);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,21 +345,26 @@ recvbeacon(Wifi *, Wnode *wn, uchar *d, int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notify aux/wpa with a zero length write that we got deassociated from the ap */
|
|
||||||
static void
|
static void
|
||||||
wifideassoc(Wifi *wifi)
|
wifideassoc(Wifi *wifi, Wnode *wn)
|
||||||
{
|
{
|
||||||
Ether *ether;
|
Ether *ether;
|
||||||
Netfile *f;
|
Netfile *f;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* deassociate node, clear keys */
|
||||||
|
if(wn != nil){
|
||||||
|
memset(wn->rxkey, 0, sizeof(wn->rxkey));
|
||||||
|
memset(wn->txkey, 0, sizeof(wn->txkey));
|
||||||
|
wn->aid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* notify aux/wpa with a zero length write that we got deassociated from the ap */
|
||||||
ether = wifi->ether;
|
ether = wifi->ether;
|
||||||
for(i=0; i<ether->nfile; i++){
|
for(i=0; i<ether->nfile; i++){
|
||||||
f = ether->f[i];
|
f = ether->f[i];
|
||||||
if(f == nil || f->in == nil || f->inuse == 0 || f->type != 0x888e)
|
if(f == nil || f->in == nil || f->inuse == 0 || f->type != 0x888e)
|
||||||
continue;
|
continue;
|
||||||
if(wifi->debug)
|
|
||||||
print("#l%d: wifideassoc: %#p\n", ether->ctlrno, f);
|
|
||||||
qwrite(f->in, 0, 0);
|
qwrite(f->in, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,10 +423,28 @@ wifiproc(void *arg)
|
||||||
b->rp += wifihdrlen(w);
|
b->rp += wifihdrlen(w);
|
||||||
recvbeacon(wifi, wn, b->rp, BLEN(b));
|
recvbeacon(wifi, wn, b->rp, BLEN(b));
|
||||||
if(wifi->bss == nil && goodbss(wifi, wn)){
|
if(wifi->bss == nil && goodbss(wifi, wn)){
|
||||||
|
wifi->watchdog = 0;
|
||||||
wifi->bss = wn;
|
wifi->bss = wn;
|
||||||
setstatus(wifi, Sconn);
|
setstatus(wifi, Sconn);
|
||||||
sendauth(wifi, wn);
|
sendauth(wifi, wn);
|
||||||
}
|
}
|
||||||
|
if(wn == wifi->bss){
|
||||||
|
ulong wdog;
|
||||||
|
|
||||||
|
/* on each beacon from the bss, check if we'r stuck */
|
||||||
|
wdog = ++wifi->watchdog;
|
||||||
|
if(wifi->status == Sconn && (wdog & 0x1f) == 0){
|
||||||
|
setstatus(wifi, Sunauth);
|
||||||
|
wifi->bss = nil;
|
||||||
|
} else if(wifi->status == Sauth && (wdog & 0x1f) == 0){
|
||||||
|
setstatus(wifi, Sunauth);
|
||||||
|
wifi->bss = nil;
|
||||||
|
} else if(wifi->status == Sblocked && (wdog & 0x3f) == 0){
|
||||||
|
setstatus(wifi, Sunauth);
|
||||||
|
wifideassoc(wifi, wn);
|
||||||
|
wifi->bss = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(memcmp(w->a1, wifi->ether->ea, Eaddrlen))
|
if(memcmp(w->a1, wifi->ether->ea, Eaddrlen))
|
||||||
|
@ -432,6 +454,8 @@ wifiproc(void *arg)
|
||||||
if(wn != wifi->bss)
|
if(wn != wifi->bss)
|
||||||
continue;
|
continue;
|
||||||
switch(w->fc[0] & 0xf0){
|
switch(w->fc[0] & 0xf0){
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
case 0x10: /* assoc response */
|
case 0x10: /* assoc response */
|
||||||
case 0x30: /* reassoc response */
|
case 0x30: /* reassoc response */
|
||||||
b->rp += wifihdrlen(w);
|
b->rp += wifihdrlen(w);
|
||||||
|
@ -445,13 +469,11 @@ wifiproc(void *arg)
|
||||||
break;
|
break;
|
||||||
case 0xc0: /* deauth */
|
case 0xc0: /* deauth */
|
||||||
setstatus(wifi, Sunauth);
|
setstatus(wifi, Sunauth);
|
||||||
memset(wn->rxkey, 0, sizeof(wn->rxkey));
|
wifideassoc(wifi, wn);
|
||||||
memset(wn->txkey, 0, sizeof(wn->txkey));
|
wifi->bss = nil;
|
||||||
wn->aid = 0;
|
|
||||||
wifideassoc(wifi);
|
|
||||||
sendauth(wifi, wn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
wifi->watchdog = 0;
|
||||||
}
|
}
|
||||||
pexit("wifi in queue closed", 0);
|
pexit("wifi in queue closed", 0);
|
||||||
}
|
}
|
||||||
|
@ -683,6 +705,7 @@ wifictl(Wifi *wifi, void *buf, long n)
|
||||||
break;
|
break;
|
||||||
for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++)
|
for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++)
|
||||||
if(goodbss(wifi, wn)){
|
if(goodbss(wifi, wn)){
|
||||||
|
wifi->watchdog = 0;
|
||||||
wifi->bss = wn;
|
wifi->bss = wn;
|
||||||
setstatus(wifi, Sconn);
|
setstatus(wifi, Sconn);
|
||||||
sendauth(wifi, wn);
|
sendauth(wifi, wn);
|
||||||
|
|
|
@ -49,6 +49,7 @@ struct Wifi
|
||||||
|
|
||||||
Queue *iq;
|
Queue *iq;
|
||||||
char *status;
|
char *status;
|
||||||
|
ulong watchdog;
|
||||||
Ref txseq;
|
Ref txseq;
|
||||||
void (*transmit)(Wifi*, Wnode*, Block*);
|
void (*transmit)(Wifi*, Wnode*, Block*);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue