aboutsummaryrefslogtreecommitdiffstats
path: root/include/recvbuff.h
blob: 2a4c84c5afc3b0696a616ef75caae1c4b362609e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef RECVBUFF_H
#define RECVBUFF_H

#include "ntp.h"
#include "ntp_net.h"
#include "ntp_lists.h"

#include <isc/result.h>

/*
 * recvbuf memory management
 */
#define RECV_INIT	64	/* 64 buffers initially */
#define RECV_LOWAT	3	/* when we're down to three buffers get more */
#define RECV_INC	32	/* [power of 2] get 32 more at a time */
#define RECV_BATCH	128	/* [power of 2] max increment in one sweep */
#define RECV_TOOMANY	4096	/* this should suffice, really. TODO: tos option? */

/* If we have clocks, keep an iron reserve of receive buffers for
 * clocks only.
 */
#if defined(REFCLOCK)
# if !defined(RECV_CLOCK) || RECV_CLOCK == 0
#  undef RECV_CLOCK
#  define RECV_CLOCK	16
# endif
#else
# if defined(RECV_CLOCK)
#  undef RECV_CLOCK
# endif
# define RECV_CLOCK 0
#endif

#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(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 contains the NTP header, one Autokey
 *  request, one Autokey response and the MAC. Assuming certificates don't
 *  get too big, the maximum packet length is set arbitrarily at 1200.
 *  (was 1000, but that bumps on 2048 RSA keys)
 */   
#define	RX_BUFF_SIZE	1200		/* hail Mary */


typedef struct recvbuf recvbuf_t;

struct recvbuf {
	recvbuf_t *	link;	/* next in list */
	union {
		sockaddr_u	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
#ifndef HAVE_IO_COMPLETION_PORT
	sockaddr_u	srcadr;		/* where packet came from */
#else
	int		recv_srcadr_len;/* filled in on completion */
#endif
	endpt *		dstadr;		/* address pkt arrived on */
	SOCKET		fd;		/* fd on which it was received */
	int		msg_flags;	/* Flags received about the packet */
	l_fp		recv_time;	/* time of arrival */
	void		(*receiver)(struct recvbuf *); /* callback */
	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
	int used;		/* reference count */
};

extern	void	init_recvbuff(int);

/* freerecvbuf - make a single recvbuf available for reuse
 */
extern	void	freerecvbuf(struct recvbuf *);

/*  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 
 */

/* signal safe - no malloc, returns NULL when no bufs */
extern	struct recvbuf *get_free_recv_buffer(int /*BOOL*/ urgent);
/* signal unsafe - may malloc, returns NULL when no bufs */
extern	struct recvbuf *get_free_recv_buffer_alloc(int /*BOOL*/ urgent);

/*   Add a buffer to the full list
 */
extern	void	add_full_recv_buffer(struct recvbuf *);

/* number of recvbufs on freelist */
extern u_long free_recvbuffs(void);		
extern u_long full_recvbuffs(void);		
extern u_long total_recvbuffs(void);
extern u_long lowater_additions(void);
		
/*  Returns the next buffer in the full list.
 *
 */
extern	struct recvbuf *get_full_recv_buffer(void);

/*
 * purge_recv_buffers_for_fd() - purges any previously-received input
 *				 from a given file descriptor.
 */
extern	void purge_recv_buffers_for_fd(int);

/*
 * Checks to see if there are buffers to process
 */
extern isc_boolean_t has_full_recv_buffer(void);

#endif	/* RECVBUFF_H */