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.

  ++ 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
