common_time_server.cpp revision e1d6c080f0b1769637d742e51cc22167c7af12bb
1d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen/* 2354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman * Copyright (C) 2012 The Android Open Source Project 3d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * 4d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * you may not use this file except in compliance with the License. 6d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * You may obtain a copy of the License at 7d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * 8d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * http://www.apache.org/licenses/LICENSE-2.0 9d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * 10d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * Unless required by applicable law or agreed to in writing, software 11d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * distributed under the License is distributed on an "AS IS" BASIS, 12d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * See the License for the specific language governing permissions and 14d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * limitations under the License. 15d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen */ 16d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 17d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen/* 18d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * A service that exchanges time synchronization information between 19d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen * a master that defines a timeline and clients that follow the timeline. 20d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen */ 21d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 22354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman#define LOG_TAG "common_time" 23354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman#include <utils/Log.h> 24354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 25d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <arpa/inet.h> 26d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <assert.h> 27d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <fcntl.h> 28354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman#include <limits> 29d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <linux/if_ether.h> 30d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <net/if.h> 31d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <net/if_arp.h> 32d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <netinet/ip.h> 33d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <poll.h> 34d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <stdio.h> 35354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman#include <sys/eventfd.h> 36d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <sys/ioctl.h> 37d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <sys/stat.h> 38d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <sys/types.h> 39d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <sys/socket.h> 40d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 41232f869c99b8b33276ddad8054fc3e89e44852e5John Grossman#include <common_time/local_clock.h> 42d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <binder/IPCThreadState.h> 43d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <binder/ProcessState.h> 44d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include <utils/Timers.h> 45d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 46232f869c99b8b33276ddad8054fc3e89e44852e5John Grossman#include "common_clock_service.h" 479387f4f80081128601da936fe5e6006809ff479cJohn Grossman#include "common_time_config_service.h" 48354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman#include "common_time_server.h" 49354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman#include "common_time_server_packets.h" 50d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include "clock_recovery.h" 51d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen#include "common_clock.h" 52d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 53354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanusing std::numeric_limits; 54d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 55354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmannamespace android { 56d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 57354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst char* CommonTimeServer::kDefaultMasterElectionAddr = "239.195.128.88"; 58354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8887; 59354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst uint64_t CommonTimeServer::kDefaultSyncGroupID = 0; 60354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst uint8_t CommonTimeServer::kDefaultMasterPriority = 1; 61354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000; 62354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000; 63354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000; 64354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst bool CommonTimeServer::kDefaultAutoDisable = true; 65354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst int CommonTimeServer::kSetupRetryTimeout = 30000; 66354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanconst int64_t CommonTimeServer::kNoGoodDataPanicThreshold = 600000000ll; 67354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 68354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman// timeout value representing an infinite timeout 69232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanconst int CommonTimeServer::kInfiniteTimeout = -1; 70d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 71d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen/*** Initial state constants ***/ 72d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 73d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// number of WhoIsMaster attempts sent before giving up 74232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanconst int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6; 75d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 76d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// timeout used when waiting for a response to a WhoIsMaster request 77232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanconst int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500; 78d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 79d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen/*** Client state constants ***/ 80d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 81d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// number of sync requests that can fail before a client assumes its master 82d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// is dead 83e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kClient_NumSyncRequestRetries = 10; 84d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 85d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen/*** Master state constants ***/ 86d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 87d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen/*** Ronin state constants ***/ 88d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 89d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// number of WhoIsMaster attempts sent before declaring ourselves master 90e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 20; 91d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 92d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// timeout used when waiting for a response to a WhoIsMaster request 93232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanconst int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500; 94d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 95d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen/*** WaitForElection state constants ***/ 96d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 97d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// how long do we wait for an announcement from a master before 98d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// trying another election? 99e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossmanconst int CommonTimeServer::kWaitForElection_TimeoutMs = 12500; 100d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 101232f869c99b8b33276ddad8054fc3e89e44852e5John GrossmanCommonTimeServer::CommonTimeServer() 102d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen : Thread(false) 1037f1d9e1c5301e58891db62061cee7d413542be81John Grossman , mState(ICommonClock::STATE_INITIAL) 104d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen , mClockRecovery(&mLocalClock, &mCommonClock) 105d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen , mSocket(-1) 106d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen , mLastPacketRxLocalTime(0) 107d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen , mTimelineID(ICommonClock::kInvalidTimelineID) 108d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen , mClockSynced(false) 109354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman , mCommonClockHasClients(false) 110d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen , mInitial_WhoIsMasterRequestTimeouts(0) 111d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen , mClient_MasterDeviceID(0) 112354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman , mClient_MasterDevicePriority(0) 113d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen , mRonin_WhoIsMasterRequestTimeouts(0) { 114354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // zero out sync stats 115354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman resetSyncStats(); 116354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 117354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Setup the master election endpoint to use the default. 118354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman struct sockaddr_in* meep = 119354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP); 120354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP)); 121354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr); 122354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman meep->sin_family = AF_INET; 123354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman meep->sin_port = htons(kDefaultMasterElectionPort); 124354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 125354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Zero out the master endpoint. 126354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman memset(&mMasterEP, 0, sizeof(mMasterEP)); 127354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mMasterEPValid = false; 128354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mBindIfaceValid = false; 129354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman setForceLowPriority(false); 130354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 131354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Set all remaining configuration parameters to their defaults. 132354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mDeviceID = 0; 133354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mSyncGroupID = kDefaultSyncGroupID; 134354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mMasterPriority = kDefaultMasterPriority; 135354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs; 136354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mSyncRequestIntervalMs = kDefaultSyncRequestIntervalMs; 137354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mPanicThresholdUsec = kDefaultPanicThresholdUsec; 138354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mAutoDisable = kDefaultAutoDisable; 139354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 140354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Create the eventfd we will use to signal our thread to wake up when 141354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // needed. 142354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mWakeupThreadFD = eventfd(0, EFD_NONBLOCK); 143354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 144354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // seed the random number generator (used to generated timeline IDs) 145354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman srand48(static_cast<unsigned int>(systemTime())); 146d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 147d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 148232f869c99b8b33276ddad8054fc3e89e44852e5John GrossmanCommonTimeServer::~CommonTimeServer() { 149354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman shutdownThread(); 150354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 151354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // No need to grab the lock here. We are in the destructor; if the the user 152354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // has a thread in any of the APIs while the destructor is being called, 153354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // there is a threading problem a the application level we cannot reasonably 154354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // do anything about. 155354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman cleanupSocket_l(); 156354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 157354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mWakeupThreadFD >= 0) { 158354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman close(mWakeupThreadFD); 159354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mWakeupThreadFD = -1; 160d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 161d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 162d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 163354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::startServices() { 164354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // start the ICommonClock service 165354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mICommonClock = CommonClockService::instantiate(*this); 166354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mICommonClock == NULL) 167354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 168354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 169354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // start the ICommonTimeConfig service 170354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mICommonTimeConfig = CommonTimeConfigService::instantiate(*this); 171354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mICommonTimeConfig == NULL) 172354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 173354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 174354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return true; 175354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 176354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 177232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::threadLoop() { 178354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Register our service interfaces. 179354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!startServices()) 180354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 181354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 182354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Hold the lock while we are in the main thread loop. It will release the 183354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // lock when it blocks, and hold the lock at all other times. 184354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mLock.lock(); 185354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman runStateMachine_l(); 186354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mLock.unlock(); 187354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 188d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen IPCThreadState::self()->stopProcess(); 189d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 190d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 191d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 192354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::runStateMachine_l() { 193d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (!mLocalClock.initCheck()) 194d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 195d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 196d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (!mCommonClock.init(mLocalClock.getLocalFreq())) 197d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 198d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 199354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Enter the initial state. 200354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman becomeInitial("startup"); 201d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 202d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // run the state machine 203354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman while (!exitPending()) { 204354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman struct pollfd pfds[2]; 205354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int rc; 206354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int eventCnt = 0; 207354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t wakeupTime; 208354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 209354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // We are always interested in our wakeup FD. 210354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pfds[eventCnt].fd = mWakeupThreadFD; 211354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pfds[eventCnt].events = POLLIN; 212354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pfds[eventCnt].revents = 0; 213354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman eventCnt++; 214354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 215354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we have a valid socket, then we are interested in what it has to 216354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // say as well. 217354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mSocket >= 0) { 218354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pfds[eventCnt].fd = mSocket; 219354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pfds[eventCnt].events = POLLIN; 220354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pfds[eventCnt].revents = 0; 221354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman eventCnt++; 222354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 223d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 224354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Note, we were holding mLock when this function was called. We 225354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // release it only while we are blocking and hold it at all other times. 226354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mLock.unlock(); 227354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman rc = poll(pfds, eventCnt, mCurTimeout.msecTillTimeout()); 228354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman wakeupTime = mLocalClock.getLocalTime(); 229354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mLock.lock(); 230354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 231354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Is it time to shutdown? If so, don't hesitate... just do it. 232354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (exitPending()) 233354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 234354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 235354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Did the poll fail? This should never happen and is fatal if it does. 236354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (rc < 0) { 237d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen LOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__); 238d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 239d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 240d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 241354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (rc == 0) 242354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(kInfiniteTimeout); 243354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 244354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Were we woken up on purpose? If so, clear the eventfd with a read. 245354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (pfds[0].revents) 246354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman clearPendingWakeupEvents_l(); 247354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 248354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Is out bind address dirty? If so, clean up our socket (if any). 249354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Alternatively, do we have an active socket but should be auto 250354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // disabled? If so, release the socket and enter the proper sync state. 251354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman bool droppedSocket = false; 252354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) { 253354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman cleanupSocket_l(); 254354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mBindIfaceDirty = false; 255354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman droppedSocket = true; 256354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 257d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 258354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Do we not have a socket but should have one? If so, try to set one 259354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // up. 260354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) { 261354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (setupSocket_l()) { 262354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Success! We are now joining a new network (either coming 263354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // from no network, or coming from a potentially different 264354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // network). Force our priority to be lower so that we defer to 265354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // any other masters which may already be on the network we are 266354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // joining. Later, when we enter either the client or the 267354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // master state, we will clear this flag and go back to our 268354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // normal election priority. 269354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman setForceLowPriority(true); 270354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman switch (mState) { 271354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we were in initial (whether we had a immediately 272354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // before this network or not) we want to simply reset the 273354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // system and start again. Forcing a transition from 274354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // INITIAL to INITIAL should do the job. 275354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case CommonClockService::STATE_INITIAL: 276354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman becomeInitial("bound interface"); 277354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 278354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 279354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we were in the master state, then either we were the 280354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // master in a no-network situation, or we were the master 281354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // of a different network and have moved to a new interface. 282e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // In either case, immediately transition to Ronin at low 283e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // priority. If there is no one in the network we just 284e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // joined, we will become master soon enough. If there is, 285e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // we want to be certain to defer master status to the 286e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // existing timeline currently running on the network. 287e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // 288354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case CommonClockService::STATE_MASTER: 289e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman becomeRonin("leaving networkless mode"); 290354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 291354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 292354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we were in any other state (CLIENT, RONIN, or 293354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // WAIT_FOR_ELECTION) then we must be moving from one 294354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // network to another. We have lost our old master; 295354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // transition to RONIN in an attempt to find a new master. 296354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If there are none out there, we will just assume 297354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // responsibility for the timeline we used to be a client 298354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // of. 299354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman default: 300354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman becomeRonin("bound interface"); 301354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 302d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 303354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } else { 304354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // That's odd... we failed to set up our socket. This could be 305354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // due to some transient network change which will work itself 306354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // out shortly; schedule a retry attempt in the near future. 307354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(kSetupRetryTimeout); 308d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 309354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 310354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // One way or the other, we don't have any data to process at this 311354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // point (since we just tried to bulid a new socket). Loop back 312354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // around and wait for the next thing to do. 313354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman continue; 314354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } else if (droppedSocket) { 315354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // We just lost our socket, and for whatever reason (either no 316354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // config, or auto disable engaged) we are not supposed to rebuild 317354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // one at this time. We are not going to rebuild our socket until 318354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // something about our config/auto-disabled status changes, so we 319354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // are basically in network-less mode. If we are already in either 320354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // INITIAL or MASTER, just stay there until something changes. If 321354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION), 322354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // then transition to either INITIAL or MASTER depending on whether 323354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // or not our timeline is valid. 324354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGI("Entering networkless mode interface is %s, " 325354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "shouldAutoDisable = %s", 326354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mBindIfaceValid ? "valid" : "invalid", 327354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman shouldAutoDisable() ? "true" : "false"); 328354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if ((mState != ICommonClock::STATE_INITIAL) && 329354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman (mState != ICommonClock::STATE_MASTER)) { 330354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mTimelineID == ICommonClock::kInvalidTimelineID) 331354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman becomeInitial("network-less mode"); 332354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman else 333354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman becomeMaster("network-less mode"); 334354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 335354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 336354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman continue; 337354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 338354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 339354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Did we wakeup with no signalled events across all of our FDs? If so, 340354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // we must have hit our timeout. 341354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (rc == 0) { 342354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!handleTimeout()) 343354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("handleTimeout failed"); 344354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman continue; 345354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 346354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 347354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Does our socket have data for us (assuming we still have one, we 348354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // may have RXed a packet at the same time as a config change telling us 349354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // to shut our socket down)? If so, process its data. 350354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) { 351354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mLastPacketRxLocalTime = wakeupTime; 352354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!handlePacket()) 353354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("handlePacket failed"); 354d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 355d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 356d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 357354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman cleanupSocket_l(); 358d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 359d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 360d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 361354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanvoid CommonTimeServer::clearPendingWakeupEvents_l() { 362354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t tmp; 363354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman read(mWakeupThreadFD, &tmp, sizeof(tmp)); 364354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 365354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 366354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanvoid CommonTimeServer::wakeupThread_l() { 367354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t tmp = 1; 368354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman write(mWakeupThreadFD, &tmp, sizeof(tmp)); 369354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 370354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 371354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanvoid CommonTimeServer::cleanupSocket_l() { 372354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mSocket >= 0) { 373354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman close(mSocket); 374354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mSocket = -1; 375354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 376354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 377354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 378354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanvoid CommonTimeServer::shutdownThread() { 379354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Flag the work thread for shutdown. 380354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman this->requestExit(); 381354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 382354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Signal the thread in case its sleeping. 383354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mLock.lock(); 384354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman wakeupThread_l(); 385354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mLock.unlock(); 386354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 387354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Wait for the thread to exit. 388354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman this->join(); 389354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 390354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 391354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::setupSocket_l() { 392d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen int rc; 393354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman bool ret_val = false; 394354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman struct sockaddr_in* ipv4_addr = NULL; 395354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman char masterElectionEPStr[64]; 396354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const int one = 1; 397354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 398354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // This should never be needed, but if we happened to have an old socket 399354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // lying around, be sure to not leak it before proceeding. 400354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman cleanupSocket_l(); 401354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 402354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we don't have a valid endpoint to bind to, then how did we get here in 403354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // the first place? Regardless, we know that we are going to fail to bind, 404354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // so don't even try. 405354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!mBindIfaceValid) 406354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 407d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 408354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sockaddrToString(mMasterElectionEP, true, masterElectionEPStr, 409354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sizeof(masterElectionEPStr)); 410354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGI("Building socket :: bind = %s master election = %s", 411354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mBindIface.string(), masterElectionEPStr); 412354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 413354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // TODO: add proper support for IPv6. Right now, we block IPv6 addresses at 414354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // the configuration interface level. 415354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (AF_INET != mMasterElectionEP.ss_family) { 416354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGW("TODO: add proper IPv6 support"); 417354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 418354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 419d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 420d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // open a UDP socket for the timeline serivce 421d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 422354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mSocket < 0) { 423354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("Failed to create socket (errno = %d)", errno); 424354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 425d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 426d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 427354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE. 428354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman struct ifreq ifr; 429354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman memset(&ifr, 0, sizeof(ifr)); 430354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string()); 431354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0; 432354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE, 433354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman (void *)&ifr, sizeof(ifr)); 434354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (rc) { 435354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("Failed to bind socket at to interface %s (errno = %d)", 436354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ifr.ifr_name, errno); 437354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 438354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 439d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 440354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Bind our socket to INADDR_ANY and the master election port. The 441354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // interface binding we made using SO_BINDTODEVICE should limit us to 442354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // traffic only on the interface we are interested in. We need to bind to 443354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // INADDR_ANY and the specific master election port in order to be able to 444354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // receive both unicast traffic and master election multicast traffic with 445354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // just a single socket. 446d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen struct sockaddr_in bindAddr; 447354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP); 448354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr)); 449354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman bindAddr.sin_addr.s_addr = INADDR_ANY; 450354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman rc = bind(mSocket, 451354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const sockaddr *>(&bindAddr), 452354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sizeof(bindAddr)); 453d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (rc) { 454354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("Failed to bind socket to port %hu (errno = %d)", 455354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ntohs(bindAddr.sin_port), errno); 456354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 457d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 458d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 459354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) { 460354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If our master election endpoint is a multicast address, be sure to join 461354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // the multicast group. 462354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman struct ip_mreq mreq; 463354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mreq.imr_multiaddr = ipv4_addr->sin_addr; 464354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mreq.imr_interface.s_addr = htonl(INADDR_ANY); 465354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, 466354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman &mreq, sizeof(mreq)); 467354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (rc == -1) { 468354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("Failed to join multicast group at %s. (errno = %d)", 469354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman masterElectionEPStr, errno); 470354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 471354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 472354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 473354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // disable loopback of multicast packets 474354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const int zero = 0; 475354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP, 476354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman &zero, sizeof(zero)); 477354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (rc == -1) { 478354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("Failed to disable multicast loopback (errno = %d)", errno); 479354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 480354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 481354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } else 482354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (ntohl(ipv4_addr->sin_addr.s_addr) != 0xFFFFFFFF) { 483354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If the master election address is neither broadcast, nor multicast, 484354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // then we are misconfigured. The config API layer should prevent this 485354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // from ever happening. 486354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 487d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 488d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 489354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Set the TTL of sent packets to 1. (Time protocol sync should never leave 490354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // the local subnet) 491354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one)); 492d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (rc == -1) { 493354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("Failed to set TTL to %d (errno = %d)", one, errno); 494354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 495d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 496d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 497d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // get the device's unique ID 498d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (!assignDeviceID()) 499354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman goto bailout; 500d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 501354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ret_val = true; 5029387f4f80081128601da936fe5e6006809ff479cJohn Grossman 503354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbailout: 504354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!ret_val) 505354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman cleanupSocket_l(); 506354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return ret_val; 507d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 508d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 509d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// generate a unique device ID that can be used for arbitration 510232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::assignDeviceID() { 511583a03ac046901f90b6292a9e143dda6a7a053d6John Grossman if (!mBindIfaceValid) 512583a03ac046901f90b6292a9e143dda6a7a053d6John Grossman return false; 513583a03ac046901f90b6292a9e143dda6a7a053d6John Grossman 514d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen struct ifreq ifr; 515d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen memset(&ifr, 0, sizeof(ifr)); 516d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen ifr.ifr_addr.sa_family = AF_INET; 517583a03ac046901f90b6292a9e143dda6a7a053d6John Grossman strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ); 518d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 519d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr); 520d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (rc) { 521d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen LOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__); 522d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 523d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 524d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 525d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) { 526d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen LOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__); 527d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 528d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 529d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 530d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mDeviceID = 0; 531d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen for (int i = 0; i < ETH_ALEN; i++) { 532d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i]; 533d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 534d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 535d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 536d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 537d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 538d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// generate a new timeline ID 539232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanvoid CommonTimeServer::assignTimelineID() { 540d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen do { 541354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mTimelineID = (static_cast<uint64_t>(lrand48()) << 32) 542354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman | static_cast<uint64_t>(lrand48()); 543d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } while (mTimelineID == ICommonClock::kInvalidTimelineID); 544d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 545d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 546d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// Select a preference between the device IDs of two potential masters. 547d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen// Returns true if the first ID wins, or false if the second ID wins. 548354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::arbitrateMaster( 549354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint64_t deviceID1, uint8_t devicePrio1, 550354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint64_t deviceID2, uint8_t devicePrio2) { 551354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return ((devicePrio1 > devicePrio2) || 552354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2))); 553d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 554d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 555232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handlePacket() { 556354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint8_t buf[256]; 557354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman struct sockaddr_storage srcAddr; 558d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen socklen_t srcAddrLen = sizeof(srcAddr); 559d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 560d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen ssize_t recvBytes = recvfrom( 561d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mSocket, buf, sizeof(buf), 0, 562d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen); 563d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 564354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (recvBytes < 0) { 565d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen LOGE("%s:%d recvfrom failed", __PRETTY_FUNCTION__, __LINE__); 566d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 567d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 568d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 569354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman UniversalTimeServicePacket pkt; 570354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman recvBytes = pkt.deserializePacket(buf, recvBytes, mSyncGroupID); 571354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (recvBytes < 0) 572d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 573d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 574d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen bool result; 575354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman switch (pkt.packetType) { 576354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case TIME_PACKET_WHO_IS_MASTER_REQUEST: 577354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request, 578354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman srcAddr); 579354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 580354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 581354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case TIME_PACKET_WHO_IS_MASTER_RESPONSE: 582354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response, 583354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman srcAddr); 584354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 585354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 586354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case TIME_PACKET_SYNC_REQUEST: 587354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman result = handleSyncRequest(&pkt.p.sync_request, srcAddr); 588354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 589354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 590354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case TIME_PACKET_SYNC_RESPONSE: 591354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman result = handleSyncResponse(&pkt.p.sync_response, srcAddr); 592354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 593354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 594354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case TIME_PACKET_MASTER_ANNOUNCEMENT: 595354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman result = handleMasterAnnouncement(&pkt.p.master_announcement, 596354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman srcAddr); 597354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 598d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 599d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen default: { 600354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGD("%s:%d unknown packet type(%d)", 601354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman __PRETTY_FUNCTION__, __LINE__, pkt.packetType); 602d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen result = false; 603d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } break; 604d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 605d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 606d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return result; 607d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 608d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 609232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleTimeout() { 610354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we have no socket, then this must be a timeout to retry socket setup. 611354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mSocket < 0) 612354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return true; 613354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 614d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen switch (mState) { 6157f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_INITIAL: 616d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return handleTimeoutInitial(); 6177f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_CLIENT: 618d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return handleTimeoutClient(); 6197f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_MASTER: 620d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return handleTimeoutMaster(); 6217f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_RONIN: 622d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return handleTimeoutRonin(); 6237f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_WAIT_FOR_ELECTION: 624d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return handleTimeoutWaitForElection(); 625d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 626d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 627d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 628d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 629d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 630232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleTimeoutInitial() { 631d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (++mInitial_WhoIsMasterRequestTimeouts == 632d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen kInitial_NumWhoIsMasterRetries) { 633d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // none of our attempts to discover a master succeeded, so make 634d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // this device the master 635354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeMaster("initial timeout"); 636d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 637d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // retry the WhoIsMaster request 638d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return sendWhoIsMasterRequest(); 639d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 640d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 641d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 642232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleTimeoutClient() { 643354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (shouldPanicNotGettingGoodData()) 644354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeInitial("timeout panic, no good data"); 645354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 646d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (mClient_SyncRequestPending) { 647d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClient_SyncRequestPending = false; 648d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 649d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) { 650d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // a sync request has timed out, so retry 651d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return sendSyncRequest(); 652d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 653d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // The master has failed to respond to a sync request for too many 654d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // times in a row. Assume the master is dead and start electing 655d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // a new master. 656354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeRonin("master not responding"); 657d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 658d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 659d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // initiate the next sync request 660d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return sendSyncRequest(); 661d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 662d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 663d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 664232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleTimeoutMaster() { 665d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // send another announcement from the master 666d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return sendMasterAnnouncement(); 667d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 668d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 669232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleTimeoutRonin() { 670d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) { 671d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // no other master is out there, so we won the election 672354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeMaster("no better masters detected"); 673d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 674d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return sendWhoIsMasterRequest(); 675d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 676d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 677d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 678232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleTimeoutWaitForElection() { 679354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeRonin("timeout waiting for election conclusion"); 680d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 681d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 682232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleWhoIsMasterRequest( 683d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen const WhoIsMasterRequestPacket* request, 684354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const sockaddr_storage& srcAddr) { 6857f1d9e1c5301e58891db62061cee7d413542be81John Grossman if (mState == ICommonClock::STATE_MASTER) { 686d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // is this request related to this master's timeline? 687354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (request->timelineID != ICommonClock::kInvalidTimelineID && 688354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman request->timelineID != mTimelineID) 689d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 690d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 691354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman WhoIsMasterResponsePacket pkt; 692354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.initHeader(mTimelineID, mSyncGroupID); 693354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.deviceID = mDeviceID; 694354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.devicePriority = effectivePriority(); 695354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 696354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint8_t buf[256]; 697354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf)); 698354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (bufSz < 0) 699354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 700d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 701d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen ssize_t sendBytes = sendto( 702354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mSocket, buf, bufSz, 0, 703d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen reinterpret_cast<const sockaddr *>(&srcAddr), 704d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen sizeof(srcAddr)); 705d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (sendBytes == -1) { 706d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen LOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__); 707d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 708d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 7097f1d9e1c5301e58891db62061cee7d413542be81John Grossman } else if (mState == ICommonClock::STATE_RONIN) { 710d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // if we hear a WhoIsMaster request from another device following 711d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // the same timeline and that device wins arbitration, then we will stop 712d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // trying to elect ourselves master and will instead wait for an 713d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // announcement from the election winner 714354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (request->timelineID != mTimelineID) 715d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 716d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 717354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (arbitrateMaster(request->senderDeviceID, 718354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman request->senderDevicePriority, 719354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mDeviceID, 720354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman effectivePriority())) 721354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeWaitForElection("would lose election"); 722d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 723d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 7247f1d9e1c5301e58891db62061cee7d413542be81John Grossman } else if (mState == ICommonClock::STATE_INITIAL) { 725d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // If a group of devices booted simultaneously (e.g. after a power 726d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // outage) and all of them are in the initial state and there is no 727d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // master, then each device may time out and declare itself master at 728d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // the same time. To avoid this, listen for 729d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // WhoIsMaster(InvalidTimeline) requests from peers. If we would lose 730d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // arbitration against that peer, reset our timeout count so that the 731d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // peer has a chance to become master before we time out. 732354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (request->timelineID == ICommonClock::kInvalidTimelineID && 733354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman arbitrateMaster(request->senderDeviceID, 734354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman request->senderDevicePriority, 735354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mDeviceID, 736354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman effectivePriority())) { 737d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mInitial_WhoIsMasterRequestTimeouts = 0; 738d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 739d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 740d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 741d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 742d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 743d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 744232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleWhoIsMasterResponse( 745d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen const WhoIsMasterResponsePacket* response, 746354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const sockaddr_storage& srcAddr) { 7477f1d9e1c5301e58891db62061cee7d413542be81John Grossman if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) { 748d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return becomeClient(srcAddr, 749354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman response->deviceID, 750354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman response->devicePriority, 751354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman response->timelineID, 752354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "heard whois response"); 7537f1d9e1c5301e58891db62061cee7d413542be81John Grossman } else if (mState == ICommonClock::STATE_CLIENT) { 754d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // if we get multiple responses because there are multiple devices 755d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // who believe that they are master, then follow the master that 756d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // wins arbitration 757354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (arbitrateMaster(response->deviceID, 758354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman response->devicePriority, 759354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDeviceID, 760354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDevicePriority)) { 761d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return becomeClient(srcAddr, 762354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman response->deviceID, 763354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman response->devicePriority, 764354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman response->timelineID, 765354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "heard whois response"); 766d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 767d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 768d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 769d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 770d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 771d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 772232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request, 773354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const sockaddr_storage& srcAddr) { 774354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman SyncResponsePacket pkt; 775354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.initHeader(mTimelineID, mSyncGroupID); 776d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 777354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if ((mState == ICommonClock::STATE_MASTER) && 778354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman (mTimelineID == request->timelineID)) { 779354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t rxLocalTime = mLastPacketRxLocalTime; 780d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen int64_t rxCommonTime; 781354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 782354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we are master on an actual network and have actual clients, then 783354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // we are no longer low priority. 784354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman setForceLowPriority(false); 785354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 786d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) { 787d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 788d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 789d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 790d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen int64_t txLocalTime = mLocalClock.getLocalTime();; 791d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen int64_t txCommonTime; 792d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) { 793d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 794d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 795d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 796354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.nak = 0; 797354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.clientTxLocalTime = request->clientTxLocalTime; 798354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.masterRxCommonTime = rxCommonTime; 799354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.masterTxCommonTime = txCommonTime; 800d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 801354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.nak = 1; 802354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.clientTxLocalTime = 0; 803354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.masterRxCommonTime = 0; 804354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.masterTxCommonTime = 0; 805d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 806d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 807354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint8_t buf[256]; 808354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf)); 809354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (bufSz < 0) 810354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 811354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 812d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen ssize_t sendBytes = sendto( 813354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mSocket, &buf, bufSz, 0, 814d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen reinterpret_cast<const sockaddr *>(&srcAddr), 815d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen sizeof(srcAddr)); 816d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (sendBytes == -1) { 817d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen LOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__); 818d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return false; 819d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 820d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 821d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 822d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 823d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 824232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleSyncResponse( 825d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen const SyncResponsePacket* response, 826354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const sockaddr_storage& srcAddr) { 8277f1d9e1c5301e58891db62061cee7d413542be81John Grossman if (mState != ICommonClock::STATE_CLIENT) 828d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 829d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 830354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman assert(mMasterEPValid); 831354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!sockaddrMatch(srcAddr, mMasterEP, true)) { 832354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman char srcEP[64], expectedEP[64]; 833354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP)); 834354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP)); 835464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman LOGI("Dropping sync response from unexpected address." 836354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman " Expected %s Got %s", expectedEP, srcEP); 837464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman return true; 838464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman } 839464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman 840354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (response->nak) { 841d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // if our master is no longer accepting requests, then we need to find 842d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // a new master 843354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeRonin("master NAK'ed"); 844d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 845d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 846d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClient_SyncRequestPending = 0; 847d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClient_SyncRequestTimeouts = 0; 848354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_PacketRTTLog.logRX(response->clientTxLocalTime, 849354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mLastPacketRxLocalTime); 850d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 851d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen bool result; 852354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!(mClient_SyncRespsRXedFromCurMaster++)) { 853d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // the first request/response exchange between a client and a master 854d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // may take unusually long due to ARP, so discard it. 855d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen result = true; 856d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 857354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t clientTxLocalTime = response->clientTxLocalTime; 858354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t clientRxLocalTime = mLastPacketRxLocalTime; 859354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t masterTxCommonTime = response->masterTxCommonTime; 860354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t masterRxCommonTime = response->masterRxCommonTime; 861d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 862d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen int64_t rtt = (clientRxLocalTime - clientTxLocalTime); 863d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen int64_t avgLocal = (clientTxLocalTime + clientRxLocalTime) >> 1; 864d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1; 865d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 866354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // if the RTT of the packet is significantly larger than the panic 867354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // threshold, we should simply discard it. Its better to do nothing 868354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // than to take cues from a packet like that. 869354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int rttCommon = mCommonClock.localDurationToCommonDuration(rtt); 870354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) * 5)) { 871354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGV("Dropping sync response with RTT of %lld uSec", rttCommon); 872354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_ExpiredSyncRespsRXedFromCurMaster++; 873354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (shouldPanicNotGettingGoodData()) 874354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeInitial("RX panic, no good data"); 875d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 87617fe2476167ae741de44a2f0c0f5cb43fafe5584Kent Ryhorchuk result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon); 877354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_LastGoodSyncRX = clientRxLocalTime; 878354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 879354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (result) { 880354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // indicate to listeners that we've synced to the common timeline 881354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman notifyClockSync(); 882354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } else { 883354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("Panic! Observed clock sync error is too high to tolerate," 884354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman " resetting state machine and starting over."); 885354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman notifyClockSyncLoss(); 886354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeInitial("panic"); 887354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 888d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 889d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 890d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 891354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(mSyncRequestIntervalMs); 892d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return result; 893d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 894d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 895232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::handleMasterAnnouncement( 896d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen const MasterAnnouncementPacket* packet, 897354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const sockaddr_storage& srcAddr) { 898354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint64_t newDeviceID = packet->deviceID; 899354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint8_t newDevicePrio = packet->devicePriority; 900354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint64_t newTimelineID = packet->timelineID; 901d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 9027f1d9e1c5301e58891db62061cee7d413542be81John Grossman if (mState == ICommonClock::STATE_INITIAL || 9037f1d9e1c5301e58891db62061cee7d413542be81John Grossman mState == ICommonClock::STATE_RONIN || 9047f1d9e1c5301e58891db62061cee7d413542be81John Grossman mState == ICommonClock::STATE_WAIT_FOR_ELECTION) { 905d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // if we aren't currently following a master, then start following 906d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // this new master 907354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeClient(srcAddr, 908354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman newDeviceID, 909354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman newDevicePrio, 910354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman newTimelineID, 911354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "heard master announcement"); 9127f1d9e1c5301e58891db62061cee7d413542be81John Grossman } else if (mState == ICommonClock::STATE_CLIENT) { 913d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // if the new master wins arbitration against our current master, 914d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // then become a client of the new master 915354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (arbitrateMaster(newDeviceID, 916354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman newDevicePrio, 917354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDeviceID, 918354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDevicePriority)) 919354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeClient(srcAddr, 920354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman newDeviceID, 921354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman newDevicePrio, 922354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman newTimelineID, 923354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "heard master announcement"); 9247f1d9e1c5301e58891db62061cee7d413542be81John Grossman } else if (mState == ICommonClock::STATE_MASTER) { 925d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // two masters are competing - if the new one wins arbitration, then 926d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // cease acting as master 927354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (arbitrateMaster(newDeviceID, newDevicePrio, 928354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mDeviceID, effectivePriority())) 929354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeClient(srcAddr, newDeviceID, 930354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman newDevicePrio, newTimelineID, 931354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "heard master announcement"); 932d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 933d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 934d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 935d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 936d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 937232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::sendWhoIsMasterRequest() { 9387f1d9e1c5301e58891db62061cee7d413542be81John Grossman assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN); 939d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 940354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we have no socket, then we must be in the unconfigured initial state. 941354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Don't report any errors, just don't try to send the initial who-is-master 942354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // query. Eventually, our network will either become configured, or we will 943354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // be forced into network-less master mode by higher level code. 944354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mSocket < 0) { 945354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman assert(mState == ICommonClock::STATE_INITIAL); 946354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return true; 947354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 948d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 949354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman bool ret = false; 950354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman WhoIsMasterRequestPacket pkt; 951354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.initHeader(mSyncGroupID); 952354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.senderDeviceID = mDeviceID; 953354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.senderDevicePriority = effectivePriority(); 954354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 955354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint8_t buf[256]; 956354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf)); 957354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (bufSz >= 0) { 958354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ssize_t sendBytes = sendto( 959354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mSocket, buf, bufSz, 0, 960354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const sockaddr *>(&mMasterElectionEP), 961354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sizeof(mMasterElectionEP)); 962354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (sendBytes < 0) 963354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("WhoIsMaster sendto failed (errno %d)", errno); 964354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ret = true; 965d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 966d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 9677f1d9e1c5301e58891db62061cee7d413542be81John Grossman if (mState == ICommonClock::STATE_INITIAL) { 968354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs); 969d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 970354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs); 971d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 972d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 973354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return ret; 974d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 975d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 976232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::sendSyncRequest() { 977354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we are sending sync requests, then we must be in the client state and 978354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // we must have a socket (when we have no network, we are only supposed to 979354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // be in INITIAL or MASTER) 9807f1d9e1c5301e58891db62061cee7d413542be81John Grossman assert(mState == ICommonClock::STATE_CLIENT); 981354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman assert(mSocket >= 0); 982d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 983354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman bool ret = false; 984354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman SyncRequestPacket pkt; 985354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.initHeader(mTimelineID, mSyncGroupID); 986354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.clientTxLocalTime = mLocalClock.getLocalTime(); 987d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 988354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!mClient_FirstSyncTX) 989354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_FirstSyncTX = pkt.clientTxLocalTime; 990354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 991354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime); 992354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 993354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint8_t buf[256]; 994354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf)); 995354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (bufSz >= 0) { 996354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ssize_t sendBytes = sendto( 997354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mSocket, buf, bufSz, 0, 998354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const sockaddr *>(&mMasterEP), 999354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sizeof(mMasterEP)); 1000354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (sendBytes < 0) 1001354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("SyncRequest sendto failed (errno %d)", errno); 1002354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ret = true; 1003d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 1004d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1005464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman mClient_SyncsSentToCurMaster++; 1006354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(mSyncRequestIntervalMs); 1007d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClient_SyncRequestPending = true; 1008354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1009354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return ret; 1010d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1011d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1012232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanbool CommonTimeServer::sendMasterAnnouncement() { 1013354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman bool ret = false; 10147f1d9e1c5301e58891db62061cee7d413542be81John Grossman assert(mState == ICommonClock::STATE_MASTER); 1015d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1016354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // If we are being asked to send a master announcement, but we have no 1017354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // socket, we must be in network-less master mode. Don't bother to send the 1018354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // announcement, and don't bother to schedule a timeout. When the network 1019354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // comes up, the work thread will get poked and start the process of 1020354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // figuring out who the current master should be. 1021354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mSocket < 0) { 1022354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(kInfiniteTimeout); 1023354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return true; 1024354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 1025d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1026354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman MasterAnnouncementPacket pkt; 1027354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.initHeader(mTimelineID, mSyncGroupID); 1028354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.deviceID = mDeviceID; 1029354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman pkt.devicePriority = effectivePriority(); 1030354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1031354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint8_t buf[256]; 1032354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf)); 1033354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (bufSz >= 0) { 1034354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ssize_t sendBytes = sendto( 1035354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mSocket, buf, bufSz, 0, 1036354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const sockaddr *>(&mMasterElectionEP), 1037354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sizeof(mMasterElectionEP)); 1038354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (sendBytes < 0) 1039354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGE("MasterAnnouncement sendto failed (errno %d)", errno); 1040354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ret = true; 1041d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 1042d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1043354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(mMasterAnnounceIntervalMs); 1044354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return ret; 1045d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1046d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1047354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP, 1048354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint64_t masterDeviceID, 1049354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint8_t masterDevicePriority, 1050354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint64_t timelineID, 1051354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const char* cause) { 1052354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman char newEPStr[64], oldEPStr[64]; 1053354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr)); 1054354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr)); 1055354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1056354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGI("%s --> CLIENT (%s) :%s" 1057354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman " OldMaster: %02x-%014llx::%016llx::%s" 1058354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman " NewMaster: %02x-%014llx::%016llx::%s", 1059354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman stateToString(mState), cause, 1060464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman (mTimelineID != timelineID) ? " (new timeline)" : "", 1061354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDevicePriority, mClient_MasterDeviceID, 1062354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mTimelineID, oldEPStr, 1063354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman masterDevicePriority, masterDeviceID, 1064354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman timelineID, newEPStr); 1065d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1066d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (mTimelineID != timelineID) { 1067d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // start following a new timeline 1068d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mTimelineID = timelineID; 1069d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClockRecovery.reset(true, true); 1070d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen notifyClockSyncLoss(); 1071d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } else { 1072d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // start following a new master on the existing timeline 1073d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClockRecovery.reset(false, true); 1074d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 1075d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1076354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mMasterEP = masterEP; 1077354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mMasterEPValid = true; 1078e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman 1079e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // If we are on a real network as a client of a real master, then we should 1080e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // no longer force low priority. If our master disappears, we should have 1081e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // the high priority bit set during the election to replace the master 1082e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // because this group was a real group and not a singleton created in 1083e1d6c080f0b1769637d742e51cc22167c7af12bbJohn Grossman // networkless mode. 1084354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman setForceLowPriority(false); 1085354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1086464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman mClient_MasterDeviceID = masterDeviceID; 1087354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDevicePriority = masterDevicePriority; 1088354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman resetSyncStats(); 1089d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 10907f1d9e1c5301e58891db62061cee7d413542be81John Grossman setState(ICommonClock::STATE_CLIENT); 1091d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1092d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // add some jitter to when the various clients send their requests 1093d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // in order to reduce the likelihood that a group of clients overload 1094d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // the master after receiving a master announcement 1095354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman usleep((lrand48() % 100) * 1000); 1096d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1097d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return sendSyncRequest(); 1098d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1099d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1100354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::becomeMaster(const char* cause) { 1101354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint64_t oldTimelineID = mTimelineID; 1102d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (mTimelineID == ICommonClock::kInvalidTimelineID) { 1103d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // this device has not been following any existing timeline, 1104d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // so it will create a new timeline and declare itself master 1105d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen assert(!mCommonClock.isValid()); 1106d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1107d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // set the common time basis 1108d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mCommonClock.setBasis(mLocalClock.getLocalTime(), 0); 1109d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1110d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // assign an arbitrary timeline iD 1111d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen assignTimelineID(); 1112d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1113d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // notify listeners that we've created a common timeline 1114d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen notifyClockSync(); 1115d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 1116d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1117354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGI("%s --> MASTER (%s) : %s timeline %016llx", 1118354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman stateToString(mState), cause, 1119464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman (oldTimelineID == mTimelineID) ? "taking ownership of" 1120464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman : "creating new", 1121464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman mTimelineID); 1122464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman 1123354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman memset(&mMasterEP, 0, sizeof(mMasterEP)); 1124354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mMasterEPValid = false; 1125354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDevicePriority = effectivePriority(); 1126354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDeviceID = mDeviceID; 1127d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClockRecovery.reset(false, true); 1128354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman resetSyncStats(); 1129d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 11307f1d9e1c5301e58891db62061cee7d413542be81John Grossman setState(ICommonClock::STATE_MASTER); 1131d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return sendMasterAnnouncement(); 1132d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1133d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1134354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::becomeRonin(const char* cause) { 11359684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman // If we were the client of a given timeline, but had never received even a 11369684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman // single time sync packet, then we transition back to Initial instead of 11379684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman // Ronin. If we transition to Ronin and end up becoming the new Master, we 11389684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman // will be unable to service requests for other clients because we never 11399684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman // actually knew what time it was. By going to initial, we ensure that 11409684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman // other clients who know what time it is, but would lose master arbitration 11419684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman // in the Ronin case, will step up and become the proper new master of the 11429684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman // old timeline. 1143354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1144354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman char oldEPStr[64]; 1145354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr)); 1146354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman memset(&mMasterEP, 0, sizeof(mMasterEP)); 1147354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mMasterEPValid = false; 1148354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 11499684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman if (mCommonClock.isValid()) { 1150354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGI("%s --> RONIN (%s) : lost track of previously valid timeline " 1151354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)", 1152354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman stateToString(mState), cause, 1153354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDevicePriority, mClient_MasterDeviceID, 1154354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mTimelineID, oldEPStr, 1155464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman mClient_SyncsSentToCurMaster, 1156354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_SyncRespsRXedFromCurMaster, 1157354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_ExpiredSyncRespsRXedFromCurMaster); 1158464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman 11599684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman mRonin_WhoIsMasterRequestTimeouts = 0; 11607f1d9e1c5301e58891db62061cee7d413542be81John Grossman setState(ICommonClock::STATE_RONIN); 11619684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman return sendWhoIsMasterRequest(); 11629684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman } else { 1163354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGI("%s --> INITIAL (%s) : never synced timeline " 1164354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)", 1165354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman stateToString(mState), cause, 1166354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDevicePriority, mClient_MasterDeviceID, 1167354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mTimelineID, oldEPStr, 1168464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman mClient_SyncsSentToCurMaster, 1169354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_SyncRespsRXedFromCurMaster, 1170354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_ExpiredSyncRespsRXedFromCurMaster); 1171464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman 1172354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return becomeInitial("ronin, no timeline"); 11739684be35bf2a3477de640978a5b16bfc55e1461cJohn Grossman } 1174d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1175d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1176354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::becomeWaitForElection(const char* cause) { 1177354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGI("%s --> WAIT_FOR_ELECTION (%s) : dropping out of election," 1178354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman " waiting %d mSec for completion.", 1179354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman stateToString(mState), cause, kWaitForElection_TimeoutMs); 1180464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman 11817f1d9e1c5301e58891db62061cee7d413542be81John Grossman setState(ICommonClock::STATE_WAIT_FOR_ELECTION); 1182354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(kWaitForElection_TimeoutMs); 1183d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return true; 1184d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1185d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1186354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::becomeInitial(const char* cause) { 1187354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman LOGI("Entering INITIAL (%s), total reset.", cause); 1188464a98151c83d71c4dd94b95968eb2f42eb83126John Grossman 11897f1d9e1c5301e58891db62061cee7d413542be81John Grossman setState(ICommonClock::STATE_INITIAL); 1190d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1191d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // reset clock recovery 1192d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClockRecovery.reset(true, true); 1193d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1194d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // reset internal state bookkeeping. 1195354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mCurTimeout.setTimeout(kInfiniteTimeout); 1196354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman memset(&mMasterEP, 0, sizeof(mMasterEP)); 1197354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mMasterEPValid = false; 1198d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mLastPacketRxLocalTime = 0; 1199d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mTimelineID = ICommonClock::kInvalidTimelineID; 1200d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClockSynced = false; 1201d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mInitial_WhoIsMasterRequestTimeouts = 0; 1202d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClient_MasterDeviceID = 0; 1203354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mClient_MasterDevicePriority = 0; 1204d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mRonin_WhoIsMasterRequestTimeouts = 0; 1205354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman resetSyncStats(); 1206d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1207d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen // send the first request to discover the master 1208d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return sendWhoIsMasterRequest(); 1209d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1210d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1211232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanvoid CommonTimeServer::notifyClockSync() { 1212d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (!mClockSynced) { 1213d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClockSynced = true; 12142627965d612c3b30b59c64631d40c8a810dabba4John Grossman mICommonClock->notifyOnTimelineChanged(mTimelineID); 1215d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 1216d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1217d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1218232f869c99b8b33276ddad8054fc3e89e44852e5John Grossmanvoid CommonTimeServer::notifyClockSyncLoss() { 1219d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen if (mClockSynced) { 1220d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mClockSynced = false; 12212627965d612c3b30b59c64631d40c8a810dabba4John Grossman mICommonClock->notifyOnTimelineChanged( 12222627965d612c3b30b59c64631d40c8a810dabba4John Grossman ICommonClock::kInvalidTimelineID); 1223d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 1224d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1225d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 12267f1d9e1c5301e58891db62061cee7d413542be81John Grossmanvoid CommonTimeServer::setState(ICommonClock::State s) { 1227d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen mState = s; 1228d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1229d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 12307f1d9e1c5301e58891db62061cee7d413542be81John Grossmanconst char* CommonTimeServer::stateToString(ICommonClock::State s) { 1231d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen switch(s) { 12327f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_INITIAL: 1233d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return "INITIAL"; 12347f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_CLIENT: 1235d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return "CLIENT"; 12367f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_MASTER: 1237d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return "MASTER"; 12387f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_RONIN: 1239d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return "RONIN"; 12407f1d9e1c5301e58891db62061cee7d413542be81John Grossman case ICommonClock::STATE_WAIT_FOR_ELECTION: 1241d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return "WAIT_FOR_ELECTION"; 1242d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen default: 1243d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen return "unknown"; 1244d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen } 1245d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1246d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1247354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanvoid CommonTimeServer::sockaddrToString(const sockaddr_storage& addr, 1248354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman bool addrValid, 1249354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman char* buf, size_t bufLen) { 1250354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!bufLen || !buf) 1251354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return; 1252354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1253354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (addrValid) { 1254354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman switch (addr.ss_family) { 1255354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case AF_INET: { 1256354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const struct sockaddr_in* sa = 1257354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const struct sockaddr_in*>(&addr); 1258354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman unsigned long a = ntohl(sa->sin_addr.s_addr); 1259354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint16_t p = ntohs(sa->sin_port); 1260354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu", 1261354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ((a >> 24) & 0xFF), ((a >> 16) & 0xFF), 1262354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ((a >> 8) & 0xFF), (a & 0xFF), p); 1263354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } break; 1264354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1265354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case AF_INET6: { 1266354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const struct sockaddr_in6* sa = 1267354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const struct sockaddr_in6*>(&addr); 1268354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const uint8_t* a = sa->sin6_addr.s6_addr; 1269354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint16_t p = ntohs(sa->sin6_port); 1270354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman snprintf(buf, bufLen, 1271354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "%02X%02X:%02X%02X:%02X%02X:%02X%02X:" 1272354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd", 1273354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7], 1274354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], 1275354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman p); 1276354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } break; 1277354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1278354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman default: 1279354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman snprintf(buf, bufLen, 1280354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman "<unknown sockaddr family %d>", addr.ss_family); 1281354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 1282354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 1283354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } else { 1284354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman snprintf(buf, bufLen, "<none>"); 1285354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 1286354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1287354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman buf[bufLen - 1] = 0; 1288354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 1289354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1290354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1, 1291354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const sockaddr_storage& a2, 1292354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman bool matchAddressOnly) { 1293354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (a1.ss_family != a2.ss_family) 1294354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 1295354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1296354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman switch (a1.ss_family) { 1297354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case AF_INET: { 1298354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const struct sockaddr_in* sa1 = 1299354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const struct sockaddr_in*>(&a1); 1300354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const struct sockaddr_in* sa2 = 1301354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const struct sockaddr_in*>(&a2); 1302354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1303354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr) 1304354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 1305354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1306354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return (matchAddressOnly || (sa1->sin_port == sa2->sin_port)); 1307354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } break; 1308354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1309354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman case AF_INET6: { 1310354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const struct sockaddr_in6* sa1 = 1311354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const struct sockaddr_in6*>(&a1); 1312354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman const struct sockaddr_in6* sa2 = 1313354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman reinterpret_cast<const struct sockaddr_in6*>(&a2); 1314354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1315354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr))) 1316354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 1317354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1318354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port)); 1319354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } break; 1320354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1321354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // Huh? We don't deal in non-IPv[46] addresses. Not sure how we got 1322354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // here, but we don't know how to comapre these addresses and simply 1323354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman // default to a no-match decision. 1324354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman default: return false; 1325354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 1326354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 1327d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1328354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanvoid CommonTimeServer::TimeoutHelper::setTimeout(int msec) { 1329354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mTimeoutValid = (msec >= 0); 1330354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mTimeoutValid) 1331354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman mEndTime = systemTime() + 1332354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman (static_cast<nsecs_t>(msec) * 1000000); 1333354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 1334354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1335354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanint CommonTimeServer::TimeoutHelper::msecTillTimeout() { 1336354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!mTimeoutValid) 1337354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return kInfiniteTimeout; 1338d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1339354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman nsecs_t now = systemTime(); 1340354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (now >= mEndTime) 1341354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return 0; 1342d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1343354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint64_t deltaMsec = (((mEndTime - now) + 999999) / 1000000); 1344d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen 1345354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (deltaMsec > static_cast<uint64_t>(std::numeric_limits<int>::max())) 1346354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return std::numeric_limits<int>::max(); 1347354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1348354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return static_cast<int>(deltaMsec); 1349d8dbdf7ead80c6a20db5165dd95d2d974b8e143aMike J. Chen} 1350354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1351354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanbool CommonTimeServer::shouldPanicNotGettingGoodData() { 1352354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (mClient_FirstSyncTX) { 1353354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t now = mLocalClock.getLocalTime(); 1354354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t delta = now - (mClient_LastGoodSyncRX 1355354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman ? mClient_LastGoodSyncRX 1356354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman : mClient_FirstSyncTX); 1357354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta); 1358354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1359354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (deltaUsec >= kNoGoodDataPanicThreshold) 1360354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return true; 1361354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 1362354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1363354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return false; 1364354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 1365354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1366354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanvoid CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) { 1367354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman txTimes[wrPtr] = txTime; 1368354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman rxTimes[wrPtr] = 0; 1369354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman wrPtr = (wrPtr + 1) % RTT_LOG_SIZE; 1370354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!wrPtr) 1371354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman logFull = true; 1372354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 1373354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1374354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossmanvoid CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) { 1375354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (!logFull && !wrPtr) 1376354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman return; 1377354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1378354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman uint32_t i = logFull ? wrPtr : 0; 1379354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman do { 1380354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman if (txTimes[i] == txTime) { 1381354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman rxTimes[i] = rxTime; 1382354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman break; 1383354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } 1384354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman i = (i + 1) % RTT_LOG_SIZE; 1385354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman } while (i != wrPtr); 1386354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} 1387354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman 1388354edbc80ec3f12539e08b32058702b7fe3a27cdJohn Grossman} // namespace android 1389