blob: 4af73b5adf169302ab39c4fee5bdc4ebf9bdf151 [file] [log] [blame]
Mike J. Chen6c929512011-08-15 11:59:47 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
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
22#define LOG_TAG "common_time"
23#include <utils/Log.h>
24
25#include <arpa/inet.h>
26#include <assert.h>
27#include <fcntl.h>
28#include <limits>
29#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>
35#include <sys/eventfd.h>
36#include <sys/ioctl.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39#include <sys/socket.h>
40
41#include <common_time/local_clock.h>
42#include <binder/IPCThreadState.h>
43#include <binder/ProcessState.h>
44#include <utils/Timers.h>
45
46#include "common_clock_service.h"
47#include "common_time_config_service.h"
48#include "common_time_server.h"
49#include "common_time_server_packets.h"
50#include "clock_recovery.h"
51#include "common_clock.h"
52
53using std::numeric_limits;
54
55namespace android {
56
57const 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::kSetupRetryTimeoutMs = 30000;
66const int64_t CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
67const uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;
68
69// timeout value representing an infinite timeout
70const int CommonTimeServer::kInfiniteTimeout = -1;
71
72/*** Initial state constants ***/
73
74// number of WhoIsMaster attempts sent before giving up
75const int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
76
77// timeout used when waiting for a response to a WhoIsMaster request
78const int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
79
80/*** Client state constants ***/
81
82// number of sync requests that can fail before a client assumes its master
83// is dead
84const int CommonTimeServer::kClient_NumSyncRequestRetries = 5;
85
86/*** Master state constants ***/
87
88/*** Ronin state constants ***/
89
90// number of WhoIsMaster attempts sent before declaring ourselves master
91const int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 4;
92
93// timeout used when waiting for a response to a WhoIsMaster request
94const int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
95
96/*** WaitForElection state constants ***/
97
98// how long do we wait for an announcement from a master before
99// trying another election?
100const int CommonTimeServer::kWaitForElection_TimeoutMs = 5000;
101
102CommonTimeServer::CommonTimeServer()
103 : Thread(false)
104 , mState(ICommonClock::STATE_INITIAL)
105 , mClockRecovery(&mLocalClock, &mCommonClock)
106 , mSocket(-1)
107 , mLastPacketRxLocalTime(0)
108 , mTimelineID(ICommonClock::kInvalidTimelineID)
109 , mClockSynced(false)
110 , mCommonClockHasClients(false)
111 , mInitial_WhoIsMasterRequestTimeouts(0)
112 , mClient_MasterDeviceID(0)
113 , mClient_MasterDevicePriority(0)
114 , mRonin_WhoIsMasterRequestTimeouts(0) {
115 // zero out sync stats
116 resetSyncStats();
117
118 // Setup the master election endpoint to use the default.
119 struct sockaddr_in* meep =
120 reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
121 memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
122 inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
123 meep->sin_family = AF_INET;
124 meep->sin_port = htons(kDefaultMasterElectionPort);
125
126 // Zero out the master endpoint.
127 memset(&mMasterEP, 0, sizeof(mMasterEP));
128 mMasterEPValid = false;
129 mBindIfaceValid = false;
130 setForceLowPriority(false);
131
132 // Set all remaining configuration parameters to their defaults.
133 mDeviceID = 0;
134 mSyncGroupID = kDefaultSyncGroupID;
135 mMasterPriority = kDefaultMasterPriority;
136 mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
137 mSyncRequestIntervalMs = kDefaultSyncRequestIntervalMs;
138 mPanicThresholdUsec = kDefaultPanicThresholdUsec;
139 mAutoDisable = kDefaultAutoDisable;
140
141 // Create the eventfd we will use to signal our thread to wake up when
142 // needed.
143 mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);
144
145 // seed the random number generator (used to generated timeline IDs)
146 srand48(static_cast<unsigned int>(systemTime()));
147}
148
149CommonTimeServer::~CommonTimeServer() {
150 shutdownThread();
151
152 // No need to grab the lock here. We are in the destructor; if the the user
153 // has a thread in any of the APIs while the destructor is being called,
154 // there is a threading problem a the application level we cannot reasonably
155 // do anything about.
156 cleanupSocket_l();
157
158 if (mWakeupThreadFD >= 0) {
159 close(mWakeupThreadFD);
160 mWakeupThreadFD = -1;
161 }
162}
163
164bool CommonTimeServer::startServices() {
165 // start the ICommonClock service
166 mICommonClock = CommonClockService::instantiate(*this);
167 if (mICommonClock == NULL)
168 return false;
169
170 // start the ICommonTimeConfig service
171 mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
172 if (mICommonTimeConfig == NULL)
173 return false;
174
175 return true;
176}
177
178bool CommonTimeServer::threadLoop() {
179 // Register our service interfaces.
180 if (!startServices())
181 return false;
182
183 // Hold the lock while we are in the main thread loop. It will release the
184 // lock when it blocks, and hold the lock at all other times.
185 mLock.lock();
186 runStateMachine_l();
187 mLock.unlock();
188
189 IPCThreadState::self()->stopProcess();
190 return false;
191}
192
193bool CommonTimeServer::runStateMachine_l() {
194 if (!mLocalClock.initCheck())
195 return false;
196
197 if (!mCommonClock.init(mLocalClock.getLocalFreq()))
198 return false;
199
200 // Enter the initial state.
201 becomeInitial("startup");
202
203 // run the state machine
204 while (!exitPending()) {
205 struct pollfd pfds[2];
206 int rc;
207 int eventCnt = 0;
208 int64_t wakeupTime;
209
210 // We are always interested in our wakeup FD.
211 pfds[eventCnt].fd = mWakeupThreadFD;
212 pfds[eventCnt].events = POLLIN;
213 pfds[eventCnt].revents = 0;
214 eventCnt++;
215
216 // If we have a valid socket, then we are interested in what it has to
217 // say as well.
218 if (mSocket >= 0) {
219 pfds[eventCnt].fd = mSocket;
220 pfds[eventCnt].events = POLLIN;
221 pfds[eventCnt].revents = 0;
222 eventCnt++;
223 }
224
225 // Note, we were holding mLock when this function was called. We
226 // release it only while we are blocking and hold it at all other times.
227 mLock.unlock();
228 rc = poll(pfds, eventCnt, mCurTimeout.msecTillTimeout());
229 wakeupTime = mLocalClock.getLocalTime();
230 mLock.lock();
231
232 // Is it time to shutdown? If so, don't hesitate... just do it.
233 if (exitPending())
234 break;
235
236 // Did the poll fail? This should never happen and is fatal if it does.
237 if (rc < 0) {
238 ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
239 return false;
240 }
241
242 if (rc == 0)
243 mCurTimeout.setTimeout(kInfiniteTimeout);
244
245 // Were we woken up on purpose? If so, clear the eventfd with a read.
246 if (pfds[0].revents)
247 clearPendingWakeupEvents_l();
248
249 // Is out bind address dirty? If so, clean up our socket (if any).
250 // Alternatively, do we have an active socket but should be auto
251 // disabled? If so, release the socket and enter the proper sync state.
252 bool droppedSocket = false;
253 if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
254 cleanupSocket_l();
255 mBindIfaceDirty = false;
256 droppedSocket = true;
257 }
258
259 // Do we not have a socket but should have one? If so, try to set one
260 // up.
261 if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
262 if (setupSocket_l()) {
263 // Success! We are now joining a new network (either coming
264 // from no network, or coming from a potentially different
265 // network). Force our priority to be lower so that we defer to
266 // any other masters which may already be on the network we are
267 // joining. Later, when we enter either the client or the
268 // master state, we will clear this flag and go back to our
269 // normal election priority.
270 setForceLowPriority(true);
271 switch (mState) {
272 // If we were in initial (whether we had a immediately
273 // before this network or not) we want to simply reset the
274 // system and start again. Forcing a transition from
275 // INITIAL to INITIAL should do the job.
276 case CommonClockService::STATE_INITIAL:
277 becomeInitial("bound interface");
278 break;
279
280 // If we were in the master state, then either we were the
281 // master in a no-network situation, or we were the master
282 // of a different network and have moved to a new interface.
283 // In either case, immediately send out a master
284 // announcement at low priority.
285 case CommonClockService::STATE_MASTER:
286 sendMasterAnnouncement();
287 break;
288
289 // If we were in any other state (CLIENT, RONIN, or
290 // WAIT_FOR_ELECTION) then we must be moving from one
291 // network to another. We have lost our old master;
292 // transition to RONIN in an attempt to find a new master.
293 // If there are none out there, we will just assume
294 // responsibility for the timeline we used to be a client
295 // of.
296 default:
297 becomeRonin("bound interface");
298 break;
299 }
300 } else {
301 // That's odd... we failed to set up our socket. This could be
302 // due to some transient network change which will work itself
303 // out shortly; schedule a retry attempt in the near future.
304 mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
305 }
306
307 // One way or the other, we don't have any data to process at this
308 // point (since we just tried to bulid a new socket). Loop back
309 // around and wait for the next thing to do.
310 continue;
311 } else if (droppedSocket) {
312 // We just lost our socket, and for whatever reason (either no
313 // config, or auto disable engaged) we are not supposed to rebuild
314 // one at this time. We are not going to rebuild our socket until
315 // something about our config/auto-disabled status changes, so we
316 // are basically in network-less mode. If we are already in either
317 // INITIAL or MASTER, just stay there until something changes. If
318 // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
319 // then transition to either INITIAL or MASTER depending on whether
320 // or not our timeline is valid.
321 ALOGI("Entering networkless mode interface is %s, "
322 "shouldAutoDisable = %s",
323 mBindIfaceValid ? "valid" : "invalid",
324 shouldAutoDisable() ? "true" : "false");
325 if ((mState != ICommonClock::STATE_INITIAL) &&
326 (mState != ICommonClock::STATE_MASTER)) {
327 if (mTimelineID == ICommonClock::kInvalidTimelineID)
328 becomeInitial("network-less mode");
329 else
330 becomeMaster("network-less mode");
331 }
332
333 continue;
334 }
335
336 // Did we wakeup with no signalled events across all of our FDs? If so,
337 // we must have hit our timeout.
338 if (rc == 0) {
339 if (!handleTimeout())
340 ALOGE("handleTimeout failed");
341 continue;
342 }
343
344 // Does our socket have data for us (assuming we still have one, we
345 // may have RXed a packet at the same time as a config change telling us
346 // to shut our socket down)? If so, process its data.
347 if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
348 mLastPacketRxLocalTime = wakeupTime;
349 if (!handlePacket())
350 ALOGE("handlePacket failed");
351 }
352 }
353
354 cleanupSocket_l();
355 return true;
356}
357
358void CommonTimeServer::clearPendingWakeupEvents_l() {
359 int64_t tmp;
360 read(mWakeupThreadFD, &tmp, sizeof(tmp));
361}
362
363void CommonTimeServer::wakeupThread_l() {
364 int64_t tmp = 1;
365 write(mWakeupThreadFD, &tmp, sizeof(tmp));
366}
367
368void CommonTimeServer::cleanupSocket_l() {
369 if (mSocket >= 0) {
370 close(mSocket);
371 mSocket = -1;
372 }
373}
374
375void CommonTimeServer::shutdownThread() {
376 // Flag the work thread for shutdown.
377 this->requestExit();
378
379 // Signal the thread in case its sleeping.
380 mLock.lock();
381 wakeupThread_l();
382 mLock.unlock();
383
384 // Wait for the thread to exit.
385 this->join();
386}
387
388bool CommonTimeServer::setupSocket_l() {
389 int rc;
390 bool ret_val = false;
391 struct sockaddr_in* ipv4_addr = NULL;
392 char masterElectionEPStr[64];
393 const int one = 1;
394
395 // This should never be needed, but if we happened to have an old socket
396 // lying around, be sure to not leak it before proceeding.
397 cleanupSocket_l();
398
399 // If we don't have a valid endpoint to bind to, then how did we get here in
400 // the first place? Regardless, we know that we are going to fail to bind,
401 // so don't even try.
402 if (!mBindIfaceValid)
403 return false;
404
405 sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
406 sizeof(masterElectionEPStr));
407 ALOGI("Building socket :: bind = %s master election = %s",
408 mBindIface.string(), masterElectionEPStr);
409
410 // TODO: add proper support for IPv6. Right now, we block IPv6 addresses at
411 // the configuration interface level.
412 if (AF_INET != mMasterElectionEP.ss_family) {
413 ALOGW("TODO: add proper IPv6 support");
414 goto bailout;
415 }
416
417 // open a UDP socket for the timeline serivce
418 mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
419 if (mSocket < 0) {
420 ALOGE("Failed to create socket (errno = %d)", errno);
421 goto bailout;
422 }
423
424 // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
425 struct ifreq ifr;
426 memset(&ifr, 0, sizeof(ifr));
427 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
428 ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
429 rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
430 (void *)&ifr, sizeof(ifr));
431 if (rc) {
432 ALOGE("Failed to bind socket at to interface %s (errno = %d)",
433 ifr.ifr_name, errno);
434 goto bailout;
435 }
436
437 // Bind our socket to INADDR_ANY and the master election port. The
438 // interface binding we made using SO_BINDTODEVICE should limit us to
439 // traffic only on the interface we are interested in. We need to bind to
440 // INADDR_ANY and the specific master election port in order to be able to
441 // receive both unicast traffic and master election multicast traffic with
442 // just a single socket.
443 struct sockaddr_in bindAddr;
444 ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
445 memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
446 bindAddr.sin_addr.s_addr = INADDR_ANY;
447 rc = bind(mSocket,
448 reinterpret_cast<const sockaddr *>(&bindAddr),
449 sizeof(bindAddr));
450 if (rc) {
451 ALOGE("Failed to bind socket to port %hu (errno = %d)",
452 ntohs(bindAddr.sin_port), errno);
453 goto bailout;
454 }
455
456 if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
457 // If our master election endpoint is a multicast address, be sure to join
458 // the multicast group.
459 struct ip_mreq mreq;
460 mreq.imr_multiaddr = ipv4_addr->sin_addr;
461 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
462 rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
463 &mreq, sizeof(mreq));
464 if (rc == -1) {
465 ALOGE("Failed to join multicast group at %s. (errno = %d)",
466 masterElectionEPStr, errno);
467 goto bailout;
468 }
469
470 // disable loopback of multicast packets
471 const int zero = 0;
472 rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
473 &zero, sizeof(zero));
474 if (rc == -1) {
475 ALOGE("Failed to disable multicast loopback (errno = %d)", errno);
476 goto bailout;
477 }
478 } else
479 if (ntohl(ipv4_addr->sin_addr.s_addr) != 0xFFFFFFFF) {
480 // If the master election address is neither broadcast, nor multicast,
481 // then we are misconfigured. The config API layer should prevent this
482 // from ever happening.
483 goto bailout;
484 }
485
486 // Set the TTL of sent packets to 1. (Time protocol sync should never leave
487 // the local subnet)
488 rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
489 if (rc == -1) {
490 ALOGE("Failed to set TTL to %d (errno = %d)", one, errno);
491 goto bailout;
492 }
493
494 // get the device's unique ID
495 if (!assignDeviceID())
496 goto bailout;
497
498 ret_val = true;
499
500bailout:
501 if (!ret_val)
502 cleanupSocket_l();
503 return ret_val;
504}
505
506// generate a unique device ID that can be used for arbitration
507bool CommonTimeServer::assignDeviceID() {
508 if (!mBindIfaceValid)
509 return false;
510
511 struct ifreq ifr;
512 memset(&ifr, 0, sizeof(ifr));
513 ifr.ifr_addr.sa_family = AF_INET;
514 strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
515
516 int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
517 if (rc) {
518 ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
519 return false;
520 }
521
522 if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
523 ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
524 return false;
525 }
526
527 mDeviceID = 0;
528 for (int i = 0; i < ETH_ALEN; i++) {
529 mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
530 }
531
532 return true;
533}
534
535// generate a new timeline ID
536void CommonTimeServer::assignTimelineID() {
537 do {
538 mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
539 | static_cast<uint64_t>(lrand48());
540 } while (mTimelineID == ICommonClock::kInvalidTimelineID);
541}
542
543// Select a preference between the device IDs of two potential masters.
544// Returns true if the first ID wins, or false if the second ID wins.
545bool CommonTimeServer::arbitrateMaster(
546 uint64_t deviceID1, uint8_t devicePrio1,
547 uint64_t deviceID2, uint8_t devicePrio2) {
548 return ((devicePrio1 > devicePrio2) ||
549 ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
550}
551
552bool CommonTimeServer::handlePacket() {
553 uint8_t buf[256];
554 struct sockaddr_storage srcAddr;
555 socklen_t srcAddrLen = sizeof(srcAddr);
556
557 ssize_t recvBytes = recvfrom(
558 mSocket, buf, sizeof(buf), 0,
559 reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);
560
561 if (recvBytes < 0) {
562 ALOGE("%s:%d recvfrom failed", __PRETTY_FUNCTION__, __LINE__);
563 return false;
564 }
565
566 UniversalTimeServicePacket pkt;
567 recvBytes = pkt.deserializePacket(buf, recvBytes, mSyncGroupID);
568 if (recvBytes < 0)
569 return false;
570
571 bool result;
572 switch (pkt.packetType) {
573 case TIME_PACKET_WHO_IS_MASTER_REQUEST:
574 result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
575 srcAddr);
576 break;
577
578 case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
579 result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
580 srcAddr);
581 break;
582
583 case TIME_PACKET_SYNC_REQUEST:
584 result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
585 break;
586
587 case TIME_PACKET_SYNC_RESPONSE:
588 result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
589 break;
590
591 case TIME_PACKET_MASTER_ANNOUNCEMENT:
592 result = handleMasterAnnouncement(&pkt.p.master_announcement,
593 srcAddr);
594 break;
595
596 default: {
597 ALOGD("%s:%d unknown packet type(%d)",
598 __PRETTY_FUNCTION__, __LINE__, pkt.packetType);
599 result = false;
600 } break;
601 }
602
603 return result;
604}
605
606bool CommonTimeServer::handleTimeout() {
607 // If we have no socket, then this must be a timeout to retry socket setup.
608 if (mSocket < 0)
609 return true;
610
611 switch (mState) {
612 case ICommonClock::STATE_INITIAL:
613 return handleTimeoutInitial();
614 case ICommonClock::STATE_CLIENT:
615 return handleTimeoutClient();
616 case ICommonClock::STATE_MASTER:
617 return handleTimeoutMaster();
618 case ICommonClock::STATE_RONIN:
619 return handleTimeoutRonin();
620 case ICommonClock::STATE_WAIT_FOR_ELECTION:
621 return handleTimeoutWaitForElection();
622 }
623
624 return false;
625}
626
627bool CommonTimeServer::handleTimeoutInitial() {
628 if (++mInitial_WhoIsMasterRequestTimeouts ==
629 kInitial_NumWhoIsMasterRetries) {
630 // none of our attempts to discover a master succeeded, so make
631 // this device the master
632 return becomeMaster("initial timeout");
633 } else {
634 // retry the WhoIsMaster request
635 return sendWhoIsMasterRequest();
636 }
637}
638
639bool CommonTimeServer::handleTimeoutClient() {
640 if (shouldPanicNotGettingGoodData())
641 return becomeInitial("timeout panic, no good data");
642
643 if (mClient_SyncRequestPending) {
644 mClient_SyncRequestPending = false;
645
646 if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
647 // a sync request has timed out, so retry
648 return sendSyncRequest();
649 } else {
650 // The master has failed to respond to a sync request for too many
651 // times in a row. Assume the master is dead and start electing
652 // a new master.
653 return becomeRonin("master not responding");
654 }
655 } else {
656 // initiate the next sync request
657 return sendSyncRequest();
658 }
659}
660
661bool CommonTimeServer::handleTimeoutMaster() {
662 // send another announcement from the master
663 return sendMasterAnnouncement();
664}
665
666bool CommonTimeServer::handleTimeoutRonin() {
667 if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
668 // no other master is out there, so we won the election
669 return becomeMaster("no better masters detected");
670 } else {
671 return sendWhoIsMasterRequest();
672 }
673}
674
675bool CommonTimeServer::handleTimeoutWaitForElection() {
676 return becomeRonin("timeout waiting for election conclusion");
677}
678
679bool CommonTimeServer::handleWhoIsMasterRequest(
680 const WhoIsMasterRequestPacket* request,
681 const sockaddr_storage& srcAddr) {
682 if (mState == ICommonClock::STATE_MASTER) {
683 // is this request related to this master's timeline?
684 if (request->timelineID != ICommonClock::kInvalidTimelineID &&
685 request->timelineID != mTimelineID)
686 return true;
687
688 WhoIsMasterResponsePacket pkt;
689 pkt.initHeader(mTimelineID, mSyncGroupID);
690 pkt.deviceID = mDeviceID;
691 pkt.devicePriority = effectivePriority();
692
693 uint8_t buf[256];
694 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
695 if (bufSz < 0)
696 return false;
697
698 ssize_t sendBytes = sendto(
699 mSocket, buf, bufSz, 0,
700 reinterpret_cast<const sockaddr *>(&srcAddr),
701 sizeof(srcAddr));
702 if (sendBytes == -1) {
703 ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
704 return false;
705 }
706 } else if (mState == ICommonClock::STATE_RONIN) {
707 // if we hear a WhoIsMaster request from another device following
708 // the same timeline and that device wins arbitration, then we will stop
709 // trying to elect ourselves master and will instead wait for an
710 // announcement from the election winner
711 if (request->timelineID != mTimelineID)
712 return true;
713
714 if (arbitrateMaster(request->senderDeviceID,
715 request->senderDevicePriority,
716 mDeviceID,
717 effectivePriority()))
718 return becomeWaitForElection("would lose election");
719
720 return true;
721 } else if (mState == ICommonClock::STATE_INITIAL) {
722 // If a group of devices booted simultaneously (e.g. after a power
723 // outage) and all of them are in the initial state and there is no
724 // master, then each device may time out and declare itself master at
725 // the same time. To avoid this, listen for
726 // WhoIsMaster(InvalidTimeline) requests from peers. If we would lose
727 // arbitration against that peer, reset our timeout count so that the
728 // peer has a chance to become master before we time out.
729 if (request->timelineID == ICommonClock::kInvalidTimelineID &&
730 arbitrateMaster(request->senderDeviceID,
731 request->senderDevicePriority,
732 mDeviceID,
733 effectivePriority())) {
734 mInitial_WhoIsMasterRequestTimeouts = 0;
735 }
736 }
737
738 return true;
739}
740
741bool CommonTimeServer::handleWhoIsMasterResponse(
742 const WhoIsMasterResponsePacket* response,
743 const sockaddr_storage& srcAddr) {
744 if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
745 return becomeClient(srcAddr,
746 response->deviceID,
747 response->devicePriority,
748 response->timelineID,
749 "heard whois response");
750 } else if (mState == ICommonClock::STATE_CLIENT) {
751 // if we get multiple responses because there are multiple devices
752 // who believe that they are master, then follow the master that
753 // wins arbitration
754 if (arbitrateMaster(response->deviceID,
755 response->devicePriority,
756 mClient_MasterDeviceID,
757 mClient_MasterDevicePriority)) {
758 return becomeClient(srcAddr,
759 response->deviceID,
760 response->devicePriority,
761 response->timelineID,
762 "heard whois response");
763 }
764 }
765
766 return true;
767}
768
769bool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
770 const sockaddr_storage& srcAddr) {
771 SyncResponsePacket pkt;
772 pkt.initHeader(mTimelineID, mSyncGroupID);
773
774 if ((mState == ICommonClock::STATE_MASTER) &&
775 (mTimelineID == request->timelineID)) {
776 int64_t rxLocalTime = mLastPacketRxLocalTime;
777 int64_t rxCommonTime;
778
779 // If we are master on an actual network and have actual clients, then
780 // we are no longer low priority.
781 setForceLowPriority(false);
782
783 if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
784 return false;
785 }
786
787 int64_t txLocalTime = mLocalClock.getLocalTime();;
788 int64_t txCommonTime;
789 if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
790 return false;
791 }
792
793 pkt.nak = 0;
794 pkt.clientTxLocalTime = request->clientTxLocalTime;
795 pkt.masterRxCommonTime = rxCommonTime;
796 pkt.masterTxCommonTime = txCommonTime;
797 } else {
798 pkt.nak = 1;
799 pkt.clientTxLocalTime = 0;
800 pkt.masterRxCommonTime = 0;
801 pkt.masterTxCommonTime = 0;
802 }
803
804 uint8_t buf[256];
805 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
806 if (bufSz < 0)
807 return false;
808
809 ssize_t sendBytes = sendto(
810 mSocket, &buf, bufSz, 0,
811 reinterpret_cast<const sockaddr *>(&srcAddr),
812 sizeof(srcAddr));
813 if (sendBytes == -1) {
814 ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
815 return false;
816 }
817
818 return true;
819}
820
821bool CommonTimeServer::handleSyncResponse(
822 const SyncResponsePacket* response,
823 const sockaddr_storage& srcAddr) {
824 if (mState != ICommonClock::STATE_CLIENT)
825 return true;
826
827 assert(mMasterEPValid);
828 if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
829 char srcEP[64], expectedEP[64];
830 sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
831 sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
832 ALOGI("Dropping sync response from unexpected address."
833 " Expected %s Got %s", expectedEP, srcEP);
834 return true;
835 }
836
837 if (response->nak) {
838 // if our master is no longer accepting requests, then we need to find
839 // a new master
840 return becomeRonin("master NAK'ed");
841 }
842
843 mClient_SyncRequestPending = 0;
844 mClient_SyncRequestTimeouts = 0;
845 mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
846 mLastPacketRxLocalTime);
847
848 bool result;
849 if (!(mClient_SyncRespsRXedFromCurMaster++)) {
850 // the first request/response exchange between a client and a master
851 // may take unusually long due to ARP, so discard it.
852 result = true;
853 } else {
854 int64_t clientTxLocalTime = response->clientTxLocalTime;
855 int64_t clientRxLocalTime = mLastPacketRxLocalTime;
856 int64_t masterTxCommonTime = response->masterTxCommonTime;
857 int64_t masterRxCommonTime = response->masterRxCommonTime;
858
859 int64_t rtt = (clientRxLocalTime - clientTxLocalTime);
860 int64_t avgLocal = (clientTxLocalTime + clientRxLocalTime) >> 1;
861 int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;
862
863 // if the RTT of the packet is significantly larger than the panic
864 // threshold, we should simply discard it. Its better to do nothing
865 // than to take cues from a packet like that.
866 int rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
867 if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) *
868 kRTTDiscardPanicThreshMultiplier)) {
869 ALOGV("Dropping sync response with RTT of %lld uSec", rttCommon);
870 mClient_ExpiredSyncRespsRXedFromCurMaster++;
871 if (shouldPanicNotGettingGoodData())
872 return becomeInitial("RX panic, no good data");
873 } else {
874 result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rtt);
875 mClient_LastGoodSyncRX = clientRxLocalTime;
876
877 if (result) {
878 // indicate to listeners that we've synced to the common timeline
879 notifyClockSync();
880 } else {
881 ALOGE("Panic! Observed clock sync error is too high to tolerate,"
882 " resetting state machine and starting over.");
883 notifyClockSyncLoss();
884 return becomeInitial("panic");
885 }
886 }
887 }
888
889 mCurTimeout.setTimeout(mSyncRequestIntervalMs);
890 return result;
891}
892
893bool CommonTimeServer::handleMasterAnnouncement(
894 const MasterAnnouncementPacket* packet,
895 const sockaddr_storage& srcAddr) {
896 uint64_t newDeviceID = packet->deviceID;
897 uint8_t newDevicePrio = packet->devicePriority;
898 uint64_t newTimelineID = packet->timelineID;
899
900 if (mState == ICommonClock::STATE_INITIAL ||
901 mState == ICommonClock::STATE_RONIN ||
902 mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
903 // if we aren't currently following a master, then start following
904 // this new master
905 return becomeClient(srcAddr,
906 newDeviceID,
907 newDevicePrio,
908 newTimelineID,
909 "heard master announcement");
910 } else if (mState == ICommonClock::STATE_CLIENT) {
911 // if the new master wins arbitration against our current master,
912 // then become a client of the new master
913 if (arbitrateMaster(newDeviceID,
914 newDevicePrio,
915 mClient_MasterDeviceID,
916 mClient_MasterDevicePriority))
917 return becomeClient(srcAddr,
918 newDeviceID,
919 newDevicePrio,
920 newTimelineID,
921 "heard master announcement");
922 } else if (mState == ICommonClock::STATE_MASTER) {
923 // two masters are competing - if the new one wins arbitration, then
924 // cease acting as master
925 if (arbitrateMaster(newDeviceID, newDevicePrio,
926 mDeviceID, effectivePriority()))
927 return becomeClient(srcAddr, newDeviceID,
928 newDevicePrio, newTimelineID,
929 "heard master announcement");
930 }
931
932 return true;
933}
934
935bool CommonTimeServer::sendWhoIsMasterRequest() {
936 assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
937
938 // If we have no socket, then we must be in the unconfigured initial state.
939 // Don't report any errors, just don't try to send the initial who-is-master
940 // query. Eventually, our network will either become configured, or we will
941 // be forced into network-less master mode by higher level code.
942 if (mSocket < 0) {
943 assert(mState == ICommonClock::STATE_INITIAL);
944 return true;
945 }
946
947 bool ret = false;
948 WhoIsMasterRequestPacket pkt;
949 pkt.initHeader(mSyncGroupID);
950 pkt.senderDeviceID = mDeviceID;
951 pkt.senderDevicePriority = effectivePriority();
952
953 uint8_t buf[256];
954 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
955 if (bufSz >= 0) {
956 ssize_t sendBytes = sendto(
957 mSocket, buf, bufSz, 0,
958 reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
959 sizeof(mMasterElectionEP));
960 if (sendBytes < 0)
961 ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
962 ret = true;
963 }
964
965 if (mState == ICommonClock::STATE_INITIAL) {
966 mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
967 } else {
968 mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
969 }
970
971 return ret;
972}
973
974bool CommonTimeServer::sendSyncRequest() {
975 // If we are sending sync requests, then we must be in the client state and
976 // we must have a socket (when we have no network, we are only supposed to
977 // be in INITIAL or MASTER)
978 assert(mState == ICommonClock::STATE_CLIENT);
979 assert(mSocket >= 0);
980
981 bool ret = false;
982 SyncRequestPacket pkt;
983 pkt.initHeader(mTimelineID, mSyncGroupID);
984 pkt.clientTxLocalTime = mLocalClock.getLocalTime();
985
986 if (!mClient_FirstSyncTX)
987 mClient_FirstSyncTX = pkt.clientTxLocalTime;
988
989 mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
990
991 uint8_t buf[256];
992 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
993 if (bufSz >= 0) {
994 ssize_t sendBytes = sendto(
995 mSocket, buf, bufSz, 0,
996 reinterpret_cast<const sockaddr *>(&mMasterEP),
997 sizeof(mMasterEP));
998 if (sendBytes < 0)
999 ALOGE("SyncRequest sendto failed (errno %d)", errno);
1000 ret = true;
1001 }
1002
1003 mClient_SyncsSentToCurMaster++;
1004 mCurTimeout.setTimeout(mSyncRequestIntervalMs);
1005 mClient_SyncRequestPending = true;
1006
1007 return ret;
1008}
1009
1010bool CommonTimeServer::sendMasterAnnouncement() {
1011 bool ret = false;
1012 assert(mState == ICommonClock::STATE_MASTER);
1013
1014 // If we are being asked to send a master announcement, but we have no
1015 // socket, we must be in network-less master mode. Don't bother to send the
1016 // announcement, and don't bother to schedule a timeout. When the network
1017 // comes up, the work thread will get poked and start the process of
1018 // figuring out who the current master should be.
1019 if (mSocket < 0) {
1020 mCurTimeout.setTimeout(kInfiniteTimeout);
1021 return true;
1022 }
1023
1024 MasterAnnouncementPacket pkt;
1025 pkt.initHeader(mTimelineID, mSyncGroupID);
1026 pkt.deviceID = mDeviceID;
1027 pkt.devicePriority = effectivePriority();
1028
1029 uint8_t buf[256];
1030 ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
1031 if (bufSz >= 0) {
1032 ssize_t sendBytes = sendto(
1033 mSocket, buf, bufSz, 0,
1034 reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
1035 sizeof(mMasterElectionEP));
1036 if (sendBytes < 0)
1037 ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
1038 ret = true;
1039 }
1040
1041 mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
1042 return ret;
1043}
1044
1045bool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
1046 uint64_t masterDeviceID,
1047 uint8_t masterDevicePriority,
1048 uint64_t timelineID,
1049 const char* cause) {
1050 char newEPStr[64], oldEPStr[64];
1051 sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
1052 sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
1053
1054 ALOGI("%s --> CLIENT (%s) :%s"
1055 " OldMaster: %02x-%014llx::%016llx::%s"
1056 " NewMaster: %02x-%014llx::%016llx::%s",
1057 stateToString(mState), cause,
1058 (mTimelineID != timelineID) ? " (new timeline)" : "",
1059 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1060 mTimelineID, oldEPStr,
1061 masterDevicePriority, masterDeviceID,
1062 timelineID, newEPStr);
1063
1064 if (mTimelineID != timelineID) {
1065 // start following a new timeline
1066 mTimelineID = timelineID;
1067 mClockRecovery.reset(true, true);
1068 notifyClockSyncLoss();
1069 } else {
1070 // start following a new master on the existing timeline
1071 mClockRecovery.reset(false, true);
1072 }
1073
1074 mMasterEP = masterEP;
1075 mMasterEPValid = true;
1076 setForceLowPriority(false);
1077
1078 mClient_MasterDeviceID = masterDeviceID;
1079 mClient_MasterDevicePriority = masterDevicePriority;
1080 resetSyncStats();
1081
1082 setState(ICommonClock::STATE_CLIENT);
1083
1084 // add some jitter to when the various clients send their requests
1085 // in order to reduce the likelihood that a group of clients overload
1086 // the master after receiving a master announcement
1087 usleep((lrand48() % 100) * 1000);
1088
1089 return sendSyncRequest();
1090}
1091
1092bool CommonTimeServer::becomeMaster(const char* cause) {
1093 uint64_t oldTimelineID = mTimelineID;
1094 if (mTimelineID == ICommonClock::kInvalidTimelineID) {
1095 // this device has not been following any existing timeline,
1096 // so it will create a new timeline and declare itself master
1097 assert(!mCommonClock.isValid());
1098
1099 // set the common time basis
1100 mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
1101
1102 // assign an arbitrary timeline iD
1103 assignTimelineID();
1104
1105 // notify listeners that we've created a common timeline
1106 notifyClockSync();
1107 }
1108
1109 ALOGI("%s --> MASTER (%s) : %s timeline %016llx",
1110 stateToString(mState), cause,
1111 (oldTimelineID == mTimelineID) ? "taking ownership of"
1112 : "creating new",
1113 mTimelineID);
1114
1115 memset(&mMasterEP, 0, sizeof(mMasterEP));
1116 mMasterEPValid = false;
1117 setForceLowPriority(false);
1118 mClient_MasterDevicePriority = effectivePriority();
1119 mClient_MasterDeviceID = mDeviceID;
1120 mClockRecovery.reset(false, true);
1121 resetSyncStats();
1122
1123 setState(ICommonClock::STATE_MASTER);
1124 return sendMasterAnnouncement();
1125}
1126
1127bool CommonTimeServer::becomeRonin(const char* cause) {
1128 // If we were the client of a given timeline, but had never received even a
1129 // single time sync packet, then we transition back to Initial instead of
1130 // Ronin. If we transition to Ronin and end up becoming the new Master, we
1131 // will be unable to service requests for other clients because we never
1132 // actually knew what time it was. By going to initial, we ensure that
1133 // other clients who know what time it is, but would lose master arbitration
1134 // in the Ronin case, will step up and become the proper new master of the
1135 // old timeline.
1136
1137 char oldEPStr[64];
1138 sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
1139 memset(&mMasterEP, 0, sizeof(mMasterEP));
1140 mMasterEPValid = false;
1141
1142 if (mCommonClock.isValid()) {
1143 ALOGI("%s --> RONIN (%s) : lost track of previously valid timeline "
1144 "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
1145 stateToString(mState), cause,
1146 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1147 mTimelineID, oldEPStr,
1148 mClient_SyncsSentToCurMaster,
1149 mClient_SyncRespsRXedFromCurMaster,
1150 mClient_ExpiredSyncRespsRXedFromCurMaster);
1151
1152 mRonin_WhoIsMasterRequestTimeouts = 0;
1153 setState(ICommonClock::STATE_RONIN);
1154 return sendWhoIsMasterRequest();
1155 } else {
1156 ALOGI("%s --> INITIAL (%s) : never synced timeline "
1157 "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
1158 stateToString(mState), cause,
1159 mClient_MasterDevicePriority, mClient_MasterDeviceID,
1160 mTimelineID, oldEPStr,
1161 mClient_SyncsSentToCurMaster,
1162 mClient_SyncRespsRXedFromCurMaster,
1163 mClient_ExpiredSyncRespsRXedFromCurMaster);
1164
1165 return becomeInitial("ronin, no timeline");
1166 }
1167}
1168
1169bool CommonTimeServer::becomeWaitForElection(const char* cause) {
1170 ALOGI("%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
1171 " waiting %d mSec for completion.",
1172 stateToString(mState), cause, kWaitForElection_TimeoutMs);
1173
1174 setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
1175 mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
1176 return true;
1177}
1178
1179bool CommonTimeServer::becomeInitial(const char* cause) {
1180 ALOGI("Entering INITIAL (%s), total reset.", cause);
1181
1182 setState(ICommonClock::STATE_INITIAL);
1183
1184 // reset clock recovery
1185 mClockRecovery.reset(true, true);
1186
1187 // reset internal state bookkeeping.
1188 mCurTimeout.setTimeout(kInfiniteTimeout);
1189 memset(&mMasterEP, 0, sizeof(mMasterEP));
1190 mMasterEPValid = false;
1191 mLastPacketRxLocalTime = 0;
1192 mTimelineID = ICommonClock::kInvalidTimelineID;
1193 mClockSynced = false;
1194 mInitial_WhoIsMasterRequestTimeouts = 0;
1195 mClient_MasterDeviceID = 0;
1196 mClient_MasterDevicePriority = 0;
1197 mRonin_WhoIsMasterRequestTimeouts = 0;
1198 resetSyncStats();
1199
1200 // send the first request to discover the master
1201 return sendWhoIsMasterRequest();
1202}
1203
1204void CommonTimeServer::notifyClockSync() {
1205 if (!mClockSynced) {
1206 mClockSynced = true;
1207 mICommonClock->notifyOnTimelineChanged(mTimelineID);
1208 }
1209}
1210
1211void CommonTimeServer::notifyClockSyncLoss() {
1212 if (mClockSynced) {
1213 mClockSynced = false;
1214 mICommonClock->notifyOnTimelineChanged(
1215 ICommonClock::kInvalidTimelineID);
1216 }
1217}
1218
1219void CommonTimeServer::setState(ICommonClock::State s) {
1220 mState = s;
1221}
1222
1223const char* CommonTimeServer::stateToString(ICommonClock::State s) {
1224 switch(s) {
1225 case ICommonClock::STATE_INITIAL:
1226 return "INITIAL";
1227 case ICommonClock::STATE_CLIENT:
1228 return "CLIENT";
1229 case ICommonClock::STATE_MASTER:
1230 return "MASTER";
1231 case ICommonClock::STATE_RONIN:
1232 return "RONIN";
1233 case ICommonClock::STATE_WAIT_FOR_ELECTION:
1234 return "WAIT_FOR_ELECTION";
1235 default:
1236 return "unknown";
1237 }
1238}
1239
1240void CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
1241 bool addrValid,
1242 char* buf, size_t bufLen) {
1243 if (!bufLen || !buf)
1244 return;
1245
1246 if (addrValid) {
1247 switch (addr.ss_family) {
1248 case AF_INET: {
1249 const struct sockaddr_in* sa =
1250 reinterpret_cast<const struct sockaddr_in*>(&addr);
1251 unsigned long a = ntohl(sa->sin_addr.s_addr);
1252 uint16_t p = ntohs(sa->sin_port);
1253 snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
1254 ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
1255 ((a >> 8) & 0xFF), (a & 0xFF), p);
1256 } break;
1257
1258 case AF_INET6: {
1259 const struct sockaddr_in6* sa =
1260 reinterpret_cast<const struct sockaddr_in6*>(&addr);
1261 const uint8_t* a = sa->sin6_addr.s6_addr;
1262 uint16_t p = ntohs(sa->sin6_port);
1263 snprintf(buf, bufLen,
1264 "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
1265 "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
1266 a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
1267 a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
1268 p);
1269 } break;
1270
1271 default:
1272 snprintf(buf, bufLen,
1273 "<unknown sockaddr family %d>", addr.ss_family);
1274 break;
1275 }
1276 } else {
1277 snprintf(buf, bufLen, "<none>");
1278 }
1279
1280 buf[bufLen - 1] = 0;
1281}
1282
1283bool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
1284 const sockaddr_storage& a2,
1285 bool matchAddressOnly) {
1286 if (a1.ss_family != a2.ss_family)
1287 return false;
1288
1289 switch (a1.ss_family) {
1290 case AF_INET: {
1291 const struct sockaddr_in* sa1 =
1292 reinterpret_cast<const struct sockaddr_in*>(&a1);
1293 const struct sockaddr_in* sa2 =
1294 reinterpret_cast<const struct sockaddr_in*>(&a2);
1295
1296 if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
1297 return false;
1298
1299 return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
1300 } break;
1301
1302 case AF_INET6: {
1303 const struct sockaddr_in6* sa1 =
1304 reinterpret_cast<const struct sockaddr_in6*>(&a1);
1305 const struct sockaddr_in6* sa2 =
1306 reinterpret_cast<const struct sockaddr_in6*>(&a2);
1307
1308 if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
1309 return false;
1310
1311 return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
1312 } break;
1313
1314 // Huh? We don't deal in non-IPv[46] addresses. Not sure how we got
1315 // here, but we don't know how to comapre these addresses and simply
1316 // default to a no-match decision.
1317 default: return false;
1318 }
1319}
1320
1321void CommonTimeServer::TimeoutHelper::setTimeout(int msec) {
1322 mTimeoutValid = (msec >= 0);
1323 if (mTimeoutValid)
1324 mEndTime = systemTime() +
1325 (static_cast<nsecs_t>(msec) * 1000000);
1326}
1327
1328int CommonTimeServer::TimeoutHelper::msecTillTimeout() {
1329 if (!mTimeoutValid)
1330 return kInfiniteTimeout;
1331
1332 nsecs_t now = systemTime();
1333 if (now >= mEndTime)
1334 return 0;
1335
1336 uint64_t deltaMsec = (((mEndTime - now) + 999999) / 1000000);
1337
1338 if (deltaMsec > static_cast<uint64_t>(std::numeric_limits<int>::max()))
1339 return std::numeric_limits<int>::max();
1340
1341 return static_cast<int>(deltaMsec);
1342}
1343
1344bool CommonTimeServer::shouldPanicNotGettingGoodData() {
1345 if (mClient_FirstSyncTX) {
1346 int64_t now = mLocalClock.getLocalTime();
1347 int64_t delta = now - (mClient_LastGoodSyncRX
1348 ? mClient_LastGoodSyncRX
1349 : mClient_FirstSyncTX);
1350 int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
1351
1352 if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
1353 return true;
1354 }
1355
1356 return false;
1357}
1358
1359void CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
1360 txTimes[wrPtr] = txTime;
1361 rxTimes[wrPtr] = 0;
1362 wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
1363 if (!wrPtr)
1364 logFull = true;
1365}
1366
1367void CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
1368 if (!logFull && !wrPtr)
1369 return;
1370
1371 uint32_t i = logFull ? wrPtr : 0;
1372 do {
1373 if (txTimes[i] == txTime) {
1374 rxTimes[i] = rxTime;
1375 break;
1376 }
1377 i = (i + 1) % RTT_LOG_SIZE;
1378 } while (i != wrPtr);
1379}
1380
1381} // namespace android