Wed 13 Sep 2006 07:02:05 PM UTC, original submission:
description:
ppp.c consists a bug in pppMain(). When connection is lost (ppp thread dead) allocated memory by pppInProc is not free. The memory is wasted every time when pppOpen - pppClose sequence is done during data link is active and data are still exchanging near time before true killing ppp. Finally it is possible NO FREE MBUFS! message... There is necessery to free pbuf memory.
Solution:
pppDrop() at end of pppMain()
best regards
Janusz Uzycki
example the code:
static void pppMain(void *arg)
{
err_t err;
int pd = (int)arg;
struct pbuf *p;
PPPControl* pc;
pc = &pppControl[pd];
p = pbuf_alloc(PBUF_RAW, PPP_MRU+PPP_HDRLEN, PBUF_RAM);
PPPDEBUG((LOG_WARNING, "pppMain: pbuf alloc %08x\n", p)); //JU
if(!p) {
LWIP_ASSERT("p != NULL", p);
pc->errCode = PPPERR_ALLOC;
goto out;
}
/*
- Start the connection and handle incoming events (packet or timeout).
*/
PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd));
err = tcpip_callback(pppStartCB, arg);
LWIP_ASSERT( "pppMain: can't install callback handler\n", err == ERR_OK );
while (lcp_phase[pd] != PHASE_DEAD) {
if (pc->kill_link) {
PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d kill_link -> pppStopCB\n", pd));
pc->errCode = PPPERR_USER;
/* This will leave us at PHASE_DEAD. */
tcpip_callback(pppStopCB, arg);
pc->kill_link = 0;
}
else if (pc->sig_hup) {
PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sig_hup -> pppHupCB\n", pd));
pc->sig_hup = 0;
tcpip_callback(pppHupCB, arg);
} else {
int c = sio_read(pc->fd, p->payload, p->len);
if(c > 0) {
pppInProc(pd, p->payload, c);
} else {
/* PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sio_read len=%d returned %d\n", pd, p->len, c)); */
}
}
}
PPPDEBUG((LOG_INFO, "pppMain: unit %d: PHASE_D EAD\n", pd));
pppDrop(pc); // or in line after PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d sio_read len=%d returned %d\n", pd, p->len, c));
PPPDEBUG((LOG_WARNING, "pppMain: pbuf free %08x\n", p)); //JU
pbuf_free(p);
out:
PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
if(pc->linkStatusCB)
pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
pc->openFlag = 0;
/* Remove this thread from the running ones. */
sys_arch_thread_remove( sys_arch_thread_current( ) );
LWIP_ASSERT( "pppMain: sys_arch_thread_remove did return\n", 0 );
}
|