blob: 59576aa245e6d76c7097752b6e99dc42adf57d37 [file] [log] [blame]
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001/*
John Grossman354edbc2012-01-20 12:12:59 -08002 * Copyright (C) 2012 The Android Open Source Project
Mike J. Chend8dbdf72011-08-15 11:21:37 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * A service that exchanges time synchronization information between
19 * a master that defines a timeline and clients that follow the timeline.
20 */
21
John Grossman354edbc2012-01-20 12:12:59 -080022#define LOG_TAG "common_time"
23#include <utils/Log.h>
24
Mike J. Chend8dbdf72011-08-15 11:21:37 -070025#include <arpa/inet.h>
26#include <assert.h>
27#include <fcntl.h>
John Grossman354edbc2012-01-20 12:12:59 -080028#include <limits>
Mike J. Chend8dbdf72011-08-15 11:21:37 -070029#include <linux/if_ether.h>
30#include <net/if.h>
31#include <net/if_arp.h>
32#include <netinet/ip.h>
33#include <poll.h>
34#include <stdio.h>
John Grossman354edbc2012-01-20 12:12:59 -080035#include <sys/eventfd.h>
Mike J. Chend8dbdf72011-08-15 11:21:37 -070036#include <sys/ioctl.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39#include <sys/socket.h>
40
John Grossman232f8692012-01-17 18:52:32 -080041#include <common_time/local_clock.h>
Mike J. Chend8dbdf72011-08-15 11:21:37 -070042#include <binder/IPCThreadState.h>
43#include <binder/ProcessState.h>
Mike J. Chend8dbdf72011-08-15 11:21:37 -070044#include <utils/Timers.h>
45
John Grossman232f8692012-01-17 18:52:32 -080046#include "common_clock_service.h"
John Grossman9387f4f2012-01-18 15:00:33 -080047#include "common_time_config_service.h"
John Grossman354edbc2012-01-20 12:12:59 -080048#include "common_time_server.h"
49#include "common_time_server_packets.h"
Mike J. Chend8dbdf72011-08-15 11:21:37 -070050#include "clock_recovery.h"
51#include "common_clock.h"
52
John Grossman354edbc2012-01-20 12:12:59 -080053using std::numeric_limits;
54
Mike J. Chend8dbdf72011-08-15 11:21:37 -070055namespace android {
56
John Grossman354edbc2012-01-20 12:12:59 -080057const char* CommonTimeServer::kDefaultMasterElectionAddr = "239.195.128.88";
58const uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8887;
59const uint64_t CommonTimeServer::kDefaultSyncGroupID = 0;
60const uint8_t CommonTimeServer::kDefaultMasterPriority = 1;
61const uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
62const uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
63const uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
64const bool CommonTimeServer::kDefaultAutoDisable = true;
65const int CommonTimeServer::kSetupRetryTimeout = 30000;
66const int64_t CommonTimeServer::kNoGoodDataPanicThreshold = 600000000ll;
Mike J. Chend8dbdf72011-08-15 11:21:37 -070067
John Grossman354edbc2012-01-20 12:12:59 -080068// timeout value representing an infinite timeout
John Grossman232f8692012-01-17 18:52:32 -080069const int CommonTimeServer::kInfiniteTimeout = -1;
Mike J. Chend8dbdf72011-08-15 11:21:37 -070070
71/*** Initial state constants ***/
72
73// number of WhoIsMaster attempts sent before giving up
John Grossman232f8692012-01-17 18:52:32 -080074const int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
Mike J. Chend8dbdf72011-08-15 11:21:37 -070075
76// timeout used when waiting for a response to a WhoIsMaster request
John Grossman232f8692012-01-17 18:52:32 -080077const int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
Mike J. Chend8dbdf72011-08-15 11:21:37 -070078
79/*** Client state constants ***/
80
Mike J. Chend8dbdf72011-08-15 11:21:37 -070081// number of sync requests that can fail before a client assumes its master
82// is dead
John Grossmane1d6c082012-04-09 11:26:16 -070083const int CommonTimeServer::kClient_NumSyncRequestRetries = 10;
Mike J. Chend8dbdf72011-08-15 11:21:37 -070084
85/*** Master state constants ***/
86
Mike J. Chend8dbdf72011-08-15 11:21:37 -070087/*** Ronin state constants ***/
88
89// number of WhoIsMaster attempts sent before declaring ourselves master
John Grossmane1d6c082012-04-09 11:26:16 -070090const int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 20;
Mike J. Chend8dbdf72011-08-15 11:21:37 -070091
92// timeout used when waiting for a response to a WhoIsMaster request
John Grossman232f8692012-01-17 18:52:32 -080093const int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
Mike J. Chend8dbdf72011-08-15 11:21:37 -070094
95/*** WaitForElection state constants ***/
96
97// how long do we wait for an announcement from a master before
98// trying another election?
John Grossmane1d6c082012-04-09 11:26:16 -070099const int CommonTimeServer::kWaitForElection_TimeoutMs = 12500;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700100
John Grossman232f8692012-01-17 18:52:32 -0800101CommonTimeServer::CommonTimeServer()
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700102 : Thread(false)
John Grossman7f1d9e12012-01-17 10:20:12 -0800103 , mState(ICommonClock::STATE_INITIAL)
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700104 , mClockRecovery(&mLocalClock, &mCommonClock)
105 , mSocket(-1)
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700106 , mLastPacketRxLocalTime(0)
107 , mTimelineID(ICommonClock::kInvalidTimelineID)
108 , mClockSynced(false)
John Grossman354edbc2012-01-20 12:12:59 -0800109 , mCommonClockHasClients(false)
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700110 , mInitial_WhoIsMasterRequestTimeouts(0)
111 , mClient_MasterDeviceID(0)
John Grossman354edbc2012-01-20 12:12:59 -0800112 , mClient_MasterDevicePriority(0)
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700113 , mRonin_WhoIsMasterRequestTimeouts(0) {
John Grossman354edbc2012-01-20 12:12:59 -0800114 // zero out sync stats
115 resetSyncStats();
116
117 // Setup the master election endpoint to use the default.
118 struct sockaddr_in* meep =
119 reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
120 memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
121 inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
122 meep->sin_family = AF_INET;
123 meep->sin_port = htons(kDefaultMasterElectionPort);
124
125 // Zero out the master endpoint.
126 memset(&mMasterEP, 0, sizeof(mMasterEP));
127 mMasterEPValid = false;
128 mBindIfaceValid = false;
129 setForceLowPriority(false);
130
131 // Set all remaining configuration parameters to their defaults.
132 mDeviceID = 0;
133 mSyncGroupID = kDefaultSyncGroupID;
134 mMasterPriority = kDefaultMasterPriority;
135 mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
136 mSyncRequestIntervalMs = kDefaultSyncRequestIntervalMs;
137 mPanicThresholdUsec = kDefaultPanicThresholdUsec;
138 mAutoDisable = kDefaultAutoDisable;
139
140 // Create the eventfd we will use to signal our thread to wake up when
141 // needed.
142 mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);
143
144 // seed the random number generator (used to generated timeline IDs)
145 srand48(static_cast<unsigned int>(systemTime()));
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700146}
147
John Grossman232f8692012-01-17 18:52:32 -0800148CommonTimeServer::~CommonTimeServer() {
John Grossman354edbc2012-01-20 12:12:59 -0800149 shutdownThread();
150
151 // No need to grab the lock here. We are in the destructor; if the the user
152 // has a thread in any of the APIs while the destructor is being called,
153 // there is a threading problem a the application level we cannot reasonably
154 // do anything about.
155 cleanupSocket_l();
156
157 if (mWakeupThreadFD >= 0) {
158 close(mWakeupThreadFD);
159 mWakeupThreadFD = -1;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700160 }
161}
162
John Grossman354edbc2012-01-20 12:12:59 -0800163bool CommonTimeServer::startServices() {
164 // start the ICommonClock service
165 mICommonClock = CommonClockService::instantiate(*this);
166 if (mICommonClock == NULL)
167 return false;
168
169 // start the ICommonTimeConfig service
170 mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
171 if (mICommonTimeConfig == NULL)
172 return false;
173
174 return true;
175}
176
John Grossman232f8692012-01-17 18:52:32 -0800177bool CommonTimeServer::threadLoop() {
John Grossman354edbc2012-01-20 12:12:59 -0800178 // Register our service interfaces.
179 if (!startServices())
180 return false;
181
182 // Hold the lock while we are in the main thread loop. It will release the
183 // lock when it blocks, and hold the lock at all other times.
184 mLock.lock();
185 runStateMachine_l();
186 mLock.unlock();
187
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700188 IPCThreadState::self()->stopProcess();
189 return false;
190}
191
John Grossman354edbc2012-01-20 12:12:59 -0800192bool CommonTimeServer::runStateMachine_l() {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700193 if (!mLocalClock.initCheck())
194 return false;
195
196 if (!mCommonClock.init(mLocalClock.getLocalFreq()))
197 return false;
198
John Grossman354edbc2012-01-20 12:12:59 -0800199 // Enter the initial state.
200 becomeInitial("startup");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700201
202 // run the state machine
John Grossman354edbc2012-01-20 12:12:59 -0800203 while (!exitPending()) {
204 struct pollfd pfds[2];
205 int rc;
206 int eventCnt = 0;
207 int64_t wakeupTime;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700208
John Grossman354edbc2012-01-20 12:12:59 -0800209 // We are always interested in our wakeup FD.
210 pfds[eventCnt].fd = mWakeupThreadFD;
211 pfds[eventCnt].events = POLLIN;
212 pfds[eventCnt].revents = 0;
213 eventCnt++;
214
215 // If we have a valid socket, then we are interested in what it has to
216 // say as well.
217 if (mSocket >= 0) {
218 pfds[eventCnt].fd = mSocket;
219 pfds[eventCnt].events = POLLIN;
220 pfds[eventCnt].revents = 0;
221 eventCnt++;
222 }
223
224 // Note, we were holding mLock when this function was called. We
225 // release it only while we are blocking and hold it at all other times.
226 mLock.unlock();
227 rc = poll(pfds, eventCnt, mCurTimeout.msecTillTimeout());
228 wakeupTime = mLocalClock.getLocalTime();
229 mLock.lock();
230
231 // Is it time to shutdown? If so, don't hesitate... just do it.
232 if (exitPending())
233 break;
234
235 // Did the poll fail? This should never happen and is fatal if it does.
236 if (rc < 0) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700237 LOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
238 return false;
239 }
240
John Grossman354edbc2012-01-20 12:12:59 -0800241 if (rc == 0)
242 mCurTimeout.setTimeout(kInfiniteTimeout);
243
244 // Were we woken up on purpose? If so, clear the eventfd with a read.
245 if (pfds[0].revents)
246 clearPendingWakeupEvents_l();
247
248 // Is out bind address dirty? If so, clean up our socket (if any).
249 // Alternatively, do we have an active socket but should be auto
250 // disabled? If so, release the socket and enter the proper sync state.
251 bool droppedSocket = false;
252 if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
253 cleanupSocket_l();
254 mBindIfaceDirty = false;
255 droppedSocket = true;
256 }
257
258 // Do we not have a socket but should have one? If so, try to set one
259 // up.
260 if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
261 if (setupSocket_l()) {
262 // Success! We are now joining a new network (either coming
263 // from no network, or coming from a potentially different
264 // network). Force our priority to be lower so that we defer to
265 // any other masters which may already be on the network we are
266 // joining. Later, when we enter either the client or the
267 // master state, we will clear this flag and go back to our
268 // normal election priority.
269 setForceLowPriority(true);
270 switch (mState) {
271 // If we were in initial (whether we had a immediately
272 // before this network or not) we want to simply reset the
273 // system and start again. Forcing a transition from
274 // INITIAL to INITIAL should do the job.
275 case CommonClockService::STATE_INITIAL:
276 becomeInitial("bound interface");
277 break;
278
279 // If we were in the master state, then either we were the
280 // master in a no-network situation, or we were the master
281 // of a different network and have moved to a new interface.
John Grossmane1d6c082012-04-09 11:26:16 -0700282 // In either case, immediately transition to Ronin at low
283 // priority. If there is no one in the network we just
284 // joined, we will become master soon enough. If there is,
285 // we want to be certain to defer master status to the
286 // existing timeline currently running on the network.
287 //
John Grossman354edbc2012-01-20 12:12:59 -0800288 case CommonClockService::STATE_MASTER:
John Grossmane1d6c082012-04-09 11:26:16 -0700289 becomeRonin("leaving networkless mode");
John Grossman354edbc2012-01-20 12:12:59 -0800290 break;
291
292 // If we were in any other state (CLIENT, RONIN, or
293 // WAIT_FOR_ELECTION) then we must be moving from one
294 // network to another. We have lost our old master;
295 // transition to RONIN in an attempt to find a new master.
296 // If there are none out there, we will just assume
297 // responsibility for the timeline we used to be a client
298 // of.
299 default:
300 becomeRonin("bound interface");
301 break;
302 }
303 } else {
304 // That's odd... we failed to set up our socket. This could be
305 // due to some transient network change which will work itself
306 // out shortly; schedule a retry attempt in the near future.
307 mCurTimeout.setTimeout(kSetupRetryTimeout);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700308 }
309
John Grossman354edbc2012-01-20 12:12:59 -0800310 // One way or the other, we don't have any data to process at this
311 // point (since we just tried to bulid a new socket). Loop back
312 // around and wait for the next thing to do.
313 continue;
314 } else if (droppedSocket) {
315 // We just lost our socket, and for whatever reason (either no
316 // config, or auto disable engaged) we are not supposed to rebuild
317 // one at this time. We are not going to rebuild our socket until
318 // something about our config/auto-disabled status changes, so we
319 // are basically in network-less mode. If we are already in either
320 // INITIAL or MASTER, just stay there until something changes. If
321 // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
322 // then transition to either INITIAL or MASTER depending on whether
323 // or not our timeline is valid.
324 LOGI("Entering networkless mode interface is %s, "
325 "shouldAutoDisable = %s",
326 mBindIfaceValid ? "valid" : "invalid",
327 shouldAutoDisable() ? "true" : "false");
328 if ((mState != ICommonClock::STATE_INITIAL) &&
329 (mState != ICommonClock::STATE_MASTER)) {
330 if (mTimelineID == ICommonClock::kInvalidTimelineID)
331 becomeInitial("network-less mode");
332 else
333 becomeMaster("network-less mode");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700334 }
John Grossman354edbc2012-01-20 12:12:59 -0800335
336 continue;
337 }
338
339 // Did we wakeup with no signalled events across all of our FDs? If so,
340 // we must have hit our timeout.
341 if (rc == 0) {
342 if (!handleTimeout())
343 LOGE("handleTimeout failed");
344 continue;
345 }
346
347 // Does our socket have data for us (assuming we still have one, we
348 // may have RXed a packet at the same time as a config change telling us
349 // to shut our socket down)? If so, process its data.
350 if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
351 mLastPacketRxLocalTime = wakeupTime;
352 if (!handlePacket())
353 LOGE("handlePacket failed");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700354 }
355 }
356
John Grossman354edbc2012-01-20 12:12:59 -0800357 cleanupSocket_l();
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700358 return true;
359}
360
John Grossman354edbc2012-01-20 12:12:59 -0800361void CommonTimeServer::clearPendingWakeupEvents_l() {
362 int64_t tmp;
363 read(mWakeupThreadFD, &tmp, sizeof(tmp));
364}
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700365
John Grossman354edbc2012-01-20 12:12:59 -0800366void CommonTimeServer::wakeupThread_l() {
367 int64_t tmp = 1;
368 write(mWakeupThreadFD, &tmp, sizeof(tmp));
369}
370
371void CommonTimeServer::cleanupSocket_l() {
372 if (mSocket >= 0) {
373 close(mSocket);
374 mSocket = -1;
375 }
376}
377
378void CommonTimeServer::shutdownThread() {
379 // Flag the work thread for shutdown.
380 this->requestExit();
381
382 // Signal the thread in case its sleeping.
383 mLock.lock();
384 wakeupThread_l();
385 mLock.unlock();
386
387 // Wait for the thread to exit.
388 this->join();
389}
390
391bool CommonTimeServer::setupSocket_l() {
392 int rc;
393 bool ret_val = false;
394 struct sockaddr_in* ipv4_addr = NULL;
395 char masterElectionEPStr[64];
396 const int one = 1;
397
398 // This should never be needed, but if we happened to have an old socket
399 // lying around, be sure to not leak it before proceeding.
400 cleanupSocket_l();
401
402 // If we don't have a valid endpoint to bind to, then how did we get here in
403 // the first place? Regardless, we know that we are going to fail to bind,
404 // so don't even try.
405 if (!mBindIfaceValid)
406 return false;
407
408 sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
409 sizeof(masterElectionEPStr));
410 LOGI("Building socket :: bind = %s master election = %s",
411 mBindIface.string(), masterElectionEPStr);
412
413 // TODO: add proper support for IPv6. Right now, we block IPv6 addresses at
414 // the configuration interface level.
415 if (AF_INET != mMasterElectionEP.ss_family) {
416 LOGW("TODO: add proper IPv6 support");
417 goto bailout;
418 }
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700419
420 // open a UDP socket for the timeline serivce
421 mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
John Grossman354edbc2012-01-20 12:12:59 -0800422 if (mSocket < 0) {
423 LOGE("Failed to create socket (errno = %d)", errno);
424 goto bailout;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700425 }
426
John Grossman354edbc2012-01-20 12:12:59 -0800427 // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
428 struct ifreq ifr;
429 memset(&ifr, 0, sizeof(ifr));
430 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
431 ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
432 rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
433 (void *)&ifr, sizeof(ifr));
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700434 if (rc) {
John Grossman354edbc2012-01-20 12:12:59 -0800435 LOGE("Failed to bind socket at to interface %s (errno = %d)",
436 ifr.ifr_name, errno);
437 goto bailout;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700438 }
439
John Grossman354edbc2012-01-20 12:12:59 -0800440 // Bind our socket to INADDR_ANY and the master election port. The
441 // interface binding we made using SO_BINDTODEVICE should limit us to
442 // traffic only on the interface we are interested in. We need to bind to
443 // INADDR_ANY and the specific master election port in order to be able to
444 // receive both unicast traffic and master election multicast traffic with
445 // just a single socket.
446 struct sockaddr_in bindAddr;
447 ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
448 memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
449 bindAddr.sin_addr.s_addr = INADDR_ANY;
450 rc = bind(mSocket,
451 reinterpret_cast<const sockaddr *>(&bindAddr),
452 sizeof(bindAddr));
453 if (rc) {
454 LOGE("Failed to bind socket to port %hu (errno = %d)",
455 ntohs(bindAddr.sin_port), errno);
456 goto bailout;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700457 }
458
John Grossman354edbc2012-01-20 12:12:59 -0800459 if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
460 // If our master election endpoint is a multicast address, be sure to join
461 // the multicast group.
462 struct ip_mreq mreq;
463 mreq.imr_multiaddr = ipv4_addr->sin_addr;
464 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
465 rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
466 &mreq, sizeof(mreq));
467 if (rc == -1) {
468 LOGE("Failed to join multicast group at %s. (errno = %d)",
469 masterElectionEPStr, errno);
470 goto bailout;
471 }
472
473 // disable loopback of multicast packets
474 const int zero = 0;
475 rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
476 &zero, sizeof(zero));
477 if (rc == -1) {
478 LOGE("Failed to disable multicast loopback (errno = %d)", errno);
479 goto bailout;
480 }
481 } else
482 if (ntohl(ipv4_addr->sin_addr.s_addr) != 0xFFFFFFFF) {
483 // If the master election address is neither broadcast, nor multicast,
484 // then we are misconfigured. The config API layer should prevent this
485 // from ever happening.
486 goto bailout;
487 }
488
489 // Set the TTL of sent packets to 1. (Time protocol sync should never leave
490 // the local subnet)
491 rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700492 if (rc == -1) {
John Grossman354edbc2012-01-20 12:12:59 -0800493 LOGE("Failed to set TTL to %d (errno = %d)", one, errno);
494 goto bailout;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700495 }
496
497 // get the device's unique ID
498 if (!assignDeviceID())
John Grossman354edbc2012-01-20 12:12:59 -0800499 goto bailout;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700500
John Grossman354edbc2012-01-20 12:12:59 -0800501 ret_val = true;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700502
John Grossman354edbc2012-01-20 12:12:59 -0800503bailout:
504 if (!ret_val)
505 cleanupSocket_l();
506 return ret_val;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700507}
508
509// generate a unique device ID that can be used for arbitration
John Grossman232f8692012-01-17 18:52:32 -0800510bool CommonTimeServer::assignDeviceID() {
John Grossman583a03a2012-01-12 11:05:37 -0800511 if (!mBindIfaceValid)
512 return false;
513
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700514 struct ifreq ifr;
515 memset(&ifr, 0, sizeof(ifr));
516 ifr.ifr_addr.sa_family = AF_INET;
John Grossman583a03a2012-01-12 11:05:37 -0800517 strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700518
519 int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
520 if (rc) {
521 LOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
522 return false;
523 }
524
525 if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
526 LOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
527 return false;
528 }
529
530 mDeviceID = 0;
531 for (int i = 0; i < ETH_ALEN; i++) {
532 mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
533 }
534
535 return true;
536}
537
538// generate a new timeline ID
John Grossman232f8692012-01-17 18:52:32 -0800539void CommonTimeServer::assignTimelineID() {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700540 do {
John Grossman354edbc2012-01-20 12:12:59 -0800541 mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
542 | static_cast<uint64_t>(lrand48());
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700543 } while (mTimelineID == ICommonClock::kInvalidTimelineID);
544}
545
546// Select a preference between the device IDs of two potential masters.
547// Returns true if the first ID wins, or false if the second ID wins.
John Grossman354edbc2012-01-20 12:12:59 -0800548bool CommonTimeServer::arbitrateMaster(
549 uint64_t deviceID1, uint8_t devicePrio1,
550 uint64_t deviceID2, uint8_t devicePrio2) {
551 return ((devicePrio1 > devicePrio2) ||
552 ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700553}
554
John Grossman232f8692012-01-17 18:52:32 -0800555bool CommonTimeServer::handlePacket() {
John Grossman354edbc2012-01-20 12:12:59 -0800556 uint8_t buf[256];
557 struct sockaddr_storage srcAddr;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700558 socklen_t srcAddrLen = sizeof(srcAddr);
559
560 ssize_t recvBytes = recvfrom(
561 mSocket, buf, sizeof(buf), 0,
562 reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);
563
John Grossman354edbc2012-01-20 12:12:59 -0800564 if (recvBytes < 0) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700565 LOGE("%s:%d recvfrom failed", __PRETTY_FUNCTION__, __LINE__);
566 return false;
567 }
568
John Grossman354edbc2012-01-20 12:12:59 -0800569 UniversalTimeServicePacket pkt;
570 recvBytes = pkt.deserializePacket(buf, recvBytes, mSyncGroupID);
571 if (recvBytes < 0)
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700572 return false;
573
574 bool result;
John Grossman354edbc2012-01-20 12:12:59 -0800575 switch (pkt.packetType) {
576 case TIME_PACKET_WHO_IS_MASTER_REQUEST:
577 result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
578 srcAddr);
579 break;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700580
John Grossman354edbc2012-01-20 12:12:59 -0800581 case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
582 result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
583 srcAddr);
584 break;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700585
John Grossman354edbc2012-01-20 12:12:59 -0800586 case TIME_PACKET_SYNC_REQUEST:
587 result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
588 break;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700589
John Grossman354edbc2012-01-20 12:12:59 -0800590 case TIME_PACKET_SYNC_RESPONSE:
591 result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
592 break;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700593
John Grossman354edbc2012-01-20 12:12:59 -0800594 case TIME_PACKET_MASTER_ANNOUNCEMENT:
595 result = handleMasterAnnouncement(&pkt.p.master_announcement,
596 srcAddr);
597 break;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700598
599 default: {
John Grossman354edbc2012-01-20 12:12:59 -0800600 LOGD("%s:%d unknown packet type(%d)",
601 __PRETTY_FUNCTION__, __LINE__, pkt.packetType);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700602 result = false;
603 } break;
604 }
605
606 return result;
607}
608
John Grossman232f8692012-01-17 18:52:32 -0800609bool CommonTimeServer::handleTimeout() {
John Grossman354edbc2012-01-20 12:12:59 -0800610 // If we have no socket, then this must be a timeout to retry socket setup.
611 if (mSocket < 0)
612 return true;
613
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700614 switch (mState) {
John Grossman7f1d9e12012-01-17 10:20:12 -0800615 case ICommonClock::STATE_INITIAL:
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700616 return handleTimeoutInitial();
John Grossman7f1d9e12012-01-17 10:20:12 -0800617 case ICommonClock::STATE_CLIENT:
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700618 return handleTimeoutClient();
John Grossman7f1d9e12012-01-17 10:20:12 -0800619 case ICommonClock::STATE_MASTER:
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700620 return handleTimeoutMaster();
John Grossman7f1d9e12012-01-17 10:20:12 -0800621 case ICommonClock::STATE_RONIN:
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700622 return handleTimeoutRonin();
John Grossman7f1d9e12012-01-17 10:20:12 -0800623 case ICommonClock::STATE_WAIT_FOR_ELECTION:
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700624 return handleTimeoutWaitForElection();
625 }
626
627 return false;
628}
629
John Grossman232f8692012-01-17 18:52:32 -0800630bool CommonTimeServer::handleTimeoutInitial() {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700631 if (++mInitial_WhoIsMasterRequestTimeouts ==
632 kInitial_NumWhoIsMasterRetries) {
633 // none of our attempts to discover a master succeeded, so make
634 // this device the master
John Grossman354edbc2012-01-20 12:12:59 -0800635 return becomeMaster("initial timeout");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700636 } else {
637 // retry the WhoIsMaster request
638 return sendWhoIsMasterRequest();
639 }
640}
641
John Grossman232f8692012-01-17 18:52:32 -0800642bool CommonTimeServer::handleTimeoutClient() {
John Grossman354edbc2012-01-20 12:12:59 -0800643 if (shouldPanicNotGettingGoodData())
644 return becomeInitial("timeout panic, no good data");
645
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700646 if (mClient_SyncRequestPending) {
647 mClient_SyncRequestPending = false;
648
649 if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
650 // a sync request has timed out, so retry
651 return sendSyncRequest();
652 } else {
653 // The master has failed to respond to a sync request for too many
654 // times in a row. Assume the master is dead and start electing
655 // a new master.
John Grossman354edbc2012-01-20 12:12:59 -0800656 return becomeRonin("master not responding");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700657 }
658 } else {
659 // initiate the next sync request
660 return sendSyncRequest();
661 }
662}
663
John Grossman232f8692012-01-17 18:52:32 -0800664bool CommonTimeServer::handleTimeoutMaster() {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700665 // send another announcement from the master
666 return sendMasterAnnouncement();
667}
668
John Grossman232f8692012-01-17 18:52:32 -0800669bool CommonTimeServer::handleTimeoutRonin() {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700670 if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
671 // no other master is out there, so we won the election
John Grossman354edbc2012-01-20 12:12:59 -0800672 return becomeMaster("no better masters detected");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700673 } else {
674 return sendWhoIsMasterRequest();
675 }
676}
677
John Grossman232f8692012-01-17 18:52:32 -0800678bool CommonTimeServer::handleTimeoutWaitForElection() {
John Grossman354edbc2012-01-20 12:12:59 -0800679 return becomeRonin("timeout waiting for election conclusion");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700680}
681
John Grossman232f8692012-01-17 18:52:32 -0800682bool CommonTimeServer::handleWhoIsMasterRequest(
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700683 const WhoIsMasterRequestPacket* request,
John Grossman354edbc2012-01-20 12:12:59 -0800684 const sockaddr_storage& srcAddr) {
John Grossman7f1d9e12012-01-17 10:20:12 -0800685 if (mState == ICommonClock::STATE_MASTER) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700686 // is this request related to this master's timeline?
John Grossman354edbc2012-01-20 12:12:59 -0800687 if (request->timelineID != ICommonClock::kInvalidTimelineID &&
688 request->timelineID != mTimelineID)
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700689 return true;
690
John Grossman354edbc2012-01-20 12:12:59 -0800691 WhoIsMasterResponsePacket pkt;
692 pkt.initHeader(mTimelineID, mSyncGroupID);
693 pkt.deviceID = mDeviceID;
694 pkt.devicePriority = effectivePriority();
695
696 uint8_t buf[256];
697 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
698 if (bufSz < 0)
699 return false;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700700
701 ssize_t sendBytes = sendto(
John Grossman354edbc2012-01-20 12:12:59 -0800702 mSocket, buf, bufSz, 0,
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700703 reinterpret_cast<const sockaddr *>(&srcAddr),
704 sizeof(srcAddr));
705 if (sendBytes == -1) {
706 LOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
707 return false;
708 }
John Grossman7f1d9e12012-01-17 10:20:12 -0800709 } else if (mState == ICommonClock::STATE_RONIN) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700710 // if we hear a WhoIsMaster request from another device following
711 // the same timeline and that device wins arbitration, then we will stop
712 // trying to elect ourselves master and will instead wait for an
713 // announcement from the election winner
John Grossman354edbc2012-01-20 12:12:59 -0800714 if (request->timelineID != mTimelineID)
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700715 return true;
716
John Grossman354edbc2012-01-20 12:12:59 -0800717 if (arbitrateMaster(request->senderDeviceID,
718 request->senderDevicePriority,
719 mDeviceID,
720 effectivePriority()))
721 return becomeWaitForElection("would lose election");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700722
723 return true;
John Grossman7f1d9e12012-01-17 10:20:12 -0800724 } else if (mState == ICommonClock::STATE_INITIAL) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700725 // If a group of devices booted simultaneously (e.g. after a power
726 // outage) and all of them are in the initial state and there is no
727 // master, then each device may time out and declare itself master at
728 // the same time. To avoid this, listen for
729 // WhoIsMaster(InvalidTimeline) requests from peers. If we would lose
730 // arbitration against that peer, reset our timeout count so that the
731 // peer has a chance to become master before we time out.
John Grossman354edbc2012-01-20 12:12:59 -0800732 if (request->timelineID == ICommonClock::kInvalidTimelineID &&
733 arbitrateMaster(request->senderDeviceID,
734 request->senderDevicePriority,
735 mDeviceID,
736 effectivePriority())) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700737 mInitial_WhoIsMasterRequestTimeouts = 0;
738 }
739 }
740
741 return true;
742}
743
John Grossman232f8692012-01-17 18:52:32 -0800744bool CommonTimeServer::handleWhoIsMasterResponse(
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700745 const WhoIsMasterResponsePacket* response,
John Grossman354edbc2012-01-20 12:12:59 -0800746 const sockaddr_storage& srcAddr) {
John Grossman7f1d9e12012-01-17 10:20:12 -0800747 if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700748 return becomeClient(srcAddr,
John Grossman354edbc2012-01-20 12:12:59 -0800749 response->deviceID,
750 response->devicePriority,
751 response->timelineID,
752 "heard whois response");
John Grossman7f1d9e12012-01-17 10:20:12 -0800753 } else if (mState == ICommonClock::STATE_CLIENT) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700754 // if we get multiple responses because there are multiple devices
755 // who believe that they are master, then follow the master that
756 // wins arbitration
John Grossman354edbc2012-01-20 12:12:59 -0800757 if (arbitrateMaster(response->deviceID,
758 response->devicePriority,
759 mClient_MasterDeviceID,
760 mClient_MasterDevicePriority)) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700761 return becomeClient(srcAddr,
John Grossman354edbc2012-01-20 12:12:59 -0800762 response->deviceID,
763 response->devicePriority,
764 response->timelineID,
765 "heard whois response");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700766 }
767 }
768
769 return true;
770}
771
John Grossman232f8692012-01-17 18:52:32 -0800772bool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
John Grossman354edbc2012-01-20 12:12:59 -0800773 const sockaddr_storage& srcAddr) {
774 SyncResponsePacket pkt;
775 pkt.initHeader(mTimelineID, mSyncGroupID);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700776
John Grossman354edbc2012-01-20 12:12:59 -0800777 if ((mState == ICommonClock::STATE_MASTER) &&
778 (mTimelineID == request->timelineID)) {
779 int64_t rxLocalTime = mLastPacketRxLocalTime;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700780 int64_t rxCommonTime;
John Grossman354edbc2012-01-20 12:12:59 -0800781
782 // If we are master on an actual network and have actual clients, then
783 // we are no longer low priority.
784 setForceLowPriority(false);
785
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700786 if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
787 return false;
788 }
789
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700790 int64_t txLocalTime = mLocalClock.getLocalTime();;
791 int64_t txCommonTime;
792 if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
793 return false;
794 }
795
John Grossman354edbc2012-01-20 12:12:59 -0800796 pkt.nak = 0;
797 pkt.clientTxLocalTime = request->clientTxLocalTime;
798 pkt.masterRxCommonTime = rxCommonTime;
799 pkt.masterTxCommonTime = txCommonTime;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700800 } else {
John Grossman354edbc2012-01-20 12:12:59 -0800801 pkt.nak = 1;
802 pkt.clientTxLocalTime = 0;
803 pkt.masterRxCommonTime = 0;
804 pkt.masterTxCommonTime = 0;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700805 }
806
John Grossman354edbc2012-01-20 12:12:59 -0800807 uint8_t buf[256];
808 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
809 if (bufSz < 0)
810 return false;
811
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700812 ssize_t sendBytes = sendto(
John Grossman354edbc2012-01-20 12:12:59 -0800813 mSocket, &buf, bufSz, 0,
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700814 reinterpret_cast<const sockaddr *>(&srcAddr),
815 sizeof(srcAddr));
816 if (sendBytes == -1) {
817 LOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
818 return false;
819 }
820
821 return true;
822}
823
John Grossman232f8692012-01-17 18:52:32 -0800824bool CommonTimeServer::handleSyncResponse(
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700825 const SyncResponsePacket* response,
John Grossman354edbc2012-01-20 12:12:59 -0800826 const sockaddr_storage& srcAddr) {
John Grossman7f1d9e12012-01-17 10:20:12 -0800827 if (mState != ICommonClock::STATE_CLIENT)
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700828 return true;
829
John Grossman354edbc2012-01-20 12:12:59 -0800830 assert(mMasterEPValid);
831 if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
832 char srcEP[64], expectedEP[64];
833 sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
834 sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
John Grossman464a9812011-10-31 16:34:24 -0700835 LOGI("Dropping sync response from unexpected address."
John Grossman354edbc2012-01-20 12:12:59 -0800836 " Expected %s Got %s", expectedEP, srcEP);
John Grossman464a9812011-10-31 16:34:24 -0700837 return true;
838 }
839
John Grossman354edbc2012-01-20 12:12:59 -0800840 if (response->nak) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700841 // if our master is no longer accepting requests, then we need to find
842 // a new master
John Grossman354edbc2012-01-20 12:12:59 -0800843 return becomeRonin("master NAK'ed");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700844 }
845
846 mClient_SyncRequestPending = 0;
847 mClient_SyncRequestTimeouts = 0;
John Grossman354edbc2012-01-20 12:12:59 -0800848 mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
849 mLastPacketRxLocalTime);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700850
851 bool result;
John Grossman354edbc2012-01-20 12:12:59 -0800852 if (!(mClient_SyncRespsRXedFromCurMaster++)) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700853 // the first request/response exchange between a client and a master
854 // may take unusually long due to ARP, so discard it.
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700855 result = true;
856 } else {
John Grossman354edbc2012-01-20 12:12:59 -0800857 int64_t clientTxLocalTime = response->clientTxLocalTime;
858 int64_t clientRxLocalTime = mLastPacketRxLocalTime;
859 int64_t masterTxCommonTime = response->masterTxCommonTime;
860 int64_t masterRxCommonTime = response->masterRxCommonTime;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700861
862 int64_t rtt = (clientRxLocalTime - clientTxLocalTime);
863 int64_t avgLocal = (clientTxLocalTime + clientRxLocalTime) >> 1;
864 int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700865
John Grossman354edbc2012-01-20 12:12:59 -0800866 // if the RTT of the packet is significantly larger than the panic
867 // threshold, we should simply discard it. Its better to do nothing
868 // than to take cues from a packet like that.
869 int rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
870 if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) * 5)) {
871 LOGV("Dropping sync response with RTT of %lld uSec", rttCommon);
872 mClient_ExpiredSyncRespsRXedFromCurMaster++;
873 if (shouldPanicNotGettingGoodData())
874 return becomeInitial("RX panic, no good data");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700875 } else {
Kent Ryhorchuk17fe2472012-02-13 16:24:29 -0800876 result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon);
John Grossman354edbc2012-01-20 12:12:59 -0800877 mClient_LastGoodSyncRX = clientRxLocalTime;
878
879 if (result) {
880 // indicate to listeners that we've synced to the common timeline
881 notifyClockSync();
882 } else {
883 LOGE("Panic! Observed clock sync error is too high to tolerate,"
884 " resetting state machine and starting over.");
885 notifyClockSyncLoss();
886 return becomeInitial("panic");
887 }
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700888 }
889 }
890
John Grossman354edbc2012-01-20 12:12:59 -0800891 mCurTimeout.setTimeout(mSyncRequestIntervalMs);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700892 return result;
893}
894
John Grossman232f8692012-01-17 18:52:32 -0800895bool CommonTimeServer::handleMasterAnnouncement(
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700896 const MasterAnnouncementPacket* packet,
John Grossman354edbc2012-01-20 12:12:59 -0800897 const sockaddr_storage& srcAddr) {
898 uint64_t newDeviceID = packet->deviceID;
899 uint8_t newDevicePrio = packet->devicePriority;
900 uint64_t newTimelineID = packet->timelineID;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700901
John Grossman7f1d9e12012-01-17 10:20:12 -0800902 if (mState == ICommonClock::STATE_INITIAL ||
903 mState == ICommonClock::STATE_RONIN ||
904 mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700905 // if we aren't currently following a master, then start following
906 // this new master
John Grossman354edbc2012-01-20 12:12:59 -0800907 return becomeClient(srcAddr,
908 newDeviceID,
909 newDevicePrio,
910 newTimelineID,
911 "heard master announcement");
John Grossman7f1d9e12012-01-17 10:20:12 -0800912 } else if (mState == ICommonClock::STATE_CLIENT) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700913 // if the new master wins arbitration against our current master,
914 // then become a client of the new master
John Grossman354edbc2012-01-20 12:12:59 -0800915 if (arbitrateMaster(newDeviceID,
916 newDevicePrio,
917 mClient_MasterDeviceID,
918 mClient_MasterDevicePriority))
919 return becomeClient(srcAddr,
920 newDeviceID,
921 newDevicePrio,
922 newTimelineID,
923 "heard master announcement");
John Grossman7f1d9e12012-01-17 10:20:12 -0800924 } else if (mState == ICommonClock::STATE_MASTER) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700925 // two masters are competing - if the new one wins arbitration, then
926 // cease acting as master
John Grossman354edbc2012-01-20 12:12:59 -0800927 if (arbitrateMaster(newDeviceID, newDevicePrio,
928 mDeviceID, effectivePriority()))
929 return becomeClient(srcAddr, newDeviceID,
930 newDevicePrio, newTimelineID,
931 "heard master announcement");
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700932 }
933
934 return true;
935}
936
John Grossman232f8692012-01-17 18:52:32 -0800937bool CommonTimeServer::sendWhoIsMasterRequest() {
John Grossman7f1d9e12012-01-17 10:20:12 -0800938 assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700939
John Grossman354edbc2012-01-20 12:12:59 -0800940 // If we have no socket, then we must be in the unconfigured initial state.
941 // Don't report any errors, just don't try to send the initial who-is-master
942 // query. Eventually, our network will either become configured, or we will
943 // be forced into network-less master mode by higher level code.
944 if (mSocket < 0) {
945 assert(mState == ICommonClock::STATE_INITIAL);
946 return true;
947 }
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700948
John Grossman354edbc2012-01-20 12:12:59 -0800949 bool ret = false;
950 WhoIsMasterRequestPacket pkt;
951 pkt.initHeader(mSyncGroupID);
952 pkt.senderDeviceID = mDeviceID;
953 pkt.senderDevicePriority = effectivePriority();
954
955 uint8_t buf[256];
956 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
957 if (bufSz >= 0) {
958 ssize_t sendBytes = sendto(
959 mSocket, buf, bufSz, 0,
960 reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
961 sizeof(mMasterElectionEP));
962 if (sendBytes < 0)
963 LOGE("WhoIsMaster sendto failed (errno %d)", errno);
964 ret = true;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700965 }
966
John Grossman7f1d9e12012-01-17 10:20:12 -0800967 if (mState == ICommonClock::STATE_INITIAL) {
John Grossman354edbc2012-01-20 12:12:59 -0800968 mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700969 } else {
John Grossman354edbc2012-01-20 12:12:59 -0800970 mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700971 }
972
John Grossman354edbc2012-01-20 12:12:59 -0800973 return ret;
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700974}
975
John Grossman232f8692012-01-17 18:52:32 -0800976bool CommonTimeServer::sendSyncRequest() {
John Grossman354edbc2012-01-20 12:12:59 -0800977 // If we are sending sync requests, then we must be in the client state and
978 // we must have a socket (when we have no network, we are only supposed to
979 // be in INITIAL or MASTER)
John Grossman7f1d9e12012-01-17 10:20:12 -0800980 assert(mState == ICommonClock::STATE_CLIENT);
John Grossman354edbc2012-01-20 12:12:59 -0800981 assert(mSocket >= 0);
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700982
John Grossman354edbc2012-01-20 12:12:59 -0800983 bool ret = false;
984 SyncRequestPacket pkt;
985 pkt.initHeader(mTimelineID, mSyncGroupID);
986 pkt.clientTxLocalTime = mLocalClock.getLocalTime();
Mike J. Chend8dbdf72011-08-15 11:21:37 -0700987
John Grossman354edbc2012-01-20 12:12:59 -0800988 if (!mClient_FirstSyncTX)
989 mClient_FirstSyncTX = pkt.clientTxLocalTime;
990
991 mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
992
993 uint8_t buf[256];
994 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
995 if (bufSz >= 0) {
996 ssize_t sendBytes = sendto(
997 mSocket, buf, bufSz, 0,
998 reinterpret_cast<const sockaddr *>(&mMasterEP),
999 sizeof(mMasterEP));
1000 if (sendBytes < 0)
1001 LOGE("SyncRequest sendto failed (errno %d)", errno);
1002 ret = true;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001003 }
1004
John Grossman464a9812011-10-31 16:34:24 -07001005 mClient_SyncsSentToCurMaster++;
John Grossman354edbc2012-01-20 12:12:59 -08001006 mCurTimeout.setTimeout(mSyncRequestIntervalMs);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001007 mClient_SyncRequestPending = true;
John Grossman354edbc2012-01-20 12:12:59 -08001008
1009 return ret;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001010}
1011
John Grossman232f8692012-01-17 18:52:32 -08001012bool CommonTimeServer::sendMasterAnnouncement() {
John Grossman354edbc2012-01-20 12:12:59 -08001013 bool ret = false;
John Grossman7f1d9e12012-01-17 10:20:12 -08001014 assert(mState == ICommonClock::STATE_MASTER);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001015
John Grossman354edbc2012-01-20 12:12:59 -08001016 // If we are being asked to send a master announcement, but we have no
1017 // socket, we must be in network-less master mode. Don't bother to send the
1018 // announcement, and don't bother to schedule a timeout. When the network
1019 // comes up, the work thread will get poked and start the process of
1020 // figuring out who the current master should be.
1021 if (mSocket < 0) {
1022 mCurTimeout.setTimeout(kInfiniteTimeout);
1023 return true;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001024 }
1025
John Grossman354edbc2012-01-20 12:12:59 -08001026 MasterAnnouncementPacket pkt;
1027 pkt.initHeader(mTimelineID, mSyncGroupID);
1028 pkt.deviceID = mDeviceID;
1029 pkt.devicePriority = effectivePriority();
1030
1031 uint8_t buf[256];
1032 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
1033 if (bufSz >= 0) {
1034 ssize_t sendBytes = sendto(
1035 mSocket, buf, bufSz, 0,
1036 reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
1037 sizeof(mMasterElectionEP));
1038 if (sendBytes < 0)
1039 LOGE("MasterAnnouncement sendto failed (errno %d)", errno);
1040 ret = true;
1041 }
1042
1043 mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
1044 return ret;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001045}
1046
John Grossman354edbc2012-01-20 12:12:59 -08001047bool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
1048 uint64_t masterDeviceID,
1049 uint8_t masterDevicePriority,
1050 uint64_t timelineID,
1051 const char* cause) {
1052 char newEPStr[64], oldEPStr[64];
1053 sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
1054 sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
1055
1056 LOGI("%s --> CLIENT (%s) :%s"
1057 " OldMaster: %02x-%014llx::%016llx::%s"
1058 " NewMaster: %02x-%014llx::%016llx::%s",
1059 stateToString(mState), cause,
John Grossman464a9812011-10-31 16:34:24 -07001060 (mTimelineID != timelineID) ? " (new timeline)" : "",
John Grossman354edbc2012-01-20 12:12:59 -08001061 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1062 mTimelineID, oldEPStr,
1063 masterDevicePriority, masterDeviceID,
1064 timelineID, newEPStr);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001065
1066 if (mTimelineID != timelineID) {
1067 // start following a new timeline
1068 mTimelineID = timelineID;
1069 mClockRecovery.reset(true, true);
1070 notifyClockSyncLoss();
1071 } else {
1072 // start following a new master on the existing timeline
1073 mClockRecovery.reset(false, true);
1074 }
1075
John Grossman354edbc2012-01-20 12:12:59 -08001076 mMasterEP = masterEP;
1077 mMasterEPValid = true;
John Grossmane1d6c082012-04-09 11:26:16 -07001078
1079 // If we are on a real network as a client of a real master, then we should
1080 // no longer force low priority. If our master disappears, we should have
1081 // the high priority bit set during the election to replace the master
1082 // because this group was a real group and not a singleton created in
1083 // networkless mode.
John Grossman354edbc2012-01-20 12:12:59 -08001084 setForceLowPriority(false);
1085
John Grossman464a9812011-10-31 16:34:24 -07001086 mClient_MasterDeviceID = masterDeviceID;
John Grossman354edbc2012-01-20 12:12:59 -08001087 mClient_MasterDevicePriority = masterDevicePriority;
1088 resetSyncStats();
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001089
John Grossman7f1d9e12012-01-17 10:20:12 -08001090 setState(ICommonClock::STATE_CLIENT);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001091
1092 // add some jitter to when the various clients send their requests
1093 // in order to reduce the likelihood that a group of clients overload
1094 // the master after receiving a master announcement
John Grossman354edbc2012-01-20 12:12:59 -08001095 usleep((lrand48() % 100) * 1000);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001096
1097 return sendSyncRequest();
1098}
1099
John Grossman354edbc2012-01-20 12:12:59 -08001100bool CommonTimeServer::becomeMaster(const char* cause) {
1101 uint64_t oldTimelineID = mTimelineID;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001102 if (mTimelineID == ICommonClock::kInvalidTimelineID) {
1103 // this device has not been following any existing timeline,
1104 // so it will create a new timeline and declare itself master
1105 assert(!mCommonClock.isValid());
1106
1107 // set the common time basis
1108 mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
1109
1110 // assign an arbitrary timeline iD
1111 assignTimelineID();
1112
1113 // notify listeners that we've created a common timeline
1114 notifyClockSync();
1115 }
1116
John Grossman354edbc2012-01-20 12:12:59 -08001117 LOGI("%s --> MASTER (%s) : %s timeline %016llx",
1118 stateToString(mState), cause,
John Grossman464a9812011-10-31 16:34:24 -07001119 (oldTimelineID == mTimelineID) ? "taking ownership of"
1120 : "creating new",
1121 mTimelineID);
1122
John Grossman354edbc2012-01-20 12:12:59 -08001123 memset(&mMasterEP, 0, sizeof(mMasterEP));
1124 mMasterEPValid = false;
John Grossman354edbc2012-01-20 12:12:59 -08001125 mClient_MasterDevicePriority = effectivePriority();
1126 mClient_MasterDeviceID = mDeviceID;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001127 mClockRecovery.reset(false, true);
John Grossman354edbc2012-01-20 12:12:59 -08001128 resetSyncStats();
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001129
John Grossman7f1d9e12012-01-17 10:20:12 -08001130 setState(ICommonClock::STATE_MASTER);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001131 return sendMasterAnnouncement();
1132}
1133
John Grossman354edbc2012-01-20 12:12:59 -08001134bool CommonTimeServer::becomeRonin(const char* cause) {
John Grossman9684be32011-10-13 12:34:29 -07001135 // If we were the client of a given timeline, but had never received even a
1136 // single time sync packet, then we transition back to Initial instead of
1137 // Ronin. If we transition to Ronin and end up becoming the new Master, we
1138 // will be unable to service requests for other clients because we never
1139 // actually knew what time it was. By going to initial, we ensure that
1140 // other clients who know what time it is, but would lose master arbitration
1141 // in the Ronin case, will step up and become the proper new master of the
1142 // old timeline.
John Grossman354edbc2012-01-20 12:12:59 -08001143
1144 char oldEPStr[64];
1145 sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
1146 memset(&mMasterEP, 0, sizeof(mMasterEP));
1147 mMasterEPValid = false;
1148
John Grossman9684be32011-10-13 12:34:29 -07001149 if (mCommonClock.isValid()) {
John Grossman354edbc2012-01-20 12:12:59 -08001150 LOGI("%s --> RONIN (%s) : lost track of previously valid timeline "
1151 "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
1152 stateToString(mState), cause,
1153 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1154 mTimelineID, oldEPStr,
John Grossman464a9812011-10-31 16:34:24 -07001155 mClient_SyncsSentToCurMaster,
John Grossman354edbc2012-01-20 12:12:59 -08001156 mClient_SyncRespsRXedFromCurMaster,
1157 mClient_ExpiredSyncRespsRXedFromCurMaster);
John Grossman464a9812011-10-31 16:34:24 -07001158
John Grossman9684be32011-10-13 12:34:29 -07001159 mRonin_WhoIsMasterRequestTimeouts = 0;
John Grossman7f1d9e12012-01-17 10:20:12 -08001160 setState(ICommonClock::STATE_RONIN);
John Grossman9684be32011-10-13 12:34:29 -07001161 return sendWhoIsMasterRequest();
1162 } else {
John Grossman354edbc2012-01-20 12:12:59 -08001163 LOGI("%s --> INITIAL (%s) : never synced timeline "
1164 "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
1165 stateToString(mState), cause,
1166 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1167 mTimelineID, oldEPStr,
John Grossman464a9812011-10-31 16:34:24 -07001168 mClient_SyncsSentToCurMaster,
John Grossman354edbc2012-01-20 12:12:59 -08001169 mClient_SyncRespsRXedFromCurMaster,
1170 mClient_ExpiredSyncRespsRXedFromCurMaster);
John Grossman464a9812011-10-31 16:34:24 -07001171
John Grossman354edbc2012-01-20 12:12:59 -08001172 return becomeInitial("ronin, no timeline");
John Grossman9684be32011-10-13 12:34:29 -07001173 }
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001174}
1175
John Grossman354edbc2012-01-20 12:12:59 -08001176bool CommonTimeServer::becomeWaitForElection(const char* cause) {
1177 LOGI("%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
1178 " waiting %d mSec for completion.",
1179 stateToString(mState), cause, kWaitForElection_TimeoutMs);
John Grossman464a9812011-10-31 16:34:24 -07001180
John Grossman7f1d9e12012-01-17 10:20:12 -08001181 setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
John Grossman354edbc2012-01-20 12:12:59 -08001182 mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001183 return true;
1184}
1185
John Grossman354edbc2012-01-20 12:12:59 -08001186bool CommonTimeServer::becomeInitial(const char* cause) {
1187 LOGI("Entering INITIAL (%s), total reset.", cause);
John Grossman464a9812011-10-31 16:34:24 -07001188
John Grossman7f1d9e12012-01-17 10:20:12 -08001189 setState(ICommonClock::STATE_INITIAL);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001190
1191 // reset clock recovery
1192 mClockRecovery.reset(true, true);
1193
1194 // reset internal state bookkeeping.
John Grossman354edbc2012-01-20 12:12:59 -08001195 mCurTimeout.setTimeout(kInfiniteTimeout);
1196 memset(&mMasterEP, 0, sizeof(mMasterEP));
1197 mMasterEPValid = false;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001198 mLastPacketRxLocalTime = 0;
1199 mTimelineID = ICommonClock::kInvalidTimelineID;
1200 mClockSynced = false;
1201 mInitial_WhoIsMasterRequestTimeouts = 0;
1202 mClient_MasterDeviceID = 0;
John Grossman354edbc2012-01-20 12:12:59 -08001203 mClient_MasterDevicePriority = 0;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001204 mRonin_WhoIsMasterRequestTimeouts = 0;
John Grossman354edbc2012-01-20 12:12:59 -08001205 resetSyncStats();
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001206
1207 // send the first request to discover the master
1208 return sendWhoIsMasterRequest();
1209}
1210
John Grossman232f8692012-01-17 18:52:32 -08001211void CommonTimeServer::notifyClockSync() {
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001212 if (!mClockSynced) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001213 mClockSynced = true;
John Grossman26279652012-01-17 17:10:55 -08001214 mICommonClock->notifyOnTimelineChanged(mTimelineID);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001215 }
1216}
1217
John Grossman232f8692012-01-17 18:52:32 -08001218void CommonTimeServer::notifyClockSyncLoss() {
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001219 if (mClockSynced) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001220 mClockSynced = false;
John Grossman26279652012-01-17 17:10:55 -08001221 mICommonClock->notifyOnTimelineChanged(
1222 ICommonClock::kInvalidTimelineID);
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001223 }
1224}
1225
John Grossman7f1d9e12012-01-17 10:20:12 -08001226void CommonTimeServer::setState(ICommonClock::State s) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001227 mState = s;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001228}
1229
John Grossman7f1d9e12012-01-17 10:20:12 -08001230const char* CommonTimeServer::stateToString(ICommonClock::State s) {
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001231 switch(s) {
John Grossman7f1d9e12012-01-17 10:20:12 -08001232 case ICommonClock::STATE_INITIAL:
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001233 return "INITIAL";
John Grossman7f1d9e12012-01-17 10:20:12 -08001234 case ICommonClock::STATE_CLIENT:
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001235 return "CLIENT";
John Grossman7f1d9e12012-01-17 10:20:12 -08001236 case ICommonClock::STATE_MASTER:
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001237 return "MASTER";
John Grossman7f1d9e12012-01-17 10:20:12 -08001238 case ICommonClock::STATE_RONIN:
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001239 return "RONIN";
John Grossman7f1d9e12012-01-17 10:20:12 -08001240 case ICommonClock::STATE_WAIT_FOR_ELECTION:
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001241 return "WAIT_FOR_ELECTION";
1242 default:
1243 return "unknown";
1244 }
1245}
1246
John Grossman354edbc2012-01-20 12:12:59 -08001247void CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
1248 bool addrValid,
1249 char* buf, size_t bufLen) {
1250 if (!bufLen || !buf)
1251 return;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001252
John Grossman354edbc2012-01-20 12:12:59 -08001253 if (addrValid) {
1254 switch (addr.ss_family) {
1255 case AF_INET: {
1256 const struct sockaddr_in* sa =
1257 reinterpret_cast<const struct sockaddr_in*>(&addr);
1258 unsigned long a = ntohl(sa->sin_addr.s_addr);
1259 uint16_t p = ntohs(sa->sin_port);
1260 snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
1261 ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
1262 ((a >> 8) & 0xFF), (a & 0xFF), p);
1263 } break;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001264
John Grossman354edbc2012-01-20 12:12:59 -08001265 case AF_INET6: {
1266 const struct sockaddr_in6* sa =
1267 reinterpret_cast<const struct sockaddr_in6*>(&addr);
1268 const uint8_t* a = sa->sin6_addr.s6_addr;
1269 uint16_t p = ntohs(sa->sin6_port);
1270 snprintf(buf, bufLen,
1271 "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
1272 "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
1273 a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
1274 a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
1275 p);
1276 } break;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001277
John Grossman354edbc2012-01-20 12:12:59 -08001278 default:
1279 snprintf(buf, bufLen,
1280 "<unknown sockaddr family %d>", addr.ss_family);
1281 break;
1282 }
1283 } else {
1284 snprintf(buf, bufLen, "<none>");
1285 }
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001286
John Grossman354edbc2012-01-20 12:12:59 -08001287 buf[bufLen - 1] = 0;
Mike J. Chend8dbdf72011-08-15 11:21:37 -07001288}
John Grossman354edbc2012-01-20 12:12:59 -08001289
1290bool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
1291 const sockaddr_storage& a2,
1292 bool matchAddressOnly) {
1293 if (a1.ss_family != a2.ss_family)
1294 return false;
1295
1296 switch (a1.ss_family) {
1297 case AF_INET: {
1298 const struct sockaddr_in* sa1 =
1299 reinterpret_cast<const struct sockaddr_in*>(&a1);
1300 const struct sockaddr_in* sa2 =
1301 reinterpret_cast<const struct sockaddr_in*>(&a2);
1302
1303 if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
1304 return false;
1305
1306 return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
1307 } break;
1308
1309 case AF_INET6: {
1310 const struct sockaddr_in6* sa1 =
1311 reinterpret_cast<const struct sockaddr_in6*>(&a1);
1312 const struct sockaddr_in6* sa2 =
1313 reinterpret_cast<const struct sockaddr_in6*>(&a2);
1314
1315 if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
1316 return false;
1317
1318 return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
1319 } break;
1320
1321 // Huh? We don't deal in non-IPv[46] addresses. Not sure how we got
1322 // here, but we don't know how to comapre these addresses and simply
1323 // default to a no-match decision.
1324 default: return false;
1325 }
1326}
1327
1328void CommonTimeServer::TimeoutHelper::setTimeout(int msec) {
1329 mTimeoutValid = (msec >= 0);
1330 if (mTimeoutValid)
1331 mEndTime = systemTime() +
1332 (static_cast<nsecs_t>(msec) * 1000000);
1333}
1334
1335int CommonTimeServer::TimeoutHelper::msecTillTimeout() {
1336 if (!mTimeoutValid)
1337 return kInfiniteTimeout;
1338
1339 nsecs_t now = systemTime();
1340 if (now >= mEndTime)
1341 return 0;
1342
1343 uint64_t deltaMsec = (((mEndTime - now) + 999999) / 1000000);
1344
1345 if (deltaMsec > static_cast<uint64_t>(std::numeric_limits<int>::max()))
1346 return std::numeric_limits<int>::max();
1347
1348 return static_cast<int>(deltaMsec);
1349}
1350
1351bool CommonTimeServer::shouldPanicNotGettingGoodData() {
1352 if (mClient_FirstSyncTX) {
1353 int64_t now = mLocalClock.getLocalTime();
1354 int64_t delta = now - (mClient_LastGoodSyncRX
1355 ? mClient_LastGoodSyncRX
1356 : mClient_FirstSyncTX);
1357 int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
1358
1359 if (deltaUsec >= kNoGoodDataPanicThreshold)
1360 return true;
1361 }
1362
1363 return false;
1364}
1365
1366void CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
1367 txTimes[wrPtr] = txTime;
1368 rxTimes[wrPtr] = 0;
1369 wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
1370 if (!wrPtr)
1371 logFull = true;
1372}
1373
1374void CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
1375 if (!logFull && !wrPtr)
1376 return;
1377
1378 uint32_t i = logFull ? wrPtr : 0;
1379 do {
1380 if (txTimes[i] == txTime) {
1381 rxTimes[i] = rxTime;
1382 break;
1383 }
1384 i = (i + 1) % RTT_LOG_SIZE;
1385 } while (i != wrPtr);
1386}
1387
1388} // namespace android