recvbuff.h revision 362716
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 */
43extern 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
64typedef struct recvbuf recvbuf_t;
65
66struct 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
96extern	void	init_recvbuff(int);
97
98/* freerecvbuf - make a single recvbuf available for reuse
99 */
100extern	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 */
110extern	struct recvbuf *get_free_recv_buffer(int /*BOOL*/ urgent);
111/* signal unsafe - may malloc, returns NULL when no bufs */
112extern	struct recvbuf *get_free_recv_buffer_alloc(int /*BOOL*/ urgent);
113
114/*   Add a buffer to the full list
115 */
116extern	void	add_full_recv_buffer(struct recvbuf *);
117
118/* number of recvbufs on freelist */
119extern u_long free_recvbuffs(void);
120extern u_long full_recvbuffs(void);
121extern u_long total_recvbuffs(void);
122extern u_long lowater_additions(void);
123
124/*  Returns the next buffer in the full list.
125 *
126 */
127extern	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 */
133extern	void purge_recv_buffers_for_fd(int);
134
135/*
136 * Checks to see if there are buffers to process
137 */
138extern isc_boolean_t has_full_recv_buffer(void);
139
140#endif	/* RECVBUFF_H */
141