767173cec2
Update 4.2.8p14 --> 4.2.8p15 Summary: Systems that use a CMAC algorithm in ntp.keys will not release a bit of memory on each packet that uses a CMAC keyid, eventually causing ntpd to run out of memory and fail. The CMAC cleanup from https://bugs.ntp.org/3447, part of ntp-4.2.8p11, introduced a bug whereby the CMAC data structure was no longer completely removed. MFC after: 3 days Security: NTP Bug 3661
141 lines
3.8 KiB
C
141 lines
3.8 KiB
C
#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 */
|