X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=secnet.git;a=blobdiff_plain;f=secnet.h;h=b2f6927af03ff29fd4d0c35482f84e245db25031;hp=f458f8a345724e3cdb78b2dcf25b7ac1b873261f;hb=a0fac2f1c903f765c8b8596f1ec93beb52b72c7a;hpb=a32d56fb47ceff7404072e49a21290fc7314a7c3 diff --git a/secnet.h b/secnet.h index f458f8a..b2f6927 100644 --- a/secnet.h +++ b/secnet.h @@ -3,6 +3,8 @@ #ifndef secnet_h #define secnet_h +#define ADNS_FEATURE_MANYAF + #include "config.h" #include #include @@ -11,12 +13,16 @@ #include #include #include +#include #include #include +#include #include #include #include +#include + #define MAX_PEER_ADDRS 5 /* send at most this many copies; honour at most that many addresses */ @@ -33,6 +39,9 @@ typedef _Bool bool_t; union iaddr { struct sockaddr sa; struct sockaddr_in sin; +#ifdef CONFIG_IPV6 + struct sockaddr_in6 sin6; +#endif }; #define ASSERT(x) do { if (!(x)) { fatal("assertion failed line %d file " \ @@ -50,6 +59,10 @@ extern struct log_if *system_log; /* from process.c */ extern void start_signal_handling(void); +void afterfork(void); +/* Must be called before exec in every child made after + start_signal_handling. Safe to call in earlier children too. */ + /***** CONFIGURATION support *****/ extern bool_t just_check_config; /* If True then we're going to exit after @@ -111,7 +124,7 @@ extern cstring_t *dict_keys(dict_t *dict); /* List-manipulation functions */ extern list_t *list_new(void); -extern int32_t list_length(list_t *a); +extern int32_t list_length(const list_t *a); extern list_t *list_append(list_t *a, item_t *i); extern list_t *list_append_list(list_t *a, list_t *b); /* Returns an item from the list (index starts at 0), or NULL */ @@ -133,6 +146,14 @@ extern uint32_t dict_read_number(dict_t *dict, cstring_t key, bool_t required, /* return value can safely be assigned to int32_t */ extern bool_t dict_read_bool(dict_t *dict, cstring_t key, bool_t required, cstring_t desc, struct cloc loc, bool_t def); +const char **dict_read_string_array(dict_t *dict, cstring_t key, + bool_t required, cstring_t desc, + struct cloc loc, const char *const *def); + /* Return value is a NULL-terminated array obtained from malloc; + * Individual string values are still owned by config file machinery + * and must not be modified or freed. Returns NULL if key not + * found. */ + struct flagstr { cstring_t name; uint32_t value; @@ -149,8 +170,11 @@ extern uint32_t string_list_to_word(list_t *l, struct flagstr *f, extern char *safe_strdup(const char *string, const char *message); extern void *safe_malloc(size_t size, const char *message); extern void *safe_malloc_ary(size_t size, size_t count, const char *message); +extern void *safe_realloc_ary(void *p, size_t size, size_t count, + const char *message); void setcloexec(int fd); /* cannot fail */ +void setnonblock(int fd); /* cannot fail */ void pipe_cloexec(int fd[2]); /* pipe(), setcloexec() twice; cannot fail */ extern int sys_cmd(const char *file, const char *argc, ...); @@ -180,20 +204,37 @@ int32_t calculate_max_start_pad(void); /* If nfds_io is insufficient for your needs, set it to the required number and return ERANGE. timeout is in milliseconds; if it is too - high then lower it. It starts at -1 (==infinite) */ + high then lower it. It starts at -1 (==infinite). */ +/* Note that beforepoll_fn may NOT do anything which might change the + fds or timeouts wanted by other registered poll loop loopers. + Callers should make sure of this by not making any calls into other + modules from the beforepoll_fn; the easiest way to ensure this is + for beforepoll_fn to only retreive information and not take any + action. + */ typedef int beforepoll_fn(void *st, struct pollfd *fds, int *nfds_io, int *timeout_io); typedef void afterpoll_fn(void *st, struct pollfd *fds, int nfds); + /* If beforepoll_fn returned ERANGE, afterpoll_fn gets nfds==0. + afterpoll_fn never gets !!(fds[].revents & POLLNVAL) - such + a report is detected as a fatal error by the event loop. */ + +/* void BEFOREPOLL_WANT_FDS(int want); + * Expects: int *nfds_io; + * Can perform non-local exit. + * Checks whether there is space for want fds. If so, sets *nfds_io. + * If not, sets *nfds_io and returns. */ +#define BEFOREPOLL_WANT_FDS(want) do{ \ + if (*nfds_io<(want)) { *nfds_io=(want); return ERANGE; } \ + *nfds_io=(want); \ + }while(0) /* Register interest in the main loop of the program. Before a call to poll() your supplied beforepoll function will be called. After - the call to poll() the supplied afterpoll function will be called. - max_nfds is a _hint_ about the maximum number of struct pollfd - structures you may require - you can always ask for more in - *nfds_io. */ -extern void register_for_poll(void *st, beforepoll_fn *before, - afterpoll_fn *after, int32_t max_nfds, - cstring_t desc); + the call to poll() the supplied afterpoll function will be called. */ +struct poll_interest *register_for_poll(void *st, beforepoll_fn *before, + afterpoll_fn *after, cstring_t desc); +void deregister_for_poll(struct poll_interest *i); /***** END of scheduling support */ @@ -292,7 +333,10 @@ struct buffer_if; actually found in the DNS, which may be bigger if addrs is equal to MAX_PEER_ADDRS (ie there were too many). */ typedef void resolve_answer_fn(void *st, const struct comm_addr *addrs, - int naddrs, int was_naddrs); + int naddrs, int was_naddrs, + const char *name, const char *failwhy); + /* name is the same ptr as passed to request, so its lifetime must + * be suitable*/ typedef bool_t resolve_request_fn(void *st, cstring_t name, int remoteport, struct comm_if *comm, resolve_answer_fn *cb, void *cst); @@ -334,17 +378,13 @@ struct rsaprivkey_if { struct comm_addr { /* This struct is pure data; in particular comm's clients may freely copy it. */ - /* Everyone is also guaranteed that all padding is set to zero, ie - that comm_addrs referring to semantically identical peers will - compare equal with memcmp. Anyone who constructs a comm_addr - must start by memsetting it with FILLZERO, or some - equivalent. */ struct comm_if *comm; union iaddr ia; + int ix; /* see comment `Re comm_addr.ix' in udp.c */ }; /* Return True if the packet was processed, and shouldn't be passed to - any other potential receivers. */ + any other potential receivers. (buf is freed iff True returned.) */ typedef bool_t comm_notify_fn(void *state, struct buffer_if *buf, const struct comm_addr *source); typedef void comm_request_notify_fn(void *commst, void *nst, @@ -367,11 +407,19 @@ struct comm_if { comm_addr_to_string_fn *addr_to_string; }; +bool_t iaddr_equal(const union iaddr *ia, const union iaddr *ib); + static inline const char *comm_addr_to_string(const struct comm_addr *ca) { return ca->comm->addr_to_string(ca->comm->st, ca); } +static inline bool_t comm_addr_equal(const struct comm_addr *a, + const struct comm_addr *b) +{ + return a->comm==b->comm && iaddr_equal(&a->ia,&b->ia); +} + /* LOG interface */ #define LOG_MESSAGE_BUFLEN 1023 @@ -545,6 +593,19 @@ extern NORETURN(fatal_status(int status, const char *message, ...)) extern NORETURN(fatal_perror_status(int status, const char *message, ...)) FORMAT(printf,2,3); +/* Convenient nonfatal logging. Requires message that does not end in '\n'. + * If class contains M_FATAL, exits (after entering PHASE_SHUTDOWN). + * lg, errnoval and loc may sensibly be 0. desc must NOT be 0. + * lg_[v]perror save and restore errno. */ +void lg_vperror(struct log_if *lg, const char *desc, struct cloc *loc, + int class, int errnoval, const char *fmt, va_list al) + FORMAT(printf,6,0); +void lg_perror(struct log_if *lg, const char *desc, struct cloc *loc, + int class, int errnoval, const char *fmt, ...) + FORMAT(printf,6,7); +void lg_exitstatus(struct log_if *lg, const char *desc, struct cloc *loc, + int class, int status, const char *progname); + /* The cfgfatal() family of functions require messages that end in '\n' */ extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility, const char *message, ...)) FORMAT(printf,3,4); @@ -568,6 +629,7 @@ extern void log_from_fd(int fd, cstring_t prefix, struct log_if *log); #define STRING(x) STRING2(x) #define FILLZERO(obj) (memset(&(obj),0,sizeof((obj)))) +#define ARRAY_SIZE(ary) (sizeof((ary))/sizeof((ary)[0])) /* * void COPY_OBJ( OBJECT& dst, const OBJECT& src);