|
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>:
[Prev in Thread] | Current Thread | [Next in Thread] |