diff options
author | Kozlov Dmitry <xeb@mail.ru> | 2013-08-30 14:40:22 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2013-08-30 14:40:51 +0400 |
commit | 50244b414c64064bbfd91531d6cc694a96e241af (patch) | |
tree | 92dcfcb66c4f8806d1f5ef9b915155eb1e38f80b /accel-pppd | |
parent | 0614a5ed9e54982604f4c1b4a44617625312e5fd (diff) | |
download | accel-ppp-50244b414c64064bbfd91531d6cc694a96e241af.tar.gz accel-ppp-50244b414c64064bbfd91531d6cc694a96e241af.zip |
ipoe: fixed race during session activation
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index e8fbaba8..73854c0c 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -153,6 +153,7 @@ static void ipoe_serv_close(struct triton_context_t *ctx); static void __ipoe_session_activate(struct ipoe_session *ses); static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *pack); static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *pack, int force); +static void ipoe_session_keepalive(struct dhcpv4_packet *pack); static int get_offer_delay(); static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct dhcpv4_packet *pack, struct ipoe_session **opt82_ses) @@ -757,8 +758,20 @@ static void __ipoe_session_activate(struct ipoe_session *ses) triton_timer_mod(&ses->timer, 0); } -static void ipoe_session_activate(struct ipoe_session *ses) +static void ipoe_session_activate(struct dhcpv4_packet *pack) { + struct ipoe_session *ses = container_of(triton_context_self(), typeof(*ses), ctx); + + if (ses->ses.state == AP_STATE_ACTIVE) { + ipoe_session_keepalive(pack); + return; + } + + if (ses->dhcpv4_request) + dhcpv4_packet_free(ses->dhcpv4_request); + + ses->dhcpv4_request = pack; + if (ses->serv->dhcpv4_relay) dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id); else @@ -1310,10 +1323,9 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet if (serv->opt_shared == 0) ipoe_drop_sessions(serv, ses); - if (ses->ses.state == AP_STATE_STARTING && ses->yiaddr && !ses->dhcpv4_request) { - ses->dhcpv4_request = pack; + if (ses->ses.state == AP_STATE_STARTING && ses->yiaddr) { dhcpv4_packet_ref(pack); - triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_activate, ses); + triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_activate, pack); } else if (ses->ses.state == AP_STATE_ACTIVE) { dhcpv4_packet_ref(pack); triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_keepalive, pack); |