mirror of https://github.com/ARMmbed/mbed-os.git
Squashed 'features/FEATURE_LWIP/lwip-interface/lwip/' changes from 10f93f4..7648b58
git-subtree-dir: features/FEATURE_LWIP/lwip-interface/lwip git-subtree-split: 7648b58d03006bd60b9592f1853c167bf52b0193pull/4814/head
parent
61a7b15741
commit
7bbc850309
75
CHANGELOG
75
CHANGELOG
|
@ -4,6 +4,81 @@ HISTORY
|
|||
|
||||
* [Enter new changes just after this line - do not remove this line]
|
||||
|
||||
(STABLE-2.0.2)
|
||||
|
||||
++ New features:
|
||||
|
||||
2017-02-10: Dirk Ziegelmeier
|
||||
* Implement task #14367: Hooks need a better place to be defined:
|
||||
We now have a #define for a header file name that is #included in every .c
|
||||
file that provides hooks.
|
||||
|
||||
++ Bugfixes:
|
||||
|
||||
2017-03-08
|
||||
* tcp: do not keep sending SYNs when getting ACKs
|
||||
|
||||
2017-03-08: Joel Cunningham
|
||||
* tcp: Initialize ssthresh to TCP_SND_BUF (bug #50476)
|
||||
|
||||
2017-03-01: Simon Goldschmidt
|
||||
* httpd: LWIP_HTTPD_POST_MANUAL_WND: fixed double-free when httpd_post_data_recved
|
||||
is called nested from httpd_post_receive_data() (bug #50424)
|
||||
|
||||
2017-02-28: David van Moolenbroek/Simon Goldschmidt
|
||||
* tcp: fixed bug #50418: LWIP_EVENT_API: fix invalid calbacks for SYN_RCVD pcb
|
||||
|
||||
2017-02-17: Simon Goldschmidt
|
||||
* dns: Improved DNS_LOCAL_HOSTLIST interface (bug #50325)
|
||||
|
||||
2017-02-16: Simon Goldschmidt
|
||||
* LWIP_NETCONN_FULLDUPLEX: fixed shutdown during write (bug #50274)
|
||||
|
||||
2017-02-13: Simon Goldschmidt/Dirk Ziegelmeier
|
||||
* For tiny targtes, LWIP_RAND is optional (fix compile time checks)
|
||||
|
||||
2017-02-10: Simon Goldschmidt
|
||||
* tcp: Fixed bug #47485 (tcp_close() should not fail on memory error) by retrying
|
||||
to send FIN from tcp_fasttmr
|
||||
|
||||
2017-02-09: Simon Goldschmidt
|
||||
* sockets: Fixed bug #44032 (LWIP_NETCONN_FULLDUPLEX: select might work on
|
||||
invalid/reused socket) by not allowing to reallocate a socket that has
|
||||
"select_waiting != 0"
|
||||
|
||||
2017-02-09: Simon Goldschmidt
|
||||
* httpd: Fixed bug #50059 (httpd LWIP_HTTPD_SUPPORT_11_KEEPALIVE vs.
|
||||
LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED)
|
||||
|
||||
2017-02-08: Dirk Ziegelmeier
|
||||
* Rename "IPv6 mapped IPv4 addresses" to their correct name from RFC4191:
|
||||
"IPv4-mapped IPv6 address"
|
||||
|
||||
2017-02-08: Luc Revardel
|
||||
* mld6.c: Fix bug #50220 (mld6_leavegroup does not send ICMP6_TYPE_MLD, even
|
||||
if last reporter)
|
||||
|
||||
2017-02-08: David van Moolenbroek
|
||||
* ip6.c: Patch #9250: fix source substitution in ip6_output_if()
|
||||
|
||||
2017-02-08: Simon Goldschmidt
|
||||
* tcp_out.c: Fixed bug #50090 (last_unsent->oversize_left can become wrong value
|
||||
in tcp_write error path)
|
||||
|
||||
2017-02-02: Dirk Ziegelmeier
|
||||
* Fix bug #50206: UDP Netconn bind to IP6_ADDR_ANY fails
|
||||
|
||||
2017-01-18: Dirk Ziegelmeier
|
||||
* Fix zero-copy RX, see bug bug #50064. PBUF_REFs were not supported as ARP requests.
|
||||
|
||||
2017-01-15: Axel Lin, Dirk Ziegelmeier
|
||||
* minor bug fixes in mqtt
|
||||
|
||||
2017-01-11: Knut Andre Tidemann
|
||||
* sockets/netconn: fix broken default ICMPv6 handling of checksums
|
||||
|
||||
(STABLE-2.0.1)
|
||||
|
||||
++ New features:
|
||||
|
||||
2016-12-31: Simon Goldschmidt
|
||||
|
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = "lwIP"
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "2.0.1"
|
||||
PROJECT_NUMBER = "2.0.2"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
* @verbinclude "UPGRADING"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page changelog Changelog
|
||||
* @verbinclude "CHANGELOG"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page contrib How to contribute to lwIP
|
||||
* @verbinclude "contrib.txt"
|
||||
|
|
|
@ -562,6 +562,13 @@ pcb_new(struct api_msg *msg)
|
|||
case NETCONN_RAW:
|
||||
msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto);
|
||||
if (msg->conn->pcb.raw != NULL) {
|
||||
#if LWIP_IPV6
|
||||
/* ICMPv6 packets should always have checksum calculated by the stack as per RFC 3542 chapter 3.1 */
|
||||
if (NETCONNTYPE_ISIPV6(msg->conn->type) && msg->conn->pcb.raw->protocol == IP6_NEXTH_ICMP6) {
|
||||
msg->conn->pcb.raw->chksum_reqd = 1;
|
||||
msg->conn->pcb.raw->chksum_offset = 2;
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
|
||||
}
|
||||
break;
|
||||
|
@ -1777,25 +1784,28 @@ lwip_netconn_do_close(void *m)
|
|||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
if (msg->msg.sd.shut & NETCONN_SHUT_WR) {
|
||||
/* close requested, abort running write */
|
||||
sys_sem_t* op_completed_sem;
|
||||
sys_sem_t* write_completed_sem;
|
||||
LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
|
||||
op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg);
|
||||
write_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg);
|
||||
msg->conn->current_msg->err = ERR_CLSD;
|
||||
msg->conn->current_msg = NULL;
|
||||
msg->conn->write_offset = 0;
|
||||
msg->conn->state = NETCONN_NONE;
|
||||
state = NETCONN_NONE;
|
||||
NETCONN_SET_SAFE_ERR(msg->conn, ERR_CLSD);
|
||||
sys_sem_signal(op_completed_sem);
|
||||
sys_sem_signal(write_completed_sem);
|
||||
} else {
|
||||
LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD);
|
||||
/* In this case, let the write continue and do not interfere with
|
||||
conn->current_msg or conn->state! */
|
||||
msg->err = tcp_shutdown(msg->conn->pcb.tcp, 1, 0);
|
||||
}
|
||||
}
|
||||
if (state == NETCONN_NONE) {
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
msg->err = ERR_INPROGRESS;
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
} else {
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
if (msg->msg.sd.shut & NETCONN_SHUT_RD) {
|
||||
/* Drain and delete mboxes */
|
||||
netconn_drain(msg->conn);
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include "lwip/def.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#include "lwip/errno.h"
|
||||
#include "lwip/lwip_errno.h"
|
||||
|
||||
#if !NO_SYS
|
||||
/** Table to quickly map an lwIP error (err_t) to a socket error
|
||||
|
|
|
@ -407,7 +407,7 @@ alloc_socket(struct netconn *newconn, int accepted)
|
|||
for (i = 0; i < NUM_SOCKETS; ++i) {
|
||||
/* Protect socket array */
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (!sockets[i].conn) {
|
||||
if (!sockets[i].conn && (sockets[i].select_waiting == 0)) {
|
||||
sockets[i].conn = newconn;
|
||||
/* The socket is not yet known to anyone, so no need to protect
|
||||
after having marked it as used. */
|
||||
|
@ -420,7 +420,6 @@ alloc_socket(struct netconn *newconn, int accepted)
|
|||
sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
|
||||
sockets[i].errevent = 0;
|
||||
sockets[i].err = 0;
|
||||
sockets[i].select_waiting = 0;
|
||||
return i + LWIP_SOCKET_OFFSET;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
@ -585,9 +584,9 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
|
|||
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port));
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
/* Dual-stack: Unmap IPv6 mapped IPv4 addresses */
|
||||
if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv6mappedipv4(ip_2_ip6(&local_addr))) {
|
||||
unmap_ipv6_mapped_ipv4(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr));
|
||||
/* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
|
||||
if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) {
|
||||
unmap_ipv4_mapped_ipv6(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr));
|
||||
IP_SET_TYPE_VAL(local_addr, IPADDR_TYPE_V4);
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
|
@ -677,9 +676,9 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
|
|||
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port));
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
/* Dual-stack: Unmap IPv6 mapped IPv4 addresses */
|
||||
if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv6mappedipv4(ip_2_ip6(&remote_addr))) {
|
||||
unmap_ipv6_mapped_ipv4(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr));
|
||||
/* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
|
||||
if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) {
|
||||
unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr));
|
||||
IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4);
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
|
@ -865,9 +864,9 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
|
|||
}
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
/* Dual-stack: Map IPv4 addresses to IPv6 mapped IPv4 */
|
||||
/* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */
|
||||
if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) && IP_IS_V4(fromaddr)) {
|
||||
ip4_2_ipv6_mapped_ipv4(ip_2_ip6(fromaddr), ip_2_ip4(fromaddr));
|
||||
ip4_2_ipv4_mapped_ipv6(ip_2_ip6(fromaddr), ip_2_ip4(fromaddr));
|
||||
IP_SET_TYPE(fromaddr, IPADDR_TYPE_V6);
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
|
@ -995,6 +994,10 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags)
|
|||
((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);
|
||||
|
||||
for (i = 0; i < msg->msg_iovlen; i++) {
|
||||
u8_t apiflags = write_flags;
|
||||
if (i + 1 < msg->msg_iovlen) {
|
||||
apiflags |= NETCONN_MORE;
|
||||
}
|
||||
written = 0;
|
||||
err = netconn_write_partly(sock->conn, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len, write_flags, &written);
|
||||
if (err == ERR_OK) {
|
||||
|
@ -1092,9 +1095,9 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags)
|
|||
|
||||
if (err == ERR_OK) {
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
/* Dual-stack: Unmap IPv6 mapped IPv4 addresses */
|
||||
if (IP_IS_V6_VAL(chain_buf->addr) && ip6_addr_isipv6mappedipv4(ip_2_ip6(&chain_buf->addr))) {
|
||||
unmap_ipv6_mapped_ipv4(ip_2_ip4(&chain_buf->addr), ip_2_ip6(&chain_buf->addr));
|
||||
/* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
|
||||
if (IP_IS_V6_VAL(chain_buf->addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&chain_buf->addr))) {
|
||||
unmap_ipv4_mapped_ipv6(ip_2_ip4(&chain_buf->addr), ip_2_ip6(&chain_buf->addr));
|
||||
IP_SET_TYPE_VAL(chain_buf->addr, IPADDR_TYPE_V4);
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
|
@ -1190,9 +1193,9 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
|||
#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
|
||||
if (err == ERR_OK) {
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
/* Dual-stack: Unmap IPv6 mapped IPv4 addresses */
|
||||
if (IP_IS_V6_VAL(buf.addr) && ip6_addr_isipv6mappedipv4(ip_2_ip6(&buf.addr))) {
|
||||
unmap_ipv6_mapped_ipv4(ip_2_ip4(&buf.addr), ip_2_ip6(&buf.addr));
|
||||
/* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
|
||||
if (IP_IS_V6_VAL(buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&buf.addr))) {
|
||||
unmap_ipv4_mapped_ipv6(ip_2_ip4(&buf.addr), ip_2_ip6(&buf.addr));
|
||||
IP_SET_TYPE_VAL(buf.addr, IPADDR_TYPE_V4);
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
|
@ -1490,9 +1493,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||
SYS_ARCH_PROTECT(lev);
|
||||
sock = tryget_socket(i);
|
||||
if (sock != NULL) {
|
||||
/* @todo: what if this is a new socket (reallocated?) in this case,
|
||||
select_waiting-- would be wrong (a global 'sockalloc' counter,
|
||||
stored per socket could help) */
|
||||
/* for now, handle select_waiting==0... */
|
||||
LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
|
||||
if (sock->select_waiting > 0) {
|
||||
sock->select_waiting--;
|
||||
|
@ -1684,8 +1685,7 @@ again:
|
|||
}
|
||||
|
||||
/**
|
||||
* Unimplemented: Close one end of a full-duplex connection.
|
||||
* Currently, the full connection is closed.
|
||||
* Close one end of a full-duplex connection.
|
||||
*/
|
||||
int
|
||||
lwip_shutdown(int s, int how)
|
||||
|
@ -1750,10 +1750,10 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
|
|||
}
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
/* Dual-stack: Map IPv4 addresses to IPv6 mapped IPv4 */
|
||||
/* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */
|
||||
if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) &&
|
||||
IP_IS_V4_VAL(naddr)) {
|
||||
ip4_2_ipv6_mapped_ipv4(ip_2_ip6(&naddr), ip_2_ip4(&naddr));
|
||||
ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&naddr), ip_2_ip4(&naddr));
|
||||
IP_SET_TYPE_VAL(naddr, IPADDR_TYPE_V6);
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
|
@ -2574,6 +2574,12 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_
|
|||
switch (optname) {
|
||||
#if LWIP_IPV6 && LWIP_RAW
|
||||
case IPV6_CHECKSUM:
|
||||
/* It should not be possible to disable the checksum generation with ICMPv6
|
||||
* as per RFC 3542 chapter 3.1 */
|
||||
if(sock->conn->pcb.raw->protocol == IPPROTO_ICMPV6) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW);
|
||||
if (*(const int *)optval < 0) {
|
||||
sock->conn->pcb.raw->chksum_reqd = 0;
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
#include <stdlib.h> /* atoi */
|
||||
#include <stdio.h>
|
||||
|
||||
#if LWIP_TCP
|
||||
#if LWIP_TCP && LWIP_CALLBACK_API
|
||||
|
||||
/** Minimum length for a valid HTTP/0.9 request: "GET /\r\n" -> 7 bytes */
|
||||
#define MIN_REQ_LEN 7
|
||||
|
@ -335,9 +335,34 @@ char *http_cgi_param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each ext
|
|||
/** global list of active HTTP connections, use to kill the oldest when
|
||||
running out of memory */
|
||||
static struct http_state *http_connections;
|
||||
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
|
||||
|
||||
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
|
||||
static void
|
||||
http_add_connection(struct http_state *hs)
|
||||
{
|
||||
/* add the connection to the list */
|
||||
hs->next = http_connections;
|
||||
http_connections = hs;
|
||||
}
|
||||
|
||||
static void
|
||||
http_remove_connection(struct http_state *hs)
|
||||
{
|
||||
/* take the connection off the list */
|
||||
if (http_connections) {
|
||||
if (http_connections == hs) {
|
||||
http_connections = hs->next;
|
||||
} else {
|
||||
struct http_state *last;
|
||||
for(last = http_connections; last->next != NULL; last = last->next) {
|
||||
if (last->next == hs) {
|
||||
last->next = hs->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
http_kill_oldest_connection(u8_t ssi_required)
|
||||
{
|
||||
|
@ -366,6 +391,11 @@ http_kill_oldest_connection(u8_t ssi_required)
|
|||
http_close_or_abort_conn(hs_free_next->next->pcb, hs_free_next->next, 1); /* this also unlinks the http_state from the list */
|
||||
}
|
||||
}
|
||||
#else /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
|
||||
|
||||
#define http_add_connection(hs)
|
||||
#define http_remove_connection(hs)
|
||||
|
||||
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
|
||||
|
||||
#if LWIP_HTTPD_SSI
|
||||
|
@ -422,17 +452,7 @@ http_state_alloc(void)
|
|||
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
|
||||
if (ret != NULL) {
|
||||
http_state_init(ret);
|
||||
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
|
||||
/* add the connection to the list */
|
||||
if (http_connections == NULL) {
|
||||
http_connections = ret;
|
||||
} else {
|
||||
struct http_state *last;
|
||||
for(last = http_connections; last->next != NULL; last = last->next);
|
||||
LWIP_ASSERT("last != NULL", last != NULL);
|
||||
last->next = ret;
|
||||
}
|
||||
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
|
||||
http_add_connection(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -481,22 +501,7 @@ http_state_free(struct http_state *hs)
|
|||
{
|
||||
if (hs != NULL) {
|
||||
http_state_eof(hs);
|
||||
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
|
||||
/* take the connection off the list */
|
||||
if (http_connections) {
|
||||
if (http_connections == hs) {
|
||||
http_connections = hs->next;
|
||||
} else {
|
||||
struct http_state *last;
|
||||
for(last = http_connections; last->next != NULL; last = last->next) {
|
||||
if (last->next == hs) {
|
||||
last->next = hs->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
|
||||
http_remove_connection(hs);
|
||||
HTTP_FREE_HTTP_STATE(hs);
|
||||
}
|
||||
}
|
||||
|
@ -638,17 +643,14 @@ http_eof(struct tcp_pcb *pcb, struct http_state *hs)
|
|||
/* HTTP/1.1 persistent connection? (Not supported for SSI) */
|
||||
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||
if (hs->keepalive) {
|
||||
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
|
||||
struct http_state* next = hs->next;
|
||||
#endif
|
||||
http_remove_connection(hs);
|
||||
|
||||
http_state_eof(hs);
|
||||
http_state_init(hs);
|
||||
/* restore state: */
|
||||
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
|
||||
hs->next = next;
|
||||
#endif
|
||||
hs->pcb = pcb;
|
||||
hs->keepalive = 1;
|
||||
http_add_connection(hs);
|
||||
/* ensure nagle doesn't interfere with sending all data as fast as possible: */
|
||||
tcp_nagle_disable(pcb);
|
||||
} else
|
||||
|
@ -1690,7 +1692,14 @@ http_post_rxpbuf(struct http_state *hs, struct pbuf *p)
|
|||
hs->post_content_len_left -= p->tot_len;
|
||||
}
|
||||
}
|
||||
#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND
|
||||
/* prevent connection being closed if httpd_post_data_recved() is called nested */
|
||||
hs->unrecved_bytes++;
|
||||
#endif
|
||||
err = httpd_post_receive_data(hs, p);
|
||||
#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND
|
||||
hs->unrecved_bytes--;
|
||||
#endif
|
||||
if (err != ERR_OK) {
|
||||
/* Ignore remaining content in case of application error */
|
||||
hs->post_content_len_left = 0;
|
||||
|
@ -1751,8 +1760,8 @@ http_post_request(struct pbuf *inp, struct http_state *hs,
|
|||
if (content_len >= 0) {
|
||||
/* adjust length of HTTP header passed to application */
|
||||
const char *hdr_start_after_uri = uri_end + 1;
|
||||
u16_t hdr_len = LWIP_MIN(data_len, crlfcrlf + 4 - data);
|
||||
u16_t hdr_data_len = LWIP_MIN(data_len, crlfcrlf + 4 - hdr_start_after_uri);
|
||||
u16_t hdr_len = (u16_t)LWIP_MIN(data_len, crlfcrlf + 4 - data);
|
||||
u16_t hdr_data_len = (u16_t)LWIP_MIN(data_len, crlfcrlf + 4 - hdr_start_after_uri);
|
||||
u8_t post_auto_wnd = 1;
|
||||
http_uri_buf[0] = 0;
|
||||
/* trim http header */
|
||||
|
@ -2617,4 +2626,4 @@ http_set_cgi_handlers(const tCGI *cgis, int num_handlers)
|
|||
}
|
||||
#endif /* LWIP_HTTPD_CGI */
|
||||
|
||||
#endif /* LWIP_TCP */
|
||||
#endif /* LWIP_TCP && LWIP_CALLBACK_API */
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#include <string.h>
|
||||
|
||||
/* Currently, only TCP-over-IPv4 is implemented (does iperf support IPv6 anyway?) */
|
||||
#if LWIP_IPV4 && LWIP_TCP
|
||||
#if LWIP_IPV4 && LWIP_TCP && LWIP_CALLBACK_API
|
||||
|
||||
/** Specify the idle timeout (in seconds) after that the test fails */
|
||||
#ifndef LWIPERF_TCP_MAX_IDLE_SEC
|
||||
|
@ -658,4 +658,4 @@ lwiperf_abort(void* lwiperf_session)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* LWIP_IPV4 && LWIP_TCP */
|
||||
#endif /* LWIP_IPV4 && LWIP_TCP && LWIP_CALLBACK_API */
|
||||
|
|
|
@ -47,14 +47,16 @@
|
|||
* Erik Andersson <erian747@gmail.com>
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "lwip/apps/mqtt.h"
|
||||
#include "lwip/timeouts.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "lwip/apps/mqtt.h"
|
||||
#include <string.h>
|
||||
|
||||
#if LWIP_TCP && LWIP_CALLBACK_API
|
||||
|
||||
/**
|
||||
* MQTT_DEBUG: Default is off.
|
||||
|
@ -257,7 +259,7 @@ mqtt_create_request(struct mqtt_request_t *r_objs, u16_t pkt_id, mqtt_request_cb
|
|||
struct mqtt_request_t *r = NULL;
|
||||
u8_t n;
|
||||
LWIP_ASSERT("mqtt_create_request: r_objs != NULL", r_objs != NULL);
|
||||
for (n = 0; n < MQTT_REQ_MAX_IN_FLIGHT && r == NULL; n++) {
|
||||
for (n = 0; n < MQTT_REQ_MAX_IN_FLIGHT; n++) {
|
||||
/* Item point to itself if not in use */
|
||||
if (r_objs[n].next == &r_objs[n]) {
|
||||
r = &r_objs[n];
|
||||
|
@ -265,6 +267,7 @@ mqtt_create_request(struct mqtt_request_t *r_objs, u16_t pkt_id, mqtt_request_cb
|
|||
r->cb = cb;
|
||||
r->arg = arg;
|
||||
r->pkt_id = pkt_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
@ -281,7 +284,7 @@ mqtt_append_request(struct mqtt_request_t **tail, struct mqtt_request_t *r)
|
|||
{
|
||||
struct mqtt_request_t *head = NULL;
|
||||
s16_t time_before = 0;
|
||||
struct mqtt_request_t *iter = *tail;
|
||||
struct mqtt_request_t *iter;
|
||||
|
||||
LWIP_ASSERT("mqtt_append_request: tail != NULL", tail != NULL);
|
||||
|
||||
|
@ -634,7 +637,7 @@ mqtt_incomming_suback(struct mqtt_request_t *r, u8_t result)
|
|||
* @param remaining_length Remaining length of complete message
|
||||
*/
|
||||
static mqtt_connection_status_t
|
||||
mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u32_t remaining_length)
|
||||
mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u32_t remaining_length)
|
||||
{
|
||||
mqtt_connection_status_t res = MQTT_CONNECT_ACCEPTED;
|
||||
|
||||
|
@ -680,7 +683,7 @@ mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u
|
|||
topic = var_hdr_payload + 2;
|
||||
after_topic = 2 + topic_len;
|
||||
/* Check length, add one byte even for QoS 0 so that zero termination will fit */
|
||||
if ((after_topic + qos ? 2 : 1) > length) {
|
||||
if ((after_topic + (qos? 2 : 1)) > length) {
|
||||
LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: Receive buffer can not fit topic + pkt_id\n"));
|
||||
goto out_disconnect;
|
||||
}
|
||||
|
@ -1230,6 +1233,7 @@ mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port,
|
|||
}
|
||||
len = strlen(client_info->will_topic);
|
||||
LWIP_ERROR("mqtt_client_connect: client_info->will_topic length overflow", len <= 0xFF, return ERR_VAL);
|
||||
LWIP_ERROR("mqtt_client_connect: client_info->will_topic length must be > 0", len > 0, return ERR_VAL);
|
||||
will_topic_len = (u8_t)len;
|
||||
len = strlen(client_info->will_msg);
|
||||
LWIP_ERROR("mqtt_client_connect: client_info->will_msg length overflow", len <= 0xFF, return ERR_VAL);
|
||||
|
@ -1291,7 +1295,7 @@ mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port,
|
|||
/* Append client id */
|
||||
mqtt_output_append_string(&client->output, client_info->client_id, client_id_length);
|
||||
/* Append will message if used */
|
||||
if (will_topic_len > 0) {
|
||||
if ((flags & MQTT_CONNECT_FLAG_WILL) != 0) {
|
||||
mqtt_output_append_string(&client->output, client_info->will_topic, will_topic_len);
|
||||
mqtt_output_append_string(&client->output, client_info->will_msg, will_msg_len);
|
||||
}
|
||||
|
@ -1333,3 +1337,5 @@ mqtt_client_is_connected(mqtt_client_t *client)
|
|||
LWIP_ASSERT("mqtt_client_is_connected: client != NULL", client);
|
||||
return client->conn_state == MQTT_CONNECTED;
|
||||
}
|
||||
|
||||
#endif /* LWIP_TCP && LWIP_CALLBACK_API */
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
/** Re-request a used ARP entry 1 minute before it would expire to prevent
|
||||
|
@ -128,7 +132,11 @@ static u8_t etharp_cached_entry;
|
|||
|
||||
|
||||
static err_t etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr* hw_dst_addr);
|
||||
|
||||
static err_t etharp_raw(struct netif *netif,
|
||||
const struct eth_addr *ethsrc_addr, const struct eth_addr *ethdst_addr,
|
||||
const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr,
|
||||
const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr,
|
||||
const u16_t opcode);
|
||||
|
||||
#if ARP_QUEUEING
|
||||
/**
|
||||
|
@ -695,38 +703,12 @@ etharp_input(struct pbuf *p, struct netif *netif)
|
|||
LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n"));
|
||||
/* ARP request for our address? */
|
||||
if (for_us) {
|
||||
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: replying to ARP request for our IP address\n"));
|
||||
/* Re-use pbuf to send ARP reply.
|
||||
Since we are re-using an existing pbuf, we can't call etharp_raw since
|
||||
that would allocate a new pbuf. */
|
||||
hdr->opcode = lwip_htons(ARP_REPLY);
|
||||
|
||||
IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr);
|
||||
IPADDR2_COPY(&hdr->sipaddr, netif_ip4_addr(netif));
|
||||
|
||||
LWIP_ASSERT("netif->hwaddr_len must be the same as ETH_HWADDR_LEN for etharp!",
|
||||
(netif->hwaddr_len == ETH_HWADDR_LEN));
|
||||
|
||||
/* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header
|
||||
are already correct, we tested that before */
|
||||
|
||||
ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
|
||||
ETHADDR16_COPY(&hdr->shwaddr, netif->hwaddr);
|
||||
|
||||
/* return ARP reply */
|
||||
#if LWIP_AUTOIP
|
||||
/* If we are using Link-Local, all ARP packets that contain a Link-Local
|
||||
* 'sender IP address' MUST be sent using link-layer broadcast instead of
|
||||
* link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
|
||||
if (ip4_addr_islinklocal(netif_ip4_addr(netif))) {
|
||||
ethernet_output(netif, p, &hdr->shwaddr, ðbroadcast, ETHTYPE_ARP);
|
||||
} else
|
||||
#endif /* LWIP_AUTOIP */
|
||||
{
|
||||
ethernet_output(netif, p, &hdr->shwaddr, &hdr->dhwaddr, ETHTYPE_ARP);
|
||||
}
|
||||
|
||||
/* send ARP response */
|
||||
etharp_raw(netif,
|
||||
(struct eth_addr *)netif->hwaddr, &hdr->shwaddr,
|
||||
(struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif),
|
||||
&hdr->shwaddr, &sipaddr,
|
||||
ARP_REPLY);
|
||||
/* we are not configured? */
|
||||
} else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
|
||||
/* { for_us == 0 and netif->ip_addr.addr == 0 } */
|
||||
|
|
|
@ -51,6 +51,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
#endif
|
||||
|
||||
/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be
|
||||
* used to modify and send a response packet (and to 1 if this is not the case,
|
||||
* e.g. when link header is stripped of when receiving) */
|
||||
|
|
|
@ -240,7 +240,7 @@ igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr)
|
|||
* @return a struct igmp_group*,
|
||||
* NULL on memory error.
|
||||
*/
|
||||
struct igmp_group *
|
||||
static struct igmp_group *
|
||||
igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
|
||||
{
|
||||
struct igmp_group *group;
|
||||
|
|
|
@ -59,6 +59,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
#endif
|
||||
|
||||
/** Set this to 0 in the rare case of wanting to call an extra function to
|
||||
* generate the IP checksum (in contrast to calculating it on-the-fly). */
|
||||
#ifndef LWIP_INLINE_IP_CHKSUM
|
||||
|
|
|
@ -60,6 +60,10 @@
|
|||
#include "lwip/debug.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Finds the appropriate network interface for a given IPv6 address. It tries to select
|
||||
* a netif following a sequence of heuristics:
|
||||
|
@ -443,9 +447,11 @@ ip6_input(struct pbuf *p, struct netif *inp)
|
|||
ip_addr_copy_from_ip6(ip_data.current_iphdr_dest, ip6hdr->dest);
|
||||
ip_addr_copy_from_ip6(ip_data.current_iphdr_src, ip6hdr->src);
|
||||
|
||||
/* Don't accept virtual IPv6 mapped IPv4 addresses */
|
||||
if (ip6_addr_isipv6mappedipv4(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
|
||||
ip6_addr_isipv6mappedipv4(ip_2_ip6(&ip_data.current_iphdr_src)) ) {
|
||||
/* Don't accept virtual IPv4 mapped IPv6 addresses.
|
||||
* Don't accept multicast source addresses. */
|
||||
if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
|
||||
ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) ||
|
||||
ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) {
|
||||
IP6_STATS_INC(ip6.err);
|
||||
IP6_STATS_INC(ip6.drop);
|
||||
return ERR_OK;
|
||||
|
@ -815,8 +821,8 @@ ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
|
|||
const ip6_addr_t *src_used = src;
|
||||
if (dest != LWIP_IP_HDRINCL) {
|
||||
if (src != NULL && ip6_addr_isany(src)) {
|
||||
src = ip_2_ip6(ip6_select_source_address(netif, dest));
|
||||
if ((src == NULL) || ip6_addr_isany(src)) {
|
||||
src_used = ip_2_ip6(ip6_select_source_address(netif, dest));
|
||||
if ((src_used == NULL) || ip6_addr_isany(src_used)) {
|
||||
/* No appropriate source address was found for this packet. */
|
||||
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n"));
|
||||
IP6_STATS_INC(ip6.rterr);
|
||||
|
|
|
@ -573,6 +573,11 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
|
|||
/* Add hop-by-hop headers options: router alert with MLD value. */
|
||||
ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD);
|
||||
|
||||
if (type == ICMP6_TYPE_MLR) {
|
||||
/* Remember we were the last to report */
|
||||
group->last_reporter_flag = 1;
|
||||
}
|
||||
|
||||
/* Send the packet out. */
|
||||
MLD6_STATS_INC(mld6.xmit);
|
||||
ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address),
|
||||
|
|
|
@ -64,6 +64,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
|
||||
#error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
|
||||
#endif
|
||||
|
|
|
@ -280,6 +280,7 @@ DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static
|
|||
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||
|
||||
static void dns_init_local(void);
|
||||
static err_t dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype));
|
||||
#endif /* DNS_LOCAL_HOSTLIST */
|
||||
|
||||
|
||||
|
@ -430,6 +431,38 @@ dns_init_local(void)
|
|||
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup dns
|
||||
* Iterate the local host-list for a hostname.
|
||||
*
|
||||
* @param iterator_fn a function that is called for every entry in the local host-list
|
||||
* @param iterator_arg 3rd argument passed to iterator_fn
|
||||
* @return the number of entries in the local host-list
|
||||
*/
|
||||
size_t
|
||||
dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg)
|
||||
{
|
||||
size_t i;
|
||||
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
|
||||
struct local_hostlist_entry *entry = local_hostlist_dynamic;
|
||||
i = 0;
|
||||
while (entry != NULL) {
|
||||
if (iterator_fn != NULL) {
|
||||
iterator_fn(entry->name, &entry->addr, iterator_arg);
|
||||
}
|
||||
i++;
|
||||
entry = entry->next;
|
||||
}
|
||||
#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||
for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) {
|
||||
if (iterator_fn != NULL) {
|
||||
iterator_fn(local_hostlist_static[i].name, &local_hostlist_static[i].addr, iterator_arg);
|
||||
}
|
||||
}
|
||||
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup dns
|
||||
* Scans the local host-list for a hostname.
|
||||
|
@ -437,8 +470,20 @@ dns_init_local(void)
|
|||
* @param hostname Hostname to look for in the local host-list
|
||||
* @param addr the first IP address for the hostname in the local host-list or
|
||||
* IPADDR_NONE if not found.
|
||||
* @param dns_addrtype - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 (ATTENTION: no fallback here!)
|
||||
* - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 (ATTENTION: no fallback here!)
|
||||
* - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only
|
||||
* - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only
|
||||
* @return ERR_OK if found, ERR_ARG if not found
|
||||
*/
|
||||
err_t
|
||||
dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype)
|
||||
{
|
||||
LWIP_UNUSED_ARG(dns_addrtype);
|
||||
return dns_lookup_local(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype));
|
||||
}
|
||||
|
||||
/* Internal implementation for dns_local_lookup and dns_lookup */
|
||||
static err_t
|
||||
dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype))
|
||||
{
|
||||
|
@ -1436,9 +1481,9 @@ dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback foun
|
|||
* ERR_INPROGRESS is returned!)
|
||||
* @param callback_arg argument to pass to the callback function
|
||||
* @param dns_addrtype - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 first, try IPv6 if IPv4 fails only
|
||||
* - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 first, try IPv4 if IPv6 fails only
|
||||
* - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only
|
||||
* - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only
|
||||
* - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 first, try IPv4 if IPv6 fails only
|
||||
* - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only
|
||||
* - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only
|
||||
*/
|
||||
err_t
|
||||
dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_callback found,
|
||||
|
|
|
@ -218,9 +218,6 @@ PACK_STRUCT_END
|
|||
#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT)
|
||||
#error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT"
|
||||
#endif
|
||||
#if (LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND)
|
||||
#error "When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value (in arch/cc.h)"
|
||||
#endif
|
||||
#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING
|
||||
#error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too"
|
||||
#endif
|
||||
|
|
|
@ -75,7 +75,6 @@
|
|||
#include "lwip/ip6_frag.h"
|
||||
#include "lwip/mld6.h"
|
||||
|
||||
|
||||
#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)
|
||||
#include "lwip/priv/memp_std.h"
|
||||
|
||||
|
@ -84,6 +83,10 @@ const struct memp_desc* const memp_pools[MEMP_MAX] = {
|
|||
#include "lwip/priv/memp_std.h"
|
||||
};
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
#endif
|
||||
|
||||
#if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2
|
||||
#undef MEMP_OVERFLOW_CHECK
|
||||
/* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */
|
||||
|
|
|
@ -350,8 +350,18 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
|
|||
|
||||
break;
|
||||
case PBUF_RAM:
|
||||
/* If pbuf is to be allocated in RAM, allocate memory for it. */
|
||||
p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length));
|
||||
{
|
||||
mem_size_t alloc_len = LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length);
|
||||
|
||||
/* bug #50040: Check for integer overflow when calculating alloc_len */
|
||||
if (alloc_len < LWIP_MEM_ALIGN_SIZE(length)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If pbuf is to be allocated in RAM, allocate memory for it. */
|
||||
p = (struct pbuf*)mem_malloc(alloc_len);
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -812,6 +822,7 @@ pbuf_ref(struct pbuf *p)
|
|||
/* pbuf given? */
|
||||
if (p != NULL) {
|
||||
SYS_ARCH_INC(p->ref, 1);
|
||||
LWIP_ASSERT("pbuf ref overflow", p->ref > 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ raw_input(struct pbuf *p, struct netif *inp)
|
|||
err_t
|
||||
raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
|
||||
{
|
||||
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
|
||||
if ((pcb == NULL) || (ipaddr == NULL)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);
|
||||
|
@ -233,7 +233,7 @@ raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
|
|||
err_t
|
||||
raw_connect(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
|
||||
{
|
||||
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
|
||||
if ((pcb == NULL) || (ipaddr == NULL)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr);
|
||||
|
|
|
@ -96,7 +96,7 @@ stats_display_igmp(struct stats_igmp *igmp, const char *name)
|
|||
LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report));
|
||||
LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join));
|
||||
LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave));
|
||||
LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report));
|
||||
LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n", igmp->tx_report));
|
||||
}
|
||||
#endif /* IGMP_STATS || MLD6_STATS */
|
||||
|
||||
|
@ -135,7 +135,7 @@ stats_display_sys(struct stats_sys *sys)
|
|||
LWIP_PLATFORM_DIAG(("mutex.err: %"U32_F"\n\t", (u32_t)sys->mutex.err));
|
||||
LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used));
|
||||
LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max));
|
||||
LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n\t", (u32_t)sys->mbox.err));
|
||||
LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n", (u32_t)sys->mbox.err));
|
||||
}
|
||||
#endif /* SYS_STATS */
|
||||
|
||||
|
|
|
@ -62,6 +62,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
#endif
|
||||
|
||||
#ifndef TCP_LOCAL_PORT_RANGE_START
|
||||
/* From http://www.iana.org/assignments/port-numbers:
|
||||
"The Dynamic and/or Private Ports are those from 49152 through 65535" */
|
||||
|
@ -132,6 +136,8 @@ static u8_t tcp_timer;
|
|||
static u8_t tcp_timer_ctr;
|
||||
static u16_t tcp_new_port(void);
|
||||
|
||||
static err_t tcp_close_shutdown_fin(struct tcp_pcb *pcb);
|
||||
|
||||
/**
|
||||
* Initialize this module.
|
||||
*/
|
||||
|
@ -258,8 +264,6 @@ tcp_backlog_accepted(struct tcp_pcb* pcb)
|
|||
static err_t
|
||||
tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
||||
{
|
||||
err_t err;
|
||||
|
||||
if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
|
||||
if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND_MAX(pcb))) {
|
||||
/* Not all data received by application, send RST to tell the remote
|
||||
|
@ -290,6 +294,8 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
|||
}
|
||||
}
|
||||
|
||||
/* - states which free the pcb are handled here,
|
||||
- states which send FIN and change state are handled in tcp_close_shutdown_fin() */
|
||||
switch (pcb->state) {
|
||||
case CLOSED:
|
||||
/* Closing a pcb in the CLOSED state might seem erroneous,
|
||||
|
@ -299,27 +305,34 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
|||
* or for a pcb that has been used and then entered the CLOSED state
|
||||
* is erroneous, but this should never happen as the pcb has in those cases
|
||||
* been freed, and so any remaining handles are bogus. */
|
||||
err = ERR_OK;
|
||||
if (pcb->local_port != 0) {
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
}
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
pcb = NULL;
|
||||
break;
|
||||
case LISTEN:
|
||||
err = ERR_OK;
|
||||
tcp_listen_closed(pcb);
|
||||
tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB_LISTEN, pcb);
|
||||
pcb = NULL;
|
||||
break;
|
||||
case SYN_SENT:
|
||||
err = ERR_OK;
|
||||
TCP_PCB_REMOVE_ACTIVE(pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
pcb = NULL;
|
||||
MIB2_STATS_INC(mib2.tcpattemptfails);
|
||||
break;
|
||||
default:
|
||||
return tcp_close_shutdown_fin(pcb);
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static err_t
|
||||
tcp_close_shutdown_fin(struct tcp_pcb *pcb)
|
||||
{
|
||||
err_t err;
|
||||
LWIP_ASSERT("pcb != NULL", pcb != NULL);
|
||||
|
||||
switch (pcb->state) {
|
||||
case SYN_RCVD:
|
||||
err = tcp_send_fin(pcb);
|
||||
if (err == ERR_OK) {
|
||||
|
@ -344,18 +357,20 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
|||
break;
|
||||
default:
|
||||
/* Has already been closed, do nothing. */
|
||||
err = ERR_OK;
|
||||
pcb = NULL;
|
||||
return ERR_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pcb != NULL && err == ERR_OK) {
|
||||
if (err == ERR_OK) {
|
||||
/* To ensure all data has been sent when tcp_close returns, we have
|
||||
to make sure tcp_output doesn't fail.
|
||||
Since we don't really have to ensure all data has been sent when tcp_close
|
||||
returns (unsent data is sent from tcp timer functions, also), we don't care
|
||||
for the return value of tcp_output for now. */
|
||||
tcp_output(pcb);
|
||||
} else if (err == ERR_MEM) {
|
||||
/* Mark this pcb for closing. Closing is retried from tcp_tmr. */
|
||||
pcb->flags |= TF_CLOSEPEND;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -467,6 +482,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
|||
} else {
|
||||
int send_rst = 0;
|
||||
u16_t local_port = 0;
|
||||
enum tcp_state last_state;
|
||||
seqno = pcb->snd_nxt;
|
||||
ackno = pcb->rcv_nxt;
|
||||
#if LWIP_CALLBACK_API
|
||||
|
@ -499,8 +515,9 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
|||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
|
||||
tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
|
||||
}
|
||||
last_state = pcb->state;
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
|
||||
TCP_EVENT_ERR(last_state, errf, errf_arg, ERR_ABRT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -551,7 +568,7 @@ tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
|
|||
#endif /* LWIP_IPV4 */
|
||||
|
||||
/* still need to check for ipaddr == NULL in IPv6 only case */
|
||||
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
|
||||
if ((pcb == NULL) || (ipaddr == NULL)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
|
@ -859,7 +876,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
|
|||
u32_t iss;
|
||||
u16_t old_local_port;
|
||||
|
||||
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
|
||||
if ((pcb == NULL) || (ipaddr == NULL)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
|
@ -931,7 +948,6 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
|
|||
pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip);
|
||||
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
|
||||
pcb->cwnd = 1;
|
||||
pcb->ssthresh = TCP_WND;
|
||||
#if LWIP_CALLBACK_API
|
||||
pcb->connected = connected;
|
||||
#else /* LWIP_CALLBACK_API */
|
||||
|
@ -997,11 +1013,11 @@ tcp_slowtmr_start:
|
|||
pcb_remove = 0;
|
||||
pcb_reset = 0;
|
||||
|
||||
if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
|
||||
if (pcb->state == SYN_SENT && pcb->nrtx >= TCP_SYNMAXRTX) {
|
||||
++pcb_remove;
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
|
||||
}
|
||||
else if (pcb->nrtx == TCP_MAXRTX) {
|
||||
else if (pcb->nrtx >= TCP_MAXRTX) {
|
||||
++pcb_remove;
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
|
||||
} else {
|
||||
|
@ -1035,7 +1051,8 @@ tcp_slowtmr_start:
|
|||
/* Double retransmission time-out unless we are trying to
|
||||
* connect to somebody (i.e., we are in SYN_SENT). */
|
||||
if (pcb->state != SYN_SENT) {
|
||||
pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
|
||||
u8_t backoff_idx = LWIP_MIN(pcb->nrtx, sizeof(tcp_backoff)-1);
|
||||
pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[backoff_idx];
|
||||
}
|
||||
|
||||
/* Reset the retransmission timer. */
|
||||
|
@ -1132,6 +1149,7 @@ tcp_slowtmr_start:
|
|||
tcp_err_fn err_fn = pcb->errf;
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
void *err_arg;
|
||||
enum tcp_state last_state;
|
||||
tcp_pcb_purge(pcb);
|
||||
/* Remove PCB from tcp_active_pcbs list. */
|
||||
if (prev != NULL) {
|
||||
|
@ -1149,12 +1167,13 @@ tcp_slowtmr_start:
|
|||
}
|
||||
|
||||
err_arg = pcb->callback_arg;
|
||||
last_state = pcb->state;
|
||||
pcb2 = pcb;
|
||||
pcb = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb2);
|
||||
|
||||
tcp_active_pcbs_changed = 0;
|
||||
TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT);
|
||||
TCP_EVENT_ERR(last_state, err_fn, err_arg, ERR_ABRT);
|
||||
if (tcp_active_pcbs_changed) {
|
||||
goto tcp_slowtmr_start;
|
||||
}
|
||||
|
@ -1244,6 +1263,12 @@ tcp_fasttmr_start:
|
|||
tcp_output(pcb);
|
||||
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
|
||||
}
|
||||
/* send pending FIN */
|
||||
if (pcb->flags & TF_CLOSEPEND) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: pending FIN\n"));
|
||||
pcb->flags &= ~(TF_CLOSEPEND);
|
||||
tcp_close_shutdown_fin(pcb);
|
||||
}
|
||||
|
||||
next = pcb->next;
|
||||
|
||||
|
@ -1590,6 +1615,14 @@ tcp_alloc(u8_t prio)
|
|||
pcb->tmr = tcp_ticks;
|
||||
pcb->last_timer = tcp_timer_ctr;
|
||||
|
||||
/* RFC 5681 recommends setting ssthresh abritrarily high and gives an example
|
||||
of using the largest advertised receive window. We've seen complications with
|
||||
receiving TCPs that use window scaling and/or window auto-tuning where the
|
||||
initial advertised window is very small and then grows rapidly once the
|
||||
connection is established. To avoid these complications, we set ssthresh to the
|
||||
largest effective cwnd (amount of in-flight data) that the sender can have. */
|
||||
pcb->ssthresh = TCP_SND_BUF;
|
||||
|
||||
#if LWIP_CALLBACK_API
|
||||
pcb->recv = tcp_recv_null;
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
|
|
|
@ -61,8 +61,6 @@
|
|||
|
||||
/** Initial CWND calculation as defined RFC 2581 */
|
||||
#define LWIP_TCP_CALC_INITIAL_CWND(mss) LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U));
|
||||
/** Initial slow start threshold value: we use the full window */
|
||||
#define LWIP_TCP_INITIAL_SSTHRESH(pcb) ((pcb)->snd_wnd)
|
||||
|
||||
/* These variables are global to all functions involved in the input
|
||||
processing of TCP segments. They are set by the tcp_input()
|
||||
|
@ -378,7 +376,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
end. We then call the error callback to inform the
|
||||
application that the connection is dead before we
|
||||
deallocate the PCB. */
|
||||
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
|
||||
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST);
|
||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
} else {
|
||||
|
@ -413,7 +411,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
/* Connection closed although the application has only shut down the
|
||||
tx side: call the PCB's err callback and indicate the closure to
|
||||
ensure the application doesn't continue using the PCB. */
|
||||
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD);
|
||||
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
|
||||
}
|
||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
|
@ -615,7 +613,6 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
|||
tcp_parseopt(npcb);
|
||||
npcb->snd_wnd = tcphdr->wnd;
|
||||
npcb->snd_wnd_max = npcb->snd_wnd;
|
||||
npcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(npcb);
|
||||
|
||||
#if TCP_CALCULATE_EFF_SEND_MSS
|
||||
npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, &npcb->remote_ip);
|
||||
|
@ -771,9 +768,6 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip);
|
||||
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
|
||||
|
||||
/* Set ssthresh again after changing 'mss' and 'snd_wnd' */
|
||||
pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb);
|
||||
|
||||
pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
|
||||
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F
|
||||
" ssthresh %"TCPWNDSIZE_F"\n",
|
||||
|
@ -816,9 +810,12 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
ip_current_src_addr(), tcphdr->dest, tcphdr->src);
|
||||
/* Resend SYN immediately (don't wait for rto timeout) to establish
|
||||
connection faster */
|
||||
pcb->rtime = 0;
|
||||
tcp_rexmit_rto(pcb);
|
||||
connection faster, but do not send more SYNs than we otherwise would
|
||||
have, or we might get caught in a loop on loopback interfaces. */
|
||||
if (pcb->nrtx < TCP_SYNMAXRTX) {
|
||||
pcb->rtime = 0;
|
||||
tcp_rexmit_rto(pcb);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SYN_RCVD:
|
||||
|
@ -827,14 +824,16 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
|
||||
pcb->state = ESTABLISHED;
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
|
||||
#if LWIP_CALLBACK_API
|
||||
LWIP_ASSERT("pcb->listener->accept != NULL",
|
||||
(pcb->listener == NULL) || (pcb->listener->accept != NULL));
|
||||
#endif
|
||||
if (pcb->listener == NULL) {
|
||||
/* listen pcb might be closed by now */
|
||||
err = ERR_VAL;
|
||||
} else
|
||||
#endif
|
||||
#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
|
||||
{
|
||||
tcp_backlog_accepted(pcb);
|
||||
/* Call the accept function. */
|
||||
|
@ -853,11 +852,6 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
* we'd better pass it on to the application as well. */
|
||||
tcp_receive(pcb);
|
||||
|
||||
/* passive open: update initial ssthresh now that the correct window is
|
||||
known: if the remote side supports window scaling, the window sent
|
||||
with the initial SYN can be smaller than the one used later */
|
||||
pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb);
|
||||
|
||||
/* Prevent ACK for SYN to generate a sent event */
|
||||
if (recv_acked != 0) {
|
||||
recv_acked--;
|
||||
|
@ -925,7 +919,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
break;
|
||||
case CLOSING:
|
||||
tcp_receive(pcb);
|
||||
if (flags & TCP_ACK && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
|
||||
if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
tcp_pcb_purge(pcb);
|
||||
TCP_RMV_ACTIVE(pcb);
|
||||
|
@ -935,7 +929,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
break;
|
||||
case LAST_ACK:
|
||||
tcp_receive(pcb);
|
||||
if (flags & TCP_ACK && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
|
||||
if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
/* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
|
||||
recv_flags |= TF_CLOSED;
|
||||
|
@ -1417,7 +1411,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||
TCP_SEQ_GEQ(seqno + tcplen,
|
||||
next->tcphdr->seqno + next->len)) {
|
||||
/* inseg cannot have FIN here (already processed above) */
|
||||
if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
|
||||
if ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0 &&
|
||||
(TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
|
||||
TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
|
||||
tcplen = TCP_TCPLEN(&inseg);
|
||||
|
|
|
@ -376,6 +376,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||
#if TCP_OVERSIZE
|
||||
u16_t oversize = 0;
|
||||
u16_t oversize_used = 0;
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
u16_t oversize_add = 0;
|
||||
#endif /* TCP_OVERSIZE_DBGCHECK*/
|
||||
#endif /* TCP_OVERSIZE */
|
||||
u16_t extendlen = 0;
|
||||
#if TCP_CHECKSUM_ON_COPY
|
||||
|
@ -461,13 +464,13 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||
*/
|
||||
#if TCP_OVERSIZE
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
/* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */
|
||||
/* check that pcb->unsent_oversize matches last_unsent->oversize_left */
|
||||
LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)",
|
||||
pcb->unsent_oversize == last_unsent->oversize_left);
|
||||
#endif /* TCP_OVERSIZE_DBGCHECK */
|
||||
oversize = pcb->unsent_oversize;
|
||||
if (oversize > 0) {
|
||||
LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space);
|
||||
LWIP_ASSERT("inconsistent oversize vs. space", oversize <= space);
|
||||
seg = last_unsent;
|
||||
oversize_used = LWIP_MIN(space, LWIP_MIN(oversize, len));
|
||||
pos += oversize_used;
|
||||
|
@ -475,7 +478,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||
space -= oversize_used;
|
||||
}
|
||||
/* now we are either finished or oversize is zero */
|
||||
LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len));
|
||||
LWIP_ASSERT("inconsistent oversize vs. len", (oversize == 0) || (pos == len));
|
||||
#endif /* TCP_OVERSIZE */
|
||||
|
||||
/*
|
||||
|
@ -490,7 +493,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||
* the end.
|
||||
*/
|
||||
if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
|
||||
u16_t seglen = space < len - pos ? space : len - pos;
|
||||
u16_t seglen = LWIP_MIN(space, len - pos);
|
||||
seg = last_unsent;
|
||||
|
||||
/* Create a pbuf with a copy or reference to seglen bytes. We
|
||||
|
@ -505,7 +508,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||
goto memerr;
|
||||
}
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
last_unsent->oversize_left += oversize;
|
||||
oversize_add = oversize;
|
||||
#endif /* TCP_OVERSIZE_DBGCHECK */
|
||||
TCP_DATA_COPY2(concat_p->payload, (const u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped);
|
||||
#if TCP_CHECKSUM_ON_COPY
|
||||
|
@ -557,7 +560,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||
struct pbuf *p;
|
||||
u16_t left = len - pos;
|
||||
u16_t max_len = mss_local - optlen;
|
||||
u16_t seglen = left > max_len ? max_len : left;
|
||||
u16_t seglen = LWIP_MIN(left, max_len);
|
||||
#if TCP_CHECKSUM_ON_COPY
|
||||
u16_t chksum = 0;
|
||||
u8_t chksum_swapped = 0;
|
||||
|
@ -656,6 +659,11 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||
* All three segmentation phases were successful. We can commit the
|
||||
* transaction.
|
||||
*/
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
if ((last_unsent != NULL) && (oversize_add != 0)) {
|
||||
last_unsent->oversize_left += oversize_add;
|
||||
}
|
||||
#endif /* TCP_OVERSIZE_DBGCHECK */
|
||||
|
||||
/*
|
||||
* Phase 1: If data has been added to the preallocated tail of
|
||||
|
@ -1412,7 +1420,9 @@ tcp_rexmit_rto(struct tcp_pcb *pcb)
|
|||
pcb->unacked = NULL;
|
||||
|
||||
/* increment number of retransmissions */
|
||||
++pcb->nrtx;
|
||||
if (pcb->nrtx < 0xFF) {
|
||||
++pcb->nrtx;
|
||||
}
|
||||
|
||||
/* Don't take any RTT measurements after retransmitting. */
|
||||
pcb->rttest = 0;
|
||||
|
@ -1457,7 +1467,9 @@ tcp_rexmit(struct tcp_pcb *pcb)
|
|||
}
|
||||
#endif /* TCP_OVERSIZE */
|
||||
|
||||
++pcb->nrtx;
|
||||
if (pcb->nrtx < 0xFF) {
|
||||
++pcb->nrtx;
|
||||
}
|
||||
|
||||
/* Don't take any rtt measurements after retransmitting. */
|
||||
pcb->rttest = 0;
|
||||
|
@ -1488,11 +1500,7 @@ tcp_rexmit_fast(struct tcp_pcb *pcb)
|
|||
|
||||
/* Set ssthresh to half of the minimum of the current
|
||||
* cwnd and the advertised window */
|
||||
if (pcb->cwnd > pcb->snd_wnd) {
|
||||
pcb->ssthresh = pcb->snd_wnd / 2;
|
||||
} else {
|
||||
pcb->ssthresh = pcb->cwnd / 2;
|
||||
}
|
||||
pcb->ssthresh = LWIP_MIN(pcb->cwnd, pcb->snd_wnd) / 2;
|
||||
|
||||
/* The minimum value for ssthresh should be 2 MSS */
|
||||
if (pcb->ssthresh < (2U * pcb->mss)) {
|
||||
|
|
|
@ -892,7 +892,7 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
|
|||
#endif /* LWIP_IPV4 */
|
||||
|
||||
/* still need to check for ipaddr == NULL in IPv6 only case */
|
||||
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
|
||||
if ((pcb == NULL) || (ipaddr == NULL)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
|
@ -982,7 +982,7 @@ udp_connect(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
|
|||
{
|
||||
struct udp_pcb *ipcb;
|
||||
|
||||
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
|
||||
if ((pcb == NULL) || (ipaddr == NULL)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,9 @@
|
|||
|
||||
#include "lwip/apps/mqtt_opts.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
@ -236,7 +237,7 @@ err_t mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_re
|
|||
err_t mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain,
|
||||
mqtt_request_cb_t cb, void *arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
#endif
|
||||
|
||||
/** Define random number generator function of your system */
|
||||
#ifndef LWIP_RAND
|
||||
#ifdef __DOXYGEN__
|
||||
#define LWIP_RAND() ((u32_t)rand())
|
||||
#endif
|
||||
|
||||
|
@ -76,7 +76,7 @@
|
|||
* systems, this should be defined to something less resource-consuming.
|
||||
*/
|
||||
#ifndef LWIP_PLATFORM_DIAG
|
||||
#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
|
||||
#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
@ -162,6 +162,19 @@ typedef uintptr_t mem_ptr_t;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
|
||||
* the limits.h header. You need to define the type limits yourself in this case
|
||||
* (e.g. INT_MAX).
|
||||
*/
|
||||
#ifndef LWIP_NO_LIMITS_H
|
||||
#define LWIP_NO_LIMITS_H 0
|
||||
#endif
|
||||
|
||||
/* Include limits.h? */
|
||||
#if !LWIP_NO_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
/** C++ const_cast<target_type>(val) equivalent to remove constness from a value (GCC -Wcast-qual) */
|
||||
#ifndef LWIP_CONST_CAST
|
||||
#define LWIP_CONST_CAST(target_type, val) ((target_type)((ptrdiff_t)val))
|
||||
|
|
|
@ -76,6 +76,7 @@ struct local_hostlist_entry {
|
|||
ip_addr_t addr;
|
||||
struct local_hostlist_entry *next;
|
||||
};
|
||||
#define DNS_LOCAL_HOSTLIST_ELEM(name, addr_init) {name, addr_init, NULL}
|
||||
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
|
||||
#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN
|
||||
#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH
|
||||
|
@ -111,10 +112,14 @@ err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *add
|
|||
u8_t dns_addrtype);
|
||||
|
||||
|
||||
#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC
|
||||
#if DNS_LOCAL_HOSTLIST
|
||||
size_t dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg);
|
||||
err_t dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype);
|
||||
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
|
||||
int dns_local_removehost(const char *hostname, const ip_addr_t *addr);
|
||||
err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr);
|
||||
#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||
#endif /* DNS_LOCAL_HOSTLIST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ enum icmp_dur_type {
|
|||
|
||||
/** ICMP time exceeded codes */
|
||||
enum icmp_te_type {
|
||||
/* time to live exceeded in transit */
|
||||
/** time to live exceeded in transit */
|
||||
ICMP_TE_TTL = 0,
|
||||
/** fragment reassembly time exceeded */
|
||||
ICMP_TE_FRAG = 1
|
||||
|
|
|
@ -54,7 +54,7 @@ extern "C" {
|
|||
/** x.X.x: Minor version of the stack */
|
||||
#define LWIP_VERSION_MINOR 0
|
||||
/** x.x.X: Revision of the stack */
|
||||
#define LWIP_VERSION_REVISION 1
|
||||
#define LWIP_VERSION_REVISION 2
|
||||
/** For release candidates, this is set to 1..254
|
||||
* For official releases, this is set to 255 (LWIP_RC_RELEASE)
|
||||
* For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */
|
||||
|
|
|
@ -159,7 +159,7 @@ typedef struct ip6_addr ip6_addr_t;
|
|||
|
||||
#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL))
|
||||
|
||||
#define ip6_addr_isipv6mappedipv4(ip6addr) (((ip6addr)->addr[0] == 0) && ((ip6addr)->addr[1] == 0) && (((ip6addr)->addr[2]) == PP_HTONL(0x0000FFFFUL)))
|
||||
#define ip6_addr_isipv4mappedipv6(ip6addr) (((ip6addr)->addr[0] == 0) && ((ip6addr)->addr[1] == 0) && (((ip6addr)->addr[2]) == PP_HTONL(0x0000FFFFUL)))
|
||||
|
||||
#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL))
|
||||
#define ip6_addr_multicast_transient_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL))
|
||||
|
|
|
@ -222,14 +222,14 @@ int ipaddr_aton(const char *cp, ip_addr_t *addr);
|
|||
#define IPADDR_STRLEN_MAX IP6ADDR_STRLEN_MAX
|
||||
|
||||
/** @ingroup ipaddr */
|
||||
#define ip4_2_ipv6_mapped_ipv4(ip6addr, ip4addr) do { \
|
||||
#define ip4_2_ipv4_mapped_ipv6(ip6addr, ip4addr) do { \
|
||||
(ip6addr)->addr[3] = (ip4addr)->addr; \
|
||||
(ip6addr)->addr[2] = PP_HTONL(0x0000FFFFUL); \
|
||||
(ip6addr)->addr[1] = 0; \
|
||||
(ip6addr)->addr[0] = 0; } while(0);
|
||||
|
||||
/** @ingroup ipaddr */
|
||||
#define unmap_ipv6_mapped_ipv4(ip4addr, ip6addr) \
|
||||
#define unmap_ipv4_mapped_ipv6(ip4addr, ip6addr) \
|
||||
(ip4addr)->addr = (ip6addr)->addr[3];
|
||||
|
||||
#define IP46_ADDR_ANY(type) (((type) == IPADDR_TYPE_V6)? IP6_ADDR_ANY : IP4_ADDR_ANY)
|
||||
|
|
|
@ -1047,11 +1047,9 @@
|
|||
#define LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING 2
|
||||
#define LWIP_DNS_SECURE_RAND_SRC_PORT 4
|
||||
|
||||
/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled,
|
||||
* you have to define
|
||||
* \#define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}}
|
||||
* (an array of structs name/address, where address is an u32_t in network
|
||||
* byte order).
|
||||
/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, you have to define an initializer:
|
||||
* \#define DNS_LOCAL_HOSTLIST_INIT {DNS_LOCAL_HOSTLIST_ELEM("host_ip4", IPADDR4_INIT_BYTES(1,2,3,4)), \
|
||||
* DNS_LOCAL_HOSTLIST_ELEM("host_ip6", IPADDR6_INIT_HOST(123, 234, 345, 456)}
|
||||
*
|
||||
* Instead, you can also use an external function:
|
||||
* \#define DNS_LOOKUP_LOCAL_EXTERN(x) extern err_t my_lookup_function(const char *name, ip_addr_t *addr, u8_t dns_addrtype)
|
||||
|
@ -2415,6 +2413,15 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* LWIP_HOOK_FILENAME: Custom filename to #include in files that provide hooks.
|
||||
* Declare your hook function prototypes in there, you may also #include all headers
|
||||
* providing data types that are need in this file.
|
||||
*/
|
||||
#ifdef __DOXYGEN__
|
||||
#define LWIP_HOOK_FILENAME "path/to/my/lwip_hooks.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_HOOK_TCP_ISN:
|
||||
* Hook for generation of the Initial Sequence Number (ISN) for a new TCP
|
||||
|
|
|
@ -170,16 +170,18 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb);
|
|||
LWIP_EVENT_RECV, NULL, 0, ERR_OK)
|
||||
#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
|
||||
LWIP_EVENT_CONNECTED, NULL, 0, (err))
|
||||
#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
|
||||
LWIP_EVENT_POLL, NULL, 0, ERR_OK)
|
||||
#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \
|
||||
LWIP_EVENT_ERR, NULL, 0, (err))
|
||||
#define TCP_EVENT_POLL(pcb,ret) do { if ((pcb)->state != SYN_RCVD) { \
|
||||
ret = lwip_tcp_event((pcb)->callback_arg, (pcb), LWIP_EVENT_POLL, NULL, 0, ERR_OK); \
|
||||
} else { \
|
||||
ret = ERR_ARG; } } while(0)
|
||||
#define TCP_EVENT_ERR(last_state,errf,arg,err) do { if (last_state != SYN_RCVD) { \
|
||||
lwip_tcp_event((arg), NULL, LWIP_EVENT_ERR, NULL, 0, (err)); } } while(0)
|
||||
|
||||
#else /* LWIP_EVENT_API */
|
||||
|
||||
#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) \
|
||||
do { \
|
||||
if((lpcb != NULL) && ((lpcb)->accept != NULL)) \
|
||||
if((lpcb)->accept != NULL) \
|
||||
(ret) = (lpcb)->accept((arg),(pcb),(err)); \
|
||||
else (ret) = ERR_ARG; \
|
||||
} while (0)
|
||||
|
@ -223,8 +225,9 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb);
|
|||
else (ret) = ERR_OK; \
|
||||
} while (0)
|
||||
|
||||
#define TCP_EVENT_ERR(errf,arg,err) \
|
||||
#define TCP_EVENT_ERR(last_state,errf,arg,err) \
|
||||
do { \
|
||||
LWIP_UNUSED_ARG(last_state); \
|
||||
if((errf) != NULL) \
|
||||
(errf)((arg),(err)); \
|
||||
} while (0)
|
||||
|
@ -249,7 +252,7 @@ struct tcp_seg {
|
|||
#if TCP_OVERSIZE_DBGCHECK
|
||||
u16_t oversize_left; /* Extra bytes available at the end of the last
|
||||
pbuf in unsent (used for asserting vs.
|
||||
tcp_pcb.unsent_oversized only) */
|
||||
tcp_pcb.unsent_oversize only) */
|
||||
#endif /* TCP_OVERSIZE_DBGCHECK */
|
||||
#if TCP_CHECKSUM_ON_COPY
|
||||
u16_t chksum;
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/errno.h"
|
||||
#include "lwip/lwip_errno.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -145,7 +145,7 @@ typedef u32_t tcpwnd_size_t;
|
|||
typedef u16_t tcpwnd_size_t;
|
||||
#endif
|
||||
|
||||
#if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG
|
||||
#if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG || LWIP_TCP_TIMESTAMPS
|
||||
typedef u16_t tcpflags_t;
|
||||
#else
|
||||
typedef u8_t tcpflags_t;
|
||||
|
@ -210,7 +210,7 @@ struct tcp_pcb {
|
|||
#define TF_ACK_DELAY 0x01U /* Delayed ACK. */
|
||||
#define TF_ACK_NOW 0x02U /* Immediate ACK. */
|
||||
#define TF_INFR 0x04U /* In fast recovery. */
|
||||
#define TF_TIMESTAMP 0x08U /* Timestamp option enabled */
|
||||
#define TF_CLOSEPEND 0x08U /* If this is set, tcp_close failed to enqueue the FIN (retried in tcp_tmr) */
|
||||
#define TF_RXCLOSED 0x10U /* rx closed by tcp_shutdown */
|
||||
#define TF_FIN 0x20U /* Connection was closed locally (FIN segment enqueued). */
|
||||
#define TF_NODELAY 0x40U /* Disable Nagle algorithm */
|
||||
|
@ -220,6 +220,9 @@ struct tcp_pcb {
|
|||
#endif
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
#define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */
|
||||
#endif
|
||||
#if LWIP_TCP_TIMESTAMPS
|
||||
#define TF_TIMESTAMP 0x0400U /* Timestamp option enabled */
|
||||
#endif
|
||||
|
||||
/* the rest of the fields are in host byte order
|
||||
|
@ -358,7 +361,11 @@ void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept);
|
|||
#endif /* LWIP_CALLBACK_API */
|
||||
void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval);
|
||||
|
||||
#if LWIP_TCP_TIMESTAMPS
|
||||
#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss)
|
||||
#else /* LWIP_TCP_TIMESTAMPS */
|
||||
#define tcp_mss(pcb) ((pcb)->mss)
|
||||
#endif /* LWIP_TCP_TIMESTAMPS */
|
||||
#define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf))
|
||||
#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen)
|
||||
/** @ingroup tcp_raw */
|
||||
|
|
|
@ -138,10 +138,10 @@
|
|||
*/
|
||||
struct link_callbacks {
|
||||
/* Start a connection (e.g. Initiate discovery phase) */
|
||||
err_t (*connect) (ppp_pcb *pcb, void *ctx);
|
||||
void (*connect) (ppp_pcb *pcb, void *ctx);
|
||||
#if PPP_SERVER
|
||||
/* Listen for an incoming connection (Passive mode) */
|
||||
err_t (*listen) (ppp_pcb *pcb, void *ctx);
|
||||
void (*listen) (ppp_pcb *pcb, void *ctx);
|
||||
#endif /* PPP_SERVER */
|
||||
/* End a connection (i.e. initiate disconnect phase) */
|
||||
void (*disconnect) (ppp_pcb *pcb, void *ctx);
|
||||
|
|
|
@ -30,4 +30,4 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "lwip/errno.h"
|
||||
#include "lwip/lwip_errno.h"
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
#include "netif/ppp/pppoe.h"
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
#endif
|
||||
|
||||
const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
||||
const struct eth_addr ethzero = {{0,0,0,0,0,0}};
|
||||
|
||||
|
|
|
@ -275,8 +275,8 @@ err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff) {
|
|||
PPPDEBUG(LOG_DEBUG, ("ppp_connect[%d]: holdoff=%d\n", pcb->netif->num, holdoff));
|
||||
|
||||
if (holdoff == 0) {
|
||||
new_phase(pcb, PPP_PHASE_INITIALIZE);
|
||||
return pcb->link_cb->connect(pcb, pcb->link_ctx_cb);
|
||||
ppp_do_connect(pcb);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
new_phase(pcb, PPP_PHASE_HOLDOFF);
|
||||
|
@ -302,7 +302,8 @@ err_t ppp_listen(ppp_pcb *pcb) {
|
|||
|
||||
if (pcb->link_cb->listen) {
|
||||
new_phase(pcb, PPP_PHASE_INITIALIZE);
|
||||
return pcb->link_cb->listen(pcb, pcb->link_ctx_cb);
|
||||
pcb->link_cb->listen(pcb, pcb->link_ctx_cb);
|
||||
return ERR_OK;
|
||||
}
|
||||
return ERR_IF;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ LWIP_MEMPOOL_DECLARE(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_so
|
|||
/* callbacks called from PPP core */
|
||||
static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p);
|
||||
static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol);
|
||||
static err_t pppoe_connect(ppp_pcb *ppp, void *ctx);
|
||||
static void pppoe_connect(ppp_pcb *ppp, void *ctx);
|
||||
static void pppoe_disconnect(ppp_pcb *ppp, void *ctx);
|
||||
static err_t pppoe_destroy(ppp_pcb *ppp, void *ctx);
|
||||
|
||||
|
@ -879,7 +879,7 @@ pppoe_timeout(void *arg)
|
|||
}
|
||||
|
||||
/* Start a connection (i.e. initiate discovery phase) */
|
||||
static err_t
|
||||
static void
|
||||
pppoe_connect(ppp_pcb *ppp, void *ctx)
|
||||
{
|
||||
err_t err;
|
||||
|
@ -934,7 +934,6 @@ pppoe_connect(ppp_pcb *ppp, void *ctx)
|
|||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
}
|
||||
sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* disconnect */
|
||||
|
|
|
@ -73,7 +73,7 @@ LWIP_MEMPOOL_DECLARE(PPPOL2TP_PCB, MEMP_NUM_PPPOL2TP_INTERFACES, sizeof(pppol2tp
|
|||
static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p);
|
||||
static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol);
|
||||
static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx); /* Destroy a L2TP control block */
|
||||
static err_t pppol2tp_connect(ppp_pcb *ppp, void *ctx); /* Be a LAC, connect to a LNS. */
|
||||
static void pppol2tp_connect(ppp_pcb *ppp, void *ctx); /* Be a LAC, connect to a LNS. */
|
||||
static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx); /* Disconnect */
|
||||
|
||||
/* Prototypes for procedures local to this file. */
|
||||
|
@ -255,7 +255,7 @@ static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx) {
|
|||
}
|
||||
|
||||
/* Be a LAC, connect to a LNS. */
|
||||
static err_t pppol2tp_connect(ppp_pcb *ppp, void *ctx) {
|
||||
static void pppol2tp_connect(ppp_pcb *ppp, void *ctx) {
|
||||
err_t err;
|
||||
pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx;
|
||||
lcp_options *lcp_wo;
|
||||
|
@ -326,7 +326,6 @@ static err_t pppol2tp_connect(ppp_pcb *ppp, void *ctx) {
|
|||
PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err));
|
||||
}
|
||||
sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Disconnect */
|
||||
|
|
|
@ -57,9 +57,9 @@ LWIP_MEMPOOL_DECLARE(PPPOS_PCB, MEMP_NUM_PPPOS_INTERFACES, sizeof(pppos_pcb), "P
|
|||
/* callbacks called from PPP core */
|
||||
static err_t pppos_write(ppp_pcb *ppp, void *ctx, struct pbuf *p);
|
||||
static err_t pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol);
|
||||
static err_t pppos_connect(ppp_pcb *ppp, void *ctx);
|
||||
static void pppos_connect(ppp_pcb *ppp, void *ctx);
|
||||
#if PPP_SERVER
|
||||
static err_t pppos_listen(ppp_pcb *ppp, void *ctx);
|
||||
static void pppos_listen(ppp_pcb *ppp, void *ctx);
|
||||
#endif /* PPP_SERVER */
|
||||
static void pppos_disconnect(ppp_pcb *ppp, void *ctx);
|
||||
static err_t pppos_destroy(ppp_pcb *ppp, void *ctx);
|
||||
|
@ -298,7 +298,7 @@ pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol)
|
|||
return err;
|
||||
}
|
||||
|
||||
static err_t
|
||||
static void
|
||||
pppos_connect(ppp_pcb *ppp, void *ctx)
|
||||
{
|
||||
pppos_pcb *pppos = (pppos_pcb *)ctx;
|
||||
|
@ -327,11 +327,10 @@ pppos_connect(ppp_pcb *ppp, void *ctx)
|
|||
*/
|
||||
PPPDEBUG(LOG_INFO, ("pppos_connect: unit %d: connecting\n", ppp->netif->num));
|
||||
ppp_start(ppp); /* notify upper layers */
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
#if PPP_SERVER
|
||||
static err_t
|
||||
static void
|
||||
pppos_listen(ppp_pcb *ppp, void *ctx)
|
||||
{
|
||||
pppos_pcb *pppos = (pppos_pcb *)ctx;
|
||||
|
@ -360,7 +359,6 @@ pppos_listen(ppp_pcb *ppp, void *ctx)
|
|||
*/
|
||||
PPPDEBUG(LOG_INFO, ("pppos_listen: unit %d: listening\n", ppp->netif->num));
|
||||
ppp_start(ppp); /* notify upper layers */
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* PPP_SERVER */
|
||||
|
||||
|
|
|
@ -155,19 +155,19 @@ tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip,
|
|||
|
||||
if (state == ESTABLISHED) {
|
||||
TCP_REG(&tcp_active_pcbs, pcb);
|
||||
pcb->local_ip.addr = local_ip->addr;
|
||||
ip_addr_copy(pcb->local_ip, *local_ip);
|
||||
pcb->local_port = local_port;
|
||||
pcb->remote_ip.addr = remote_ip->addr;
|
||||
ip_addr_copy(pcb->remote_ip, *remote_ip);
|
||||
pcb->remote_port = remote_port;
|
||||
} else if(state == LISTEN) {
|
||||
TCP_REG(&tcp_listen_pcbs.pcbs, pcb);
|
||||
pcb->local_ip.addr = local_ip->addr;
|
||||
ip_addr_copy(pcb->local_ip, *local_ip);
|
||||
pcb->local_port = local_port;
|
||||
} else if(state == TIME_WAIT) {
|
||||
TCP_REG(&tcp_tw_pcbs, pcb);
|
||||
pcb->local_ip.addr = local_ip->addr;
|
||||
ip_addr_copy(pcb->local_ip, *local_ip);
|
||||
pcb->local_port = local_port;
|
||||
pcb->remote_ip.addr = remote_ip->addr;
|
||||
ip_addr_copy(pcb->remote_ip, *remote_ip);
|
||||
pcb->remote_port = remote_port;
|
||||
} else {
|
||||
fail();
|
||||
|
@ -302,8 +302,8 @@ void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcoun
|
|||
}
|
||||
netif->output = test_tcp_netif_output;
|
||||
netif->flags |= NETIF_FLAG_UP | NETIF_FLAG_LINK_UP;
|
||||
ip4_addr_copy(netif->netmask, *ip_2_ip4(netmask));
|
||||
ip4_addr_copy(netif->ip_addr, *ip_2_ip4(ip_addr));
|
||||
ip_addr_copy_from_ip4(netif->netmask, *ip_2_ip4(netmask));
|
||||
ip_addr_copy_from_ip4(netif->ip_addr, *ip_2_ip4(ip_addr));
|
||||
for (n = netif_list; n != NULL; n = n->next) {
|
||||
if (n == netif) {
|
||||
return;
|
||||
|
|
|
@ -46,9 +46,9 @@ tcp_setup(void)
|
|||
static void
|
||||
tcp_teardown(void)
|
||||
{
|
||||
tcp_remove_all();
|
||||
netif_list = NULL;
|
||||
netif_default = NULL;
|
||||
tcp_remove_all();
|
||||
}
|
||||
|
||||
|
||||
|
@ -422,6 +422,8 @@ START_TEST(test_tcp_fast_rexmit_wraparound)
|
|||
pcb->mss = TCP_MSS;
|
||||
/* disable initial congestion window (we don't send a SYN here...) */
|
||||
pcb->cwnd = 2*TCP_MSS;
|
||||
/* start in congestion advoidance */
|
||||
pcb->ssthresh = pcb->cwnd;
|
||||
|
||||
/* send 6 mss-sized segments */
|
||||
for (i = 0; i < 6; i++) {
|
||||
|
@ -442,7 +444,9 @@ START_TEST(test_tcp_fast_rexmit_wraparound)
|
|||
/* ACK the first segment */
|
||||
p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
|
||||
test_tcp_input(p, &netif);
|
||||
/* ensure this didn't trigger a retransmission */
|
||||
/* ensure this didn't trigger a retransmission. Only one
|
||||
segment should be transmitted because cwnd opened up by
|
||||
TCP_MSS and a fraction since we are in congestion avoidance */
|
||||
EXPECT(txcounters.num_tx_calls == 1);
|
||||
EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
|
||||
memset(&txcounters, 0, sizeof(txcounters));
|
||||
|
|
Loading…
Reference in New Issue