diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-11-24 07:07:42 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-11-24 07:07:42 +0100 |
commit | ca6c7e42f93eb2b0ce246eafd8b0e4ac27414f6b (patch) | |
tree | 05b52babec2451c1e7ef62e02a59ea30317eeaf8 /networking/ntpd.c | |
parent | 887d96303725d784e245c6562cf9fd5583b37224 (diff) | |
download | busybox-w32-ca6c7e42f93eb2b0ce246eafd8b0e4ac27414f6b.tar.gz busybox-w32-ca6c7e42f93eb2b0ce246eafd8b0e4ac27414f6b.tar.bz2 busybox-w32-ca6c7e42f93eb2b0ce246eafd8b0e4ac27414f6b.zip |
ntp: simplifications; libbb: simpler resolution of numeric hostnames
function old new delta
str2sockaddr 405 567 +162
ntp_init 310 317 +7
scale_interval 58 59 +1
error_interval 22 23 +1
ntpd_main 3257 3214 -43
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 171/-43) Total: 128 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/ntpd.c')
-rw-r--r-- | networking/ntpd.c | 208 |
1 files changed, 108 insertions, 100 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c index 8ee42e627..4e661ce98 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * | 5 | * |
6 | * Licensed under GPLv2, see file LICENSE in this tarball for details. | 6 | * Licensed under GPLv2, see file LICENSE in this tarball for details. |
7 | */ | 7 | */ |
8 | |||
9 | #include "libbb.h" | 8 | #include "libbb.h" |
10 | #include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */ | 9 | #include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */ |
11 | 10 | ||
@@ -59,30 +58,32 @@ typedef struct { | |||
59 | uint16_t fractions; | 58 | uint16_t fractions; |
60 | } s_fixedpt_t; | 59 | } s_fixedpt_t; |
61 | 60 | ||
62 | #define NTP_DIGESTSIZE 16 | 61 | enum { |
63 | #define NTP_MSGSIZE_NOAUTH 48 | 62 | NTP_DIGESTSIZE = 16, |
64 | #define NTP_MSGSIZE (NTP_MSGSIZE_NOAUTH + 4 + NTP_DIGESTSIZE) | 63 | NTP_MSGSIZE_NOAUTH = 48, |
64 | NTP_MSGSIZE = (NTP_MSGSIZE_NOAUTH + 4 + NTP_DIGESTSIZE), | ||
65 | }; | ||
65 | 66 | ||
66 | typedef struct { | 67 | typedef struct { |
67 | uint8_t status; /* status of local clock and leap info */ | 68 | uint8_t status; /* status of local clock and leap info */ |
68 | uint8_t stratum; /* Stratum level */ | 69 | uint8_t stratum; /* stratum level */ |
69 | uint8_t ppoll; /* poll value */ | 70 | uint8_t ppoll; /* poll value */ |
70 | int8_t precision; | 71 | int8_t precision; |
71 | s_fixedpt_t rootdelay; | 72 | s_fixedpt_t rootdelay; |
72 | s_fixedpt_t dispersion; | 73 | s_fixedpt_t dispersion; |
73 | uint32_t refid; | 74 | uint32_t refid; |
74 | l_fixedpt_t reftime; | 75 | l_fixedpt_t reftime; |
75 | l_fixedpt_t orgtime; | 76 | l_fixedpt_t orgtime; |
76 | l_fixedpt_t rectime; | 77 | l_fixedpt_t rectime; |
77 | l_fixedpt_t xmttime; | 78 | l_fixedpt_t xmttime; |
78 | uint32_t keyid; | 79 | uint32_t keyid; |
79 | uint8_t digest[NTP_DIGESTSIZE]; | 80 | uint8_t digest[NTP_DIGESTSIZE]; |
80 | } ntp_msg_t; | 81 | } ntp_msg_t; |
81 | 82 | ||
82 | typedef struct { | 83 | typedef struct { |
83 | int fd; | 84 | int fd; |
84 | ntp_msg_t msg; | 85 | ntp_msg_t msg; |
85 | double xmttime; | 86 | double xmttime; |
86 | } ntp_query_t; | 87 | } ntp_query_t; |
87 | 88 | ||
88 | enum { | 89 | enum { |
@@ -97,6 +98,7 @@ enum { | |||
97 | /* Status Masks */ | 98 | /* Status Masks */ |
98 | MODE_MASK = (7 << 0), | 99 | MODE_MASK = (7 << 0), |
99 | VERSION_MASK = (7 << 3), | 100 | VERSION_MASK = (7 << 3), |
101 | VERSION_SHIFT = 3, | ||
100 | LI_MASK = (3 << 6), | 102 | LI_MASK = (3 << 6), |
101 | 103 | ||
102 | /* Mode values */ | 104 | /* Mode values */ |
@@ -107,7 +109,7 @@ enum { | |||
107 | MODE_SERVER = 4, /* server */ | 109 | MODE_SERVER = 4, /* server */ |
108 | MODE_BROADCAST = 5, /* broadcast */ | 110 | MODE_BROADCAST = 5, /* broadcast */ |
109 | MODE_RES1 = 6, /* reserved for NTP control message */ | 111 | MODE_RES1 = 6, /* reserved for NTP control message */ |
110 | MODE_RES2 = 7 /* reserved for private use */ | 112 | MODE_RES2 = 7, /* reserved for private use */ |
111 | }; | 113 | }; |
112 | 114 | ||
113 | #define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ | 115 | #define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ |
@@ -115,7 +117,7 @@ enum { | |||
115 | enum client_state { | 117 | enum client_state { |
116 | STATE_NONE, | 118 | STATE_NONE, |
117 | STATE_QUERY_SENT, | 119 | STATE_QUERY_SENT, |
118 | STATE_REPLY_RECEIVED | 120 | STATE_REPLY_RECEIVED, |
119 | }; | 121 | }; |
120 | 122 | ||
121 | typedef struct { | 123 | typedef struct { |
@@ -132,24 +134,27 @@ typedef struct { | |||
132 | } ntp_status_t; | 134 | } ntp_status_t; |
133 | 135 | ||
134 | typedef struct { | 136 | typedef struct { |
135 | ntp_status_t status; | 137 | ntp_status_t status; |
136 | double offset; | 138 | double offset; |
137 | double delay; | 139 | double delay; |
138 | double error; | 140 | double error; |
139 | time_t rcvd; | 141 | time_t rcvd; |
140 | uint8_t good; | 142 | uint8_t good; |
141 | } ntp_offset_t; | 143 | } ntp_offset_t; |
142 | 144 | ||
143 | typedef struct { | 145 | typedef struct { |
146 | //TODO: | ||
147 | // (1) store dotted addr str, to avoid constant translations | ||
148 | // (2) periodically re-resolve DNS names | ||
144 | len_and_sockaddr *lsa; | 149 | len_and_sockaddr *lsa; |
145 | ntp_query_t query; | 150 | ntp_query_t query; |
146 | ntp_offset_t reply[OFFSET_ARRAY_SIZE]; | 151 | ntp_offset_t reply[OFFSET_ARRAY_SIZE]; |
147 | ntp_offset_t update; | 152 | ntp_offset_t update; |
148 | enum client_state state; | 153 | enum client_state state; |
149 | time_t next; | 154 | time_t next; |
150 | time_t deadline; | 155 | time_t deadline; |
151 | uint8_t shift; | 156 | uint8_t shift; |
152 | uint8_t trustlevel; | 157 | uint8_t trustlevel; |
153 | } ntp_peer_t; | 158 | } ntp_peer_t; |
154 | 159 | ||
155 | enum { | 160 | enum { |
@@ -211,8 +216,7 @@ add_peers(const char *s) | |||
211 | static double | 216 | static double |
212 | gettime(void) | 217 | gettime(void) |
213 | { | 218 | { |
214 | struct timeval tv; | 219 | struct timeval tv; |
215 | |||
216 | gettimeofday(&tv, NULL); /* never fails */ | 220 | gettimeofday(&tv, NULL); /* never fails */ |
217 | return (tv.tv_sec + JAN_1970 + 1.0e-6 * tv.tv_usec); | 221 | return (tv.tv_sec + JAN_1970 + 1.0e-6 * tv.tv_usec); |
218 | } | 222 | } |
@@ -228,45 +232,43 @@ d_to_tv(double d, struct timeval *tv) | |||
228 | static double | 232 | static double |
229 | lfp_to_d(l_fixedpt_t lfp) | 233 | lfp_to_d(l_fixedpt_t lfp) |
230 | { | 234 | { |
231 | double ret; | 235 | double ret; |
232 | |||
233 | lfp.int_partl = ntohl(lfp.int_partl); | 236 | lfp.int_partl = ntohl(lfp.int_partl); |
234 | lfp.fractionl = ntohl(lfp.fractionl); | 237 | lfp.fractionl = ntohl(lfp.fractionl); |
235 | ret = (double)(lfp.int_partl) + ((double)lfp.fractionl / UINT_MAX); | 238 | ret = (double)lfp.int_partl + ((double)lfp.fractionl / UINT_MAX); |
236 | return ret; | 239 | return ret; |
237 | } | 240 | } |
238 | 241 | ||
239 | #if ENABLE_FEATURE_NTPD_SERVER | ||
240 | static l_fixedpt_t | ||
241 | d_to_lfp(double d) | ||
242 | { | ||
243 | l_fixedpt_t lfp; | ||
244 | |||
245 | lfp.int_partl = htonl((uint32_t)d); | ||
246 | lfp.fractionl = htonl((uint32_t)((d - (u_int32_t)d) * UINT_MAX)); | ||
247 | return lfp; | ||
248 | } | ||
249 | #endif | ||
250 | |||
251 | static double | 242 | static double |
252 | sfp_to_d(s_fixedpt_t sfp) | 243 | sfp_to_d(s_fixedpt_t sfp) |
253 | { | 244 | { |
254 | double ret; | 245 | double ret; |
255 | |||
256 | sfp.int_parts = ntohs(sfp.int_parts); | 246 | sfp.int_parts = ntohs(sfp.int_parts); |
257 | sfp.fractions = ntohs(sfp.fractions); | 247 | sfp.fractions = ntohs(sfp.fractions); |
258 | ret = (double)(sfp.int_parts) + ((double)sfp.fractions / USHRT_MAX); | 248 | ret = (double)sfp.int_parts + ((double)sfp.fractions / USHRT_MAX); |
259 | return ret; | 249 | return ret; |
260 | } | 250 | } |
261 | 251 | ||
262 | #if ENABLE_FEATURE_NTPD_SERVER | 252 | #if ENABLE_FEATURE_NTPD_SERVER |
253 | static l_fixedpt_t | ||
254 | d_to_lfp(double d) | ||
255 | { | ||
256 | l_fixedpt_t lfp; | ||
257 | lfp.int_partl = (uint32_t)d; | ||
258 | lfp.fractionl = (uint32_t)((d - lfp.int_partl) * UINT_MAX); | ||
259 | lfp.int_partl = htonl(lfp.int_partl); | ||
260 | lfp.fractionl = htonl(lfp.fractionl); | ||
261 | return lfp; | ||
262 | } | ||
263 | |||
263 | static s_fixedpt_t | 264 | static s_fixedpt_t |
264 | d_to_sfp(double d) | 265 | d_to_sfp(double d) |
265 | { | 266 | { |
266 | s_fixedpt_t sfp; | 267 | s_fixedpt_t sfp; |
267 | 268 | sfp.int_parts = (uint16_t)d; | |
268 | sfp.int_parts = htons((uint16_t)d); | 269 | sfp.fractions = (uint16_t)((d - sfp.int_parts) * USHRT_MAX); |
269 | sfp.fractions = htons((uint16_t)((d - (u_int16_t)d) * USHRT_MAX)); | 270 | sfp.int_parts = htons(sfp.int_parts); |
271 | sfp.fractions = htons(sfp.fractions); | ||
270 | return sfp; | 272 | return sfp; |
271 | } | 273 | } |
272 | #endif | 274 | #endif |
@@ -282,9 +284,8 @@ static time_t | |||
282 | error_interval(void) | 284 | error_interval(void) |
283 | { | 285 | { |
284 | time_t interval, r; | 286 | time_t interval, r; |
285 | |||
286 | interval = INTERVAL_QUERY_PATHETIC * QSCALE_OFF_MAX / QSCALE_OFF_MIN; | 287 | interval = INTERVAL_QUERY_PATHETIC * QSCALE_OFF_MAX / QSCALE_OFF_MIN; |
287 | r = random() % (interval / 10); | 288 | r = (unsigned)random() % (unsigned long)(interval / 10); |
288 | return (interval + r); | 289 | return (interval + r); |
289 | } | 290 | } |
290 | 291 | ||
@@ -352,12 +353,8 @@ client_query(ntp_peer_t *p) | |||
352 | static int | 353 | static int |
353 | offset_compare(const void *aa, const void *bb) | 354 | offset_compare(const void *aa, const void *bb) |
354 | { | 355 | { |
355 | const ntp_peer_t * const *a; | 356 | const ntp_peer_t *const *a = aa; |
356 | const ntp_peer_t * const *b; | 357 | const ntp_peer_t *const *b = bb; |
357 | |||
358 | a = aa; | ||
359 | b = bb; | ||
360 | |||
361 | if ((*a)->update.offset < (*b)->update.offset) | 358 | if ((*a)->update.offset < (*b)->update.offset) |
362 | return -1; | 359 | return -1; |
363 | return ((*a)->update.offset > (*b)->update.offset); | 360 | return ((*a)->update.offset > (*b)->update.offset); |
@@ -368,7 +365,6 @@ updated_scale(double offset) | |||
368 | { | 365 | { |
369 | if (offset < 0) | 366 | if (offset < 0) |
370 | offset = -offset; | 367 | offset = -offset; |
371 | |||
372 | if (offset > QSCALE_OFF_MAX) | 368 | if (offset > QSCALE_OFF_MAX) |
373 | return 1; | 369 | return 1; |
374 | if (offset < QSCALE_OFF_MIN) | 370 | if (offset < QSCALE_OFF_MIN) |
@@ -559,9 +555,8 @@ static time_t | |||
559 | scale_interval(time_t requested) | 555 | scale_interval(time_t requested) |
560 | { | 556 | { |
561 | time_t interval, r; | 557 | time_t interval, r; |
562 | |||
563 | interval = requested * G.scale; | 558 | interval = requested * G.scale; |
564 | r = random() % MAX(5, interval / 10); | 559 | r = (unsigned)random() % (unsigned long)(MAX(5, interval / 10)); |
565 | return (interval + r); | 560 | return (interval + r); |
566 | } | 561 | } |
567 | 562 | ||
@@ -577,9 +572,10 @@ client_dispatch(ntp_peer_t *p) | |||
577 | 572 | ||
578 | addr = xmalloc_sockaddr2dotted_noport(&p->lsa->u.sa); | 573 | addr = xmalloc_sockaddr2dotted_noport(&p->lsa->u.sa); |
579 | 574 | ||
580 | size = recvfrom(p->query.fd, &msg, sizeof(msg), 0, NULL, NULL); | 575 | //TODO: use MSG_DONTWAIT flag? |
576 | size = recv(p->query.fd, &msg, sizeof(msg), 0); | ||
581 | if (size == -1) { | 577 | if (size == -1) { |
582 | bb_perror_msg("recvfrom(%s) error", addr); | 578 | bb_perror_msg("recv(%s) error", addr); |
583 | if (errno == EHOSTUNREACH || errno == EHOSTDOWN | 579 | if (errno == EHOSTUNREACH || errno == EHOSTDOWN |
584 | || errno == ENETUNREACH || errno == ENETDOWN | 580 | || errno == ENETUNREACH || errno == ENETDOWN |
585 | || errno == ECONNREFUSED || errno == EADDRNOTAVAIL | 581 | || errno == ECONNREFUSED || errno == EADDRNOTAVAIL |
@@ -693,48 +689,58 @@ client_dispatch(ntp_peer_t *p) | |||
693 | static void | 689 | static void |
694 | server_dispatch(int fd) | 690 | server_dispatch(int fd) |
695 | { | 691 | { |
696 | ssize_t size; | 692 | ssize_t size; |
697 | uint8_t version; | 693 | uint8_t version; |
698 | double rectime; | 694 | double rectime; |
699 | len_and_sockaddr *to; | 695 | len_and_sockaddr *to; |
700 | struct sockaddr *from; | 696 | struct sockaddr *from; |
701 | ntp_msg_t query, reply; | 697 | ntp_msg_t msg; |
698 | uint8_t query_status; | ||
699 | uint8_t query_ppoll; | ||
700 | l_fixedpt_t query_xmttime; | ||
702 | 701 | ||
703 | to = get_sock_lsa(G.listen_fd); | 702 | to = get_sock_lsa(G.listen_fd); |
704 | from = xzalloc(to->len); | 703 | from = xzalloc(to->len); |
705 | 704 | ||
706 | size = recv_from_to(fd, &query, sizeof(query), 0, from, &to->u.sa, to->len); | 705 | //TODO: use MGS_DONTWAIT flag? |
707 | if (size == -1) | 706 | size = recv_from_to(fd, &msg, sizeof(msg), 0, from, &to->u.sa, to->len); |
708 | bb_error_msg_and_die("recv_from_to"); | ||
709 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { | 707 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { |
710 | char *addr = xmalloc_sockaddr2dotted_noport(from); | 708 | char *addr; |
709 | if (size < 0) | ||
710 | bb_error_msg_and_die("recv_from_to"); | ||
711 | addr = xmalloc_sockaddr2dotted_noport(from); | ||
711 | bb_error_msg("malformed packet received from %s", addr); | 712 | bb_error_msg("malformed packet received from %s", addr); |
712 | free(addr); | 713 | free(addr); |
713 | goto bail; | 714 | goto bail; |
714 | } | 715 | } |
715 | 716 | ||
716 | rectime = gettime(); | 717 | query_status = msg.status; |
717 | version = (query.status & VERSION_MASK) >> 3; | 718 | query_ppoll = msg.ppoll; |
719 | query_xmttime = msg.xmttime; | ||
718 | 720 | ||
719 | memset(&reply, 0, sizeof(reply)); | 721 | /* Build a reply packet */ |
720 | reply.status = G.status.synced ? G.status.leap : LI_ALARM; | 722 | memset(&msg, 0, sizeof(msg)); |
721 | reply.status |= (query.status & VERSION_MASK); | 723 | msg.status = G.status.synced ? G.status.leap : LI_ALARM; |
722 | reply.status |= ((query.status & MODE_MASK) == MODE_CLIENT) ? | 724 | msg.status |= (query_status & VERSION_MASK); |
725 | msg.status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? | ||
723 | MODE_SERVER : MODE_SYM_PAS; | 726 | MODE_SERVER : MODE_SYM_PAS; |
724 | reply.stratum = G.status.stratum; | 727 | msg.stratum = G.status.stratum; |
725 | reply.ppoll = query.ppoll; | 728 | msg.ppoll = query_ppoll; |
726 | reply.precision = G.status.precision; | 729 | msg.precision = G.status.precision; |
727 | reply.rectime = d_to_lfp(rectime); | 730 | rectime = gettime(); |
728 | reply.reftime = d_to_lfp(G.status.reftime); | 731 | msg.xmttime = msg.rectime = d_to_lfp(rectime); |
729 | reply.xmttime = d_to_lfp(gettime()); | 732 | msg.reftime = d_to_lfp(G.status.reftime); |
730 | reply.orgtime = query.xmttime; | 733 | //msg.xmttime = d_to_lfp(gettime()); // = msg.rectime |
731 | reply.rootdelay = d_to_sfp(G.status.rootdelay); | 734 | msg.orgtime = query_xmttime; |
732 | reply.refid = (version > 3) ? G.status.refid4 : G.status.refid; | 735 | msg.rootdelay = d_to_sfp(G.status.rootdelay); |
736 | version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */ | ||
737 | msg.refid = (version > (3 << VERSION_SHIFT)) ? G.status.refid4 : G.status.refid; | ||
733 | 738 | ||
734 | /* We reply from the address packet was sent to, | 739 | /* We reply from the address packet was sent to, |
735 | * this makes to/from look swapped here: */ | 740 | * this makes to/from look swapped here: */ |
736 | sendmsg_wrap(fd, /*from:*/ &to->u.sa, /*to:*/ from, /*addrlen:*/ to->len, | 741 | sendmsg_wrap(fd, |
737 | &reply, size); | 742 | /*from:*/ &to->u.sa, /*to:*/ from, /*addrlen:*/ to->len, |
743 | &msg, size); | ||
738 | 744 | ||
739 | bail: | 745 | bail: |
740 | free(to); | 746 | free(to); |
@@ -835,7 +841,8 @@ static NOINLINE void ntp_init(char **argv) | |||
835 | unsigned opts; | 841 | unsigned opts; |
836 | llist_t *peers; | 842 | llist_t *peers; |
837 | 843 | ||
838 | tzset(); | 844 | srandom(getpid()); |
845 | /* tzset(); - why? it's called automatically when needed, no? */ | ||
839 | 846 | ||
840 | if (getuid()) | 847 | if (getuid()) |
841 | bb_error_msg_and_die("need root privileges"); | 848 | bb_error_msg_and_die("need root privileges"); |
@@ -911,7 +918,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
911 | 918 | ||
912 | while (!bb_got_signal) { | 919 | while (!bb_got_signal) { |
913 | llist_t *item; | 920 | llist_t *item; |
914 | unsigned i, j, idx_peers; | 921 | unsigned i, j, first_peer_idx; |
915 | unsigned sent_cnt, trial_cnt; | 922 | unsigned sent_cnt, trial_cnt; |
916 | int nfds, timeout; | 923 | int nfds, timeout; |
917 | time_t nextaction; | 924 | time_t nextaction; |
@@ -926,7 +933,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
926 | i++; | 933 | i++; |
927 | } | 934 | } |
928 | #endif | 935 | #endif |
929 | idx_peers = i; | 936 | first_peer_idx = i; |
930 | sent_cnt = trial_cnt = 0; | 937 | sent_cnt = trial_cnt = 0; |
931 | for (item = g.ntp_peers; item != NULL; item = item->link) { | 938 | for (item = g.ntp_peers; item != NULL; item = item->link) { |
932 | ntp_peer_t *p = (ntp_peer_t *) item->data; | 939 | ntp_peer_t *p = (ntp_peer_t *) item->data; |
@@ -960,7 +967,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
960 | if (p->state == STATE_QUERY_SENT) { | 967 | if (p->state == STATE_QUERY_SENT) { |
961 | pfd[i].fd = p->query.fd; | 968 | pfd[i].fd = p->query.fd; |
962 | pfd[i].events = POLLIN; | 969 | pfd[i].events = POLLIN; |
963 | idx2peer[i - idx_peers] = p; | 970 | idx2peer[i - first_peer_idx] = p; |
964 | i++; | 971 | i++; |
965 | } | 972 | } |
966 | } | 973 | } |
@@ -978,7 +985,8 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
978 | 985 | ||
979 | j = 0; | 986 | j = 0; |
980 | #if ENABLE_FEATURE_NTPD_SERVER | 987 | #if ENABLE_FEATURE_NTPD_SERVER |
981 | for (; nfds > 0 && j < idx_peers; j++) { | 988 | //TODO: simplify. There is only one server fd! |
989 | for (; nfds > 0 && j < first_peer_idx; j++) { | ||
982 | if (pfd[j].revents & (POLLIN|POLLERR)) { | 990 | if (pfd[j].revents & (POLLIN|POLLERR)) { |
983 | nfds--; | 991 | nfds--; |
984 | server_dispatch(pfd[j].fd); | 992 | server_dispatch(pfd[j].fd); |
@@ -988,7 +996,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
988 | for (; nfds > 0 && j < i; j++) { | 996 | for (; nfds > 0 && j < i; j++) { |
989 | if (pfd[j].revents & (POLLIN|POLLERR)) { | 997 | if (pfd[j].revents & (POLLIN|POLLERR)) { |
990 | nfds--; | 998 | nfds--; |
991 | client_dispatch(idx2peer[j - idx_peers]); | 999 | client_dispatch(idx2peer[j - first_peer_idx]); |
992 | } | 1000 | } |
993 | } | 1001 | } |
994 | } /* while (!bb_got_signal) */ | 1002 | } /* while (!bb_got_signal) */ |