This file lists major changes between release versions that require
ports or applications to be changed. Use it to update a port or an
application written for an older version of lwIP to correctly work
with newer versions.


(CVS HEAD)

  * [Enter new changes just after this line - do not remove this line]

  ++ Application changes:

  * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for
    compatibility to old applications, but will be removed in the future).

  * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc()

  +++ Raw API:
    * Changed the semantics of tcp_close() (since it was rather a
      shutdown before): Now the application does *NOT* get any calls to the recv
      callback (aside from NULL/closed) after calling tcp_close()

    * When calling tcp_abort() from a raw API TCP callback function,
      make sure you return ERR_ABRT to prevent accessing unallocated memory.
      (ERR_ABRT now means the applicaiton has called tcp_abort!)

  +++ Netconn API:
    * Changed netconn_receive() and netconn_accept() to return
      err_t, not a pointer to new data/netconn.

  +++ Socket API:
    * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they
      now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT.

    * Added a minimal version of posix fctl() to have a
      standardised way to set O_NONBLOCK for nonblocking sockets.

  +++ all APIs:
    * correctly implemented SO(F)_REUSEADDR

  ++ Port changes

  +++ new files:

    * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h:

    * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains
      the actual application programmer's API
  
    * Separated timer implementation from sys.h/.c, moved to timers.h/.c;
      Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you
      still want to use your own timer implementation for NO_SYS==0 (as before).

  +++ sys layer:

    * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/
      sys_sem_t;

    * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t;

    * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use
      binary semaphores instead of mutexes - as before)

  +++ new options:

     * Don't waste memory when chaining segments, added option TCP_OVERSIZE to
       prevent creating many small pbufs when calling tcp_write with many small
       blocks of data. Instead, pbufs are allocated larger than needed and the
       space is used for later calls to tcp_write.

     * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs
       in tcp_write/udp_send.

    * Added an additional option LWIP_ETHERNET to support ethernet without ARP
      (necessary for pure PPPoE)

    * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may
      be used to place these pools into user-defined memory by using external
      declaration.

    * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT

  +++ new pools:

     * Netdb uses a memp pool for allocating memory when getaddrinfo() is called,
       so MEMP_NUM_NETDB has to be set accordingly.

     * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so
       MEMP_NUM_LOCALHOSTLIST has to be set accordingly.

     * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have
       to be set accordingly.

     * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES
       has to be set accordingly

  * Integrated loopif into netif.c - loopif does not have to be created by the
    port any more, just define LWIP_HAVE_LOOPIF to 1.

  * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined
    in cc.h, e.g. used by igmp)

  * Added printf-formatter X8_F to printf u8_t as hex

  * The heap now may be moved to user-defined memory by defining
    LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address

  * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work
    with user-allocated structs instead of calling mem_malloc

  * Added const char* name to mem- and memp-stats for easier debugging.

  * Calculate the TCP/UDP checksum while copying to only fetch data once:
    Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum

  * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
    more than one pcb.

  * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
    off any more, if this is set to 0, only one packet (the most recent one) is
    queued (like demanded by RFC 1122).

  
  ++ Major bugfixes/improvements

  * Implemented tcp_shutdown() to only shut down one end of a connection
  * Implemented shutdown() at socket- and netconn-level
  * Added errorset support to select() + improved select speed overhead
  * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x)
  * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1
  * Use macros defined in ip_addr.h to work with IP addresses
  * Implemented many nonblocking socket/netconn functions
  * Fixed ARP input processing: only add a new entry if a request was directed as us
  * mem_realloc() to mem_trim() to prevent confusion with realloc()
  * Some improvements for AutoIP (don't route/forward link-local addresses, don't break
    existing connections when assigning a routable address)
  * Correctly handle remote side overrunning our rcv_wnd in ooseq case
  * Removed packing from ip_addr_t, the packed version is now only used in protocol headers
  * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0
  * Added support for static ARP table entries

(STABLE-1.3.2)

  * initial version of this file
