[32F417] LWIP/MbedTLS - any idea if SPI SRAM could be used for buffers? - Page 1
Forum section: electronics / general

author: peter-h
author_rank: Super Contributor
timestamp: June 29, 2022, 01:30:39 pm
content: My target has 128k SRAM which has about 60k spare, and 64k CCM which is allocated whole to FreeRTOS stacks etc (its private heap, memory model #4).I am running a simplified HTTP server (for local config etc), which uses fairly minimal RAM (a few k), and an HTTPS/TLS client which uses about 50k (for its private heap).So if both of the above are running concurrently, there is only ~10k RAM left, but it does work, but when TLS is doing its handshake/negotiation (which on a 168MHz 32F417 takes 2-3 seconds) the HTTP server temporarily hangs.Investigating this, it appears that LWIP is running out of buffers during TLS and is rejecting incoming packets.I don't really want to change the CPU to the next one up which has another 64k RAM, because a) I have stock of the 417 and this took about a year to get, b) the design is rock solid and I don't want to tempt fate (there is a lot of subtle hardware usage e.g. DAC ADC DMA timers) even though in theory it should be just alternate function pin changes, c) some versions of the product may not need TLS at all.I have an option of an 8MB SPI-attached RAMhttps://www.eevblog.com/forum/microcontrollers/lyontek-ly68l6400-8-megabyte-spi-sram-am-i-reading-the-data-sheet-right/which does work and is not bad at $3 (there are cheaper 128kbyte versions too), but obviously cannot be addressed as normal RAM. The ESP32 can do that but the 32F4 can't without a huge amount of work to do what is basically invalid address trapping and virtual memory emulationhttps://www.eevblog.com/forum/microcontrollers/st-32f417-any-way-to-make-an-spi-sram-to-look-like-normal-ram/Does anyone know enough about the internals of LWIP, and MbedTLS, to know whether the memory usage structure lends itself to this kind of "overlay" memory? One can read or write say 1k bytes in 400us, in my target (21MHz SPI with DMA). Obviously this would be horribly inefficient for a byte at a time emulation but perhaps one can switch buffers in and out...There is at least one MbedTLS "support forum" but almost nobody answers any questions there. If somebody knows of a concrete route, I am happy to pay for the time.

author: Scrts
author_rank: Frequent Contributor
timestamp: July 02, 2022, 05:18:56 am
content: Not an expert here, but instead of RAM, maybe offload TLS to some secure element? E.g. ATECC608B?

author: peter-h
author_rank: Super Contributor
timestamp: July 02, 2022, 05:34:18 am
content: That chip does only the crypto, which isn't too much of an issue. It is also unobtainable - typical Microchip situation now, 1.5 years lead time.

author: dare
author_rank: Contributor
timestamp: July 02, 2022, 04:08:30 pm
content: QuoteLwIP has a number of different memory allocation schemes, and can be straightforwardly modified to support others. However all memory use by LwIP involves fine-grained access to allocated memory blocks. This is undoubtedly true for MbedTLS as well.Modern TCP and TLS were not designed to run in highly memory constrained environments. It can be done, but it requires very careful tuning of stack behavior, allocation strategies and threading disciplines. In theory you could use your SPI ram to create an external queue of incoming packets between the network interface layer and the LwIP input function. However this would entail a fair amount of work, and really should only be done after optimizing the rest of the stack (and even then there's no guarantee it will solve the problem).Here are some ideas for optimizing things:First off, ensure that you've turned off all LwIP and MbedTLS features that you don't need. Some of these come with initialization-time memory overheads that, in simple contexts, represent completely wasted space.Second, ensure you're using the pooled allocator for all important LwIP structures (packet buffers, PCBs, etc.). Using a general heap-based allocator (e.g. malloc) invites fragmentation that can drastically reduce memory utilization efficiency.Third, ensure your TCP window size is set appropriately. If you're truly discarding incoming packets due to lack of packet buffers, the implication is that the other side is sending data too fast. This is could be because the advertised receive window size is too large.Forth, based on a quick review of some open source projects using MbedTLS with LwIP, it appears that a copy is taken when data flows out of the TCP connection and into the MbedTLS session. This is an unfortunate design, but may be unavoidable based on the way MbedTLS works. If this is the case in your context, then you need to ensure that the memory pool in MbedTLS is sized appropriately to handle the largest TLS message that will be processed. This will be dominated by the cypher suite chosen and the type of certificates used by the peer. The challenge, of course, is coming up with the memory. It may be, however, that you have too much memory devoted to the LwIP pool and not enough devoted to MbedTLS.If you have control over the types of certificated used by the peer, chose elliptic curve certs, which are smaller than RSA certs, and thus reduce the overall memory usage while receiving and processing TLS handshake messages. Additionally, if you're minting your own certificates (i.e. running your own trust domain), use certs with short distinguished names and minimal certificate extensions to further reduce certificate size.Finally, consider the effects of crypto compute overhead on your threading model. On small devices, the fundamental crypto operations can take a considerable amount of compute time; seconds in many cases. In LwIP, incoming data over a TCP connection is delivered up-stack via a callback that runs on the LwIP TCPIP thread. If this upcall ends up performing crypto operations (note: I'm not familiar enough with MbedTLS to confirm that this is true), then the LwIP TCPIP thread will be blocked from further work until the crypto op completes. This means it will be unable to do things like deliver ACKs to the peer, or process additional incoming packets. As a result, the peer may retransmit packets that have already been received, but just not ACKed yet. This multiplies the pressure on the buffer pool, which can lead to buffer exhaustion.

author: peter-h
author_rank: Super Contributor
timestamp: July 04, 2022, 11:55:27 am
content: Thank you for a very informative reply.It seems that your last para is the closest, although the callback mechanism seems to be slightly different in that it uses an internal "MBOX" messaging system.The funny thing is that I have been playing with the lwipopts.h and tried all kinds of stuff like doubling every buffer size, and nothing makes the slightest difference. This is (to me) suspicious and maybe it is something quite narrow, which is your suggestion.One option that's available is due to the HTTP server being required only for simple local config tasks, so one will be able to simply disable TLS while that is running.

author: tellurium
author_rank: Frequent Contributor
timestamp: July 04, 2022, 01:59:09 pm
content: Few more considerations, in case you decide to run an HTTPS local server (which is a bad idea):1. When a browser fetches your index.html, and finds references to local resources - images, JS scripts, CSS files, it creates 4-5 more connections to downloads those fast2. Therefore in addition to an original connection, you've got 4-5 more HTTPS connections, which usually kill small devices3. In addition to that, a browser might download "favicon.ico" file, to show a little icon on a browser tab. That's another connection.To alleviate a multiple connections issue, you can amalgamate your configuration page into once single page with no local references: just inline JS and CSS, and images too. You can make all images SVG and inline them, or make them PNG and base64-inline them too. This way, you can get away with a single HTTP connection.In order to prevent a browser creating a connection for every new request (e.g. for POSTing new configuration), make sure to use HTTP/1.1 in all responses, and set up Content-Length properly (alternatively, use Transfer-Encoding: chunked). This way, your browser will know the boundary of the response and will re-use an existing connection for the next request.Consider browser caching for static resources: add a "Etag" header for static content, and handle "If-None-Match" header. This way, you can simply reponse with 304 Not Modified on repeated requests to static resources.

author: peter-h
author_rank: Super Contributor
timestamp: July 04, 2022, 03:22:46 pm
content: Thanks very much. Very useful tips.We are absolutely not running an HTTPSserver. This is impossible since each TLS session is ~50k (plus or minus the crypto suite usage on the particular connection) and we don't have that extra RAM. The product application area is just a) the simpleHTTP serverand b) anHTTPS client(which will be connecting to a server that may or may not be under our control).The page which the HTTP server is serving is just text and it will eventually have a few links on it. I am informed that only images are prefetched, not links. Thanks for the tip about inlining images.There is a lot of stuff online re browsers trying to fetch a favicon and thus generating a double hit, but if Chrome does it, it doesn't appear to do it all the time.I was planning to have a facility in the product's file system to squirt out some JS (if it finds a specific .js file) but this will be optional.The current header isCode:static const unsigned char PAGE_START[] ="HTTP/1.1 200 OK\r\n""Server: XXXXXX\r\n""Content-type: text/html\r\n\r\n""<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">""<html>""<head>"" <title>XXXXXX Status</title>"" <meta http-equiv=Content-Type content=\"text/html; charset=utf-8\">"" <meta http-equiv=refresh content=1>""</head>""<body>""<pre><font size=\"+2\"><b>XXXXXX Status</font></b><br><br>";On the original Q I think I can see scenarios where SPI RAM could be used. It would be for receiving a firmware upgrade which has a CRC on the end. This CRC could be validated before writing the data to a filesystem file. There is value in this because a FAT filesystem can be corrupted.FWIW, this is a bit out of my notes on the project memory usage:Middlewares/Third_Party/LwIP has a 10k MEM_SIZE defined in lwipopts.h and takes 10k bytes, used for a local LWIP heapMiddlewares/Third_Party/LwIP has pbuf_pullsize and others which take up 7.5kethernetif.c takes up 12520 bytesSo ETH+LWIP alone (no TLS) uses up 30k RAM. This is statically allocated.TLS gets another 50k for its private heap.EDIT: I am seeingdoublehits on another board now, with the 2nd hit being a favicon request. Both with Chrome but something is different. For now, I have suppressed the favicon request withhttps://stackoverflow.com/a/62258760.I have also received the following suggestion from an MbedTLS mailing list, which seems easy enough. It's a hack and I don't like it; I would rather get both working concurrently (temporarily) even if the rest of the system has to be stripped down to get the extra RAM, to prove the problem. But the interaction of LWIP and TLS seems so complicated, and I don't know anybody who has a good understanding of it, so it may have to be solved by blocking the HTTPS client while the HTTP server is being used for local config. The following suggestion is the opposite; blocking the HTTP server's client from making requests while TLS is active:Peter via mbed-tls <mbed-tls@lists.trustedfirmware.org> wrote:> So if both of the above are running concurrently, there is only ~10k> RAM left, but it does work, but when TLS is doing its> handshake/negotiation (which on a 168MHz 32F417 takes 2-3 seconds) the> HTTP server temporarily hangs.I suggest that you send a TCP window=0 message, which will keep the clientfrom attempting to send any data. If you send that message before and afterthe https negotiation calculations, then you can keep the client from timing out.

author: tellurium
author_rank: Frequent Contributor
timestamp: July 05, 2022, 09:55:03 am
content: Hacking the TCP window size is an interesting hack indeed. "We should go deeper", as it was said in the Inception movie.The interaction of mbedTLS and the network stack depends on the LWIP usage mode. LWIP has 3: raw, netconn, and socket. For example, for the socket mode, there are only two callback functions you need to give mbedTLS:Code:int send_callback(void *ctx, const unsigned char *buf, size_t len);int recv_callback(void *ctx, unsigned char *buf, size_t len);You specify those two, and feed them to mbedTLS via this call:Code:mbedtls_ssl_set_bio(ssl, user_data, send_callback, recv_callback, 0);That's pretty much it. Then, when your application calls e.g. "mbedtls_ssl_read()", the TLS library calls a read callback if it needs more data from the wire.

author: peter-h
author_rank: Super Contributor
timestamp: July 05, 2022, 02:09:44 pm
content: I need to decide whether the HTTP server session should block the HTTPS client, or vice versa. For my application it is arguable both ways.I think the former will be better (because HTTP will be barely used) although best only during longer HTTP operations (basically file transfers). Perhaps set the block status on every HTTP action and release it after a timeout of a few seconds - because there is no "session" as such with HTTP; it's entirely client-driven and if the client is just sitting there...OTOH there is a "system status" page which self-refreshes (standard HTML construct, not JS) every 1 sec and it is on that page that we notice the HTTP server getting buggered by TLS, for the several seconds which a 168MHz 32F417 takes to do the TLS. So perhaps that page ought to block HTTPS permanently, but that's not a good idea either because one may want to watch the status page for a while.

author: dare
author_rank: Contributor
timestamp: July 05, 2022, 03:32:54 pm
content: QuoteThis sounds like a threading issue to me, not a memory pressure issue. The TLS protocol is effectively idle during large crypto operations (generally signature generation/validation). This means there is little pressure on network buffers during this time, which should be free to conduct the HTTP interaction.I would investigate what the various threads are doing at the time the crypto operation is happening. Presumably the thread the runs the HTTPS client is busy doing crypto in the MbedTLS code (if this is not the case, then this could be the problem). But what is the is the LwIP TCPIP thread doing during this time? And what is happening on the thread that runs the HTTP server? My suspicion is that somehow a thread that is necessary for conducting the HTTP interaction is either busy or blocked on a resource that is tied up with the TLS handshake.

author: peter-h
author_rank: Super Contributor
timestamp: July 05, 2022, 04:25:52 pm
content: To the limited extent I understand this code, I agree on all counts. Playing around with buffers etc made no difference whatsoever so it sounds like some sort of hard block, by TLS, on TCP/IP ops.The RTOS priority of the HTTP server also makes no difference. Maybe I can play with TCP/IP priority; that's a separate thread, but it is already pretty high upTLS is not in the above list since it runs in the RTOS thread of whichever task is using it, which is the healthcheck one, or 1 other one.The guy who was working on this is around only Mondays and he spent the last few Mondays looking into it, and doesn't want to do any more on it. I think that's reasonable now, unless some magic clue is found.The HTTP blocking issue is only for ~2-3 seconds during the TLS crypto. It amazes me that a 168MHz arm32 takes 2-3s to do RSA or EC, but some of that time may be waiting for certificates or whatever to arrive (and the code is clearly not yielding back to RTOS). If this was a real issue we would put in one of those Microchip crypto chips (which are unobtainable).Cube IDE has a FreeRTOS process monitor but I never got it actually running real time (it needs some software hooks, AFAIK). The above screenshot is from my HTTP server Status page, which is generated by some sample code from the STM port of FreeRTOS. This page vanishes for 2-3s.

author: tellurium
author_rank: Frequent Contributor
timestamp: July 05, 2022, 04:34:18 pm
content: Quote from: peter-h on July 05, 2022, 02:09:44 pmI don't see any reason for that. HTTP server and HTTPS client can (and should) be completely independent.If you're using raw LWIP API, then you don't need to do anything.If you're using netconn or socket API - use separate threads for HTTP server and HTTPS client.In those separate threads, either blocking or non-blocking API can be used - by either way, if HTTPS thread is busy doing crypto, the OS should give some time to the HTTP server to process data anyway.

author: tellurium
author_rank: Frequent Contributor
timestamp: July 05, 2022, 04:41:43 pm
content: I see HTTP server in the process list, but not HTTPS client.Are they in the same thread?If yes, split them. And make HTTPS the lowest prio.

author: peter-h
author_rank: Super Contributor
timestamp: July 05, 2022, 09:04:23 pm
content: TLS (the HTTPS client) is not in the above list since it runs in the RTOS thread of whichever task is using it, which is the healthcheck one, or 1 other one.I will pass back your comment; I don't know enough to say.I have offered money to someone who knows this stuff really well

author: dare
author_rank: Contributor
timestamp: July 05, 2022, 09:21:04 pm
content: QuoteI'm pretty sure signature verification wont start until all the necessary certificates have arrived. Also, remember that validation of the peer requires one signature verification (RSA or ECDSA) for each level in the certificate chain. And most certification chains are at least 3 levels deep (server certificate, intermediate CA certificate and root certificate). So 3 signatures to be verified, minimum.Add to this the time taken to generate the client's signature (if using client certs), and the key derivation/confirmation operations, and the time does not seem surprising to me. In the past, I implemented a system that achieved certificate-based, mutually authenticated session establish in 1.8 seconds on an 80 Mhz Cortext M4. But this was using a faster crypto library (MbedTLS is not great) and a more efficient protocol than TLS.QuoteAt this point, I would get a debugger with thread support hooked up and manually break the system at the point it locks up. Should be pretty easy, given a 2-3 second window. Then look around an see what all the important threads are doing. In particular, confirm that it is the client thread that is running the crypto code, not some other thread. Also, check what the LwIP TCPIP thread is doing. If its blocked on anything other than its central mbox (TCPIP_MBOX_FETCH()), then figure out what that things is and whether it makes sense for it to be waiting there.

author: tellurium
author_rank: Frequent Contributor
timestamp: July 05, 2022, 09:38:43 pm
content: Quote from: dare on July 05, 2022, 09:21:04 pmAs you've mentioned, the time taken depends on the chain length - also, on the cert type (RSA/EC) and cert size.We've seen cases when long cert chains with large RSA certs took 20+ seconds on 160 MHz MCU.

author: peter-h
author_rank: Super Contributor
timestamp: July 06, 2022, 06:15:49 am
content: The TLS action involves- pinginghttps://healthchecks.io/(which can be done with HTTP or HTTPS, but is currently done with HTTPS for test purposes)- sending a tiny file to a commercial server (legit, but I am not posting which one for commercial reasons)On the first one, this is a log showing times in ms. I believe we are not verifying their certificate i.e. we are doing encryption but not authentication. This is because the product does not currently have the capability to walk through multiple certificates, as is needed for any "open" commercial serverCode:82797: healthcheck interval= 60 secs82806: healthcheck url= http://hc-ping.com/8cd78cf4-eb2b-4844-b572-d5639a3128b682819:. Seeding the random number generator...82829: ok82838: . Loading the CA root certificate ...82851: ok82860: . Connecting to tcp/hc-ping.com/443...82870: udp_bind(ipaddr =82880: 0.0.0.082890: , port = 23000)82900: udp_bind: bound to82910: 0.0.0.082920: , port 23000)82930: udp_send82982: udp_input: calculating checksum83042: connect ok83052: . Setting up the SSL/TLS structure...83062: ok83073: . Performing the SSL/TLS handshake...85389: ../Middlewares/Third_Party/mbedTLS/library/ssl_tls.c:5757: x509_verify_cert() returned -9984 (-0x2700)88063: TLS handshake ok88072: . Verifying peer X.509 certificate...88082: peer cert failure ignored88092: > Write to server:88103: 72 initial bytes written:88112: < Read from server:88523: Headers length = 188, Content-Length = 288532: 190 bytes read:88542: HTTP/1.1 200 OKserver: nginxdate: Wed, 06 Jul 2022 05:58:46 GMTcontent-type: text/plain; chars...The above is 5.745 seconds. If I strip out all other RTOS tasks, it is the same, within 100ms.The log from the other server interaction (some info obfuscated) is here and takes 4.95s:Code:289594: xxxxxx access token response= HTTP/1.1 200 OKCache-Control: no-cache, no-store, must-revalidateExpires: 0Pragma: no-cac289603: xxxxxx_token_expiry_seconds= 14400289613: xxxxxx_token= sl.BK1cExxxxxxx289626:. Seeding the random number generator...289636: ok289645: . Loading the CA root certificate ...289658: ok289667: . Connecting to tcp/content.xxxxxxapi.com/443...289677: udp_bind(ipaddr =289687: 0.0.0.0289697: , port = 1942)289707: udp_bind: bound to289717: 0.0.0.0289727: , port 1942)289737: udp_send289762: udp_input: calculating checksum289802: connect ok289812: . Setting up the SSL/TLS structure...290926: ../Middlewares/Third_Party/mbedTLS/library/ssl_tls.c:5757: x509_verify_cert() returned -9984 (-0x2700)293053: TLS handshake ok293062: . Verifying peer X.509 certificate...293072: peer cert failure ignored293082: > Write to server:293093: 474 initial bytes written:293102: < Read from server:294503: Headers length = 0, Content-Length = 405294512: 256 bytes read:294522: ...294534: xxxxxx response= HTTP/1.1 200 OKCache-Control: no-cacheX-Content-Type-Options: nosniffX-Server-Response-Time: 9294544: xxxxxx upload succeededSo 2-3 secs goes into just setting up the (AIUI) public and private keys, and there is some certificate validation which fails (total time 10ms for that) because we don't have the root certificate collection.The main bit takes ~2.5 secs, and there are odd bits of (considerable) remote system latency of ~500ms which nothing can be done about. Probably a lot of that is done deliberately to make DOS attacks harder.What is embarrassing is that with all the other RTOS tasks removed, the HTTP thread isnotaffected by the TLS stuffWatch this space!EDIT: what breaks it is an NTP server/client thread. That uses LWIP sockets. I am wondering whether there is a #define somewhere for the max # of sockets which can be grabbed, and we are on the limit of that?This is a bit of that taskCode:int NtpOpenSocket(){//Open an UDP socket, bind it and return the socket id//This function binds to all network interfaces ( 0.0.0.0 )int fd = -1;struct sockaddr_in sock_addr;fd = socket(AF_INET, SOCK_DGRAM, 0);if (fd < 0){dbg_printf("NTP can't get a socket!\n");osDelay(pdMS_TO_TICKS(1000)); //Wait 1 second before retryingreturn fd; //failed, return}memset(&sock_addr, 0, sizeof(sock_addr));sock_addr.sin_family = AF_INET;sock_addr.sin_port = htons(NTP_PORT);if (bind(fd, (struct sockaddr*) &sock_addr, sizeof(sock_addr)) !=0 ){//bind failed!dbg_printf("NTP socket Bind failed!\n");close(fd);fd = -1;}if (fd >=0 ){dbg_printf("NTP socket init OK\n");}return fd;}and digging around I find this value defined in lwipopts.h (the other definition applies only if not already defined)But it appears to be 10 for TCP and 6 for UDPCode:/* ---------- Memory options ---------- *//* MEM_ALIGNMENT: should be set to the alignment of the CPU for whichlwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2byte alignment -> define MEM_ALIGNMENT to 2. */#define MEM_ALIGNMENT 4/* MEM_SIZE: the size of the heap memory. If the application will senda lot of data that needs to be copied, this should be set high. */#define MEM_SIZE (10*1024)/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the applicationsends a lot of data out of ROM (or other static memory), thisshould be set high. */#define MEMP_NUM_PBUF 10/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. Oneper active UDP "connection". */#define MEMP_NUM_UDP_PCB 6/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCPconnections. */#define MEMP_NUM_TCP_PCB 10/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCPconnections. */#define MEMP_NUM_TCP_PCB_LISTEN 5/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCPsegments. */#define MEMP_NUM_TCP_SEG 8/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously activetimeouts. */#define MEMP_NUM_SYS_TIMEOUT 10/* ---------- Pbuf options ---------- *//* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */#define PBUF_POOL_SIZE 8/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */#define PBUF_POOL_BUFSIZE 512I've played with all these values before. Setting MEMP_NUM_UDP_PCB=10 or 20 makes no difference.This is the line in the above source that breaks itfd = socket(AF_INET, SOCK_DGRAM, 0);One possibility suggested is that while the above NTP server uses the socket API, the HTTP server uses the netconn API which opens a socket but at a lower level and via a different API. However thishttps://lwip.fandom.com/wiki/Application_API_layerssuggests both are very similar in structure. Also I am told by the guy working on this on Mondays that LWIP error counters starts incrementing during the time that the HTTP server is failing, suggesting that LWIP is unable to transmit some packets. The Q however remains why the single call above to allocate the one UDP socket is sufficientaloneto cause this problem.This is interesting toohttps://www.nongnu.org/lwip/2_0_x/raw_api.htmlNetconn or Socket API functions are thread safe against thecore thread but they are not reentrant at the control blockgranularity level. That is, a UDP or TCP control block mustnot be shared among multiple threads without proper locking.That NTP thread is opening a UDP socket, and the mere opening of that socket, without it being used at all ever, is enough to stop the HTTP netconn server working while the TLS handshake is being done.In the NTP thread, closing that UDP socket and then hanging afterwards (while yielding to RTOS), fixes the problem. Removing the close() returns the problem.

author: peter-h
author_rank: Super Contributor
timestamp: July 06, 2022, 04:38:15 pm
content: Problem summary, and a hack solution:The issue is: the NTP thread opens a single UDP socket. If this socket is open (even if never used) the netconn HTTP server breaks during TLS handshake.The solution implemented is HTTP client activity detection with a 10 sec timeout, during which the NTP thread is suspended (and its UDP socket is closed, which is essential).This hack may or may not be needed for the new HTTP server, which uses the socket API instead of netconn. But netconn gets sockets via the same API as the socket API...The hack works. TLS still affects HTTP but all that happens is a very rare extension of a ~50ms server response time to ~300ms, which is fine.What a rabbit-hole!

author: peter-h
author_rank: Super Contributor
timestamp: July 07, 2022, 10:02:02 am
content: I could start a new thread on this but this is a simple Q: what ways are there with LWIP to open a UDP socket?The code in question uses socket() - called the Netconn API - which then ends up in the same function as quite a few others including TLS, but my board also has DHCP and DNS which are also supposed to use UDP but (according to breakpoints) they don't call this function. They use very deep code and I was not able to track it down easily.