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