From 9d29b73dac0bfbce4e17229982068970bf1b45f8 Mon Sep 17 00:00:00 2001 From: Gregg Date: Sun, 2 Jun 2024 20:57:41 -0500 Subject: [PATCH] Fixed memory leak [needed to free `body` in tlvRespond()] This hopefully addresses memory leak that occurs when not using a Home Hub and connections constantly drop and re-establish. To do: must add back logic for notifications using new hap linked-list structure, and then delete static hap array code. --- src/HAP.cpp | 21 +++++++++++++-------- src/HAP.h | 1 + src/HomeSpan.cpp | 17 ++++++++++------- src/src.ino | 2 ++ 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index cf10f51..b7027d6 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -324,7 +324,7 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){ iosTLV.print(); LOG2("------------ END TLVS! ------------\n"); - LOG1("In Pair Setup #%d (%s)...",client.fd()-LWIP_SOCKET_OFFSET,client.remoteIP().toString().c_str()); + LOG1("In Pair Setup #%d (%s)...",clientNumber,client.remoteIP().toString().c_str()); auto itState=iosTLV.find(kTLVType_State); @@ -574,7 +574,7 @@ int HAPClient::postPairVerifyURL(uint8_t *content, size_t len){ iosTLV.print(); LOG2("------------ END TLVS! ------------\n"); - LOG1("In Pair Verify #%d (%s)...",client.fd()-LWIP_SOCKET_OFFSET,client.remoteIP().toString().c_str()); + LOG1("In Pair Verify #%d (%s)...",clientNumber,client.remoteIP().toString().c_str()); auto itState=iosTLV.find(kTLVType_State); @@ -756,7 +756,7 @@ int HAPClient::postPairingsURL(uint8_t *content, size_t len){ iosTLV.print(); LOG2("------------ END TLVS! ------------\n"); - LOG1("In Post Pairings #%d (%s)...",client.fd()-LWIP_SOCKET_OFFSET,client.remoteIP().toString().c_str()); + LOG1("In Post Pairings #%d (%s)...",clientNumber,client.remoteIP().toString().c_str()); auto itState=iosTLV.find(kTLVType_State); auto itMethod=iosTLV.find(kTLVType_Method); @@ -882,7 +882,7 @@ int HAPClient::getAccessoriesURL(){ return(0); } - LOG1("In Get Accessories #%d (%s)...\n",client.fd()-LWIP_SOCKET_OFFSET,client.remoteIP().toString().c_str()); + LOG1("In Get Accessories #%d (%s)...\n",clientNumber,client.remoteIP().toString().c_str()); homeSpan.printfAttributes(); size_t nBytes=hapOut.getSize(); @@ -910,7 +910,7 @@ int HAPClient::getCharacteristicsURL(char *urlBuf){ return(0); } - LOG1("In Get Characteristics #%d (%s)...\n",client.fd()-LWIP_SOCKET_OFFSET,client.remoteIP().toString().c_str()); + LOG1("In Get Characteristics #%d (%s)...\n",clientNumber,client.remoteIP().toString().c_str()); int len=strlen(urlBuf); // determine number of IDs specified by counting commas in URL int numIDs=1; @@ -978,7 +978,7 @@ int HAPClient::putCharacteristicsURL(char *json){ return(0); } - LOG1("In Put Characteristics #%d (%s)...\n",client.fd()-LWIP_SOCKET_OFFSET,client.remoteIP().toString().c_str()); + LOG1("In Put Characteristics #%d (%s)...\n",clientNumber,client.remoteIP().toString().c_str()); int n=homeSpan.countCharacteristics(json); // count number of objects in JSON request if(n==0) // if no objects found, return @@ -1031,7 +1031,7 @@ int HAPClient::putPrepareURL(char *json){ return(0); } - LOG1("In Put Prepare #%d (%s)...\n",client.fd()-LWIP_SOCKET_OFFSET,client.remoteIP().toString().c_str()); + LOG1("In Put Prepare #%d (%s)...\n",clientNumber,client.remoteIP().toString().c_str()); char ttlToken[]="\"ttl\":"; char pidToken[]="\"pid\":"; @@ -1291,6 +1291,8 @@ void HAPClient::tlvRespond(TLV8 &tlv8){ LOG2("------------ SENT! --------------\n"); else LOG2("-------- SENT ENCRYPTED! --------\n"); + + free(body); } // tlvRespond @@ -1559,9 +1561,12 @@ HapOut::HapStreamBuffer::HapStreamBuffer(){ ////////////////////////////////////// HapOut::HapStreamBuffer::~HapStreamBuffer(){ - + sync(); free(buffer); + free(encBuf); + free(hash); + free(ctx); } ////////////////////////////////////// diff --git a/src/HAP.h b/src/HAP.h index 0aa42b8..c3c9d4a 100644 --- a/src/HAP.h +++ b/src/HAP.h @@ -92,6 +92,7 @@ struct HAPClient { // individual structures and data defined for each Hap Client connection WiFiClient client; // handle to client + int clientNumber; // client number Controller *cPair=NULL; // pointer to info on current, session-verified Paired Controller (NULL=un-verified, and therefore un-encrypted, connection) // These temporary Curve25519 keys are generated in the first call to pair-verify and used in the second call to pair-verify so must persist for a short period diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index fd3a155..7bc9e0a 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -235,13 +235,14 @@ void Span::pollTask() { auto it=hapList.emplace(hapList.begin()); (*it).client=hapServer->available(); + (*it).clientNumber=(*it).client.fd()-LWIP_SOCKET_OFFSET; // homeSpan.clearNotify(socket); // clear all notification requests for this connection HAPClient::pairStatus=pairState_M1; // reset starting PAIR STATE (which may be needed if Accessory failed in middle of pair-setup) LOG2("=======================================\n"); - LOG1("** Client #%d Connected (%lu sec): %s\n",(*it).client.fd()-LWIP_SOCKET_OFFSET,millis()/1000,(*it).client.remoteIP().toString().c_str()); + LOG1("** Client #%d Connected (%lu sec): %s\n",(*it).clientNumber,millis()/1000,(*it).client.remoteIP().toString().c_str()); LOG2("\n"); } @@ -257,7 +258,7 @@ void Span::pollTask() { } it++; } else { - LOG1("** Client #%d DISCONNECTED (%lu sec)\n",(*it).client.fd()-LWIP_SOCKET_OFFSET,millis()/1000); + LOG1("** Client #%d DISCONNECTED (%lu sec)\n",(*it).clientNumber,millis()/1000); (*it).client.stop(); delay(5); it=hapList.erase(it); @@ -557,9 +558,11 @@ void Span::processSerialCommand(const char *c){ switch(c[0]){ case 'Z': { - for(int i=0;iclient) - hap[i]->client.stop(); + for(auto it=hapList.begin(); it!=hapList.end(); ++it){ + (*it).client.stop(); + delay(5); + + } } break; @@ -580,11 +583,11 @@ void Span::processSerialCommand(const char *c){ LOG0("\n"); for(auto it=hapList.begin(); it!=hapList.end(); ++it){ - LOG0("Client #%d: %s",(*it).client.fd()-LWIP_SOCKET_OFFSET,(*it).client.remoteIP().toString().c_str()); + LOG0("Client #%d: %s",(*it).clientNumber,(*it).client.remoteIP().toString().c_str()); if((*it).cPair){ LOG0(" ID="); HAPClient::charPrintRow((*it).cPair->getID(),36); - LOG0((*it).cPair->isAdmin()?" (admin)":" (regular)\n"); + LOG0((*it).cPair->isAdmin()?" (admin)\n":" (regular)\n"); } else { LOG0(" (unverified)\n"); } diff --git a/src/src.ino b/src/src.ino index e371724..98d9733 100644 --- a/src/src.ino +++ b/src/src.ino @@ -35,6 +35,8 @@ void setup() { homeSpan.enableWebLog(); homeSpan.begin(Category::Lighting,"HomeSpan LightBulb"); + + new SpanUserCommand('D', " - disconnect WiFi", [](const char *buf){WiFi.disconnect();}); new SpanAccessory(); new Service::AccessoryInformation();