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