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: Thu, 6 Aug 2009 15:00:45 +0200
User-agent: Internet Messaging Program (IMP) H3 (4.1.6)

Hi,

please find here my function http_poll:

static err_t
http_poll(void *arg, struct tcp_pcb *pcb)
{
    struct http_connect_state* hcs;
    hcs = arg;

    if (hcs == NULL) {
        tcp_abort(pcb);
        return ERR_ABRT;
    } else {
        ++hcs->retries;
        if (hcs->retries >= 4) {
            tcp_abort(pcb);
            return ERR_ABRT;
        }
        send_data(pcb, hcs);
    }

    return ERR_OK;
}

Can you explain me what is the purpose of this function?

Baptiste

Quoting Bill Auerbach <address@hidden>:

> What does your http_poll do?
>
>
>
> From: address@hidden
> [mailto:address@hidden On Behalf
> Of Baptiste Chaboud-crousaz
> Sent: Thursday, August 06, 2009 5:51 AM
> To: address@hidden
> Subject: Re: [lwip-users] Problem with NULL pcb->callback_arg
>
>
>
> Hi all,
>
> Since my problem is not resolved, I ask you again to help me.
> I use the HTTP (RAW version) server provided by the lwip site in the
> /contrib/apps/httpserver_raw folder.
>
> Sometimes, the argument passed to http_sent is NULL which leads an hardfault
> exception. In the majority of cases, there is no problem. This problem is
> avoided or limited when I increases the size of MEM_SIZE. But I have to
> drastically reduce this size to meet my hardware requirements.
>
> My understanding is that a memory allocation is done out the memory space
> dedicted to lwip.
> But I don' understand how it can be possible. All the results of memory
> allocation are checked. Would it be possible that there is a bug in lwip? If
> yes where?
>
> What should I do?????
>
> Best regards.
> Baptiste
>
> Quoting Baptiste Chaboud-crousaz <address@hidden>:
>
>>
>>
>>   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]