void Peer::terminate() { terminateStatusOn(); terminateReceiverThread(); terminateQueueReads(); #ifndef DISABLE_LIBNICE nice.quit(); #endif for (descriptor_pair desc : knownPeers.getAllDescriptors()) { if (desc.type == DESCRIPTOR_SOCK) { close(desc.desc); } else if (desc.type == DESCRIPTOR_NICE) { // terminating the NiceAgent object is enough } } if (coordinatorFd >= 0) { close(coordinatorFd); } }
static void *receiveBundles(void *parm) { /* Main loop for bundle reception thread on one * connection, terminating when connection is lost. */ ReceiverThreadParms *parms = (ReceiverThreadParms *) parm; char *procName = "brsscla"; time_t currentTime; unsigned char sdnvText[10]; int sdnvLength = 0; unsigned int ductNbr; uvast val; int senderSocket; char registration[24]; time_t timeTag; char keyName[32]; char key[DIGEST_LEN]; int keyBufLen = sizeof key; int keyLen; char errtext[300]; char digest[DIGEST_LEN]; AcqWorkArea *work; char *buffer; currentTime = time(NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); memset(sdnvText, 0, sizeof sdnvText); /* Get duct number, expressed as an SDNV. */ while (1) { switch (receiveBytesByTCP(parms->bundleSocket, (char *) (sdnvText + sdnvLength), 1)) { case 1: break; /* Out of switch. */ case -1: putErrmsg("Can't get duct number.", NULL); /* Intentional fall-through. */ default: /* Inauthentic. */ *parms->authenticated = 1; terminateReceiverThread(parms); return NULL; } if ((*(sdnvText + sdnvLength) & 0x80) == 0) { break; /* Out of loop. */ } sdnvLength++; if (sdnvLength < 10) { continue; } putErrmsg("Duct number SDNV is too long.", NULL); *parms->authenticated = 1; /* Inauthentic. */ terminateReceiverThread(parms); return NULL; } oK(decodeSdnv(&val, sdnvText)); ductNbr = val; if (ductNbr < parms->baseDuctNbr || ductNbr > parms->lastDuctNbr) { putErrmsg("Duct number is too large.", utoa(ductNbr)); *parms->authenticated = 1; /* Inauthentic. */ terminateReceiverThread(parms); return NULL; } parms->ductNbr = ductNbr; senderSocket = ductNbr - parms->baseDuctNbr; if (parms->brsSockets[senderSocket] != -1) { putErrmsg("Client is already connected.", utoa(ductNbr)); *parms->authenticated = 1; /* Inauthentic. */ terminateReceiverThread(parms); return NULL; } isprintf(keyName, sizeof keyName, "%u.brs", ductNbr); keyLen = sec_get_key(keyName, &keyBufLen, key); if (keyLen == 0) { putErrmsg("Can't get HMAC key for duct.", keyName); *parms->authenticated = 1; /* Inauthentic. */ terminateReceiverThread(parms); return NULL; } /* Get time tag and its HMAC-SHA1 digest. */ switch (receiveBytesByTCP(parms->bundleSocket, registration, REGISTRATION_LEN)) { case REGISTRATION_LEN: break; /* Out of switch. */ case -1: putErrmsg("Can't get registration.", NULL); /* Intentional fall-through to next case. */ default: *parms->authenticated = 1; terminateReceiverThread(parms); return NULL; } memcpy((char *) &timeTag, registration, 4); timeTag = ntohl(timeTag); if (timeTag - currentTime > BRSTERM || currentTime - timeTag > BRSTERM) { isprintf(errtext, sizeof errtext, "[?] Registration rejected: \ time tag is %u, must be between %u and %u.", (unsigned int) timeTag, (unsigned int) (currentTime - BRSTERM), (unsigned int) (currentTime + BRSTERM)); writeMemo(errtext); *parms->authenticated = 1; /* Inauthentic. */ terminateReceiverThread(parms); return NULL; }