[En-Nut-Discussion] net/ipout.c memory leak
Stefan Hax
stefan at escherlogic.com
Mon Jun 7 18:36:28 CEST 2010
Found the leak in the form of duplicate entries in the routing table. A
simple fix I propose as follows in net/route.c :
int NutIpRouteAdd(uint32_t ip, uint32_t mask, uint32_t gate, NUTDEVICE *
dev)
{
int rc = -1;
RTENTRY *rte;
RTENTRY *rtp;
RTENTRY **rtpp;
...added code......
rtp = rteList;
while (rtp) { // go through the whole list!!
// check for duplicate!!
if( (rtp->rt_ip == (ip & mask)) && (rtp->rt_mask == mask) &&
(rtp->rt_gateway == gate) && (rtp->rt_dev == dev) ) {
return 0; // duplicate found ... bye
}
rtp = rtp->rt_next;
}
..................
/*
* Insert a new entry into the list, which is
* sorted based on the mask. Host routes are
* in front, default routes at the end and
* networks in between.
*/
rtp = rteList;
rtpp = &rteList;
while (rtp && rtp->rt_mask > mask) {
...etc...
Stefan.
Stefan Hax wrote:
> Sorry, the call to (*nif->if_output)() already frees nb_clone in case of
> error. Although I have not found my memory leak, NutNetBufFree() does
> not look right when dealing with clones. Here is my suggestion:
>
> extending nb_flags in the structure to be a uint16_t instead of a
> uint8_t then:
> #define NBAF_DIE 0x0100
>
> ... in /net/netbuf.c:
>
> void NutNetBufFree(NETBUF * nb)
> {
> if (nb->nb_flags & NBAF_REFCNT) { // referecned
> by something??
> nb->nb_flags |= NBAF_DIE; // just mark
> this for death
>
> } else { // no ref...
> start free'ing what is owned
> if (nb->nb_flags & NBAF_DATALINK) {
> if(nb->nb_ref) {
> if(nb->nb_ref->nb_dl.vp != nb->nb_dl.vp) {
> // our's to relese?? then relese it.
> NutHeapFree(nb->nb_dl.vp);
> }
> } else {
> NutHeapFree(nb->nb_dl.vp);
> }
> }
>
> if (nb->nb_flags & NBAF_NETWORK) {
> if(nb->nb_ref) {
> if(nb->nb_ref->nb_nw.vp != nb->nb_nw.vp) {
> // our's to relese?? then relese it.
> NutHeapFree(nb->nb_nw.vp);
> }
> } else {
> NutHeapFree(nb->nb_nw.vp);
> }
> }
>
> if (nb->nb_flags & NBAF_TRANSPORT) {
> if(nb->nb_ref) {
> if(nb->nb_ref->nb_tp.vp != nb->nb_tp.vp) {
> // our's to relese?? then relese it.
> NutHeapFree(nb->nb_tp.vp);
> }
> } else {
> NutHeapFree(nb->nb_tp.vp);
> }
> }
>
> if (nb->nb_flags & NBAF_APPLICATION) {
> if(nb->nb_ref) {
> if(nb->nb_ref->nb_ap.vp != nb->nb_ap.vp) {
> // our,s to relese?? then relese it.
> NutHeapFree(nb->nb_ap.vp);
> }
> } else {
> NutHeapFree(nb->nb_ap.vp);
> }
> }
>
> if (nb->nb_ref) {
> if(nb->nb_ref->nb_flags & NBAF_REFCNT) { // dec
> parent count of this ref??
> nb->nb_ref->nb_flags--;
> }
>
> if(nb->nb_ref->nb_flags & NBAF_DIE) { //
> parent marked for death?? then free it..
> NutNetBufFree(nb->nb_ref);
> }
> }
>
> NutHeapFree(nb);
> }
> }
>
> If what is being freed is the 'parent' and their are still references to
> it then only mark for freeing when all clones have been freed.
> Otherwise, this will just release what bufferes were allocated when the
> clone was created and decrement the reference count in the parent then
> free the clone, and finally, the parent is freed once all references are
> gone.
>
> Stefan.
>
> Stefan Hax wrote:
>> noticed a small memory leak in ../net/ipout.c during UDP broadcast failures.
>>
>> code is:
>> NutIpOutput(..)
>> {
>> ...
>> if (nif->if_type == IFT_ETHER)
>> rc = (*nif->if_output) (dev, ETHERTYPE_IP, ha,
>> nb_clone);
>> else if (nif->if_type == IFT_PPP)
>> rc = (*nif->if_output) (dev, PPP_IP, 0, nb_clone);
>>
>> if (rc == 0) {
>> NutNetBufFree(nb_clone);
>> }
>> ...
>> }
>>
>>
>> sugested:
>> NutIpOutput(..)
>> {
>> ...
>> if (nif->if_type == IFT_ETHER)
>> rc = (*nif->if_output) (dev, ETHERTYPE_IP, ha,
>> nb_clone);
>> else if (nif->if_type == IFT_PPP)
>> rc = (*nif->if_output) (dev, PPP_IP, 0, nb_clone);
>>
>> if(nb_clone) { /* <-- might be a better choice */
>> NutNetBufFree(nb_clone);
>> }
>> ...
>> }
>>
>>
>> Regards, Stefan.
>> _______________________________________________
>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>
More information about the En-Nut-Discussion
mailing list