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