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