Mreged back changes that were lost during the savannah hack 3 weeks ago (using the sources from http://git.infradead.org/users/dwmw2/lwip.git)

This commit is contained in:
goldsimon 2010-12-20 18:03:51 +00:00
parent 1bd06bee82
commit effcb90fdf
8 changed files with 71 additions and 35 deletions

View File

@ -13,7 +13,7 @@ HISTORY
++ New features:
2010-06-16: Simon Goldschmidt
2010-11-21: Simon Goldschmidt
* dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif
(fixes bug #31525).
@ -233,18 +233,30 @@ HISTORY
++ Bugfixes:
2010-11-20: Simon Goldschmidt
2010-12-02: Simon Goldschmidt
* err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal.
2010-11-20: Simon Goldschmidt
2010-11-23: Simon Goldschmidt
* api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for
LWIP_SO_RCVBUF and ioctl/FIONREAD.
2010-11-23: Simon Goldschmidt
* etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at
least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet.
2010-11-23: Simon Goldschmidt
* tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after
refusing 'refused_data' again.
2010-11-22: Simon Goldschmidt
* sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS
after a successful nonblocking connection.
2010-11-20: Simon Goldschmidt
2010-11-22: Simon Goldschmidt
* etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr
must be sent link-local
2010-11-20: Simon Goldschmidt
2010-11-22: Simon Goldschmidt
* timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for
LWIP_TIMERS==0

View File

@ -408,7 +408,9 @@ netconn_recv_data(struct netconn *conn, void **new_buf)
}
#endif /* (LWIP_UDP || LWIP_RAW) */
#if LWIP_SO_RCVBUF
SYS_ARCH_DEC(conn->recv_avail, len);
#endif /* LWIP_SO_RCVBUF */
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);

View File

@ -120,7 +120,9 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
netbuf_delete(buf);
return 0;
} else {
#if LWIP_SO_RCVBUF
SYS_ARCH_INC(conn->recv_avail, len);
#endif /* LWIP_SO_RCVBUF */
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
}
@ -194,7 +196,9 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
netbuf_delete(buf);
return;
} else {
#if LWIP_SO_RCVBUF
SYS_ARCH_INC(conn->recv_avail, len);
#endif /* LWIP_SO_RCVBUF */
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
}
@ -248,7 +252,9 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
/* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
return ERR_MEM;
} else {
#if LWIP_SO_RCVBUF
SYS_ARCH_INC(conn->recv_avail, len);
#endif /* LWIP_SO_RCVBUF */
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
}
@ -614,7 +620,6 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
conn->socket = -1;
#endif /* LWIP_SOCKET */
conn->callback = callback;
conn->recv_avail = 0;
#if LWIP_TCP
conn->current_msg = NULL;
conn->write_offset = 0;
@ -624,6 +629,7 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVBUF
conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
conn->recv_avail = 0;
#endif /* LWIP_SO_RCVBUF */
conn->flags = 0;
return conn;

View File

@ -2252,15 +2252,18 @@ int
lwip_ioctl(int s, long cmd, void *argp)
{
struct lwip_sock *sock = get_socket(s);
u8_t val;
#if LWIP_SO_RCVBUF
u16_t buflen = 0;
s16_t recv_avail;
u8_t val;
#endif /* LWIP_SO_RCVBUF */
if (!sock) {
return -1;
}
switch (cmd) {
#if LWIP_SO_RCVBUF
case FIONREAD:
if (!argp) {
sock_set_errno(sock, EINVAL);
@ -2288,6 +2291,7 @@ lwip_ioctl(int s, long cmd, void *argp)
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp)));
sock_set_errno(sock, 0);
return 0;
#endif /* LWIP_SO_RCVBUF */
case FIONBIO:
val = 0;

View File

@ -305,9 +305,10 @@ tcp_input(struct pbuf *p, struct netif *inp)
TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
if (err == ERR_OK) {
pcb->refused_data = NULL;
} else {
} else if ((err == ERR_ABRT) || (tcplen > 0)) {
/* if err == ERR_ABRT, 'pcb' is already deallocated */
/* drop incoming packets, because pcb is "full" */
/* Drop incoming packets because pcb is "full" (only if the incoming
segment contains data). */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
TCP_STATS_INC(tcp.drop);
snmp_inc_tcpinerrs();
@ -346,6 +347,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
}
if (recv_data != NULL) {
LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
if (pcb->flags & TF_RXCLOSED) {
/* received data although already closed -> abort (send RST) to
notify the remote host that not all data has been processed */

View File

@ -168,12 +168,11 @@ struct netconn {
/** maximum amount of bytes queued in recvmbox
not used for TCP: adjust TCP_WND instead! */
int recv_bufsize;
#endif /* LWIP_SO_RCVBUF */
/** number of bytes currently in recvmbox to be received,
tested against recv_bufsize to limit bytes on recvmbox
for UDP and RAW
@todo: should only be necessary with LWIP_SO_RCVBUF==1 */
for UDP and RAW, used for FIONREAD */
s16_t recv_avail;
#endif /* LWIP_SO_RCVBUF */
/** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
u8_t flags;
#if LWIP_TCP

View File

@ -432,11 +432,14 @@
#endif
/**
* ARP_QUEUEING==1: Outgoing packets are queued during hardware address
* resolution.
* ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address
* resolution. By default, only the most recent packet is queued per IP address.
* This is sufficient for most protocols and mainly reduces TCP connection
* startup time. Set this to 1 if you know your application sends more than one
* packet in a row to an IP address that is not in the ARP cache.
*/
#ifndef ARP_QUEUEING
#define ARP_QUEUEING 1
#define ARP_QUEUEING 0
#endif
/**

View File

@ -93,6 +93,9 @@ struct etharp_entry {
#if ARP_QUEUEING
/** Pointer to queue of pending outgoing packets on this ARP entry. */
struct etharp_q_entry *q;
#else /* ARP_QUEUEING */
/** Pointer to a single pending outgoing packet on this ARP entry. */
struct pbuf *q;
#endif /* ARP_QUEUEING */
ip_addr_t ipaddr;
struct eth_addr ethaddr;
@ -154,6 +157,11 @@ free_etharp_q(struct etharp_q_entry *q)
memp_free(MEMP_ARP_QUEUE, r);
}
}
#else /* ARP_QUEUEING */
/** Compatibility define: free the queued pbuf */
#define free_etharp_q(q) pbuf_free(q)
#endif /* ARP_QUEUEING */
/** Clean up ARP table entries */
@ -162,7 +170,6 @@ free_entry(int i)
{
/* remove from SNMP ARP index tree */
snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr);
#if ARP_QUEUEING
/* and empty packet queue */
if (arp_table[i].q != NULL) {
/* remove all queued packets */
@ -170,7 +177,6 @@ free_entry(int i)
free_etharp_q(arp_table[i].q);
arp_table[i].q = NULL;
}
#endif /* ARP_QUEUEING */
/* recycle entry for re-use */
arp_table[i].state = ETHARP_STATE_EMPTY;
#if ETHARP_SUPPORT_STATIC_ENTRIES
@ -254,12 +260,10 @@ find_entry(ip_addr_t *ipaddr, u8_t flags)
s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
s8_t empty = ARP_TABLE_SIZE;
u8_t i = 0, age_pending = 0, age_stable = 0;
#if ARP_QUEUEING
/* oldest entry with packets on queue */
s8_t old_queue = ARP_TABLE_SIZE;
/* its age */
u8_t age_queue = 0;
#endif /* ARP_QUEUEING */
/**
* a) do a search through the cache, remember candidates
@ -295,14 +299,12 @@ find_entry(ip_addr_t *ipaddr, u8_t flags)
/* pending entry? */
if (state == ETHARP_STATE_PENDING) {
/* pending with queued packets? */
#if ARP_QUEUEING
if (arp_table[i].q != NULL) {
if (arp_table[i].ctime >= age_queue) {
old_queue = i;
age_queue = arp_table[i].ctime;
}
} else
#endif /* ARP_QUEUEING */
/* pending without queued packets? */
{
if (arp_table[i].ctime >= age_pending) {
@ -355,22 +357,18 @@ find_entry(ip_addr_t *ipaddr, u8_t flags)
/* recycle oldest stable*/
i = old_stable;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
#if ARP_QUEUEING
/* no queued packets should exist on stable entries */
LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
#endif /* ARP_QUEUEING */
/* 3) found recyclable pending entry without queued packets? */
} else if (old_pending < ARP_TABLE_SIZE) {
/* recycle oldest pending */
i = old_pending;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
#if ARP_QUEUEING
/* 4) found recyclable pending entry with queued packets? */
} else if (old_queue < ARP_TABLE_SIZE) {
/* recycle oldest pending (queued packets are free in free_entry) */
i = old_queue;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q)));
#endif /* ARP_QUEUEING */
/* no empty or recyclable entries found */
} else {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty or recyclable entries found\n"));
@ -486,8 +484,8 @@ update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethadd
ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
/* reset time stamp */
arp_table[i].ctime = 0;
#if ARP_QUEUEING
/* this is where we will send out queued packets! */
#if ARP_QUEUEING
while (arp_table[i].q != NULL) {
struct pbuf *p;
/* remember remainder of queue */
@ -498,12 +496,16 @@ update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethadd
p = q->p;
/* now queue entry can be freed */
memp_free(MEMP_ARP_QUEUE, q);
#else /* ARP_QUEUEING */
if (arp_table[i].q != NULL) {
struct pbuf *p = arp_table[i].q;
arp_table[i].q = NULL;
#endif /* ARP_QUEUEING */
/* send the queued IP packet */
etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
/* free the queued IP packet */
pbuf_free(p);
}
#endif /* ARP_QUEUEING */
return ERR_OK;
}
@ -1015,7 +1017,7 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
/* pending entry? (either just created or already pending */
} else if (arp_table[i].state == ETHARP_STATE_PENDING) {
#if ARP_QUEUEING /* queue the given q packet */
/* entry is still pending, queue the given packet 'q' */
struct pbuf *p;
int copy_needed = 0;
/* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but
@ -1047,6 +1049,7 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
/* packet could be taken over? */
if (p != NULL) {
/* queue packet ... */
#if ARP_QUEUEING
struct etharp_q_entry *new_entry;
/* allocate a new arp queue entry */
new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE);
@ -1071,18 +1074,23 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
/* the pool MEMP_ARP_QUEUE is empty */
pbuf_free(p);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
/* { result == ERR_MEM } through initialization */
result = ERR_MEM;
}
#else /* ARP_QUEUEING */
/* always queue one packet per ARP request only, freeing a previously queued packet */
if (arp_table[i].q != NULL) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
pbuf_free(arp_table[i].q);
}
arp_table[i].q = p;
result = ERR_OK;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
#endif /* ARP_QUEUEING */
} else {
ETHARP_STATS_INC(etharp.memerr);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
/* { result == ERR_MEM } through initialization */
result = ERR_MEM;
}
#else /* ARP_QUEUEING */
/* q && state == PENDING && ARP_QUEUEING == 0 => result = ERR_MEM */
/* { result == ERR_MEM } through initialization */
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: Ethernet destination address unknown, queueing disabled, packet %p dropped\n", (void *)q));
#endif /* ARP_QUEUEING */
}
return result;
}