xref: /freebsd-src/contrib/ntp/include/recvbuff.h (revision 767173cec2b2041e1f847bc8896092f9c1481242)
12b15cb3dSCy Schubert #ifndef RECVBUFF_H
22b15cb3dSCy Schubert #define RECVBUFF_H
3c0b746e5SOllivier Robert 
4c0b746e5SOllivier Robert #include "ntp.h"
52b15cb3dSCy Schubert #include "ntp_net.h"
62b15cb3dSCy Schubert #include "ntp_lists.h"
7c0b746e5SOllivier Robert 
8ea906c41SOllivier Robert #include <isc/result.h>
9ea906c41SOllivier Robert 
10c0b746e5SOllivier Robert /*
11c0b746e5SOllivier Robert  * recvbuf memory management
12c0b746e5SOllivier Robert  */
13*767173ceSCy Schubert #define RECV_INIT	64	/* 64 buffers initially */
14c0b746e5SOllivier Robert #define RECV_LOWAT	3	/* when we're down to three buffers get more */
15*767173ceSCy Schubert #define RECV_INC	32	/* [power of 2] get 32 more at a time */
16*767173ceSCy Schubert #define RECV_BATCH	128	/* [power of 2] max increment in one sweep */
17*767173ceSCy Schubert #define RECV_TOOMANY	4096	/* this should suffice, really. TODO: tos option? */
18*767173ceSCy Schubert 
19*767173ceSCy Schubert /* If we have clocks, keep an iron reserve of receive buffers for
20*767173ceSCy Schubert  * clocks only.
21*767173ceSCy Schubert  */
22*767173ceSCy Schubert #if defined(REFCLOCK)
23*767173ceSCy Schubert # if !defined(RECV_CLOCK) || RECV_CLOCK == 0
24*767173ceSCy Schubert #  undef RECV_CLOCK
25*767173ceSCy Schubert #  define RECV_CLOCK	16
26*767173ceSCy Schubert # endif
27*767173ceSCy Schubert #else
28*767173ceSCy Schubert # if defined(RECV_CLOCK)
29*767173ceSCy Schubert #  undef RECV_CLOCK
30*767173ceSCy Schubert # endif
31*767173ceSCy Schubert # define RECV_CLOCK 0
32*767173ceSCy Schubert #endif
33c0b746e5SOllivier Robert 
34c0b746e5SOllivier Robert #if defined HAVE_IO_COMPLETION_PORT
35c0b746e5SOllivier Robert # include "ntp_iocompletionport.h"
36c0b746e5SOllivier Robert # include "ntp_timer.h"
37c0b746e5SOllivier Robert 
38c0b746e5SOllivier Robert # define RECV_BLOCK_IO()	EnterCriticalSection(&RecvCritSection)
39c0b746e5SOllivier Robert # define RECV_UNBLOCK_IO()	LeaveCriticalSection(&RecvCritSection)
40c0b746e5SOllivier Robert 
41c0b746e5SOllivier Robert /*  Return the event which is set when items are added to the full list
42c0b746e5SOllivier Robert  */
432b15cb3dSCy Schubert extern HANDLE	get_recv_buff_event(void);
44c0b746e5SOllivier Robert #else
45c0b746e5SOllivier Robert # define RECV_BLOCK_IO()
46c0b746e5SOllivier Robert # define RECV_UNBLOCK_IO()
47c0b746e5SOllivier Robert #endif
48c0b746e5SOllivier Robert 
49c0b746e5SOllivier Robert 
50c0b746e5SOllivier Robert /*
51c0b746e5SOllivier Robert  * Format of a recvbuf.  These are used by the asynchronous receive
52c0b746e5SOllivier Robert  * routine to store incoming packets and related information.
53c0b746e5SOllivier Robert  */
54c0b746e5SOllivier Robert 
55c0b746e5SOllivier Robert /*
569c2daa00SOllivier Robert  *  the maximum length NTP packet contains the NTP header, one Autokey
579c2daa00SOllivier Robert  *  request, one Autokey response and the MAC. Assuming certificates don't
5809100258SXin LI  *  get too big, the maximum packet length is set arbitrarily at 1200.
5909100258SXin LI  *  (was 1000, but that bumps on 2048 RSA keys)
60c0b746e5SOllivier Robert  */
6109100258SXin LI #define	RX_BUFF_SIZE	1200		/* hail Mary */
62c0b746e5SOllivier Robert 
63ea906c41SOllivier Robert 
64ea906c41SOllivier Robert typedef struct recvbuf recvbuf_t;
65ea906c41SOllivier Robert 
66c0b746e5SOllivier Robert struct recvbuf {
672b15cb3dSCy Schubert 	recvbuf_t *	link;	/* next in list */
68c0b746e5SOllivier Robert 	union {
692b15cb3dSCy Schubert 		sockaddr_u	X_recv_srcadr;
70c0b746e5SOllivier Robert 		caddr_t		X_recv_srcclock;
71c0b746e5SOllivier Robert 		struct peer *	X_recv_peer;
72c0b746e5SOllivier Robert 	} X_from_where;
73c0b746e5SOllivier Robert #define recv_srcadr		X_from_where.X_recv_srcadr
74c0b746e5SOllivier Robert #define	recv_srcclock		X_from_where.X_recv_srcclock
75c0b746e5SOllivier Robert #define recv_peer		X_from_where.X_recv_peer
762b15cb3dSCy Schubert #ifndef HAVE_IO_COMPLETION_PORT
772b15cb3dSCy Schubert 	sockaddr_u	srcadr;		/* where packet came from */
78c0b746e5SOllivier Robert #else
792b15cb3dSCy Schubert 	int		recv_srcadr_len;/* filled in on completion */
80c0b746e5SOllivier Robert #endif
812b15cb3dSCy Schubert 	endpt *		dstadr;		/* address pkt arrived on */
829c2daa00SOllivier Robert 	SOCKET		fd;		/* fd on which it was received */
83ea906c41SOllivier Robert 	int		msg_flags;	/* Flags received about the packet */
84c0b746e5SOllivier Robert 	l_fp		recv_time;	/* time of arrival */
852b15cb3dSCy Schubert 	void		(*receiver)(struct recvbuf *); /* callback */
86c0b746e5SOllivier Robert 	int		recv_length;	/* number of octets received */
87c0b746e5SOllivier Robert 	union {
88c0b746e5SOllivier Robert 		struct pkt	X_recv_pkt;
89c0b746e5SOllivier Robert 		u_char		X_recv_buffer[RX_BUFF_SIZE];
90c0b746e5SOllivier Robert 	} recv_space;
91c0b746e5SOllivier Robert #define	recv_pkt		recv_space.X_recv_pkt
92c0b746e5SOllivier Robert #define	recv_buffer		recv_space.X_recv_buffer
932b15cb3dSCy Schubert 	int used;		/* reference count */
94c0b746e5SOllivier Robert };
95c0b746e5SOllivier Robert 
962b15cb3dSCy Schubert extern	void	init_recvbuff(int);
97c0b746e5SOllivier Robert 
98c0b746e5SOllivier Robert /* freerecvbuf - make a single recvbuf available for reuse
99c0b746e5SOllivier Robert  */
1002b15cb3dSCy Schubert extern	void	freerecvbuf(struct recvbuf *);
101c0b746e5SOllivier Robert 
102c0b746e5SOllivier Robert /*  Get a free buffer (typically used so an async
103c0b746e5SOllivier Robert  *  read can directly place data into the buffer
104c0b746e5SOllivier Robert  *
105c0b746e5SOllivier Robert  *  The buffer is removed from the free list. Make sure
106c0b746e5SOllivier Robert  *  you put it back with freerecvbuf() or
107c0b746e5SOllivier Robert  */
1082b15cb3dSCy Schubert 
109*767173ceSCy Schubert /* signal safe - no malloc, returns NULL when no bufs */
110*767173ceSCy Schubert extern	struct recvbuf *get_free_recv_buffer(int /*BOOL*/ urgent);
111*767173ceSCy Schubert /* signal unsafe - may malloc, returns NULL when no bufs */
112*767173ceSCy Schubert extern	struct recvbuf *get_free_recv_buffer_alloc(int /*BOOL*/ urgent);
113c0b746e5SOllivier Robert 
114c0b746e5SOllivier Robert /*   Add a buffer to the full list
115c0b746e5SOllivier Robert  */
1162b15cb3dSCy Schubert extern	void	add_full_recv_buffer(struct recvbuf *);
117c0b746e5SOllivier Robert 
118c0b746e5SOllivier Robert /* number of recvbufs on freelist */
1192b15cb3dSCy Schubert extern u_long free_recvbuffs(void);
1202b15cb3dSCy Schubert extern u_long full_recvbuffs(void);
1212b15cb3dSCy Schubert extern u_long total_recvbuffs(void);
1222b15cb3dSCy Schubert extern u_long lowater_additions(void);
123c0b746e5SOllivier Robert 
124c0b746e5SOllivier Robert /*  Returns the next buffer in the full list.
125c0b746e5SOllivier Robert  *
126c0b746e5SOllivier Robert  */
1272b15cb3dSCy Schubert extern	struct recvbuf *get_full_recv_buffer(void);
1282b15cb3dSCy Schubert 
1292b15cb3dSCy Schubert /*
1302b15cb3dSCy Schubert  * purge_recv_buffers_for_fd() - purges any previously-received input
1312b15cb3dSCy Schubert  *				 from a given file descriptor.
1322b15cb3dSCy Schubert  */
1334990d495SXin LI extern	void purge_recv_buffers_for_fd(int);
134c0b746e5SOllivier Robert 
135ea906c41SOllivier Robert /*
136ea906c41SOllivier Robert  * Checks to see if there are buffers to process
137ea906c41SOllivier Robert  */
1382b15cb3dSCy Schubert extern isc_boolean_t has_full_recv_buffer(void);
139ea906c41SOllivier Robert 
1402b15cb3dSCy Schubert #endif	/* RECVBUFF_H */
141