Memory leak if libzt events aren't consumed by user app If arg is not enqueued by Events, then treat as if ownership has NOT been transferred and caller of Events->enqueue is responsible for freeing
This commit is contained in:
@@ -93,11 +93,18 @@ void Events::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::enqueue(unsigned int event_code, const void* arg, int len)
|
bool Events::enqueue(unsigned int event_code, const void* arg, int len)
|
||||||
{
|
{
|
||||||
if (! _enabled) {
|
if (! _enabled) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (_callbackMsgQueue.size_approx() > 1024) {
|
||||||
|
/* Rate-limit number of events. This value should only grow if the
|
||||||
|
user application isn't returning from the event handler in a timely manner.
|
||||||
|
For most applications it should hover around 1 to 2 */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
zts_event_msg_t* msg = new zts_event_msg_t();
|
zts_event_msg_t* msg = new zts_event_msg_t();
|
||||||
msg->event_code = event_code;
|
msg->event_code = event_code;
|
||||||
|
|
||||||
@@ -132,15 +139,12 @@ void Events::enqueue(unsigned int event_code, const void* arg, int len)
|
|||||||
msg->cache = (void*)arg;
|
msg->cache = (void*)arg;
|
||||||
msg->len = len;
|
msg->len = len;
|
||||||
}
|
}
|
||||||
if (msg && _callbackMsgQueue.size_approx() > 1024) {
|
|
||||||
/* Rate-limit number of events. This value should only grow if the
|
//
|
||||||
user application isn't returning from the event handler in a timely manner.
|
// ownership of arg is now transferred
|
||||||
For most applications it should hover around 1 to 2 */
|
//
|
||||||
destroy(msg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_callbackMsgQueue.enqueue(msg);
|
_callbackMsgQueue.enqueue(msg);
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::destroy(zts_event_msg_t* msg)
|
void Events::destroy(zts_event_msg_t* msg)
|
||||||
|
|||||||
@@ -115,8 +115,12 @@ class Events {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueue an event to be sent to the user application
|
* Enqueue an event to be sent to the user application
|
||||||
|
*
|
||||||
|
* Returns true if arg was enqueued.
|
||||||
|
* If enqueued, then ownership of arg has been transferred.
|
||||||
|
* If NOT enqueued, then ownership of arg has NOT been transferred.
|
||||||
*/
|
*/
|
||||||
void enqueue(unsigned int event_code, const void* arg, int len = 0);
|
bool enqueue(unsigned int event_code, const void* arg, int len = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send callback message to user application
|
* Send callback message to user application
|
||||||
|
|||||||
@@ -957,13 +957,17 @@ void NodeService::sendEventToUser(unsigned int zt_event_code, const void* obj, u
|
|||||||
|
|
||||||
void* objptr = NULL;
|
void* objptr = NULL;
|
||||||
|
|
||||||
|
zts_node_info_t* nd;
|
||||||
|
zts_net_info_t* nt;
|
||||||
|
zts_peer_info_t* pr;
|
||||||
|
|
||||||
switch (zt_event_code) {
|
switch (zt_event_code) {
|
||||||
case ZTS_EVENT_NODE_UP:
|
case ZTS_EVENT_NODE_UP:
|
||||||
case ZTS_EVENT_NODE_ONLINE:
|
case ZTS_EVENT_NODE_ONLINE:
|
||||||
case ZTS_EVENT_NODE_OFFLINE:
|
case ZTS_EVENT_NODE_OFFLINE:
|
||||||
case ZTS_EVENT_NODE_DOWN:
|
case ZTS_EVENT_NODE_DOWN:
|
||||||
case ZTS_EVENT_NODE_FATAL_ERROR: {
|
case ZTS_EVENT_NODE_FATAL_ERROR: {
|
||||||
zts_node_info_t* nd = new zts_node_info_t;
|
nd = new zts_node_info_t;
|
||||||
nd->node_id = _nodeId;
|
nd->node_id = _nodeId;
|
||||||
nd->ver_major = ZEROTIER_ONE_VERSION_MAJOR;
|
nd->ver_major = ZEROTIER_ONE_VERSION_MAJOR;
|
||||||
nd->ver_minor = ZEROTIER_ONE_VERSION_MINOR;
|
nd->ver_minor = ZEROTIER_ONE_VERSION_MINOR;
|
||||||
@@ -980,7 +984,7 @@ void NodeService::sendEventToUser(unsigned int zt_event_code, const void* obj, u
|
|||||||
case ZTS_EVENT_NETWORK_ACCESS_DENIED:
|
case ZTS_EVENT_NETWORK_ACCESS_DENIED:
|
||||||
case ZTS_EVENT_NETWORK_DOWN: {
|
case ZTS_EVENT_NETWORK_DOWN: {
|
||||||
NetworkState* ns = (NetworkState*)obj;
|
NetworkState* ns = (NetworkState*)obj;
|
||||||
zts_net_info_t* nt = new zts_net_info_t();
|
nt = new zts_net_info_t();
|
||||||
nt->net_id = ns->config.nwid;
|
nt->net_id = ns->config.nwid;
|
||||||
objptr = (void*)nt;
|
objptr = (void*)nt;
|
||||||
break;
|
break;
|
||||||
@@ -990,7 +994,7 @@ void NodeService::sendEventToUser(unsigned int zt_event_code, const void* obj, u
|
|||||||
case ZTS_EVENT_NETWORK_READY_IP6:
|
case ZTS_EVENT_NETWORK_READY_IP6:
|
||||||
case ZTS_EVENT_NETWORK_OK: {
|
case ZTS_EVENT_NETWORK_OK: {
|
||||||
NetworkState* ns = (NetworkState*)obj;
|
NetworkState* ns = (NetworkState*)obj;
|
||||||
zts_net_info_t* nt = new zts_net_info_t();
|
nt = new zts_net_info_t();
|
||||||
nt->net_id = ns->config.nwid;
|
nt->net_id = ns->config.nwid;
|
||||||
nt->mac = ns->config.mac;
|
nt->mac = ns->config.mac;
|
||||||
strncpy(nt->name, ns->config.name, sizeof(ns->config.name));
|
strncpy(nt->name, ns->config.name, sizeof(ns->config.name));
|
||||||
@@ -1051,7 +1055,7 @@ void NodeService::sendEventToUser(unsigned int zt_event_code, const void* obj, u
|
|||||||
case ZTS_EVENT_PEER_UNREACHABLE:
|
case ZTS_EVENT_PEER_UNREACHABLE:
|
||||||
case ZTS_EVENT_PEER_PATH_DISCOVERED:
|
case ZTS_EVENT_PEER_PATH_DISCOVERED:
|
||||||
case ZTS_EVENT_PEER_PATH_DEAD: {
|
case ZTS_EVENT_PEER_PATH_DEAD: {
|
||||||
zts_peer_info_t* pr = new zts_peer_info_t();
|
pr = new zts_peer_info_t();
|
||||||
ZT_Peer* peer = (ZT_Peer*)obj;
|
ZT_Peer* peer = (ZT_Peer*)obj;
|
||||||
memcpy(pr, peer, sizeof(zts_peer_info_t));
|
memcpy(pr, peer, sizeof(zts_peer_info_t));
|
||||||
for (unsigned int j = 0; j < peer->pathCount; j++) {
|
for (unsigned int j = 0; j < peer->pathCount; j++) {
|
||||||
@@ -1067,7 +1071,64 @@ void NodeService::sendEventToUser(unsigned int zt_event_code, const void* obj, u
|
|||||||
// Send event
|
// Send event
|
||||||
|
|
||||||
if (objptr) {
|
if (objptr) {
|
||||||
_events->enqueue(zt_event_code, objptr, len);
|
if (!_events->enqueue(zt_event_code, objptr, len)) {
|
||||||
|
//
|
||||||
|
// ownership of objptr was NOT transferred, so delete any news from above
|
||||||
|
//
|
||||||
|
switch (zt_event_code) {
|
||||||
|
case ZTS_EVENT_NODE_UP:
|
||||||
|
case ZTS_EVENT_NODE_ONLINE:
|
||||||
|
case ZTS_EVENT_NODE_OFFLINE:
|
||||||
|
case ZTS_EVENT_NODE_DOWN:
|
||||||
|
case ZTS_EVENT_NODE_FATAL_ERROR: {
|
||||||
|
delete nd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ZTS_EVENT_NETWORK_NOT_FOUND:
|
||||||
|
case ZTS_EVENT_NETWORK_CLIENT_TOO_OLD:
|
||||||
|
case ZTS_EVENT_NETWORK_REQ_CONFIG:
|
||||||
|
case ZTS_EVENT_NETWORK_ACCESS_DENIED:
|
||||||
|
case ZTS_EVENT_NETWORK_DOWN: {
|
||||||
|
delete nt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ZTS_EVENT_NETWORK_UPDATE:
|
||||||
|
case ZTS_EVENT_NETWORK_READY_IP4:
|
||||||
|
case ZTS_EVENT_NETWORK_READY_IP6:
|
||||||
|
case ZTS_EVENT_NETWORK_OK: {
|
||||||
|
delete nt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ZTS_EVENT_ADDR_ADDED_IP4:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_ADDR_ADDED_IP6:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_ADDR_REMOVED_IP4:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_ADDR_REMOVED_IP6:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_STORE_IDENTITY_PUBLIC:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_STORE_IDENTITY_SECRET:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_STORE_PLANET:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_STORE_PEER:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_STORE_NETWORK:
|
||||||
|
break;
|
||||||
|
case ZTS_EVENT_PEER_DIRECT:
|
||||||
|
case ZTS_EVENT_PEER_RELAY:
|
||||||
|
case ZTS_EVENT_PEER_UNREACHABLE:
|
||||||
|
case ZTS_EVENT_PEER_PATH_DISCOVERED:
|
||||||
|
case ZTS_EVENT_PEER_PATH_DEAD: {
|
||||||
|
delete pr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -312,6 +312,10 @@ static void zts_main_lwip_driver_loop(void* arg)
|
|||||||
zts_util_delay(LWIP_DRIVER_LOOP_INTERVAL);
|
zts_util_delay(LWIP_DRIVER_LOOP_INTERVAL);
|
||||||
}
|
}
|
||||||
_has_exited = true;
|
_has_exited = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// no need to check if event was enqueued since NULL is being passed
|
||||||
|
//
|
||||||
zts_events->enqueue(ZTS_EVENT_STACK_DOWN, NULL);
|
zts_events->enqueue(ZTS_EVENT_STACK_DOWN, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user