/** * Delete a netconn and all its resources. * The pcb is NOT freed (since we might not be in the right thread context do this). * * @param conn the netconn to free */ void netconn_free(struct netconn *conn) { void *mem; LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); /* Drain the recvmbox. */ if (conn->recvmbox != SYS_MBOX_NULL) { while (sys_mbox_tryfetch(conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { if (conn->type == NETCONN_TCP) { if(mem != NULL) { pbuf_free((struct pbuf *)mem); } } else { netbuf_delete((struct netbuf *)mem); } } sys_mbox_free(conn->recvmbox); conn->recvmbox = SYS_MBOX_NULL; } /* Drain the acceptmbox. */ if (conn->acceptmbox != SYS_MBOX_NULL) { while (sys_mbox_tryfetch(conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { netconn_delete((struct netconn *)mem); } sys_mbox_free(conn->acceptmbox); conn->acceptmbox = SYS_MBOX_NULL; } sys_sem_free(conn->op_completed); conn->op_completed = SYS_SEM_NULL; memp_free(MEMP_NETCONN, conn); }
/** * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in * these mboxes * * @param conn the netconn to free * @bytes_drained bytes drained from recvmbox * @accepts_drained pending connections drained from acceptmbox */ static void netconn_drain(struct netconn *conn) { void *mem; #if LWIP_TCP struct pbuf *p; #endif /* LWIP_TCP */ /* This runs in tcpip_thread, so we don't need to lock against rx packets */ /* Delete and drain the recvmbox. */ if (sys_mbox_valid(&conn->recvmbox)) { while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { #if LWIP_TCP if (conn->type == NETCONN_TCP) { if(mem != NULL) { p = (struct pbuf*)mem; /* pcb might be set to NULL already by err_tcp() */ if (conn->pcb.tcp != NULL) { tcp_recved(conn->pcb.tcp, p->tot_len); } pbuf_free(p); } } else #endif /* LWIP_TCP */ { netbuf_delete((struct netbuf *)mem); } } sys_mbox_free(&conn->recvmbox); sys_mbox_set_invalid(&conn->recvmbox); } /* Delete and drain the acceptmbox. */ #if LWIP_TCP if (sys_mbox_valid(&conn->acceptmbox)) { while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { struct netconn *newconn = (struct netconn *)mem; /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ /* pcb might be set to NULL already by err_tcp() */ if (conn->pcb.tcp != NULL) { tcp_accepted(conn->pcb.tcp); } /* drain recvmbox */ netconn_drain(newconn); if (newconn->pcb.tcp != NULL) { tcp_abort(newconn->pcb.tcp); newconn->pcb.tcp = NULL; } netconn_free(newconn); } sys_mbox_free(&conn->acceptmbox); sys_mbox_set_invalid(&conn->acceptmbox); } #endif /* LWIP_TCP */ }
static void pxudp_pcb_forward_inbound(struct pxudp *pxudp) { struct pbuf *p; u32_t timo; err_t error; if (!sys_mbox_valid(&pxudp->inmbox)) { return; } timo = sys_mbox_tryfetch(&pxudp->inmbox, (void **)&p); if (timo == SYS_MBOX_EMPTY) { return; } error = udp_send(pxudp->pcb, p); if (error != ERR_OK) { DPRINTF(("%s: udp_send(pcb %p) err %d\n", __func__, (void *)pxudp, error)); } pbuf_free(p); /* * If we enabled counting in pxudp_pcb_forward_outbound() check * that we have (all) the reply(s). */ if (pxudp->count > 0) { --pxudp->count; if (pxudp->count == 0) { pxudp_pcb_expired(pxudp); } } }
static void fwtcp_pcb_delete(void *arg) { struct fwtcp *fwtcp = (struct fwtcp *)arg; void *data; u32_t timo; timo = sys_mbox_tryfetch(&fwtcp->connmbox, &data); LWIP_ASSERT1(timo == SYS_MBOX_EMPTY); LWIP_UNUSED_ARG(timo); /* only in assert */ sys_mbox_free(&fwtcp->connmbox); free(fwtcp); }
static void pxudp_drain_inmbox(struct pxudp *pxudp) { void *ptr; if (!sys_mbox_valid(&pxudp->inmbox)) { return; } while (sys_mbox_tryfetch(&pxudp->inmbox, &ptr) != SYS_MBOX_EMPTY) { struct pbuf *p = (struct pbuf *)ptr; pbuf_free(p); } sys_mbox_free(&pxudp->inmbox); sys_mbox_set_invalid(&pxudp->inmbox); }
void fwtcp_pcb_connect(void *arg) { struct fwtcp *fwtcp = (struct fwtcp *)arg; struct pxtcp *pxtcp; u32_t timo; if (!sys_mbox_valid(&fwtcp->connmbox)) { return; } pxtcp = NULL; timo = sys_mbox_tryfetch(&fwtcp->connmbox, (void **)&pxtcp); if (timo == SYS_MBOX_EMPTY) { return; } LWIP_ASSERT1(pxtcp != NULL); /* hand off to pxtcp */ pxtcp_pcb_connect(pxtcp, &fwtcp->fwspec); }