1999-07-20 Harlan Stenn <stenn@whimsy.udel.edu>
+ * include/ntp.h:
+ include/ntp_fp.h:
+ include/ntp_io.h:
+ include/ntp_machine.h:
+ include/ntp_refclock.h:
+ include/ntp_stdlib.h:
+ include/ntpd.h:
+ libntp/Makefile.am:
+ libntp/emalloc.c:
+ libntp/machines.c:
+ libntp/mexit.c:
+ libntp/msyslog.c:
+ libntp/statestr.c:
+ libntp/syssignal.c:
+ libntp/systime.c:
+ libparse/parse.c:
+ libparse/parse_conf.c:
+ ntpd/ntp_control.c:
+ ntpd/ntp_intres.c:
+ ntpd/ntp_io.c:
+ ntpd/ntp_proto.c:
+ ntpd/ntp_refclock.c:
+ ntpd/ntp_request.c:
+ ntpd/ntp_timer.c:
+ ntpd/ntp_util.c:
+ ntpd/ntpd.c:
+ ntpd/refclock_nmea.c:
+ ntpd/refclock_palisade.c:
+ ntpd/refclock_palisade.h:
+ ntpd/refclock_shm.c:
+ ntpdate/ntpdate.c:
+ ntptrace/ntptrace.c: Cleanup
+ * libntp/recvbuff.c:
+ libntp/iosignal.c:
+ include/iosignal.h:
+ include/recvbuff.h: Added
+ From: Sven_Dietrich@Trimble.COM
+
* README: Add README.cvs
* configure.in (ac_cv_var_struct_ntptime_val_timespec): Typo.
--- /dev/null
+#if !defined _ntp_iosignaled_h
+#define _ntp_iosignaled_h
+
+#include "ntp_refclock.h"
+
+#if defined(HAVE_SIGNALED_IO)
+extern void block_sigio P((void));
+extern void unblock_sigio P((void));
+extern int init_clock_sig P((struct refclockio *));
+extern void init_socket_sig P((int));
+extern void set_signal P((void));
+RETSIGTYPE sigio_handler P((int));
+
+# define BLOCKIO() ((void) block_sigio())
+# define UNBLOCKIO() ((void) unblock_sigio())
+
+#else
+
+# define BLOCKIO()
+# define UNBLOCKIO()
+#endif /* HAVE_SIGNALED_IO */
+
+#endif
#define STRATUM_TO_PKT(s) ((u_char)(((s) == (STRATUM_UNSPEC)) ?\
(STRATUM_PKT_UNSPEC) : (s)))
-/*
- * Format of a recvbuf. These are used by the asynchronous receive
- * routine to store incoming packets and related information.
- */
-
-/*
- * the maximum length NTP packet is a full length NTP control message with
- * the maximum length message authenticator. I hate to hard-code 468 and 12,
- * but only a few modules include ntp_control.h...
- */
-#define RX_BUFF_SIZE (468+12+MAX_MAC_LEN)
-
-struct recvbuf {
- struct recvbuf *next; /* next buffer in chain */
- union {
- struct sockaddr_in X_recv_srcadr;
- caddr_t X_recv_srcclock;
- } X_from_where;
-#define recv_srcadr X_from_where.X_recv_srcadr
-#define recv_srcclock X_from_where.X_recv_srcclock
- struct sockaddr_in srcadr; /* where packet came from */
- struct interface *dstadr; /* interface datagram arrived thru */
- int fd; /* fd on which it was received */
- l_fp recv_time; /* time of arrival */
- void (*receiver) P((struct recvbuf *)); /* routine to receive buffer */
- int recv_length; /* number of octets received */
- union {
- struct pkt X_recv_pkt;
- u_char X_recv_buffer[RX_BUFF_SIZE];
- } recv_space;
-#define recv_pkt recv_space.X_recv_pkt
-#define recv_buffer recv_space.X_recv_buffer
-};
-
/*
* Event codes. Used for reporting errors/events to the control module
+#if !defined _NTP_IO_H
+#define _NTP_IO_H
/*
* POSIX says use <fnct.h> to get O_* symbols and
* SEEK_SET symbol form <unistd.h>.
#if !defined(SEEK_SET) && defined(L_SET)
# define SEEK_SET L_SET
#endif
+
#ifdef SYS_WINNT
# include <io.h>
+# include "win32_io.h"
+#endif
+
#endif
* Windows NT
*/
#if defined(SYS_WINNT)
-#if !defined(HAVE_CONFIG_H)
-# define MCAST /* Enable Multicast Support */
-# undef OPEN_BCAST_SOCKET /* for ntp_io.c */
-# undef UDP_WILDCARD_DELIVERY /* for ntp_io.c */
-# define REFCLOCK /* from ntpd.mak */
-# define CLOCK_LOCAL /* from ntpd.mak */
-# define CLOCK_SHM /* from ntpd.mak */
-# define CLOCK_PALISADE /* from ntpd.mak */
-# undef DES /* from libntp.mak */
-# undef MD5 /* from libntp.mak */
-# define NTP_LITTLE_ENDIAN /* from libntp.mak */
-# define SYSLOG_FILE /* from libntp.mak */
-# define HAVE_PROTOTYPES /* from ntpq.mak */
-
-# define SIZEOF_INT 4 /* for ntp_types.h */
-# define SYSV_TIMEOFDAY /* for ntp_unixtime.h */
-# define HAVE_NET_IF_H
-# define QSORT_USES_VOID_P
-# define HAVE_MEMMOVE
-# define volatile
-# define STDC_HEADERS
-# define NEED_S_CHAR_TYPEDEF
-# define SIZEOF_SIGNED_CHAR 1
-# define HAVE_NO_NICE
-# define NOKMEM
-# define PRESET_TICK (every / 10)
-# define PRESET_TICKADJ 50
-# define RETSIGTYPE void
-# define NTP_POSIX_SOURCE
-# define HAVE_SETVBUF
-# define HAVE_VSPRINTF
-# ifndef STR_SYSTEM
-# define STR_SYSTEM "WINDOWS/NT"
-# endif
+# if !defined(HAVE_CONFIG_H) || !defined(__config)
+# error "NT requires config.h to be included"
# endif /* HAVE_CONFIG_H) */
-/* winsock.h contains macros for class A,B,C only */
-# define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
-# define IN_CLASSD_NET 0xf0000000
-# define IN_CLASSD_NSHIFT 28
-# define IN_CLASSD_HOST 0xfffffff
-# define IN_MULTICAST(i) IN_CLASSD(i)
+
+#if defined SYS_WINNT
+# define ifreq _INTERFACE_INFO
+# define ifr_flags iiFlags
+# define ifr_addr iiAddress.AddressIn
+# define ifr_broadaddr iiBroadcastAddress.AddressIn
+# define ifr_mask iiNetmask.AddressIn
+#endif /* SYS_WINNT */
+
# define isascii __isascii
# define isatty _isatty
-# define fileno _fileno
# define mktemp _mktemp
# define getpid GetCurrentProcessId
-# include <winsock.h>
# include <windows.h>
-# include <winbase.h>
+# include <ws2tcpip.h>
# undef interface
-typedef char *caddr_t;
-void PASCAL alarming P((UINT,UINT,DWORD,DWORD,DWORD));
+ typedef char *caddr_t;
#endif /* SYS_WINNT */
int ntp_set_tod P((struct timeval *tvp, void *tzp));
#endif /* CLK */
#endif /* STREAM */
+#include "recvbuff.h"
+
#if !defined(SYSV_TTYS) && !defined(STREAM) & !defined(BSD_TTYS)
#define BSD_TTYS
#endif /* SYSV_TTYS STREAM BSD_TTYS */
# endif
#endif
-#if defined(__STDC__)
+#if defined(__STDC__) || defined(HAVE_STDARG_H)
# include <stdarg.h>
extern void msyslog P((int, const char *, ...))
__attribute__((__format__(__printf__, 2, 3)));
extern u_long calyearstart P((u_long));
extern const char *clockname P((int));
extern int clocktime P((int, int, int, int, int, u_long, u_long *, u_int32 *));
+#if defined SYS_WINNT && defined DEBUG
+# define emalloc(_c) debug_emalloc(_c, __FILE__, __LINE__)
+extern void * debug_emalloc P((u_int, char *, int));
+#else
extern void * emalloc P((u_int));
+#endif
extern int ntp_getopt P((int, char **, const char *));
extern void init_auth P((void));
extern void init_lib P((void));
#include "ntp.h"
#include "ntp_malloc.h"
#include "ntp_refclock.h"
+#include "recvbuff.h"
#define MAXINTERFACES 512
/* ntp_io.c */
extern struct interface *findbcastinter P((struct sockaddr_in *));
extern struct interface *findinterface P((struct sockaddr_in *));
-extern void freerecvbuf P((struct recvbuf *));
-extern struct recvbuf *getrecvbufs P((void));
+
extern void init_io P((void));
extern void input_handler P((l_fp *));
extern void io_clr_stats P((void));
extern volatile u_long full_recvbufs; /* number of recvbufs on fulllist */
extern volatile u_long free_recvbufs; /* number of recvbufs on freelist */
extern u_long total_recvbufs; /* total recvbufs currently in use */
-extern u_long lowater_additions; /* number of times we have added memory */
/*
* Other statistics of possible interest
--- /dev/null
+#if !defined __recvbuff_h
+#define __recvbuff_h
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntp.h"
+#include "ntp_fp.h"
+#include "ntp_types.h"
+
+/*
+ * recvbuf memory management
+ */
+#define RECV_INIT 10 /* 10 buffers initially */
+#define RECV_LOWAT 3 /* when we're down to three buffers get more */
+#define RECV_INC 5 /* get 5 more at a time */
+#define RECV_TOOMANY 40 /* this is way too many buffers */
+
+#if defined HAVE_IO_COMPLETION_PORT
+# include "ntp_iocompletionport.h"
+#include "ntp_timer.h"
+
+# define RECV_BLOCK_IO() EnterCriticalSection(&RecvCritSection)
+# define RECV_UNBLOCK_IO() LeaveCriticalSection(&RecvCritSection)
+
+/* Return the event which is set when items are added to the full list
+ */
+extern HANDLE get_recv_buff_event P((void));
+#else
+# define RECV_BLOCK_IO()
+# define RECV_UNBLOCK_IO()
+#endif
+
+
+/*
+ * Format of a recvbuf. These are used by the asynchronous receive
+ * routine to store incoming packets and related information.
+ */
+
+/*
+ * the maximum length NTP packet is a full length NTP control message with
+ * the maximum length message authenticator. I hate to hard-code 468 and 12,
+ * but only a few modules include ntp_control.h...
+ */
+#define RX_BUFF_SIZE (468+12+MAX_MAC_LEN)
+
+struct recvbuf {
+ struct recvbuf *next; /* next buffer in chain */
+ union {
+ struct sockaddr_in X_recv_srcadr;
+ caddr_t X_recv_srcclock;
+ struct peer *X_recv_peer;
+ } X_from_where;
+#define recv_srcadr X_from_where.X_recv_srcadr
+#define recv_srcclock X_from_where.X_recv_srcclock
+#define recv_peer X_from_where.X_recv_peer
+#if defined HAVE_IO_COMPLETION_PORT
+ IoCompletionInfo iocompletioninfo;
+ WSABUF wsabuff;
+ DWORD AddressLength;
+#else
+ struct sockaddr_in srcadr; /* where packet came from */
+#endif
+ struct interface *dstadr; /* interface datagram arrived thru */
+ int fd; /* fd on which it was received */
+ l_fp recv_time; /* time of arrival */
+ void (*receiver) P((struct recvbuf *)); /* routine to receive buffer */
+ int recv_length; /* number of octets received */
+ union {
+ struct pkt X_recv_pkt;
+ u_char X_recv_buffer[RX_BUFF_SIZE];
+ } recv_space;
+#define recv_pkt recv_space.X_recv_pkt
+#define recv_buffer recv_space.X_recv_buffer
+};
+
+extern void init_recvbuff P((int));
+
+/* freerecvbuf - make a single recvbuf available for reuse
+ */
+extern void freerecvbuf P((struct recvbuf *));
+
+
+extern struct recvbuf * getrecvbufs P((void));
+
+/* Get a free buffer (typically used so an async
+ * read can directly place data into the buffer
+ *
+ * The buffer is removed from the free list. Make sure
+ * you put it back with freerecvbuf() or
+ */
+extern struct recvbuf *get_free_recv_buffer P((void));
+
+/* Add a buffer to the full list
+ */
+extern void add_full_recv_buffer P((struct recvbuf *));
+
+/*extern void process_recv_buffers P((void)); */
+
+/* number of recvbufs on freelist */
+extern u_long free_recvbuffs P((void));
+extern u_long full_recvbuffs P((void));
+extern u_long total_recvbuffs P((void));
+extern u_long lowater_additions P((void));
+
+/* Returns the next buffer in the full list.
+ *
+ */
+extern struct recvbuf *get_full_recv_buffer P((void));
+
+#endif /* defined __recvbuff_h */
+
msyslog.c netof.c numtoa.c numtohost.c octtoint.c prettydate.c \
ranny.c refnumtoa.c statestr.c syssignal.c systime.c tsftomsu.c \
tstotv.c tvtoa.c tvtots.c uglydate.c uinttoa.c utvtoa.c ymd2yd.c \
- mfp_mul.c binio.c ieee754io.c gpstolfp.c
+ mfp_mul.c binio.c ieee754io.c gpstolfp.c recvbuff.c iosignal.c
libntp_a_LIBADD = @LIBOBJS@
libntp_a_DEPENDENCIES = @LIBOBJS@
INCLUDES = -I$(top_srcdir)/include
msyslog.c netof.c numtoa.c numtohost.c octtoint.c prettydate.c \
ranny.c refnumtoa.c statestr.c syssignal.c systime.c tsftomsu.c \
tstotv.c tvtoa.c tvtots.c uglydate.c uinttoa.c utvtoa.c ymd2yd.c \
- mfp_mul.c binio.c ieee754io.c gpstolfp.c
+ mfp_mul.c binio.c ieee754io.c gpstolfp.c recvbuff.c iosignal.c
libntp_a_LIBADD = @LIBOBJS@
libntp_a_DEPENDENCIES = @LIBOBJS@
octtoint$U.o prettydate$U.o ranny$U.o refnumtoa$U.o statestr$U.o \
syssignal$U.o systime$U.o tsftomsu$U.o tstotv$U.o tvtoa$U.o tvtots$U.o \
uglydate$U.o uinttoa$U.o utvtoa$U.o ymd2yd$U.o mfp_mul$U.o binio$U.o \
-ieee754io$U.o gpstolfp$U.o
+ieee754io$U.o gpstolfp$U.o recvbuff$U.o iosignal$U.o
libntp_a_OBJECTS = $(am_libntp_a_OBJECTS)
AR = ar
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
.deps/dolfptoa.P .deps/emalloc.P .deps/findconfig.P .deps/fptoa.P \
.deps/fptoms.P .deps/getopt.P .deps/gpstolfp.P .deps/hextoint.P \
.deps/hextolfp.P .deps/humandate.P .deps/ieee754io.P .deps/inttoa.P \
-.deps/lib_strbuf.P .deps/machines.P .deps/md5c.P .deps/memmove.P \
-.deps/mexit.P .deps/mfp_mul.P .deps/mfptoa.P .deps/mfptoms.P \
-.deps/mktime.P .deps/modetoa.P .deps/mstolfp.P .deps/msutotsf.P \
-.deps/msyslog.P .deps/netof.P .deps/numtoa.P .deps/numtohost.P \
-.deps/octtoint.P .deps/prettydate.P .deps/ranny.P .deps/refnumtoa.P \
-.deps/statestr.P .deps/strerror.P .deps/syssignal.P .deps/systime.P \
-.deps/tsftomsu.P .deps/tstotv.P .deps/tvtoa.P .deps/tvtots.P \
-.deps/uglydate.P .deps/uinttoa.P .deps/utvtoa.P .deps/ymd2yd.P
+.deps/iosignal.P .deps/lib_strbuf.P .deps/machines.P .deps/md5c.P \
+.deps/memmove.P .deps/mexit.P .deps/mfp_mul.P .deps/mfptoa.P \
+.deps/mfptoms.P .deps/mktime.P .deps/modetoa.P .deps/mstolfp.P \
+.deps/msutotsf.P .deps/msyslog.P .deps/netof.P .deps/numtoa.P \
+.deps/numtohost.P .deps/octtoint.P .deps/prettydate.P .deps/ranny.P \
+.deps/recvbuff.P .deps/refnumtoa.P .deps/statestr.P .deps/strerror.P \
+.deps/syssignal.P .deps/systime.P .deps/tsftomsu.P .deps/tstotv.P \
+.deps/tvtoa.P .deps/tvtots.P .deps/uglydate.P .deps/uinttoa.P \
+.deps/utvtoa.P .deps/ymd2yd.P
SOURCES = $(libntp_a_SOURCES)
OBJECTS = $(am_libntp_a_OBJECTS)
binio$U.o:
ieee754io$U.o:
gpstolfp$U.o:
+recvbuff$U.o:
+iosignal$U.o:
libntp.a: $(libntp_a_OBJECTS) $(libntp_a_DEPENDENCIES)
-rm -f libntp.a
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ieee754io.c; then echo $(srcdir)/ieee754io.c; else echo ieee754io.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ieee754io_.c
inttoa_.c: inttoa.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/inttoa.c; then echo $(srcdir)/inttoa.c; else echo inttoa.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > inttoa_.c
+iosignal_.c: iosignal.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/iosignal.c; then echo $(srcdir)/iosignal.c; else echo iosignal.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > iosignal_.c
lib_strbuf_.c: lib_strbuf.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/lib_strbuf.c; then echo $(srcdir)/lib_strbuf.c; else echo lib_strbuf.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > lib_strbuf_.c
machines_.c: machines.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/prettydate.c; then echo $(srcdir)/prettydate.c; else echo prettydate.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > prettydate_.c
ranny_.c: ranny.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ranny.c; then echo $(srcdir)/ranny.c; else echo ranny.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ranny_.c
+recvbuff_.c: recvbuff.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/recvbuff.c; then echo $(srcdir)/recvbuff.c; else echo recvbuff.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > recvbuff_.c
refnumtoa_.c: refnumtoa.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/refnumtoa.c; then echo $(srcdir)/refnumtoa.c; else echo refnumtoa.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > refnumtoa_.c
statestr_.c: statestr.c $(ANSI2KNR)
calyearstart_.o clocktime_.o clocktypes_.o decodenetnum_.o dofptoa_.o \
dolfptoa_.o emalloc_.o findconfig_.o fptoa_.o fptoms_.o getopt_.o \
gpstolfp_.o hextoint_.o hextolfp_.o humandate_.o ieee754io_.o inttoa_.o \
-lib_strbuf_.o machines_.o md5c_.o memmove_.o mexit_.o mfp_mul_.o \
-mfptoa_.o mfptoms_.o mktime_.o modetoa_.o mstolfp_.o msutotsf_.o \
-msyslog_.o netof_.o numtoa_.o numtohost_.o octtoint_.o prettydate_.o \
-ranny_.o refnumtoa_.o statestr_.o strerror_.o syssignal_.o systime_.o \
-tsftomsu_.o tstotv_.o tvtoa_.o tvtots_.o uglydate_.o uinttoa_.o \
-utvtoa_.o ymd2yd_.o : $(ANSI2KNR)
+iosignal_.o lib_strbuf_.o machines_.o md5c_.o memmove_.o mexit_.o \
+mfp_mul_.o mfptoa_.o mfptoms_.o mktime_.o modetoa_.o mstolfp_.o \
+msutotsf_.o msyslog_.o netof_.o numtoa_.o numtohost_.o octtoint_.o \
+prettydate_.o ranny_.o recvbuff_.o refnumtoa_.o statestr_.o strerror_.o \
+syssignal_.o systime_.o tsftomsu_.o tstotv_.o tvtoa_.o tvtots_.o \
+uglydate_.o uinttoa_.o utvtoa_.o ymd2yd_.o : $(ANSI2KNR)
tags: TAGS
#include "ntp_stdlib.h"
#include "ntp_syslog.h"
+#if defined SYS_WINNT && defined DEBUG
+#include <crtdbg.h>
+#endif
+
+#if defined SYS_WINNT && defined DEBUG
+
+void *
+debug_emalloc(
+ u_int size,
+ char *filename,
+ int line
+ )
+{
+ char *mem;
+
+ if ((mem = (char *)_malloc_dbg(size, _NORMAL_BLOCK, filename, line)) == 0) {
+ msyslog(LOG_ERR, "No more memory!");
+ exit(1);
+ }
+ return mem;
+}
+
+#else
+
void *
emalloc(
u_int size
}
return mem;
}
+
+
+#endif
--- /dev/null
+/*
+ * ntp_io.c - input/output routines for ntpd. The socket-opening code
+ * was shamelessly stolen from ntpd.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
+# include <sys/sockio.h>
+#endif
+#include <arpa/inet.h>
+
+#if _BSDI_VERSION >= 199510
+# include <ifaddrs.h>
+#endif
+/* 98/06/01 */
+#include "ntp_machine.h" /* 98/06/01 */
+#include "ntpd.h"
+#include "ntp_select.h"
+#include "ntp_io.h"
+#include "ntp_if.h"
+#include "ntp_stdlib.h"
+#include "iosignal.h"
+extern int debug;
+
+#if defined(HAVE_SIGNALED_IO)
+static int sigio_block_count = 0;
+extern void input_handler P((l_fp *));
+
+/*
+ * SIGPOLL and SIGIO ROUTINES.
+ */
+
+ /*
+ * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
+ * a few have separate SIGIO and SIGPOLL signals. This code checks for the
+ * SIGIO == SIGPOLL case at compile time.
+ * Do not defined USE_SIGPOLL or USE_SIGIO.
+ * these are interal only to ntp_io.c!
+ */
+# if defined(USE_SIGPOLL)
+# undef USE_SIGPOLL
+# endif
+# if defined(USE_SIGIO)
+# undef USE_SIGIO
+# endif
+
+# if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
+# define USE_SIGPOLL
+# endif
+
+# if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
+# define USE_SIGIO
+# endif
+
+# if defined(USE_SIGIO) && defined(USE_SIGPOLL)
+# if SIGIO == SIGPOLL
+# define USE_SIGIO
+# undef USE_SIGPOLL
+# endif /* SIGIO == SIGPOLL */
+# endif /* USE_SIGIO && USE_SIGIO */
+
+
+/*
+ * TTY initialization routines.
+ */
+int
+init_clock_sig(
+ struct refclockio *rio
+ )
+{
+# ifdef USE_TTY_SIGPOLL
+ {
+ /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
+ if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
+ {
+ msyslog(LOG_ERR,
+ "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
+ return 1;
+ }
+ return 0;
+ }
+# else
+ /*
+ * Special cases first!
+ */
+ /* Was: defined(SYS_HPUX) */
+# if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
+#define CLOCK_DONE
+ {
+ int pgrp, on = 1;
+
+ /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
+ pgrp = getpid();
+ if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * set non-blocking, async I/O on the descriptor
+ */
+ if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+
+ if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+ return 0;
+ }
+# endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
+ /* Was: defined(SYS_AIX) && !defined(_BSD) */
+# if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
+ /*
+ * SYSV compatibility mode under AIX.
+ */
+#define CLOCK_DONE
+ {
+ int pgrp, on = 1;
+
+ /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
+ if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
+ return 1;
+ }
+ pgrp = -getpid();
+ if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
+ return 1;
+ }
+
+ if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
+ {
+ msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
+ return 1;
+ }
+ return 0;
+ }
+# endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
+# ifndef CLOCK_DONE
+ {
+ /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
+# if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
+ /*
+ * there are, however, always exceptions to the rules
+ * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
+ * CTTYs. SunOS and HPUX do not semm to have this restriction.
+ * another question is: how can you do multiple SIGIO from several
+ * ttys (as they all should be CTTYs), wondering...
+ *
+ * kd 95-07-16
+ */
+ if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
+ return 1;
+ }
+# endif /* TIOCSCTTY && USE_FSETOWNCTTY */
+
+ if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
+ {
+ msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
+ return 1;
+ }
+
+ if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
+ {
+ msyslog(LOG_ERR,
+ "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
+ return 1;
+ }
+ return 0;
+ }
+# endif /* CLOCK_DONE */
+# endif /* !USE_TTY_SIGPOLL */
+}
+
+
+
+void
+init_socket_sig(
+ int fd
+ )
+{
+# ifdef USE_UDP_SIGPOLL
+ {
+ if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
+ {
+ msyslog(LOG_ERR,
+ "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
+ exit(1);
+ }
+ }
+# else /* USE_UDP_SIGPOLL */
+ {
+ int pgrp;
+# ifdef FIOASYNC
+ int on = 1;
+# endif
+
+# if defined(FIOASYNC)
+ if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+# elif defined(FASYNC)
+ {
+ int flags;
+
+ if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
+ {
+ msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+ if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
+ {
+ msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+ }
+# else
+# include "Bletch: Need asynchronous I/O!"
+# endif
+
+# ifdef UDP_BACKWARDS_SETOWN
+ pgrp = -getpid();
+# else
+ pgrp = getpid();
+# endif
+
+# if defined(SIOCSPGRP)
+ if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+# elif defined(FIOSETOWN)
+ if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+# elif defined(F_SETOWN)
+ if (fcntl(fd, F_SETOWN, pgrp) == -1)
+ {
+ msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m");
+ exit(1);
+ /*NOTREACHED*/
+ }
+# else
+# include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
+# endif
+ }
+# endif /* USE_UDP_SIGPOLL */
+}
+
+RETSIGTYPE
+sigio_handler(
+ int sig
+ )
+{
+ int saved_errno = errno;
+ l_fp ts;
+
+ get_systime(&ts);
+ (void)input_handler(&ts);
+ errno = saved_errno;
+}
+
+/*
+ * Signal support routines.
+ */
+# ifdef HAVE_SIGACTION
+void
+set_signal(void)
+{
+# ifdef USE_SIGIO
+ (void) signal_no_reset(SIGIO, sigio_handler);
+# endif
+# ifdef USE_SIGPOLL
+ (void) signal_no_reset(SIGPOLL, sigio_handler);
+# endif
+}
+
+void
+block_io_and_alarm(void)
+{
+ sigset_t set;
+
+ if (sigemptyset(&set))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
+# if defined(USE_SIGIO)
+ if (sigaddset(&set, SIGIO))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigaddset(&set, SIGPOLL))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
+# endif
+ if (sigaddset(&set, SIGALRM))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
+
+ if (sigprocmask(SIG_BLOCK, &set, NULL))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
+}
+
+void
+block_sigio(void)
+{
+ sigset_t set;
+
+ ++sigio_block_count;
+ if (sigio_block_count > 1)
+ msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
+ if (sigio_block_count < 1)
+ msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
+
+ if (sigemptyset(&set))
+ msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
+# if defined(USE_SIGIO)
+ if (sigaddset(&set, SIGIO))
+ msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigaddset(&set, SIGPOLL))
+ msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
+# endif
+
+ if (sigprocmask(SIG_BLOCK, &set, NULL))
+ msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
+}
+
+void
+unblock_io_and_alarm(void)
+{
+ sigset_t unset;
+
+ if (sigemptyset(&unset))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
+
+# if defined(USE_SIGIO)
+ if (sigaddset(&unset, SIGIO))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigaddset(&unset, SIGPOLL))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
+# endif
+ if (sigaddset(&unset, SIGALRM))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
+
+ if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
+ msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
+}
+
+void
+unblock_sigio(void)
+{
+ sigset_t unset;
+
+ --sigio_block_count;
+ if (sigio_block_count > 0)
+ msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
+ if (sigio_block_count < 0)
+ msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
+
+ if (sigemptyset(&unset))
+ msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
+
+# if defined(USE_SIGIO)
+ if (sigaddset(&unset, SIGIO))
+ msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigaddset(&unset, SIGPOLL))
+ msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
+# endif
+
+ if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
+ msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
+}
+
+void
+wait_for_signal(void)
+{
+ sigset_t old;
+
+ if (sigprocmask(SIG_UNBLOCK, NULL, &old))
+ msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
+
+# if defined(USE_SIGIO)
+ if (sigdelset(&old, SIGIO))
+ msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
+# endif
+# if defined(USE_SIGPOLL)
+ if (sigdelset(&old, SIGPOLL))
+ msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
+# endif
+ if (sigdelset(&old, SIGALRM))
+ msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
+
+ if (sigsuspend(&old) && (errno != EINTR))
+ msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
+}
+
+# else /* !HAVE_SIGACTION */
+/*
+ * Must be an old bsd system.
+ * We assume there is no SIGPOLL.
+ */
+
+void
+block_io_and_alarm(void)
+{
+ int mask;
+
+ mask = sigmask(SIGIO) | sigmask(SIGALRM);
+ if (sigblock(mask))
+ msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
+}
+
+void
+block_sigio(void)
+{
+ int mask;
+
+ ++sigio_block_count;
+ if (sigio_block_count > 1)
+ msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
+ if (sigio_block_count < 1)
+ msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
+
+ mask = sigmask(SIGIO);
+ if (sigblock(mask))
+ msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
+}
+
+void
+set_signal(void)
+{
+ (void) signal_no_reset(SIGIO, sigio_handler);
+}
+
+void
+unblock_io_and_alarm(void)
+{
+ int mask, omask;
+
+ mask = sigmask(SIGIO) | sigmask(SIGALRM);
+ omask = sigblock(0);
+ omask &= ~mask;
+ (void) sigsetmask(omask);
+}
+
+void
+unblock_sigio(void)
+{
+ int mask, omask;
+
+ --sigio_block_count;
+ if (sigio_block_count > 0)
+ msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
+ if (sigio_block_count < 0)
+ msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
+ mask = sigmask(SIGIO);
+ omask = sigblock(0);
+ omask &= ~mask;
+ (void) sigsetmask(omask);
+}
+
+void
+wait_for_signal(void)
+{
+ int mask, omask;
+
+ mask = sigmask(SIGIO) | sigmask(SIGALRM);
+ omask = sigblock(0);
+ omask &= ~mask;
+ if (sigpause(omask) && (errno != EINTR))
+ msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
+}
+
+# endif /* HAVE_SIGACTION */
+#else
+static int NotAnEmptyCompilationUnit;
+#endif
#include <time.h>
#include <sys\timeb.h>
-#include <conio.h>
#include "ntp_syslog.h"
char * set_tod_using = "SetSystemTime";
* SystemTimeToFileTime()
*/
-#define FILETIME_1970 0x019db1ded53e8000
-const BYTE DWLEN = sizeof(DWORD) * 8; /* number of bits in DWORD */
+#define FILETIME_1970 0x019db1ded53e8000
+#define HECTONANOSECONDS 10000000ui64
+static LONGLONG PerfFrequency = 0;
+static LONGLONG LastTimerCount = 0;
+static ULONGLONG LastTimerTime = 0;
+static CRITICAL_SECTION TimerCritialSection; /* lock for LastTimerCount & LastTimerTime */
+
+
+extern int debug;
int
gettimeofday(
struct timeval *tv
)
{
- FILETIME ft;
- __int64 msec;
-
- GetSystemTimeAsFileTime(&ft); /* 100ns intervals since 1/1/1601 */
- msec = (__int64) ft.dwHighDateTime << DWLEN | ft.dwLowDateTime;
- msec = (msec - FILETIME_1970) / 10;
- tv->tv_sec = (long) (msec / 1000000);
- tv->tv_usec = (long) (msec % 1000000);
+ /* Use the system time (roughly synchronised to the tick, and
+ * extrapolated using the system performance counter.
+ */
+
+ ULONGLONG Count;
+ ULONGLONG Time;
+ LARGE_INTEGER LargeIntNowCount;
+ ULONGLONG NowCount;
+ ULONGLONG TicksElapsed;
+
+ /* Mark a mark ASAP. The latency to here should
+ * be reasonably deterministic
+ */
+ if (!QueryPerformanceCounter(&LargeIntNowCount)) {
+ msyslog(LOG_ERR, "QueryPeformanceCounter failed: %m");
+ exit(1);
+ }
+ NowCount = LargeIntNowCount.QuadPart;
+
+ /* Get base time we are going to extrapolate from
+ */
+ EnterCriticalSection(&TimerCritialSection);
+ {
+ Count = LastTimerCount;
+ Time = LastTimerTime;
+ }
+ LeaveCriticalSection(&TimerCritialSection);
+
+ printf ("Count %I64d\n", Count);
+
+ /* Caclulate when now is.
+ *
+ * Result = LastTimerTime + (NowCount - LastTimerCount) / PerfFrequency
+ */
+ if (NowCount >= Count) {
+ TicksElapsed = NowCount - Count; /* linear progression of ticks */
+ }
+ else {
+ TicksElapsed = NowCount + 1 + ~Count; /* tick counter has wrapped around - I don't think this will ever happen*/
+ }
+
+ /* Calculate the new time (in 100's of nano-seconds)
+ */
+ Time += ((TicksElapsed * HECTONANOSECONDS) / PerfFrequency);
+
+
+ /* Convert the hecto-nano second time to tv format
+ */
+ Time -= FILETIME_1970;
+ tv->tv_sec = (LONG) ( Time / 10000000ui64);
+ tv->tv_usec = (LONG) (( Time % 10000000ui64) / 10);
return 0;
}
+static void CALLBACK
+TimerApcFunction(
+ LPVOID lpArgToCompletionRoutine,
+ DWORD dwTimerLowValue,
+ DWORD dwTimerHighValue
+ )
+{
+ LARGE_INTEGER LargeIntNowCount;
+ ULARGE_INTEGER Time;
+ (void) lpArgToCompletionRoutine; /* not used */
+
+ if (QueryPerformanceCounter(&LargeIntNowCount)) {
+
+ /* Fill in the data
+ */
+ Time.u.LowPart = dwTimerLowValue;
+ Time.u.HighPart = dwTimerHighValue;
+
+ EnterCriticalSection(&TimerCritialSection);
+ {
+ LastTimerCount = LargeIntNowCount.QuadPart;
+ LastTimerTime = Time.QuadPart;
+ }
+ LeaveCriticalSection(&TimerCritialSection);
+ }
+}
+
+
+
+
+static HANDLE ClockThreadHandle = NULL;
+static HANDLE TimerThreadExitRequest = NULL;
+
+DWORD WINAPI ClockThread(void *arg)
+{
+ LARGE_INTEGER DueTime;
+ HANDLE WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL);
+
+ (void) arg; /* not used */
+
+ if (WaitableTimerHandle != NULL) {
+ DueTime.QuadPart = 0i64;
+ if (SetWaitableTimer(WaitableTimerHandle, &DueTime, 10L /* ms */, TimerApcFunction, &WaitableTimerHandle, FALSE) != NO_ERROR) {
+ for(;;) {
+ if (WaitForSingleObjectEx(TimerThreadExitRequest, INFINITE, TRUE) == WAIT_OBJECT_0) {
+ break; /* we've been asked to exit */
+ }
+ }
+ }
+ CloseHandle(WaitableTimerHandle);
+ WaitableTimerHandle = NULL;
+ }
+ return 0;
+}
+
+static void StartClockThread(void)
+{
+ DWORD tid;
+ FILETIME StartTime;
+ LARGE_INTEGER Freq = { 0, 0 };
+
+ /* get the performance counter freq*/
+ if (QueryPerformanceFrequency(&Freq)) {
+ PerfFrequency = Freq.QuadPart;
+ }
+
+ /* init variables with the time now */
+ GetSystemTimeAsFileTime(&StartTime);
+ LastTimerTime = (((ULONGLONG) StartTime.dwHighDateTime) << 32) + (ULONGLONG) StartTime.dwLowDateTime;
+
+ /* init sync objects */
+ InitializeCriticalSection(&TimerCritialSection);
+ TimerThreadExitRequest = CreateEvent(NULL, FALSE, FALSE, NULL);
+ ClockThreadHandle = CreateThread(NULL, 0, ClockThread, NULL, 0, &tid);
+ if (ClockThreadHandle != NULL) {
+ /* remober the thread priority is only within the process class */
+ if (!SetThreadPriority(ClockThreadHandle, THREAD_PRIORITY_TIME_CRITICAL)) {
+ printf("Error setting thread priority\n");
+ }
+ }
+}
+
+static void StopClockThread(void)
+{
+ if (SetEvent(TimerThreadExitRequest) &&
+ WaitForSingleObject(ClockThreadHandle, 10000L) == 0) {
+ CloseHandle(TimerThreadExitRequest);
+ TimerThreadExitRequest = NULL;
+
+ CloseHandle(ClockThreadHandle);
+ ClockThreadHandle = NULL;
+
+ DeleteCriticalSection(&TimerCritialSection);
+ }
+}
+
+typedef void (__cdecl *CRuntimeFunction)(void);
+
+#pragma data_seg(".CRT$XIY")
+ CRuntimeFunction _StartClockThread = StartClockThread;
+#pragma data_seg(".CRT$XTY")
+ CRuntimeFunction _StopClockThread = StopClockThread;
+#pragma data_seg() /* reset */
+
+
int
ntp_set_tod(
struct timeval *tv,
struct tm *gmtm;
long x = tv->tv_sec;
long y = tv->tv_usec;
+ (void) tzp;
gmtm = gmtime((const time_t *) &x);
st.wSecond = (WORD) gmtm->tm_sec;
}
-/*
- * alarming for WinNT - invoke the timer() routine after grabbing the mutex
- */
-extern void timer(void);
-void PASCAL alarming (UINT wTimerID, UINT msg,
- DWORD dwUser, DWORD dw1, DWORD dw2)
-{
- extern int debug;
- static int initializing2 = 1;
- extern HANDLE TimerThreadHandle;
- static DWORD threadID;
-#ifdef DEBUG
- SYSTEMTIME st;
-#endif
-
- /*
- * set the priority for timer() thread to be higher than the main thread
- */
- if (initializing2) {
- TimerThreadHandle = GetCurrentThread();
- if (!SetThreadPriority(TimerThreadHandle, (DWORD) THREAD_PRIORITY_HIGHEST))
- msyslog(LOG_ERR, "SetThreadPriority failed: %m");
- threadID = GetCurrentThreadId();
- initializing2 = 0;
- }
-
-#ifdef DEBUG
- if (debug > 3) {
- GetSystemTime(&st);
- printf("thread %u (timer callback): time %02u:%02u:%02u:%03u\n",
- threadID, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
- fflush(stdout);
- }
-#endif
-
- timer();
-
- UNREFERENCED_PARAMETER(dw1);
- UNREFERENCED_PARAMETER(dw2);
- UNREFERENCED_PARAMETER(dwUser);
- UNREFERENCED_PARAMETER(msg);
- UNREFERENCED_PARAMETER(wTimerID);
-}
#endif /* SYS_WINNT */
#else /* not SYS_WINNT */
int mexit_bs;
#endif /* not SYS_WINNT */
+#ifdef SYS_WINNT
+#include <stdio.h>
+#include <windows.h>
+
+HANDLE hServDoneEvent = NULL;
+
+void
+service_exit(
+ int status
+ )
+{
+ extern int debug;
+
+ if (debug) /* did not become a service, simply exit */
+ ExitThread((DWORD)status);
+ else {
+ /* service mode, need to have the service_main routine
+ * register with the service control manager that the
+ * service has stopped running, before exiting
+ */
+ if ((status > 0) && (hServDoneEvent != NULL))
+ SetEvent(hServDoneEvent);
+ ExitThread((DWORD)status);
+ }
+}
+
+#else /* not SYS_WINNT */
+int mexit_bs;
+#endif /* not SYS_WINNT */
#endif /* SYS_WINNT */
extern char *progname;
-#if defined(__STDC__)
+#if defined(__STDC__) || defined(HAVE_STDARG_H)
void msyslog(int level, const char *fmt, ...)
-#else
+#else /* defined(__STDC__) || defined(HAVE_STDARG_H) */
/*VARARGS*/
void msyslog(va_alist)
va_dcl
-#endif
+#endif /* defined(__STDC__) || defined(HAVE_STDARG_H) */
{
-#ifndef __STDC__
+#if defined(__STDC__) || defined(HAVE_STDARG_H)
+#else
int level;
const char *fmt;
#endif
int olderrno;
char *err;
-#ifdef __STDC__
+#if defined(__STDC__) || defined(HAVE_STDARG_H)
va_start(ap, fmt);
#else
va_start(ap);
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include "ntp_machine.h"
+#include "ntp_fp.h"
+#include "ntp_stdlib.h"
+#include "ntp_syslog.h"
+#include "ntp_io.h"
+#include "recvbuff.h"
+#include "iosignal.h"
+
+extern int debug;
+
+/*
+ * Memory allocation
+ */
+static u_long volatile full_recvbufs; /* number of recvbufs on fulllist */
+static u_long volatile free_recvbufs; /* number of recvbufs on freelist */
+static u_long volatile total_recvbufs; /* total recvbufs currently in use */
+static u_long volatile lowater_adds; /* number of times we have added memory */
+
+static struct recvbuf *volatile freelist; /* free buffers */
+static struct recvbuf *volatile fulllist; /* lifo buffers with data */
+static struct recvbuf *volatile beginlist; /* fifo buffers with data */
+
+#if defined(HAVE_IO_COMPLETION_PORT)
+static HANDLE fulldatabufferevent;
+static CRITICAL_SECTION RecvCritSection;
+# define RECV_BLOCK_IO() EnterCriticalSection(&RecvCritSection)
+# define RECV_UNBLOCK_IO() LeaveCriticalSection(&RecvCritSection)
+#else
+# define RECV_BLOCK_IO()
+# define RECV_UNBLOCK_IO()
+#endif
+
+u_long
+free_recvbuffs (void)
+{
+ return free_recvbufs;
+}
+
+u_long
+full_recvbuffs (void)
+{
+ return free_recvbufs;
+}
+
+u_long
+total_recvbuffs (void)
+{
+ return free_recvbufs;
+}
+
+u_long
+lowater_additions(void)
+{
+ return lowater_adds;
+}
+
+static void
+initialise_buffer(struct recvbuf *buff)
+{
+ memset((char *) buff, 0, sizeof(struct recvbuf));
+
+#if defined HAVE_IO_COMPLETION_PORT
+ buff->iocompletioninfo.overlapped.hEvent = CreateEvent(NULL, FALSE,FALSE, NULL);
+ buff->wsabuff.len = RX_BUFF_SIZE;
+ buff->wsabuff.buf = (char *) buff->recv_buffer;
+#endif
+}
+
+static void
+create_buffers(void)
+{
+ register struct recvbuf *buf;
+ int i;
+ buf = (struct recvbuf *)
+ emalloc(RECV_INC*sizeof(struct recvbuf));
+ for (i = 0; i < RECV_INC; i++)
+ {
+ initialise_buffer(buf);
+ buf->next = (struct recvbuf *) freelist;
+ freelist = buf;
+ buf++;
+ }
+
+ free_recvbufs += RECV_INC;
+ total_recvbufs += RECV_INC;
+ lowater_adds++;
+}
+
+void
+init_recvbuff(int nbufs)
+{
+ register struct recvbuf *buf;
+ int i;
+
+ /*
+ * Init buffer free list and stat counters
+ */
+ freelist = 0;
+
+ buf = (struct recvbuf *)
+ emalloc(nbufs*sizeof(struct recvbuf));
+ for (i = 0; i < nbufs; i++)
+ {
+ initialise_buffer(buf);
+ buf->next = (struct recvbuf *) freelist;
+ freelist = buf;
+ buf++;
+ }
+
+ fulllist = 0;
+ free_recvbufs = total_recvbufs = RECV_INIT;
+ full_recvbufs = lowater_adds = 0;
+
+#if defined(HAVE_IO_COMPLETION_PORT)
+ InitializeCriticalSection(&RecvCritSection);
+ fulldatabufferevent = CreateEvent(NULL, FALSE,FALSE, NULL);
+#endif
+
+}
+
+#if defined(HAVE_IO_COMPLETION_PORT)
+
+/* Return the new full buffer event handle . This handle is
+ * signalled when a recv buffer is placed in the full list.
+ */
+HANDLE
+get_recv_buff_event()
+{
+ return fulldatabufferevent;
+}
+#endif
+
+/*
+ * getrecvbufs - get receive buffers which have data in them
+ *
+ *
+ */
+
+struct recvbuf *
+getrecvbufs(void)
+{
+ struct recvbuf *rb = NULL; /* nothing has arrived */;
+
+ RECV_BLOCK_IO();
+ if (full_recvbufs == 0)
+ {
+#ifdef DEBUG
+ if (debug > 4)
+ printf("getrecvbufs called, no action here\n");
+#endif
+ }
+ else {
+
+ /*
+ * Get the fulllist chain and mark it empty
+ */
+#ifdef DEBUG
+ if (debug > 4)
+ printf("getrecvbufs returning %ld buffers\n", full_recvbufs);
+#endif
+ rb = beginlist;
+ fulllist = 0;
+ full_recvbufs = 0;
+
+ /*
+ * Check to see if we're below the low water mark.
+ */
+ if (free_recvbufs <= RECV_LOWAT)
+ {
+ if (total_recvbufs >= RECV_TOOMANY)
+ msyslog(LOG_ERR, "too many recvbufs allocated (%d)",
+ total_recvbufs);
+ else
+ {
+ create_buffers();
+ }
+ }
+ }
+ RECV_UNBLOCK_IO();
+
+ /*
+ * Return the chain
+ */
+ return rb;
+}
+
+/*
+ * freerecvbuf - make a single recvbuf available for reuse
+ */
+void
+freerecvbuf(
+ struct recvbuf *rb
+ )
+{
+ RECV_BLOCK_IO();
+ BLOCKIO();
+ rb->next = (struct recvbuf *) freelist;
+ freelist = rb;
+ free_recvbufs++;
+ UNBLOCKIO();
+ RECV_UNBLOCK_IO();
+}
+
+
+void
+add_full_recv_buffer(
+ struct recvbuf *rb
+ )
+{
+ RECV_BLOCK_IO();
+ if (full_recvbufs == 0)
+ {
+ beginlist = rb;
+ rb->next = 0;
+ }
+ else
+ {
+ rb->next = fulllist->next;
+ fulllist->next = rb;
+ }
+ fulllist = rb;
+ full_recvbufs++;
+
+#if defined(HAVE_IO_COMPLETION_PORT)
+ if (!SetEvent(fulldatabufferevent)) {
+ msyslog(LOG_ERR, "Can't set receive buffer event");
+ }
+#endif
+ RECV_UNBLOCK_IO();
+}
+
+struct recvbuf *
+get_free_recv_buffer(void)
+{
+ struct recvbuf * buffer = NULL;
+ RECV_BLOCK_IO();
+ if (free_recvbufs <= RECV_LOWAT)
+ {
+ if (total_recvbufs >= RECV_TOOMANY) {
+ msyslog(LOG_ERR, "too many recvbufs allocated (%d)",
+ total_recvbufs);
+ }
+ else
+ {
+ create_buffers();
+ }
+ }
+
+ if (free_recvbufs > 0)
+ {
+ buffer = freelist;
+ freelist = buffer->next;
+ buffer->next = NULL;
+ --free_recvbufs;
+ }
+
+ RECV_UNBLOCK_IO();
+ return buffer;
+}
+
+struct recvbuf *
+get_full_recv_buffer(void)
+{
+ struct recvbuf * buffer = NULL;
+ RECV_BLOCK_IO();
+ if (full_recvbufs > 0) {
+ --full_recvbufs;
+ buffer = beginlist;
+ beginlist = buffer->next;
+ buffer->next = NULL;
+ }
+ RECV_UNBLOCK_IO();
+ return buffer;
+}
/*
* Handcraft the bits
*/
- pst = CTL_PEER_STATVAL(st);
+ pst = (u_char) CTL_PEER_STATVAL(st);
if (!(pst & CTL_PST_REACH)) {
(void)strcpy(cb, "unreach");
} else {
void
signal_no_reset(
-#ifdef __STDC__
+#if defined(__STDC__) || defined(HAVE_STDARG_H)
int sig,
void (*func) (int)
#else
sig, func
#endif
)
-#ifdef __STDC__
+#if defined(__STDC__) || defined(HAVE_STDARG_H)
#else
int sig;
void (*func) P((int));
#include "ntp_syslog.h"
#include "ntp_unixtime.h"
#include "ntp_stdlib.h"
+#if defined SYS_WINNT
+#include "ntp_timer.h"
+#endif
#if defined SCO5_CLOCK
int sco5_oldclock; /* runtime detection of new clock */
* rounding wiggles, which may overflow the fraction.
*/
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETCLOCK)
-#ifdef HAVE_CLOCK_GETTIME
+# ifdef HAVE_CLOCK_GETTIME
(void) clock_gettime(CLOCK_REALTIME, &ts);
-#else
+# else
(void) getclock(TIMEOFDAY, &ts);
-#endif
+# endif
now->l_i = ts.tv_sec + JAN_1970;
dtemp = ts.tv_nsec * FRAC / 1e9;
if (dtemp >= FRAC)
now->l_i++;
now->l_uf = (u_int32)dtemp;
#endif /* HAVE_CLOCK_GETTIME */
+
}
/*
* we honk to the log. If the previous adjustment did not complete,
* we correct the residual offset.
*/
- if (
#if !defined (SYS_WINNT) && !defined (SYS_CYGWIN32)
/* casey - we need a posix type thang here */
- (adjtime(&adjtv, &oadjtv) < 0)
+ if (adjtime(&adjtv, &oadjtv) < 0)
#else
- (!SetSystemTimeAdjustment(dwTimeAdjustment, FALSE))
+ if (debug) {
+ printf("SetSystemTimeAdjustment( %ld)\n", dwTimeAdjustment);
+ }
+ if (!SetSystemTimeAdjustment(dwTimeAdjustment, FALSE))
#endif /* SYS_WINNT */
- ) {
+ {
msyslog(LOG_ERR, "Can't adjust time: %m");
return 0;
- } else {
+ }
+ else {
#if !defined (SYS_WINNT) && !defined (SYS_CYGWIN32)
sys_residual += oadjtv.tv_usec / 1e6;
#endif /* SYS_WINNT */
#include <sys/types.h>
#include <sys/time.h>
-#include <sys/errno.h>
+#include <errno.h>
#include "ntp_fp.h"
#include "ntp_unixtime.h"
#include <sys/types.h>
#include <sys/time.h>
-#include <sys/errno.h>
+#include <errno.h>
#include "ntp_fp.h"
#include "ntp_unixtime.h"
#include "ntp_calendar.h"
* fill in the fields. We assume rpkt.sequence and rpkt.associd
* have already been filled in.
*/
- rpkt.r_m_e_op = CTL_RESPONSE|CTL_ERROR|(res_opcode & CTL_OP_MASK);
+ rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode & CTL_OP_MASK));
rpkt.status = htons((u_short) ((errcode<<8) & 0xff00));
rpkt.count = 0;
/*
* Fill in the packet with the current info
*/
- rpkt.r_m_e_op = CTL_RESPONSE|more|(res_opcode & CTL_OP_MASK);
+ rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode & CTL_OP_MASK));
rpkt.count = htons((u_short) dlen);
rpkt.offset = htons( (u_short) res_offset);
if (res_async) {
*/
doconfigure(1);
if (confentries == NULL)
+#if defined SYS_WINNT
+ ExitThread(0); /* Don't want to kill whole NT process */
+#else
exit(0); /* done that quick */
+#endif
/*
* Here we've got some problem children. Set up the timer
# include <config.h>
#endif
+/* Modified by Sven 7/14/99 322pm */
#include <stdio.h>
#include <signal.h>
#include "ntpd.h"
#include "ntp_select.h"
#include "ntp_io.h"
+#include "iosignal.h"
#include "ntp_refclock.h"
#include "ntp_if.h"
#include "ntp_stdlib.h"
#define IFF_BROADCAST IFR$M_IFF_BROADCAST
#define IFF_LOOPBACK IFR$M_IFF_LOOPBACK
+#endif /* VMS */
+
+
+#if defined(VMS) || defined(SYS_WINNT)
/* structure used in SIOCGIFCONF request (after [KSR] OSF/1) */
struct ifconf {
int ifc_len; /* size of buffer */
* better to drop a packet than to be inaccurate.
*/
-/*
- * Block the interrupt, for critical sections.
- */
-#if defined(HAVE_SIGNALED_IO)
-static int sigio_block_count = 0;
-# define BLOCKIO() ((void) block_sigio())
-# define UNBLOCKIO() ((void) unblock_sigio())
-#else
-# define BLOCKIO()
-# define UNBLOCKIO()
-#endif
-
-/*
- * recvbuf memory management
- */
-#define RECV_INIT 10 /* 10 buffers initially */
-#define RECV_LOWAT 3 /* when we're down to three buffers get more */
-#define RECV_INC 5 /* get 5 more at a time */
-#define RECV_TOOMANY 40 /* this is way too many buffers */
-
-/*
- * Memory allocation
- */
-volatile u_long full_recvbufs; /* number of recvbufs on fulllist */
-volatile u_long free_recvbufs; /* number of recvbufs on freelist */
-
-static struct recvbuf *volatile freelist; /* free buffers */
-static struct recvbuf *volatile fulllist; /* lifo buffers with data */
-static struct recvbuf *volatile beginlist; /* fifo buffers with data */
-
-u_long total_recvbufs; /* total recvbufs currently in use */
-u_long lowater_additions; /* number of times we have added memory */
-
-static struct recvbuf initial_bufs[RECV_INIT]; /* initial allocation */
-
/*
* Other statistics of possible interest
static void close_socket P((int));
static void close_file P((int));
static char * fdbits P((int, fd_set *));
-#ifdef HAVE_SIGNALED_IO
-static int init_clock_sig P((struct refclockio *));
-static void init_socket_sig P((int));
-static RETSIGTYPE sigio_handler P((int));
-static void block_sigio P((void));
-static void unblock_sigio P((void));
-static void set_signal P((void));
-#endif /* HAVE_SIGNALED_IO */
/*
* init_io - initialize I/O data structures and call socket creation routine
void
init_io(void)
{
- register int i;
-
#ifdef SYS_WINNT
WORD wVersionRequested;
WSADATA wsaData;
+ init_transmitbuff();
#endif /* SYS_WINNT */
/*
* Init buffer free list and stat counters
*/
- freelist = 0;
- for (i = 0; i < RECV_INIT; i++)
- {
- initial_bufs[i].next = (struct recvbuf *) freelist;
- freelist = &initial_bufs[i];
- }
+ init_recvbuff(RECV_INIT);
- fulllist = 0;
- free_recvbufs = total_recvbufs = RECV_INIT;
- full_recvbufs = lowater_additions = 0;
packets_dropped = packets_received = 0;
packets_ignored = 0;
packets_sent = packets_notsent = 0;
# endif /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
i = 1;
-
+# if !defined(SYS_WINNT)
ifc.ifc_len = sizeof(buf);
+# endif
# ifdef STREAMS_TLI
ioc.ic_cmd = SIOCGIFCONF;
ioc.ic_timout = 0;
ifc.ifc_buf = buf;
# ifndef SYS_WINNT
if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0)
- {
- msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFCONF) failed: %m - exiting");
- exit(1);
- }
# else
- if (get_winnt_interfaces(&ifc) < 0)
- {
- msyslog(LOG_ERR, "create_sockets: get_winnt_interfaces() failed: %m - exiting");
- exit(1);
- }
+ if (WSAIoctl(vs, SIO_GET_INTERFACE_LIST, 0, 0, ifc.ifc_buf, ifc.ifc_len, &ifc.ifc_len, 0, 0) == SOCKET_ERROR)
# endif /* SYS_WINNT */
+{
+ msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFCONF) failed: %m - exiting");
+ exit(1);
+}
# endif /* not STREAMS_TLI */
# endif
n -= size;
-
+# if !defined(SYS_WINNT)
/* Exclude logical interfaces (indicated by ':' in the interface name) */
if (strchr(ifr->ifr_name, (int)':') != NULL) {
continue;
}
if
-# ifdef VMS /* VMS+UCX */
+# ifdef VMS /* VMS+UCX */
(((struct sockaddr *)&(ifr->ifr_addr))->sa_family != AF_INET)
-# else
+# else
(ifr->ifr_addr.sa_family != AF_INET)
-# endif /* VMS+UCX */
+# endif /* VMS+UCX */
continue;
+# endif /* SYS_WINNT */
ifreq = *ifr;
inter_list[i].flags = 0;
/* is it broadcast capable? */
# endif /* not STREAMS_TLI */
# endif /* not SYS_WINNT */
#endif /* 0 */
-
- (void)strncpy(inter_list[i].name, ifreq.ifr_name,
- sizeof(inter_list[i].name));
+# if defined(SYS_WINNT)
+ {int TODO_FillInTheNameWithSomeThingReasonble;}
+# else
+ (void)strncpy(inter_list[i].name, ifreq.ifr_name,
+ sizeof(inter_list[i].name));
+# endif
inter_list[i].sin = *(struct sockaddr_in *)&ifr->ifr_addr;
inter_list[i].sin.sin_family = AF_INET;
inter_list[i].sin.sin_port = port;
}
# endif /* not STREAMS_TLI */
inter_list[i].mask = *(struct sockaddr_in *)&ifreq.ifr_addr;
-#else
+# else
/* winnt here */
- inter_list[i].bcast = *(struct sockaddr_in *)&ifreq.ifr_broadaddr;
+ inter_list[i].bcast = ifreq.ifr_broadaddr;
inter_list[i].bcast.sin_family = AF_INET;
inter_list[i].bcast.sin_port = port;
- inter_list[i].mask.sin_addr.s_addr = inet_addr(ifreq.ifr_mask);
+ inter_list[i].mask = ifreq.ifr_mask;
# endif /* not SYS_WINNT */
/*
inet_ntoa((inter_list[i].mask.sin_addr)));
}
}
+#endif
+#if defined (HAVE_IO_COMPLETION_PORT)
+
+ for (i = 0; i < ninterfaces; i++)
+ {
+ io_completion_port_add_socket(&inter_list[i]);
+ }
#endif
return ninterfaces;
}
-
/*
* io_setbclient - open the broadcast client sockets
*/
}
-/* XXX ELIMINATE getrecvbufs (almost) identical to ntpdate.c, ntptrace.c, ntp_io.c */
-/*
- * getrecvbufs - get receive buffers which have data in them
- *
- * ***N.B. must be called with SIGIO blocked***
- */
-struct recvbuf *
-getrecvbufs(void)
-{
- struct recvbuf *rb;
-
-#ifdef DEBUG
- if (debug > 4)
- printf("getrecvbufs: %ld handler interrupts, %ld frames\n",
- handler_calls, handler_pkts);
-#endif
-
- if (full_recvbufs == 0)
- {
-#ifdef DEBUG
- if (debug > 4)
- printf("getrecvbufs called, no action here\n");
-#endif
- return (struct recvbuf *)0; /* nothing has arrived */
- }
-
- /*
- * Get the fulllist chain and mark it empty
- */
-#ifdef DEBUG
- if (debug > 4)
- printf("getrecvbufs returning %ld buffers\n", full_recvbufs);
-#endif
- rb = (struct recvbuf *) beginlist;
- fulllist = 0;
- full_recvbufs = 0;
-
- /*
- * Check to see if we're below the low water mark.
- */
- if (free_recvbufs <= RECV_LOWAT)
- {
- register struct recvbuf *buf;
- register int i;
-
- if (total_recvbufs >= RECV_TOOMANY)
- msyslog(LOG_ERR, "too many recvbufs allocated (%ld)",
- total_recvbufs);
- else
- {
- buf = (struct recvbuf *)
- emalloc(RECV_INC*sizeof(struct recvbuf));
- for (i = 0; i < RECV_INC; i++)
- {
- buf->next = (struct recvbuf *) freelist;
- freelist = buf;
- buf++;
- }
-
- free_recvbufs += RECV_INC;
- total_recvbufs += RECV_INC;
- lowater_additions++;
- }
- }
-
- /*
- * Return the chain
- */
- return rb;
-}
-
-
-/* XXX ELIMINATE freerecvbuf (almost) identical to ntpdate.c, ntptrace.c, ntp_io.c */
-/*
- * freerecvbuf - make a single recvbuf available for reuse
- */
-void
-freerecvbuf(
- struct recvbuf *rb
- )
-{
- BLOCKIO();
- rb->next = (struct recvbuf *) freelist;
- freelist = rb;
- free_recvbufs++;
- UNBLOCKIO();
-}
-
-
/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
/*
* sendpkt - send a packet to the specified destination. Maintain a
badaddrs[slot].addr.s_addr == dest->sin_addr.s_addr)
break;
+#if defined(HAVE_IO_COMPLETION_PORT)
+ err = io_completion_port_sendto(inter, pkt, len, dest);
+ if (err != ERROR_SUCCESS)
+#else
cc = sendto(inter->fd, (char *)pkt, len, 0, (struct sockaddr *)dest,
sizeof(struct sockaddr_in));
if (cc == -1)
+#endif
{
inter->notsent++;
packets_notsent++;
-#ifndef SYS_WINNT
- if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
-#else
- err = WSAGetLastError();
+#if defined(HAVE_IO_COMPLETION_PORT)
if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0)
-#endif /* SYS_WINNT */
+#else
+ if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
+#endif
{
/*
* Remember this, if there's an empty slot
}
}
+#if !defined(HAVE_IO_COMPLETION_PORT)
/*
* fdbits - generate ascii representation of fd_set (FAU debug support)
* HFDF format - highest fd first.
return buffer;
}
-
/*
* input_handler - receive packets asynchronously
*/
-void
+extern void
input_handler(
l_fp *cts
)
if (FD_ISSET(fd, &fds))
{
n--;
- if (free_recvbufs == 0)
+ if (free_recvbuffs() == 0)
{
char buf[RX_BUFF_SIZE];
goto select_again;
}
- rb = (struct recvbuf *) freelist;
- freelist = rb->next;
- free_recvbufs--;
+ rb = get_free_recv_buffer();
i = (rp->datalen == 0
|| rp->datalen > sizeof(rb->recv_space))
if (rb->recv_length == -1)
{
msyslog(LOG_ERR, "clock read fd %d: %m", fd);
- rb->next = (struct recvbuf *) freelist;
- freelist = rb;
- free_recvbufs++;
+ freerecvbuf(rb);
goto select_again;
}
* data was consumed - nothing to pass up
* into block input machine
*/
- rb->next = (struct recvbuf *) freelist;
- freelist = rb;
- free_recvbufs++;
+ freerecvbuf(rb);
#if 1
goto select_again;
#else
}
}
- if (fulllist == 0)
- {
- beginlist = rb;
- rb->next = 0;
- }
- else
- {
- rb->next = fulllist->next;
- fulllist->next = rb;
- }
- fulllist = rb;
- full_recvbufs++;
+ add_full_recv_buffer(rb);
rp->recvcount++;
packets_received++;
* these guys manage to put properly addressed
* packets into the wildcard queue
*/
- (free_recvbufs == 0)
+ (free_recvbuffs() == 0)
#else
- ((i == 0) || (free_recvbufs == 0))
+ ((i == 0) || (free_recvbuffs() == 0))
#endif
)
{
if (debug)
printf("%s on %d(%lu) fd=%d from %s\n",
(i) ? "drop" : "ignore",
- i, free_recvbufs, fd,
+ i, free_recvbuffs(), fd,
inet_ntoa(((struct sockaddr_in *) &from)->sin_addr));
#endif
if (i == 0)
goto select_again;
}
- rb = (struct recvbuf *) freelist;
+ rb = get_free_recv_buffer();
fromlen = sizeof(struct sockaddr_in);
rb->recv_length = recvfrom(fd,
sizeof(rb->recv_space), 0,
(struct sockaddr *)&rb->recv_srcadr,
&fromlen);
- if (rb->recv_length > 0)
- {
- freelist = rb->next;
- free_recvbufs--;
- }
- else if (rb->recv_length == 0
+ if (rb->recv_length == 0
#ifdef EWOULDBLOCK
|| errno==EWOULDBLOCK
#endif
#ifdef EAGAIN
|| errno==EAGAIN
#endif
- )
+ ) {
+ freerecvbuf(rb);
continue;
- else
+ }
+ else if (rb->recv_length < 0)
{
msyslog(LOG_ERR, "recvfrom() fd=%d: %m", fd);
#ifdef DEBUG
if (debug)
printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd);
#endif
+ freerecvbuf(rb);
continue;
}
#ifdef DEBUG
rb->recv_time = ts;
rb->receiver = receive;
- if (fulllist == 0)
- {
- beginlist = rb;
- rb->next = 0;
- }
- else
- {
- rb->next = fulllist->next;
- fulllist->next = rb;
- }
- fulllist = rb;
- full_recvbufs++;
-
+ add_full_recv_buffer(rb);
+
inter_list[i].received++;
packets_received++;
goto select_again;
return;
}
+#endif
+
/*
* findinterface - utility used by other modules to find an interface
* given an address.
UNBLOCKIO();
return 0;
}
+# elif defined(HAVE_IO_COMPLETION_PORT)
+ if (io_completion_port_add_clock_io(rio))
+ {
+ refio = rio->next;
+ UNBLOCKIO();
+ return 0;
+ }
# endif
if (rio->fd > maxactivefd)
}
#endif /* REFCLOCK */
-/*
- * SIGPOLL and SIGIO ROUTINES.
- */
-#ifdef HAVE_SIGNALED_IO
-/*
- * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
- * a few have separate SIGIO and SIGPOLL signals. This code checks for the
- * SIGIO == SIGPOLL case at compile time.
- * Do not defined USE_SIGPOLL or USE_SIGIO.
- * these are interal only to ntp_io.c!
- */
-# if defined(USE_SIGPOLL)
-# undef USE_SIGPOLL
-# endif
-# if defined(USE_SIGIO)
-# undef USE_SIGIO
-# endif
-
-# if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
-# define USE_SIGPOLL
-# endif
-
-# if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
-# define USE_SIGIO
-# endif
-
-# if defined(USE_SIGIO) && defined(USE_SIGPOLL)
-# if SIGIO == SIGPOLL
-# define USE_SIGIO
-# undef USE_SIGPOLL
-# endif /* SIGIO == SIGPOLL */
-# endif /* USE_SIGIO && USE_SIGIO */
-
-
-/*
- * TTY initialization routines.
- */
-static int
-init_clock_sig(
- struct refclockio *rio
- )
-{
-# ifdef USE_TTY_SIGPOLL
- {
- /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
- if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
- {
- msyslog(LOG_ERR,
- "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
- return 1;
- }
- return 0;
- }
-# else
- /*
- * Special cases first!
- */
- /* Was: defined(SYS_HPUX) */
-# if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
-#define CLOCK_DONE
- {
- int pgrp, on = 1;
-
- /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
- pgrp = getpid();
- if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
- {
- msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m");
- exit(1);
- /*NOTREACHED*/
- }
-
- /*
- * set non-blocking, async I/O on the descriptor
- */
- if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
- {
- msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m");
- exit(1);
- /*NOTREACHED*/
- }
-
- if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
- {
- msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m");
- exit(1);
- /*NOTREACHED*/
- }
- return 0;
- }
-# endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
- /* Was: defined(SYS_AIX) && !defined(_BSD) */
-# if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
- /*
- * SYSV compatibility mode under AIX.
- */
-#define CLOCK_DONE
- {
- int pgrp, on = 1;
-
- /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
- if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
- {
- msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
- return 1;
- }
- pgrp = -getpid();
- if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
- {
- msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
- return 1;
- }
-
- if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
- {
- msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
- return 1;
- }
- return 0;
- }
-# endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
-# ifndef CLOCK_DONE
- {
- /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
-# if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
- /*
- * there are, however, always exceptions to the rules
- * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
- * CTTYs. SunOS and HPUX do not semm to have this restriction.
- * another question is: how can you do multiple SIGIO from several
- * ttys (as they all should be CTTYs), wondering...
- *
- * kd 95-07-16
- */
- if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
- {
- msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
- return 1;
- }
-# endif /* TIOCSCTTY && USE_FSETOWNCTTY */
-
- if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
- {
- msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
- return 1;
- }
-
- if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
- {
- msyslog(LOG_ERR,
- "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
- return 1;
- }
- return 0;
- }
-# endif /* CLOCK_DONE */
-# endif /* !USE_TTY_SIGPOLL */
-}
-
-
-
-static void
-init_socket_sig(
- int fd
- )
-{
-# ifdef USE_UDP_SIGPOLL
- {
- if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
- {
- msyslog(LOG_ERR,
- "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
- exit(1);
- }
- }
-# else /* USE_UDP_SIGPOLL */
- {
- int pgrp;
-# ifdef FIOASYNC
- int on = 1;
-# endif
-
-# if defined(FIOASYNC)
- if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
- {
- msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m");
- exit(1);
- /*NOTREACHED*/
- }
-# elif defined(FASYNC)
- {
- int flags;
-
- if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
- {
- msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m");
- exit(1);
- /*NOTREACHED*/
- }
- if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
- {
- msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m");
- exit(1);
- /*NOTREACHED*/
- }
- }
-# else
-# include "Bletch: Need asynchronous I/O!"
-# endif
-
-# ifdef UDP_BACKWARDS_SETOWN
- pgrp = -getpid();
-# else
- pgrp = getpid();
-# endif
-
-# if defined(SIOCSPGRP)
- if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
- {
- msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m");
- exit(1);
- /*NOTREACHED*/
- }
-# elif defined(FIOSETOWN)
- if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
- {
- msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m");
- exit(1);
- /*NOTREACHED*/
- }
-# elif defined(F_SETOWN)
- if (fcntl(fd, F_SETOWN, pgrp) == -1)
- {
- msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m");
- exit(1);
- /*NOTREACHED*/
- }
-# else
-# include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
-# endif
- }
-# endif /* USE_UDP_SIGPOLL */
-}
-
-
-static RETSIGTYPE
-sigio_handler(
- int sig
- )
-{
- int saved_errno = errno;
- l_fp ts;
-
- get_systime(&ts);
- (void)input_handler(&ts);
- errno = saved_errno;
-}
-
-/*
- * Signal support routines.
- */
-# ifdef HAVE_SIGACTION
-static void
-set_signal(void)
-{
-# ifdef USE_SIGIO
- (void) signal_no_reset(SIGIO, sigio_handler);
-# endif
-# ifdef USE_SIGPOLL
- (void) signal_no_reset(SIGPOLL, sigio_handler);
-# endif
-}
-
-void
-block_io_and_alarm(void)
-{
- sigset_t set;
-
- if (sigemptyset(&set))
- msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
-# if defined(USE_SIGIO)
- if (sigaddset(&set, SIGIO))
- msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
-# endif
-# if defined(USE_SIGPOLL)
- if (sigaddset(&set, SIGPOLL))
- msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
-# endif
- if (sigaddset(&set, SIGALRM))
- msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
-
- if (sigprocmask(SIG_BLOCK, &set, NULL))
- msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
-}
-
-static void
-block_sigio(void)
-{
- sigset_t set;
-
- ++sigio_block_count;
- if (sigio_block_count > 1)
- msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
- if (sigio_block_count < 1)
- msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
-
- if (sigemptyset(&set))
- msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
-# if defined(USE_SIGIO)
- if (sigaddset(&set, SIGIO))
- msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
-# endif
-# if defined(USE_SIGPOLL)
- if (sigaddset(&set, SIGPOLL))
- msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
-# endif
-
- if (sigprocmask(SIG_BLOCK, &set, NULL))
- msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
-}
-
-void
-unblock_io_and_alarm(void)
-{
- sigset_t unset;
-
- if (sigemptyset(&unset))
- msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
-
-# if defined(USE_SIGIO)
- if (sigaddset(&unset, SIGIO))
- msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
-# endif
-# if defined(USE_SIGPOLL)
- if (sigaddset(&unset, SIGPOLL))
- msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
-# endif
- if (sigaddset(&unset, SIGALRM))
- msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
-
- if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
- msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
-}
-
-static
-void
-unblock_sigio(void)
-{
- sigset_t unset;
-
- --sigio_block_count;
- if (sigio_block_count > 0)
- msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
- if (sigio_block_count < 0)
- msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
-
- if (sigemptyset(&unset))
- msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
-
-# if defined(USE_SIGIO)
- if (sigaddset(&unset, SIGIO))
- msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
-# endif
-# if defined(USE_SIGPOLL)
- if (sigaddset(&unset, SIGPOLL))
- msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
-# endif
-
- if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
- msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
-}
-
-void
-wait_for_signal(void)
-{
- sigset_t old;
-
- if (sigprocmask(SIG_UNBLOCK, NULL, &old))
- msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
-
-# if defined(USE_SIGIO)
- if (sigdelset(&old, SIGIO))
- msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
-# endif
-# if defined(USE_SIGPOLL)
- if (sigdelset(&old, SIGPOLL))
- msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
-# endif
- if (sigdelset(&old, SIGALRM))
- msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
-
- if (sigsuspend(&old) && (errno != EINTR))
- msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
-}
-
-# else /* !HAVE_SIGACTION */
-/*
- * Must be an old bsd system.
- * We assume there is no SIGPOLL.
- */
-
-void
-block_io_and_alarm(void)
-{
- int mask;
-
- mask = sigmask(SIGIO) | sigmask(SIGALRM);
- if (sigblock(mask))
- msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
-}
-
-static void
-block_sigio(void)
-{
- int mask;
-
- ++sigio_block_count;
- if (sigio_block_count > 1)
- msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
- if (sigio_block_count < 1)
- msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
-
- mask = sigmask(SIGIO);
- if (sigblock(mask))
- msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
-}
-
-static void
-set_signal(void)
-{
- (void) signal_no_reset(SIGIO, sigio_handler);
-}
-
-void
-unblock_io_and_alarm(void)
-{
- int mask, omask;
-
- mask = sigmask(SIGIO) | sigmask(SIGALRM);
- omask = sigblock(0);
- omask &= ~mask;
- (void) sigsetmask(omask);
-}
-
-static void
-unblock_sigio(void)
-{
- int mask, omask;
-
- --sigio_block_count;
- if (sigio_block_count > 0)
- msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
- if (sigio_block_count < 0)
- msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
- mask = sigmask(SIGIO);
- omask = sigblock(0);
- omask &= ~mask;
- (void) sigsetmask(omask);
-}
-
-void
-wait_for_signal(void)
-{
- int mask, omask;
-
- mask = sigmask(SIGIO) | sigmask(SIGALRM);
- omask = sigblock(0);
- omask &= ~mask;
- if (sigpause(omask) && (errno != EINTR))
- msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
-}
-# endif /* HAVE_SIGACTION */
-#endif /* HAVE_SIGNALED_IO */
-
void
kill_asyncio(void)
{
for (i = 0; i <= maxactivefd; i++)
(void)close_socket(i);
}
-
-#ifdef SYS_WINNT
-/* ------------------------------------------------------------------------------------------------------------------ */
-/* modified with suggestions from Kevin Dunlap so we only pick out netcards bound to tcpip */
-
-int
-get_winnt_interfaces(
- struct ifconf *ifc
- )
-{
- char *ifc_buffer = ifc->ifc_buf;
-
- struct ifreq *ifr;
- int maxsize = sizeof(ifc_buffer);
- HKEY hk, hksub; /* registry key handle */
- BOOL bSuccess;
- char newkey[200];
-
- char servicename[50];
- DWORD sizeofservicename = 50;
- int Done = 0;
-
- /*
- * these need to be big as they are multi_sz in type and hold all
- * ip addresses and subnet mask for a given interface
- */
- char IpAddresses[10000];
- char *ipptr = IpAddresses;
- DWORD sizeofipaddresses = 10000;
- char SubNetMasks[10000];
- char *subptr = SubNetMasks;
- DWORD sizeofsubnetmasks = 10000;
- char bindservicenames[1000];
- DWORD sizeofbindnames = 1000;
- DWORD enableDhcp;
- DWORD sizeofenable = sizeof(DWORD);
- char *ipkeyname;
- char *maskkeyname;
- long ip, broad;
-
- char oneIpAddress[16];
- char oneSubNetMask[16];
- int count = 0;
- char *onenetcard;
-
- /* now get all the netcard values which are bound to tcpip */
-
- strcpy(newkey,"SYSTEM\\Currentcontrolset\\Services\\");
- strcat(newkey,"tcpip\\linkage");
-
- bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,newkey,&hk);
- if(bSuccess != ERROR_SUCCESS)
- {
- msyslog(LOG_ERR, "failed to Open TCP/IP Linkage Registry key: %m");
-#ifdef DEBUG
- if (debug)
- printf("Cannot get TCP/IP Linkage from registery.\n");
-#endif
- return -1;
- }
-
- /* now get the bind value */
- sizeofbindnames = 1000;
- bSuccess = RegQueryValueEx(hk, /* subkey handle */
- "Bind", /* value name */
- NULL, /* must be zero */
- NULL, /* value type not required */
- (LPBYTE) &bindservicenames, /* address of value data */
- &sizeofbindnames); /* length of value data */
- if(bSuccess != ERROR_SUCCESS)
- {
- msyslog(LOG_ERR, "Error in RegQueryValueEx fetching Bind Service names parameter: %m");
- RegCloseKey(hk);
- return -1;
- }
-
- /* now loop through and get all the values which are bound to tcpip */
- /* we can also close the key here as we have the values now */
- RegCloseKey(hk);
- onenetcard = bindservicenames;
- while(1)
- {
- onenetcard = onenetcard + 8; /* skip /Device/ prefix on the service name */
- if ((onenetcard < (bindservicenames + sizeofbindnames)) &&
- (sscanf(onenetcard,"%s",servicename) != EOF))
- {
- onenetcard+= strlen(servicename) + 1;
- }
- else { /* no more */
- break;
- }
-
- /*
- * skip services that are NDISWAN... since these are temporary
- * interfaces like ras and if we bind to these we would have to
- * check if the socket is still ok everytime before using it as
- * when the link goes down and comes back up the socket is no
- * longer any good... and the server eventually crashes if we
- * don't check this.. and to check it entails a lot of overhead...
- * shouldn't be a problem with machines with only a RAS
- * interface anyway as we can bind to the loopback or 0.0.0.0
- */
-
- if ((strlen(servicename) >= 7) && (strncmp(strupr(servicename),"NDISWAN",7) == 0))
- {
- /* skip it */
-#ifdef DEBUG
- if (debug)
- printf("Skipping temporary interface [%s]\n",servicename);
-#endif
- }
- else {
- /* if opening this key fails we can assume it is not a network card ie digiboard and go on.. */
- /* ok now that we have the service name parameter close the key and go get the ipaddress and subnet mask */
-
- strcpy(newkey,"SYSTEM\\Currentcontrolset\\Services\\");
- strcat(newkey,servicename);
- strcat(newkey,"\\parameters\\tcpip");
-
- bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,newkey,&hksub);
- if(bSuccess != ERROR_SUCCESS)
- {
-#ifdef DEBUG
- if (debug)
- printf("Skipping interface [%s] ... It is not a network card.\n",servicename);
-#endif
- }
- else
- { /* ok it is a network card */
- /* check for DHCP */
- sizeofenable = sizeof(DWORD);
- bSuccess =
- RegQueryValueEx(hksub, /* subkey handle */
- "EnableDHCP", /* value name */
- NULL, /* must be zero */
- NULL, /* value type not required */
- (LPBYTE)&enableDhcp, /* address of value data */
- &sizeofenable); /* length of value data */
- if(bSuccess != ERROR_SUCCESS)
- {
- msyslog(LOG_ERR, "Error in RegQueryValueEx fetching EnableDHCP parameter: %m");
- RegCloseKey(hksub);
- return -1;
- }
-
- if (enableDhcp) {
- ipkeyname = "DhcpIpAddress";
- maskkeyname = "DhcpSubNetMask";
- }
- else {
- ipkeyname = "IpAddress";
- maskkeyname = "SubNetMask";
- }
- /* ok now get the ipaddress */
- sizeofipaddresses = 10000;
- bSuccess =
- RegQueryValueEx(hksub, /* subkey handle */
- ipkeyname, /* value name */
- NULL, /* must be zero */
- NULL, /* value type not required */
- (LPBYTE)&IpAddresses, /* address of value data */
- &sizeofipaddresses); /* length of value data */
- if(bSuccess != ERROR_SUCCESS)
- {
- msyslog(LOG_ERR, "Error in RegQueryValueEx fetching IpAddress parameter: %m");
- RegCloseKey(hksub);
- return -1;
- }
-
- /* ok now get the subnetmask */
- sizeofsubnetmasks = 10000;
- bSuccess =
- RegQueryValueEx(hksub, /* subkey handle */
- maskkeyname, /* value name */
- NULL, /* must be zero */
- NULL, /* value type not required */
- (LPBYTE)&SubNetMasks, /* address of value data */
- &sizeofsubnetmasks); /* length of value data */
- if(bSuccess != ERROR_SUCCESS)
- {
- msyslog(LOG_ERR, "Error in RegQueryValueEx fetching SubNetMask parameter: %m");
- RegCloseKey(hksub);
- return -1;
- }
-
- RegCloseKey(hksub);
- /* ok now that we have some addresses and subnet masks go through each one and add to our structure... */
- /* multi_sz strings are terminated by two \0 in a row */
- /* however, the dhcp strings are not multi_sz, they are just plain strings */
-
- ipptr = IpAddresses;
- subptr = SubNetMasks;
- Done = 0;
- while (!Done)
- {
- if (sscanf(ipptr,"%s",oneIpAddress) != EOF)
- ipptr+= strlen(oneIpAddress) + 1; /* add one for terminator \0 */
- else Done = 1;
-
- if (sscanf(subptr,"%s",oneSubNetMask) != EOF)
- subptr += strlen(oneSubNetMask) + 1;
- else Done = 1;
-
- /* now add to interface structure */
- if (!Done)
- {
- ifr = (struct ifreq *)ifc_buffer;
- ip = inet_addr(oneIpAddress);
- broad = ~inet_addr(oneSubNetMask) | ip;
- ifr->ifr_addr.sa_family = AF_INET;
- ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr = ip;
- ifr->ifr_broadaddr.sa_family = AF_INET;
- ((struct sockaddr_in *)&ifr->ifr_broadaddr)->sin_addr.s_addr = broad;
- strcpy(ifr->ifr_mask,oneSubNetMask);
-
- if (strlen(servicename) > 15)
- strncpy(ifr->ifr_name,servicename,15);
- else strcpy(ifr->ifr_name,servicename);
-
- /* now increment pointer */
- ifc_buffer += sizeof(struct ifreq);
- ++count;
- if (((char *)ipptr == '\0') || ((char *)subptr == '\0') || (enableDhcp))
- Done = 1;
- }
- }
- } /* it is a network card */
- } /* it is/not a temporary ndiswan name */
- } /* end of loop */
-
- /* add the loopback interface */
- ifr = (struct ifreq *)ifc_buffer;
- ip = inet_addr("127.0.0.1");
- broad = ~inet_addr("255.0.0.0") | ip;
- ifr->ifr_addr.sa_family = AF_INET;
- ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr = ip;
- ifr->ifr_broadaddr.sa_family = AF_INET;
- ((struct sockaddr_in *)&ifr->ifr_broadaddr)->sin_addr.s_addr = broad;
- strcpy(ifr->ifr_mask,"255.0.0.0");
- strcpy(ifr->ifr_name,"loopback");
-
- /* now increment pointer */
- ifc_buffer += sizeof(struct ifreq);
- ++count;
-
- /* now reset the length */
- ifc->ifc_len = count * (sizeof(struct ifreq));
- return 0;
-}
-
-#endif /* SYS_WINNT */
l_fp p_rec, p_xmt, p_org, p_reftime;
l_fp ci;
int pmode;
-#ifdef SYS_WINNT
- DWORD dwWaitResult;
-#endif /* SYS_WINNT */
/*
* Swap header fields and keep the books.
return(1);
}
-#ifdef SYS_WINNT
- /* prevent timer() from fiddling with the clock at the same time
- * as us by grabbing the mutex the mutex should be held for as
- * small a time as possible (in order that the timer() routine
- * is not blocked unneccessarily) and should probably be grabbed
- * much later (in local_clock() maybe), but this works
- * reasonably well too
- */
- dwWaitResult = WaitForSingleObject(
- hMutex, /* handle of mutex */
- 5000L); /* five-second time-out interval */
- switch (dwWaitResult) {
- case WAIT_OBJECT_0:
- /* The thread got mutex ownership. */
- break;
- default:
- /* Cannot get mutex ownership due to time-out. */
- msyslog(LOG_ERR, "receive error with mutex: %m\n");
- exit(1);
- }
-#endif /* SYS_WINNT */
/*
* This one is valid. Mark it so, give it to clock_filter().
clock_select();
record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
peer->offset, peer->delay, peer->disp, SQRT(peer->variance));
-#ifdef SYS_WINNT
- if (!ReleaseMutex(hMutex)) {
- msyslog(LOG_ERR, "receive cannot release mutex: %m\n");
- exit(1);
- }
-#endif /* SYS_WINNT */
return(1);
}
double sample_disp
)
{
- register int i, j, k, n;
+ register int i, j, k, n = 0;
register u_char *ord;
double distance[NTP_SHIFT];
double x, y, z, off;
#if defined SYS_WINNT || defined SYS_CYGWIN32
DWORD every;
BOOL noslew;
+ LARGE_INTEGER freq;
- if (!GetSystemTimeAdjustment(&units_per_tick, &every, &noslew))
- {
- printf("GetSystemTimeAdjustment\n");
- return 10000;
+ if (GetSystemTimeAdjustment(&units_per_tick, &every, &noslew)) {
+ adj_precision = 1000000L / (long)every;
}
- adj_precision = 1000000L / (long)every;
+
+
+ if (QueryPerformanceFrequency(&freq)) {
+ int i;
+ for (i = 1; freq.QuadPart ; i--) {
+ freq.QuadPart >>= 1;
+ }
+ return (i);
+ }
+
#endif
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
/*
* refclock_process - process a pile of samples from the clock
*
- * This routine converts the timecode in the form days, hours, miinutes,
+ * This routine converts the timecode in the form days, hours, minutes,
* seconds, milliseconds/microseconds to internal timestamp format.
* Further processing is then delegated to refclock sample
*/
#include "ntp_refclock.h"
#include "ntp_if.h"
#include "ntp_stdlib.h"
+#include "recvbuff.h"
#ifdef KERNEL_PLL
#include "ntp_syscall.h"
* Importations from the io module
*/
extern u_long io_timereset;
- extern u_long full_recvbufs;
- extern u_long free_recvbufs;
- extern u_long total_recvbufs;
- extern u_long lowater_additions;
+
extern u_long packets_dropped;
extern u_long packets_ignored;
extern u_long packets_received;
sizeof(struct info_io_stats));
io->timereset = htonl((u_int32)(current_time - io_timereset));
- io->totalrecvbufs = htons((u_short) total_recvbufs);
- io->freerecvbufs = htons((u_short) free_recvbufs);
- io->fullrecvbufs = htons((u_short) full_recvbufs);
- io->lowwater = htons((u_short) lowater_additions);
+ io->totalrecvbufs = htons((u_short) total_recvbuffs());
+ io->freerecvbufs = htons((u_short) free_recvbuffs());
+ io->fullrecvbufs = htons((u_short) full_recvbuffs());
+ io->lowwater = htons((u_short) lowater_additions());
io->dropped = htonl((u_int32)packets_dropped);
io->ignored = htonl((u_int32)packets_ignored);
io->received = htonl((u_int32)packets_received);
* ntp_timer.c - event timer support routines
*/
#ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
#endif
#include <stdio.h>
#include "ntp_machine.h"
#include "ntpd.h"
#include "ntp_stdlib.h"
+#if defined(HAVE_IO_COMPLETION_PORT)
+# include "ntp_iocompletionport.h"
+# include "ntp_timer.h"
+#endif
+
+extern int debug;
/*
* These routines provide support for the event timer. The timer is
static int vmsinc[2]; /* timer increment */
#endif /* VMS */
+#if defined SYS_WINNT
+static HANDLE WaitableTimerHandle = NULL;
+#endif /* SYS_WINNT */
+
+
/*
* init_timer - initialize the timer data structures
*/
static timer_t ntpd_timerid; /* should be global if we ever want */
/* to kill timer without rebooting ... */
struct itimerspec itimer;
-# endif
-# else /* SYS_WINNT */
+# endif /* HAVE_TIMER_SETTIME */
+# endif /* !SYS_WINNT */
+# if defined(SYS_CYGWIN32) || defined(SYS_WINNT)
TIMECAPS tc;
UINT wTimerRes, wTimerID;
# endif /* SYS_WINNT */
-#if defined(SYS_CYGWIN32) || defined(SYS_WINNT)
+# if defined(SYS_CYGWIN32) || defined(SYS_WINNT)
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
-#endif
-#endif /* VMS */
+# endif
+#endif /* !VMS */
/*
* Initialize...
timer_xmtcalls = 0;
timer_timereset = 0;
-#ifndef SYS_WINNT
+#if !defined(SYS_WINNT)
/*
* Set up the alarm interrupt. The first comes 2**EVENT_TIMEOUT
* seconds from now and they continue on every 2**EVENT_TIMEOUT
lib$addx(&vmsinc, &vmstimer, &vmstimer);
sys$setimr(0, &vmstimer, alarming, alarming, 0);
# endif /* VMS */
-#ifdef SYS_CYGWIN32
+# ifdef SYS_CYGWIN32
/*
* Get privileges needed for fiddling with the clock
*/
/* cannot test return value of AdjustTokenPrivileges. */
if (GetLastError() != ERROR_SUCCESS)
msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
-#endif
+# endif /* SYS_CYGWIN32 */
#else /* SYS_WINNT */
_tzset();
/* get set-time privilege for this process. */
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
/* cannot test return value of AdjustTokenPrivileges. */
- if (GetLastError() != ERROR_SUCCESS)
+ if (GetLastError() != ERROR_SUCCESS) {
msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
+ }
/*
* Set up timer interrupts for every 2**EVENT_TIMEOUT seconds
- * Under Windows/NT, expiry of timer interval leads to invocation
- * of a callback function (on a different thread) rather than
- * generating an alarm signal
+ * Under Windows/NT,
*/
- /* determine max and min resolution supported */
- if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
- msyslog(LOG_ERR, "timeGetDevCaps failed: %m");
+ WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL);
+ if (WaitableTimerHandle == NULL) {
+ msyslog(LOG_ERR, "CreateWaitableTimer failed: %m");
exit(1);
}
- wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
- /* establish the minimum timer resolution that we'll use */
- timeBeginPeriod(wTimerRes);
-
- hMutex = CreateMutex(
- NULL, /* no security attributes */
- FALSE, /* initially not owned */
- "MutexForNTP"); /* name of mutex */
- if (hMutex == NULL) {
- msyslog(LOG_ERR, "cannot create a mutex: %m\n");
- exit(1);
+ else {
+ DWORD Period = (1<<EVENT_TIMEOUT) * 1000;
+ LARGE_INTEGER DueTime;
+ DueTime.QuadPart = Period * 10000i64;
+ if (!SetWaitableTimer(WaitableTimerHandle, &DueTime, Period, NULL, NULL, FALSE) != NO_ERROR) {
+ msyslog(LOG_ERR, "SetWaitableTimer failed: %m");
+ exit(1);
+ }
}
- /* start the timer event */
- wTimerID = timeSetEvent(
- (1<<EVENT_TIMEOUT) * 1000, /* Delay in ms */
- wTimerRes, /* Resolution */
- (LPTIMECALLBACK) alarming, /* Callback function */
- (DWORD) 0, /* User data */
- TIME_PERIODIC); /* Event type (periodic) */
- if (wTimerID == 0) {
- msyslog(LOG_ERR, "timeSetEvent failed: %m");
- exit(1);
- }
#endif /* SYS_WINNT */
}
+#if defined(SYS_WINNT)
+extern HANDLE
+get_timer_handle(void)
+{
+ return WaitableTimerHandle;
+}
+#endif
/*
* timer - dispatch anyone who needs to be
{
register struct peer *peer, *next_peer;
int n;
-#ifdef SYS_WINNT
- DWORD dwWaitResult;
-
- dwWaitResult = WaitForSingleObject(
- hMutex, /* handle of mutex */
- 5000L); /* five-second time-out interval */
-
- switch (dwWaitResult) {
- case WAIT_OBJECT_0:
- /* The thread got mutex ownership. */
- break;
- default:
- /* Cannot get mutex ownership due to time-out. */
- msyslog(LOG_ERR, "timer() cannot obtain mutex: %m\n");
- exit(1);
- }
-#endif
current_time += (1<<EVENT_TIMEOUT);
adj_host_clock();
}
-#ifdef SYS_WINNT
- if (!ReleaseMutex(hMutex)) {
- msyslog(LOG_ERR, "timer() cannot release mutex: %m\n");
- exit(1);
- }
-#endif /* SYS_WINNT */
-
/*
* Now dispatch any peers whose event timer has expired. Be careful
* here, since the peer structure might go away as the result of
timer_xmtcalls = 0;
timer_timereset = current_time;
}
+
}
if (key_file_name == 0) {
- key_file_name = (char*)emalloc((u_int)
#ifndef SYS_WINNT
- (len + 1)
+ key_file_name = (char*)emalloc((u_int) (len + 1));
#else
- (MAXPATHLEN)
+ key_file_name = (char*)emalloc((u_int) (MAXPATHLEN));
#endif
- );
}
#ifndef SYS_WINNT
memmove(key_file_name, keyfile, (unsigned)(len+1));
# include <process.h>
# include <io.h>
# include "../libntp/log.h"
+# include <crtdbg.h>
#endif /* SYS_WINNT */
#if defined(HAVE_RTPRIO)
# ifdef HAVE_SYS_RESOURCE_H
#include "ntpd.h"
#include "ntp_select.h"
#include "ntp_io.h"
+
#include "ntp_stdlib.h"
+#include "recvbuff.h"
#if 0 /* HMS: I don't think we need this. 961223 */
#ifdef LOCK_PROCESS
#ifndef SYS_WINNT
#define SIGDIE1 SIGHUP
#define SIGDIE3 SIGQUIT
-#endif /* SYS_WINNT */
#define SIGDIE2 SIGINT
#define SIGDIE4 SIGTERM
+#endif /* SYS_WINNT */
#if defined SYS_WINNT || defined SYS_CYGWIN32
/* handles for various threads, process, and objects */
-HANDLE process_handle = NULL, WorkerThreadHandle = NULL,
- ResolverThreadHandle = NULL, TimerThreadHandle = NULL,
- hMutex = NULL;
+HANDLE ResolverThreadHandle = NULL;
/* variables used to inform the Service Control Manager of our current state */
SERVICE_STATUS ssStatus;
SERVICE_STATUS_HANDLE sshStatusHandle;
-int was_stopped = 0;
+HANDLE WaitHandles[3] = { NULL, NULL, NULL };
char szMsgPath[255];
+static BOOL WINAPI OnConsoleEvent(DWORD dwCtrlType);
#endif /* SYS_WINNT */
/*
* Scheduling priority we run at
*/
-#define NTPD_PRIO (-12)
+#if !defined SYS_WINNT
+# define NTPD_PRIO (-12)
+#else
+# define NTPD_PRIO REALTIME_PRIORITY_CLASS
+#endif
/*
* Debugging flag
extern int syscall P((int, ...));
#endif /* DECL_SYSCALL */
-#ifdef SYS_WINNT
-extern void worker_thread P((void *));
-#endif /* SYS_WINNT */
#ifdef SIGDIE2
static RETSIGTYPE finish P((int));
set_process_priority(void)
{
#ifdef SYS_WINNT
- process_handle = GetCurrentProcess();
- if (!SetPriorityClass(process_handle, (DWORD) REALTIME_PRIORITY_CLASS))
+ if (!SetPriorityClass(GetCurrentProcess(), (DWORD) REALTIME_PRIORITY_CLASS))
{
msyslog(LOG_ERR, "SetPriorityClass: %m");
return;
)
{
l_fp now;
-#ifndef SYS_WINNT
char *cp;
struct recvbuf *rbuflist;
struct recvbuf *rbuf;
-#endif
#ifdef _AIX /* HMS: ifdef SIGDANGER? */
struct sigaction sa;
#endif
/* daemonize */
if (!StartServiceCtrlDispatcher(dispatchTable))
{
- if (!was_stopped)
- {
- msyslog(LOG_ERR, "StartServiceCtrlDispatcher: %m");
- ExitProcess(2);
- }
- else
- {
- NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
- msyslog(LOG_INFO, "StartServiceCtrlDispatcher: service stopped");
- ExitProcess(0);
- }
+ msyslog(LOG_ERR, "StartServiceCtrlDispatcher: %m");
+ ExitProcess(2);
}
}
#endif /* SYS_WINNT */
)
{
char *cp;
- DWORD dwWait;
+ struct recvbuf *rbuflist;
+ struct recvbuf *rbuf;
if(!debug)
{
return;
}
- /*
- * create an event object that the control handler function
- * will signal when it receives the "stop" control code
- */
- if (!(hServDoneEvent = CreateEvent(
- NULL, /* no security attributes */
- TRUE, /* manual reset event */
- FALSE, /* not-signalled */
- NULL))) /* no name */
- {
- msyslog(LOG_ERR, "CreateEvent failed: %m");
- ssStatus.dwCurrentState = SERVICE_STOPPED;
- SetServiceStatus(sshStatusHandle, &ssStatus);
- return;
- }
} /* debug */
#endif /* defined(SYS_WINNT) && !defined(NODETACH) */
#endif /* VMS */
(void) signal_no_reset(SIGPIPE, SIG_IGN);
#endif /* SIGPIPE */
+#if defined SYS_WINNT
+ if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE)) {
+ msyslog(LOG_ERR, "Can't set console control handler: %m");
+ }
+#endif
+
/*
* Call the init_ routines to initialize the data structures.
*/
+#if defined (HAVE_IO_COMPLETION_PORT)
+ init_io_completion_port();
+#endif
init_auth();
init_util();
init_restrict();
# if defined(DEBUG)
if(!debug)
{
-# endif
-
- /*
- * the service_main() thread will have to wait for requests to
- * start/stop/pause/continue from the services icon in the Control
- * Panel or from any WIN32 application start a new thread to perform
- * all the work of the NTP service
- */
- if (!(WorkerThreadHandle = (HANDLE)_beginthread(
- worker_thread,
- 0, /* stack size */
- NULL))) /* argument to thread */
- {
- msyslog(LOG_ERR, "_beginthread: %m");
- if (hServDoneEvent != NULL)
- CloseHandle(hServDoneEvent);
- if (ResolverThreadHandle != NULL)
- CloseHandle(ResolverThreadHandle);
- ssStatus.dwCurrentState = SERVICE_STOPPED;
- SetServiceStatus(sshStatusHandle, &ssStatus);
- return;
- }
-
+#endif
/* report to the service control manager that the service is running */
ssStatus.dwCurrentState = SERVICE_RUNNING;
ssStatus.dwWin32ExitCode = NO_ERROR;
if (!SetServiceStatus(sshStatusHandle, &ssStatus))
{
msyslog(LOG_ERR, "SetServiceStatus: %m");
- if (hServDoneEvent != NULL)
- CloseHandle(hServDoneEvent);
if (ResolverThreadHandle != NULL)
CloseHandle(ResolverThreadHandle);
ssStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(sshStatusHandle, &ssStatus);
return;
}
-
- /* wait indefinitely until hServDoneEvent is signaled */
- dwWait = WaitForSingleObject(hServDoneEvent,INFINITE);
- if (hServDoneEvent != NULL)
- CloseHandle(hServDoneEvent);
- if (ResolverThreadHandle != NULL)
- CloseHandle(ResolverThreadHandle);
- if (WorkerThreadHandle != NULL)
- CloseHandle(WorkerThreadHandle);
- if (TimerThreadHandle != NULL)
- CloseHandle(TimerThreadHandle);
- /* restore the clock frequency back to its original value */
- if (!SetSystemTimeAdjustment((DWORD)0, TRUE))
- msyslog(LOG_ERR, "Failed to reset clock frequency, SetSystemTimeAdjustment(): %m");
- ssStatus.dwCurrentState = SERVICE_STOPPED;
- SetServiceStatus(sshStatusHandle, &ssStatus);
- return;
# if defined(DEBUG)
}
- else
- worker_thread( (void *) 0 );
-# endif
-} /* end service_main() */
-
-
-/*
- * worker_thread - perform all remaining functions after initialization and and becoming a service
- */
-void
-worker_thread(
- void *notUsed
- )
-{
- struct recvbuf *rbuflist;
- struct recvbuf *rbuf;
-
-#endif /* defined(SYS_WINNT) && !defined(NODETACH) */
+#endif
+#endif
/*
* Report that we're up to any trappers
* between checking for alarms and doing the select().
* Mostly harmless, I think.
*/
- /*
- * Under NT, a timer periodically invokes a callback function
- * on a different thread. This callback function has no way
- * of interrupting a winsock "select" call on a different
- * thread. A mutex is used to synchronize access to clock
- * related variables between the two threads (one blocking
- * on a select or processing the received packets and the
- * other that calls the timer callback function, timer(),
- * every second). Due to this change, timer() routine can
- * be invoked between processing two or more received
- * packets, or even during processing a single received
- * packet before entering the clock_update routine (if
- * needed). The potential race condition is also avoided.
- */
/* On VMS, I suspect that select() can't be interrupted
* by a "signal" either, so I take the easy way out and
* have select() time out after one second.
* and - lacking a hardware reference clock - I have
* yet to learn about anything else that is.
*/
+# if defined(HAVE_IO_COMPLETION_PORT)
+ {
+ WaitHandles[0] = CreateEvent(NULL, FALSE, FALSE, NULL); /* exit reques */
+ WaitHandles[1] = get_recv_buff_event();
+ WaitHandles[2] = get_timer_handle();
+
+ for (;;) {
+ DWORD Index = MsgWaitForMultipleObjectsEx(sizeof(WaitHandles)/sizeof(WaitHandles[0]), WaitHandles, INFINITE, QS_ALLEVENTS, MWMO_ALERTABLE);
+ switch (Index) {
+ case WAIT_OBJECT_0 + 0 : /* exit request */
+ exit(0);
+ break;
+
+ case WAIT_OBJECT_0 + 1 : {/* recv buffer */
+ if (NULL != (rbuf = get_full_recv_buffer())) {
+ if (rbuf->receiver != NULL) {
+ rbuf->receiver(rbuf);
+ }
+ freerecvbuf(rbuf);
+ }
+ }
+ break;
+
+ case WAIT_OBJECT_0 + 2 : /* 1 second timer */
+ timer();
+ break;
+
+ case WAIT_OBJECT_0 + 3 : { /* Windows message */
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ if (msg.message == WM_QUIT) {
+ exit(0);
+ }
+ DispatchMessage(&msg);
+ }
+ }
+ break;
+
+ case WAIT_IO_COMPLETION : /* loop */
+ case WAIT_TIMEOUT :
+ break;
+
+ }
+
+ }
+ }
+# else /* normal I/O */
+
was_alarmed = 0;
rbuflist = (struct recvbuf *)0;
for (;;)
{
-#ifndef HAVE_SIGNALED_IO
+# if !defined(HAVE_SIGNALED_IO)
extern fd_set activefds;
extern int maxactivefd;
fd_set rdfdes;
int nfound;
-#else
+# elif defined(HAVE_SIGNALED_IO)
block_io_and_alarm();
-#endif
+# endif
rbuflist = getrecvbufs(); /* get received buffers */
if (alarm_flag) /* alarmed? */
(void)input_handler(&ts);
}
- else if (
-#ifndef SYS_WINNT
- (nfound == -1 && errno != EINTR)
-#else /* SYS_WINNT */
- (nfound == SOCKET_ERROR && WSAGetLastError() != WSAEINTR)
-#endif /* SYS_WINNT */
- )
+ else if (nfound == -1 && errno != EINTR)
msyslog(LOG_ERR, "select() error: %m");
else if (debug) {
-#if !defined SYS_VXWORKS && !defined SYS_CYGWIN32 /* to unclutter log */
+# if !defined SYS_VXWORKS && !defined SYS_CYGWIN32 /* to unclutter log */
msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
-#endif
+# endif
}
-#else
+# else /* HAVE_SIGNALED_IO */
+
wait_for_signal();
-#endif
+# endif /* HAVE_SIGNALED_IO */
if (alarm_flag) /* alarmed? */
{
was_alarmed = 1;
}
rbuflist = getrecvbufs(); /* get received buffers */
}
-#ifdef HAVE_SIGNALED_IO
+# ifdef HAVE_SIGNALED_IO
unblock_io_and_alarm();
-#endif /* HAVE_SIGNALED_IO */
+# endif /* HAVE_SIGNALED_IO */
/*
* Out here, signals are unblocked. Call timer routine
* to process expiry.
*/
-#ifndef SYS_WINNT
- /*
- * under WinNT, the timer() routine is directly called
- * by the timer callback function (alarming)
- * was_alarmed should have never been set, but don't
- * want to risk timer() being accidently called here
- */
if (was_alarmed)
{
timer();
was_alarmed = 0;
}
-#endif /* SYS_WINNT */
/*
* Call the data procedure to handle each received
(rbuf->receiver)(rbuf);
freerecvbuf(rbuf);
}
+# if defined DEBUG && defined SYS_WINNT
+ if (debug > 4)
+ printf("getrecvbufs: %ld handler interrupts, %ld frames\n",
+ handler_calls, handler_pkts);
+# endif
+
/*
* Go around again
*/
}
+# endif /* HAVE_IO_COMPLETION_PORT */
+ exit(0);
}
msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig);
-#ifdef SYS_WINNT
- /*
- * with any exit(0)'s in the worker_thread, the service_main()
- * thread needs to be informed to quit also
- */
- SetEvent(hServDoneEvent);
-#endif /* SYS_WINNT */
-
switch (sig)
{
#ifdef SIGBUS
break;
case SERVICE_CONTROL_STOP:
- dwState = SERVICE_STOP_PENDING;
- /*
- * Report the status, specifying the checkpoint and waithint,
- * before setting the termination event.
- */
- ssStatus.dwCurrentState = dwState;
- ssStatus.dwWin32ExitCode = NO_ERROR;
- ssStatus.dwWaitHint = 3000;
- if (!SetServiceStatus(sshStatusHandle, &ssStatus))
- {
- msyslog(LOG_ERR, "SetServiceStatus: %m");
- }
- was_stopped = 1;
- SetEvent(hServDoneEvent);
+ dwState = SERVICE_STOP_PENDING;
+ /*
+ * Report the status, specifying the checkpoint and waithint,
+ * before setting the termination event.
+ */
+ ssStatus.dwCurrentState = dwState;
+ ssStatus.dwWin32ExitCode = NO_ERROR;
+ ssStatus.dwWaitHint = 3000;
+ if (!SetServiceStatus(sshStatusHandle, &ssStatus))
+ {
+ msyslog(LOG_ERR, "SetServiceStatus: %m");
+ }
+ if (WaitHandles[0] != NULL) {
+ SetEvent(WaitHandles[0]);
+ }
return;
case SERVICE_CONTROL_INTERROGATE:
msyslog(LOG_ERR, "SetServiceStatus: %m");
}
}
+
+static BOOL WINAPI
+OnConsoleEvent(
+ DWORD dwCtrlType
+ )
+{
+ switch (dwCtrlType) {
+ case CTRL_BREAK_EVENT :
+ if (debug > 0) {
+ debug <<= 1;
+ }
+ else {
+ debug = 1;
+ }
+ if (debug > 8) {
+ debug = 0;
+ }
+ printf("debug level %d\n", debug);
+ break ;
+
+ case CTRL_C_EVENT :
+ case CTRL_CLOSE_EVENT :
+ case CTRL_SHUTDOWN_EVENT :
+ if (WaitHandles[0] != NULL) {
+ SetEvent(WaitHandles[0]);
+ }
+ break;
+
+ default :
+ return FALSE;
+
+
+ }
+ return TRUE;;
+}
+
+
+/*
+ * NT version of exit() - all calls to exit() should be routed to
+ * this function.
+ */
+void
+service_exit(
+ int status
+ )
+{
+ /* restore the clock frequency back to its original value */
+ if (!SetSystemTimeAdjustment((DWORD)0, TRUE)) {
+ msyslog(LOG_ERR, "Failed to reset clock frequency, SetSystemTimeAdjustment(): %m");
+ }
+
+ if (!debug) { /* did not become a service, simply exit */
+ /* service mode, need to have the service_main routine
+ * register with the service control manager that the
+ * service has stopped running, before exiting
+ */
+ ssStatus.dwCurrentState = SERVICE_STOPPED;
+ SetServiceStatus(sshStatusHandle, &ssStatus);
+
+ }
+ uninit_io_completion_port();
+
+# if defined _MSC_VER
+ _CrtDumpMemoryLeaks();
+# endif
+#undef exit
+ exit(status);
+}
+
#endif /* SYS_WINNT */
#if defined(REFCLOCK) && defined(CLOCK_NMEA)
-#define DEBUG 1
-
#include <stdio.h>
#include <ctype.h>
#include <sys/time.h>
* Post Office Box 3642
* Sunnyvale, CA 94088-3642
*
- * Version 2.43; May 11, 1999
+ * Version 2.45; July 14, 1999
*
*/
pp->io.srcclock = (caddr_t)peer;
pp->io.datalen = 0;
pp->io.fd = fd;
- pp->nstages = PALISADE_SAMPLES;
+ pp->nstages = 1;
#ifndef PALISADE
- pp->nskeep = PALISADE_SAMPLES * 3 / 5;
+ pp->nskeep = 1;
#endif
if (!io_addclock(&pp->io)) {
* proper format, declare bad format and exit.
*/
- if (up->rpt_buf[0] == (char) 0x41)
+ if ((up->rpt_buf[0] == (char) 0x41) ||
+ (up->rpt_buf[0] == (char) 0x46) ||
+ (up->rpt_buf[0] == (char) 0x54) ||
+ (up->rpt_buf[0] == (char) 0x4B) ||
+ (up->rpt_buf[0] == (char) 0x6D)) {
+
/* standard time packet - GPS time and GPS week number */
+#ifdef DEBUG
+ printf("Palisade Port B packets detected. Connect to Port A\n");
+#endif
+
return 0;
+ }
if (up->rpt_buf[0] == (char) 0x8f) {
/*
else if (up->rpt_status == TSIP_PARSED_EMPTY)
up->rpt_cnt = 0;
- else if (up->rpt_cnt > TSIP_MAXLEN)
+ else if (up->rpt_cnt > BMAX)
up->rpt_status =TSIP_PARSED_EMPTY;
if (up->rpt_status == TSIP_PARSED_FULL)
} /* while chars in buffer */
}
-#if defined SYS_WINNT
-static int
-nt_poll(
- struct refclockproc *pp,
- l_fp *postpoll
- )
-{
- struct palisade_unit *up;
-
- up = (struct palisade_unit *)pp->unitptr;
-
-
- get_systime(&pp->lastrec);
- if (!EscapeCommFunction((HANDLE) pp->io.fd, SETRTS)) {
-
- msyslog (LOG_ERR, "NT_COM: Unit %d: Error set RTS %m", up->unit);
- return -1;
- }
- get_systime(postpoll);
-
- if (!EscapeCommFunction((HANDLE) pp->io.fd, CLRRTS)) {
-
- msyslog (LOG_ERR, "NT_COM: Unit %d: Error clear RTS %m", up->unit);
- return -1;
- }
-
- return 0;
-}
-#endif
-
/*
* Trigger the Palisade's event input, which is driven off the RTS
up = (struct palisade_unit *) pp->unitptr;
-#if defined SYS_WINNT
- if (nt_poll(pp, &pp->lastrec)) {
- msyslog(LOG_ERR, "Palisade(%d) NT_poll: ioctl(fd,GET): %m",
- up->unit);
- return -1;
- }
-#else /* !NT handler */
/* read the current status, so we put things back right */
- if (ioctl(pp->io.fd, TIOCMGET, &x) == -1) {
+ if (ioctl(pp->io.fd, TIOCMGET, &x) < 0) {
#ifdef DEBUG
if (debug)
printf("Palisade HW_poll: unit %d: GET %s\n", up->unit, strerror(errno));
get_systime(&pp->lastrec);
/* Leading edge trigger */
- if (ioctl(pp->io.fd, TIOCMSET, &x) == -1) {
+ if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) {
#ifdef DEBUG
if (debug)
printf("Palisade HW_poll: unit %d: SET \n", up->unit);
up->unit);
return -1;
}
-#endif /* ! SYS_WINNT */
return 0;
}
#define DESCRIPTION "Trimble Palisade GPS" /* Long name */
#define PRECISION (-20) /* precision assumed (about 1 us) */
#define REFID "GPS\0" /* reference ID */
-#define TRMB_MINPOLL 5 /* 32 seconds */
-#define TRMB_MAXPOLL 10 /* 1024 seconds */
-#define PALISADE_SAMPLES 3
+#define TRMB_MINPOLL 5 /* 16 seconds */
+#define TRMB_MAXPOLL 7 /* 64 seconds */
/*
* I/O Definitions
#define DEVICE "/dev/palisade%d" /* device name and unit */
#define SPEED232 B9600 /* uart speed (9600 baud) */
-#define TSIP_MAXLEN 128 /* maximum length TSIP packet */
-
/*
* TSIP Report Definitions
*/
/*
* Leap-Insert and Leap-Delete are encoded as follows:
* PALISADE_UTC_TIME set and PALISADE_LEAP_PENDING set: INSERT leap
- * PALISADE_UTC_TIME clear and PALISADE_LEAP_PENDING set: DELETE leap
*/
#define PALISADE_LEAP_INPROGRESS 0x08 /* This is the leap flag */
char leap_status; /* leap second flag */
char rpt_status; /* TSIP Parser State */
short rpt_cnt; /* TSIP packet length so far */
- char rpt_buf[TSIP_MAXLEN]; /* packet assembly buffer */
+ char rpt_buf[BMAX]; /* packet assembly buffer */
};
/*
extern int errno;
int shmid=0;
- assert (unit<10); // MAXUNIT is 4, so should never happen
+ assert (unit<10); /* MAXUNIT is 4, so should never happen */
shmid=shmget (0x4e545030+unit, sizeof (struct shmTime),
IPC_CREAT|(unit<2?0700:0777));
- if (shmid==-1) { //error
+ if (shmid==-1) { /*error */
char buf[20];
char *pe=buf;
if (errno<sys_nerr)
msyslog(LOG_ERR,"SHM shmget (unit %d): %s",unit,pe);
return 0;
}
- else { // no error
+ else { /* no error */
struct shmTime *p=(struct shmTime *)shmat (shmid, 0, 0);
- if ((int)(long)p==-1) { //error
+ if ((int)(long)p==-1) { /* error */
char buf[20];
char *pe=buf;
if (errno<sys_nerr)
SECURITY_DESCRIPTOR sd;
SECURITY_ATTRIBUTES sa;
sprintf (buf,"NTP%d",unit);
- if (unit>=2) { // world access
+ if (unit>=2) { /* world access */
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
msyslog(LOG_ERR,"SHM InitializeSecurityDescriptor (unit %d): %m",unit);
return 0;
}
shmid=CreateFileMapping ((HANDLE)0xffffffff, psec, PAGE_READWRITE,
0, sizeof (struct shmTime),buf);
- if (!shmid) { //error
+ if (!shmid) { /*error*/
char buf[1000];
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
0, GetLastError (), 0, buf, sizeof (buf), 0);
else {
struct shmTime *p=(struct shmTime *) MapViewOfFile (shmid,
FILE_MAP_WRITE, 0, 0, sizeof (struct shmTime));
- if (p==0) { //error
+ if (p==0) { /*error*/
char buf[1000];
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
0, GetLastError (), 0, buf, sizeof (buf), 0);
pp->lasttime = current_time;
pp->polls++;
t=gmtime (&tvt.tv_sec);
- pp->day=t->tm_yday;//+2;
+ pp->day=t->tm_yday;/*+2; */
pp->hour=t->tm_hour;
pp->minute=t->tm_min;
pp->second=t->tm_sec;
#include "ntp_syslog.h"
#include "ntp_select.h"
#include "ntp_stdlib.h"
+#include "recvbuff.h"
#ifdef SYS_WINNT
# define TARGET_RESOLUTION 1 /* Try for 1-millisecond accuracy
on Windows NT timers. */
+#pragma comment(lib, "winmm")
#endif /* SYS_WINNT */
/*
static RETSIGTYPE alarming P((int));
#endif /* SYS_WINNT */
static void init_io P((void));
-static struct recvbuf *getrecvbufs P((void));
-static void freerecvbuf P((struct recvbuf *));
static void sendpkt P((struct sockaddr_in *, struct pkt *, int));
-static void input_handler P((void));
+void input_handler P((void));
static int l_adj_systime P((l_fp *));
static int l_step_systime P((l_fp *));
int is_authentic;
if (debug)
- printf("receive(%s)\n", ntoa(&rbufp->srcadr));
+ printf("receive(%s)\n", ntoa(&rbufp->recv_srcadr));
/*
* Check to see if the packet basically looks like something
* intended for us.
/*
* So far, so good. See if this is from a server we know.
*/
- server = findserver(&(rbufp->srcadr));
+ server = findserver(&(rbufp->recv_srcadr));
if (server == NULL) {
if (debug)
printf("receive: server not found\n");
}
+#ifndef SYS_WINNT
+/*
+ * alarming - record the occurance of an alarm interrupt
+ */
+static RETSIGTYPE
+alarming(
+ int sig
+ )
+#else
+void CALLBACK
+alarming(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
+#endif /* SYS_WINNT */
+{
+ alarm_flag++;
+}
+
/*
* init_alarm - set up the timer interrupt
}
-#ifndef SYS_WINNT
-/*
- * alarming - record the occurance of an alarm interrupt
- */
-static RETSIGTYPE
-alarming(
- int sig
- )
-{
- alarm_flag++;
-}
-#endif /* SYS_WINNT */
/*
* plus 2. This should be plenty.
*/
-/*
- * recvbuf lists
- */
-struct recvbuf *freelist; /* free buffers */
-struct recvbuf *fulllist; /* buffers with data */
-
-int full_recvbufs; /* number of full ones */
-int free_recvbufs;
-
/*
* init_io - initialize I/O data and open socket
/*
* Init buffer free list and stat counters
*/
- rb = (struct recvbuf *)
- emalloc((sys_numservers + 2) * sizeof(struct recvbuf));
- freelist = 0;
- for (i = sys_numservers + 2; i > 0; i--) {
- rb->next = freelist;
- freelist = rb;
- rb++;
- }
-
- fulllist = 0;
- full_recvbufs = 0;
- free_recvbufs = sys_numservers + 2;
-
+ init_recvbuff(sys_numservers + 2);
/*
* Open the socket
*/
}
-/* XXX ELIMINATE getrecvbufs (almost) identical to ntpdate.c, ntptrace.c, ntp_io.c */
-/*
- * getrecvbufs - get receive buffers which have data in them
- *
- * ***N.B. must be called with SIGIO blocked***
- */
-static struct recvbuf *
-getrecvbufs(void)
-{
- struct recvbuf *rb;
-
- if (full_recvbufs == 0) {
- return (struct recvbuf *)0; /* nothing has arrived */
- }
-
- /*
- * Get the fulllist chain and mark it empty
- */
- rb = fulllist;
- fulllist = 0;
- full_recvbufs = 0;
-
- /*
- * Return the chain
- */
- return rb;
-}
-
-
-/* XXX ELIMINATE freerecvbuf (almost) identical to ntpdate.c, ntptrace.c, ntp_io.c */
-/*
- * freerecvbuf - make a single recvbuf available for reuse
- */
-static void
-freerecvbuf(
- struct recvbuf *rb
- )
-{
-
- rb->next = freelist;
- freelist = rb;
- free_recvbufs++;
-}
-
-
/*
* sendpkt - send a packet to the specified destination
*/
/*
* input_handler - receive packets asynchronously
*/
-static void
+void
input_handler(void)
{
register int n;
* haven't got a buffer, or this is received
* on the wild card socket, just dump the packet.
*/
- if (initializing || free_recvbufs == 0) {
+ if (initializing || free_recvbuffs() == 0) {
char buf[100];
#ifndef SYS_WINNT
continue;
}
- rb = freelist;
- freelist = rb->next;
- free_recvbufs--;
+ rb = get_free_recv_buffer();
fromlen = sizeof(struct sockaddr_in);
rb->recv_length = recvfrom(fd, (char *)&rb->recv_pkt,
sizeof(rb->recv_pkt), 0,
- (struct sockaddr *)&rb->srcadr, &fromlen);
+ (struct sockaddr *)&rb->recv_srcadr, &fromlen);
if (rb->recv_length == -1) {
- rb->next = freelist;
- freelist = rb;
- free_recvbufs++;
+ freerecvbuf(rb);
continue;
}
* put it on the full list.
*/
rb->recv_time = ts;
- rb->next = fulllist;
- fulllist = rb;
- full_recvbufs++;
+ add_full_recv_buffer(rb);
}
}
#include "ntp_syslog.h"
#include "ntp_select.h"
#include "ntp_stdlib.h"
-
+#include "recvbuff.h"
/*
* only 16 stratums, so this is more than enough.
*/
int sys_maxservers = NTP_MAXSTRATUM+1; /* max number of servers to deal with */
int sys_version = NTP_OLDVERSION; /* version to poll with */
-/*
- * recvbuf lists
- */
-struct recvbuf *freelist; /* free buffers */
-struct recvbuf *fulllist; /* buffers with data */
-
-int full_recvbufs; /* number of full ones */
-int free_recvbufs;
/*
* File descriptor masks etc. for call to select
int ntptracemain P((int, char **));
static void DoTrace P((struct server *));
static void DoTransmit P((struct server *));
-static int DoReceive P((struct server *));
-static int ReceiveBuf P((struct server *, struct recvbuf *));
-static struct server *addserver P((struct in_addr *));
-static struct server *addservbyname P((const char *));
+static int DoReceive P((struct server *));
+static int ReceiveBuf P((struct server *, struct recvbuf *));
+static struct server *addserver P((struct in_addr *));
+static struct server *addservbyname P((const char *));
static void setup_io P((void));
-static void freerecvbuf P((struct recvbuf *));
static void sendpkt P((struct sockaddr_in *, struct pkt *, int));
-static int getipaddr P((const char *, u_int32 *));
-static int decodeipaddr P((const char *, u_int32 *));
+static int getipaddr P((const char *, u_int32 *));
+static int decodeipaddr P((const char *, u_int32 *));
static void printserver P((struct server *, FILE *));
static void printrefid P((FILE *, struct server *));
HANDLE TimerThreadHandle = NULL; /* 1998/06/03 - Used in ntplib/machines.c */
void timer(void) { ; }; /* 1998/06/03 - Used in ntplib/machines.c */
-
#endif /* SYS_WINNT */
+extern void input_handler(l_fp * x) { ; };
#ifdef NO_MAIN_ALLOWED
CALL(ntptrace,"ntptrace",ntptracemain);
}
get_systime(&ts);
- if (free_recvbufs == 0) {
+ if (free_recvbuffs() == 0) {
msyslog(LOG_ERR, "no buffers");
exit(1);
}
- rb = freelist;
- freelist = rb->next;
- free_recvbufs--;
+ rb = get_free_recv_buffer();
fromlen = sizeof(struct sockaddr_in);
rb->recv_length = recvfrom(fd, (char *)&rb->recv_pkt,
sizeof(rb->recv_pkt), 0,
- (struct sockaddr *)&rb->srcadr, &fromlen);
+ (struct sockaddr *)&rb->recv_srcadr, &fromlen);
if (rb->recv_length == -1) {
- rb->next = freelist;
- freelist = rb;
- free_recvbufs++;
+ freerecvbuf(rb);
continue;
}
* put it on the full list.
*/
rb->recv_time = ts;
- rb->next = fulllist;
- fulllist = rb;
- full_recvbufs++;
+ add_full_recv_buffer(rb);
status = ReceiveBuf(server, rb);
if (debug) {
printf("ReceiveBuf(%s, ", ntoa(&server->srcadr));
- printf("%s)\n", ntoa(&rbufp->srcadr));
+ printf("%s)\n", ntoa(&rbufp->recv_srcadr));
}
/*
rbufp->recv_length);
return(0); /* funny length packet */
}
- if (rbufp->srcadr.sin_addr.s_addr != server->srcadr.sin_addr.s_addr) {
+ if (rbufp->recv_srcadr.sin_addr.s_addr != server->srcadr.sin_addr.s_addr) {
if (debug)
printf("receive: wrong server\n");
return(0); /* funny length packet */
}
-/* XXX ELIMINATE getrecvbufs (almost) identical to ntpdate.c, ntptrace.c, ntp_io.c */
-/*
- * setup_io - initialize I/O data and open socket
- */
static void
setup_io(void)
{
- register int i;
- register struct recvbuf *rb;
-
/*
* Init buffer free list and stat counters
*/
- rb = (struct recvbuf *)
- emalloc((sys_maxservers + 2) * sizeof(struct recvbuf));
- freelist = 0;
- for (i = sys_maxservers + 2; i > 0; i--) {
- rb->next = freelist;
- freelist = rb;
- rb++;
- }
-
- fulllist = 0;
- full_recvbufs = 0;
- free_recvbufs = sys_maxservers + 2;
+ init_recvbuff(sys_maxservers + 2);
/* create a datagram (UDP) socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0))
FD_SET(fd, &fdmask);
}
-/* XXX ELIMINATE freerecvbuf (almost) identical to ntpdate.c, ntptrace.c, ntp_io.c */
-/*
- * freerecvbuf - make a single recvbuf available for reuse
- */
-static void
-freerecvbuf(
- struct recvbuf *rb
- )
-{
- rb->next = freelist;
- freelist = rb;
- free_recvbufs++;
-}
/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */