lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Problem with NULL pcb->callback_arg


From: Baptiste Chaboud-crousaz
Subject: Re: [lwip-users] Problem with NULL pcb->callback_arg
Date: Tue, 4 Aug 2009 16:46:35 +0200
User-agent: Internet Messaging Program (IMP) H3 (4.1.6)

Hi,

For a better understanding I give a part of the code of my HTTP server:

===============================================

void httpd_init(void)
{
  struct tcp_pcb *pcb;

  pcb = tcp_new();
  tcp_bind(pcb, IP_ADDR_ANY, 80);
  pcb = tcp_listen(pcb);
  tcp_accept(pcb, http_accept);
}

===============================================

static err_t
http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
    struct http_connect_state* hcs;

    tcp_setprio(pcb, TCP_PRIO_MIN);

    /* Allocate memory for the structure that holds the state of the connection. */
    hcs = mem_malloc(sizeof(struct http_connect_state));

    if (hcs == NULL) {
        return ERR_MEM;
    }

    /* Initialize the structure. */
    hcs->file            = NULL;
    hcs->resource_id    = 0;
    hcs->method_id        = 0;
    hcs->retries        = 0;

    /* Tell TCP that this is the structure we wish to be passed for our callbacks. */
    tcp_arg(pcb, hcs);

    /* Tell TCP that we wish to be informed of incoming data by a call to the http_recv() function. */
    tcp_recv(pcb, http_recv);

    tcp_err(pcb, conn_err);

    tcp_poll(pcb, http_poll, 4);

    return ERR_OK;
}

===============================================

static err_t
http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct http_connect_state* hcs;

    hcs = arg;

    if (ERR_OK == err)
    {
          if (NULL != p)
        {
            /* Inform TCP that we have taken the data. */
            tcp_recved(pcb, p->tot_len);
   
            if (hcs->file == NULL)
            {
                ProcessHttpRequest(hcs, p, &(pcb->remote_ip));
               
                if (hcs->file != NULL)
                {
                    pbuf_free(p);
                    send_data(pcb, hcs);
       
                    /* Tell TCP that we wish be to informed of data that has been
                     successfully sent by a call to the http_sent() function. */
                    tcp_sent(pcb, http_sent);
                }
                else
                {
                    pbuf_free(p);
                    p = NULL;
                }             
            }
            else
            {
                pbuf_free(p);
                p = NULL;
            }
        }
   
        if (NULL == p)
        {
            close_conn(pcb, hcs);
        }
    }

    return err;
}

===============================================

static err_t
http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
  struct http_connect_state* hcs;

  if(arg != NULL)
  {
      hcs = arg;
      hcs->retries = 0;
      send_data(pcb, hcs);
  }

  return ERR_OK;
}

===============================================

static void
close_conn(struct tcp_pcb *pcb, struct http_connect_state* hcs)
{
    tcp_arg(pcb, NULL);
    tcp_sent(pcb, NULL);
    tcp_recv(pcb, NULL);

    if(hcs->file) {
        wfs_close(hcs->file);
        hcs->file = NULL;
    }

    mem_free(hcs);
    tcp_close(pcb);
}

===============================================

As you can see at the HTTP init, the http_accept is set as callback for ACCEPT and in http_recv, http_sent is set as callback which will be called by TCP_EVENT_SENT.

When I use a single web browser there is no problem: the arg value passed to http_sent is never NULL. But when I launch another web browser, this parameter becomes sometimes NULL. It seems to be when the stack receives the new SYN frame from the client.

You said "That could be a hint that you are writing beyond allocated memory
somwhere and overwrite the memory where the PCB lies with zeros". But I always check the returned value when I make a memory allocation. If the functions used for memory allocation return an invalid space => there is a bug in the stack!

Baptiste

Quoting "address@hidden" <address@hidden>:


> Baptiste Chaboud-crousaz wrote:
>>
>> Sometimes, the face trouble with my callback http_connect - called 
>> by the macro TCP_EVENT_SENT - because "arg" is null.
>>
>
> I don't understand that one:
> a) there is no function 'http_connect' in the code you posted
> b) TCP_EVENT_SENT calls the function set by calling tcp_sent(pcb, fn) -
> the code you posted doesn't call tcp_sent().
> c) I would have thought a connect function would be used with a client,
> not a server - whereas an accept function (as you posted) is used with
> a server, not a client)
>
>> My understanding is that the http_accept function binds a pcb to an 
>> argument by a call to tcp_arg(...). I don't undersatnd why 
>> sometimes my callback is called with a NULL arg!!!
>>
>> This issue seems to be avoided/limited by increasing the size of 
>> MEM_SIZE and PBUF_POOL_SIZE.
>>
>
> That could be a hint that you are writing beyond allocated memory
> somwhere and overwrite the memory where the PCB lies with zeros...
>
>> If anybody has an idea, let me knwo about it...
>>
>
> Except for the above, I'm afraid I don't have an idea. Unless you call
> *tcp_arg(pcb, NULL) somewhere else, of course...*
>
> Does the argument get NULL during the connection or right at the start?
>
>
> Simon
>
>
> _______________________________________________
> lwip-users mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/lwip-users


reply via email to

[Prev in Thread] Current Thread [Next in Thread]