/** * Close clients during a clean shutdown */ void Protocol_closing() { int connected_count = 0; Node* current = NULL; FUNC_ENTRY; current = TreeNextElement(bstate->clients, current); while (current) { Clients* client = (Clients*)(current->content); current = TreeNextElement(bstate->clients, current); if (client->connected) { /* we can close a client if there are no in-process messages */ if (!Protocol_inProcess(client)) MQTTProtocol_closeSession(client, 0); else ++connected_count; } } if (connected_count == 0) bstate->state = BROKER_STOPPED; FUNC_EXIT; }
int traverse(Tree *t, int lookfor) { Node* curnode = NULL; int rc = 0; printf("Traversing\n"); curnode = TreeNextElement(t, curnode); //printf("content int %d\n", *(int*)(curnode->content)); while (curnode) { Node* prevnode = curnode; curnode = TreeNextElement(t, curnode); //if (curnode) // printf("content int %d\n", *(int*)(curnode->content)); if (prevnode && curnode && (*(int*)(curnode->content) < *(int*)(prevnode->content))) { printf("out of order %d < %d\n", *(int*)(curnode->content), *(int*)(prevnode->content)); } if (curnode && (lookfor == *(int*)(curnode->content))) printf("missing item %d actually found\n", lookfor); } printf("End traverse %d\n", rc); return rc; }
/** * MQTT retry protocol and socket pending writes processing. * @param now current time * @param doRetry boolean - retries as well as pending writes? * @return not actually used */ int MQTTProtocol_retry(time_t now, int doRetry) { Node* current = NULL; int rc = 0; FUNC_ENTRY; current = TreeNextElement(bstate->clients, current); /* look through the outbound message list of each client, checking to see if a retry is necessary */ while (current) { Clients* client = (Clients*)(current->content); current = TreeNextElement(bstate->clients, current); if (client->connected == 0) { #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) { if (difftime(now,client->lastContact) > bstate->retry_interval) { int rc2 = 0; /* NB: no dup bit for these packets */ if (client->connect_state == 1) /* TODO: handle err */ rc2 = MQTTSPacket_send_willTopicReq(client); else if (client->connect_state == 2) /* TODO: handle err */ rc2 = MQTTSPacket_send_willMsgReq(client); if (rc2 == SOCKET_ERROR) { client->good = 0; Log(LOG_WARNING, 29, NULL, client->clientID, client->socket); MQTTProtocol_closeSession(client, 1); client = NULL; } } } #endif continue; } if (client->good == 0) { MQTTProtocol_closeSession(client, 1); continue; } if (Socket_noPendingWrites(client->socket) == 0) continue; if (doRetry) MQTTProtocol_retries(now, client); if (client) { if (MQTTProtocol_processQueued(client)) rc = 1; } } FUNC_EXIT_RC(rc); return rc; }
/** * MQTT protocol keepAlive processing. Sends PINGREQ packets as required. * @param now current time */ void MQTTProtocol_keepalive(time_t now) { Node* current = NULL; FUNC_ENTRY; current = TreeNextElement(bstate->clients, current); while (current) { Clients* client = (Clients*)(current->content); current = TreeNextElement(bstate->clients, current); #if !defined(NO_BRIDGE) if (client->outbound) { if (client->connected && client->keepAliveInterval > 0 && (difftime(now, client->lastContact) >= client->keepAliveInterval)) { if (client->ping_outstanding) { Log(LOG_INFO, 143, NULL, client->keepAliveInterval, client->clientID); MQTTProtocol_closeSession(client, 1); } else { #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) { int rc = MQTTSPacket_send_pingReq(client); if (rc == SOCKET_ERROR) MQTTProtocol_closeSession(client, 1); } else if (client->protocol == PROTOCOL_MQTTS_DTLS) { int rc = MQTTSPacket_send_pingReq(client); if (rc == SOCKET_ERROR) MQTTProtocol_closeSession(client, 1); } else #endif MQTTPacket_send_pingreq(client->socket, client->clientID); client->lastContact = now; client->ping_outstanding = 1; } } } else #endif if (client->connected && client->keepAliveInterval > 0 && (difftime(now, client->lastContact) > 2*(client->keepAliveInterval))) { /* zero keepalive interval means never disconnect */ Log(LOG_INFO, 24, NULL, client->keepAliveInterval, client->clientID); MQTTProtocol_closeSession(client, 1); } } FUNC_EXIT; }
void MQTTProtocol_shutdownclients(Tree* clients, int terminate) { Node* current = NULL; FUNC_ENTRY; current = TreeNextElement(clients, current); while (current) { Clients* client = (Clients*)(current->content); current = TreeNextElement(clients, current); Log(LOG_INFO, 17, NULL, client->clientID); if (terminate) client->cleansession = 1; /* no persistence, so everything is clean */ MQTTProtocol_closeSession(client, 0); } FUNC_EXIT; }
int check(Tree *t) { Node* curnode = NULL; int rc = 0; curnode = TreeNextElement(t, curnode); while (curnode) { Node* prevnode = curnode; curnode = TreeNextElement(t, curnode); if (prevnode && curnode && (*(int*)(curnode->content) < *(int*)(prevnode->content))) { printf("out of order %d < %d\n", *(int*)(curnode->content), *(int*)(prevnode->content)); rc = 99; } } return rc; }
/** * Clean up a client list by closing any marked as "not good". * @param clients the list of clients */ void MQTTProtocol_clean_clients(Tree* clients) { Node* current = NULL; FUNC_ENTRY; current = TreeNextElement(clients, current); while (current) { Clients* client = (Clients*)(current->content); current = TreeNextElement(clients, current); if (client->good == 0) { Log(LOG_WARNING, 18, NULL, client->clientID, client->socket, Socket_getpeer(client->socket)); MQTTProtocol_closeSession(client, 1); } } FUNC_EXIT; }
/** * Scans the heap and reports any items currently allocated. * To be used at shutdown if any heap items have not been freed. */ static void HeapScan(enum LOG_LEVELS log_level) { Node* current = NULL; Thread_lock_mutex(heap_mutex); Log(log_level, -1, "Heap scan start, total %d bytes", state.current_size); while ((current = TreeNextElement(&heap, current)) != NULL) { storageElement* s = (storageElement*)(current->content); Log(log_level, -1, "Heap element size %d, line %d, file %s, ptr %p", s->size, s->line, s->file, s->ptr); Log(log_level, -1, " Content %*.s", (10 > current->size) ? s->size : 10, (char*)(((int*)s->ptr) + 1)); } Log(log_level, -1, "Heap scan end"); Thread_unlock_mutex(heap_mutex); }
/** * Dump the state of the heap * @param file file handle to dump the heap contents to */ int HeapDump(FILE* file) { int rc = 0; Node* current = NULL; while (rc == 0 && (current = TreeNextElement(&heap, current))) { storageElement* s = (storageElement*)(current->content); if (fwrite(&(s->ptr), sizeof(s->ptr), 1, file) != 1) rc = -1; else if (fwrite(&(current->size), sizeof(current->size), 1, file) != 1) rc = -1; else if (fwrite(s->ptr, current->size, 1, file) != 1) rc = -1; } return rc; }