From: Harlan Stenn Date: Wed, 21 Jul 1999 00:52:07 +0000 (-0000) Subject: Many files: X-Git-Tag: NTP_4_0_94~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=408095938b364272b9acbcf0c678562d48ffd1a6;p=thirdparty%2Fntp.git Many files: * 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 bk: 379519b7Rr5hhsTrdbPJyHdaOPBGYA --- diff --git a/ChangeLog b/ChangeLog index f249809cd..dc6c8767b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,43 @@ 1999-07-20 Harlan Stenn + * 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. diff --git a/include/iosignal.h b/include/iosignal.h new file mode 100644 index 000000000..bd74e096d --- /dev/null +++ b/include/iosignal.h @@ -0,0 +1,23 @@ +#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 diff --git a/include/ntp.h b/include/ntp.h index d9c8822e3..ecd4daf43 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -428,40 +428,6 @@ struct pkt { #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 diff --git a/include/ntp_io.h b/include/ntp_io.h index 325b70ca4..0ef4fa653 100644 --- a/include/ntp_io.h +++ b/include/ntp_io.h @@ -1,3 +1,5 @@ +#if !defined _NTP_IO_H +#define _NTP_IO_H /* * POSIX says use to get O_* symbols and * SEEK_SET symbol form . @@ -22,6 +24,10 @@ #if !defined(SEEK_SET) && defined(L_SET) # define SEEK_SET L_SET #endif + #ifdef SYS_WINNT # include +# include "win32_io.h" +#endif + #endif diff --git a/include/ntp_machine.h b/include/ntp_machine.h index f0b8ff1a6..82a9f3544 100644 --- a/include/ntp_machine.h +++ b/include/ntp_machine.h @@ -231,58 +231,26 @@ typedef unsigned long u_long; * 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 # include -# include +# include # 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)); diff --git a/include/ntp_refclock.h b/include/ntp_refclock.h index 9a481697c..f977c0c33 100644 --- a/include/ntp_refclock.h +++ b/include/ntp_refclock.h @@ -36,6 +36,8 @@ #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 */ diff --git a/include/ntp_stdlib.h b/include/ntp_stdlib.h index deab1a391..a57183502 100644 --- a/include/ntp_stdlib.h +++ b/include/ntp_stdlib.h @@ -23,7 +23,7 @@ # endif #endif -#if defined(__STDC__) +#if defined(__STDC__) || defined(HAVE_STDARG_H) # include extern void msyslog P((int, const char *, ...)) __attribute__((__format__(__printf__, 2, 3))); @@ -56,7 +56,12 @@ extern u_long calleapwhen P((u_long)); 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)); diff --git a/include/ntpd.h b/include/ntpd.h index 0588f24d8..d5fd71731 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -7,6 +7,7 @@ #include "ntp.h" #include "ntp_malloc.h" #include "ntp_refclock.h" +#include "recvbuff.h" #define MAXINTERFACES 512 @@ -81,8 +82,7 @@ extern void ntp_intres P((void)); /* 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)); @@ -240,7 +240,6 @@ extern char * req_file; /* name of the file with configuration info */ 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 diff --git a/include/recvbuff.h b/include/recvbuff.h new file mode 100644 index 000000000..687bc9659 --- /dev/null +++ b/include/recvbuff.h @@ -0,0 +1,113 @@ +#if !defined __recvbuff_h +#define __recvbuff_h + +#ifdef HAVE_CONFIG_H +# include +#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 */ + diff --git a/libntp/Makefile.am b/libntp/Makefile.am index 3a9aded6e..9ba3c097d 100644 --- a/libntp/Makefile.am +++ b/libntp/Makefile.am @@ -11,7 +11,7 @@ libntp_a_SOURCES = a_md5encrypt.c adjtime.c atoint.c atolfp.c atouint.c \ 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 diff --git a/libntp/Makefile.in b/libntp/Makefile.in index 1b335b7d3..3f9d16b3c 100644 --- a/libntp/Makefile.in +++ b/libntp/Makefile.in @@ -108,7 +108,7 @@ libntp_a_SOURCES = a_md5encrypt.c adjtime.c atoint.c atolfp.c atouint.c \ 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@ @@ -141,7 +141,7 @@ mstolfp$U.o msutotsf$U.o msyslog$U.o netof$U.o numtoa$U.o numtohost$U.o \ 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) @@ -166,14 +166,15 @@ DEP_FILES = .deps/a_md5encrypt.P .deps/adjtime.P .deps/atoint.P \ .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) @@ -283,6 +284,8 @@ mfp_mul$U.o: 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 @@ -352,6 +355,8 @@ ieee754io_.c: ieee754io.c $(ANSI2KNR) $(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) @@ -390,6 +395,8 @@ prettydate_.c: prettydate.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) @@ -422,12 +429,12 @@ binio_.o buftvtots_.o caljulian_.o calleapwhen_.o caltontp_.o \ 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 diff --git a/libntp/emalloc.c b/libntp/emalloc.c index ff693211e..0918c9c7b 100644 --- a/libntp/emalloc.c +++ b/libntp/emalloc.c @@ -6,6 +6,30 @@ #include "ntp_stdlib.h" #include "ntp_syslog.h" +#if defined SYS_WINNT && defined DEBUG +#include +#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 @@ -19,3 +43,6 @@ emalloc( } return mem; } + + +#endif diff --git a/libntp/iosignal.c b/libntp/iosignal.c new file mode 100644 index 000000000..85710f784 --- /dev/null +++ b/libntp/iosignal.c @@ -0,0 +1,521 @@ +/* + * ntp_io.c - input/output routines for ntpd. The socket-opening code + * was shamelessly stolen from ntpd. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#ifdef HAVE_SYS_PARAM_H +# include +#endif /* HAVE_SYS_PARAM_H */ +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance ) */ +# include +#endif +#include + +#if _BSDI_VERSION >= 199510 +# include +#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 diff --git a/libntp/machines.c b/libntp/machines.c index 1205de09a..4bf24aaf7 100644 --- a/libntp/machines.c +++ b/libntp/machines.c @@ -212,7 +212,6 @@ settimeofday_NT( #include #include -#include #include "ntp_syslog.h" char * set_tod_using = "SetSystemTime"; @@ -227,26 +226,181 @@ 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, @@ -257,6 +411,7 @@ ntp_set_tod( 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; @@ -276,49 +431,6 @@ ntp_set_tod( } -/* - * 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 */ diff --git a/libntp/mexit.c b/libntp/mexit.c index 6ae452ef3..b04e7de8f 100644 --- a/libntp/mexit.c +++ b/libntp/mexit.c @@ -32,3 +32,32 @@ service_exit( #else /* not SYS_WINNT */ int mexit_bs; #endif /* not SYS_WINNT */ +#ifdef SYS_WINNT +#include +#include + +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 */ diff --git a/libntp/msyslog.c b/libntp/msyslog.c index 712fd21cc..ef0bf433a 100644 --- a/libntp/msyslog.c +++ b/libntp/msyslog.c @@ -45,15 +45,16 @@ static WORD event_type[] = { #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 @@ -72,7 +73,7 @@ void msyslog(int level, const char *fmt, ...) int olderrno; char *err; -#ifdef __STDC__ +#if defined(__STDC__) || defined(HAVE_STDARG_H) va_start(ap, fmt); #else va_start(ap); diff --git a/libntp/recvbuff.c b/libntp/recvbuff.c new file mode 100644 index 000000000..fb4434c5c --- /dev/null +++ b/libntp/recvbuff.c @@ -0,0 +1,279 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#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; +} diff --git a/libntp/statestr.c b/libntp/statestr.c index 7ac5d7c2b..7dd600979 100644 --- a/libntp/statestr.c +++ b/libntp/statestr.c @@ -189,7 +189,7 @@ statustoa( /* * 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 { diff --git a/libntp/syssignal.c b/libntp/syssignal.c index 612d1203b..1f0d33518 100644 --- a/libntp/syssignal.c +++ b/libntp/syssignal.c @@ -12,14 +12,14 @@ extern int errno; 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)); diff --git a/libntp/systime.c b/libntp/systime.c index fea624720..dcb629820 100644 --- a/libntp/systime.c +++ b/libntp/systime.c @@ -24,6 +24,9 @@ #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 */ @@ -76,11 +79,11 @@ get_systime( * 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) @@ -114,6 +117,7 @@ get_systime( now->l_i++; now->l_uf = (u_int32)dtemp; #endif /* HAVE_CLOCK_GETTIME */ + } /* @@ -183,17 +187,20 @@ adj_systime( * 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 */ diff --git a/libparse/parse.c b/libparse/parse.c index a0c5aff1e..727a32b70 100644 --- a/libparse/parse.c +++ b/libparse/parse.c @@ -45,7 +45,7 @@ static char rcsid[] = "parse.c,v 4.13 1999/02/28 11:50:20 kardel RELEASE_1999022 #include #include -#include +#include #include "ntp_fp.h" #include "ntp_unixtime.h" diff --git a/libparse/parse_conf.c b/libparse/parse_conf.c index bb40d83e3..b8519f2b6 100644 --- a/libparse/parse_conf.c +++ b/libparse/parse_conf.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "ntp_fp.h" #include "ntp_unixtime.h" #include "ntp_calendar.h" diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 234bb062a..437987778 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -447,7 +447,7 @@ ctl_error( * 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; @@ -740,7 +740,7 @@ ctl_flushpkt( /* * 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) { diff --git a/ntpd/ntp_intres.c b/ntpd/ntp_intres.c index 49fb3429c..3b39e1671 100644 --- a/ntpd/ntp_intres.c +++ b/ntpd/ntp_intres.c @@ -195,7 +195,11 @@ ntp_intres(void) */ 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 diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index c6ac5db85..e94378e45 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -7,6 +7,7 @@ # include #endif +/* Modified by Sven 7/14/99 322pm */ #include #include @@ -37,6 +38,7 @@ #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" @@ -55,6 +57,10 @@ #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 */ @@ -91,41 +97,6 @@ struct ifconf { * 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 @@ -167,14 +138,6 @@ static int open_socket P((struct sockaddr_in *, int, int)); 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 @@ -182,26 +145,17 @@ static void set_signal P((void)); 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; @@ -412,8 +366,9 @@ create_sockets( # 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; @@ -438,17 +393,13 @@ create_sockets( 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 */ @@ -463,19 +414,20 @@ create_sockets( # 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? */ @@ -548,9 +500,12 @@ create_sockets( # 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; @@ -616,12 +571,12 @@ create_sockets( } # 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 */ /* @@ -716,11 +671,17 @@ create_sockets( 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 */ @@ -1162,95 +1123,6 @@ findbcastinter( } -/* 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 @@ -1324,18 +1196,22 @@ sendpkt( 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 @@ -1365,6 +1241,7 @@ sendpkt( } } +#if !defined(HAVE_IO_COMPLETION_PORT) /* * fdbits - generate ascii representation of fd_set (FAU debug support) * HFDF format - highest fd first. @@ -1390,11 +1267,10 @@ fdbits( return buffer; } - /* * input_handler - receive packets asynchronously */ -void +extern void input_handler( l_fp *cts ) @@ -1449,7 +1325,7 @@ input_handler( if (FD_ISSET(fd, &fds)) { n--; - if (free_recvbufs == 0) + if (free_recvbuffs() == 0) { char buf[RX_BUFF_SIZE]; @@ -1462,9 +1338,7 @@ input_handler( 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)) @@ -1481,9 +1355,7 @@ input_handler( 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; } @@ -1508,9 +1380,7 @@ input_handler( * 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 @@ -1519,18 +1389,7 @@ input_handler( } } - 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++; @@ -1573,9 +1432,9 @@ input_handler( * 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 ) { @@ -1588,7 +1447,7 @@ input_handler( 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) @@ -1598,7 +1457,7 @@ input_handler( goto select_again; } - rb = (struct recvbuf *) freelist; + rb = get_free_recv_buffer(); fromlen = sizeof(struct sockaddr_in); rb->recv_length = recvfrom(fd, @@ -1606,27 +1465,25 @@ input_handler( 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 @@ -1647,19 +1504,8 @@ input_handler( 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; @@ -1744,6 +1590,8 @@ input_handler( return; } +#endif + /* * findinterface - utility used by other modules to find an interface * given an address. @@ -1837,6 +1685,13 @@ io_addclock( 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) @@ -1891,480 +1746,6 @@ io_closeclock( } #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) { @@ -2374,254 +1755,3 @@ 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 */ diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 97d2975be..61f465441 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -686,9 +686,6 @@ process_packet( 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. @@ -856,27 +853,6 @@ process_packet( 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(). @@ -885,12 +861,6 @@ process_packet( 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); } @@ -1072,7 +1042,7 @@ clock_filter( 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; @@ -1951,13 +1921,21 @@ default_get_precision(void) #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 diff --git a/ntpd/ntp_refclock.c b/ntpd/ntp_refclock.c index f424fea22..7feec6aa6 100644 --- a/ntpd/ntp_refclock.c +++ b/ntpd/ntp_refclock.c @@ -440,7 +440,7 @@ refclock_process_offset( /* * 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 */ diff --git a/ntpd/ntp_request.c b/ntpd/ntp_request.c index ff264977b..39daa9462 100644 --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -18,6 +18,7 @@ #include "ntp_refclock.h" #include "ntp_if.h" #include "ntp_stdlib.h" +#include "recvbuff.h" #ifdef KERNEL_PLL #include "ntp_syscall.h" @@ -1055,10 +1056,7 @@ io_stats( * 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; @@ -1071,10 +1069,10 @@ io_stats( 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); diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index 072a7df9f..9fb5f8145 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -2,7 +2,7 @@ * ntp_timer.c - event timer support routines */ #ifdef HAVE_CONFIG_H -#include +# include #endif #include @@ -15,6 +15,12 @@ #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 @@ -67,6 +73,11 @@ static int vmstimer[2]; /* time for next timer AST */ 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 */ @@ -81,16 +92,17 @@ init_timer(void) 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... @@ -104,7 +116,7 @@ init_timer(void) 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 @@ -143,7 +155,7 @@ init_timer(void) 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 */ @@ -162,7 +174,7 @@ init_timer(void) /* cannot test return value of AdjustTokenPrivileges. */ if (GetLastError() != ERROR_SUCCESS) msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); -#endif +# endif /* SYS_CYGWIN32 */ #else /* SYS_WINNT */ _tzset(); @@ -182,48 +194,40 @@ init_timer(void) /* 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< # include # include "../libntp/log.h" +# include #endif /* SYS_WINNT */ #if defined(HAVE_RTPRIO) # ifdef HAVE_SYS_RESOURCE_H @@ -71,7 +72,9 @@ #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 @@ -98,26 +101,29 @@ #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 @@ -154,9 +160,6 @@ int was_alarmed; 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)); @@ -227,8 +230,7 @@ static void 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; @@ -302,11 +304,9 @@ ntpdmain( ) { l_fp now; -#ifndef SYS_WINNT char *cp; struct recvbuf *rbuflist; struct recvbuf *rbuf; -#endif #ifdef _AIX /* HMS: ifdef SIGDANGER? */ struct sigaction sa; #endif @@ -453,17 +453,8 @@ ntpdmain( /* 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 */ @@ -488,7 +479,8 @@ service_main( ) { char *cp; - DWORD dwWait; + struct recvbuf *rbuflist; + struct recvbuf *rbuf; if(!debug) { @@ -516,21 +508,6 @@ service_main( 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 */ @@ -662,9 +639,18 @@ service_main( (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(); @@ -700,80 +686,23 @@ service_main( # 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 @@ -788,20 +717,6 @@ worker_thread( * 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. @@ -809,19 +724,67 @@ worker_thread( * 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? */ @@ -858,22 +821,17 @@ worker_thread( (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; @@ -881,27 +839,19 @@ worker_thread( } 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 @@ -914,10 +864,18 @@ worker_thread( (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); } @@ -933,14 +891,6 @@ finish( 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 @@ -1034,20 +984,21 @@ service_ctrl( 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: @@ -1067,4 +1018,73 @@ service_ctrl( 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 */ diff --git a/ntpd/refclock_nmea.c b/ntpd/refclock_nmea.c index 475173711..ce11d49ad 100644 --- a/ntpd/refclock_nmea.c +++ b/ntpd/refclock_nmea.c @@ -9,8 +9,6 @@ #if defined(REFCLOCK) && defined(CLOCK_NMEA) -#define DEBUG 1 - #include #include #include diff --git a/ntpd/refclock_palisade.c b/ntpd/refclock_palisade.c index 69eb6f7d6..b7201809e 100644 --- a/ntpd/refclock_palisade.c +++ b/ntpd/refclock_palisade.c @@ -48,7 +48,7 @@ * Post Office Box 3642 * Sunnyvale, CA 94088-3642 * - * Version 2.43; May 11, 1999 + * Version 2.45; July 14, 1999 * */ @@ -200,9 +200,9 @@ palisade_start ( 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)) { @@ -326,9 +326,19 @@ TSIP_decode ( * 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) { /* @@ -712,7 +722,7 @@ palisade_io ( 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) @@ -721,36 +731,6 @@ palisade_io ( } /* 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 @@ -774,15 +754,8 @@ HW_poll ( 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)); @@ -797,7 +770,7 @@ HW_poll ( 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); @@ -819,7 +792,6 @@ HW_poll ( up->unit); return -1; } -#endif /* ! SYS_WINNT */ return 0; } diff --git a/ntpd/refclock_palisade.h b/ntpd/refclock_palisade.h index de9b1adce..b78d9880b 100644 --- a/ntpd/refclock_palisade.h +++ b/ntpd/refclock_palisade.h @@ -91,9 +91,8 @@ #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 @@ -101,8 +100,6 @@ #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 */ @@ -126,7 +123,6 @@ /* * 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 */ @@ -149,7 +145,7 @@ struct palisade_unit { 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 */ }; /* diff --git a/ntpd/refclock_shm.c b/ntpd/refclock_shm.c index 6cdca1e53..1e884befb 100644 --- a/ntpd/refclock_shm.c +++ b/ntpd/refclock_shm.c @@ -99,10 +99,10 @@ struct shmTime *getShmTime (int unit) { 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=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; @@ -151,7 +151,7 @@ struct shmTime *getShmTime (int unit) { } 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); @@ -161,7 +161,7 @@ struct shmTime *getShmTime (int unit) { 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); @@ -290,7 +290,7 @@ shm_poll( 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; diff --git a/ntpdate/ntpdate.c b/ntpdate/ntpdate.c index 1293c81d8..4ee283f66 100644 --- a/ntpdate/ntpdate.c +++ b/ntpdate/ntpdate.c @@ -56,10 +56,12 @@ struct timeval timeout = {60,0}; #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 */ /* @@ -196,10 +198,8 @@ static void init_alarm P((void)); 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 *)); @@ -724,7 +724,7 @@ receive( 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. @@ -758,7 +758,7 @@ receive( /* * 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"); @@ -1327,6 +1327,22 @@ timer(void) } +#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 @@ -1464,18 +1480,6 @@ init_alarm(void) } -#ifndef SYS_WINNT -/* - * alarming - record the occurance of an alarm interrupt - */ -static RETSIGTYPE -alarming( - int sig - ) -{ - alarm_flag++; -} -#endif /* SYS_WINNT */ /* @@ -1491,15 +1495,6 @@ alarming( * 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 @@ -1513,19 +1508,7 @@ init_io(void) /* * 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 */ @@ -1610,51 +1593,6 @@ init_io(void) } -/* 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 */ @@ -1691,7 +1629,7 @@ sendpkt( /* * input_handler - receive packets asynchronously */ -static void +void input_handler(void) { register int n; @@ -1742,7 +1680,7 @@ input_handler(void) * 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 @@ -1758,18 +1696,14 @@ input_handler(void) 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; } @@ -1778,9 +1712,7 @@ input_handler(void) * put it on the full list. */ rb->recv_time = ts; - rb->next = fulllist; - fulllist = rb; - full_recvbufs++; + add_full_recv_buffer(rb); } } diff --git a/ntptrace/ntptrace.c b/ntptrace/ntptrace.c index d78e2747e..fa430fae5 100644 --- a/ntptrace/ntptrace.c +++ b/ntptrace/ntptrace.c @@ -32,7 +32,7 @@ #include "ntp_syslog.h" #include "ntp_select.h" #include "ntp_stdlib.h" - +#include "recvbuff.h" /* * only 16 stratums, so this is more than enough. */ @@ -63,14 +63,6 @@ int sys_numservers = 0; /* number of servers to poll */ 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 @@ -87,15 +79,14 @@ int always_step = 0; 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 *)); @@ -106,9 +97,9 @@ WSADATA wsaData; 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); @@ -345,23 +336,19 @@ DoReceive( } 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; } @@ -370,9 +357,7 @@ DoReceive( * 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); @@ -404,7 +389,7 @@ ReceiveBuf( if (debug) { printf("ReceiveBuf(%s, ", ntoa(&server->srcadr)); - printf("%s)\n", ntoa(&rbufp->srcadr)); + printf("%s)\n", ntoa(&rbufp->recv_srcadr)); } /* @@ -417,7 +402,7 @@ ReceiveBuf( 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 */ @@ -578,31 +563,13 @@ addservbyname( } -/* 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)) @@ -621,19 +588,6 @@ setup_io(void) 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 */