1285612Sdelphij#ifndef RECVBUFF_H
2285612Sdelphij#define RECVBUFF_H
354359Sroberto
454359Sroberto#include "ntp.h"
5285612Sdelphij#include "ntp_net.h"
6285612Sdelphij#include "ntp_lists.h"
754359Sroberto
8182007Sroberto#include <isc/result.h>
9182007Sroberto
1054359Sroberto/*
1154359Sroberto * recvbuf memory management
1254359Sroberto */
1354359Sroberto#define RECV_INIT	10	/* 10 buffers initially */
1454359Sroberto#define RECV_LOWAT	3	/* when we're down to three buffers get more */
1554359Sroberto#define RECV_INC	5	/* get 5 more at a time */
1654359Sroberto#define RECV_TOOMANY	40	/* this is way too many buffers */
1754359Sroberto
1854359Sroberto#if defined HAVE_IO_COMPLETION_PORT
1954359Sroberto# include "ntp_iocompletionport.h"
20285612Sdelphij# include "ntp_timer.h"
2154359Sroberto
2254359Sroberto# define RECV_BLOCK_IO()	EnterCriticalSection(&RecvCritSection)
2354359Sroberto# define RECV_UNBLOCK_IO()	LeaveCriticalSection(&RecvCritSection)
2454359Sroberto
2554359Sroberto/*  Return the event which is set when items are added to the full list
2654359Sroberto */
27285612Sdelphijextern HANDLE	get_recv_buff_event(void);
2854359Sroberto#else
2954359Sroberto# define RECV_BLOCK_IO()
3054359Sroberto# define RECV_UNBLOCK_IO()
3154359Sroberto#endif
3254359Sroberto
3354359Sroberto
3454359Sroberto/*
3554359Sroberto * Format of a recvbuf.  These are used by the asynchronous receive
3654359Sroberto * routine to store incoming packets and related information.
3754359Sroberto */
3854359Sroberto
3954359Sroberto/*
40132451Sroberto *  the maximum length NTP packet contains the NTP header, one Autokey
41132451Sroberto *  request, one Autokey response and the MAC. Assuming certificates don't
42132451Sroberto *  get too big, the maximum packet length is set arbitrarily at 1000.
4354359Sroberto */
44132451Sroberto#define	RX_BUFF_SIZE	1000		/* hail Mary */
4554359Sroberto
46182007Sroberto
47182007Srobertotypedef struct recvbuf recvbuf_t;
48182007Sroberto
4954359Srobertostruct recvbuf {
50285612Sdelphij	recvbuf_t *	link;	/* next in list */
5154359Sroberto	union {
52285612Sdelphij		sockaddr_u	X_recv_srcadr;
53285612Sdelphij		caddr_t		X_recv_srcclock;
54285612Sdelphij		struct peer *	X_recv_peer;
5554359Sroberto	} X_from_where;
56285612Sdelphij#define recv_srcadr		X_from_where.X_recv_srcadr
57285612Sdelphij#define	recv_srcclock		X_from_where.X_recv_srcclock
58285612Sdelphij#define recv_peer		X_from_where.X_recv_peer
59285612Sdelphij#ifndef HAVE_IO_COMPLETION_PORT
60285612Sdelphij	sockaddr_u	srcadr;		/* where packet came from */
6154359Sroberto#else
62285612Sdelphij	int		recv_srcadr_len;/* filled in on completion */
6354359Sroberto#endif
64285612Sdelphij	endpt *		dstadr;		/* address pkt arrived on */
65285612Sdelphij	SOCKET		fd;		/* fd on which it was received */
66285612Sdelphij	int		msg_flags;	/* Flags received about the packet */
67285612Sdelphij	l_fp		recv_time;	/* time of arrival */
68285612Sdelphij	void		(*receiver)(struct recvbuf *); /* callback */
69285612Sdelphij	int		recv_length;	/* number of octets received */
7054359Sroberto	union {
71285612Sdelphij		struct pkt	X_recv_pkt;
72285612Sdelphij		u_char		X_recv_buffer[RX_BUFF_SIZE];
7354359Sroberto	} recv_space;
74285612Sdelphij#define	recv_pkt		recv_space.X_recv_pkt
75285612Sdelphij#define	recv_buffer		recv_space.X_recv_buffer
76285612Sdelphij	int used;		/* reference count */
7754359Sroberto};
7854359Sroberto
79285612Sdelphijextern	void	init_recvbuff(int);
8054359Sroberto
8154359Sroberto/* freerecvbuf - make a single recvbuf available for reuse
8254359Sroberto */
83285612Sdelphijextern	void	freerecvbuf(struct recvbuf *);
8454359Sroberto
8554359Sroberto/*  Get a free buffer (typically used so an async
8654359Sroberto *  read can directly place data into the buffer
8754359Sroberto *
8854359Sroberto *  The buffer is removed from the free list. Make sure
8954359Sroberto *  you put it back with freerecvbuf() or
9054359Sroberto */
9154359Sroberto
92285612Sdelphij/* signal safe - no malloc */
93285612Sdelphijextern	struct recvbuf *get_free_recv_buffer(void);
94298770Sdelphij/* signal unsafe - may malloc, never returs NULL */
95285612Sdelphijextern	struct recvbuf *get_free_recv_buffer_alloc(void);
96285612Sdelphij
9754359Sroberto/*   Add a buffer to the full list
9854359Sroberto */
99285612Sdelphijextern	void	add_full_recv_buffer(struct recvbuf *);
10054359Sroberto
10154359Sroberto/* number of recvbufs on freelist */
102285612Sdelphijextern u_long free_recvbuffs(void);
103285612Sdelphijextern u_long full_recvbuffs(void);
104285612Sdelphijextern u_long total_recvbuffs(void);
105285612Sdelphijextern u_long lowater_additions(void);
10654359Sroberto
10754359Sroberto/*  Returns the next buffer in the full list.
10854359Sroberto *
10954359Sroberto */
110285612Sdelphijextern	struct recvbuf *get_full_recv_buffer(void);
11154359Sroberto
112182007Sroberto/*
113285612Sdelphij * purge_recv_buffers_for_fd() - purges any previously-received input
114285612Sdelphij *				 from a given file descriptor.
115285612Sdelphij */
116298770Sdelphijextern	void purge_recv_buffers_for_fd(int);
117285612Sdelphij
118285612Sdelphij/*
119182007Sroberto * Checks to see if there are buffers to process
120182007Sroberto */
121285612Sdelphijextern isc_boolean_t has_full_recv_buffer(void);
122182007Sroberto
123285612Sdelphij#endif	/* RECVBUFF_H */
124