summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/ntp_intres.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/ntpd/ntp_intres.c')
-rw-r--r--contrib/ntp/ntpd/ntp_intres.c246
1 files changed, 169 insertions, 77 deletions
diff --git a/contrib/ntp/ntpd/ntp_intres.c b/contrib/ntp/ntpd/ntp_intres.c
index e9a387e..9653fdd 100644
--- a/contrib/ntp/ntpd/ntp_intres.c
+++ b/contrib/ntp/ntpd/ntp_intres.c
@@ -20,19 +20,25 @@
# include <config.h>
#endif
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <netdb.h>
-#include <signal.h>
-
#include "ntpd.h"
#include "ntp_io.h"
#include "ntp_request.h"
#include "ntp_stdlib.h"
#include "ntp_syslog.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <signal.h>
+
+/**/
+#include <netinet/in.h>
+#include <arpa/inet.h>
+/**/
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h> /* MAXHOSTNAMELEN (often) */
+#endif
+
#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
/*
@@ -52,6 +58,7 @@ struct conf_entry {
#define ce_flags ce_config.flags
#define ce_ttl ce_config.ttl
#define ce_keyid ce_config.keyid
+#define ce_keystr ce_config.keystr
/*
* confentries is a pointer to the list of configuration entries
@@ -73,7 +80,6 @@ static struct conf_entry *confentries = NULL;
#define MAXRESOLVE 32
#define CONFIG_TIME 2
#define ALARM_TIME 30
-
#define SLEEPTIME 2
static volatile int config_timer = 0;
@@ -107,7 +113,8 @@ static int resolve_value; /* next value of resolve timer */
#define TOK_FLAGS 5
#define TOK_TTL 6
#define TOK_KEYID 7
-#define NUMTOK 8
+#define TOK_KEYSTR 8
+#define NUMTOK 9
#define MAXLINESIZE 512
@@ -120,7 +127,7 @@ static int sockfd = -1;
/* stuff to be filled in by caller */
-u_long req_keyid; /* request keyid */
+keyid_t req_keyid; /* request keyid */
char *req_file; /* name of the file with configuration info */
/* end stuff to be filled in */
@@ -129,7 +136,8 @@ char *req_file; /* name of the file with configuration info */
static RETSIGTYPE bong P((int));
static void checkparent P((void));
static void removeentry P((struct conf_entry *));
-static void addentry P((char *, int, int, int, int, int, int, u_long));
+static void addentry P((char *, int, int, int, int, u_int,
+ int, keyid_t, char *));
static int findhostaddr P((struct conf_entry *));
static void openntp P((void));
static int request P((struct conf_peer *));
@@ -137,10 +145,48 @@ static char * nexttoken P((char **));
static void readconf P((FILE *, char *));
static void doconfigure P((int));
+struct ntp_res_t_pkt { /* Tagged packet: */
+ void *tag; /* For the caller */
+ u_int32 paddr; /* IP to look up, or 0 */
+ char name[MAXHOSTNAMELEN]; /* Name to look up (if 1st byte is not 0) */
+};
+
+struct ntp_res_c_pkt { /* Control packet: */
+ char name[MAXHOSTNAMELEN];
+ u_int32 paddr;
+ int mode;
+ int version;
+ int minpoll;
+ int maxpoll;
+ u_int flags;
+ int ttl;
+ keyid_t keyid;
+ u_char keystr[MAXFILENAME];
+};
+
+
/*
- * assumes: req_key, req_keyid, conffile valid
- * syslog still open
+ * ntp_res_recv: Process an answer from the resolver
*/
+
+void
+ntp_res_recv(void)
+{
+ /*
+ We have data ready on our descriptor.
+ It may be an EOF, meaning the resolver process went away.
+ Otherwise, it will be an "answer".
+ */
+}
+
+
+/*
+ * ntp_intres needs;
+ *
+ * req_key(???), req_keyid, req_file valid
+ * syslog still open
+ */
+
void
ntp_intres(void)
{
@@ -149,7 +195,7 @@ ntp_intres(void)
sigset_t set;
sigemptyset(&set);
-#endif /* NTP_POSIX_SOURCE */
+#endif /* HAVE_SIGSUSPEND */
#ifdef DEBUG
if (debug > 1) {
@@ -160,7 +206,7 @@ ntp_intres(void)
/* check out auth stuff */
if (sys_authenticate) {
if (!authistrusted(req_keyid)) {
- msyslog(LOG_ERR, "invalid request keyid %lu",
+ msyslog(LOG_ERR, "invalid request keyid %08x",
req_keyid );
exit(1);
}
@@ -180,7 +226,7 @@ ntp_intres(void)
(void) fclose(in);
if (!debug )
- (void) unlink(req_file);
+ (void) unlink(req_file);
/*
* Sleep a little to make sure the server is completely up
@@ -192,12 +238,13 @@ ntp_intres(void)
* Make a first cut at resolving the bunch
*/
doconfigure(1);
- if (confentries == NULL)
+ if (confentries == NULL) {
#if defined SYS_WINNT
- ExitThread(0); /* Don't want to kill whole NT process */
+ ExitThread(0); /* Don't want to kill whole NT process */
#else
- exit(0); /* done that quick */
+ exit(0); /* done that quick */
#endif
+ }
/*
* Here we've got some problem children. Set up the timer
@@ -221,7 +268,8 @@ ntp_intres(void)
resolve_value <<= 1;
resolve_timer = resolve_value;
#ifdef DEBUG
- msyslog(LOG_INFO, "resolve_timer: 0->%d", resolve_timer);
+ if (debug > 2)
+ msyslog(LOG_INFO, "resolve_timer: 0->%d", resolve_timer);
#endif
config_timer = CONFIG_TIME;
doconfigure(1);
@@ -229,7 +277,8 @@ ntp_intres(void)
} else if (config_timer == 0) {
config_timer = CONFIG_TIME;
#ifdef DEBUG
- msyslog(LOG_INFO, "config_timer: 0->%d", config_timer);
+ if (debug > 2)
+ msyslog(LOG_INFO, "config_timer: 0->%d", config_timer);
#endif
doconfigure(0);
continue;
@@ -239,11 +288,11 @@ ntp_intres(void)
* There is a race in here. Is okay, though, since
* all it does is delay things by 30 seconds.
*/
-#ifdef HAVE_SIGSUSPEND
+# ifdef HAVE_SIGSUSPEND
sigsuspend(&set);
-#else
+# else
sigpause(0);
-#endif /* HAVE_SIGSUSPEND */
+# endif /* HAVE_SIGSUSPEND */
#else
if (config_timer > 0)
config_timer--;
@@ -336,17 +385,25 @@ addentry(
int version,
int minpoll,
int maxpoll,
- int flags,
+ u_int flags,
int ttl,
- u_long keyid
+ keyid_t keyid,
+ char *keystr
)
{
register char *cp;
register struct conf_entry *ce;
unsigned int len;
+#ifdef DEBUG
+ if (debug > 1)
+ msyslog(LOG_INFO,
+ "intres: <%s> %d %d %d %d %x %d %x %s\n", name,
+ mode, version, minpoll, maxpoll, flags, ttl, keyid,
+ keystr);
+#endif
len = strlen(name) + 1;
- cp = (char*)emalloc(len);
+ cp = (char *)emalloc(len);
memmove(cp, name, len);
ce = (struct conf_entry *)emalloc(sizeof(struct conf_entry));
@@ -359,6 +416,7 @@ addentry(
ce->ce_flags = (u_char)flags;
ce->ce_ttl = (u_char)ttl;
ce->ce_keyid = keyid;
+ strncpy((char *)ce->ce_keystr, keystr, MAXFILENAME);
ce->ce_next = NULL;
if (confentries == NULL) {
@@ -375,12 +433,12 @@ addentry(
/*
- * findhostaddr - resolve a host name into an address
+ * findhostaddr - resolve a host name into an address (Or vice-versa)
*
- * The routine sticks the address into the entry's ce_peeraddr if it
- * gets one. It returns 1 for "success" and 0 for an uncorrectable
- * failure. Note that "success" includes try again errors. You can
- * tell that you got a try again since ce_peeraddr will still be zero.
+ * Given one of {ce_peeraddr,ce_name}, find the other one.
+ * It returns 1 for "success" and 0 for an uncorrectable failure.
+ * Note that "success" includes try again errors. You can tell that you
+ * got a "try again" since {ce_peeraddr,ce_name} will still be zero.
*/
static int
findhostaddr(
@@ -388,31 +446,80 @@ findhostaddr(
)
{
struct hostent *hp;
+ struct in_addr in;
checkparent(); /* make sure our guy is still running */
- hp = gethostbyname(entry->ce_name);
+ if (entry->ce_name && entry->ce_peeraddr) {
+ /* HMS: Squawk? */
+ msyslog(LOG_ERR, "findhostaddr: both ce_name and ce_peeraddr are defined...");
+ return 1;
+ }
+
+ if (!entry->ce_name && !entry->ce_peeraddr) {
+ msyslog(LOG_ERR, "findhostaddr: both ce_name and ce_peeraddr are undefined!");
+ return 0;
+ }
+
+ if (entry->ce_name) {
+#ifdef DEBUG
+ if (debug > 2)
+ msyslog(LOG_INFO, "findhostaddr: Resolving <%s>",
+ entry->ce_name);
+#endif /* DEBUG */
+ hp = gethostbyname(entry->ce_name);
+ } else {
+#ifdef DEBUG
+ if (debug > 2)
+ msyslog(LOG_INFO, "findhostaddr: Resolving %x>",
+ entry->ce_peeraddr);
+#endif
+ in.s_addr = entry->ce_peeraddr;
+ hp = gethostbyaddr((const char *)&in,
+ sizeof entry->ce_peeraddr,
+ AF_INET);
+ }
if (hp == NULL) {
-#ifndef NODNS
/*
* If the resolver is in use, see if the failure is
* temporary. If so, return success.
*/
if (h_errno == TRY_AGAIN)
return (1);
-#endif
return (0);
}
- /*
- * Use the first address. We don't have any way to
- * tell preferences and older gethostbyname() implementations
- * only return one.
- */
- memmove((char *)&(entry->ce_peeraddr),
- (char *)hp->h_addr,
- sizeof(struct in_addr));
+ if (entry->ce_name) {
+#ifdef DEBUG
+ if (debug > 2)
+ msyslog(LOG_INFO, "findhostaddr: name resolved.");
+#endif
+ /*
+ * Use the first address. We don't have any way to tell
+ * preferences and older gethostbyname() implementations
+ * only return one.
+ */
+ memmove((char *)&(entry->ce_peeraddr),
+ (char *)hp->h_addr,
+ sizeof(struct in_addr));
+ if (entry->ce_keystr[0] == '*')
+ strncpy((char *)&(entry->ce_keystr), hp->h_name,
+ MAXFILENAME);
+ } else {
+ char *cp;
+ size_t s;
+
+#ifdef DEBUG
+ if (debug > 2)
+ msyslog(LOG_INFO, "findhostaddr: address resolved.");
+#endif
+ s = strlen(hp->h_name) + 1;
+ cp = emalloc(s);
+ strcpy(cp, hp->h_name);
+ entry->ce_name = cp;
+ }
+
return (1);
}
@@ -460,7 +567,7 @@ openntp(void)
#endif /* O_NONBLOCK */
#else /* SYS_WINNT */
{
- int on=1;
+ int on = 1;
if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) {
msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m");
exit(1); /* Windows NT - set socket in non-blocking mode */
@@ -470,7 +577,7 @@ openntp(void)
if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
- msyslog(LOG_ERR, "connect() failed: %m");
+ msyslog(LOG_ERR, "openntp: connect() failed: %m");
exit(1);
}
}
@@ -531,6 +638,11 @@ request(
reqpkt.request = REQ_CONFIG; /* configure a new peer */
reqpkt.err_nitems = ERR_NITEMS(0, 1); /* one item */
reqpkt.mbz_itemsize = MBZ_ITEMSIZE(sizeof(struct conf_peer));
+ /* Make sure mbz_itemsize <= sizeof reqpkt.data */
+ if (sizeof(struct conf_peer) > sizeof (reqpkt.data)) {
+ msyslog(LOG_ERR, "Bletch: conf_peer is too big for reqpkt.data!");
+ exit(1);
+ }
memmove(reqpkt.data, (char *)conf, sizeof(struct conf_peer));
reqpkt.keyid = htonl(req_keyid);
@@ -552,7 +664,7 @@ request(
}
#else
/* In the NT world, documentation seems to indicate that there
- * exist _write and _read routines that can be used to so blocking
+ * exist _write and _read routines that can be used to do blocking
* I/O on sockets. Problem is these routines require a socket
* handle obtained through the _open_osf_handle C run-time API
* of which there is no explanation in the documentation. We need
@@ -603,8 +715,8 @@ request(
}
else if (n == 0)
{
- if(debug)
- msyslog(LOG_DEBUG, "select() returned 0.");
+ if (debug)
+ msyslog(LOG_INFO, "select() returned 0.");
return 0;
}
@@ -814,7 +926,7 @@ readconf(
register int i;
char *token[NUMTOK];
u_long intval[NUMTOK];
- int flags;
+ u_int flags;
char buf[MAXLINESIZE];
char *bp;
@@ -830,7 +942,7 @@ readconf(
}
}
- for (i = 1; i < NUMTOK; i++) {
+ for (i = 1; i < NUMTOK - 1; i++) {
if (!atouint(token[i], &intval[i])) {
msyslog(LOG_ERR,
"format error for integer token `%s', file `%s', quitting",
@@ -868,7 +980,7 @@ readconf(
}
if ((intval[TOK_FLAGS] & ~(FLAG_AUTHENABLE | FLAG_PREFER |
- FLAG_NOSELECT | FLAG_BURST | FLAG_SKEY))
+ FLAG_NOSELECT | FLAG_BURST | FLAG_IBURST | FLAG_SKEY))
!= 0) {
msyslog(LOG_ERR, "invalid flags (%ld) in file %s",
intval[TOK_FLAGS], name);
@@ -884,6 +996,8 @@ readconf(
flags |= CONF_FLAG_NOSELECT;
if (intval[TOK_FLAGS] & FLAG_BURST)
flags |= CONF_FLAG_BURST;
+ if (intval[TOK_FLAGS] & FLAG_IBURST)
+ flags |= CONF_FLAG_IBURST;
if (intval[TOK_FLAGS] & FLAG_SKEY)
flags |= CONF_FLAG_SKEY;
@@ -893,7 +1007,7 @@ readconf(
addentry(token[TOK_HOSTNAME], (int)intval[TOK_HMODE],
(int)intval[TOK_VERSION], (int)intval[TOK_MINPOLL],
(int)intval[TOK_MAXPOLL], flags, (int)intval[TOK_TTL],
- intval[TOK_KEYID]);
+ intval[TOK_KEYID], token[TOK_KEYSTR]);
}
}
@@ -909,16 +1023,12 @@ doconfigure(
register struct conf_entry *ce;
register struct conf_entry *ceremove;
-#ifdef DEBUG
- if (debug > 1)
- msyslog(LOG_INFO, "doconfigure(%d)", dores);
-#endif
-
ce = confentries;
while (ce != NULL) {
#ifdef DEBUG
if (debug > 1)
- msyslog(LOG_INFO, "doconfigure: <%s> has peeraddr %#x",
+ msyslog(LOG_INFO,
+ "doconfigure: <%s> has peeraddr %#x",
ce->ce_name, ce->ce_peeraddr);
#endif
if (dores && ce->ce_peeraddr == 0) {
@@ -931,28 +1041,10 @@ doconfigure(
removeentry(ceremove);
continue;
}
-#ifdef DEBUG
- if (debug > 1) {
- msyslog(LOG_INFO,
- "doconfigure:findhostaddr() worked");
- }
-#endif
}
if (ce->ce_peeraddr != 0) {
-#ifdef DEBUG
- if (debug > 1) {
- msyslog(LOG_INFO,
- "doconfigure: calling request()");
- }
-#endif
if (request(&ce->ce_config)) {
-#ifdef DEBUG
- if (debug > 1) {
- msyslog(LOG_INFO,
- "doconfigure: request() OK, removing this entry");
- }
-#endif
ceremove = ce;
ce = ceremove->ce_next;
removeentry(ceremove);
@@ -961,7 +1053,7 @@ doconfigure(
#ifdef DEBUG
if (debug > 1) {
msyslog(LOG_INFO,
- "doconfigure: request() FAILED, maybe next time.");
+ "doconfigure: request() FAILED, maybe next time.");
}
#endif
}
OpenPOWER on IntegriCloud