X-Git-Url: https://git.distorted.org.uk/~mdw/secnet/blobdiff_plain/5e7a5e2d42c1b06f249debca72c10ad33d157402..eff48c1250f7f654a00495c5048766a9261c64ce:/secnet.h diff --git a/secnet.h b/secnet.h index 1bfe8a1..63307ac 100644 --- a/secnet.h +++ b/secnet.h @@ -1,4 +1,22 @@ /* Core interface of secnet, to be used by all modules */ +/* + * This file is part of secnet. + * See README for full list of copyright holders. + * + * secnet is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version d of the License, or + * (at your option) any later version. + * + * secnet is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 3 along with secnet; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ #ifndef secnet_h #define secnet_h @@ -14,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +82,12 @@ void afterfork(void); /* Must be called before exec in every child made after start_signal_handling. Safe to call in earlier children too. */ +void childpersist_closefd_hook(void *fd_p, uint32_t newphase); +/* Convenience hook function for use with add_hook PHASE_CHILDPERSIST. + With `int fd' in your state struct, pass fd_p=&fd. The hook checks + whether fd>=0, so you can use it for an fd which is only sometimes + open. This function will set fd to -1, so it is idempotent. */ + /***** CONFIGURATION support *****/ extern bool_t just_check_config; /* If True then we're going to exit after @@ -146,6 +171,8 @@ 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); +extern dict_t *dict_read_dict(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc); 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); @@ -173,7 +200,18 @@ 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); +#define NEW(p) \ + ((p)=safe_malloc(sizeof(*(p)), \ + __FILE__ ":" #p)) +#define NEW_ARY(p,count) \ + ((p)=safe_malloc_ary(sizeof(*(p)),(count), \ + __FILE__ ":" #p "[" #count "]")) +#define REALLOC_ARY(p,count) \ + ((p)=safe_realloc_ary((p),sizeof(*(p)),(count), \ + __FILE__ ":" #p "[" #count "]")) + 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, ...); @@ -256,10 +294,18 @@ enum phase { PHASE_DROPPRIV, /* Last chance for privileged operations */ PHASE_RUN, PHASE_SHUTDOWN, /* About to die; delete key material, etc. */ + PHASE_CHILDPERSIST, /* Forked long-term child: close fds, etc. */ /* Keep this last: */ NR_PHASES, }; +/* Each module should, in its CHILDPERSIST hooks, close all fds which + constitute ownership of important operating system resources, or + which are used for IPC with other processes who want to get the + usual disconnection effects if the main secnet process dies. + CHILDPERSIST hooks are not run if the child is going to exec; + so fds such as described above should be CLOEXEC too. */ + typedef void hook_fn(void *self, uint32_t newphase); bool_t add_hook(uint32_t phase, hook_fn *f, void *state); bool_t remove_hook(uint32_t phase, hook_fn *f, void *state); @@ -267,12 +313,20 @@ bool_t remove_hook(uint32_t phase, hook_fn *f, void *state); extern uint32_t current_phase; extern void enter_phase(uint32_t new_phase); +void phase_hooks_init(void); /* for main() only */ +void clear_phase_hooks(uint32_t phase); /* for afterfork() */ + /* Some features (like netlink 'soft' routes) require that secnet retain root privileges. They should indicate that here when appropriate. */ extern bool_t require_root_privileges; extern cstring_t require_root_privileges_explanation; +/* Some modules may want to know whether secnet is going to drop + privilege, so that they know whether to do privsep. Call only + in phases SETUP and later. */ +bool_t will_droppriv(void); + /***** END of program lifetime support *****/ /***** MODULE support *****/ @@ -287,6 +341,7 @@ extern void init_builtin_modules(dict_t *dict); extern init_module resolver_module; extern init_module random_module; extern init_module udp_module; +extern init_module polypath_module; extern init_module util_module; extern init_module site_module; extern init_module transform_eax_module; @@ -406,7 +461,8 @@ struct comm_if { comm_addr_to_string_fn *addr_to_string; }; -bool_t iaddr_equal(const union iaddr *ia, const union iaddr *ib); +bool_t iaddr_equal(const union iaddr *ia, const union iaddr *ib, + bool_t ignoreport); static inline const char *comm_addr_to_string(const struct comm_addr *ca) { @@ -416,7 +472,7 @@ static inline const char *comm_addr_to_string(const struct comm_addr *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); + return a->comm==b->comm && iaddr_equal(&a->ia,&b->ia,False); } /* LOG interface */