Compare commits
119 Commits
master
...
STABLE-2_1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ca936f6b5 | ||
|
|
e7b74570d9 | ||
|
|
018c64ab94 | ||
|
|
7e92fb3d7f | ||
|
|
051fbea5e6 | ||
|
|
214e2d90f3 | ||
|
|
4022a19cbc | ||
|
|
a32ea1e793 | ||
|
|
f67f2692d4 | ||
|
|
3b745f7154 | ||
|
|
d876d3c4df | ||
|
|
e8b0c52806 | ||
|
|
5bd7518343 | ||
|
|
51265f3f7d | ||
|
|
2e4932f23b | ||
|
|
dbd0bc8a2c | ||
|
|
e5627ec649 | ||
|
|
5c8fd3158d | ||
|
|
d5843944cc | ||
|
|
f62be85576 | ||
|
|
f1bd63046e | ||
|
|
ed6c951a19 | ||
|
|
ad9e7a6d87 | ||
|
|
6f7b26b1a8 | ||
|
|
ecd6009a5e | ||
|
|
6ffe30d9ba | ||
|
|
8f5a0aaacb | ||
|
|
ba3b04e7fe | ||
|
|
379d55044e | ||
|
|
843a116155 | ||
|
|
1c6202c414 | ||
|
|
066a2b022d | ||
|
|
aca41b0beb | ||
|
|
b5e8ab6c15 | ||
|
|
896c8a9f72 | ||
|
|
59ecea3d8c | ||
|
|
b1f8ce8769 | ||
|
|
8c43d83689 | ||
|
|
87d44bbfcd | ||
|
|
07d3b3330d | ||
|
|
61349cf124 | ||
|
|
7316b26740 | ||
|
|
d4b3a006dc | ||
|
|
2f8886794f | ||
|
|
02ab8c91a9 | ||
|
|
74ea1e43ca | ||
|
|
e9000658fb | ||
|
|
d58e0f1a1a | ||
|
|
674c4ed080 | ||
|
|
a68d6f1a9a | ||
|
|
c0643e21ed | ||
|
|
3fbb84f950 | ||
|
|
053f5aa10d | ||
|
|
6b9264b49e | ||
|
|
e60f9bb24f | ||
|
|
1bb6e7f52d | ||
|
|
108ca1521e | ||
|
|
ea2bb9cd5b | ||
|
|
e6d05db86f | ||
|
|
d1f920a7d1 | ||
|
|
fee64d7515 | ||
|
|
aad77fcacb | ||
|
|
bebf072b77 | ||
|
|
7f53f7ced4 | ||
|
|
91a4d59eb4 | ||
|
|
1bd34ea364 | ||
|
|
a9a215c52e | ||
|
|
5cea646b12 | ||
|
|
ff14bbb3c1 | ||
|
|
89be04ce7a | ||
|
|
4b3c59e4cc | ||
|
|
beeb300c18 | ||
|
|
79732693f3 | ||
|
|
ef3d12c60e | ||
|
|
608a2f9741 | ||
|
|
174cc87227 | ||
|
|
0d6d8922f2 | ||
|
|
67350e3c01 | ||
|
|
1a6455bc25 | ||
|
|
e1528e084d | ||
|
|
1892f445e2 | ||
|
|
484f0fbafa | ||
|
|
5378fd84df | ||
|
|
9d8b8d9c69 | ||
|
|
cd91647999 | ||
|
|
5cc46d7989 | ||
|
|
fe4395336a | ||
|
|
9d97a467ca | ||
|
|
039056370d | ||
|
|
159e31b689 | ||
|
|
17c60d2728 | ||
|
|
52e75369c1 | ||
|
|
66706f469d | ||
|
|
98d1cb1c00 | ||
|
|
1940cae827 | ||
|
|
d184463e2a | ||
|
|
3b53b6e481 | ||
|
|
78ee1ee2cf | ||
|
|
422623a87b | ||
|
|
4aa6df7633 | ||
|
|
2d2336014c | ||
|
|
def427bcaf | ||
|
|
ba3a39957d | ||
|
|
f58324b576 | ||
|
|
205cd7c1f6 | ||
|
|
398333da9a | ||
|
|
e678219bdf | ||
|
|
830217ac78 | ||
|
|
e4db22d9f5 | ||
|
|
c8e9772cd0 | ||
|
|
437b11f869 | ||
|
|
b7bee87fb5 | ||
|
|
2f3ef94ad4 | ||
|
|
7154e51ff2 | ||
|
|
db46863f75 | ||
|
|
ebb0dc14a7 | ||
|
|
368128a647 | ||
|
|
bc25863d1b | ||
|
|
130f947037 |
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -2,3 +2,9 @@
|
||||
*.txt text
|
||||
*.c text
|
||||
*.h text
|
||||
|
||||
# For git archive
|
||||
.gitignore export-ignore
|
||||
.gitattributes export-ignore
|
||||
.travis.yml export-ignore
|
||||
.vscode export-ignore
|
||||
|
||||
55
CHANGELOG
55
CHANGELOG
@@ -6,6 +6,61 @@ HISTORY
|
||||
|
||||
* [Enter new changes just after this line - do not remove this line]
|
||||
|
||||
(STABLE-2.1.2):
|
||||
|
||||
++ Bugfixes:
|
||||
|
||||
2018-11-21: Jens Nielsen
|
||||
* netbiosns.c: fix expecting too large packet (bug #55069)
|
||||
|
||||
2018-11-19: Dirk Ziegelmeier
|
||||
* smtp.c: fix compiling with strict C compatibility because of strnlen (bug #55034)
|
||||
|
||||
2018-11-12: Simon Goldschmidt
|
||||
* tcp.c: fix overflow check in tcp_recved triggering invalid assertion (bug #55015)
|
||||
|
||||
2018-11-12: Simon Goldschmidt
|
||||
* tcp.c: fix a bug in sending RST segments (sent from port 0)
|
||||
|
||||
(STABLE-2.1.1):
|
||||
|
||||
++ Bugfixes:
|
||||
|
||||
2018-11-01: Joan Lledó
|
||||
* sockets.c: fix bad assertion in lwip_poll_dec_sockets_used() (bug #54933)
|
||||
|
||||
2018-11-01: Dirk Ziegelmeier
|
||||
* ip4.c: don't send 127.* to default netif (bug #54670)
|
||||
|
||||
2018-10-23: David Girault
|
||||
* altcp_tls_mbedtls.c: fix use-after free (bug #54774)
|
||||
|
||||
2018-10-23: Ognjen Bjelica, Dirk Ziegelmeier
|
||||
* snmp_scalar.c: Avoid NULL pointer dereference (bug #54886)
|
||||
|
||||
2018-10-23: Simon Goldschmidt
|
||||
* Fix missing standard includes in multiple files
|
||||
|
||||
2018-10-17: Ivan Warren
|
||||
* def.h: fix casting htonX and ntohX to u16_t (bug #54850)
|
||||
|
||||
2018-10-12: Simon Goldschmidt
|
||||
* Revert "tcp_abandon: no need to buffer pcb->local_port" (fix that source port was 0 for RST
|
||||
called when aborting a connection)
|
||||
|
||||
2018-10-11: Jonas Rabenstein
|
||||
* tcp.c: tcp_recved: check for overflow and warn about too big values (patch #9699)
|
||||
|
||||
2018-10-06: Joan Lledó
|
||||
* sockets.c: alloc_socket(): Check for LWIP_SOCKET_POLL when setting select-
|
||||
related variables (patch #9696)
|
||||
|
||||
2018-10-04: Spencer
|
||||
* tcp.c: Update prev pointer when skipping entries in tcp_slowtmr (patch #9694)
|
||||
|
||||
2018-09-27: Martine Lenders
|
||||
* lowpan6.c: Fix IEEE 802.15.4 address setting (bug #54749)
|
||||
|
||||
(STABLE-2.1.0):
|
||||
|
||||
++ New features:
|
||||
|
||||
@@ -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.1.0"
|
||||
PROJECT_NUMBER = "2.1.3"
|
||||
|
||||
# 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
|
||||
|
||||
@@ -204,6 +204,15 @@
|
||||
* Read especially sections "Cache coherency" and "Buffer alignment".
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page mem_err Debugging memory pool sizes
|
||||
* If you have issues with lwIP and you are using memory pools, check that your pools
|
||||
* are correctly sized.\n
|
||||
* To debug pool sizes, \#define LWIP_STATS and MEMP_STATS to 1. Check the global variable
|
||||
* lwip_stats.memp[] using a debugger. If the "err" member of a pool is > 0, the pool
|
||||
* may be too small for your application and you need to increase its size.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page bugs Reporting bugs
|
||||
* Please report bugs in the lwIP bug tracker at savannah.\n
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
set(LWIP_VERSION_MAJOR "2")
|
||||
set(LWIP_VERSION_MINOR "1")
|
||||
set(LWIP_VERSION_REVISION "0")
|
||||
set(LWIP_VERSION_REVISION "3")
|
||||
# LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases
|
||||
# LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions
|
||||
# Numbers 1..31 are reserved for release candidates
|
||||
|
||||
@@ -201,16 +201,16 @@ netconn_prepare_delete(struct netconn *conn)
|
||||
|
||||
API_MSG_VAR_ALLOC(msg);
|
||||
API_MSG_VAR_REF(msg).conn = conn;
|
||||
#if LWIP_TCP
|
||||
#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
|
||||
/* get the time we started, which is later compared to
|
||||
sys_now() + conn->send_timeout */
|
||||
API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
|
||||
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
|
||||
#if LWIP_TCP
|
||||
API_MSG_VAR_REF(msg).msg.sd.polls_left =
|
||||
((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
|
||||
#endif /* LWIP_TCP */
|
||||
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
|
||||
#endif /* LWIP_TCP */
|
||||
err = netconn_apimsg(lwip_netconn_do_delconn, &API_MSG_VAR_REF(msg));
|
||||
API_MSG_VAR_FREE(msg);
|
||||
|
||||
@@ -500,7 +500,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
||||
|
||||
NETCONN_MBOX_WAITING_INC(conn);
|
||||
if (netconn_is_nonblocking(conn)) {
|
||||
if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_ARCH_TIMEOUT) {
|
||||
if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_MBOX_EMPTY) {
|
||||
API_MSG_VAR_FREE_ACCEPT(msg);
|
||||
NETCONN_MBOX_WAITING_DEC(conn);
|
||||
return ERR_WOULDBLOCK;
|
||||
@@ -597,7 +597,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
|
||||
NETCONN_MBOX_WAITING_INC(conn);
|
||||
if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) ||
|
||||
(conn->flags & NETCONN_FLAG_MBOXCLOSED) || (conn->pending_err != ERR_OK)) {
|
||||
if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_ARCH_TIMEOUT) {
|
||||
if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_MBOX_EMPTY) {
|
||||
err_t err;
|
||||
NETCONN_MBOX_WAITING_DEC(conn);
|
||||
err = netconn_err(conn);
|
||||
@@ -1346,7 +1346,7 @@ void
|
||||
netconn_thread_init(void)
|
||||
{
|
||||
sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
|
||||
if ((sem == NULL) || !sys_sem_valid(sem)) {
|
||||
if (!sys_sem_valid(sem)) {
|
||||
/* call alloc only once */
|
||||
LWIP_NETCONN_THREAD_SEM_ALLOC();
|
||||
LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET()));
|
||||
@@ -1357,7 +1357,7 @@ void
|
||||
netconn_thread_cleanup(void)
|
||||
{
|
||||
sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
|
||||
if ((sem != NULL) && sys_sem_valid(sem)) {
|
||||
if (sys_sem_valid(sem)) {
|
||||
/* call free only once */
|
||||
LWIP_NETCONN_THREAD_SEM_FREE();
|
||||
}
|
||||
|
||||
@@ -716,6 +716,9 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
||||
conn->pending_err = ERR_OK;
|
||||
conn->type = t;
|
||||
conn->pcb.tcp = NULL;
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
conn->mbox_threads_waiting = 0;
|
||||
#endif
|
||||
|
||||
/* If all sizes are the same, every compiler should optimize this switch to nothing */
|
||||
switch (NETCONNTYPE_GROUP(t)) {
|
||||
|
||||
@@ -128,8 +128,7 @@ lwip_gethostbyname(const char *name)
|
||||
if (s_hostent.h_addr_list != NULL) {
|
||||
u8_t idx;
|
||||
for (idx = 0; s_hostent.h_addr_list[idx]; idx++) {
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa(s_phostent_addr[idx])));
|
||||
}
|
||||
}
|
||||
#endif /* DNS_DEBUG */
|
||||
@@ -306,7 +305,11 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
|
||||
/* service name specified: convert to port number
|
||||
* @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */
|
||||
port_nr = atoi(servname);
|
||||
if ((port_nr <= 0) || (port_nr > 0xffff)) {
|
||||
if (port_nr == 0 && (servname[0] != '0')) {
|
||||
/* atoi failed - service was not numeric */
|
||||
return EAI_SERVICE;
|
||||
}
|
||||
if ((port_nr < 0) || (port_nr > 0xffff)) {
|
||||
return EAI_SERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,14 +522,14 @@ alloc_socket(struct netconn *newconn, int accepted)
|
||||
after having marked it as used. */
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
sockets[i].lastdata.pbuf = NULL;
|
||||
#if LWIP_SOCKET_SELECT
|
||||
#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
|
||||
LWIP_ASSERT("sockets[i].select_waiting == 0", sockets[i].select_waiting == 0);
|
||||
sockets[i].rcvevent = 0;
|
||||
/* TCP sendbuf is empty, but the socket is not yet writable until connected
|
||||
* (unless it has been created by accept()). */
|
||||
sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
|
||||
sockets[i].errevent = 0;
|
||||
#endif /* LWIP_SOCKET_SELECT */
|
||||
#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
|
||||
return i + LWIP_SOCKET_OFFSET;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
@@ -688,7 +688,6 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
||||
err = netconn_peer(newconn, &naddr, &port);
|
||||
if (err != ERR_OK) {
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err));
|
||||
netconn_delete(newconn);
|
||||
free_socket(nsock, 1);
|
||||
sock_set_errno(sock, err_to_errno(err));
|
||||
done_socket(sock);
|
||||
@@ -1305,7 +1304,7 @@ lwip_recvmsg(int s, struct msghdr *message, int flags)
|
||||
if ((message->msg_iov[i].iov_base == NULL) || ((ssize_t)message->msg_iov[i].iov_len <= 0) ||
|
||||
((size_t)(ssize_t)message->msg_iov[i].iov_len != message->msg_iov[i].iov_len) ||
|
||||
((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) {
|
||||
sock_set_errno(sock, ERR_VAL);
|
||||
sock_set_errno(sock, err_to_errno(ERR_VAL));
|
||||
done_socket(sock);
|
||||
return -1;
|
||||
}
|
||||
@@ -2073,7 +2072,9 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
/* Call lwip_selscan again: there could have been events between
|
||||
the last scan (without us on the list) and putting us on the list! */
|
||||
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
|
||||
if (!nready) {
|
||||
if (nready < 0) {
|
||||
set_errno(EBADF);
|
||||
} else if (!nready) {
|
||||
/* Still none ready, just wait to be woken */
|
||||
if (timeout == 0) {
|
||||
/* Wait forever */
|
||||
@@ -2102,7 +2103,8 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
(exceptset && FD_ISSET(i, exceptset))) {
|
||||
struct lwip_sock *sock;
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
sock = tryget_socket_unconn_locked(i);
|
||||
sock = tryget_socket_unconn_nouse(i);
|
||||
LWIP_ASSERT("socket gone at the end of select", sock != NULL);
|
||||
if (sock != NULL) {
|
||||
/* for now, handle select_waiting==0... */
|
||||
LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
|
||||
@@ -2110,7 +2112,6 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
sock->select_waiting--;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
done_socket(sock);
|
||||
} else {
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
/* Not a valid socket */
|
||||
@@ -2147,6 +2148,11 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
/* See what's set now after waiting */
|
||||
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
|
||||
if (nready < 0) {
|
||||
set_errno(EBADF);
|
||||
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2304,7 +2310,6 @@ lwip_poll_dec_sockets_used(struct pollfd *fds, nfds_t nfds)
|
||||
/* Go through each struct pollfd in the array. */
|
||||
for (fdi = 0; fdi < nfds; fdi++) {
|
||||
struct lwip_sock *sock = tryget_socket_unconn_nouse(fds[fdi].fd);
|
||||
LWIP_ASSERT("socket gone at the end of select", sock != NULL);
|
||||
if (sock != NULL) {
|
||||
done_socket(sock);
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ tcpip_thread_poll_one(void)
|
||||
int ret = 0;
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_ARCH_TIMEOUT) {
|
||||
if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_MBOX_EMPTY) {
|
||||
LOCK_TCPIP_CORE();
|
||||
if (msg != NULL) {
|
||||
tcpip_thread_handle_msg(msg);
|
||||
|
||||
@@ -40,17 +40,13 @@
|
||||
* track of the ratio of application data and TLS overhead would be too much.
|
||||
*
|
||||
* Mandatory security-related configuration:
|
||||
* - define ALTCP_MBEDTLS_RNG_FN to a custom GOOD rng function returning 0 on success:
|
||||
* int my_rng_fn(void *ctx, unsigned char *buffer , size_t len)
|
||||
* - ensure to add at least one strong entropy source to your mbedtls port (implement
|
||||
* mbedtls_platform_entropy_poll or mbedtls_hardware_poll providing strong entropy)
|
||||
* - define ALTCP_MBEDTLS_ENTROPY_PTR and ALTCP_MBEDTLS_ENTROPY_LEN to something providing
|
||||
* GOOD custom entropy
|
||||
*
|
||||
* Missing things / @todo:
|
||||
* - RX data is acknowledged after receiving (tcp_recved is called when enqueueing
|
||||
* the pbuf for mbedTLS receive, not when processed by mbedTLS or the inner
|
||||
* connection; altcp_recved() from inner connection does nothing)
|
||||
* - Client connections starting with 'connect()' are not handled yet...
|
||||
* - some unhandled things are caught by LWIP_ASSERTs...
|
||||
* - some unhandled/untested things migh be caught by LWIP_ASSERTs...
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
@@ -80,6 +76,7 @@
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/memory_buffer_alloc.h"
|
||||
#include "mbedtls/ssl_cache.h"
|
||||
#include "mbedtls/ssl_ticket.h"
|
||||
|
||||
#include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */
|
||||
|
||||
@@ -99,17 +96,30 @@ extern const struct altcp_functions altcp_mbedtls_functions;
|
||||
/** Our global mbedTLS configuration (server-specific, not connection-specific) */
|
||||
struct altcp_tls_config {
|
||||
mbedtls_ssl_config conf;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_x509_crt *cert;
|
||||
mbedtls_pk_context *pkey;
|
||||
uint8_t cert_count;
|
||||
uint8_t cert_max;
|
||||
uint8_t pkey_count;
|
||||
uint8_t pkey_max;
|
||||
mbedtls_x509_crt *ca;
|
||||
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
|
||||
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
|
||||
/** Inter-connection cache for fast connection startup */
|
||||
struct mbedtls_ssl_cache_context cache;
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS
|
||||
mbedtls_ssl_ticket_context ticket_ctx;
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Entropy and random generator are shared by all mbedTLS configuration */
|
||||
struct altcp_tls_entropy_rng {
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
int ref;
|
||||
};
|
||||
static struct altcp_tls_entropy_rng *altcp_tls_entropy_rng;
|
||||
|
||||
static err_t altcp_mbedtls_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err);
|
||||
static err_t altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn);
|
||||
static err_t altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *state);
|
||||
@@ -309,17 +319,20 @@ altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
|
||||
LWIP_ASSERT("state != NULL", state != NULL);
|
||||
buf = state->rx_app;
|
||||
if (buf) {
|
||||
state->rx_app = NULL;
|
||||
if (conn->recv) {
|
||||
u16_t tot_len = state->rx_app->tot_len;
|
||||
u16_t tot_len = buf->tot_len;
|
||||
/* this needs to be increased first because the 'recved' call may come nested */
|
||||
state->rx_passed_unrecved += tot_len;
|
||||
state->flags |= ALTCP_MBEDTLS_FLAGS_UPPER_CALLED;
|
||||
err = conn->recv(conn->arg, conn, state->rx_app, ERR_OK);
|
||||
err = conn->recv(conn->arg, conn, buf, ERR_OK);
|
||||
if (err != ERR_OK) {
|
||||
if (err == ERR_ABRT) {
|
||||
return ERR_ABRT;
|
||||
}
|
||||
/* not received, leave the pbuf(s) queued (and decrease 'unrecved' again) */
|
||||
LWIP_ASSERT("state == conn->state", state == conn->state);
|
||||
state->rx_app = buf;
|
||||
state->rx_passed_unrecved -= tot_len;
|
||||
LWIP_ASSERT("state->rx_passed_unrecved >= 0", state->rx_passed_unrecved >= 0);
|
||||
if (state->rx_passed_unrecved < 0) {
|
||||
@@ -330,7 +343,6 @@ altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
|
||||
} else {
|
||||
pbuf_free(buf);
|
||||
}
|
||||
state->rx_app = NULL;
|
||||
} else if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) ==
|
||||
ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) {
|
||||
state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSED;
|
||||
@@ -339,6 +351,11 @@ altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
|
||||
}
|
||||
}
|
||||
|
||||
/* application may have close the connection */
|
||||
if (conn->state != state) {
|
||||
/* return error code to ensure altcp_mbedtls_handle_rx_appldata() exits the loop */
|
||||
return ERR_CLSD;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@@ -444,6 +461,7 @@ altcp_mbedtls_bio_recv(void *ctx, unsigned char *buf, size_t len)
|
||||
return MBEDTLS_ERR_NET_INVALID_CONTEXT;
|
||||
}
|
||||
state = (altcp_mbedtls_state_t *)conn->state;
|
||||
LWIP_ASSERT("state != NULL", state != NULL);
|
||||
p = state->rx;
|
||||
|
||||
/* @todo: return MBEDTLS_ERR_NET_CONN_RESET/MBEDTLS_ERR_NET_RECV_FAILED? */
|
||||
@@ -631,40 +649,26 @@ altcp_tls_context(struct altcp_pcb *conn)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if ALTCP_MBEDTLS_DEBUG != LWIP_DBG_OFF
|
||||
#if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF
|
||||
static void
|
||||
altcp_mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str)
|
||||
{
|
||||
LWIP_UNUSED_ARG(str);
|
||||
LWIP_UNUSED_ARG(level);
|
||||
LWIP_UNUSED_ARG(ctx);
|
||||
LWIP_UNUSED_ARG(file);
|
||||
LWIP_UNUSED_ARG(line);
|
||||
LWIP_UNUSED_ARG(ctx);
|
||||
/* @todo: output debug string :-) */
|
||||
LWIP_UNUSED_ARG(str);
|
||||
|
||||
if (level >= ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_LIB_DEBUG, ("%s:%04d: %s", file, line, str));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ALTCP_MBEDTLS_RNG_FN
|
||||
/** ATTENTION: It is *really* important to *NOT* use this dummy RNG in production code!!!! */
|
||||
static int
|
||||
dummy_rng(void *ctx, unsigned char *buffer, size_t len)
|
||||
{
|
||||
static size_t ctr;
|
||||
size_t i;
|
||||
LWIP_UNUSED_ARG(ctx);
|
||||
for (i = 0; i < len; i++) {
|
||||
buffer[i] = (unsigned char)++ctr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#define ALTCP_MBEDTLS_RNG_FN dummy_rng
|
||||
#endif /* ALTCP_MBEDTLS_RNG_FN */
|
||||
|
||||
/** Create new TLS configuration
|
||||
* ATTENTION: Server certificate and private key have to be added outside this function!
|
||||
*/
|
||||
static struct altcp_tls_config *
|
||||
altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca)
|
||||
altcp_tls_create_config(int is_server, uint8_t cert_count, uint8_t pkey_count, int have_ca)
|
||||
{
|
||||
size_t sz;
|
||||
int ret;
|
||||
@@ -679,43 +683,62 @@ altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca
|
||||
altcp_mbedtls_mem_init();
|
||||
|
||||
sz = sizeof(struct altcp_tls_config);
|
||||
if (have_cert) {
|
||||
sz += sizeof(mbedtls_x509_crt);
|
||||
if (cert_count > 0) {
|
||||
sz += (cert_count * sizeof(mbedtls_x509_crt));
|
||||
}
|
||||
if (have_ca) {
|
||||
sz += sizeof(mbedtls_x509_crt);
|
||||
}
|
||||
if (have_pkey) {
|
||||
sz += sizeof(mbedtls_pk_context);
|
||||
if (pkey_count > 0) {
|
||||
sz += (pkey_count * sizeof(mbedtls_pk_context));
|
||||
}
|
||||
|
||||
conf = (struct altcp_tls_config *)altcp_mbedtls_alloc_config(sz);
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
conf->cert_max = cert_count;
|
||||
mem = (mbedtls_x509_crt *)(conf + 1);
|
||||
if (have_cert) {
|
||||
if (cert_count > 0) {
|
||||
conf->cert = mem;
|
||||
mem++;
|
||||
mem += cert_count;
|
||||
}
|
||||
if (have_ca) {
|
||||
conf->ca = mem;
|
||||
mem++;
|
||||
}
|
||||
if (have_pkey) {
|
||||
conf->pkey_max = pkey_count;
|
||||
if (pkey_count > 0) {
|
||||
conf->pkey = (mbedtls_pk_context *)mem;
|
||||
}
|
||||
|
||||
mbedtls_ssl_config_init(&conf->conf);
|
||||
mbedtls_entropy_init(&conf->entropy);
|
||||
mbedtls_ctr_drbg_init(&conf->ctr_drbg);
|
||||
|
||||
/* Seed the RNG */
|
||||
ret = mbedtls_ctr_drbg_seed(&conf->ctr_drbg, ALTCP_MBEDTLS_RNG_FN, &conf->entropy, ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret));
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
if (!altcp_tls_entropy_rng) {
|
||||
altcp_tls_entropy_rng = (struct altcp_tls_entropy_rng *)altcp_mbedtls_alloc_config(sizeof(struct altcp_tls_entropy_rng));
|
||||
if (altcp_tls_entropy_rng) {
|
||||
altcp_tls_entropy_rng->ref = 1;
|
||||
mbedtls_entropy_init(&altcp_tls_entropy_rng->entropy);
|
||||
mbedtls_ctr_drbg_init(&altcp_tls_entropy_rng->ctr_drbg);
|
||||
/* Seed the RNG, only once */
|
||||
ret = mbedtls_ctr_drbg_seed(&altcp_tls_entropy_rng->ctr_drbg,
|
||||
mbedtls_entropy_func, &altcp_tls_entropy_rng->entropy,
|
||||
ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret));
|
||||
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
|
||||
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
|
||||
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
|
||||
altcp_tls_entropy_rng = NULL;
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
altcp_tls_entropy_rng->ref++;
|
||||
}
|
||||
|
||||
/* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */
|
||||
@@ -723,24 +746,105 @@ altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_config_defaults failed: %d\n", ret));
|
||||
if (altcp_tls_entropy_rng->ref == 1) {
|
||||
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
|
||||
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
|
||||
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
|
||||
altcp_tls_entropy_rng = NULL;
|
||||
}
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
}
|
||||
mbedtls_ssl_conf_authmode(&conf->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
|
||||
mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &conf->ctr_drbg);
|
||||
#if ALTCP_MBEDTLS_DEBUG != LWIP_DBG_OFF
|
||||
mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg);
|
||||
#if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF
|
||||
mbedtls_ssl_conf_dbg(&conf->conf, altcp_mbedtls_debug, stdout);
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
|
||||
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
|
||||
mbedtls_ssl_conf_session_cache(&conf->conf, &conf->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set);
|
||||
mbedtls_ssl_cache_set_timeout(&conf->cache, 30);
|
||||
mbedtls_ssl_cache_set_max_entries(&conf->cache, 30);
|
||||
mbedtls_ssl_cache_set_timeout(&conf->cache, ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS);
|
||||
mbedtls_ssl_cache_set_max_entries(&conf->cache, ALTCP_MBEDTLS_SESSION_CACHE_SIZE);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS
|
||||
mbedtls_ssl_ticket_init(&conf->ticket_ctx);
|
||||
|
||||
ret = mbedtls_ssl_ticket_setup(&conf->ticket_ctx, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg,
|
||||
ALTCP_MBEDTLS_SESSION_TICKET_CIPHER, ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS);
|
||||
if (ret) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_ticket_setup failed: %d\n", ret));
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_session_tickets_cb(&conf->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse,
|
||||
&conf->ticket_ctx);
|
||||
#endif
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
struct altcp_tls_config *altcp_tls_create_config_server(uint8_t cert_count)
|
||||
{
|
||||
struct altcp_tls_config *conf = altcp_tls_create_config(1, cert_count, cert_count, 0);
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_ca_chain(&conf->conf, NULL, NULL);
|
||||
return conf;
|
||||
}
|
||||
|
||||
err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config,
|
||||
const u8_t *privkey, size_t privkey_len,
|
||||
const u8_t *privkey_pass, size_t privkey_pass_len,
|
||||
const u8_t *cert, size_t cert_len)
|
||||
{
|
||||
int ret;
|
||||
mbedtls_x509_crt *srvcert;
|
||||
mbedtls_pk_context *pkey;
|
||||
|
||||
if (config->cert_count >= config->cert_max) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
if (config->pkey_count >= config->pkey_max) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
srvcert = config->cert + config->cert_count;
|
||||
mbedtls_x509_crt_init(srvcert);
|
||||
|
||||
pkey = config->pkey + config->pkey_count;
|
||||
mbedtls_pk_init(pkey);
|
||||
|
||||
/* Load the certificates and private key */
|
||||
ret = mbedtls_x509_crt_parse(srvcert, cert, cert_len);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d\n", ret));
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
|
||||
mbedtls_x509_crt_free(srvcert);
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_conf_own_cert(&config->conf, srvcert, pkey);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d\n", ret));
|
||||
mbedtls_x509_crt_free(srvcert);
|
||||
mbedtls_pk_free(pkey);
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
config->cert_count++;
|
||||
config->pkey_count++;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/** Create new TLS configuration
|
||||
* This is a suboptimal version that gets the encrypted private key and its password,
|
||||
* as well as the server certificate.
|
||||
@@ -750,45 +854,17 @@ altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_
|
||||
const u8_t *privkey_pass, size_t privkey_pass_len,
|
||||
const u8_t *cert, size_t cert_len)
|
||||
{
|
||||
int ret;
|
||||
mbedtls_x509_crt *srvcert;
|
||||
mbedtls_pk_context *pkey;
|
||||
struct altcp_tls_config *conf = altcp_tls_create_config(1, 1, 1, 0);
|
||||
struct altcp_tls_config *conf = altcp_tls_create_config_server(1);
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
srvcert = conf->cert;
|
||||
mbedtls_x509_crt_init(srvcert);
|
||||
|
||||
pkey = conf->pkey;
|
||||
mbedtls_pk_init(pkey);
|
||||
|
||||
/* Load the certificates and private key */
|
||||
ret = mbedtls_x509_crt_parse(srvcert, cert, cert_len);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d\n", ret));
|
||||
if (altcp_tls_config_server_add_privkey_cert(conf, privkey, privkey_len,
|
||||
privkey_pass, privkey_pass_len, cert, cert_len) != ERR_OK) {
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
|
||||
mbedtls_x509_crt_free(srvcert);
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_ca_chain(&conf->conf, srvcert->next, NULL);
|
||||
ret = mbedtls_ssl_conf_own_cert(&conf->conf, srvcert, pkey);
|
||||
if (ret != 0) {
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d\n", ret));
|
||||
mbedtls_x509_crt_free(srvcert);
|
||||
mbedtls_pk_free(pkey);
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
}
|
||||
return conf;
|
||||
}
|
||||
|
||||
@@ -796,7 +872,7 @@ static struct altcp_tls_config *
|
||||
altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth)
|
||||
{
|
||||
int ret;
|
||||
struct altcp_tls_config *conf = altcp_tls_create_config(0, is_2wayauth, is_2wayauth, ca != NULL);
|
||||
struct altcp_tls_config *conf = altcp_tls_create_config(0, (is_2wayauth) ? 1 : 0, (is_2wayauth) ? 1 : 0, ca != NULL);
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -880,8 +956,21 @@ altcp_tls_free_config(struct altcp_tls_config *conf)
|
||||
}
|
||||
if (conf->ca) {
|
||||
mbedtls_x509_crt_free(conf->ca);
|
||||
}
|
||||
}
|
||||
altcp_mbedtls_free_config(conf);
|
||||
if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref)
|
||||
altcp_tls_entropy_rng->ref--;
|
||||
}
|
||||
|
||||
void
|
||||
altcp_tls_free_entropy(void)
|
||||
{
|
||||
if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref == 0) {
|
||||
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
|
||||
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
|
||||
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
|
||||
altcp_tls_entropy_rng = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* "virtual" functions */
|
||||
@@ -938,6 +1027,11 @@ altcp_mbedtls_listen(struct altcp_pcb *conn, u8_t backlog, err_t *err)
|
||||
}
|
||||
lpcb = altcp_listen_with_backlog_and_err(conn->inner_conn, backlog, err);
|
||||
if (lpcb != NULL) {
|
||||
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
|
||||
/* Free members of the ssl context (not used on listening pcb). This
|
||||
includes freeing input/output buffers, so saves ~32KByte by default */
|
||||
mbedtls_ssl_free(&state->ssl_context);
|
||||
|
||||
conn->inner_conn = lpcb;
|
||||
altcp_accept(lpcb, altcp_mbedtls_lower_accept);
|
||||
return conn;
|
||||
@@ -1163,6 +1257,10 @@ const struct altcp_functions altcp_mbedtls_functions = {
|
||||
altcp_default_get_tcp_addrinfo,
|
||||
altcp_default_get_ip,
|
||||
altcp_default_get_port
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
, altcp_default_keepalive_disable
|
||||
, altcp_default_keepalive_enable
|
||||
#endif
|
||||
#ifdef LWIP_DEBUG
|
||||
, altcp_default_dbg_get_tcp_state
|
||||
#endif
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/init.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/** This string is passed in the HTTP header as "User-Agent: " */
|
||||
#ifndef ALTCP_PROXYCONNECT_CLIENT_AGENT
|
||||
#define ALTCP_PROXYCONNECT_CLIENT_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)"
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "lwip/init.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if LWIP_TCP && LWIP_CALLBACK_API
|
||||
|
||||
@@ -1301,6 +1301,22 @@ http_send_data_ssi(struct altcp_pcb *pcb, struct http_state *hs)
|
||||
ssi->tag_state = TAG_NONE;
|
||||
}
|
||||
|
||||
#if LWIP_HTTPD_DYNAMIC_FILE_READ && !LWIP_HTTPD_SSI_INCLUDE_TAG
|
||||
if ((ssi->tag_state == TAG_NONE) &&
|
||||
(ssi->parsed - hs->file < ssi->tag_index)) {
|
||||
for(u16_t i = 0;i < ssi->tag_index;i++) {
|
||||
ssi->tag_insert[i] = http_ssi_tag_desc[ssi->tag_type].lead_in[i];
|
||||
}
|
||||
ssi->tag_insert_len = ssi->tag_index;
|
||||
hs->file += ssi->parsed - hs->file;
|
||||
hs->left -= ssi->parsed - hs->file;
|
||||
ssi->tag_end = hs->file;
|
||||
ssi->tag_index = 0;
|
||||
ssi->tag_state = TAG_SENDING;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Move on to the next character in the buffer */
|
||||
ssi->parse_left--;
|
||||
ssi->parsed++;
|
||||
|
||||
@@ -664,25 +664,24 @@ mqtt_incomming_suback(struct mqtt_request_t *r, u8_t result)
|
||||
/**
|
||||
* Complete MQTT message received or buffer full
|
||||
* @param client MQTT client
|
||||
* @param fixed_hdr_idx header index
|
||||
* @param fixed_hdr_len length of fixed header
|
||||
* @param length length received part
|
||||
* @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_len, u16_t length, u32_t remaining_length)
|
||||
{
|
||||
mqtt_connection_status_t res = MQTT_CONNECT_ACCEPTED;
|
||||
|
||||
u8_t *var_hdr_payload = client->rx_buffer + fixed_hdr_idx;
|
||||
size_t var_hdr_payload_bufsize = sizeof(client->rx_buffer) - fixed_hdr_idx;
|
||||
u8_t *var_hdr_payload = client->rx_buffer + fixed_hdr_len;
|
||||
size_t var_hdr_payload_bufsize = sizeof(client->rx_buffer) - fixed_hdr_len;
|
||||
|
||||
/* Control packet type */
|
||||
u8_t pkt_type = MQTT_CTL_PACKET_TYPE(client->rx_buffer[0]);
|
||||
u16_t pkt_id = 0;
|
||||
|
||||
LWIP_ASSERT("client->msg_idx < MQTT_VAR_HEADER_BUFFER_LEN", client->msg_idx < MQTT_VAR_HEADER_BUFFER_LEN);
|
||||
LWIP_ASSERT("fixed_hdr_idx <= client->msg_idx", fixed_hdr_idx <= client->msg_idx);
|
||||
LWIP_ERROR("buffer length mismatch", fixed_hdr_idx + length <= MQTT_VAR_HEADER_BUFFER_LEN,
|
||||
LWIP_ASSERT("fixed_hdr_len <= client->msg_idx", fixed_hdr_len <= client->msg_idx);
|
||||
LWIP_ERROR("buffer length mismatch", fixed_hdr_len + length <= MQTT_VAR_HEADER_BUFFER_LEN,
|
||||
return MQTT_CONNECT_DISCONNECTED);
|
||||
|
||||
if (pkt_type == MQTT_MSG_TYPE_CONNACK) {
|
||||
@@ -773,7 +772,9 @@ mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u
|
||||
LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received short packet (payload)\n"));
|
||||
goto out_disconnect;
|
||||
}
|
||||
client->data_cb(client->inpub_arg, var_hdr_payload + payload_offset, payload_length, remaining_length == 0 ? MQTT_DATA_FLAG_LAST : 0);
|
||||
if (client->data_cb != NULL) {
|
||||
client->data_cb(client->inpub_arg, var_hdr_payload + payload_offset, payload_length, remaining_length == 0 ? MQTT_DATA_FLAG_LAST : 0);
|
||||
}
|
||||
/* Reply if QoS > 0 */
|
||||
if (remaining_length == 0 && qos > 0) {
|
||||
/* Send PUBACK for QoS 1 or PUBREC for QoS 2 */
|
||||
@@ -840,61 +841,59 @@ mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p)
|
||||
{
|
||||
u16_t in_offset = 0;
|
||||
u32_t msg_rem_len = 0;
|
||||
u8_t fixed_hdr_idx = 0;
|
||||
u8_t fixed_hdr_len = 0;
|
||||
u8_t b = 0;
|
||||
|
||||
while (p->tot_len > in_offset) {
|
||||
/* We ALWAYS parse the header here first. Even if the header was not
|
||||
included in this segment, we re-parse it here by buffering it in
|
||||
client->rx_buffer. client->msg_idx keeps track of this. */
|
||||
if ((fixed_hdr_idx < 2) || ((b & 0x80) != 0)) {
|
||||
if ((fixed_hdr_len < 2) || ((b & 0x80) != 0)) {
|
||||
|
||||
if (fixed_hdr_idx < client->msg_idx) {
|
||||
if (fixed_hdr_len < client->msg_idx) {
|
||||
/* parse header from old pbuf (buffered in client->rx_buffer) */
|
||||
b = client->rx_buffer[fixed_hdr_idx];
|
||||
b = client->rx_buffer[fixed_hdr_len];
|
||||
} else {
|
||||
/* parse header from this pbuf and save it in client->rx_buffer in case
|
||||
it comes in segmented */
|
||||
b = pbuf_get_at(p, in_offset++);
|
||||
client->rx_buffer[client->msg_idx++] = b;
|
||||
}
|
||||
fixed_hdr_idx++;
|
||||
fixed_hdr_len++;
|
||||
|
||||
if (fixed_hdr_idx >= 2) {
|
||||
if (fixed_hdr_len >= 2) {
|
||||
/* fixed header contains at least 2 bytes but can contain more, depending on
|
||||
'remaining length'. All bytes but the last of this have 0x80 set to
|
||||
indicate more bytes are coming. */
|
||||
msg_rem_len |= (u32_t)(b & 0x7f) << ((fixed_hdr_idx - 2) * 7);
|
||||
msg_rem_len |= (u32_t)(b & 0x7f) << ((fixed_hdr_len - 2) * 7);
|
||||
if ((b & 0x80) == 0) {
|
||||
/* fixed header is done */
|
||||
LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_parse_incoming: Remaining length after fixed header: %"U32_F"\n", msg_rem_len));
|
||||
if (msg_rem_len == 0) {
|
||||
/* Complete message with no extra headers of payload received */
|
||||
mqtt_message_received(client, fixed_hdr_idx, 0, 0);
|
||||
mqtt_message_received(client, fixed_hdr_len, 0, 0);
|
||||
client->msg_idx = 0;
|
||||
fixed_hdr_idx = 0;
|
||||
fixed_hdr_len = 0;
|
||||
} else {
|
||||
/* Bytes remaining in message (changes remaining length if this is
|
||||
not the first segment of this message) */
|
||||
msg_rem_len = (msg_rem_len + fixed_hdr_idx) - client->msg_idx;
|
||||
msg_rem_len = (msg_rem_len + fixed_hdr_len) - client->msg_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Fixed header has been parsed, parse variable header */
|
||||
u16_t cpy_len, cpy_start, buffer_space;
|
||||
|
||||
cpy_start = (client->msg_idx - fixed_hdr_idx) % (MQTT_VAR_HEADER_BUFFER_LEN - fixed_hdr_idx) + fixed_hdr_idx;
|
||||
u16_t cpy_len, buffer_space;
|
||||
|
||||
/* Allow to copy the lesser one of available length in input data or bytes remaining in message */
|
||||
cpy_len = (u16_t)LWIP_MIN((u16_t)(p->tot_len - in_offset), msg_rem_len);
|
||||
|
||||
/* Limit to available space in buffer */
|
||||
buffer_space = MQTT_VAR_HEADER_BUFFER_LEN - cpy_start;
|
||||
buffer_space = MQTT_VAR_HEADER_BUFFER_LEN - fixed_hdr_len;
|
||||
if (cpy_len > buffer_space) {
|
||||
cpy_len = buffer_space;
|
||||
}
|
||||
pbuf_copy_partial(p, client->rx_buffer + cpy_start, cpy_len, in_offset);
|
||||
pbuf_copy_partial(p, client->rx_buffer + fixed_hdr_len, cpy_len, in_offset);
|
||||
|
||||
/* Advance get and put indexes */
|
||||
client->msg_idx += cpy_len;
|
||||
@@ -904,7 +903,7 @@ mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p)
|
||||
LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_parse_incoming: msg_idx: %"U32_F", cpy_len: %"U16_F", remaining %"U32_F"\n", client->msg_idx, cpy_len, msg_rem_len));
|
||||
if ((msg_rem_len == 0) || (cpy_len == buffer_space)) {
|
||||
/* Whole message received or buffer is full */
|
||||
mqtt_connection_status_t res = mqtt_message_received(client, fixed_hdr_idx, (cpy_start + cpy_len) - fixed_hdr_idx, msg_rem_len);
|
||||
mqtt_connection_status_t res = mqtt_message_received(client, fixed_hdr_len, cpy_len, msg_rem_len);
|
||||
if (res != MQTT_CONNECT_ACCEPTED) {
|
||||
return res;
|
||||
}
|
||||
@@ -912,7 +911,7 @@ mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p)
|
||||
/* Reset parser state */
|
||||
client->msg_idx = 0;
|
||||
/* msg_tot_len = 0; */
|
||||
fixed_hdr_idx = 0;
|
||||
fixed_hdr_len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,22 @@ PACK_STRUCT_END
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
/** NetBIOS message question part */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct netbios_question_hdr {
|
||||
PACK_STRUCT_FLD_8(u8_t nametype);
|
||||
PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN * 2) + 1]);
|
||||
PACK_STRUCT_FIELD(u16_t type);
|
||||
PACK_STRUCT_FIELD(u16_t cls);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
/** NetBIOS message name part */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
@@ -224,12 +240,12 @@ static struct udp_pcb *netbiosns_pcb;
|
||||
|
||||
/** Decode a NetBIOS name (from packet to string) */
|
||||
static int
|
||||
netbiosns_name_decode(char *name_enc, char *name_dec, int name_dec_len)
|
||||
netbiosns_name_decode(const char *name_enc, char *name_dec, int name_dec_len)
|
||||
{
|
||||
char *pname;
|
||||
char cname;
|
||||
char cnbname;
|
||||
int idx = 0;
|
||||
const char *pname;
|
||||
char cname;
|
||||
char cnbname;
|
||||
int idx = 0;
|
||||
|
||||
LWIP_UNUSED_ARG(name_dec_len);
|
||||
|
||||
@@ -335,11 +351,11 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
|
||||
/* if packet is valid */
|
||||
if (p != NULL) {
|
||||
char netbios_name[NETBIOS_NAME_LEN + 1];
|
||||
struct netbios_hdr *netbios_hdr = (struct netbios_hdr *)p->payload;
|
||||
struct netbios_name_hdr *netbios_name_hdr = (struct netbios_name_hdr *)(netbios_hdr + 1);
|
||||
struct netbios_hdr *netbios_hdr = (struct netbios_hdr *)p->payload;
|
||||
struct netbios_question_hdr *netbios_question_hdr = (struct netbios_question_hdr *)(netbios_hdr + 1);
|
||||
|
||||
/* is the packet long enough (we need the header in one piece) */
|
||||
if (p->len < (sizeof(struct netbios_hdr) + sizeof(struct netbios_name_hdr))) {
|
||||
if (p->len < (sizeof(struct netbios_hdr) + sizeof(struct netbios_question_hdr))) {
|
||||
/* packet too short */
|
||||
pbuf_free(p);
|
||||
return;
|
||||
@@ -352,9 +368,9 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
|
||||
((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) &&
|
||||
(netbios_hdr->questions == PP_NTOHS(1))) {
|
||||
/* decode the NetBIOS name */
|
||||
netbiosns_name_decode((char *)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));
|
||||
netbiosns_name_decode((char *)(netbios_question_hdr->encname), netbios_name, sizeof(netbios_name));
|
||||
/* check the request type */
|
||||
if (netbios_name_hdr->type == PP_HTONS(NETB_QTYPE_NB)) {
|
||||
if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NB)) {
|
||||
/* if the packet is for us */
|
||||
if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) {
|
||||
struct pbuf *q;
|
||||
@@ -376,10 +392,10 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
|
||||
resp->resp_hdr.additionalRRs = 0;
|
||||
|
||||
/* prepare NetBIOS header datas */
|
||||
MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname));
|
||||
resp->resp_name.nametype = netbios_name_hdr->nametype;
|
||||
resp->resp_name.type = netbios_name_hdr->type;
|
||||
resp->resp_name.cls = netbios_name_hdr->cls;
|
||||
MEMCPY( resp->resp_name.encname, netbios_question_hdr->encname, sizeof(netbios_question_hdr->encname));
|
||||
resp->resp_name.nametype = netbios_question_hdr->nametype;
|
||||
resp->resp_name.type = netbios_question_hdr->type;
|
||||
resp->resp_name.cls = netbios_question_hdr->cls;
|
||||
resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL);
|
||||
resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags) + sizeof(resp->resp_name.addr));
|
||||
resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE);
|
||||
@@ -393,7 +409,7 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
|
||||
}
|
||||
}
|
||||
#if LWIP_NETBIOS_RESPOND_NAME_QUERY
|
||||
} else if (netbios_name_hdr->type == PP_HTONS(NETB_QTYPE_NBSTAT)) {
|
||||
} else if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NBSTAT)) {
|
||||
/* if the packet is for us or general query */
|
||||
if (!lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) ||
|
||||
!lwip_strnicmp(netbios_name, "*", sizeof(NETBIOS_LOCAL_NAME))) {
|
||||
@@ -419,9 +435,9 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
|
||||
/* resp->answer_hdr.authorityRRs = PP_HTONS(0); done by memset() */
|
||||
/* resp->answer_hdr.additionalRRs = PP_HTONS(0); done by memset() */
|
||||
/* we will copy the length of the station name */
|
||||
resp->name_size = netbios_name_hdr->nametype;
|
||||
resp->name_size = netbios_question_hdr->nametype;
|
||||
/* we will copy the queried name */
|
||||
MEMCPY(resp->query_name, netbios_name_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1);
|
||||
MEMCPY(resp->query_name, netbios_question_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1);
|
||||
/* NBSTAT */
|
||||
resp->packet_type = PP_HTONS(0x21);
|
||||
/* Internet name */
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
#include "lwip/altcp_tcp.h"
|
||||
#include "lwip/altcp_tls.h"
|
||||
|
||||
#include <string.h> /* strnlen, memcpy */
|
||||
#include <string.h> /* strlen, memcpy */
|
||||
#include <stdlib.h>
|
||||
|
||||
/** TCP poll interval. Unit is 0.5 sec. */
|
||||
@@ -353,9 +353,8 @@ smtp_set_server_addr(const char* server)
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
|
||||
if (server != NULL) {
|
||||
/* strnlen: returns length WITHOUT terminating 0 byte OR
|
||||
* SMTP_MAX_SERVERNAME_LEN+1 when string is too long */
|
||||
len = strnlen(server, SMTP_MAX_SERVERNAME_LEN+1);
|
||||
/* strlen: returns length WITHOUT terminating 0 byte */
|
||||
len = strlen(server);
|
||||
}
|
||||
if (len > SMTP_MAX_SERVERNAME_LEN) {
|
||||
return ERR_MEM;
|
||||
|
||||
@@ -193,28 +193,40 @@ snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, st
|
||||
static s16_t
|
||||
snmp_scalar_array_get_value(struct snmp_node_instance *instance, void *value)
|
||||
{
|
||||
s16_t result = -1;
|
||||
const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
|
||||
const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
|
||||
|
||||
return array_node->get_value(array_node_def, value);
|
||||
if (array_node->get_value != NULL) {
|
||||
result = array_node->get_value(array_node_def, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static snmp_err_t
|
||||
snmp_scalar_array_set_test(struct snmp_node_instance *instance, u16_t value_len, void *value)
|
||||
{
|
||||
snmp_err_t result = SNMP_ERR_NOTWRITABLE;
|
||||
const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
|
||||
const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
|
||||
|
||||
return array_node->set_test(array_node_def, value_len, value);
|
||||
if (array_node->set_test != NULL) {
|
||||
result = array_node->set_test(array_node_def, value_len, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static snmp_err_t
|
||||
snmp_scalar_array_set_value(struct snmp_node_instance *instance, u16_t value_len, void *value)
|
||||
{
|
||||
snmp_err_t result = SNMP_ERR_NOTWRITABLE;
|
||||
const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
|
||||
const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
|
||||
|
||||
return array_node->set_value(array_node_def, value_len, value);
|
||||
if (array_node->set_value != NULL) {
|
||||
result = array_node->set_value(array_node_def, value_len, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* LWIP_SNMP */
|
||||
|
||||
@@ -55,7 +55,11 @@ threadsync_get_value_synced(void *ctx)
|
||||
{
|
||||
struct threadsync_data *call_data = (struct threadsync_data *)ctx;
|
||||
|
||||
call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value);
|
||||
if (call_data->proxy_instance.get_value != NULL) {
|
||||
call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value);
|
||||
} else {
|
||||
call_data->retval.s16 = -1;
|
||||
}
|
||||
|
||||
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||
}
|
||||
@@ -76,7 +80,11 @@ threadsync_set_test_synced(void *ctx)
|
||||
{
|
||||
struct threadsync_data *call_data = (struct threadsync_data *)ctx;
|
||||
|
||||
call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
|
||||
if (call_data->proxy_instance.set_test != NULL) {
|
||||
call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
|
||||
} else {
|
||||
call_data->retval.err = SNMP_ERR_NOTWRITABLE;
|
||||
}
|
||||
|
||||
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||
}
|
||||
@@ -98,7 +106,11 @@ threadsync_set_value_synced(void *ctx)
|
||||
{
|
||||
struct threadsync_data *call_data = (struct threadsync_data *)ctx;
|
||||
|
||||
call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
|
||||
if (call_data->proxy_instance.set_value != NULL) {
|
||||
call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
|
||||
} else {
|
||||
call_data->retval.err = SNMP_ERR_NOTWRITABLE;
|
||||
}
|
||||
|
||||
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||
}
|
||||
|
||||
@@ -238,9 +238,9 @@ struct sntp_server {
|
||||
};
|
||||
static struct sntp_server sntp_servers[SNTP_MAX_SERVERS];
|
||||
|
||||
#if SNTP_GET_SERVERS_FROM_DHCP
|
||||
#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
|
||||
static u8_t sntp_set_servers_from_dhcp;
|
||||
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
|
||||
#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
|
||||
#if SNTP_SUPPORT_MULTIPLE_SERVERS
|
||||
/** The currently used server (initialized to 0) */
|
||||
static u8_t sntp_current_server;
|
||||
@@ -371,6 +371,7 @@ sntp_retry(void *arg)
|
||||
sntp_retry_timeout));
|
||||
|
||||
/* set up a timer to send a retry and increase the retry delay */
|
||||
sys_untimeout(sntp_request, NULL);
|
||||
sys_timeout(sntp_retry_timeout, sntp_request, NULL);
|
||||
|
||||
#if SNTP_RETRY_TIMEOUT_EXP
|
||||
@@ -382,6 +383,8 @@ sntp_retry(void *arg)
|
||||
if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) &&
|
||||
(new_retry_timeout > sntp_retry_timeout)) {
|
||||
sntp_retry_timeout = new_retry_timeout;
|
||||
} else {
|
||||
sntp_retry_timeout = SNTP_RETRY_TIMEOUT_MAX;
|
||||
}
|
||||
}
|
||||
#endif /* SNTP_RETRY_TIMEOUT_EXP */
|
||||
@@ -558,6 +561,7 @@ sntp_send_request(const ip_addr_t *server_addr)
|
||||
sntp_servers[sntp_current_server].reachability <<= 1;
|
||||
#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
|
||||
/* set up receive timeout: try next server or retry on timeout */
|
||||
sys_untimeout(sntp_try_next_server, NULL);
|
||||
sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);
|
||||
#if SNTP_CHECK_RESPONSE >= 1
|
||||
/* save server address to verify it in sntp_recv */
|
||||
@@ -567,6 +571,7 @@ sntp_send_request(const ip_addr_t *server_addr)
|
||||
LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
|
||||
(u32_t)SNTP_RETRY_TIMEOUT));
|
||||
/* out of memory: set up a timer to send a retry */
|
||||
sys_untimeout(sntp_request, NULL);
|
||||
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
|
||||
}
|
||||
}
|
||||
@@ -635,6 +640,7 @@ sntp_request(void *arg)
|
||||
} else {
|
||||
/* address conversion failed, try another server */
|
||||
LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n"));
|
||||
sys_untimeout(sntp_try_next_server, NULL);
|
||||
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL);
|
||||
}
|
||||
}
|
||||
@@ -648,6 +654,7 @@ void
|
||||
sntp_init(void)
|
||||
{
|
||||
/* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */
|
||||
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_init: SNTP initialised\n"));
|
||||
|
||||
#ifdef SNTP_SERVER_ADDRESS
|
||||
#if SNTP_SERVER_DNS
|
||||
@@ -750,7 +757,7 @@ sntp_getreachability(u8_t idx)
|
||||
}
|
||||
#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
|
||||
|
||||
#if SNTP_GET_SERVERS_FROM_DHCP
|
||||
#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
|
||||
/**
|
||||
* Config SNTP server handling by IP address, name, or DHCP; clear table
|
||||
* @param set_servers_from_dhcp enable or disable getting server addresses from dhcp
|
||||
@@ -764,7 +771,7 @@ sntp_servermode_dhcp(int set_servers_from_dhcp)
|
||||
sntp_set_servers_from_dhcp = new_mode;
|
||||
}
|
||||
}
|
||||
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
|
||||
#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
|
||||
|
||||
/**
|
||||
* @ingroup sntp
|
||||
@@ -816,6 +823,33 @@ dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server)
|
||||
}
|
||||
#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */
|
||||
|
||||
#if LWIP_IPV6_DHCP6 && SNTP_GET_SERVERS_FROM_DHCPV6
|
||||
/**
|
||||
* Initialize one of the NTP servers by IP address, required by DHCPV6
|
||||
*
|
||||
* @param num the number of NTP server addresses to set must be < SNTP_MAX_SERVERS
|
||||
* @param server array of IP address of the NTP servers to set
|
||||
*/
|
||||
void
|
||||
dhcp6_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs)
|
||||
{
|
||||
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u NTP server(s) via DHCPv6\n",
|
||||
(sntp_set_servers_from_dhcp ? "Got" : "Rejected"),
|
||||
num_ntp_servers));
|
||||
if (sntp_set_servers_from_dhcp && num_ntp_servers) {
|
||||
u8_t i;
|
||||
for (i = 0; (i < num_ntp_servers) && (i < SNTP_MAX_SERVERS); i++) {
|
||||
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: NTP server %u: %s\n",
|
||||
i, ipaddr_ntoa(&ntp_server_addrs[i])));
|
||||
sntp_setserver(i, &ntp_server_addrs[i]);
|
||||
}
|
||||
for (i = num_ntp_servers; i < SNTP_MAX_SERVERS; i++) {
|
||||
sntp_setserver(i, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_DHCPv6 && SNTP_GET_SERVERS_FROM_DHCPV6 */
|
||||
|
||||
/**
|
||||
* @ingroup sntp
|
||||
* Obtain one of the currently configured by IP address (or DHCP) NTP servers
|
||||
|
||||
@@ -501,6 +501,24 @@ altcp_get_port(struct altcp_pcb *conn, int local)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
void
|
||||
altcp_keepalive_disable(struct altcp_pcb *conn)
|
||||
{
|
||||
if (conn && conn->fns && conn->fns->keepalive_disable) {
|
||||
conn->fns->keepalive_disable(conn);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
altcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count)
|
||||
{
|
||||
if (conn && conn->fns && conn->fns->keepalive_enable) {
|
||||
conn->fns->keepalive_enable(conn, idle, intvl, count);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
enum tcp_state
|
||||
altcp_dbg_get_tcp_state(struct altcp_pcb *conn)
|
||||
@@ -666,6 +684,24 @@ altcp_default_get_port(struct altcp_pcb *conn, int local)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
void
|
||||
altcp_default_keepalive_disable(struct altcp_pcb *conn)
|
||||
{
|
||||
if (conn && conn->inner_conn) {
|
||||
altcp_keepalive_disable(conn->inner_conn);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
altcp_default_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count)
|
||||
{
|
||||
if (conn && conn->inner_conn) {
|
||||
altcp_keepalive_enable(conn->inner_conn, idle, intvl, count);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
enum tcp_state
|
||||
altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn)
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "lwip/altcp_tcp.h"
|
||||
#include "lwip/priv/altcp_priv.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "lwip/priv/tcp_priv.h"
|
||||
#include "lwip/mem.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -160,21 +161,25 @@ static void
|
||||
altcp_tcp_remove_callbacks(struct tcp_pcb *tpcb)
|
||||
{
|
||||
tcp_arg(tpcb, NULL);
|
||||
tcp_recv(tpcb, NULL);
|
||||
tcp_sent(tpcb, NULL);
|
||||
tcp_err(tpcb, NULL);
|
||||
tcp_poll(tpcb, NULL, tpcb->pollinterval);
|
||||
if (tpcb->state != LISTEN) {
|
||||
tcp_recv(tpcb, NULL);
|
||||
tcp_sent(tpcb, NULL);
|
||||
tcp_err(tpcb, NULL);
|
||||
tcp_poll(tpcb, NULL, tpcb->pollinterval);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
altcp_tcp_setup_callbacks(struct altcp_pcb *conn, struct tcp_pcb *tpcb)
|
||||
{
|
||||
tcp_arg(tpcb, conn);
|
||||
tcp_recv(tpcb, altcp_tcp_recv);
|
||||
tcp_sent(tpcb, altcp_tcp_sent);
|
||||
tcp_err(tpcb, altcp_tcp_err);
|
||||
/* tcp_poll is set when interval is set by application */
|
||||
/* listen is set totally different :-) */
|
||||
/* this might be called for LISTN when close fails... */
|
||||
if (tpcb->state != LISTEN) {
|
||||
tcp_recv(tpcb, altcp_tcp_recv);
|
||||
tcp_sent(tpcb, altcp_tcp_sent);
|
||||
tcp_err(tpcb, altcp_tcp_err);
|
||||
/* tcp_poll is set when interval is set by application */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -446,6 +451,31 @@ altcp_tcp_setprio(struct altcp_pcb *conn, u8_t prio)
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
static void
|
||||
altcp_tcp_keepalive_disable(struct altcp_pcb *conn)
|
||||
{
|
||||
if (conn && conn->state) {
|
||||
struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
|
||||
ALTCP_TCP_ASSERT_CONN(conn);
|
||||
ip_reset_option(pcb, SOF_KEEPALIVE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
altcp_tcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t cnt)
|
||||
{
|
||||
if (conn && conn->state) {
|
||||
struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
|
||||
ALTCP_TCP_ASSERT_CONN(conn);
|
||||
ip_set_option(pcb, SOF_KEEPALIVE);
|
||||
pcb->keep_idle = idle ? idle : TCP_KEEPIDLE_DEFAULT;
|
||||
pcb->keep_intvl = intvl ? intvl : TCP_KEEPINTVL_DEFAULT;
|
||||
pcb->keep_cnt = cnt ? cnt : TCP_KEEPCNT_DEFAULT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
altcp_tcp_dealloc(struct altcp_pcb *conn)
|
||||
{
|
||||
@@ -535,6 +565,10 @@ const struct altcp_functions altcp_tcp_functions = {
|
||||
altcp_tcp_get_tcp_addrinfo,
|
||||
altcp_tcp_get_ip,
|
||||
altcp_tcp_get_port
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
, altcp_tcp_keepalive_disable
|
||||
, altcp_tcp_keepalive_enable
|
||||
#endif
|
||||
#ifdef LWIP_DEBUG
|
||||
, altcp_tcp_dbg_get_tcp_state
|
||||
#endif
|
||||
|
||||
@@ -237,8 +237,9 @@ PACK_STRUCT_END
|
||||
#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
|
||||
#endif
|
||||
#endif /* LWIP_NETCONN && LWIP_TCP */
|
||||
#if LWIP_SOCKET
|
||||
#endif /* LWIP_SOCKET */
|
||||
#if LWIP_NETCONN_FULLDUPLEX && !LWIP_NETCONN_SEM_PER_THREAD
|
||||
#error "For LWIP_NETCONN_FULLDUPLEX to work, LWIP_NETCONN_SEM_PER_THREAD is required"
|
||||
#endif
|
||||
|
||||
|
||||
/* Compile-time checks for deprecated options.
|
||||
|
||||
@@ -127,6 +127,11 @@
|
||||
#define LWIP_DHCP_PROVIDE_DNS_SERVERS 0
|
||||
#endif
|
||||
|
||||
#ifndef LWIP_DHCP_INPUT_ERROR
|
||||
#define LWIP_DHCP_INPUT_ERROR(message, expression, handler) do { if (!(expression)) { \
|
||||
handler;} } while(0)
|
||||
#endif
|
||||
|
||||
/** Option handling: options are parsed in dhcp_parse_reply
|
||||
* and saved in an array where other functions can load them from.
|
||||
* This might be moved into the struct dhcp (not necessarily since
|
||||
@@ -1115,13 +1120,6 @@ dhcp_bind(struct netif *netif)
|
||||
}
|
||||
|
||||
ip4_addr_copy(gw_addr, dhcp->offered_gw_addr);
|
||||
/* gateway address not given? */
|
||||
if (ip4_addr_isany_val(gw_addr)) {
|
||||
/* copy network address */
|
||||
ip4_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
|
||||
/* use first host address on network as gateway */
|
||||
ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL));
|
||||
}
|
||||
|
||||
#if LWIP_DHCP_AUTOIP_COOP
|
||||
if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
|
||||
@@ -1349,6 +1347,7 @@ dhcp_release_and_stop(struct netif *netif)
|
||||
/* create and initialize the DHCP message header */
|
||||
struct pbuf *p_out;
|
||||
u16_t options_out_len;
|
||||
dhcp_set_state(dhcp, DHCP_STATE_OFF);
|
||||
p_out = dhcp_create_msg(netif, dhcp, DHCP_RELEASE, &options_out_len);
|
||||
if (p_out != NULL) {
|
||||
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
|
||||
@@ -1365,10 +1364,12 @@ dhcp_release_and_stop(struct netif *netif)
|
||||
/* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release */
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/* remove IP address from interface (prevents routing from selecting this interface) */
|
||||
netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
|
||||
/* remove IP address from interface (prevents routing from selecting this interface) */
|
||||
netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
|
||||
} else {
|
||||
dhcp_set_state(dhcp, DHCP_STATE_OFF);
|
||||
}
|
||||
|
||||
#if LWIP_DHCP_AUTOIP_COOP
|
||||
if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
|
||||
@@ -1377,8 +1378,6 @@ dhcp_release_and_stop(struct netif *netif)
|
||||
}
|
||||
#endif /* LWIP_DHCP_AUTOIP_COOP */
|
||||
|
||||
dhcp_set_state(dhcp, DHCP_STATE_OFF);
|
||||
|
||||
if (dhcp->pcb_allocated != 0) {
|
||||
dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
|
||||
dhcp->pcb_allocated = 0;
|
||||
@@ -1509,6 +1508,7 @@ dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp)
|
||||
u8_t *options;
|
||||
u16_t offset;
|
||||
u16_t offset_max;
|
||||
u16_t options_offset;
|
||||
u16_t options_idx;
|
||||
u16_t options_idx_max;
|
||||
struct pbuf *q;
|
||||
@@ -1541,6 +1541,7 @@ dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp)
|
||||
options_idx_max = p->tot_len;
|
||||
again:
|
||||
q = p;
|
||||
options_offset = options_idx;
|
||||
while ((q != NULL) && (options_idx >= q->len)) {
|
||||
options_idx = (u16_t)(options_idx - q->len);
|
||||
options_idx_max = (u16_t)(options_idx_max - q->len);
|
||||
@@ -1579,58 +1580,58 @@ again:
|
||||
/* will be increased below */
|
||||
break;
|
||||
case (DHCP_OPTION_SUBNET_MASK):
|
||||
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
|
||||
break;
|
||||
case (DHCP_OPTION_ROUTER):
|
||||
decode_len = 4; /* only copy the first given router */
|
||||
LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_ROUTER;
|
||||
break;
|
||||
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
|
||||
case (DHCP_OPTION_DNS_SERVER):
|
||||
/* special case: there might be more than one server */
|
||||
LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
|
||||
/* limit number of DNS servers */
|
||||
decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS);
|
||||
LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
|
||||
break;
|
||||
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
|
||||
case (DHCP_OPTION_LEASE_TIME):
|
||||
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
|
||||
break;
|
||||
#if LWIP_DHCP_GET_NTP_SRV
|
||||
case (DHCP_OPTION_NTP):
|
||||
/* special case: there might be more than one server */
|
||||
LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
|
||||
/* limit number of NTP servers */
|
||||
decode_len = LWIP_MIN(len, 4 * LWIP_DHCP_MAX_NTP_SERVERS);
|
||||
LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_NTP_SERVER;
|
||||
break;
|
||||
#endif /* LWIP_DHCP_GET_NTP_SRV*/
|
||||
case (DHCP_OPTION_OVERLOAD):
|
||||
LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len == 1", len == 1, return ERR_VAL;);
|
||||
/* decode overload only in options, not in file/sname: invalid packet */
|
||||
LWIP_ERROR("overload in file/sname", options_idx == DHCP_OPTIONS_OFS, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("overload in file/sname", options_offset == DHCP_OPTIONS_OFS, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_OVERLOAD;
|
||||
break;
|
||||
case (DHCP_OPTION_MESSAGE_TYPE):
|
||||
LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len == 1", len == 1, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
|
||||
break;
|
||||
case (DHCP_OPTION_SERVER_ID):
|
||||
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_SERVER_ID;
|
||||
break;
|
||||
case (DHCP_OPTION_T1):
|
||||
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_T1;
|
||||
break;
|
||||
case (DHCP_OPTION_T2):
|
||||
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_T2;
|
||||
break;
|
||||
default:
|
||||
@@ -1662,7 +1663,7 @@ decode_next:
|
||||
if (decode_len > 4) {
|
||||
/* decode more than one u32_t */
|
||||
u16_t next_val_offset;
|
||||
LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
|
||||
dhcp_got_option(dhcp, decode_idx);
|
||||
dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value));
|
||||
decode_len = (u8_t)(decode_len - 4);
|
||||
@@ -1677,7 +1678,7 @@ decode_next:
|
||||
} else if (decode_len == 4) {
|
||||
value = lwip_ntohl(value);
|
||||
} else {
|
||||
LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
|
||||
value = ((u8_t *)&value)[0];
|
||||
}
|
||||
dhcp_got_option(dhcp, decode_idx);
|
||||
@@ -1690,7 +1691,7 @@ decode_next:
|
||||
offset_max = (u16_t)(offset_max - q->len);
|
||||
if (offset < offset_max) {
|
||||
q = q->next;
|
||||
LWIP_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
|
||||
LWIP_DHCP_INPUT_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
|
||||
options = (u8_t *)q->payload;
|
||||
} else {
|
||||
/* We've run out of bytes, probably no end marker. Don't proceed. */
|
||||
|
||||
@@ -983,6 +983,14 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
|
||||
/* We don't re-send arp request in etharp_tmr, but we still queue packets,
|
||||
since this failure could be temporary, and the next packet calling
|
||||
etharp_query again could lead to sending the queued packets. */
|
||||
} else {
|
||||
/* ARP request successfully sent */
|
||||
if ((arp_table[i].state == ETHARP_STATE_PENDING) && !is_new_entry) {
|
||||
/* A new ARP request has been sent for a pending entry. Reset the ctime to
|
||||
not let it expire too fast. */
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: reset ctime for entry %"S16_F"\n", (s16_t)i));
|
||||
arp_table[i].ctime = 0;
|
||||
}
|
||||
}
|
||||
if (q == NULL) {
|
||||
return result;
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1
|
||||
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
|
||||
|
||||
/* The amount of data from the original packet to return in a dest-unreachable */
|
||||
/* The maximum amount of data from the original packet to return in a dest-unreachable */
|
||||
#define ICMP_DEST_UNREACH_DATASIZE 8
|
||||
|
||||
static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
|
||||
@@ -345,20 +345,26 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
|
||||
struct icmp_echo_hdr *icmphdr;
|
||||
ip4_addr_t iphdr_src;
|
||||
struct netif *netif;
|
||||
u16_t response_pkt_len;
|
||||
|
||||
/* increase number of messages attempted to send */
|
||||
MIB2_STATS_INC(mib2.icmpoutmsgs);
|
||||
|
||||
/* ICMP header + IP header + 8 bytes of data */
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
|
||||
PBUF_RAM);
|
||||
/* Keep IP header + up to 8 bytes */
|
||||
response_pkt_len = IP_HLEN + ICMP_DEST_UNREACH_DATASIZE;
|
||||
if (p->tot_len < response_pkt_len) {
|
||||
response_pkt_len = p->tot_len;
|
||||
}
|
||||
|
||||
/* ICMP header + part of original packet */
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + response_pkt_len, PBUF_RAM);
|
||||
if (q == NULL) {
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
|
||||
MIB2_STATS_INC(mib2.icmpouterrors);
|
||||
return;
|
||||
}
|
||||
LWIP_ASSERT("check that first pbuf can hold icmp message",
|
||||
(q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE)));
|
||||
(q->len >= (sizeof(struct icmp_echo_hdr) + response_pkt_len)));
|
||||
|
||||
iphdr = (struct ip_hdr *)p->payload;
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
|
||||
@@ -375,7 +381,7 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
|
||||
|
||||
/* copy fields from original packet */
|
||||
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
|
||||
IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
|
||||
response_pkt_len);
|
||||
|
||||
ip4_addr_copy(iphdr_src, iphdr->src);
|
||||
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
|
||||
|
||||
@@ -214,7 +214,7 @@ ip4_route(const ip4_addr_t *dest)
|
||||
#endif /* !LWIP_SINGLE_NETIF */
|
||||
|
||||
if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) ||
|
||||
ip4_addr_isany_val(*netif_ip4_addr(netif_default))) {
|
||||
ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) {
|
||||
/* No matching netif found and default netif is not usable.
|
||||
If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
||||
|
||||
@@ -173,6 +173,8 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
|
||||
}
|
||||
for (;;) {
|
||||
if (lwip_isdigit(c)) {
|
||||
if((base == 8) && ((u32_t)(c - '0') >= 8))
|
||||
break;
|
||||
val = (val * base) + (u32_t)(c - '0');
|
||||
c = *++cp;
|
||||
} else if (base == 16 && lwip_isxdigit(c)) {
|
||||
|
||||
@@ -451,7 +451,16 @@ dhcp6_msg_finalize(u16_t options_out_len, struct pbuf *p_out)
|
||||
static void
|
||||
dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)
|
||||
{
|
||||
const u16_t requested_options[] = {DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_SNTP_SERVERS};
|
||||
const u16_t requested_options[] = {
|
||||
#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
|
||||
DHCP6_OPTION_DNS_SERVERS,
|
||||
DHCP6_OPTION_DOMAIN_LIST
|
||||
#endif
|
||||
#if LWIP_DHCP6_GET_NTP_SRV
|
||||
, DHCP6_OPTION_SNTP_SERVERS
|
||||
#endif
|
||||
};
|
||||
|
||||
u16_t msecs;
|
||||
struct pbuf *p_out;
|
||||
u16_t options_out_len;
|
||||
@@ -527,7 +536,7 @@ dhcp6_handle_config_reply(struct netif *netif, struct pbuf *p_msg_in)
|
||||
u16_t idx;
|
||||
u8_t n;
|
||||
|
||||
memset(&dns_addr, 0, sizeof(dns_addr));
|
||||
ip_addr_set_zero_ip6(&dns_addr);
|
||||
dns_addr6 = ip_2_ip6(&dns_addr);
|
||||
for (n = 0, idx = op_start; (idx < op_start + op_len) && (n < LWIP_DHCP6_PROVIDE_DNS_SERVERS);
|
||||
n++, idx += sizeof(struct ip6_addr_packed)) {
|
||||
|
||||
@@ -57,9 +57,9 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if LWIP_ICMP6_DATASIZE == 0
|
||||
#if !LWIP_ICMP6_DATASIZE || (LWIP_ICMP6_DATASIZE > (IP6_MIN_MTU_LENGTH - IP6_HLEN - ICMP6_HLEN))
|
||||
#undef LWIP_ICMP6_DATASIZE
|
||||
#define LWIP_ICMP6_DATASIZE 8
|
||||
#define LWIP_ICMP6_DATASIZE (IP6_MIN_MTU_LENGTH - IP6_HLEN - ICMP6_HLEN)
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
@@ -387,26 +387,35 @@ icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data,
|
||||
{
|
||||
struct pbuf *q;
|
||||
struct icmp6_hdr *icmp6hdr;
|
||||
u16_t datalen = LWIP_MIN(p->tot_len, LWIP_ICMP6_DATASIZE);
|
||||
u16_t offset;
|
||||
|
||||
/* ICMPv6 header + IPv6 header + data */
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE,
|
||||
/* ICMPv6 header + datalen (as much of the offending packet as possible) */
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + datalen,
|
||||
PBUF_RAM);
|
||||
if (q == NULL) {
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n"));
|
||||
ICMP6_STATS_INC(icmp6.memerr);
|
||||
return;
|
||||
}
|
||||
LWIP_ASSERT("check that first pbuf can hold icmp 6message",
|
||||
(q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));
|
||||
LWIP_ASSERT("check that first pbuf can hold icmp6 header",
|
||||
(q->len >= (sizeof(struct icmp6_hdr))));
|
||||
|
||||
icmp6hdr = (struct icmp6_hdr *)q->payload;
|
||||
icmp6hdr->type = type;
|
||||
icmp6hdr->code = code;
|
||||
icmp6hdr->data = lwip_htonl(data);
|
||||
|
||||
/* copy fields from original packet */
|
||||
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload,
|
||||
IP6_HLEN + LWIP_ICMP6_DATASIZE);
|
||||
/* copy fields from original packet (which may be a chain of pbufs) */
|
||||
offset = sizeof(struct icmp6_hdr);
|
||||
while (p && datalen) {
|
||||
u16_t len = LWIP_MIN(datalen, p->len);
|
||||
err_t res = pbuf_take_at(q, p->payload, len, offset);
|
||||
if (res != ERR_OK) break;
|
||||
datalen -= len;
|
||||
offset += len;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
/* calculate checksum */
|
||||
icmp6hdr->chksum = 0;
|
||||
|
||||
@@ -1305,6 +1305,7 @@ ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
|
||||
ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
|
||||
ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
|
||||
netif = ip6_route(&src_addr, &dest_addr);
|
||||
dest = &dest_addr;
|
||||
}
|
||||
|
||||
if (netif == NULL) {
|
||||
@@ -1364,6 +1365,7 @@ ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
|
||||
ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
|
||||
ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
|
||||
netif = ip6_route(&src_addr, &dest_addr);
|
||||
dest = &dest_addr;
|
||||
}
|
||||
|
||||
if (netif == NULL) {
|
||||
|
||||
@@ -781,7 +781,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!",
|
||||
(p->len >= (IP6_HLEN)));
|
||||
(rambuf->len >= (IP6_HLEN)));
|
||||
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
|
||||
ip6hdr = (struct ip6_hdr *)rambuf->payload;
|
||||
frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
|
||||
|
||||
@@ -253,7 +253,7 @@ mld6_input(struct pbuf *p, struct netif *inp)
|
||||
while (group != NULL) {
|
||||
if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
|
||||
(!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
|
||||
mld6_delayed_report(group, mld_hdr->max_resp_delay);
|
||||
mld6_delayed_report(group, lwip_ntohs(mld_hdr->max_resp_delay));
|
||||
}
|
||||
group = group->next;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ mld6_input(struct pbuf *p, struct netif *inp)
|
||||
group = mld6_lookfor_group(inp, ip6_current_dest_addr());
|
||||
if (group != NULL) {
|
||||
/* Schedule a report. */
|
||||
mld6_delayed_report(group, mld_hdr->max_resp_delay);
|
||||
mld6_delayed_report(group, lwip_ntohs(mld_hdr->max_resp_delay));
|
||||
}
|
||||
}
|
||||
break; /* ICMP6_TYPE_MLQ */
|
||||
|
||||
@@ -693,11 +693,11 @@ nd6_input(struct pbuf *p, struct netif *inp)
|
||||
}
|
||||
mtu_opt = (struct mtu_option *)buffer;
|
||||
mtu32 = lwip_htonl(mtu_opt->mtu);
|
||||
if ((mtu32 >= 1280) && (mtu32 <= 0xffff)) {
|
||||
if ((mtu32 >= IP6_MIN_MTU_LENGTH) && (mtu32 <= 0xffff)) {
|
||||
#if LWIP_ND6_ALLOW_RA_UPDATES
|
||||
if (inp->mtu) {
|
||||
/* don't set the mtu for IPv6 higher than the netif driver supports */
|
||||
inp->mtu6 = LWIP_MIN(inp->mtu, (u16_t)mtu32);
|
||||
inp->mtu6 = LWIP_MIN(LWIP_MIN(inp->mtu, inp->mtu6), (u16_t)mtu32);
|
||||
} else {
|
||||
inp->mtu6 = (u16_t)mtu32;
|
||||
}
|
||||
@@ -766,7 +766,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
rdnss_opt = (struct rdnss_option *)buffer;
|
||||
num = (rdnss_opt->length - 1) / 2;
|
||||
for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) {
|
||||
for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++, copy_offset += sizeof(ip6_addr_p_t)) {
|
||||
ip_addr_t rdnss_address;
|
||||
|
||||
/* Copy directly from pbuf to get an aligned, zoned copy of the prefix. */
|
||||
@@ -1182,15 +1182,27 @@ nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags)
|
||||
{
|
||||
struct ns_header *ns_hdr;
|
||||
struct pbuf *p;
|
||||
const ip6_addr_t *src_addr;
|
||||
const ip6_addr_t *src_addr = NULL;
|
||||
u16_t lladdr_opt_len;
|
||||
|
||||
LWIP_ASSERT("target address is required", target_addr != NULL);
|
||||
|
||||
if (!(flags & ND6_SEND_FLAG_ANY_SRC) &&
|
||||
ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) {
|
||||
/* Use link-local address as source address. */
|
||||
src_addr = netif_ip6_addr(netif, 0);
|
||||
if (!(flags & ND6_SEND_FLAG_ANY_SRC)) {
|
||||
int i;
|
||||
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
|
||||
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
|
||||
ip6_addr_netcmp(target_addr, netif_ip6_addr(netif, i))) {
|
||||
src_addr = netif_ip6_addr(netif, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == LWIP_IPV6_NUM_ADDRESSES) {
|
||||
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("ICMPv6 NS: no available src address\n"));
|
||||
ND6_STATS_INC(nd6.err);
|
||||
return;
|
||||
}
|
||||
|
||||
/* calculate option length (in 8-byte-blocks) */
|
||||
lladdr_opt_len = ((netif->hwaddr_len + 2) + 7) >> 3;
|
||||
} else {
|
||||
@@ -2300,7 +2312,7 @@ nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif)
|
||||
return netif_mtu6(netif);
|
||||
}
|
||||
|
||||
return 1280; /* Minimum MTU */
|
||||
return IP6_MIN_MTU_LENGTH; /* Minimum MTU */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -348,10 +348,6 @@ netif_add(struct netif *netif,
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
netif->mld_mac_filter = NULL;
|
||||
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
|
||||
#if ENABLE_LOOPBACK
|
||||
netif->loop_first = NULL;
|
||||
netif->loop_last = NULL;
|
||||
#endif /* ENABLE_LOOPBACK */
|
||||
|
||||
/* remember netif specific state information data */
|
||||
netif->state = state;
|
||||
@@ -359,9 +355,16 @@ netif_add(struct netif *netif,
|
||||
netif->input = input;
|
||||
|
||||
NETIF_RESET_HINTS(netif);
|
||||
#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
|
||||
#if ENABLE_LOOPBACK
|
||||
netif->loop_first = NULL;
|
||||
netif->loop_last = NULL;
|
||||
#if LWIP_LOOPBACK_MAX_PBUFS
|
||||
netif->loop_cnt_current = 0;
|
||||
#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
|
||||
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
|
||||
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
|
||||
netif->reschedule_poll = 0;
|
||||
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
|
||||
#endif /* ENABLE_LOOPBACK */
|
||||
|
||||
#if LWIP_IPV4
|
||||
netif_set_addr(netif, ipaddr, netmask, gw);
|
||||
@@ -1031,6 +1034,10 @@ netif_set_link_down(struct netif *netif)
|
||||
|
||||
if (netif->flags & NETIF_FLAG_LINK_UP) {
|
||||
netif_clear_flags(netif, NETIF_FLAG_LINK_UP);
|
||||
#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
|
||||
netif->mtu6 = netif->mtu;
|
||||
#endif
|
||||
|
||||
NETIF_LINK_CALLBACK(netif);
|
||||
#if LWIP_NETIF_EXT_STATUS_CALLBACK
|
||||
{
|
||||
@@ -1062,11 +1069,12 @@ netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callb
|
||||
/**
|
||||
* @ingroup netif
|
||||
* Send an IP packet to be received on the same netif (loopif-like).
|
||||
* The pbuf is simply copied and handed back to netif->input.
|
||||
* In multithreaded mode, this is done directly since netif->input must put
|
||||
* the packet on a queue.
|
||||
* In callback mode, the packet is put on an internal queue and is fed to
|
||||
* The pbuf is copied and added to an internal queue which is fed to
|
||||
* netif->input by netif_poll().
|
||||
* In multithreaded mode, the call to netif_poll() is queued to be done on the
|
||||
* TCP/IP thread.
|
||||
* In callback mode, the user has the responsibility to call netif_poll() in
|
||||
* the main loop of their application.
|
||||
*
|
||||
* @param netif the lwip network interface structure
|
||||
* @param p the (IP) packet to 'send'
|
||||
@@ -1143,6 +1151,12 @@ netif_loop_output(struct netif *netif, struct pbuf *p)
|
||||
LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
|
||||
netif->loop_last->next = r;
|
||||
netif->loop_last = last;
|
||||
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
|
||||
if (netif->reschedule_poll) {
|
||||
schedule_poll = 1;
|
||||
netif->reschedule_poll = 0;
|
||||
}
|
||||
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
|
||||
} else {
|
||||
netif->loop_first = r;
|
||||
netif->loop_last = last;
|
||||
@@ -1160,7 +1174,11 @@ netif_loop_output(struct netif *netif, struct pbuf *p)
|
||||
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
|
||||
/* For multithreading environment, schedule a call to netif_poll */
|
||||
if (schedule_poll) {
|
||||
tcpip_try_callback((tcpip_callback_fn)netif_poll, netif);
|
||||
if (tcpip_try_callback((tcpip_callback_fn)netif_poll, netif) != ERR_OK) {
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
netif->reschedule_poll = 1;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
|
||||
|
||||
@@ -1710,6 +1728,10 @@ netif_find(const char *name)
|
||||
}
|
||||
|
||||
num = (u8_t)atoi(&name[2]);
|
||||
if (!num && (name[2] != '0')) {
|
||||
/* this means atoi has failed */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NETIF_FOREACH(netif) {
|
||||
if (num == netif->num &&
|
||||
|
||||
@@ -271,7 +271,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
|
||||
break;
|
||||
}
|
||||
case PBUF_RAM: {
|
||||
u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
|
||||
mem_size_t payload_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
|
||||
mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len);
|
||||
|
||||
/* bug #50040: Check for integer overflow when calculating alloc_len */
|
||||
@@ -960,54 +960,88 @@ pbuf_dechain(struct pbuf *p)
|
||||
err_t
|
||||
pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
|
||||
{
|
||||
size_t offset_to = 0, offset_from = 0, len;
|
||||
|
||||
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
|
||||
(const void *)p_to, (const void *)p_from));
|
||||
|
||||
LWIP_ERROR("pbuf_copy: invalid source", p_from != NULL, return ERR_ARG;);
|
||||
return pbuf_copy_partial_pbuf(p_to, p_from, p_from->tot_len, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup pbuf
|
||||
* Copy part or all of one packet buffer into another, to a specified offset.
|
||||
*
|
||||
* @note Only data in one packet is copied, no packet queue!
|
||||
* @note Argument order is shared with pbuf_copy, but different than pbuf_copy_partial.
|
||||
*
|
||||
* @param p_to pbuf destination of the copy
|
||||
* @param p_from pbuf source of the copy
|
||||
* @param copy_len number of bytes to copy
|
||||
* @param offset offset in destination pbuf where to copy to
|
||||
*
|
||||
* @return ERR_OK if copy_len bytes were copied
|
||||
* ERR_ARG if one of the pbufs is NULL or p_from is shorter than copy_len
|
||||
* or p_to is not big enough to hold copy_len at offset
|
||||
* ERR_VAL if any of the pbufs are part of a queue
|
||||
*/
|
||||
err_t
|
||||
pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset)
|
||||
{
|
||||
size_t offset_to = offset, offset_from = 0, len_calc;
|
||||
u16_t len;
|
||||
|
||||
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy_partial_pbuf(%p, %p, %"U16_F", %"U16_F")\n",
|
||||
(const void *)p_to, (const void *)p_from, copy_len, offset));
|
||||
|
||||
/* is the copy_len in range? */
|
||||
LWIP_ERROR("pbuf_copy_partial_pbuf: copy_len bigger than source", ((p_from != NULL) &&
|
||||
(p_from->tot_len >= copy_len)), return ERR_ARG;);
|
||||
/* is the target big enough to hold the source? */
|
||||
LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) &&
|
||||
(p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;);
|
||||
LWIP_ERROR("pbuf_copy_partial_pbuf: target not big enough", ((p_to != NULL) &&
|
||||
(p_to->tot_len >= (offset + copy_len))), return ERR_ARG;);
|
||||
|
||||
/* iterate through pbuf chain */
|
||||
do {
|
||||
/* copy one part of the original chain */
|
||||
if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
|
||||
/* complete current p_from fits into current p_to */
|
||||
len = p_from->len - offset_from;
|
||||
len_calc = p_from->len - offset_from;
|
||||
} else {
|
||||
/* current p_from does not fit into current p_to */
|
||||
len = p_to->len - offset_to;
|
||||
len_calc = p_to->len - offset_to;
|
||||
}
|
||||
len = (u16_t)LWIP_MIN(copy_len, len_calc);
|
||||
MEMCPY((u8_t *)p_to->payload + offset_to, (u8_t *)p_from->payload + offset_from, len);
|
||||
offset_to += len;
|
||||
offset_from += len;
|
||||
copy_len -= len;
|
||||
LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
|
||||
LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len);
|
||||
if (offset_from >= p_from->len) {
|
||||
/* on to next p_from (if any) */
|
||||
offset_from = 0;
|
||||
p_from = p_from->next;
|
||||
LWIP_ERROR("p_from != NULL", (p_from != NULL) || (copy_len == 0), return ERR_ARG;);
|
||||
}
|
||||
if (offset_to == p_to->len) {
|
||||
/* on to next p_to (if any) */
|
||||
offset_to = 0;
|
||||
p_to = p_to->next;
|
||||
LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("p_to != NULL", (p_to != NULL) || (copy_len == 0), return ERR_ARG;);
|
||||
}
|
||||
|
||||
if ((p_from != NULL) && (p_from->len == p_from->tot_len)) {
|
||||
/* don't copy more than one packet! */
|
||||
LWIP_ERROR("pbuf_copy() does not allow packet queues!",
|
||||
LWIP_ERROR("pbuf_copy_partial_pbuf() does not allow packet queues!",
|
||||
(p_from->next == NULL), return ERR_VAL;);
|
||||
}
|
||||
if ((p_to != NULL) && (p_to->len == p_to->tot_len)) {
|
||||
/* don't copy more than one packet! */
|
||||
LWIP_ERROR("pbuf_copy() does not allow packet queues!",
|
||||
LWIP_ERROR("pbuf_copy_partial_pbuf() does not allow packet queues!",
|
||||
(p_to->next == NULL), return ERR_VAL;);
|
||||
}
|
||||
} while (p_from);
|
||||
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n"));
|
||||
} while (copy_len);
|
||||
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy_partial_pbuf: copy complete.\n"));
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -583,6 +583,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
||||
tcp_free(pcb);
|
||||
} else {
|
||||
int send_rst = 0;
|
||||
u16_t local_port = 0;
|
||||
enum tcp_state last_state;
|
||||
seqno = pcb->snd_nxt;
|
||||
ackno = pcb->rcv_nxt;
|
||||
@@ -597,6 +598,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
||||
}
|
||||
} else {
|
||||
send_rst = reset;
|
||||
local_port = pcb->local_port;
|
||||
TCP_PCB_REMOVE_ACTIVE(pcb);
|
||||
}
|
||||
if (pcb->unacked != NULL) {
|
||||
@@ -613,7 +615,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
||||
tcp_backlog_accepted(pcb);
|
||||
if (send_rst) {
|
||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
|
||||
tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port);
|
||||
tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
|
||||
}
|
||||
last_state = pcb->state;
|
||||
tcp_free(pcb);
|
||||
@@ -645,6 +647,7 @@ tcp_abort(struct tcp_pcb *pcb)
|
||||
* bound to all local IP addresses.
|
||||
* If another connection is bound to the same port, the function will
|
||||
* return ERR_USE, otherwise ERR_OK is returned.
|
||||
* @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
|
||||
*
|
||||
* @param pcb the tcp_pcb to bind (no check is done whether this pcb is
|
||||
* already bound!)
|
||||
@@ -887,7 +890,7 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err)
|
||||
lpcb->state = LISTEN;
|
||||
lpcb->prio = pcb->prio;
|
||||
lpcb->so_options = pcb->so_options;
|
||||
lpcb->netif_idx = NETIF_NO_INDEX;
|
||||
lpcb->netif_idx = pcb->netif_idx;
|
||||
lpcb->ttl = pcb->ttl;
|
||||
lpcb->tos = pcb->tos;
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
@@ -966,6 +969,7 @@ void
|
||||
tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
||||
{
|
||||
u32_t wnd_inflation;
|
||||
tcpwnd_size_t rcv_wnd;
|
||||
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
|
||||
@@ -975,19 +979,13 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
||||
LWIP_ASSERT("don't call tcp_recved for listen-pcbs",
|
||||
pcb->state != LISTEN);
|
||||
|
||||
pcb->rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len);
|
||||
if (pcb->rcv_wnd > TCP_WND_MAX(pcb)) {
|
||||
rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len);
|
||||
if ((rcv_wnd > TCP_WND_MAX(pcb)) || (rcv_wnd < pcb->rcv_wnd)) {
|
||||
/* window got too big or tcpwnd_size_t overflow */
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: window got too big or tcpwnd_size_t overflow\n"));
|
||||
pcb->rcv_wnd = TCP_WND_MAX(pcb);
|
||||
} else if (pcb->rcv_wnd == 0) {
|
||||
/* rcv_wnd overflowed */
|
||||
if (TCP_STATE_IS_CLOSING(pcb->state)) {
|
||||
/* In passive close, we allow this, since the FIN bit is added to rcv_wnd
|
||||
by the stack itself, since it is not mandatory for an application
|
||||
to call tcp_recved() for the FIN bit, but e.g. the netconn API does so. */
|
||||
pcb->rcv_wnd = TCP_WND_MAX(pcb);
|
||||
} else {
|
||||
LWIP_ASSERT("tcp_recved: len wrapped rcv_wnd\n", 0);
|
||||
}
|
||||
} else {
|
||||
pcb->rcv_wnd = rcv_wnd;
|
||||
}
|
||||
|
||||
wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
|
||||
@@ -1219,6 +1217,7 @@ tcp_slowtmr_start:
|
||||
LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
|
||||
if (pcb->last_timer == tcp_timer_ctr) {
|
||||
/* skip this pcb, we have already processed it */
|
||||
prev = pcb;
|
||||
pcb = pcb->next;
|
||||
continue;
|
||||
}
|
||||
@@ -1935,6 +1934,7 @@ tcp_alloc(u8_t prio)
|
||||
* any of the TCP PCB lists.
|
||||
* The pcb is not put on any list until binding using tcp_bind().
|
||||
* If memory is not available for creating the new pcb, NULL is returned.
|
||||
* @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
|
||||
*
|
||||
* @internal: Maybe there should be a idle TCP PCB list where these
|
||||
* PCBs are put on. Port reservation using tcp_bind() is implemented but
|
||||
@@ -1954,6 +1954,7 @@ tcp_new(void)
|
||||
* Creates a new TCP protocol control block but doesn't
|
||||
* place it on any of the TCP PCB lists.
|
||||
* The pcb is not put on any list until binding using tcp_bind().
|
||||
* @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
|
||||
*
|
||||
* @param type IP address type, see @ref lwip_ip_addr_type definitions.
|
||||
* If you want to listen to IPv4 and IPv6 (dual-stack) connections,
|
||||
@@ -2069,6 +2070,7 @@ tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
|
||||
* @ingroup tcp_raw
|
||||
* Used for specifying the function that should be called when a
|
||||
* LISTENing connection has been connected to another host.
|
||||
* @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
|
||||
*
|
||||
* @param pcb tcp_pcb to set the accept callback
|
||||
* @param accept callback function to call for this pcb when LISTENing
|
||||
|
||||
@@ -852,8 +852,9 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
/* Do different things depending on the TCP state. */
|
||||
switch (pcb->state) {
|
||||
case SYN_SENT:
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
|
||||
pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno)));
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %s %"U32_F"\n",
|
||||
ackno, pcb->snd_nxt, pcb->unacked ? "" : " empty:",
|
||||
pcb->unacked ? lwip_ntohl(pcb->unacked->tcphdr->seqno) : 0));
|
||||
/* received SYN ACK with expected sequence number? */
|
||||
if ((flags & TCP_ACK) && (flags & TCP_SYN)
|
||||
&& (ackno == pcb->lastack + 1)) {
|
||||
|
||||
@@ -913,6 +913,7 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split)
|
||||
|
||||
seg = tcp_create_segment(pcb, p, remainder_flags, lwip_ntohl(useg->tcphdr->seqno) + split, optflags);
|
||||
if (seg == NULL) {
|
||||
p = NULL; /* Freed by tcp_create_segment */
|
||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("tcp_split_unsent_seg: could not create new TCP segment\n"));
|
||||
goto memerr;
|
||||
@@ -2002,7 +2003,7 @@ tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno,
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
|
||||
return;
|
||||
}
|
||||
tcp_output_fill_options(pcb, p, 0, optlen);
|
||||
tcp_output_fill_options(pcb, p, 0, 0);
|
||||
|
||||
MIB2_STATS_INC(mib2.tcpoutrsts);
|
||||
|
||||
@@ -2096,7 +2097,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
|
||||
("tcp_keepalive: could not allocate memory for pbuf\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
tcp_output_fill_options(pcb, p, 0, optlen);
|
||||
tcp_output_fill_options(pcb, p, 0, 0);
|
||||
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n",
|
||||
@@ -2178,7 +2179,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
|
||||
if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
|
||||
pcb->snd_nxt = snd_nxt;
|
||||
}
|
||||
tcp_output_fill_options(pcb, p, 0, optlen);
|
||||
tcp_output_fill_options(pcb, p, 0, 0);
|
||||
|
||||
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
|
||||
|
||||
|
||||
@@ -997,9 +997,13 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
|
||||
{
|
||||
/* port matches that of PCB in list and REUSEADDR not set -> reject */
|
||||
if ((ipcb->local_port == port) &&
|
||||
(((IP_GET_TYPE(&ipcb->local_ip) == IP_GET_TYPE(ipaddr)) &&
|
||||
/* IP address matches or any IP used? */
|
||||
(ip_addr_cmp(&ipcb->local_ip, ipaddr) || ip_addr_isany(ipaddr) ||
|
||||
ip_addr_isany(&ipcb->local_ip))) {
|
||||
(ip_addr_cmp(&ipcb->local_ip, ipaddr) ||
|
||||
ip_addr_isany(ipaddr) ||
|
||||
ip_addr_isany(&ipcb->local_ip))) ||
|
||||
(IP_GET_TYPE(&ipcb->local_ip) == IPADDR_TYPE_ANY) ||
|
||||
(IP_GET_TYPE(ipaddr) == IPADDR_TYPE_ANY))) {
|
||||
/* other PCB already binds to this local IP and port */
|
||||
LWIP_DEBUGF(UDP_DEBUG,
|
||||
("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
|
||||
@@ -1208,6 +1212,7 @@ udp_remove(struct udp_pcb *pcb)
|
||||
* Creates a new UDP pcb which can be used for UDP communication. The
|
||||
* pcb is not active until it has either been bound to a local address
|
||||
* or connected to a remote address.
|
||||
* @see MEMP_NUM_UDP_PCB
|
||||
*
|
||||
* @return The UDP PCB which was created. NULL if the PCB data structure
|
||||
* could not be allocated.
|
||||
@@ -1242,7 +1247,8 @@ udp_new(void)
|
||||
* Create a UDP PCB for specific IP type.
|
||||
* The pcb is not active until it has either been bound to a local address
|
||||
* or connected to a remote address.
|
||||
*
|
||||
* @see MEMP_NUM_UDP_PCB
|
||||
*
|
||||
* @param type IP address type, see @ref lwip_ip_addr_type definitions.
|
||||
* If you want to listen to IPv4 and IPv6 (dual-stack) packets,
|
||||
* supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE.
|
||||
|
||||
@@ -129,6 +129,11 @@ err_t altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr,
|
||||
ip_addr_t *altcp_get_ip(struct altcp_pcb *conn, int local);
|
||||
u16_t altcp_get_port(struct altcp_pcb *conn, int local);
|
||||
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
void altcp_keepalive_disable(struct altcp_pcb *conn);
|
||||
void altcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
|
||||
#endif
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
enum tcp_state altcp_dbg_get_tcp_state(struct altcp_pcb *conn);
|
||||
#endif
|
||||
|
||||
@@ -61,7 +61,22 @@ extern "C" {
|
||||
struct altcp_tls_config;
|
||||
|
||||
/** @ingroup altcp_tls
|
||||
* Create an ALTCP_TLS server configuration handle
|
||||
* Create an ALTCP_TLS server configuration handle prepared for multiple certificates
|
||||
*/
|
||||
struct altcp_tls_config *altcp_tls_create_config_server(uint8_t cert_count);
|
||||
|
||||
/** @ingroup altcp_tls
|
||||
* Add a certificate to an ALTCP_TLS server configuration handle
|
||||
*/
|
||||
err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config,
|
||||
const u8_t *privkey, size_t privkey_len,
|
||||
const u8_t *privkey_pass, size_t privkey_pass_len,
|
||||
const u8_t *cert, size_t cert_len);
|
||||
|
||||
/** @ingroup altcp_tls
|
||||
* Create an ALTCP_TLS server configuration handle with one certificate
|
||||
* (short version of calling @ref altcp_tls_create_config_server and
|
||||
* @ref altcp_tls_config_server_add_privkey_cert)
|
||||
*/
|
||||
struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len,
|
||||
const u8_t *privkey_pass, size_t privkey_pass_len,
|
||||
@@ -84,6 +99,17 @@ struct altcp_tls_config *altcp_tls_create_config_client_2wayauth(const u8_t *ca,
|
||||
*/
|
||||
void altcp_tls_free_config(struct altcp_tls_config *conf);
|
||||
|
||||
/** @ingroup altcp_tls
|
||||
* Free an ALTCP_TLS global entropy instance.
|
||||
* All ALTCP_TLS configuration are linked to one altcp_tls_entropy_rng structure
|
||||
* that handle an unique system entropy & ctr_drbg instance.
|
||||
* This function allow application to free this altcp_tls_entropy_rng structure
|
||||
* when all configuration referencing it were destroyed.
|
||||
* This function does nothing if some ALTCP_TLS configuration handle are still
|
||||
* active.
|
||||
*/
|
||||
void altcp_tls_free_entropy(void);
|
||||
|
||||
/** @ingroup altcp_tls
|
||||
* Create new ALTCP_TLS layer wrapping an existing pcb as inner connection (e.g. TLS over TCP)
|
||||
*/
|
||||
|
||||
@@ -55,11 +55,49 @@
|
||||
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
/** Set a session timeout in seconds for the basic session cache
|
||||
/** Configure lwIP debug level of the mbedTLS library */
|
||||
#ifndef ALTCP_MBEDTLS_LIB_DEBUG
|
||||
#define ALTCP_MBEDTLS_LIB_DEBUG LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
/** Configure minimum internal debug level of the mbedTLS library */
|
||||
#ifndef ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN
|
||||
#define ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN 0
|
||||
#endif
|
||||
|
||||
/** Enable the basic session cache
|
||||
* ATTENTION: Using a session cache can lower security by reusing keys!
|
||||
*/
|
||||
#ifndef ALTCP_MBEDTLS_USE_SESSION_CACHE
|
||||
#define ALTCP_MBEDTLS_USE_SESSION_CACHE 0
|
||||
#endif
|
||||
|
||||
/** Maximum cache size of the basic session cache */
|
||||
#ifndef ALTCP_MBEDTLS_SESSION_CACHE_SIZE
|
||||
#define ALTCP_MBEDTLS_SESSION_CACHE_SIZE 30
|
||||
#endif
|
||||
|
||||
/** Set a session timeout in seconds for the basic session cache */
|
||||
#ifndef ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
|
||||
#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS 0
|
||||
#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS (60 * 60)
|
||||
#endif
|
||||
|
||||
/** Use session tickets to speed up connection setup (needs
|
||||
* MBEDTLS_SSL_SESSION_TICKETS enabled in mbedTLS config).
|
||||
* ATTENTION: Using session tickets can lower security by reusing keys!
|
||||
*/
|
||||
#ifndef ALTCP_MBEDTLS_USE_SESSION_TICKETS
|
||||
#define ALTCP_MBEDTLS_USE_SESSION_TICKETS 0
|
||||
#endif
|
||||
|
||||
/** Session ticket cipher */
|
||||
#ifndef ALTCP_MBEDTLS_SESSION_TICKET_CIPHER
|
||||
#define ALTCP_MBEDTLS_SESSION_TICKET_CIPHER MBEDTLS_CIPHER_AES_256_GCM
|
||||
#endif
|
||||
|
||||
/** Maximum timeout for session tickets */
|
||||
#ifndef ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS
|
||||
#define ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS (60 * 60 * 24)
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_ALTCP */
|
||||
|
||||
@@ -67,11 +67,11 @@ void sntp_setservername(u8_t idx, const char *server);
|
||||
const char *sntp_getservername(u8_t idx);
|
||||
#endif /* SNTP_SERVER_DNS */
|
||||
|
||||
#if SNTP_GET_SERVERS_FROM_DHCP
|
||||
#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
|
||||
void sntp_servermode_dhcp(int set_servers_from_dhcp);
|
||||
#else /* SNTP_GET_SERVERS_FROM_DHCP */
|
||||
#else /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
|
||||
#define sntp_servermode_dhcp(x)
|
||||
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
|
||||
#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -67,6 +67,12 @@
|
||||
#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV
|
||||
#endif
|
||||
|
||||
/** Set this to 1 to implement the callback function called by dhcpv6 when
|
||||
* NTP servers are received. */
|
||||
#if !defined SNTP_GET_SERVERS_FROM_DHCPV6 || defined __DOXYGEN__
|
||||
#define SNTP_GET_SERVERS_FROM_DHCPV6 LWIP_DHCP6_GET_NTP_SRV
|
||||
#endif
|
||||
|
||||
/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers
|
||||
* One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
|
||||
* \#define SNTP_SERVER_ADDRESS "pool.ntp.org"
|
||||
|
||||
@@ -120,9 +120,7 @@
|
||||
#endif /* LWIP_NOASSERT */
|
||||
|
||||
#ifndef LWIP_ERROR
|
||||
#ifndef LWIP_NOASSERT
|
||||
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message)
|
||||
#elif defined LWIP_DEBUG
|
||||
#ifdef LWIP_DEBUG
|
||||
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message))
|
||||
#else
|
||||
#define LWIP_PLATFORM_ERROR(message)
|
||||
|
||||
@@ -83,14 +83,14 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define lwip_htons(x) (x)
|
||||
#define lwip_ntohs(x) (x)
|
||||
#define lwip_htonl(x) (x)
|
||||
#define lwip_ntohl(x) (x)
|
||||
#define PP_HTONS(x) (x)
|
||||
#define PP_NTOHS(x) (x)
|
||||
#define PP_HTONL(x) (x)
|
||||
#define PP_NTOHL(x) (x)
|
||||
#define lwip_htons(x) ((u16_t)(x))
|
||||
#define lwip_ntohs(x) ((u16_t)(x))
|
||||
#define lwip_htonl(x) ((u32_t)(x))
|
||||
#define lwip_ntohl(x) ((u32_t)(x))
|
||||
#define PP_HTONS(x) ((u16_t)(x))
|
||||
#define PP_NTOHS(x) ((u16_t)(x))
|
||||
#define PP_HTONL(x) ((u32_t)(x))
|
||||
#define PP_NTOHL(x) ((u32_t)(x))
|
||||
#else /* BYTE_ORDER != BIG_ENDIAN */
|
||||
#ifndef lwip_htons
|
||||
u16_t lwip_htons(u16_t x);
|
||||
|
||||
@@ -49,14 +49,6 @@ extern "C" {
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Define LWIP_ERR_T in cc.h if you want to use
|
||||
* a different type for your platform (must be signed). */
|
||||
#ifdef LWIP_ERR_T
|
||||
typedef LWIP_ERR_T err_t;
|
||||
#else /* LWIP_ERR_T */
|
||||
typedef s8_t err_t;
|
||||
#endif /* LWIP_ERR_T*/
|
||||
|
||||
/** Definitions for error constants. */
|
||||
typedef enum {
|
||||
/** No error, everything OK. */
|
||||
@@ -96,6 +88,14 @@ typedef enum {
|
||||
ERR_ARG = -16
|
||||
} err_enum_t;
|
||||
|
||||
/** Define LWIP_ERR_T in cc.h if you want to use
|
||||
* a different type for your platform (must be signed). */
|
||||
#ifdef LWIP_ERR_T
|
||||
typedef LWIP_ERR_T err_t;
|
||||
#else /* LWIP_ERR_T */
|
||||
typedef s8_t err_t;
|
||||
#endif /* LWIP_ERR_T*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -49,7 +49,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef IF_NAMESIZE
|
||||
#define IF_NAMESIZE NETIF_NAMESIZE
|
||||
#endif
|
||||
|
||||
char * lwip_if_indextoname(unsigned int ifindex, char *ifname);
|
||||
unsigned int lwip_if_nametoindex(const char *ifname);
|
||||
|
||||
@@ -54,7 +54,7 @@ extern "C" {
|
||||
/** x.X.x: Minor version of the stack */
|
||||
#define LWIP_VERSION_MINOR 1
|
||||
/** x.x.X: Revision of the stack */
|
||||
#define LWIP_VERSION_REVISION 0
|
||||
#define LWIP_VERSION_REVISION 3
|
||||
/** 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) */
|
||||
|
||||
@@ -386,6 +386,10 @@ struct netif {
|
||||
#if LWIP_LOOPBACK_MAX_PBUFS
|
||||
u16_t loop_cnt_current;
|
||||
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
|
||||
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
|
||||
/* Used if the original scheduling failed. */
|
||||
u8_t reschedule_poll;
|
||||
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
|
||||
#endif /* ENABLE_LOOPBACK */
|
||||
};
|
||||
|
||||
@@ -451,7 +455,7 @@ void netif_set_gw(struct netif *netif, const ip4_addr_t *gw);
|
||||
|
||||
#define netif_set_flags(netif, set_flags) do { (netif)->flags = (u8_t)((netif)->flags | (set_flags)); } while(0)
|
||||
#define netif_clear_flags(netif, clr_flags) do { (netif)->flags = (u8_t)((netif)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
|
||||
#define netif_is_flag_set(nefif, flag) (((netif)->flags & (flag)) != 0)
|
||||
#define netif_is_flag_set(netif, flag) (((netif)->flags & (flag)) != 0)
|
||||
|
||||
void netif_set_up(struct netif *netif);
|
||||
void netif_set_down(struct netif *netif);
|
||||
|
||||
@@ -1545,7 +1545,7 @@
|
||||
* TCP_MSS, IP header, and link header.
|
||||
*/
|
||||
#if !defined PBUF_POOL_BUFSIZE || defined __DOXYGEN__
|
||||
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
|
||||
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+PBUF_IP_HLEN+PBUF_TRANSPORT_HLEN+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -1555,6 +1555,14 @@
|
||||
#if !defined LWIP_PBUF_REF_T || defined __DOXYGEN__
|
||||
#define LWIP_PBUF_REF_T u8_t
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_PBUF_CUSTOM_DATA: Store private data on pbufs (e.g. timestamps)
|
||||
* This extends struct pbuf so user can store custom data on every pbuf.
|
||||
*/
|
||||
#if !defined LWIP_PBUF_CUSTOM_DATA || defined __DOXYGEN__
|
||||
#define LWIP_PBUF_CUSTOM_DATA
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -1912,11 +1920,8 @@
|
||||
|
||||
/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread,
|
||||
* writing from a 2nd thread and closing from a 3rd thread at the same time.
|
||||
* ATTENTION: This is currently really alpha! Some requirements:
|
||||
* - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from
|
||||
* multiple threads at once
|
||||
* - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox
|
||||
* and prevent a task pending on this during/after deletion
|
||||
* LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from
|
||||
* multiple threads at once!
|
||||
*/
|
||||
#if !defined LWIP_NETCONN_FULLDUPLEX || defined __DOXYGEN__
|
||||
#define LWIP_NETCONN_FULLDUPLEX 0
|
||||
@@ -2446,7 +2451,7 @@
|
||||
* network startup.
|
||||
*/
|
||||
#if !defined LWIP_IPV6_SEND_ROUTER_SOLICIT || defined __DOXYGEN__
|
||||
#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
|
||||
#define LWIP_IPV6_SEND_ROUTER_SOLICIT LWIP_IPV6
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -2491,10 +2496,12 @@
|
||||
|
||||
/**
|
||||
* LWIP_ICMP6_DATASIZE: bytes from original packet to send back in
|
||||
* ICMPv6 error messages.
|
||||
* ICMPv6 error messages (0 = default of IP6_MIN_MTU_LENGTH)
|
||||
* ATTENTION: RFC4443 section 2.4 says IP6_MIN_MTU_LENGTH is a MUST,
|
||||
* so override this only if you absolutely have to!
|
||||
*/
|
||||
#if !defined LWIP_ICMP6_DATASIZE || defined __DOXYGEN__
|
||||
#define LWIP_ICMP6_DATASIZE 8
|
||||
#define LWIP_ICMP6_DATASIZE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -219,6 +219,9 @@ struct pbuf {
|
||||
|
||||
/** For incoming packets, this contains the input netif's index */
|
||||
u8_t if_idx;
|
||||
|
||||
/** In case the user needs to store data custom data on a pbuf */
|
||||
LWIP_PBUF_CUSTOM_DATA
|
||||
};
|
||||
|
||||
|
||||
@@ -293,6 +296,7 @@ void pbuf_cat(struct pbuf *head, struct pbuf *tail);
|
||||
void pbuf_chain(struct pbuf *head, struct pbuf *tail);
|
||||
struct pbuf *pbuf_dechain(struct pbuf *p);
|
||||
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from);
|
||||
err_t pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset);
|
||||
u16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
|
||||
void *pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset);
|
||||
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len);
|
||||
|
||||
@@ -85,6 +85,11 @@ typedef err_t (*altcp_get_tcp_addrinfo_fn)(struct altcp_pcb *conn, int local, ip
|
||||
typedef ip_addr_t *(*altcp_get_ip_fn)(struct altcp_pcb *conn, int local);
|
||||
typedef u16_t (*altcp_get_port_fn)(struct altcp_pcb *conn, int local);
|
||||
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
typedef void (*altcp_keepalive_disable_fn)(struct altcp_pcb *conn);
|
||||
typedef void (*altcp_keepalive_enable_fn)(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
|
||||
#endif
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
typedef enum tcp_state (*altcp_dbg_get_tcp_state_fn)(struct altcp_pcb *conn);
|
||||
#endif
|
||||
@@ -111,6 +116,10 @@ struct altcp_functions {
|
||||
altcp_get_tcp_addrinfo_fn addrinfo;
|
||||
altcp_get_ip_fn getip;
|
||||
altcp_get_port_fn getport;
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
altcp_keepalive_disable_fn keepalive_disable;
|
||||
altcp_keepalive_enable_fn keepalive_enable;
|
||||
#endif
|
||||
#ifdef LWIP_DEBUG
|
||||
altcp_dbg_get_tcp_state_fn dbg_get_tcp_state;
|
||||
#endif
|
||||
@@ -133,6 +142,10 @@ void altcp_default_dealloc(struct altcp_pcb *conn);
|
||||
err_t altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
|
||||
ip_addr_t *altcp_default_get_ip(struct altcp_pcb *conn, int local);
|
||||
u16_t altcp_default_get_port(struct altcp_pcb *conn, int local);
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
void altcp_default_keepalive_disable(struct altcp_pcb *conn);
|
||||
void altcp_default_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
|
||||
#endif
|
||||
#ifdef LWIP_DEBUG
|
||||
enum tcp_state altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn);
|
||||
#endif
|
||||
|
||||
@@ -146,6 +146,8 @@ PACK_STRUCT_END
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
#define ICMP6_HLEN 8
|
||||
|
||||
/** This is the ICMP6 header adapted for echo req/resp. */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IP6_MIN_MTU_LENGTH 1280
|
||||
|
||||
/** This is the packed version of ip6_addr_t,
|
||||
used in network headers that are itself packed */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
|
||||
@@ -44,6 +44,13 @@
|
||||
#define PPPOE_SUPPORT 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* PPPOE_SCNAME_SUPPORT==1: Enable PPP Over Ethernet Service Name and Concentrator Name support
|
||||
*/
|
||||
#ifndef PPPOE_SCNAME_SUPPORT
|
||||
#define PPPOE_SCNAME_SUPPORT 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* PPPOL2TP_SUPPORT==1: Enable PPP Over L2TP
|
||||
*/
|
||||
|
||||
@@ -149,10 +149,10 @@ struct pppoe_softc {
|
||||
u16_t sc_session; /* PPPoE session id */
|
||||
u8_t sc_state; /* discovery phase or session connected */
|
||||
|
||||
#ifdef PPPOE_TODO
|
||||
u8_t *sc_service_name; /* if != NULL: requested name of service */
|
||||
u8_t *sc_concentrator_name; /* if != NULL: requested concentrator id */
|
||||
#endif /* PPPOE_TODO */
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
const char *sc_service_name; /* if != NULL: requested name of service */
|
||||
const char *sc_concentrator_name; /* if != NULL: requested concentrator id */
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */
|
||||
u8_t sc_ac_cookie_len; /* length of cookie data */
|
||||
#ifdef PPPOE_SERVER
|
||||
|
||||
@@ -630,11 +630,11 @@ lowpan6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
|
||||
}
|
||||
|
||||
/* Send out the packet using the returned hardware address. */
|
||||
result = lowpan6_hwaddr_to_addr(netif, &dest);
|
||||
if (result != ERR_OK) {
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
|
||||
return result;
|
||||
}
|
||||
dest.addr_len = netif->hwaddr_len;
|
||||
/* XXX: Inferring the length of the source address from the destination address
|
||||
* is not correct for IEEE 802.15.4, but currently we don't get this information
|
||||
* from the neighbor cache */
|
||||
SMEMCPY(dest.addr, hwaddr, netif->hwaddr_len);
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
|
||||
return lowpan6_frag(netif, q, &src, &dest);
|
||||
}
|
||||
@@ -881,7 +881,7 @@ lowpan6_if_init(struct netif *netif)
|
||||
MIB2_INIT_NETIF(netif, snmp_ifType_other, 0);
|
||||
|
||||
/* maximum transfer unit */
|
||||
netif->mtu = 1280;
|
||||
netif->mtu = IP6_MIN_MTU_LENGTH;
|
||||
|
||||
/* broadcast capability */
|
||||
netif->flags = NETIF_FLAG_BROADCAST /* | NETIF_FLAG_LOWPAN6 */;
|
||||
|
||||
@@ -417,7 +417,7 @@ rfc7668_if_init(struct netif *netif)
|
||||
MIB2_INIT_NETIF(netif, snmp_ifType_other, 0);
|
||||
|
||||
/* maximum transfer unit, set according to RFC7668 ch2.4 */
|
||||
netif->mtu = 1280;
|
||||
netif->mtu = IP6_MIN_MTU_LENGTH;
|
||||
|
||||
/* no flags set (no broadcast, ethernet,...)*/
|
||||
netif->flags = 0;
|
||||
|
||||
@@ -440,7 +440,7 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
if ((lowpan6_buffer[0] & 0x18) == 0x00) {
|
||||
header_temp = ((lowpan6_buffer[lowpan6_offset+1] & 0x0f) << 16) | \
|
||||
(lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset+3];
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 00, ECN: 0x%2x, Flowlabel+DSCP: 0x%8X\n", \
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 00, ECN: 0x%"X8_F", Flowlabel+DSCP: 0x%8"X32_F"\n", \
|
||||
lowpan6_buffer[lowpan6_offset],header_temp));
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], header_temp);
|
||||
/* increase offset, processed 4 bytes here:
|
||||
@@ -448,14 +448,14 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
lowpan6_offset += 4;
|
||||
} else if ((lowpan6_buffer[0] & 0x18) == 0x08) {
|
||||
header_temp = ((lowpan6_buffer[lowpan6_offset] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset+2];
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 01, ECN: 0x%2x, Flowlabel: 0x%2X, DSCP ignored\n", \
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 01, ECN: 0x%"X8_F", Flowlabel: 0x%2"X32_F", DSCP ignored\n", \
|
||||
lowpan6_buffer[lowpan6_offset] & 0xc0,header_temp));
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset] & 0xc0, header_temp);
|
||||
/* increase offset, processed 3 bytes here:
|
||||
* TF=01: ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided.*/
|
||||
lowpan6_offset += 3;
|
||||
} else if ((lowpan6_buffer[0] & 0x18) == 0x10) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 10, DCSP+ECN: 0x%2x, Flowlabel ignored\n", lowpan6_buffer[lowpan6_offset]));
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 10, DCSP+ECN: 0x%"X8_F", Flowlabel ignored\n", lowpan6_buffer[lowpan6_offset]));
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset],0);
|
||||
/* increase offset, processed 1 byte here:
|
||||
* ECN + DSCP (1 byte), Flow Label is elided.*/
|
||||
@@ -564,7 +564,7 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
|
||||
ip6hdr->src.addr[0] = lowpan6_contexts[i].addr[0];
|
||||
ip6hdr->src.addr[1] = lowpan6_contexts[i].addr[1];
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == xx, context compression found @%d: %8X, %8X\n", (int)i, ip6hdr->src.addr[0], ip6hdr->src.addr[1]));
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == xx, context compression found @%d: %8"X32_F", %8"X32_F"\n", (int)i, ip6hdr->src.addr[0], ip6hdr->src.addr[1]));
|
||||
#else
|
||||
LWIP_UNUSED_ARG(lowpan6_contexts);
|
||||
#endif
|
||||
|
||||
@@ -216,7 +216,8 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protoc
|
||||
/***********************************/
|
||||
#if PPP_AUTH_SUPPORT
|
||||
void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) {
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD", pcb->phase == PPP_PHASE_DEAD);
|
||||
|
||||
#if PAP_SUPPORT
|
||||
pcb->settings.refuse_pap = !(authtype & PPPAUTHTYPE_PAP);
|
||||
#endif /* PAP_SUPPORT */
|
||||
@@ -238,6 +239,8 @@ void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *pas
|
||||
#if MPPE_SUPPORT
|
||||
/* Set MPPE configuration */
|
||||
void ppp_set_mppe(ppp_pcb *pcb, u8_t flags) {
|
||||
LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD", pcb->phase == PPP_PHASE_DEAD);
|
||||
|
||||
if (flags == PPP_MPPE_DISABLE) {
|
||||
pcb->settings.require_mppe = 0;
|
||||
return;
|
||||
|
||||
@@ -175,8 +175,10 @@ ppp_pcb *pppoe_create(struct netif *pppif,
|
||||
{
|
||||
ppp_pcb *ppp;
|
||||
struct pppoe_softc *sc;
|
||||
#if !PPPOE_SCNAME_SUPPORT
|
||||
LWIP_UNUSED_ARG(service_name);
|
||||
LWIP_UNUSED_ARG(concentrator_name);
|
||||
#endif /* !PPPOE_SCNAME_SUPPORT */
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
|
||||
sc = (struct pppoe_softc *)LWIP_MEMPOOL_ALLOC(PPPOE_IF);
|
||||
@@ -193,6 +195,10 @@ ppp_pcb *pppoe_create(struct netif *pppif,
|
||||
memset(sc, 0, sizeof(struct pppoe_softc));
|
||||
sc->pcb = ppp;
|
||||
sc->sc_ethif = ethif;
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
sc->sc_service_name = service_name;
|
||||
sc->sc_concentrator_name = concentrator_name;
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
/* put the new interface at the head of the list */
|
||||
sc->next = pppoe_softc_list;
|
||||
pppoe_softc_list = sc;
|
||||
@@ -300,15 +306,6 @@ pppoe_destroy(ppp_pcb *ppp, void *ctx)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PPPOE_TODO
|
||||
if (sc->sc_concentrator_name) {
|
||||
mem_free(sc->sc_concentrator_name);
|
||||
}
|
||||
if (sc->sc_service_name) {
|
||||
mem_free(sc->sc_service_name);
|
||||
}
|
||||
#endif /* PPPOE_TODO */
|
||||
LWIP_MEMPOOL_FREE(PPPOE_IF, sc);
|
||||
|
||||
return ERR_OK;
|
||||
@@ -757,13 +754,13 @@ pppoe_send_padi(struct pppoe_softc *sc)
|
||||
struct pbuf *pb;
|
||||
u8_t *p;
|
||||
int len;
|
||||
#ifdef PPPOE_TODO
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
int l1 = 0, l2 = 0; /* XXX: gcc */
|
||||
#endif /* PPPOE_TODO */
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
|
||||
/* calculate length of frame (excluding ethernet header + pppoe header) */
|
||||
len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */
|
||||
#ifdef PPPOE_TODO
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
if (sc->sc_service_name != NULL) {
|
||||
l1 = (int)strlen(sc->sc_service_name);
|
||||
len += l1;
|
||||
@@ -772,7 +769,7 @@ pppoe_send_padi(struct pppoe_softc *sc)
|
||||
l2 = (int)strlen(sc->sc_concentrator_name);
|
||||
len += 2 + 2 + l2;
|
||||
}
|
||||
#endif /* PPPOE_TODO */
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
|
||||
sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
|
||||
|
||||
@@ -787,24 +784,24 @@ pppoe_send_padi(struct pppoe_softc *sc)
|
||||
/* fill in pkt */
|
||||
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len);
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
|
||||
#ifdef PPPOE_TODO
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
if (sc->sc_service_name != NULL) {
|
||||
PPPOE_ADD_16(p, l1);
|
||||
MEMCPY(p, sc->sc_service_name, l1);
|
||||
p += l1;
|
||||
} else
|
||||
#endif /* PPPOE_TODO */
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
{
|
||||
PPPOE_ADD_16(p, 0);
|
||||
}
|
||||
#ifdef PPPOE_TODO
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
if (sc->sc_concentrator_name != NULL) {
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
|
||||
PPPOE_ADD_16(p, l2);
|
||||
MEMCPY(p, sc->sc_concentrator_name, l2);
|
||||
p += l2;
|
||||
}
|
||||
#endif /* PPPOE_TODO */
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
|
||||
PPPOE_ADD_16(p, sizeof(sc));
|
||||
MEMCPY(p, &sc, sizeof sc);
|
||||
@@ -982,17 +979,17 @@ pppoe_send_padr(struct pppoe_softc *sc)
|
||||
struct pbuf *pb;
|
||||
u8_t *p;
|
||||
size_t len;
|
||||
#ifdef PPPOE_TODO
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
size_t l1 = 0; /* XXX: gcc */
|
||||
#endif /* PPPOE_TODO */
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
|
||||
len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */
|
||||
#ifdef PPPOE_TODO
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
if (sc->sc_service_name != NULL) { /* service name tag maybe empty */
|
||||
l1 = strlen(sc->sc_service_name);
|
||||
len += l1;
|
||||
}
|
||||
#endif /* PPPOE_TODO */
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
if (sc->sc_ac_cookie_len > 0) {
|
||||
len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */
|
||||
}
|
||||
@@ -1006,13 +1003,13 @@ pppoe_send_padr(struct pppoe_softc *sc)
|
||||
p = (u8_t*)pb->payload;
|
||||
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
|
||||
#ifdef PPPOE_TODO
|
||||
#if PPPOE_SCNAME_SUPPORT
|
||||
if (sc->sc_service_name != NULL) {
|
||||
PPPOE_ADD_16(p, l1);
|
||||
MEMCPY(p, sc->sc_service_name, l1);
|
||||
p += l1;
|
||||
} else
|
||||
#endif /* PPPOE_TODO */
|
||||
#endif /* PPPOE_SCNAME_SUPPORT */
|
||||
{
|
||||
PPPOE_ADD_16(p, 0);
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ pppos_input(ppp_pcb *ppp, u8_t *s, int l)
|
||||
u8_t cur_char;
|
||||
u8_t escaped;
|
||||
PPPOS_DECL_PROTECT(lev);
|
||||
#if PPP_INPROC_IRQ_SAFE
|
||||
#if !PPP_INPROC_IRQ_SAFE
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ zepif_linkoutput(struct netif *netif, struct pbuf *p)
|
||||
state->seqno++;
|
||||
zep->len = (u8_t)p->tot_len;
|
||||
|
||||
err = pbuf_take_at(q, p->payload, p->tot_len, sizeof(struct zep_hdr));
|
||||
err = pbuf_copy_partial_pbuf(q, p, p->tot_len, sizeof(struct zep_hdr));
|
||||
if (err == ERR_OK) {
|
||||
#if ZEPIF_LOOPBACK
|
||||
zepif_udp_recv(netif, state->pcb, pbuf_clone(PBUF_RAW, PBUF_RAM, q), NULL, 0);
|
||||
|
||||
@@ -365,7 +365,23 @@ sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg)
|
||||
}
|
||||
|
||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||
#error LWIP_NETCONN_SEM_PER_THREAD==1 not supported
|
||||
/* Simple implementation of this: unit tests only support one thread */
|
||||
static sys_sem_t global_netconn_sem;
|
||||
|
||||
sys_sem_t* sys_arch_netconn_sem_get(void)
|
||||
{
|
||||
return &global_netconn_sem;
|
||||
}
|
||||
|
||||
void sys_arch_netconn_sem_alloc(void)
|
||||
{
|
||||
sys_sem_new(&global_netconn_sem, 0);
|
||||
}
|
||||
|
||||
void sys_arch_netconn_sem_free(void)
|
||||
{
|
||||
sys_sem_free(&global_netconn_sem);
|
||||
}
|
||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
|
||||
#endif /* !NO_SYS */
|
||||
|
||||
@@ -68,5 +68,12 @@ void test_sys_arch_wait_callback(test_sys_arch_waiting_fn waiting_fn);
|
||||
/* current time */
|
||||
extern u32_t lwip_sys_now;
|
||||
|
||||
sys_sem_t* sys_arch_netconn_sem_get(void);
|
||||
void sys_arch_netconn_sem_alloc(void);
|
||||
void sys_arch_netconn_sem_free(void);
|
||||
#define LWIP_NETCONN_THREAD_SEM_GET() sys_arch_netconn_sem_get()
|
||||
#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc()
|
||||
#define LWIP_NETCONN_THREAD_SEM_FREE() sys_arch_netconn_sem_free()
|
||||
|
||||
#endif /* LWIP_HDR_TEST_SYS_ARCH_H */
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#error "This tests needs LWIP_NETIF_EXT_STATUS_CALLBACK enabled"
|
||||
#endif
|
||||
|
||||
struct netif net_test;
|
||||
static struct netif net_test;
|
||||
|
||||
|
||||
/* Setups/teardown functions */
|
||||
@@ -215,13 +215,67 @@ START_TEST(test_netif_extcallbacks)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_netif_flag_set)
|
||||
{
|
||||
ip4_addr_t addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
LWIP_UNUSED_ARG(_i);
|
||||
|
||||
IP4_ADDR(&addr, 0, 0, 0, 0);
|
||||
IP4_ADDR(&netmask, 0, 0, 0, 0);
|
||||
IP4_ADDR(&gw, 0, 0, 0, 0);
|
||||
|
||||
netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
|
||||
|
||||
fail_if(netif_is_flag_set(&net_test, NETIF_FLAG_UP));
|
||||
fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_BROADCAST));
|
||||
fail_if(netif_is_flag_set(&net_test, NETIF_FLAG_LINK_UP));
|
||||
fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_ETHARP));
|
||||
fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_ETHERNET));
|
||||
fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_IGMP));
|
||||
fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_MLD6));
|
||||
|
||||
netif_remove(&net_test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_netif_find)
|
||||
{
|
||||
struct netif net0;
|
||||
struct netif net1;
|
||||
LWIP_UNUSED_ARG(_i);
|
||||
|
||||
/* No netifs available */
|
||||
fail_unless(netif_find("ch0") == NULL);
|
||||
|
||||
/* Add netifs with known names */
|
||||
fail_unless(netif_add_noaddr(&net0, NULL, testif_init, ethernet_input) == &net0);
|
||||
net0.num = 0;
|
||||
fail_unless(netif_add_noaddr(&net1, NULL, testif_init, ethernet_input) == &net1);
|
||||
net1.num = 1;
|
||||
|
||||
fail_unless(netif_find("ch0") == &net0);
|
||||
fail_unless(netif_find("CH0") == NULL);
|
||||
fail_unless(netif_find("ch1") == &net1);
|
||||
fail_unless(netif_find("ch3") == NULL);
|
||||
/* atoi failure is not treated as zero */
|
||||
fail_unless(netif_find("chX") == NULL);
|
||||
fail_unless(netif_find("ab0") == NULL);
|
||||
|
||||
netif_remove(&net0);
|
||||
netif_remove(&net1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/** Create the suite including all tests for this module */
|
||||
Suite *
|
||||
netif_suite(void)
|
||||
{
|
||||
testfunc tests[] = {
|
||||
TESTFUNC(test_netif_extcallbacks)
|
||||
TESTFUNC(test_netif_extcallbacks),
|
||||
TESTFUNC(test_netif_flag_set),
|
||||
TESTFUNC(test_netif_find)
|
||||
};
|
||||
return create_suite("NETIF", tests, sizeof(tests)/sizeof(testfunc), netif_setup, netif_teardown);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "lwip/etharp.h"
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
struct netif net_test;
|
||||
static struct netif net_test;
|
||||
|
||||
static const u8_t broadcast[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
|
||||
@@ -287,6 +287,43 @@ START_TEST(test_ip6_lladdr)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Reproduces bug #57374 */
|
||||
START_TEST(test_ip6_frag_pbuf_len_assert)
|
||||
{
|
||||
ip_addr_t my_addr = IPADDR6_INIT_HOST(0x20010db8, 0x0, 0x0, 0x1);
|
||||
ip_addr_t peer_addr = IPADDR6_INIT_HOST(0x20010db8, 0x0, 0x0, 0x4);
|
||||
struct pbuf *payload, *hdr;
|
||||
err_t err;
|
||||
int i;
|
||||
|
||||
/* Configure and enable local address */
|
||||
test_netif6.mtu = 1500;
|
||||
netif_set_up(&test_netif6);
|
||||
netif_ip6_addr_set(&test_netif6, 0, ip_2_ip6(&my_addr));
|
||||
netif_ip6_addr_set_state(&test_netif6, 0, IP6_ADDR_VALID);
|
||||
|
||||
/* Create packet with lots of small pbufs around mtu limit */
|
||||
payload = pbuf_alloc(PBUF_RAW, 1400, PBUF_POOL);
|
||||
fail_unless(payload != NULL);
|
||||
for (i = 0; i < 16; i++) {
|
||||
struct pbuf *p = pbuf_alloc(PBUF_RAW, 32, PBUF_RAM);
|
||||
fail_unless(p != NULL);
|
||||
pbuf_cat(payload, p);
|
||||
}
|
||||
/* Prefix with header like UDP would */
|
||||
hdr = pbuf_alloc(PBUF_IP, 8, PBUF_RAM);
|
||||
fail_unless(hdr != NULL);
|
||||
pbuf_chain(hdr, payload);
|
||||
|
||||
/* Send it and don't crash while fragmenting */
|
||||
err = ip6_output_if_src(hdr, ip_2_ip6(&my_addr), ip_2_ip6(&peer_addr), 15, 0, IP_PROTO_UDP, &test_netif6);
|
||||
fail_unless(err == ERR_OK);
|
||||
|
||||
pbuf_free(hdr);
|
||||
pbuf_free(payload);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/** Create the suite including all tests for this module */
|
||||
Suite *
|
||||
ip6_suite(void)
|
||||
@@ -296,7 +333,8 @@ ip6_suite(void)
|
||||
TESTFUNC(test_ip6_aton_ipv4mapped),
|
||||
TESTFUNC(test_ip6_ntoa_ipv4mapped),
|
||||
TESTFUNC(test_ip6_ntoa),
|
||||
TESTFUNC(test_ip6_lladdr)
|
||||
TESTFUNC(test_ip6_lladdr),
|
||||
TESTFUNC(test_ip6_frag_pbuf_len_assert)
|
||||
};
|
||||
return create_suite("IPv6", tests, sizeof(tests)/sizeof(testfunc), ip6_setup, ip6_teardown);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define EXPECT_RETX(x, y) do { fail_unless(x); if(!(x)) { return y; }} while(0)
|
||||
#define EXPECT_RETNULL(x) EXPECT_RETX(x, NULL)
|
||||
|
||||
#if (CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13)
|
||||
typedef struct {
|
||||
TFun func;
|
||||
const char *name;
|
||||
@@ -24,6 +25,15 @@ typedef struct {
|
||||
#define tcase_add_named_test(tc,tf) \
|
||||
_tcase_add_test((tc),(tf).func,(tf).name,0, 0, 0, 1)
|
||||
|
||||
#else
|
||||
/* From 0.13.0 check keeps track of the method name internally */
|
||||
typedef const TTest * testfunc;
|
||||
|
||||
#define TESTFUNC(x) x
|
||||
|
||||
#define tcase_add_named_test(tc,tf) tcase_add_test(tc,tf)
|
||||
#endif
|
||||
|
||||
/** typedef for a function returning a test suite */
|
||||
typedef Suite* (suite_getter_fn)(void);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#define LWIP_NETCONN !NO_SYS
|
||||
#define LWIP_SOCKET !NO_SYS
|
||||
#define LWIP_NETCONN_FULLDUPLEX LWIP_SOCKET
|
||||
#define LWIP_NETCONN_SEM_PER_THREAD 1
|
||||
#define LWIP_NETBUF_RECVINFO 1
|
||||
#define LWIP_HAVE_LOOPIF 1
|
||||
#define TCPIP_THREAD_TEST
|
||||
|
||||
@@ -94,6 +94,8 @@ START_TEST(basic_connect)
|
||||
p = pbuf_alloc(PBUF_RAW, sizeof(rxbuf), PBUF_REF);
|
||||
fail_unless(p != NULL);
|
||||
p->payload = rxbuf;
|
||||
/* since we hack the rx path, we have to hack the rx window, too: */
|
||||
client->conn->rcv_wnd -= p->tot_len;
|
||||
if (client->conn->recv(client->conn->callback_arg, client->conn, p, ERR_OK) != ERR_OK) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
@@ -330,6 +330,53 @@ START_TEST(test_tcp_passive_close)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_tcp_active_abort)
|
||||
{
|
||||
struct test_tcp_counters counters;
|
||||
struct tcp_pcb* pcb;
|
||||
char data = 0x0f;
|
||||
struct netif netif;
|
||||
struct test_tcp_txcounters txcounters;
|
||||
LWIP_UNUSED_ARG(_i);
|
||||
|
||||
memset(&txcounters, 0, sizeof(txcounters));
|
||||
|
||||
/* initialize local vars */
|
||||
test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
|
||||
|
||||
/* initialize counter struct */
|
||||
memset(&counters, 0, sizeof(counters));
|
||||
counters.expected_data_len = 1;
|
||||
counters.expected_data = &data;
|
||||
|
||||
/* create and initialize the pcb */
|
||||
pcb = test_tcp_new_counters_pcb(&counters);
|
||||
EXPECT_RET(pcb != NULL);
|
||||
tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
|
||||
|
||||
/* abort the pcb */
|
||||
EXPECT_RET(txcounters.num_tx_calls == 0);
|
||||
txcounters.copy_tx_packets = 1;
|
||||
tcp_abort(pcb);
|
||||
txcounters.copy_tx_packets = 0;
|
||||
EXPECT(txcounters.num_tx_calls == 1);
|
||||
EXPECT(txcounters.num_tx_bytes == 40U);
|
||||
EXPECT(txcounters.tx_packets != NULL);
|
||||
if (txcounters.tx_packets != NULL) {
|
||||
u16_t ret;
|
||||
struct tcp_hdr tcphdr;
|
||||
ret = pbuf_copy_partial(txcounters.tx_packets, &tcphdr, 20, 20);
|
||||
EXPECT(ret == 20);
|
||||
EXPECT(tcphdr.dest == PP_HTONS(TEST_REMOTE_PORT));
|
||||
EXPECT(tcphdr.src == PP_HTONS(TEST_LOCAL_PORT));
|
||||
pbuf_free(txcounters.tx_packets);
|
||||
txcounters.tx_packets = NULL;
|
||||
}
|
||||
|
||||
/* don't free the pcb here (part of the test!) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/** Check that we handle malformed tcp headers, and discard the pbuf(s) */
|
||||
START_TEST(test_tcp_malformed_header)
|
||||
{
|
||||
@@ -1627,6 +1674,7 @@ tcp_suite(void)
|
||||
TESTFUNC(test_tcp_recv_inseq),
|
||||
TESTFUNC(test_tcp_recv_inseq_trim),
|
||||
TESTFUNC(test_tcp_passive_close),
|
||||
TESTFUNC(test_tcp_active_abort),
|
||||
TESTFUNC(test_tcp_malformed_header),
|
||||
TESTFUNC(test_tcp_fast_retx_recover),
|
||||
TESTFUNC(test_tcp_fast_rexmit_wraparound),
|
||||
|
||||
@@ -335,13 +335,138 @@ START_TEST(test_udp_broadcast_rx_with_2_netifs)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_udp_bind)
|
||||
{
|
||||
struct udp_pcb* pcb1;
|
||||
struct udp_pcb* pcb2;
|
||||
ip_addr_t ip1;
|
||||
ip_addr_t ip2;
|
||||
err_t err1;
|
||||
err_t err2;
|
||||
LWIP_UNUSED_ARG(_i);
|
||||
|
||||
/* bind on same port using different IP address types */
|
||||
ip_addr_set_any_val(0, ip1);
|
||||
ip_addr_set_any_val(1, ip2);
|
||||
|
||||
pcb1 = udp_new_ip_type(IPADDR_TYPE_V4);
|
||||
pcb2 = udp_new_ip_type(IPADDR_TYPE_V6);
|
||||
|
||||
err1 = udp_bind(pcb1, &ip1, 2105);
|
||||
err2 = udp_bind(pcb2, &ip2, 2105);
|
||||
|
||||
fail_unless(err1 == ERR_OK);
|
||||
fail_unless(err2 == ERR_OK);
|
||||
|
||||
udp_remove(pcb1);
|
||||
udp_remove(pcb2);
|
||||
|
||||
/* bind on same port using SAME IPv4 address type */
|
||||
ip_addr_set_any_val(0, ip1);
|
||||
ip_addr_set_any_val(0, ip2);
|
||||
|
||||
pcb1 = udp_new_ip_type(IPADDR_TYPE_V4);
|
||||
pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
|
||||
|
||||
err1 = udp_bind(pcb1, &ip1, 2105);
|
||||
err2 = udp_bind(pcb2, &ip2, 2105);
|
||||
|
||||
fail_unless(err1 == ERR_OK);
|
||||
fail_unless(err2 == ERR_USE);
|
||||
|
||||
udp_remove(pcb1);
|
||||
udp_remove(pcb2);
|
||||
|
||||
/* bind on same port using SAME IPv6 address type */
|
||||
ip_addr_set_any_val(1, ip1);
|
||||
ip_addr_set_any_val(1, ip2);
|
||||
|
||||
pcb1 = udp_new_ip_type(IPADDR_TYPE_V6);
|
||||
pcb2 = udp_new_ip_type(IPADDR_TYPE_V6);
|
||||
|
||||
err1 = udp_bind(pcb1, &ip1, 2105);
|
||||
err2 = udp_bind(pcb2, &ip2, 2105);
|
||||
|
||||
fail_unless(err1 == ERR_OK);
|
||||
fail_unless(err2 == ERR_USE);
|
||||
|
||||
udp_remove(pcb1);
|
||||
udp_remove(pcb2);
|
||||
|
||||
/* Bind with different IP address type */
|
||||
ip_addr_set_any_val(0, ip1);
|
||||
ip_addr_set_any_val(1, ip2);
|
||||
|
||||
pcb1 = udp_new_ip_type(IPADDR_TYPE_V6);
|
||||
pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
|
||||
|
||||
err1 = udp_bind(pcb1, &ip1, 2105);
|
||||
err2 = udp_bind(pcb2, &ip2, 2105);
|
||||
|
||||
fail_unless(err1 == ERR_OK);
|
||||
fail_unless(err2 == ERR_OK);
|
||||
|
||||
udp_remove(pcb1);
|
||||
udp_remove(pcb2);
|
||||
|
||||
/* Bind with different IP numbers */
|
||||
IP_ADDR4(&ip1, 1, 2, 3, 4);
|
||||
IP_ADDR4(&ip2, 4, 3, 2, 1);
|
||||
|
||||
pcb1 = udp_new_ip_type(IPADDR_TYPE_V6);
|
||||
pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
|
||||
|
||||
err1 = udp_bind(pcb1, &ip1, 2105);
|
||||
err2 = udp_bind(pcb2, &ip2, 2105);
|
||||
|
||||
fail_unless(err1 == ERR_OK);
|
||||
fail_unless(err2 == ERR_OK);
|
||||
|
||||
udp_remove(pcb1);
|
||||
udp_remove(pcb2);
|
||||
|
||||
/* Bind with same IP numbers */
|
||||
IP_ADDR4(&ip1, 1, 2, 3, 4);
|
||||
IP_ADDR4(&ip2, 1, 2, 3, 4);
|
||||
|
||||
pcb1 = udp_new_ip_type(IPADDR_TYPE_V6);
|
||||
pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
|
||||
|
||||
err1 = udp_bind(pcb1, &ip1, 2105);
|
||||
err2 = udp_bind(pcb2, &ip2, 2105);
|
||||
|
||||
fail_unless(err1 == ERR_OK);
|
||||
fail_unless(err2 == ERR_USE);
|
||||
|
||||
udp_remove(pcb1);
|
||||
udp_remove(pcb2);
|
||||
|
||||
/* bind on same port using ANY + IPv4 */
|
||||
ip1 = *IP_ANY_TYPE;
|
||||
IP_ADDR4(&ip2, 1, 2, 3, 4);
|
||||
|
||||
pcb1 = udp_new_ip_type(IPADDR_TYPE_ANY);
|
||||
pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
|
||||
|
||||
err1 = udp_bind(pcb1, &ip1, 2105);
|
||||
err2 = udp_bind(pcb2, &ip2, 2105);
|
||||
|
||||
fail_unless(err1 == ERR_OK);
|
||||
fail_unless(err2 == ERR_USE);
|
||||
|
||||
udp_remove(pcb1);
|
||||
udp_remove(pcb2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/** Create the suite including all tests for this module */
|
||||
Suite *
|
||||
udp_suite(void)
|
||||
{
|
||||
testfunc tests[] = {
|
||||
TESTFUNC(test_udp_new_remove),
|
||||
TESTFUNC(test_udp_broadcast_rx_with_2_netifs)
|
||||
TESTFUNC(test_udp_broadcast_rx_with_2_netifs),
|
||||
TESTFUNC(test_udp_bind)
|
||||
};
|
||||
return create_suite("UDP", tests, sizeof(tests)/sizeof(testfunc), udp_setup, udp_teardown);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user