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