From 50244b414c64064bbfd91531d6cc694a96e241af Mon Sep 17 00:00:00 2001 From: Kozlov Dmitry Date: Fri, 30 Aug 2013 14:40:22 +0400 Subject: ipoe: fixed race during session activation --- accel-pppd/ctrl/ipoe/ipoe.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index e8fbaba..73854c0 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); -- cgit v1.2.3