// TODO: consider refactoring this to return error code void WdtSocket::readEncryptionSettingsOnce(int timeoutMs) { if (!encryptionParams_.isSet() || encryptionSettingsRead_) { return; } WDT_CHECK(!encryptionParams_.getSecret().empty()); int numRead = readInternal(buf_, 1, timeoutMs, true); if (numRead != 1) { LOG(ERROR) << "Failed to read encryption settings " << numRead << " " << port_; return; } if (buf_[0] != Protocol::ENCRYPTION_CMD) { LOG(ERROR) << "Expected to read ENCRYPTION_CMD(e), but got " << buf_[0]; readErrorCode_ = UNEXPECTED_CMD_ERROR; return; } int toRead = Protocol::kMaxEncryption - 1; // already read 1 byte for cmd numRead = readInternal(buf_, toRead, threadCtx_.getOptions().read_timeout_millis, true); if (numRead != toRead) { LOG(ERROR) << "Failed to read encryption settings " << numRead << " " << toRead << " " << port_; readErrorCode_ = SOCKET_READ_ERROR; return; } int64_t off = 0; EncryptionType encryptionType; std::string iv; if (!Protocol::decodeEncryptionSettings(buf_, off, Protocol::kMaxEncryption, encryptionType, iv)) { LOG(ERROR) << "Failed to decode encryption settings"; readErrorCode_ = PROTOCOL_ERROR; return; } if (encryptionType != encryptionParams_.getType()) { LOG(ERROR) << "Encryption type mismatch " << encryptionTypeToStr(encryptionType) << " " << encryptionTypeToStr(encryptionParams_.getType()); readErrorCode_ = PROTOCOL_ERROR; return; } if (!decryptor_.start(encryptionParams_, iv)) { readErrorCode_ = ENCRYPTION_ERROR; return; } LOG(INFO) << "Successfully read encryption settings " << port_ << " " << encryptionTypeToStr(encryptionType); encryptionSettingsRead_ = true; }
/** * will return name of AP with strongest signal found or return empty string if none found */ const char* pfodESP8266Utils::scanForStrongestAP(char* result, size_t resultLen) { // WiFi.scanNetworks will return the number of networks found int8_t n = WiFi.scanNetworks(); #ifdef DEBUG Serial.print ("Scan done\n"); #endif delay(0); int32_t maxRSSI = -1000; pfodESP8266Utils::strncpy_safe((char*)result, "", resultLen); // empty if (n <= 0) { #ifdef DEBUG Serial.print("No networks found\n"); #endif } else { #ifdef DEBUG Serial.print("Networks found:"); Serial.println(n); #endif for (int8_t i = 0; i < n; ++i) { const char * ssid_scan = WiFi.SSID_charPtr(i); int32_t rssi_scan = WiFi.RSSI(i); uint8_t sec_scan = WiFi.encryptionType(i); if (rssi_scan > maxRSSI) { maxRSSI = rssi_scan; pfodESP8266Utils::strncpy_safe((char*)result, ssid_scan, resultLen); } #ifdef DEBUG Serial.print(ssid_scan); Serial.print(" "); Serial.print(encryptionTypeToStr(sec_scan)); Serial.print(" "); Serial.println(rssi_scan); #endif delay(0); } } return result; }
std::ostream& operator<<(std::ostream& os, const TransferStats& stats) { folly::RWSpinLock::ReadHolder lock(stats.mutex_.get()); double headerOverhead = 100; double failureOverhead = 100; if (stats.effectiveDataBytes_ > 0) { headerOverhead = 100.0 * stats.headerBytes_ / stats.effectiveDataBytes_; failureOverhead = 100.0 * (stats.dataBytes_ - stats.effectiveDataBytes_) / stats.effectiveDataBytes_; } if (stats.localErrCode_ == OK && stats.remoteErrCode_ == OK) { os << "Transfer status = OK."; } else if (stats.localErrCode_ == stats.remoteErrCode_) { os << "Transfer status = " << errorCodeToStr(stats.localErrCode_) << "."; } else { os << "Transfer status (local) = " << errorCodeToStr(stats.localErrCode_) << ", (remote) = " << errorCodeToStr(stats.remoteErrCode_) << "."; } if (stats.numFiles_ > 0) { os << " Number of files transferred = " << stats.numFiles_ << "."; } else { os << " Number of blocks transferred = " << stats.numBlocks_ << "."; } os << " Data Mbytes = " << stats.effectiveDataBytes_ / kMbToB << ". Header Kbytes = " << stats.headerBytes_ / 1024. << " (" << headerOverhead << "% overhead)" << ". Total bytes = " << (stats.dataBytes_ + stats.headerBytes_) << ". Wasted bytes due to failure = " << (stats.dataBytes_ - stats.effectiveDataBytes_) << " (" << failureOverhead << "% overhead)" << ". Encryption type = " << encryptionTypeToStr(stats.encryptionType_) << "."; return os; }
const WdtTransferRequest &Receiver::init() { if (validateTransferRequest() != OK) { WLOG(ERROR) << "Couldn't validate the transfer request " << transferRequest_.getLogSafeString(); return transferRequest_; } checkAndUpdateBufferSize(); backlog_ = options_.backlog; if (getTransferId().empty()) { setTransferId(WdtBase::generateTransferId()); } setProtocolVersion(transferRequest_.protocolVersion); setDir(transferRequest_.directory); auto numThreads = transferRequest_.ports.size(); // This creates the destination directory (which is needed for transferLogMgr) fileCreator_.reset(new FileCreator(destDir_, numThreads, transferLogManager_, options_.skip_writes)); // Make sure we can get the lock on the transfer log manager early // so if we can't we don't generate a valid but useless url and end up // starting a sender doomed to fail if (options_.enable_download_resumption) { WDT_CHECK(!options_.skip_writes) << "Can not skip transfers with download resumption turned on"; if (options_.resume_using_dir_tree) { WDT_CHECK(!options_.shouldPreallocateFiles()) << "Can not resume using directory tree if preallocation is enabled"; } ErrorCode errCode = transferLogManager_.openLog(); if (errCode != OK) { WLOG(ERROR) << "Failed to open transfer log " << errorCodeToStr(errCode); transferRequest_.errorCode = errCode; return transferRequest_; } ErrorCode code = transferLogManager_.parseAndMatch( recoveryId_, getTransferConfig(), fileChunksInfo_); if (code == OK && options_.resume_using_dir_tree) { WDT_CHECK(fileChunksInfo_.empty()); traverseDestinationDir(fileChunksInfo_); } } EncryptionType encryptionType = parseEncryptionType(options_.encryption_type); // is encryption enabled? bool encrypt = (encryptionType != ENC_NONE && protocolVersion_ >= Protocol::ENCRYPTION_V1_VERSION); if (encrypt) { WLOG(INFO) << encryptionTypeToStr(encryptionType) << " encryption is enabled for this transfer "; if (!transferRequest_.encryptionData.isSet()) { WLOG(INFO) << "Receiver generating encryption key for type " << encryptionTypeToStr(encryptionType); transferRequest_.encryptionData = EncryptionParams::generateEncryptionParams(encryptionType); } if (!transferRequest_.encryptionData.isSet()) { WLOG(ERROR) << "Unable to generate encryption key for type " << encryptionTypeToStr(encryptionType); transferRequest_.errorCode = ENCRYPTION_ERROR; return transferRequest_; } } else { if (encryptionType != ENC_NONE) { WLOG(WARNING) << "Encryption is enabled, but protocol version is " << protocolVersion_ << ", minimum version required for encryption is " << Protocol::ENCRYPTION_V1_VERSION; } transferRequest_.encryptionData.erase(); } threadsController_ = new ThreadsController(numThreads); threadsController_->setNumFunnels(ReceiverThread::NUM_FUNNELS); threadsController_->setNumBarriers(ReceiverThread::NUM_BARRIERS); threadsController_->setNumConditions(ReceiverThread::NUM_CONDITIONS); // TODO: take transferRequest directly ! receiverThreads_ = threadsController_->makeThreads<Receiver, ReceiverThread>( this, transferRequest_.ports.size(), transferRequest_.ports); size_t numSuccessfulInitThreads = 0; for (auto &receiverThread : receiverThreads_) { ErrorCode code = receiverThread->init(); if (code == OK) { ++numSuccessfulInitThreads; } } WLOG(INFO) << "Registered " << numSuccessfulInitThreads << " successful sockets"; ErrorCode code = OK; const size_t targetSize = transferRequest_.ports.size(); // TODO: replace with getNumPorts/thread if (numSuccessfulInitThreads != targetSize) { code = FEWER_PORTS; if (numSuccessfulInitThreads == 0) { code = ERROR; } } transferRequest_.protocolVersion = protocolVersion_; transferRequest_.ports.clear(); for (const auto &receiverThread : receiverThreads_) { transferRequest_.ports.push_back(receiverThread->getPort()); } if (transferRequest_.hostName.empty()) { char hostName[1024]; int ret = gethostname(hostName, sizeof(hostName)); if (ret == 0) { transferRequest_.hostName.assign(hostName); } else { PLOG(ERROR) << "Couldn't find the host name"; code = ERROR; } } transferRequest_.directory = getDir(); transferRequest_.errorCode = code; return transferRequest_; }