rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the tcp_recv callback (see rawapi.txt).

This commit is contained in:
fbernon
2008-01-14 21:07:08 +00:00
parent 52e6922e5a
commit 7518acf634
6 changed files with 65 additions and 11 deletions

View File

@@ -770,7 +770,8 @@ tcp_slowtmr(void)
}
/**
* Is called every TCP_FAST_INTERVAL (250 ms) and sends delayed ACKs.
* Is called every TCP_FAST_INTERVAL (250 ms) and process data previously
* "refused" by upper layer (application) and sends delayed ACKs.
*
* Automatically called from tcp_tmr().
*/
@@ -779,8 +780,19 @@ tcp_fasttmr(void)
{
struct tcp_pcb *pcb;
/* send delayed ACKs */
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
/* If there is data which was previously "refused" by upper layer */
if (pcb->refused_data != NULL) {
/* Notify again application with data previously received. */
err_t err;
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n"));
TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
if (err == ERR_OK) {
pcb->refused_data = NULL;
}
}
/* send delayed ACKs */
if (pcb->flags & TF_ACK_DELAY) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
tcp_ack_now(pcb);
@@ -1135,15 +1147,20 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
pcb->state != LISTEN) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
if (pcb->unsent != NULL) {
if (pcb->refused_data != NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
pbuf_free(pcb->refused_data);
pcb->refused_data = NULL;
}
if (pcb->unsent != NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
}
if (pcb->unacked != NULL) {
if (pcb->unacked != NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
}
#if TCP_QUEUE_OOSEQ /* LW */
if (pcb->ooseq != NULL) {
if (pcb->ooseq != NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
}

View File

@@ -272,6 +272,23 @@ tcp_input(struct pbuf *p, struct netif *inp)
recv_data = NULL;
recv_flags = 0;
/* If there is data which was previously "refused" by upper layer */
if (pcb->refused_data != NULL) {
/* Notify again application with data previously received. */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
if (err == ERR_OK) {
pcb->refused_data = NULL;
} else {
/* drop incoming packets, because pcb is "full" */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
TCP_STATS_INC(tcp.drop);
snmp_inc_tcpinerrs();
pbuf_free(p);
return;
}
}
tcp_input_pcb = pcb;
err = tcp_process(pcb);
tcp_input_pcb = NULL;
@@ -304,15 +321,23 @@ tcp_input(struct pbuf *p, struct netif *inp)
if(flags & TCP_PSH) {
recv_data->flags |= PBUF_FLAG_PUSH;
}
/* Notify application that data has been received. */
TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
/* If the upper layer can't receive this data, store it */
if (err != ERR_OK) {
pcb->refused_data = recv_data;
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
}
}
/* If a FIN segment was received, we call the callback
function with a NULL buffer to indicate EOF. */
if (recv_flags & TF_GOT_FIN) {
TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
}
/* If there were no errors, we try to send something out. */
if (err == ERR_OK) {
tcp_output(pcb);