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